Initial revision
From-SVN: r102074
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
/* Engine -- generic getInstance method.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
|
||||
/**
|
||||
* Generic implementation of the getInstance methods in the various
|
||||
* engine classes in java.security.
|
||||
* <p>
|
||||
* These classes ({@link java.security.Signature} for example) can be
|
||||
* thought of as the "chrome, upholstery, and steering wheel", and the SPI
|
||||
* (service provider interface, e.g. {@link java.security.SignatureSpi})
|
||||
* classes can be thought of as the "engine" -- providing the actual
|
||||
* functionality of whatever cryptographic algorithm the instance
|
||||
* represents.
|
||||
*
|
||||
* @see Provider
|
||||
* @author Casey Marshall
|
||||
*/
|
||||
public final class Engine
|
||||
{
|
||||
|
||||
// Constants.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** Prefix for aliases. */
|
||||
private static final String ALG_ALIAS = "Alg.Alias.";
|
||||
|
||||
/** Maximum number of aliases to try. */
|
||||
private static final int MAX_ALIASES = 5;
|
||||
|
||||
/** Argument list for no-argument constructors. */
|
||||
private static final Object[] NO_ARGS = new Object[0];
|
||||
|
||||
// Constructor.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** This class cannot be instantiated. */
|
||||
private Engine() { }
|
||||
|
||||
// Class method.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the implementation for <i>algorithm</i> for service
|
||||
* <i>service</i> from <i>provider</i>. The service is e.g.
|
||||
* "Signature", and the algorithm "DSA".
|
||||
*
|
||||
* @param service The service name.
|
||||
* @param algorithm The name of the algorithm to get.
|
||||
* @param provider The provider to get the implementation from.
|
||||
* @return The engine class for the specified algorithm; the object
|
||||
* returned is typically a subclass of the SPI class for that
|
||||
* service, but callers should check that this is so.
|
||||
* @throws NoSuchAlgorithmException If the implementation cannot be
|
||||
* found or cannot be instantiated.
|
||||
* @throws InvocationTargetException If the SPI class's constructor
|
||||
* throws an exception.
|
||||
* @throws IllegalArgumentException If any of the three arguments are null.
|
||||
*/
|
||||
public static Object getInstance(String service, String algorithm,
|
||||
Provider provider)
|
||||
throws InvocationTargetException, NoSuchAlgorithmException
|
||||
{
|
||||
return getInstance(service, algorithm, provider, NO_ARGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the implementation for <i>algorithm</i> for service
|
||||
* <i>service</i> from <i>provider</i>, passing <i>initArgs</i> to the
|
||||
* SPI class's constructor (which cannot be null; pass a zero-length
|
||||
* array if the SPI takes no arguments). The service is e.g.
|
||||
* "Signature", and the algorithm "DSA".
|
||||
*
|
||||
* @param service The service name.
|
||||
* @param algorithm The name of the algorithm to get.
|
||||
* @param provider The provider to get the implementation from.
|
||||
* @param initArgs The arguments to pass to the SPI class's
|
||||
* constructor (cannot be null).
|
||||
* @return The engine class for the specified algorithm; the object
|
||||
* returned is typically a subclass of the SPI class for that
|
||||
* service, but callers should check that this is so.
|
||||
* @throws NoSuchAlgorithmException If the implementation cannot be
|
||||
* found or cannot be instantiated.
|
||||
* @throws InvocationTargetException If the SPI class's constructor
|
||||
* throws an exception.
|
||||
* @throws IllegalArgumentException If any of the four arguments are null.
|
||||
*/
|
||||
public static Object getInstance(String service, String algorithm,
|
||||
Provider provider, Object[] initArgs)
|
||||
throws InvocationTargetException, NoSuchAlgorithmException
|
||||
{
|
||||
if (service == null || algorithm == null
|
||||
|| provider == null || initArgs == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
// If there is no property "service.algorithm"
|
||||
if (provider.getProperty(service + "." + algorithm) == null)
|
||||
{
|
||||
// Iterate through aliases, until we find the class name or resolve
|
||||
// too many aliases.
|
||||
String alias = null;
|
||||
int count = 0;
|
||||
while ((alias = provider.getProperty(
|
||||
ALG_ALIAS + service + "." + algorithm)) != null)
|
||||
{
|
||||
if (algorithm.equals(alias)) // Refers to itself!
|
||||
break;
|
||||
algorithm = alias;
|
||||
if (count++ > MAX_ALIASES)
|
||||
throw new NoSuchAlgorithmException("too many aliases");
|
||||
}
|
||||
if (provider.getProperty(service + "." + algorithm) == null)
|
||||
throw new NoSuchAlgorithmException(algorithm);
|
||||
}
|
||||
|
||||
// Find and instantiate the implementation.
|
||||
Class clazz = null;
|
||||
ClassLoader loader = provider.getClass().getClassLoader();
|
||||
Constructor constructor = null;
|
||||
String error = algorithm;
|
||||
|
||||
try
|
||||
{
|
||||
if (loader != null)
|
||||
clazz = loader.loadClass(provider.getProperty(service+"."+algorithm));
|
||||
else
|
||||
clazz = Class.forName(provider.getProperty(service+"."+algorithm));
|
||||
constructor = getCompatibleConstructor(clazz, initArgs);
|
||||
return constructor.newInstance(initArgs);
|
||||
}
|
||||
catch (ClassNotFoundException cnfe)
|
||||
{
|
||||
error = "class not found: " + algorithm;
|
||||
}
|
||||
catch (IllegalAccessException iae)
|
||||
{
|
||||
error = "illegal access: " + iae.getMessage();
|
||||
}
|
||||
catch (InstantiationException ie)
|
||||
{
|
||||
error = "instantiation exception: " + ie.getMessage();
|
||||
}
|
||||
catch (ExceptionInInitializerError eiie)
|
||||
{
|
||||
error = "exception in initializer: " + eiie.getMessage();
|
||||
}
|
||||
catch (SecurityException se)
|
||||
{
|
||||
error = "security exception: " + se.getMessage();
|
||||
}
|
||||
catch (NoSuchMethodException nsme)
|
||||
{
|
||||
error = "no appropriate constructor found";
|
||||
}
|
||||
|
||||
throw new NoSuchAlgorithmException(error);
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find a constructor in the given class that can take the specified
|
||||
* argument list, allowing any of which to be null.
|
||||
*
|
||||
* @param clazz The class from which to get the constructor.
|
||||
* @param initArgs The argument list to be passed to the constructor.
|
||||
* @return The constructor.
|
||||
* @throws NoSuchMethodException If no constructor of the given class
|
||||
* can take the specified argument array.
|
||||
*/
|
||||
private static Constructor getCompatibleConstructor(Class clazz,
|
||||
Object[] initArgs)
|
||||
throws NoSuchMethodException
|
||||
{
|
||||
Constructor[] c = clazz.getConstructors();
|
||||
outer:for (int i = 0; i < c.length; i++)
|
||||
{
|
||||
Class[] argTypes = c[i].getParameterTypes();
|
||||
if (argTypes.length != initArgs.length)
|
||||
continue;
|
||||
for (int j = 0; j < argTypes.length; j++)
|
||||
{
|
||||
if (initArgs[j] != null &&
|
||||
!argTypes[j].isAssignableFrom(initArgs[j].getClass()))
|
||||
continue outer;
|
||||
}
|
||||
// If we reach this point, we know this constructor (c[i]) has
|
||||
// the same number of parameters as the target parameter list,
|
||||
// and all our parameters are either (1) null, or (2) assignable
|
||||
// to the target parameter type.
|
||||
return c[i];
|
||||
}
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
/* OID.java -- numeric representation of an object identifier
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security;
|
||||
|
||||
import gnu.java.security.der.DEREncodingException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* This immutable class represents an object identifier, or OID.
|
||||
*
|
||||
* <p>OIDs are represented as a series of hierarcical tokens, each of
|
||||
* which is usually represented as a single, unsigned integer. The
|
||||
* hierarchy works so that later tokens are considered within the group
|
||||
* of earlier tokens. Thus, the OID for the Serpent block cipher,
|
||||
* 1.3.6.1.4.1.11591.13.2, is maintained by the GNU project, whose OID
|
||||
* is 1.3.6.1.4.1.11591 (which is, in turn, part of bigger, more general
|
||||
* bodies; the topmost, 1, stands for the OIDs assigned by the
|
||||
* International Standards Organization, ISO).
|
||||
*
|
||||
* <p>OIDs can be represented in a variety of ways, including the
|
||||
* dotted-decimal form we use here.
|
||||
*
|
||||
* <p>OIDs may be relative, in which case the first two elements of the
|
||||
* OID are omitted.
|
||||
*
|
||||
* @author Casey Marshall (csm@gnu.org)
|
||||
*/
|
||||
public class OID implements Cloneable, Comparable, java.io.Serializable
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The numeric ID structure.
|
||||
*/
|
||||
private int[] components;
|
||||
|
||||
/**
|
||||
* The string representation of this OID, in dotted-decimal format.
|
||||
*/
|
||||
private transient String strRep;
|
||||
|
||||
/**
|
||||
* The DER encoding of this OID.
|
||||
*/
|
||||
private transient byte[] der;
|
||||
|
||||
/**
|
||||
* Whether or not this OID is relative.
|
||||
*/
|
||||
private boolean relative;
|
||||
|
||||
// Constructors.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new OID from the given byte array. The argument (which can
|
||||
* neither be null nor zero-length) is copied to prevent subsequent
|
||||
* modification.
|
||||
*
|
||||
* @param components The numeric IDs.
|
||||
* @throws IllegalArgumentException If <i>components</i> is null or empty.
|
||||
*/
|
||||
public OID(int[] components)
|
||||
{
|
||||
this(components, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new OID from the given byte array. The argument (which can
|
||||
* neither be null nor zero-length) is copied to prevent subsequent
|
||||
* modification.
|
||||
*
|
||||
* @param components The numeric IDs.
|
||||
* @param relative The relative flag.
|
||||
* @throws IllegalArgumentException If <i>components</i> is null or empty.
|
||||
*/
|
||||
public OID(int[] components, boolean relative)
|
||||
{
|
||||
if (components == null || components.length == 0)
|
||||
throw new IllegalArgumentException();
|
||||
this.components = (int[]) components.clone();
|
||||
this.relative = relative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new OID from the given dotted-decimal representation.
|
||||
*
|
||||
* @param strRep The string representation of the OID.
|
||||
* @throws IllegalArgumentException If the string does not contain at
|
||||
* least one integer.
|
||||
* @throws NumberFormatException If the string does not contain only
|
||||
* numbers and periods ('.').
|
||||
*/
|
||||
public OID(String strRep)
|
||||
{
|
||||
this(strRep, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new OID from the given dotted-decimal representation.
|
||||
*
|
||||
* @param strRep The string representation of the OID.
|
||||
* @param relative The relative flag.
|
||||
* @throws IllegalArgumentException If the string does not contain at
|
||||
* least one integer.
|
||||
* @throws NumberFormatException If the string does not contain only
|
||||
* numbers and periods ('.').
|
||||
*/
|
||||
public OID(String strRep, boolean relative)
|
||||
{
|
||||
this.relative = relative;
|
||||
this.strRep = strRep;
|
||||
components = fromString(strRep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new OID from the DER bytes in an input stream. This method
|
||||
* does not read the tag or the length field from the input stream, so
|
||||
* the caller must supply the number of octets in this OID's encoded
|
||||
* form.
|
||||
*
|
||||
* @param derIn The DER input stream.
|
||||
* @param len The number of bytes in the encoded form.
|
||||
* @throws IOException If an error occurs reading the OID.
|
||||
*/
|
||||
public OID(InputStream derIn, int len) throws IOException
|
||||
{
|
||||
this(derIn, len, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new OID from the DER bytes in an input stream. This method
|
||||
* does not read the tag or the length field from the input stream, so
|
||||
* the caller must supply the number of octets in this OID's encoded
|
||||
* form.
|
||||
*
|
||||
* @param derIn The DER input stream.
|
||||
* @param len The number of bytes in the encoded form.
|
||||
* @param relative The relative flag.
|
||||
* @throws IOException If an error occurs reading the OID.
|
||||
*/
|
||||
public OID(InputStream derIn, int len, boolean relative) throws IOException
|
||||
{
|
||||
der = new byte[len];
|
||||
derIn.read(der);
|
||||
this.relative = relative;
|
||||
try
|
||||
{
|
||||
components = fromDER(der, relative);
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException aioobe)
|
||||
{
|
||||
aioobe.printStackTrace();
|
||||
throw aioobe;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new OID from the given DER bytes.
|
||||
*
|
||||
* @param encoded The DER encoded OID.
|
||||
* @throws IOException If an error occurs reading the OID.
|
||||
*/
|
||||
public OID(byte[] encoded) throws IOException
|
||||
{
|
||||
this(encoded, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new OID from the given DER bytes.
|
||||
*
|
||||
* @param root The root OID.
|
||||
* @param encoded The encoded relative OID.
|
||||
* @param relative The relative flag.
|
||||
*/
|
||||
public OID(byte[] encoded, boolean relative) throws IOException
|
||||
{
|
||||
der = (byte[]) encoded.clone();
|
||||
this.relative = relative;
|
||||
try
|
||||
{
|
||||
components = fromDER(der, relative);
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException aioobe)
|
||||
{
|
||||
aioobe.printStackTrace();
|
||||
throw aioobe;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Our private constructor.
|
||||
*/
|
||||
private OID()
|
||||
{
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return the numeric IDs of this OID. The value returned is copied to
|
||||
* prevent modification.
|
||||
*
|
||||
* @return The IDs in a new integer array.
|
||||
*/
|
||||
public int[] getIDs()
|
||||
{
|
||||
return (int[]) components.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DER encoding of this OID, minus the tag and length fields.
|
||||
*
|
||||
* @return The DER bytes.
|
||||
*/
|
||||
public byte[] getDER()
|
||||
{
|
||||
if (der == null)
|
||||
{
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
int i = 0;
|
||||
if (!relative)
|
||||
{
|
||||
int b = components[i++] * 40 + (components.length > 1
|
||||
? components[i++] : 0);
|
||||
encodeSubID(bout, b);
|
||||
}
|
||||
for ( ; i < components.length; i++)
|
||||
encodeSubID(bout, components[i]);
|
||||
der = bout.toByteArray();
|
||||
}
|
||||
return (byte[]) der.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent OID of this OID. That is, if this OID is "1.2.3.4",
|
||||
* then the parent OID will be "1.2.3". If this OID is a top-level
|
||||
* OID, this method returns null.
|
||||
*
|
||||
* @return The parent OID, or null.
|
||||
*/
|
||||
public OID getParent()
|
||||
{
|
||||
if (components.length == 1)
|
||||
return null;
|
||||
int[] parent = new int[components.length - 1];
|
||||
System.arraycopy(components, 0, parent, 0, parent.length);
|
||||
return new OID(parent);
|
||||
}
|
||||
|
||||
public OID getChild(int id)
|
||||
{
|
||||
int[] child = new int[components.length + 1];
|
||||
System.arraycopy(components, 0, child, 0, components.length);
|
||||
child[child.length - 1] = id;
|
||||
return new OID(child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root OID of this OID. That is, the first two components.
|
||||
*
|
||||
* @return The root OID.
|
||||
*/
|
||||
public OID getRoot()
|
||||
{
|
||||
if (components.length <= 2)
|
||||
return this;
|
||||
int[] root = new int[2];
|
||||
root[0] = components[0];
|
||||
root[1] = components[1];
|
||||
return new OID(root);
|
||||
}
|
||||
|
||||
public boolean isRelative()
|
||||
{
|
||||
return relative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this OID.
|
||||
*
|
||||
* @return The copy.
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
OID oid = new OID();
|
||||
oid.components = this.components;
|
||||
oid.strRep = this.strRep;
|
||||
return oid;
|
||||
}
|
||||
|
||||
/* Nice idea, but possibly too expensive for whatever benefit it
|
||||
* provides.
|
||||
|
||||
public String getShortName()
|
||||
{
|
||||
return OIDTable.getShortName(this);
|
||||
}
|
||||
|
||||
public String getLongName()
|
||||
{
|
||||
return OIDTable.getLongName(this);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the value of this OID in dotted-decimal format.
|
||||
*
|
||||
* @return The string representation.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
if (strRep != null)
|
||||
return strRep;
|
||||
else
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 0; i < components.length; i++)
|
||||
{
|
||||
buf.append((long) components[i] & 0xFFFFFFFFL);
|
||||
if (i < components.length - 1)
|
||||
buf.append('.');
|
||||
}
|
||||
return (strRep = buf.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hash code for this OID.
|
||||
*
|
||||
* @return The hash code.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
int ret = 0;
|
||||
for (int i = 0; i < components.length; i++)
|
||||
ret += components[i] << (i & 31);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether or not this OID equals another.
|
||||
*
|
||||
* @return Whether or not this OID equals the other.
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (!(o instanceof OID))
|
||||
return false;
|
||||
return java.util.Arrays.equals(components, ((OID) o).components);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this OID to another. The comparison is essentially
|
||||
* lexicographic, where the two OIDs are compared until their
|
||||
* first difference, then that difference is returned. If one OID is
|
||||
* shorter, but all elements equal between the two for the shorter
|
||||
* length, then the shorter OID is lesser than the longer.
|
||||
*
|
||||
* @param o The object to compare.
|
||||
* @return An integer less than, equal to, or greater than zero if
|
||||
* this object is less than, equal to, or greater than the
|
||||
* argument.
|
||||
* @throws ClassCastException If <i>o</i> is not an OID.
|
||||
*/
|
||||
public int compareTo(Object o)
|
||||
{
|
||||
if (equals(o))
|
||||
return 0;
|
||||
int[] components2 = ((OID) o).components;
|
||||
int len = Math.min(components.length, components2.length);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (components[i] != components2[i])
|
||||
return (components[i] < components2[i]) ? -1 : 1;
|
||||
}
|
||||
if (components.length == components2.length)
|
||||
return 0;
|
||||
return (components.length < components2.length) ? -1 : 1;
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static int[] fromDER(byte[] der, boolean relative)
|
||||
throws DEREncodingException
|
||||
{
|
||||
// cannot be longer than this.
|
||||
int[] components = new int[der.length + 1];
|
||||
int count = 0;
|
||||
int i = 0;
|
||||
if (!relative && i < der.length)
|
||||
{
|
||||
// Non-relative OIDs have the first two arcs coded as:
|
||||
//
|
||||
// i = first_arc * 40 + second_arc;
|
||||
//
|
||||
int j = (der[i] & 0xFF);
|
||||
components[count++] = j / 40;
|
||||
components[count++] = j % 40;
|
||||
i++;
|
||||
}
|
||||
while (i < der.length)
|
||||
{
|
||||
int j = 0;
|
||||
do
|
||||
{
|
||||
j = der[i++] & 0xFF;
|
||||
components[count] <<= 7;
|
||||
components[count] |= j & 0x7F;
|
||||
if (i >= der.length && (j & 0x80) != 0)
|
||||
throw new DEREncodingException("malformed OID");
|
||||
}
|
||||
while ((j & 0x80) != 0);
|
||||
count++;
|
||||
}
|
||||
if (count == components.length)
|
||||
return components;
|
||||
int[] ret = new int[count];
|
||||
System.arraycopy(components, 0, ret, 0, count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static int[] fromString(String strRep) throws NumberFormatException
|
||||
{
|
||||
if (strRep.startsWith("OID.") || strRep.startsWith("oid."))
|
||||
strRep = strRep.substring(4);
|
||||
StringTokenizer tok = new StringTokenizer(strRep, ".");
|
||||
if (tok.countTokens() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
int[] components = new int[tok.countTokens()];
|
||||
int i = 0;
|
||||
while (tok.hasMoreTokens())
|
||||
{
|
||||
components[i++] = Integer.parseInt(tok.nextToken());
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
private static void encodeSubID(ByteArrayOutputStream out, int id)
|
||||
{
|
||||
if (id < 128)
|
||||
{
|
||||
out.write(id);
|
||||
}
|
||||
else if (id < 16384)
|
||||
{
|
||||
out.write((id >>> 7) | 0x80);
|
||||
out.write(id & 0x7F);
|
||||
}
|
||||
else if (id < 2097152)
|
||||
{
|
||||
out.write((id >>> 14) | 0x80);
|
||||
out.write(((id >>> 7) | 0x80) & 0xFF);
|
||||
out.write(id & 0x7F);
|
||||
}
|
||||
else if (id < 268435456)
|
||||
{
|
||||
out.write( (id >>> 21) | 0x80);
|
||||
out.write(((id >>> 14) | 0x80) & 0xFF);
|
||||
out.write(((id >>> 7) | 0x80) & 0xFF);
|
||||
out.write(id & 0x7F);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,667 @@
|
||||
/* PolicyFile.java -- policy file reader
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StreamTokenizer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.CodeSource;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.security.Policy;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.Security;
|
||||
import java.security.UnresolvedPermission;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* An implementation of a {@link java.security.Policy} object whose
|
||||
* permissions are specified by a <em>policy file</em>.
|
||||
*
|
||||
* <p>The approximate syntax of policy files is:</p>
|
||||
*
|
||||
* <pre>
|
||||
* policyFile ::= keystoreOrGrantEntries ;
|
||||
*
|
||||
* keystoreOrGrantEntries ::= keystoreOrGrantEntry |
|
||||
* keystoreOrGrantEntries keystoreOrGrantEntry |
|
||||
* EMPTY ;
|
||||
*
|
||||
* keystoreOrGrantEntry ::= keystoreEntry | grantEntry ;
|
||||
*
|
||||
* keystoreEntry ::= "keystore" keystoreUrl ';' |
|
||||
* "keystore" keystoreUrl ',' keystoreAlgorithm ';' ;
|
||||
*
|
||||
* keystoreUrl ::= URL ;
|
||||
* keystoreAlgorithm ::= STRING ;
|
||||
*
|
||||
* grantEntry ::= "grant" domainParameters '{' permissions '}' ';'
|
||||
*
|
||||
* domainParameters ::= domainParameter |
|
||||
* domainParameter ',' domainParameters ;
|
||||
*
|
||||
* domainParameter ::= "signedBy" signerNames |
|
||||
* "codeBase" codeBaseUrl |
|
||||
* "principal" principalClassName principalName |
|
||||
* "principal" principalName ;
|
||||
*
|
||||
* signerNames ::= quotedString ;
|
||||
* codeBaseUrl ::= URL ;
|
||||
* principalClassName ::= STRING ;
|
||||
* principalName ::= quotedString ;
|
||||
*
|
||||
* quotedString ::= quoteChar STRING quoteChar ;
|
||||
* quoteChar ::= '"' | '\'';
|
||||
*
|
||||
* permissions ::= permission | permissions permission ;
|
||||
*
|
||||
* permission ::= "permission" permissionClassName permissionTarget permissionAction |
|
||||
* "permission" permissionClassName permissionTarget |
|
||||
* "permission" permissionClassName;
|
||||
* </pre>
|
||||
*
|
||||
* <p>Comments are either form of Java comments. Keystore entries only
|
||||
* affect subsequent grant entries, so if a grant entry preceeds a
|
||||
* keystore entry, that grant entry is not affected by that keystore
|
||||
* entry. Certian instances of <code>${property-name}</code> will be
|
||||
* replaced with <code>System.getProperty("property-name")</code> in
|
||||
* quoted strings.</p>
|
||||
*
|
||||
* <p>This class will load the following files when created or
|
||||
* refreshed, in order:</p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>The file <code>${java.home}/lib/security/java.policy</code>.</li>
|
||||
* <li>All URLs specified by security properties
|
||||
* <code>"policy.file.<i>n</i>"</code>, for increasing <i>n</i>
|
||||
* starting from 1. The sequence stops at the first undefined
|
||||
* property, so you must set <code>"policy.file.1"</code> if you also
|
||||
* set <code>"policy.file.2"</code>, and so on.</li>
|
||||
* <li>The URL specified by the property
|
||||
* <code>"java.security.policy"</code>.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @author Casey Marshall (csm@gnu.org)
|
||||
* @see java.security.Policy
|
||||
*/
|
||||
public final class PolicyFile extends Policy
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static final boolean DEBUG = true;
|
||||
// Package-private to avoid a trampoline.
|
||||
static void debug(String msg)
|
||||
{
|
||||
System.err.print(">> PolicyFile: ");
|
||||
System.err.println(msg);
|
||||
}
|
||||
|
||||
private static void debug(Throwable t)
|
||||
{
|
||||
System.err.println(">> PolicyFile");
|
||||
t.printStackTrace(System.err);
|
||||
}
|
||||
|
||||
private static final String DEFAULT_POLICY = System.getProperty("java.home")
|
||||
+ System.getProperty("file.separator") + "lib"
|
||||
+ System.getProperty("file.separator") + "security"
|
||||
+ System.getProperty("file.separator") + "java.policy";
|
||||
|
||||
private final Map cs2pc;
|
||||
|
||||
// Constructors.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public PolicyFile()
|
||||
{
|
||||
cs2pc = new HashMap();
|
||||
refresh();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public PermissionCollection getPermissions(CodeSource codeSource)
|
||||
{
|
||||
Permissions perms = new Permissions();
|
||||
for (Iterator it = cs2pc.entrySet().iterator(); it.hasNext(); )
|
||||
{
|
||||
Map.Entry e = (Map.Entry) it.next();
|
||||
CodeSource cs = (CodeSource) e.getKey();
|
||||
if (cs.implies(codeSource))
|
||||
{
|
||||
if (DEBUG) debug(cs+" -> "+codeSource);
|
||||
PermissionCollection pc = (PermissionCollection) e.getValue();
|
||||
for (Enumeration ee = pc.elements(); ee.hasMoreElements(); )
|
||||
{
|
||||
perms.add((Permission) ee.nextElement());
|
||||
}
|
||||
}
|
||||
else
|
||||
if (DEBUG) debug(cs+" !-> "+codeSource);
|
||||
}
|
||||
if (DEBUG) debug ("returning permissions " + perms + " for " + codeSource);
|
||||
return perms;
|
||||
}
|
||||
|
||||
public void refresh()
|
||||
{
|
||||
cs2pc.clear();
|
||||
List policyFiles = new LinkedList();
|
||||
try
|
||||
{
|
||||
policyFiles.add(new File(DEFAULT_POLICY).toURL());
|
||||
if (DEBUG) debug ("defualt policy is " + DEFAULT_POLICY);
|
||||
policyFiles.addAll((List) AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction()
|
||||
{
|
||||
public Object run() throws Exception
|
||||
{
|
||||
LinkedList l = new LinkedList();
|
||||
for (int i = 1; ; i++)
|
||||
{
|
||||
String s = Security.getProperty("policy.file."+i);
|
||||
if (DEBUG) debug("policy.file."+i+"="+s);
|
||||
if (s == null)
|
||||
break;
|
||||
l.add(new URL(s));
|
||||
}
|
||||
String s = System.getProperty("java.security.policy");
|
||||
if (DEBUG) debug("java.security.policy="+s);
|
||||
if (s != null)
|
||||
l.add(new URL(s));
|
||||
return l;
|
||||
}
|
||||
}));
|
||||
}
|
||||
catch (PrivilegedActionException pae)
|
||||
{
|
||||
if (DEBUG) debug(pae);
|
||||
}
|
||||
catch (MalformedURLException mue)
|
||||
{
|
||||
if (DEBUG) debug(mue);
|
||||
}
|
||||
for (Iterator it = policyFiles.iterator(); it.hasNext(); )
|
||||
{
|
||||
try
|
||||
{
|
||||
URL url = (URL) it.next();
|
||||
parse(url);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
if (DEBUG) debug(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return super.toString() + " [ " + cs2pc.toString() + " ]";
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static final int STATE_BEGIN = 0;
|
||||
private static final int STATE_GRANT = 1;
|
||||
private static final int STATE_PERMS = 2;
|
||||
|
||||
/**
|
||||
* Parse a policy file, incorporating the permission definitions
|
||||
* described therein.
|
||||
*
|
||||
* @param url The URL of the policy file to read.
|
||||
* @throws IOException if an I/O error occurs, or if the policy file
|
||||
* cannot be parsed.
|
||||
*/
|
||||
private void parse(final URL url) throws IOException
|
||||
{
|
||||
if (DEBUG) debug ("reading policy file from " + url);
|
||||
final StreamTokenizer in = new StreamTokenizer(new InputStreamReader(url.openStream()));
|
||||
in.resetSyntax();
|
||||
in.slashSlashComments(true);
|
||||
in.slashStarComments(true);
|
||||
in.wordChars('A', 'Z');
|
||||
in.wordChars('a', 'z');
|
||||
in.wordChars('0', '9');
|
||||
in.wordChars('.', '.');
|
||||
in.wordChars('_', '_');
|
||||
in.wordChars('$', '$');
|
||||
in.whitespaceChars(' ', ' ');
|
||||
in.whitespaceChars('\t', '\t');
|
||||
in.whitespaceChars('\f', '\f');
|
||||
in.whitespaceChars('\n', '\n');
|
||||
in.whitespaceChars('\r', '\r');
|
||||
in.quoteChar('\'');
|
||||
in.quoteChar('"');
|
||||
|
||||
int tok;
|
||||
int state = STATE_BEGIN;
|
||||
List keystores = new LinkedList();
|
||||
URL currentBase = null;
|
||||
List currentCerts = new LinkedList();
|
||||
Permissions currentPerms = new Permissions();
|
||||
while ((tok = in.nextToken()) != StreamTokenizer.TT_EOF)
|
||||
{
|
||||
switch (tok)
|
||||
{
|
||||
case '{':
|
||||
if (state != STATE_GRANT)
|
||||
error(url, in, "spurious '{'");
|
||||
state = STATE_PERMS;
|
||||
tok = in.nextToken();
|
||||
break;
|
||||
case '}':
|
||||
if (state != STATE_PERMS)
|
||||
error(url, in, "spurious '}'");
|
||||
state = STATE_BEGIN;
|
||||
currentPerms.setReadOnly();
|
||||
Certificate[] c = null;
|
||||
if (!currentCerts.isEmpty())
|
||||
c = (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()]);
|
||||
cs2pc.put(new CodeSource(currentBase, c), currentPerms);
|
||||
currentCerts.clear();
|
||||
currentPerms = new Permissions();
|
||||
currentBase = null;
|
||||
tok = in.nextToken();
|
||||
if (tok != ';')
|
||||
in.pushBack();
|
||||
continue;
|
||||
}
|
||||
if (tok != StreamTokenizer.TT_WORD)
|
||||
{
|
||||
error(url, in, "expecting word token");
|
||||
}
|
||||
|
||||
// keystore "<keystore-path>" [',' "<keystore-type>"] ';'
|
||||
if (in.sval.equalsIgnoreCase("keystore"))
|
||||
{
|
||||
String alg = KeyStore.getDefaultType();
|
||||
tok = in.nextToken();
|
||||
if (tok != '"' && tok != '\'')
|
||||
error(url, in, "expecting key store URL");
|
||||
String store = in.sval;
|
||||
tok = in.nextToken();
|
||||
if (tok == ',')
|
||||
{
|
||||
tok = in.nextToken();
|
||||
if (tok != '"' && tok != '\'')
|
||||
error(url, in, "expecting key store type");
|
||||
alg = in.sval;
|
||||
tok = in.nextToken();
|
||||
}
|
||||
if (tok != ';')
|
||||
error(url, in, "expecting semicolon");
|
||||
try
|
||||
{
|
||||
KeyStore keystore = KeyStore.getInstance(alg);
|
||||
keystore.load(new URL(url, store).openStream(), null);
|
||||
keystores.add(keystore);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
error(url, in, x.toString());
|
||||
}
|
||||
}
|
||||
else if (in.sval.equalsIgnoreCase("grant"))
|
||||
{
|
||||
if (state != STATE_BEGIN)
|
||||
error(url, in, "extraneous grant keyword");
|
||||
state = STATE_GRANT;
|
||||
}
|
||||
else if (in.sval.equalsIgnoreCase("signedBy"))
|
||||
{
|
||||
if (state != STATE_GRANT && state != STATE_PERMS)
|
||||
error(url, in, "spurious 'signedBy'");
|
||||
if (keystores.isEmpty())
|
||||
error(url, in, "'signedBy' with no keystores");
|
||||
tok = in.nextToken();
|
||||
if (tok != '"' && tok != '\'')
|
||||
error(url, in, "expecting signedBy name");
|
||||
StringTokenizer st = new StringTokenizer(in.sval, ",");
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String alias = st.nextToken();
|
||||
for (Iterator it = keystores.iterator(); it.hasNext(); )
|
||||
{
|
||||
KeyStore keystore = (KeyStore) it.next();
|
||||
try
|
||||
{
|
||||
if (keystore.isCertificateEntry(alias))
|
||||
currentCerts.add(keystore.getCertificate(alias));
|
||||
}
|
||||
catch (KeyStoreException kse)
|
||||
{
|
||||
error(url, in, kse.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
tok = in.nextToken();
|
||||
if (tok != ',')
|
||||
{
|
||||
if (state != STATE_GRANT)
|
||||
error(url, in, "spurious ','");
|
||||
in.pushBack();
|
||||
}
|
||||
}
|
||||
else if (in.sval.equalsIgnoreCase("codeBase"))
|
||||
{
|
||||
if (state != STATE_GRANT)
|
||||
error(url, in, "spurious 'codeBase'");
|
||||
tok = in.nextToken();
|
||||
if (tok != '"' && tok != '\'')
|
||||
error(url, in, "expecting code base URL");
|
||||
String base = expand(in.sval);
|
||||
if (File.separatorChar != '/')
|
||||
base = base.replace(File.separatorChar, '/');
|
||||
try
|
||||
{
|
||||
currentBase = new URL(base);
|
||||
}
|
||||
catch (MalformedURLException mue)
|
||||
{
|
||||
error(url, in, mue.toString());
|
||||
}
|
||||
tok = in.nextToken();
|
||||
if (tok != ',')
|
||||
in.pushBack();
|
||||
}
|
||||
else if (in.sval.equalsIgnoreCase("principal"))
|
||||
{
|
||||
if (state != STATE_GRANT)
|
||||
error(url, in, "spurious 'principal'");
|
||||
tok = in.nextToken();
|
||||
if (tok == StreamTokenizer.TT_WORD)
|
||||
{
|
||||
tok = in.nextToken();
|
||||
if (tok != '"' && tok != '\'')
|
||||
error(url, in, "expecting principal name");
|
||||
String name = in.sval;
|
||||
Principal p = null;
|
||||
try
|
||||
{
|
||||
Class pclass = Class.forName(in.sval);
|
||||
Constructor c =
|
||||
pclass.getConstructor(new Class[] { String.class });
|
||||
p = (Principal) c.newInstance(new Object[] { name });
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
error(url, in, x.toString());
|
||||
}
|
||||
for (Iterator it = keystores.iterator(); it.hasNext(); )
|
||||
{
|
||||
KeyStore ks = (KeyStore) it.next();
|
||||
try
|
||||
{
|
||||
for (Enumeration e = ks.aliases(); e.hasMoreElements(); )
|
||||
{
|
||||
String alias = (String) e.nextElement();
|
||||
if (ks.isCertificateEntry(alias))
|
||||
{
|
||||
Certificate cert = ks.getCertificate(alias);
|
||||
if (!(cert instanceof X509Certificate))
|
||||
continue;
|
||||
if (p.equals(((X509Certificate) cert).getSubjectDN()) ||
|
||||
p.equals(((X509Certificate) cert).getSubjectX500Principal()))
|
||||
currentCerts.add(cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (KeyStoreException kse)
|
||||
{
|
||||
error(url, in, kse.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tok == '"' || tok == '\'')
|
||||
{
|
||||
String alias = in.sval;
|
||||
for (Iterator it = keystores.iterator(); it.hasNext(); )
|
||||
{
|
||||
KeyStore ks = (KeyStore) it.next();
|
||||
try
|
||||
{
|
||||
if (ks.isCertificateEntry(alias))
|
||||
currentCerts.add(ks.getCertificate(alias));
|
||||
}
|
||||
catch (KeyStoreException kse)
|
||||
{
|
||||
error(url, in, kse.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
error(url, in, "expecting principal");
|
||||
tok = in.nextToken();
|
||||
if (tok != ',')
|
||||
in.pushBack();
|
||||
}
|
||||
else if (in.sval.equalsIgnoreCase("permission"))
|
||||
{
|
||||
if (state != STATE_PERMS)
|
||||
error(url, in, "spurious 'permission'");
|
||||
tok = in.nextToken();
|
||||
if (tok != StreamTokenizer.TT_WORD)
|
||||
error(url, in, "expecting permission class name");
|
||||
String className = in.sval;
|
||||
Class clazz = null;
|
||||
try
|
||||
{
|
||||
clazz = Class.forName(className);
|
||||
}
|
||||
catch (ClassNotFoundException cnfe)
|
||||
{
|
||||
}
|
||||
tok = in.nextToken();
|
||||
if (tok == ';')
|
||||
{
|
||||
if (clazz == null)
|
||||
{
|
||||
currentPerms.add(new UnresolvedPermission(className,
|
||||
null, null, (Certificate[]) currentCerts.toArray(new Certificate[0])));
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
currentPerms.add((Permission) clazz.newInstance());
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
error(url, in, x.toString());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (tok != '"' && tok != '\'')
|
||||
error(url, in, "expecting permission target");
|
||||
String target = expand(in.sval);
|
||||
tok = in.nextToken();
|
||||
if (tok == ';')
|
||||
{
|
||||
if (clazz == null)
|
||||
{
|
||||
currentPerms.add(new UnresolvedPermission(className,
|
||||
target, null, (Certificate[]) currentCerts.toArray(new Certificate[0])));
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
Constructor c =
|
||||
clazz.getConstructor(new Class[] { String.class });
|
||||
currentPerms.add((Permission) c.newInstance(
|
||||
new Object[] { target }));
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
error(url, in, x.toString());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (tok != ',')
|
||||
error(url, in, "expecting ','");
|
||||
tok = in.nextToken();
|
||||
if (tok == StreamTokenizer.TT_WORD)
|
||||
{
|
||||
if (!in.sval.equalsIgnoreCase("signedBy"))
|
||||
error(url, in, "expecting 'signedBy'");
|
||||
try
|
||||
{
|
||||
Constructor c =
|
||||
clazz.getConstructor(new Class[] { String.class });
|
||||
currentPerms.add((Permission) c.newInstance(
|
||||
new Object[] { target }));
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
error(url, in, x.toString());
|
||||
}
|
||||
in.pushBack();
|
||||
continue;
|
||||
}
|
||||
if (tok != '"' && tok != '\'')
|
||||
error(url, in, "expecting permission action");
|
||||
String action = in.sval;
|
||||
if (clazz == null)
|
||||
{
|
||||
currentPerms.add(new UnresolvedPermission(className,
|
||||
target, action, (Certificate[]) currentCerts.toArray(new Certificate[0])));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Constructor c = clazz.getConstructor(
|
||||
new Class[] { String.class, String.class });
|
||||
currentPerms.add((Permission) c.newInstance(
|
||||
new Object[] { target, action }));
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
error(url, in, x.toString());
|
||||
}
|
||||
}
|
||||
tok = in.nextToken();
|
||||
if (tok != ';' && tok != ',')
|
||||
error(url, in, "expecting ';' or ','");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand all instances of <code>"${property-name}"</code> into
|
||||
* <code>System.getProperty("property-name")</code>.
|
||||
*/
|
||||
private static String expand(final String s)
|
||||
{
|
||||
final StringBuffer result = new StringBuffer();
|
||||
final StringBuffer prop = new StringBuffer();
|
||||
int state = 0;
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
if (s.charAt(i) == '$')
|
||||
state = 1;
|
||||
else
|
||||
result.append(s.charAt(i));
|
||||
break;
|
||||
case 1:
|
||||
if (s.charAt(i) == '{')
|
||||
state = 2;
|
||||
else
|
||||
{
|
||||
state = 0;
|
||||
result.append('$').append(s.charAt(i));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (s.charAt(i) == '}')
|
||||
{
|
||||
String p = prop.toString();
|
||||
if (p.equals("/"))
|
||||
p = "file.separator";
|
||||
p = System.getProperty(p);
|
||||
if (p == null)
|
||||
p = "";
|
||||
result.append(p);
|
||||
prop.setLength(0);
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
prop.append(s.charAt(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state != 0)
|
||||
result.append('$').append('{').append(prop);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* I miss macros.
|
||||
*/
|
||||
private static void error(URL base, StreamTokenizer in, String msg)
|
||||
throws IOException
|
||||
{
|
||||
throw new IOException(base+":"+in.lineno()+": "+msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/* GetPropertyAction.java
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security.action;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* PrivilegedAction implementation that calls System.getProperty() with
|
||||
* the property name passed to its constructor.
|
||||
*
|
||||
* Example of use:
|
||||
* <code>
|
||||
* GetPropertyAction action = new GetPropertyAction("http.proxyPort");
|
||||
* String port = AccessController.doPrivileged(action);
|
||||
* </code>
|
||||
*/
|
||||
public class GetPropertyAction implements PrivilegedAction
|
||||
{
|
||||
String name;
|
||||
String value = null;
|
||||
|
||||
public GetPropertyAction()
|
||||
{
|
||||
}
|
||||
|
||||
public GetPropertyAction(String propName)
|
||||
{
|
||||
setParameters(propName);
|
||||
}
|
||||
|
||||
public GetPropertyAction(String propName, String defaultValue)
|
||||
{
|
||||
setParameters(propName, defaultValue);
|
||||
}
|
||||
|
||||
public Object run()
|
||||
{
|
||||
return System.getProperty(name, value);
|
||||
}
|
||||
|
||||
public GetPropertyAction setParameters(String propName)
|
||||
{
|
||||
this.name = propName;
|
||||
this.value = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetPropertyAction setParameters(String propName, String defaultValue)
|
||||
{
|
||||
this.name = propName;
|
||||
this.value = defaultValue;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/* GetSecurityPropertyAction.java
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security.action;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.Security;
|
||||
|
||||
/**
|
||||
* PrivilegedAction implementation that calls Security.getProperty()
|
||||
* with the property name passed to its constructor.
|
||||
*
|
||||
* Example of use:
|
||||
* <code>
|
||||
* GetSecurityPropertyAction action = new GetSecurityPropertyAction("javax.net.ssl.trustStorePassword");
|
||||
* String passwd = AccessController.doPrivileged(action);
|
||||
* </code>
|
||||
*/
|
||||
public class GetSecurityPropertyAction implements PrivilegedAction
|
||||
{
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public GetSecurityPropertyAction()
|
||||
{
|
||||
}
|
||||
|
||||
public GetSecurityPropertyAction(String propName)
|
||||
{
|
||||
setParameters(propName);
|
||||
}
|
||||
|
||||
public GetSecurityPropertyAction(String propName, String defaultValue)
|
||||
{
|
||||
setParameters(propName, defaultValue);
|
||||
}
|
||||
|
||||
public GetSecurityPropertyAction setParameters(String propName)
|
||||
{
|
||||
this.name = propName;
|
||||
this.value = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetSecurityPropertyAction setParameters(String propName, String defaultValue)
|
||||
{
|
||||
this.name = propName;
|
||||
this.value = defaultValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object run()
|
||||
{
|
||||
String val = Security.getProperty(name);
|
||||
if (val == null)
|
||||
val = value;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* SetAccessibleAction.java
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security.action;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* PrivilegedAction implementation that calls setAccessible(true) on the
|
||||
* AccessibleObject passed to its constructor.
|
||||
*
|
||||
* Example of use:
|
||||
* <code>
|
||||
* Field dataField = cl.getDeclaredField("data");
|
||||
* AccessController.doPrivileged(new SetAccessibleAction(dataField));
|
||||
* </code>
|
||||
*/
|
||||
public class SetAccessibleAction implements PrivilegedAction
|
||||
{
|
||||
AccessibleObject member;
|
||||
|
||||
public SetAccessibleAction()
|
||||
{
|
||||
}
|
||||
|
||||
public SetAccessibleAction(AccessibleObject member)
|
||||
{
|
||||
this.member = member;
|
||||
}
|
||||
|
||||
public Object run()
|
||||
{
|
||||
member.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
public SetAccessibleAction setMember(AccessibleObject member)
|
||||
{
|
||||
this.member = member;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.action package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.action</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,46 @@
|
||||
/* BER.java -- basic encoding rules (BER) constants.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.ber;
|
||||
|
||||
import gnu.java.security.der.DER;
|
||||
|
||||
public interface BER extends DER
|
||||
{
|
||||
BERValue END_OF_SEQUENCE = new BERValue(0, null);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* BEREncodingException.java --- BER Encoding Exception
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.ber;
|
||||
|
||||
import gnu.java.security.der.DEREncodingException;
|
||||
|
||||
public class BEREncodingException extends DEREncodingException
|
||||
{
|
||||
public BEREncodingException()
|
||||
{
|
||||
super ();
|
||||
}
|
||||
|
||||
public BEREncodingException (String msg)
|
||||
{
|
||||
super (msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/* BERReader.java -- basic encoding rules (BER) reader.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.ber;
|
||||
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class BERReader extends DERReader implements BER
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a new DER reader from a byte array.
|
||||
*
|
||||
* @param in The encoded bytes.
|
||||
*/
|
||||
public BERReader(byte[] in)
|
||||
{
|
||||
super(in);
|
||||
}
|
||||
|
||||
public BERReader (byte[] in, int off, int len)
|
||||
{
|
||||
super(in, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DER readed from an input stream.
|
||||
*
|
||||
* @param in The encoded bytes.
|
||||
*/
|
||||
public BERReader(InputStream in)
|
||||
{
|
||||
super(in);
|
||||
}
|
||||
|
||||
public DERValue read() throws IOException
|
||||
{
|
||||
in.mark(2);
|
||||
int tag = in.read();
|
||||
if (tag == -1)
|
||||
throw new EOFException();
|
||||
int length = in.read();
|
||||
if (length == 0)
|
||||
{
|
||||
if (tag == 0)
|
||||
return END_OF_SEQUENCE;
|
||||
return new BERValue(tag, CONSTRUCTED_VALUE, new byte[] { (byte) tag, 0 });
|
||||
}
|
||||
else
|
||||
{
|
||||
in.reset();
|
||||
return super.read();
|
||||
}
|
||||
}
|
||||
|
||||
public int peek() throws IOException
|
||||
{
|
||||
in.mark(1);
|
||||
int ret = in.read();
|
||||
in.reset();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/* BERReader.java -- basic encoding rules (BER) value.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.ber;
|
||||
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
public class BERValue extends DERValue
|
||||
{
|
||||
|
||||
private boolean indefinite;
|
||||
|
||||
public BERValue(int tag, Object value, byte[] encoded)
|
||||
{
|
||||
super(tag, 0, value, encoded);
|
||||
indefinite = true;
|
||||
}
|
||||
|
||||
public BERValue(int tag, int length, Object value, byte[] encoded)
|
||||
{
|
||||
super(tag, length, value, encoded);
|
||||
}
|
||||
|
||||
public BERValue(int tag, Object value)
|
||||
{
|
||||
super(tag, 0, value, null);
|
||||
}
|
||||
|
||||
public static boolean isIndefinite(DERValue value)
|
||||
{
|
||||
if (value instanceof BERValue)
|
||||
return ((BERValue) value).getIndefinite();
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean getIndefinite()
|
||||
{
|
||||
return indefinite;
|
||||
}
|
||||
|
||||
public int getLength()
|
||||
{
|
||||
if (indefinite)
|
||||
return 0;
|
||||
return super.getLength();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.ber package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.ber</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,317 @@
|
||||
/* BitString.java -- Java representation of the BIT STRING type.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.der;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Immutable representation of a bit string, which is equivalent to a
|
||||
* byte array except some number of the rightmost bits are ignored. For
|
||||
* example, this could be the bit string:
|
||||
*
|
||||
* <pre> 00010101 11101101 11010xxx</pre>
|
||||
*
|
||||
* <p>Where the "xxx" represents three bits that should be ignored, and
|
||||
* can have any value.
|
||||
*
|
||||
* @author Casey Marshall (csm@gnu.org)
|
||||
*/
|
||||
public class BitString implements Cloneable, Comparable
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** The bits themselves. */
|
||||
private final byte[] bytes;
|
||||
|
||||
/**
|
||||
* The exportable byte array. This array has the ignored bits
|
||||
* removed.
|
||||
*/
|
||||
private transient byte[] externBytes;
|
||||
|
||||
/** The number of bits ignored at the end of the byte array. */
|
||||
private final int ignoredBits;
|
||||
|
||||
/** This bit string as a boolean array. */
|
||||
private transient boolean[] boolVal;
|
||||
|
||||
// Constructors.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new bit string, shifting the given byte array if needed.
|
||||
*
|
||||
* @param bytes The byte array holding the bit string.
|
||||
* @param ignoredBits The number of bits to ignore.
|
||||
* @param doShift Pass true in this parameter if the byte array has
|
||||
* not yet been shifted left by <i>ignoredBits</i>.
|
||||
* @throws IllegalArgumentException If <i>ignoredBits</i> is negative
|
||||
* or greater than 7.
|
||||
* @throws NullPointerException If <i>bytes</i> is null.
|
||||
*/
|
||||
public BitString(byte[] bytes, int ignoredBits, boolean doShift)
|
||||
{
|
||||
this(bytes, 0, bytes.length, ignoredBits, doShift);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bit string, shifting the given byte array if needed.
|
||||
*
|
||||
* @param bytes The byte array holding the bit string.
|
||||
* @param offset The offset where the meaningful bytes begin.
|
||||
* @param length The number of meaningful bytes.
|
||||
* @param ignoredBits The number of bits to ignore.
|
||||
* @param doShift Pass true in this parameter if the byte array has
|
||||
* not yet been shifted left by <i>ignoredBits</i>.
|
||||
* @throws IllegalArgumentException If <i>ignoredBits</i> is negative
|
||||
* or greater than 7.
|
||||
* @throws NullPointerException If <i>bytes</i> is null.
|
||||
*/
|
||||
public BitString(byte[] bytes, int offset, int length,
|
||||
int ignoredBits, boolean doShift)
|
||||
{
|
||||
if (ignoredBits < 0 || ignoredBits > 7)
|
||||
throw new IllegalArgumentException();
|
||||
if (bytes == null)
|
||||
throw new NullPointerException();
|
||||
if (doShift && ignoredBits > 0)
|
||||
{
|
||||
this.externBytes = new byte[length];
|
||||
System.arraycopy(bytes, offset, externBytes, 0, length);
|
||||
this.bytes = new BigInteger(externBytes).shiftLeft(ignoredBits)
|
||||
.toByteArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.bytes = new byte[length];
|
||||
System.arraycopy(bytes, offset, this.bytes, 0, length);
|
||||
}
|
||||
this.ignoredBits = ignoredBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bit string.
|
||||
*
|
||||
* @param bytes The byte array holding the bit string.
|
||||
* @param offset The offset where the meaningful bytes begin.
|
||||
* @param length The number of meaningful bytes.
|
||||
* @param ignoredBits The number of bits to ignore.
|
||||
* @throws IllegalArgumentException If <i>ignoredBits</i> is negative
|
||||
* or greater than 7.
|
||||
* @throws NullPointerException If <i>bytes</i> is null.
|
||||
*/
|
||||
public BitString(byte[] bytes, int offset, int length, int ignoredBits)
|
||||
{
|
||||
this(bytes, offset, length, ignoredBits, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bit string.
|
||||
*
|
||||
* @param bytes The byte array holding the bit string.
|
||||
* @param ignoredBits The number of bits to ignore.
|
||||
* @throws IllegalArgumentException If <i>ignoredBits</i> is negative
|
||||
* or greater than 7.
|
||||
* @throws NullPointerException If <i>bytes</i> is null.
|
||||
*/
|
||||
public BitString(byte[] bytes, int ignoredBits)
|
||||
{
|
||||
this(bytes, 0, bytes.length, ignoredBits, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bit string.
|
||||
*
|
||||
* @param bytes The byte array holding the bit string.
|
||||
* @param offset The offset where the meaningful bytes begin.
|
||||
* @param length The number of meaningful bytes.
|
||||
* @throws NullPointerException If <i>bytes</i> is null.
|
||||
*/
|
||||
public BitString(byte[] bytes, int offset, int length)
|
||||
{
|
||||
this(bytes, offset, length, 0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bit string.
|
||||
*
|
||||
* @param bytes The byte array holding the bit string.
|
||||
* @throws NullPointerException If <i>bytes</i> is null.
|
||||
*/
|
||||
public BitString(byte[] bytes)
|
||||
{
|
||||
this(bytes, 0, bytes.length, 0, false);
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return this bit string as a byte array, with the ignored bits
|
||||
* trimmed off. The byte array is cloned every time this method is
|
||||
* called to prevent modification.
|
||||
*
|
||||
* @return The trimmed byte array.
|
||||
*/
|
||||
public byte[] toByteArray()
|
||||
{
|
||||
if (ignoredBits == 0)
|
||||
return (byte[]) bytes.clone();
|
||||
if (externBytes == null)
|
||||
externBytes = new BigInteger(bytes).shiftRight(ignoredBits).toByteArray();
|
||||
return (byte[]) externBytes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this bit string as a byte array, with the ignored bits
|
||||
* present. The byte array is cloned every time this method is
|
||||
* called to prevent modification.
|
||||
*
|
||||
* @return The byte array.
|
||||
*/
|
||||
public byte[] getShiftedByteArray()
|
||||
{
|
||||
return (byte[]) bytes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of ignored bits.
|
||||
*
|
||||
* @return The number of ignored bits.
|
||||
*/
|
||||
public int getIgnoredBits()
|
||||
{
|
||||
return ignoredBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size, in bits, of this bit string.
|
||||
*
|
||||
* @return The size of this bit string.
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return (bytes.length << 3) - ignoredBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this bit string as a boolean array. The value returned is of
|
||||
* size {@link #size()}, and each <code>true</code> value
|
||||
* corresponding to each "1" in this bit string. The boolean array is
|
||||
* cloned before it is returned.
|
||||
*
|
||||
* @return The boolean array.
|
||||
*/
|
||||
public boolean[] toBooleanArray()
|
||||
{
|
||||
if (boolVal == null)
|
||||
{
|
||||
boolVal = new boolean[size()];
|
||||
for (int i = 0, j = 7, k = 0; i < boolVal.length; i++)
|
||||
{
|
||||
boolVal[i] = (bytes[k] & 1 << j--) != 0;
|
||||
if (j < 0)
|
||||
{
|
||||
j = 7;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (boolean[]) boolVal.clone();
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException cce)
|
||||
{
|
||||
throw new InternalError(cce.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public int compareTo(Object o)
|
||||
{
|
||||
BitString that = (BitString) o;
|
||||
if (this.equals(that))
|
||||
return 0;
|
||||
if (this.bytes.length != that.bytes.length)
|
||||
return (this.bytes.length < that.bytes.length) ? -1 : 1;
|
||||
if (this.ignoredBits != that.ignoredBits)
|
||||
return (this.ignoredBits < that.ignoredBits) ? -1 : 1;
|
||||
for (int i = 0; i < this.bytes.length; i++)
|
||||
if (this.bytes[i] != that.bytes[i])
|
||||
return (this.bytes[i] < that.bytes[i]) ? -1 : 1;
|
||||
return 0; // not reached.
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (!(o instanceof BitString))
|
||||
return false;
|
||||
BitString that = (BitString) o;
|
||||
// True for cloned instances.
|
||||
if (this.bytes == that.bytes && this.ignoredBits == that.ignoredBits)
|
||||
return true;
|
||||
if (this.ignoredBits == that.ignoredBits)
|
||||
return Arrays.equals(this.bytes, that.bytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, j = 7, k = 0; i < size(); i++)
|
||||
{
|
||||
sb.append((bytes[k] & 1 << j) != 0 ? "1" : "0");
|
||||
j--;
|
||||
if (j < 0)
|
||||
{
|
||||
j = 7;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/* DER.java -- Basic constants in DER sequences.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.der;
|
||||
|
||||
/**
|
||||
* The set of tags for DER types.
|
||||
*
|
||||
* @author Casey Marshall (csm@gnu.org)
|
||||
*/
|
||||
public interface DER
|
||||
{
|
||||
int UNIVERSAL = 0x00;
|
||||
int APPLICATION = 0x40;
|
||||
int CONTEXT = 0x80;
|
||||
int PRIVATE = 0xC0;
|
||||
|
||||
int CONSTRUCTED = 0x20;
|
||||
|
||||
int ANY = 0x00;
|
||||
int BOOLEAN = 0x01;
|
||||
int INTEGER = 0x02;
|
||||
int BIT_STRING = 0x03;
|
||||
int OCTET_STRING = 0x04;
|
||||
int NULL = 0x05;
|
||||
int OBJECT_IDENTIFIER = 0x06;
|
||||
int REAL = 0x09;
|
||||
int ENUMERATED = 0x0a;
|
||||
int RELATIVE_OID = 0x0d;
|
||||
|
||||
int SEQUENCE = 0x10;
|
||||
int SET = 0x11;
|
||||
|
||||
Object CONSTRUCTED_VALUE = new Object();
|
||||
|
||||
int NUMERIC_STRING = 0x12;
|
||||
int PRINTABLE_STRING = 0x13;
|
||||
int T61_STRING = 0x14;
|
||||
int VIDEOTEX_STRING = 0x15;
|
||||
int IA5_STRING = 0x16;
|
||||
int GRAPHIC_STRING = 0x19;
|
||||
int ISO646_STRING = 0x1A;
|
||||
int GENERAL_STRING = 0x1B;
|
||||
|
||||
int UTF8_STRING = 0x0C;
|
||||
int UNIVERSAL_STRING = 0x1C;
|
||||
int BMP_STRING = 0x1E;
|
||||
|
||||
int UTC_TIME = 0x17;
|
||||
int GENERALIZED_TIME = 0x18;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* DEREncodingException.java --- DER Encoding Exception
|
||||
Copyright (C) 1999,2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.der;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DEREncodingException extends IOException
|
||||
{
|
||||
public DEREncodingException()
|
||||
{
|
||||
super ();
|
||||
}
|
||||
|
||||
public DEREncodingException (String msg)
|
||||
{
|
||||
super (msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
/* DERReader.java -- parses ASN.1 DER sequences
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.der;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* This class decodes DER sequences into Java objects. The methods of
|
||||
* this class do not have knowledge of higher-levels of structure in the
|
||||
* DER stream -- such as ASN.1 constructions -- and it is therefore up
|
||||
* to the calling application to determine if the data are structured
|
||||
* properly by inspecting the {@link DERValue} that is returned.
|
||||
*
|
||||
* @author Casey Marshall (csm@gnu.org)
|
||||
*/
|
||||
public class DERReader implements DER
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
protected InputStream in;
|
||||
|
||||
protected final ByteArrayOutputStream encBuf;
|
||||
|
||||
// Constructor.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new DER reader from a byte array.
|
||||
*
|
||||
* @param in The encoded bytes.
|
||||
*/
|
||||
public DERReader(byte[] in)
|
||||
{
|
||||
this(new ByteArrayInputStream(in));
|
||||
}
|
||||
|
||||
public DERReader (byte[] in, int off, int len)
|
||||
{
|
||||
this (new ByteArrayInputStream (in, off, len));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DER readed from an input stream.
|
||||
*
|
||||
* @param in The encoded bytes.
|
||||
*/
|
||||
public DERReader(InputStream in)
|
||||
{
|
||||
if (!in.markSupported())
|
||||
this.in = new BufferedInputStream(in, 16384);
|
||||
else
|
||||
this.in = in;
|
||||
encBuf = new ByteArrayOutputStream(2048);
|
||||
}
|
||||
|
||||
// Class methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Convenience method for reading a single primitive value from the
|
||||
* given byte array.
|
||||
*
|
||||
* @param encoded The encoded bytes.
|
||||
* @throws IOException If the bytes do not represent an encoded
|
||||
* object.
|
||||
*/
|
||||
public static DERValue read(byte[] encoded) throws IOException
|
||||
{
|
||||
return new DERReader(encoded).read();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public void skip (int bytes) throws IOException
|
||||
{
|
||||
in.skip (bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a single value from the input stream, returning it in a new
|
||||
* {@link DERValue}. By "single value" we mean any single type in its
|
||||
* entirety -- including constructed types such as SEQUENCE and all
|
||||
* the values they contain. Usually it is sufficient to call this
|
||||
* method once to parse and return the top-level structure, then to
|
||||
* inspect the returned value for the proper contents.
|
||||
*
|
||||
* @return The parsed DER structure.
|
||||
* @throws IOException If an error occurs reading from the input
|
||||
* stream.
|
||||
* @throws DEREncodingException If the input does not represent a
|
||||
* valid DER stream.
|
||||
*/
|
||||
public DERValue read() throws IOException
|
||||
{
|
||||
int tag = in.read();
|
||||
if (tag == -1)
|
||||
throw new EOFException();
|
||||
encBuf.write(tag);
|
||||
int len = readLength();
|
||||
DERValue value = null;
|
||||
if ((tag & CONSTRUCTED) == CONSTRUCTED)
|
||||
{
|
||||
in.mark(2048);
|
||||
byte[] encoded = new byte[len];
|
||||
in.read(encoded);
|
||||
encBuf.write(encoded);
|
||||
value = new DERValue(tag, len, CONSTRUCTED_VALUE, encBuf.toByteArray());
|
||||
in.reset();
|
||||
encBuf.reset();
|
||||
return value;
|
||||
}
|
||||
switch (tag & 0xC0)
|
||||
{
|
||||
case UNIVERSAL:
|
||||
value = new DERValue(tag, len, readUniversal(tag, len),
|
||||
encBuf.toByteArray());
|
||||
encBuf.reset();
|
||||
break;
|
||||
case CONTEXT:
|
||||
byte[] encoded = new byte[len];
|
||||
in.read(encoded);
|
||||
encBuf.write(encoded);
|
||||
value = new DERValue(tag, len, encoded, encBuf.toByteArray());
|
||||
encBuf.reset();
|
||||
break;
|
||||
case APPLICATION:
|
||||
// This should not be reached, since (I think) APPLICATION is
|
||||
// always constructed.
|
||||
throw new DEREncodingException("non-constructed APPLICATION data");
|
||||
default:
|
||||
throw new DEREncodingException("PRIVATE class not supported");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected int readLength() throws IOException
|
||||
{
|
||||
int i = in.read();
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
encBuf.write(i);
|
||||
if ((i & ~0x7F) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
else if (i < 0xFF)
|
||||
{
|
||||
byte[] octets = new byte[i & 0x7F];
|
||||
in.read(octets);
|
||||
encBuf.write(octets);
|
||||
return new BigInteger(1, octets).intValue();
|
||||
}
|
||||
throw new DEREncodingException();
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private Object readUniversal(int tag, int len) throws IOException
|
||||
{
|
||||
byte[] value = new byte[len];
|
||||
in.read(value);
|
||||
encBuf.write(value);
|
||||
switch (tag & 0x1F)
|
||||
{
|
||||
case BOOLEAN:
|
||||
if (value.length != 1)
|
||||
throw new DEREncodingException();
|
||||
return Boolean.valueOf(value[0] != 0);
|
||||
case NULL:
|
||||
if (len != 0)
|
||||
throw new DEREncodingException();
|
||||
return null;
|
||||
case INTEGER:
|
||||
case ENUMERATED:
|
||||
return new BigInteger(value);
|
||||
case BIT_STRING:
|
||||
byte[] bits = new byte[len - 1];
|
||||
System.arraycopy(value, 1, bits, 0, bits.length);
|
||||
return new BitString(bits, value[0] & 0xFF);
|
||||
case OCTET_STRING:
|
||||
return value;
|
||||
case NUMERIC_STRING:
|
||||
case PRINTABLE_STRING:
|
||||
case T61_STRING:
|
||||
case VIDEOTEX_STRING:
|
||||
case IA5_STRING:
|
||||
case GRAPHIC_STRING:
|
||||
case ISO646_STRING:
|
||||
case GENERAL_STRING:
|
||||
case UNIVERSAL_STRING:
|
||||
case BMP_STRING:
|
||||
case UTF8_STRING:
|
||||
return makeString(tag, value);
|
||||
case UTC_TIME:
|
||||
case GENERALIZED_TIME:
|
||||
return makeTime(tag, value);
|
||||
case OBJECT_IDENTIFIER:
|
||||
return new OID(value);
|
||||
case RELATIVE_OID:
|
||||
return new OID(value, true);
|
||||
default:
|
||||
throw new DEREncodingException("unknown tag " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
private static String makeString(int tag, byte[] value)
|
||||
throws IOException
|
||||
{
|
||||
switch (tag & 0x1F)
|
||||
{
|
||||
case NUMERIC_STRING:
|
||||
case PRINTABLE_STRING:
|
||||
case T61_STRING:
|
||||
case VIDEOTEX_STRING:
|
||||
case IA5_STRING:
|
||||
case GRAPHIC_STRING:
|
||||
case ISO646_STRING:
|
||||
case GENERAL_STRING:
|
||||
return fromIso88591(value);
|
||||
|
||||
case UNIVERSAL_STRING:
|
||||
// XXX The docs say UniversalString is encoded in four bytes
|
||||
// per character, but Java has no support (yet) for UTF-32.
|
||||
//return new String(buf, "UTF-32");
|
||||
case BMP_STRING:
|
||||
return fromUtf16Be(value);
|
||||
|
||||
case UTF8_STRING:
|
||||
return fromUtf8(value);
|
||||
|
||||
default:
|
||||
throw new DEREncodingException("unknown string tag");
|
||||
}
|
||||
}
|
||||
|
||||
private static String fromIso88591(byte[] bytes)
|
||||
{
|
||||
StringBuffer str = new StringBuffer(bytes.length);
|
||||
for (int i = 0; i < bytes.length; i++)
|
||||
str.append((char) (bytes[i] & 0xFF));
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
private static String fromUtf16Be(byte[] bytes) throws IOException
|
||||
{
|
||||
if ((bytes.length & 0x01) != 0)
|
||||
throw new IOException("UTF-16 bytes are odd in length");
|
||||
StringBuffer str = new StringBuffer(bytes.length / 2);
|
||||
for (int i = 0; i < bytes.length; i += 2)
|
||||
{
|
||||
char c = (char) ((bytes[i] << 8) & 0xFF);
|
||||
c |= (char) (bytes[i+1] & 0xFF);
|
||||
str.append(c);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
private static String fromUtf8(byte[] bytes) throws IOException
|
||||
{
|
||||
StringBuffer str = new StringBuffer((int)(bytes.length / 1.5));
|
||||
for (int i = 0; i < bytes.length; )
|
||||
{
|
||||
char c = 0;
|
||||
if ((bytes[i] & 0xE0) == 0xE0)
|
||||
{
|
||||
if ((i + 2) >= bytes.length)
|
||||
throw new IOException("short UTF-8 input");
|
||||
c = (char) ((bytes[i++] & 0x0F) << 12);
|
||||
if ((bytes[i] & 0x80) != 0x80)
|
||||
throw new IOException("malformed UTF-8 input");
|
||||
c |= (char) ((bytes[i++] & 0x3F) << 6);
|
||||
if ((bytes[i] & 0x80) != 0x80)
|
||||
throw new IOException("malformed UTF-8 input");
|
||||
c |= (char) (bytes[i++] & 0x3F);
|
||||
}
|
||||
else if ((bytes[i] & 0xC0) == 0xC0)
|
||||
{
|
||||
if ((i + 1) >= bytes.length)
|
||||
throw new IOException("short input");
|
||||
c = (char) ((bytes[i++] & 0x1F) << 6);
|
||||
if ((bytes[i] & 0x80) != 0x80)
|
||||
throw new IOException("malformed UTF-8 input");
|
||||
c |= (char) (bytes[i++] & 0x3F);
|
||||
}
|
||||
else if ((bytes[i] & 0xFF) < 0x80)
|
||||
{
|
||||
c = (char) (bytes[i++] & 0xFF);
|
||||
}
|
||||
else
|
||||
throw new IOException("badly formed UTF-8 sequence");
|
||||
str.append(c);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
private Date makeTime(int tag, byte[] value) throws IOException
|
||||
{
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
String str = makeString(PRINTABLE_STRING, value);
|
||||
|
||||
// Classpath's SimpleDateFormat does not work for parsing these
|
||||
// types of times, so we do this by hand.
|
||||
String date = str;
|
||||
String tz = "";
|
||||
if (str.indexOf("+") > 0)
|
||||
{
|
||||
date = str.substring(0, str.indexOf("+"));
|
||||
tz = str.substring(str.indexOf("+"));
|
||||
}
|
||||
else if (str.indexOf("-") > 0)
|
||||
{
|
||||
date = str.substring(0, str.indexOf("-"));
|
||||
tz = str.substring(str.indexOf("-"));
|
||||
}
|
||||
else if (str.endsWith("Z"))
|
||||
{
|
||||
date = str.substring(0, str.length()-2);
|
||||
tz = "Z";
|
||||
}
|
||||
if (!tz.equals("Z") && tz.length() > 0)
|
||||
calendar.setTimeZone(TimeZone.getTimeZone(tz));
|
||||
else
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
if ((tag & 0x1F) == UTC_TIME)
|
||||
{
|
||||
if (date.length() < 10) // must be at least 10 chars long
|
||||
throw new DEREncodingException("cannot parse date");
|
||||
// UTCTime is of the form "yyMMddHHmm[ss](Z|(+|-)hhmm)"
|
||||
try
|
||||
{
|
||||
int year = Integer.parseInt(str.substring(0, 2));
|
||||
if (year < 50)
|
||||
year += 2000;
|
||||
else
|
||||
year += 1900;
|
||||
calendar.set(year,
|
||||
Integer.parseInt(str.substring( 2, 4))-1, // month
|
||||
Integer.parseInt(str.substring( 4, 6)), // day
|
||||
Integer.parseInt(str.substring( 6, 8)), // hour
|
||||
Integer.parseInt(str.substring( 8, 10))); // minute
|
||||
if (date.length() == 12);
|
||||
calendar.set(Calendar.SECOND,
|
||||
Integer.parseInt(str.substring(10, 12)));
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
throw new DEREncodingException("cannot parse date");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (date.length() < 10) // must be at least 10 chars long
|
||||
throw new DEREncodingException("cannot parse date");
|
||||
// GeneralTime is of the form "yyyyMMddHH[mm[ss[(.|,)SSSS]]]"
|
||||
// followed by "Z" or "(+|-)hh[mm]"
|
||||
try
|
||||
{
|
||||
calendar.set(
|
||||
Integer.parseInt(date.substring(0, 4)), // year
|
||||
Integer.parseInt(date.substring(4, 6))-1, // month
|
||||
Integer.parseInt(date.substring(6, 8)), // day
|
||||
Integer.parseInt(date.substring(8, 10)), 0); // hour, min
|
||||
switch (date.length())
|
||||
{
|
||||
case 19:
|
||||
case 18:
|
||||
case 17:
|
||||
case 16:
|
||||
calendar.set(Calendar.MILLISECOND,
|
||||
Integer.parseInt(date.substring(15)));
|
||||
case 14:
|
||||
calendar.set(Calendar.SECOND,
|
||||
Integer.parseInt(date.substring(12, 14)));
|
||||
case 12:
|
||||
calendar.set(Calendar.MINUTE,
|
||||
Integer.parseInt(date.substring(10, 12)));
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
throw new DEREncodingException("cannot parse date");
|
||||
}
|
||||
}
|
||||
return calendar.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/* DERValue.java -- a value read or written to a DER encoding.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.der;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DERValue implements DER
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private final int tagClass;
|
||||
private final boolean constructed;
|
||||
private final int tag;
|
||||
private int length;
|
||||
private final Object value;
|
||||
private byte[] encoded;
|
||||
|
||||
// Constructor.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public DERValue(int tag, int length, Object value, byte[] encoded)
|
||||
{
|
||||
tagClass = tag & 0xC0;
|
||||
this.tag = tag & 0x1F;
|
||||
constructed = (tag & CONSTRUCTED) == CONSTRUCTED;
|
||||
this.length = length;
|
||||
this.value = value;
|
||||
if (encoded != null)
|
||||
this.encoded = (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public DERValue(int tag, Object value)
|
||||
{
|
||||
this(tag, 0, value, null);
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public int getExternalTag()
|
||||
{
|
||||
return tagClass | tag | (constructed ? 0x20 : 0x00);
|
||||
}
|
||||
|
||||
public int getTag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
||||
public int getTagClass()
|
||||
{
|
||||
return tagClass;
|
||||
}
|
||||
|
||||
public boolean isConstructed()
|
||||
{
|
||||
return constructed;
|
||||
}
|
||||
|
||||
public int getLength()
|
||||
{
|
||||
if (encoded == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
length = DERWriter.write(out, this);
|
||||
encoded = out.toByteArray();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
encoded = new byte[0];
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
public Object getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object getValueAs (final int derType) throws IOException
|
||||
{
|
||||
byte[] encoded = getEncoded ();
|
||||
encoded[0] = (byte) derType;
|
||||
return DERReader.read (encoded).getValue ();
|
||||
}
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encoded == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
length = DERWriter.write(out, this);
|
||||
encoded = out.toByteArray();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
encoded = new byte[0];
|
||||
}
|
||||
}
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public int getEncodedLength()
|
||||
{
|
||||
if (encoded == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
length = DERWriter.write(out, this);
|
||||
encoded = out.toByteArray();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
encoded = new byte[0];
|
||||
}
|
||||
}
|
||||
return encoded.length;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "DERValue [ tag=" + tag + ", class=" + tagClass + ", constructed="
|
||||
+ constructed + ", value=" + value + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/* DERWriter.java -- write Java types in DER format.
|
||||
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.der;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Methods that allow various Java types to be written as a DER
|
||||
* (Distinguished Encoding Rules) stream to the specified output stream.
|
||||
* DER is used to encode ASN.1 constructions, but this class provides no
|
||||
* methods for interacting with ASN.1. Rather, callers should construct
|
||||
* their output objects properly for whatever ASN.1 construct is being
|
||||
* output.
|
||||
*
|
||||
* <p>This class only defines static methods; there are no instance
|
||||
* variables needed.
|
||||
*
|
||||
* @author Casey Marshall (csm@gnu.org)
|
||||
*/
|
||||
public class DERWriter implements DER
|
||||
{
|
||||
|
||||
// Constructors.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** This class only has static methods. */
|
||||
private DERWriter()
|
||||
{
|
||||
}
|
||||
|
||||
// Class methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public static int write(OutputStream out, DERValue object)
|
||||
throws IOException
|
||||
{
|
||||
out.write(object.getExternalTag());
|
||||
Object value = object.getValue();
|
||||
if (value == null)
|
||||
{
|
||||
writeLength(out, 0);
|
||||
return 0;
|
||||
}
|
||||
if (value instanceof Boolean)
|
||||
return writeBoolean(out, (Boolean) value);
|
||||
else if (value instanceof BigInteger)
|
||||
return writeInteger(out, (BigInteger) value);
|
||||
else if (value instanceof Date)
|
||||
return writeDate(out, object.getExternalTag(), (Date) value);
|
||||
else if (value instanceof String)
|
||||
return writeString(out, object.getExternalTag(), (String) value);
|
||||
else if (value instanceof List)
|
||||
return writeSequence(out, (List) value);
|
||||
else if (value instanceof Set)
|
||||
return writeSet(out, (Set) value);
|
||||
else if (value instanceof BitString)
|
||||
return writeBitString(out, (BitString) value);
|
||||
else if (value instanceof OID)
|
||||
return writeOID(out, (OID) value);
|
||||
else if (value instanceof byte[])
|
||||
{
|
||||
writeLength(out, ((byte[]) value).length);
|
||||
out.write((byte[]) value);
|
||||
return ((byte[]) value).length;
|
||||
}
|
||||
else if (value instanceof DERValue)
|
||||
{
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
write(bout, (DERValue) value);
|
||||
byte[] buf = bout.toByteArray();
|
||||
writeLength(out, buf.length);
|
||||
out.write(buf);
|
||||
return buf.length;
|
||||
}
|
||||
else
|
||||
throw new DEREncodingException("cannot encode " + value.getClass().getName());
|
||||
}
|
||||
|
||||
public static int definiteEncodingSize(int length)
|
||||
{
|
||||
if (length < 128)
|
||||
return 1;
|
||||
else if (length < 256)
|
||||
return 2;
|
||||
else if (length < 65536)
|
||||
return 3;
|
||||
else if (length < 16777216)
|
||||
return 4;
|
||||
else
|
||||
return 5;
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Write a BOOLEAN type to the given output stream.
|
||||
*
|
||||
* @param out The sink output stream.
|
||||
* @param b The boolean value to write.
|
||||
*/
|
||||
private static int writeBoolean(OutputStream out, Boolean b)
|
||||
throws IOException
|
||||
{
|
||||
writeLength(out, 1);
|
||||
if (b.booleanValue())
|
||||
out.write(0xFF);
|
||||
else
|
||||
out.write(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an INTEGER type to the given output stream.
|
||||
*
|
||||
* @param out The sink output stream.
|
||||
* @param integer The integer to write.
|
||||
*/
|
||||
private static int writeInteger(OutputStream out, BigInteger integer)
|
||||
throws IOException
|
||||
{
|
||||
byte[] bytes = integer.toByteArray();
|
||||
writeLength(out, bytes.length);
|
||||
out.write(bytes);
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
private static int writeSequence(OutputStream out, List sequence)
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
for (Iterator i = sequence.iterator(); i.hasNext(); )
|
||||
{
|
||||
write(bout, (DERValue) i.next());
|
||||
}
|
||||
byte[] buf = bout.toByteArray();
|
||||
writeLength(out, buf.length);
|
||||
out.write(buf);
|
||||
return buf.length;
|
||||
}
|
||||
|
||||
private static int writeSet(OutputStream out, Set set)
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
for (Iterator i = set.iterator(); i.hasNext(); )
|
||||
{
|
||||
write(bout, (DERValue) i.next());
|
||||
}
|
||||
byte[] buf = bout.toByteArray();
|
||||
writeLength(out, buf.length);
|
||||
out.write(buf);
|
||||
return buf.length;
|
||||
}
|
||||
|
||||
private static int writeOID(OutputStream out, OID oid)
|
||||
throws IOException
|
||||
{
|
||||
byte[] der = oid.getDER();
|
||||
writeLength(out, der.length);
|
||||
out.write(der);
|
||||
return der.length;
|
||||
}
|
||||
|
||||
private static int writeBitString(OutputStream out, BitString bs)
|
||||
throws IOException
|
||||
{
|
||||
byte[] buf = bs.getShiftedByteArray();
|
||||
out.write(buf.length + 1);
|
||||
out.write(bs.getIgnoredBits());
|
||||
out.write(buf);
|
||||
return buf.length;
|
||||
}
|
||||
|
||||
private static int writeString(OutputStream out, int tag, String str)
|
||||
throws IOException
|
||||
{
|
||||
byte[] b = null;
|
||||
switch (tag & 0x1F)
|
||||
{
|
||||
case NUMERIC_STRING:
|
||||
case PRINTABLE_STRING:
|
||||
case T61_STRING:
|
||||
case VIDEOTEX_STRING:
|
||||
case IA5_STRING:
|
||||
case GRAPHIC_STRING:
|
||||
case ISO646_STRING:
|
||||
case GENERAL_STRING:
|
||||
b = toIso88591(str);
|
||||
break;
|
||||
|
||||
case UNIVERSAL_STRING:
|
||||
case BMP_STRING:
|
||||
b = toUtf16Be(str);
|
||||
break;
|
||||
|
||||
case UTF8_STRING:
|
||||
default:
|
||||
b = toUtf8(str);
|
||||
break;
|
||||
}
|
||||
writeLength(out, b.length);
|
||||
out.write(b);
|
||||
return b.length;
|
||||
}
|
||||
|
||||
private static byte[] toIso88591(String string)
|
||||
{
|
||||
byte[] result = new byte[string.length()];
|
||||
for (int i = 0; i < string.length(); i++)
|
||||
result[i] = (byte) string.charAt(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] toUtf16Be(String string)
|
||||
{
|
||||
byte[] result = new byte[string.length() * 2];
|
||||
for (int i = 0; i < string.length(); i++)
|
||||
{
|
||||
result[i*2 ] = (byte) ((string.charAt(i) >>> 8) & 0xFF);
|
||||
result[i*2+1] = (byte) (string.charAt(i) & 0xFF);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] toUtf8(String string)
|
||||
{
|
||||
ByteArrayOutputStream buf =
|
||||
new ByteArrayOutputStream((int)(string.length() * 1.5));
|
||||
for (int i = 0; i < string.length(); i++)
|
||||
{
|
||||
char c = string.charAt(i);
|
||||
if (c < 0x0080)
|
||||
buf.write(c & 0xFF);
|
||||
else if (c < 0x0800)
|
||||
{
|
||||
buf.write(0xC0 | ((c >>> 6) & 0x3F));
|
||||
buf.write(0x80 | (c & 0x3F));
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.write(0xE0 | ((c >>> 12) & 0x0F));
|
||||
buf.write(0x80 | ((c >>> 6) & 0x3F));
|
||||
buf.write(0x80 | (c & 0x3F));
|
||||
}
|
||||
}
|
||||
return buf.toByteArray();
|
||||
}
|
||||
|
||||
private static int writeDate(OutputStream out, int tag, Date date)
|
||||
throws IOException
|
||||
{
|
||||
SimpleDateFormat sdf = null;
|
||||
if ((tag & 0x1F) == UTC_TIME)
|
||||
sdf = new SimpleDateFormat("yyMMddHHmmss'Z'");
|
||||
else
|
||||
sdf = new SimpleDateFormat("yyyyMMddHHmmss'.'SSS'Z'");
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
byte[] b = sdf.format(date).getBytes("ISO-8859-1");
|
||||
writeLength(out, b.length);
|
||||
out.write(b);
|
||||
return b.length;
|
||||
}
|
||||
|
||||
// Package method.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
static void writeLength(OutputStream out, int len) throws IOException
|
||||
{
|
||||
if (len < 128)
|
||||
out.write(len);
|
||||
else if (len < 256)
|
||||
{
|
||||
out.write(0x81);
|
||||
out.write(len);
|
||||
}
|
||||
else if (len < 65536)
|
||||
{
|
||||
out.write(0x82);
|
||||
out.write(len >> 8);
|
||||
out.write(len);
|
||||
}
|
||||
else if (len < 16777216)
|
||||
{
|
||||
out.write(0x83);
|
||||
out.write(len >> 16);
|
||||
out.write(len >> 8);
|
||||
out.write(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(0x84);
|
||||
out.write(len >> 24);
|
||||
out.write(len >> 16);
|
||||
out.write(len >> 8);
|
||||
out.write(len);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.der package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.der</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,364 @@
|
||||
/* PKCS7SignedData.java -- reader for PKCS#7 signedData objects
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security.pkcs;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.ber.BER;
|
||||
import gnu.java.security.ber.BEREncodingException;
|
||||
import gnu.java.security.ber.BERReader;
|
||||
import gnu.java.security.ber.BERValue;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import java.security.cert.CRL;
|
||||
import java.security.cert.CRLException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The SignedData object in PKCS #7. This is a read-only implementation of
|
||||
* this format, and is used to provide signed Jar file support.
|
||||
*
|
||||
* @author Casey Marshall (csm@gnu.org)
|
||||
*/
|
||||
public class PKCS7SignedData
|
||||
{
|
||||
|
||||
public static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1");
|
||||
public static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2");
|
||||
|
||||
private BigInteger version;
|
||||
private Set digestAlgorithms;
|
||||
private OID contentType;
|
||||
private byte[] content;
|
||||
private Certificate[] certificates;
|
||||
private CRL[] crls;
|
||||
private Set signerInfos;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static void debug(String msg)
|
||||
{
|
||||
System.err.print("PKCS7SignedData >> ");
|
||||
System.err.println(msg);
|
||||
}
|
||||
|
||||
public PKCS7SignedData(InputStream in)
|
||||
throws CRLException, CertificateException, IOException
|
||||
{
|
||||
this(new BERReader(in));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an encoded PKCS#7 SignedData object. The ASN.1 format of this
|
||||
* object is:
|
||||
*
|
||||
* <pre>
|
||||
* SignedData ::= SEQUENCE {
|
||||
* version Version,
|
||||
* digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
* contentInfo ContentInfo,
|
||||
* certificates
|
||||
* [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
|
||||
* crls
|
||||
* [1] IMPLICIT CertificateRevocationLists OPTIONAL,
|
||||
* signerInfos SignerInfos }
|
||||
*
|
||||
* Version ::= INTEGER
|
||||
*
|
||||
* DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
|
||||
*
|
||||
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
*
|
||||
* ContentInfo ::= SEQUENCE {
|
||||
* contentType ContentType,
|
||||
* content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
|
||||
*
|
||||
* ContentType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* ExtendedCertificatesAndCertificates ::=
|
||||
* SET OF ExtendedCertificatesAndCertificate
|
||||
*
|
||||
* ExtendedCertificatesAndCertificate ::= CHOICE {
|
||||
* certificate Certificate, -- from X.509
|
||||
* extendedCertificate [0] IMPLICIT ExtendedCertificate }
|
||||
*
|
||||
* CertificateRevocationLists ::= SET OF CertificateRevocationList
|
||||
* -- from X.509
|
||||
*
|
||||
* SignerInfos ::= SET OF SignerInfo
|
||||
*
|
||||
* SignerInfo ::= SEQUENCE {
|
||||
* version Version,
|
||||
* issuerAndSerialNumber IssuerAndSerialNumber,
|
||||
* digestAlgorithm DigestAlgorithmIdentifier,
|
||||
* authenticatedAttributes
|
||||
* [0] IMPLICIT Attributes OPTIONAL,
|
||||
* digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
|
||||
* encryptedDigest EncryptedDigest,
|
||||
* unauthenticatedAttributes
|
||||
* [1] IMPLICIT Attributes OPTIONAL }
|
||||
*
|
||||
* EncryptedDigest ::= OCTET STRING
|
||||
* </pre>
|
||||
*
|
||||
* <p>(Readers who are confused as to why it takes 40 levels of indirection
|
||||
* to specify "data with a signature", rest assured that the present author
|
||||
* is as confused as you are).</p>
|
||||
*/
|
||||
public PKCS7SignedData(BERReader ber)
|
||||
throws CRLException, CertificateException, IOException
|
||||
{
|
||||
CertificateFactory x509 = CertificateFactory.getInstance("X509");
|
||||
DERValue val = ber.read();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed ContentInfo");
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() != BER.OBJECT_IDENTIFIER)
|
||||
throw new BEREncodingException("malformed ContentType");
|
||||
|
||||
if (!PKCS7_SIGNED_DATA.equals(val.getValue()))
|
||||
throw new BEREncodingException("content is not SignedData");
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() != 0)
|
||||
throw new BEREncodingException("malformed Content");
|
||||
|
||||
val = ber.read();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed SignedData");
|
||||
|
||||
if (DEBUG)
|
||||
debug("SignedData: " + val);
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() != BER.INTEGER)
|
||||
throw new BEREncodingException("expecting Version");
|
||||
version = (BigInteger) val.getValue();
|
||||
|
||||
if (DEBUG)
|
||||
debug(" Version: " + version);
|
||||
|
||||
digestAlgorithms = new HashSet();
|
||||
val = ber.read();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed DigestAlgorithmIdentifiers");
|
||||
if (DEBUG)
|
||||
debug(" DigestAlgorithmIdentifiers: " + val);
|
||||
int count = 0;
|
||||
DERValue val2 = ber.read();
|
||||
while (val2 != BER.END_OF_SEQUENCE &&
|
||||
(val.getLength() > 0 && val.getLength() > count))
|
||||
{
|
||||
if (!val2.isConstructed())
|
||||
throw new BEREncodingException("malformed AlgorithmIdentifier");
|
||||
if (DEBUG)
|
||||
debug(" AlgorithmIdentifier: " + val2);
|
||||
count += val2.getEncodedLength();
|
||||
val2 = ber.read();
|
||||
if (val2.getTag() != BER.OBJECT_IDENTIFIER)
|
||||
throw new BEREncodingException("malformed AlgorithmIdentifier");
|
||||
if (DEBUG)
|
||||
debug(" ID: " + val2.getValue());
|
||||
List algId = new ArrayList(2);
|
||||
algId.add(val2.getValue());
|
||||
val2 = ber.read();
|
||||
if (val2 != BER.END_OF_SEQUENCE)
|
||||
{
|
||||
count += val2.getEncodedLength();
|
||||
if (val2.getTag() == BER.NULL)
|
||||
algId.add(null);
|
||||
else
|
||||
algId.add(val2.getEncoded());
|
||||
if (DEBUG)
|
||||
debug(" params: " + new BigInteger(1, val2.getEncoded()).toString(16));
|
||||
if (val2.isConstructed())
|
||||
ber.skip(val2.getLength());
|
||||
if (BERValue.isIndefinite(val))
|
||||
val2 = ber.read();
|
||||
}
|
||||
else
|
||||
algId.add(null);
|
||||
digestAlgorithms.add(algId);
|
||||
}
|
||||
|
||||
val = ber.read();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed ContentInfo");
|
||||
if (DEBUG)
|
||||
debug(" ContentInfo: " + val);
|
||||
val2 = ber.read();
|
||||
if (val2.getTag() != BER.OBJECT_IDENTIFIER)
|
||||
throw new BEREncodingException("malformed ContentType");
|
||||
contentType = (OID) val2.getValue();
|
||||
if (DEBUG)
|
||||
debug(" ContentType: " + contentType);
|
||||
if (BERValue.isIndefinite(val)
|
||||
|| (val.getLength() > 0 && val.getLength() > val2.getEncodedLength()))
|
||||
{
|
||||
val2 = ber.read();
|
||||
if (val2 != BER.END_OF_SEQUENCE)
|
||||
{
|
||||
content = val2.getEncoded();
|
||||
if (BERValue.isIndefinite(val))
|
||||
val2 = ber.read();
|
||||
if (DEBUG)
|
||||
debug(" Content: " + new BigInteger(1, content).toString(16));
|
||||
}
|
||||
}
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() == 0)
|
||||
{
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed ExtendedCertificatesAndCertificates");
|
||||
if (DEBUG)
|
||||
debug(" ExtendedCertificatesAndCertificates: " + val);
|
||||
count = 0;
|
||||
val2 = ber.read();
|
||||
List certs = new LinkedList();
|
||||
while (val2 != BER.END_OF_SEQUENCE &&
|
||||
(val.getLength() > 0 && val.getLength() > count))
|
||||
{
|
||||
Certificate cert =
|
||||
x509.generateCertificate(new ByteArrayInputStream(val2.getEncoded()));
|
||||
if (DEBUG)
|
||||
debug(" Certificate: " + cert);
|
||||
certs.add(cert);
|
||||
count += val2.getEncodedLength();
|
||||
ber.skip(val2.getLength());
|
||||
if (BERValue.isIndefinite(val) || val.getLength() > count)
|
||||
val2 = ber.read();
|
||||
}
|
||||
certificates = (Certificate[]) certs.toArray(new Certificate[certs.size()]);
|
||||
val = ber.read();
|
||||
}
|
||||
|
||||
if (val.getTag() == 1)
|
||||
{
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed CertificateRevocationLists");
|
||||
if (DEBUG)
|
||||
debug(" CertificateRevocationLists: " + val);
|
||||
count = 0;
|
||||
val2 = ber.read();
|
||||
List crls = new LinkedList();
|
||||
while (val2 != BER.END_OF_SEQUENCE &&
|
||||
(val.getLength() > 0 && val.getLength() > count))
|
||||
{
|
||||
CRL crl = x509.generateCRL(new ByteArrayInputStream(val2.getEncoded()));
|
||||
if (DEBUG)
|
||||
debug (" CRL: " + crl);
|
||||
crls.add(crl);
|
||||
count += val2.getEncodedLength();
|
||||
ber.skip(val2.getLength());
|
||||
if (BERValue.isIndefinite(val) || val.getLength() > count)
|
||||
val2 = ber.read();
|
||||
}
|
||||
this.crls = (CRL[]) crls.toArray(new CRL[crls.size()]);
|
||||
val = ber.read();
|
||||
}
|
||||
|
||||
signerInfos = new HashSet();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed SignerInfos");
|
||||
|
||||
if (DEBUG)
|
||||
debug(" SignerInfos: " + val);
|
||||
|
||||
// FIXME read this more carefully.
|
||||
// Since we are just reading a file (probably) we just read until we
|
||||
// reach the end.
|
||||
while (true)
|
||||
{
|
||||
int i = ber.peek();
|
||||
if (i == 0 || i == -1)
|
||||
break;
|
||||
signerInfos.add(new SignerInfo(ber));
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
public Certificate[] getCertificates()
|
||||
{
|
||||
return (certificates != null ? (Certificate[]) certificates.clone()
|
||||
: null);
|
||||
}
|
||||
|
||||
public OID getContentType()
|
||||
{
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public byte[] getContent()
|
||||
{
|
||||
return (content != null ? (byte[]) content.clone() : null);
|
||||
}
|
||||
|
||||
public Set getDigestAlgorithms()
|
||||
{
|
||||
// FIXME copy contents too, they are mutable!!!
|
||||
return Collections.unmodifiableSet(digestAlgorithms);
|
||||
}
|
||||
|
||||
public Set getSignerInfos()
|
||||
{
|
||||
Set copy = new HashSet();
|
||||
for (Iterator it = signerInfos.iterator(); it.hasNext(); )
|
||||
copy.add(it.next());
|
||||
return Collections.unmodifiableSet(copy);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
/* SignerInfo.java -- a SignerInfo object, from PKCS #7
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security.pkcs;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.ber.BER;
|
||||
import gnu.java.security.ber.BEREncodingException;
|
||||
import gnu.java.security.ber.BERReader;
|
||||
import gnu.java.security.ber.BERValue;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
public class SignerInfo
|
||||
{
|
||||
private final BigInteger version;
|
||||
private final BigInteger serialNumber;
|
||||
private final X500Principal issuer;
|
||||
private final OID digestAlgorithmId;
|
||||
private final byte[] digestAlgorithmParams;
|
||||
private final byte[] authenticatedAttributes;
|
||||
private final OID digestEncryptionAlgorithmId;
|
||||
private final byte[] digestEncryptionAlgorithmParams;
|
||||
private final byte[] encryptedDigest;
|
||||
private final byte[] unauthenticatedAttributes;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static void debug(String msg)
|
||||
{
|
||||
System.err.print("SignerInfo >> ");
|
||||
System.err.println(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a SignerInfo object.
|
||||
*/
|
||||
public SignerInfo(BERReader ber) throws IOException
|
||||
{
|
||||
DERValue val = ber.read();
|
||||
if (DEBUG)
|
||||
debug("SignerInfo: " + val);
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed SignerInfo");
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() != BER.INTEGER)
|
||||
throw new BEREncodingException("malformed Version");
|
||||
version = (BigInteger) val.getValue();
|
||||
|
||||
if (DEBUG)
|
||||
debug(" Version: " + version);
|
||||
|
||||
val = ber.read();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed IssuerAndSerialNumber");
|
||||
|
||||
if (DEBUG)
|
||||
debug(" IssuerAndSerialNumber: " + val);
|
||||
|
||||
val = ber.read();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed Issuer");
|
||||
issuer = new X500Principal(val.getEncoded());
|
||||
ber.skip(val.getLength());
|
||||
if (DEBUG)
|
||||
debug(" Issuer: " + issuer);
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() != BER.INTEGER)
|
||||
throw new BEREncodingException("malformed SerialNumber");
|
||||
serialNumber = (BigInteger) val.getValue();
|
||||
if (DEBUG)
|
||||
debug(" SerialNumber: " + serialNumber);
|
||||
|
||||
val = ber.read();
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed DigestAlgorithmIdentifier");
|
||||
if (DEBUG)
|
||||
debug(" DigestAlgorithmIdentifier: " + val);
|
||||
|
||||
int count = 0;
|
||||
DERValue val2 = ber.read();
|
||||
if (val2.getTag() != BER.OBJECT_IDENTIFIER)
|
||||
throw new BEREncodingException("malformed AlgorithmIdentifier");
|
||||
digestAlgorithmId = (OID) val2.getValue();
|
||||
if (DEBUG)
|
||||
debug(" OID: " + digestAlgorithmId);
|
||||
|
||||
if (BERValue.isIndefinite(val))
|
||||
{
|
||||
val2 = ber.read();
|
||||
if (val2 != BER.END_OF_SEQUENCE)
|
||||
{
|
||||
digestAlgorithmParams = val2.getEncoded();
|
||||
val2 = ber.read();
|
||||
if (val2 != BER.END_OF_SEQUENCE)
|
||||
throw new BEREncodingException("expecting BER end-of-sequence");
|
||||
}
|
||||
else
|
||||
digestAlgorithmParams = null;
|
||||
}
|
||||
else if (val2.getEncodedLength() < val.getLength())
|
||||
{
|
||||
val2 = ber.read();
|
||||
digestAlgorithmParams = val2.getEncoded();
|
||||
if (val2.isConstructed())
|
||||
ber.skip(val2.getLength());
|
||||
}
|
||||
else
|
||||
digestAlgorithmParams = null;
|
||||
if(DEBUG)
|
||||
debug(" params: " + (digestAlgorithmParams == null ? null
|
||||
: new BigInteger(digestAlgorithmParams).toString(16)));
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() == 0)
|
||||
{
|
||||
authenticatedAttributes = val.getEncoded();
|
||||
val = ber.read();
|
||||
if (val.isConstructed())
|
||||
ber.skip(val.getLength());
|
||||
if (DEBUG)
|
||||
debug(" AuthenticatedAttributes: " + val);
|
||||
val = ber.read();
|
||||
}
|
||||
else
|
||||
authenticatedAttributes = null;
|
||||
|
||||
if (!val.isConstructed())
|
||||
throw new BEREncodingException("malformed DigestEncryptionAlgorithmIdentifier");
|
||||
if (DEBUG)
|
||||
debug(" DigestEncryptionAlgorithmIdentifier: " + val);
|
||||
count = 0;
|
||||
val2 = ber.read();
|
||||
if (val2.getTag() != BER.OBJECT_IDENTIFIER)
|
||||
throw new BEREncodingException("malformed AlgorithmIdentifier");
|
||||
digestEncryptionAlgorithmId = (OID) val2.getValue();
|
||||
if (DEBUG)
|
||||
debug(" OID: " + digestEncryptionAlgorithmId);
|
||||
|
||||
if (BERValue.isIndefinite(val))
|
||||
{
|
||||
val2 = ber.read();
|
||||
if (val2 != BER.END_OF_SEQUENCE)
|
||||
{
|
||||
digestEncryptionAlgorithmParams = val2.getEncoded();
|
||||
val2 = ber.read();
|
||||
if (val2 != BER.END_OF_SEQUENCE)
|
||||
throw new BEREncodingException("expecting BER end-of-sequence");
|
||||
}
|
||||
else
|
||||
digestEncryptionAlgorithmParams = null;
|
||||
}
|
||||
else if (val2.getEncodedLength() < val.getLength())
|
||||
{
|
||||
val2 = ber.read();
|
||||
digestEncryptionAlgorithmParams = val2.getEncoded();
|
||||
if (val2.isConstructed())
|
||||
ber.skip(val2.getLength());
|
||||
}
|
||||
else
|
||||
digestEncryptionAlgorithmParams = null;
|
||||
if(DEBUG)
|
||||
debug(" params: " + (digestEncryptionAlgorithmParams == null ? null
|
||||
: new BigInteger(digestEncryptionAlgorithmParams).toString(16)));
|
||||
|
||||
val = ber.read();
|
||||
if (val.getTag() != BER.OCTET_STRING)
|
||||
throw new BEREncodingException("malformed EncryptedDigest");
|
||||
encryptedDigest = (byte[]) val.getValue();
|
||||
if (DEBUG)
|
||||
debug(" EncryptedDigest: " + new BigInteger(1, encryptedDigest).toString(16));
|
||||
|
||||
if (ber.peek() == 1)
|
||||
unauthenticatedAttributes = ber.read().getEncoded();
|
||||
else
|
||||
unauthenticatedAttributes = null;
|
||||
|
||||
if (ber.peek() == 0)
|
||||
ber.read();
|
||||
}
|
||||
|
||||
public BigInteger getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
public BigInteger getSerialNumber()
|
||||
{
|
||||
return serialNumber;
|
||||
}
|
||||
|
||||
public X500Principal getIssuer()
|
||||
{
|
||||
return issuer;
|
||||
}
|
||||
|
||||
public OID getDigestAlgorithmId()
|
||||
{
|
||||
return digestAlgorithmId;
|
||||
}
|
||||
|
||||
public byte[] getDigestAlgorithmParams()
|
||||
{
|
||||
return (digestAlgorithmParams != null
|
||||
? (byte[]) digestAlgorithmParams.clone()
|
||||
: null);
|
||||
}
|
||||
|
||||
public byte[] getAuthenticatedAttributes()
|
||||
{
|
||||
return (authenticatedAttributes != null
|
||||
? (byte[]) authenticatedAttributes.clone()
|
||||
: null);
|
||||
}
|
||||
|
||||
public OID getDigestEncryptionAlgorithmId()
|
||||
{
|
||||
return digestEncryptionAlgorithmId;
|
||||
}
|
||||
|
||||
public byte[] getDigestEncryptionAlgorithmParams()
|
||||
{
|
||||
return (digestEncryptionAlgorithmParams != null
|
||||
? (byte[]) digestEncryptionAlgorithmParams.clone()
|
||||
: null);
|
||||
}
|
||||
|
||||
public byte[] getEncryptedDigest()
|
||||
{
|
||||
return (encryptedDigest != null ? (byte[]) encryptedDigest.clone() : null);
|
||||
}
|
||||
|
||||
public byte[] getUnauthenticatedAttributes()
|
||||
{
|
||||
return (unauthenticatedAttributes != null
|
||||
? (byte[]) unauthenticatedAttributes.clone()
|
||||
: null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.pkcs package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.pkcs</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,102 @@
|
||||
/* CollectionCertStore.java -- Collection-based cert store.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.cert.CRL;
|
||||
import java.security.cert.CRLSelector;
|
||||
import java.security.cert.CertSelector;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.security.cert.CertStoreParameters;
|
||||
import java.security.cert.CertStoreSpi;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CollectionCertStoreParameters;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public final class CollectionCertStoreImpl extends CertStoreSpi
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private final Collection store;
|
||||
|
||||
// Constructors.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public CollectionCertStoreImpl(CertStoreParameters params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
super(params);
|
||||
if (! (params instanceof CollectionCertStoreParameters))
|
||||
throw new InvalidAlgorithmParameterException("not a CollectionCertStoreParameters object");
|
||||
store = ((CollectionCertStoreParameters) params).getCollection();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Collection engineGetCertificates(CertSelector selector)
|
||||
throws CertStoreException
|
||||
{
|
||||
LinkedList result = new LinkedList();
|
||||
for (Iterator it = store.iterator(); it.hasNext(); )
|
||||
{
|
||||
Object o = it.next();
|
||||
if ((o instanceof Certificate) && selector.match((Certificate) o))
|
||||
result.add(o);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection engineGetCRLs(CRLSelector selector)
|
||||
throws CertStoreException
|
||||
{
|
||||
LinkedList result = new LinkedList();
|
||||
for (Iterator it = store.iterator(); it.hasNext(); )
|
||||
{
|
||||
Object o = it.next();
|
||||
if ((o instanceof CRL) && selector.match((CRL) o))
|
||||
result.add(o);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/* DSAKeyFactory.java -- DSA key factory.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactorySpi;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.DSAPrivateKey;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.spec.DSAPrivateKeySpec;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
|
||||
/**
|
||||
* DSA key factory.
|
||||
*
|
||||
* @author Casey Marshall (rsdio@metastatic.org)
|
||||
*/
|
||||
public class DSAKeyFactory extends KeyFactorySpi
|
||||
{
|
||||
|
||||
// Constructor.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public DSAKeyFactory()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if (!(keySpec instanceof DSAPrivateKeySpec))
|
||||
throw new InvalidKeySpecException();
|
||||
return new GnuDSAPrivateKey(
|
||||
((DSAPrivateKeySpec) keySpec).getX(),
|
||||
((DSAPrivateKeySpec) keySpec).getP(),
|
||||
((DSAPrivateKeySpec) keySpec).getQ(),
|
||||
((DSAPrivateKeySpec) keySpec).getG());
|
||||
}
|
||||
|
||||
protected PublicKey engineGeneratePublic(KeySpec keySpec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if (!(keySpec instanceof DSAPublicKeySpec))
|
||||
throw new InvalidKeySpecException();
|
||||
return new GnuDSAPublicKey(
|
||||
((DSAPublicKeySpec) keySpec).getY(),
|
||||
((DSAPublicKeySpec) keySpec).getP(),
|
||||
((DSAPublicKeySpec) keySpec).getQ(),
|
||||
((DSAPublicKeySpec) keySpec).getG());
|
||||
}
|
||||
|
||||
protected KeySpec engineGetKeySpec(Key key, Class keySpec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if ((key instanceof DSAPublicKey) &&
|
||||
keySpec.isAssignableFrom(DSAPublicKeySpec.class))
|
||||
{
|
||||
return new DSAPublicKeySpec(((DSAPublicKey) key).getY(),
|
||||
((DSAPublicKey) key).getParams().getP(),
|
||||
((DSAPublicKey) key).getParams().getQ(),
|
||||
((DSAPublicKey) key).getParams().getG());
|
||||
}
|
||||
if ((key instanceof DSAPrivateKey) &&
|
||||
keySpec.isAssignableFrom(DSAPrivateKeySpec.class))
|
||||
{
|
||||
return new DSAPrivateKeySpec(((DSAPrivateKey) key).getX(),
|
||||
((DSAPrivateKey) key).getParams().getP(),
|
||||
((DSAPrivateKey) key).getParams().getQ(),
|
||||
((DSAPrivateKey) key).getParams().getG());
|
||||
}
|
||||
throw new InvalidKeySpecException();
|
||||
}
|
||||
|
||||
protected Key engineTranslateKey(Key key) throws InvalidKeyException
|
||||
{
|
||||
if ((key instanceof GnuDSAPublicKey) || (key instanceof GnuDSAPrivateKey))
|
||||
return key;
|
||||
if (key instanceof DSAPublicKey)
|
||||
return new GnuDSAPublicKey(((DSAPublicKey) key).getY(),
|
||||
((DSAPublicKey) key).getParams().getP(),
|
||||
((DSAPublicKey) key).getParams().getQ(),
|
||||
((DSAPublicKey) key).getParams().getG());
|
||||
if (key instanceof DSAPrivateKey)
|
||||
return new GnuDSAPrivateKey(((DSAPrivateKey) key).getX(),
|
||||
((DSAPrivateKey) key).getParams().getP(),
|
||||
((DSAPrivateKey) key).getParams().getQ(),
|
||||
((DSAPrivateKey) key).getParams().getG());
|
||||
throw new InvalidKeyException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/* GnuDSAKeyPairGenerator.java --- Gnu DSA Key Pair Generator
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameterGenerator;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGeneratorSpi;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.util.Random;
|
||||
|
||||
public class DSAKeyPairGenerator extends KeyPairGeneratorSpi
|
||||
implements java.security.interfaces.DSAKeyPairGenerator
|
||||
{
|
||||
int keysize;
|
||||
SecureRandom random;
|
||||
private BigInteger q = null; // the small prime
|
||||
private BigInteger p = null; // the big prime
|
||||
private BigInteger g = null;
|
||||
|
||||
DSAKeyPairGenerator()
|
||||
{
|
||||
keysize = 1024;
|
||||
}
|
||||
|
||||
public void initialize(int keysize, SecureRandom random)
|
||||
{
|
||||
//if( ((keysize % 64) != 0) || (keysize < 512) || (keysize > 1024) )
|
||||
// throw new InvalidAlgorithmParameterException("Invalid key size");
|
||||
|
||||
this.keysize = keysize;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public void initialize(AlgorithmParameterSpec params,
|
||||
SecureRandom random)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if( !( params instanceof DSAParameterSpec ) )
|
||||
throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec");
|
||||
|
||||
DSAParameterSpec dsaparameterspec = (DSAParameterSpec)params;
|
||||
p = dsaparameterspec.getP();
|
||||
q = dsaparameterspec.getQ();
|
||||
g = dsaparameterspec.getG();
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public void initialize(DSAParams params, SecureRandom random)
|
||||
throws InvalidParameterException
|
||||
{
|
||||
if(params.getP() != null)
|
||||
p = params.getP();
|
||||
else
|
||||
throw new InvalidParameterException();
|
||||
|
||||
if(params.getQ() != null)
|
||||
q = params.getQ();
|
||||
else
|
||||
throw new InvalidParameterException();
|
||||
|
||||
if(params.getG() != null)
|
||||
g = params.getG();
|
||||
else
|
||||
throw new InvalidParameterException();
|
||||
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public void initialize(int modlen, boolean genParams, SecureRandom random)
|
||||
throws InvalidParameterException
|
||||
{
|
||||
if( ((modlen % 64) != 0) || (modlen < 512) || (modlen > 1024) )
|
||||
throw new InvalidParameterException();
|
||||
|
||||
if( (genParams == false) && (modlen != 512) && (modlen != 768) && (modlen != 1024) )
|
||||
throw new InvalidParameterException();
|
||||
this.keysize = modlen;
|
||||
this.random = random;
|
||||
p = null;
|
||||
q = null;
|
||||
g = null;
|
||||
}
|
||||
|
||||
public KeyPair generateKeyPair()
|
||||
{
|
||||
if( getDefaults() == false) {
|
||||
try {
|
||||
AlgorithmParameterGenerator apgDSA = AlgorithmParameterGenerator.getInstance("DSA");
|
||||
AlgorithmParameters apDSA = apgDSA.generateParameters();
|
||||
DSAParameterSpec dsaparameterspec = (DSAParameterSpec)apDSA.getParameterSpec( DSAParameterSpec.class );
|
||||
p = dsaparameterspec.getP();
|
||||
q = dsaparameterspec.getQ();
|
||||
g = dsaparameterspec.getG();
|
||||
} catch ( Exception e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger x = new BigInteger( 159, new Random() );
|
||||
|
||||
BigInteger y = g.modPow( x, p );
|
||||
|
||||
return new KeyPair( new GnuDSAPublicKey(y,p,q,g), new GnuDSAPrivateKey(x,p,q,g));
|
||||
//return new KeyPair( public, private );
|
||||
}
|
||||
|
||||
//These constants are Sun's Constants copied from the
|
||||
//Cryptography Specification
|
||||
private boolean getDefaults()
|
||||
{
|
||||
if( keysize == 512) {
|
||||
p = new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16);
|
||||
q = new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16);
|
||||
g = new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16);
|
||||
return true;
|
||||
} else if( keysize == 768) {
|
||||
p = new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16);
|
||||
q = new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16);
|
||||
g = new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16);
|
||||
} else if( keysize == 512) {
|
||||
p = new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16);
|
||||
q = new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16);
|
||||
g = new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/* DSAParameterGenerator.java --- DSA Parameter Generator Implementation
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.util.Prime;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameterGeneratorSpi;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.util.Random;
|
||||
|
||||
public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi
|
||||
{
|
||||
private int size;
|
||||
private SecureRandom random = null;
|
||||
|
||||
public DSAParameterGenerator()
|
||||
{
|
||||
size = 1024;
|
||||
}
|
||||
|
||||
public void engineInit(int size, SecureRandom random)
|
||||
{
|
||||
if( (size < 512) || (size > 1024) || ( (size % 64) != 0) )
|
||||
//throw new InvalidAlgorithmParameterException("Invalid Size");
|
||||
return;
|
||||
this.size = size;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public void engineInit(AlgorithmParameterSpec genParamSpec, SecureRandom random)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if( !( genParamSpec instanceof DSAParameterSpec ) )
|
||||
throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec");
|
||||
|
||||
DSAParameterSpec dsaparameterspec = (DSAParameterSpec)genParamSpec;
|
||||
int tmp = dsaparameterspec.getP().bitLength();
|
||||
|
||||
if( (tmp < 512) || (tmp > 1024) || ( (tmp % 64) != 0) )
|
||||
throw new InvalidAlgorithmParameterException("Invalid Size");
|
||||
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
//For more information see IEEE P1363 A.16.1 (10/05/98 Draft)
|
||||
public AlgorithmParameters engineGenerateParameters()
|
||||
{
|
||||
DSAParameterSpec dsaparameterspec;
|
||||
|
||||
int L = size;
|
||||
BigInteger r, p, k, h, g;
|
||||
|
||||
//q 2^159 < q < 2^160
|
||||
r = Prime.generateRandomPrime( 159, 160, BigInteger.valueOf(1));
|
||||
|
||||
// 2^(L-1) < p < 2^L
|
||||
p = Prime.generateRandomPrime( r, BigInteger.valueOf(1), L - 1, L, BigInteger.valueOf(1));
|
||||
|
||||
k = p.subtract( BigInteger.valueOf(1) );
|
||||
k = k.divide( r );
|
||||
|
||||
Random rand = new Random();
|
||||
h = BigInteger.valueOf(1);
|
||||
|
||||
for(;;) {
|
||||
h = h.add(BigInteger.valueOf( 1 ) );
|
||||
|
||||
g = h.modPow(k, p);
|
||||
|
||||
if( g.compareTo( BigInteger.valueOf(1) ) != 1 )
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
dsaparameterspec = new DSAParameterSpec(p, r, g);
|
||||
AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
|
||||
ap.init( dsaparameterspec );
|
||||
return ap;
|
||||
} catch ( NoSuchAlgorithmException nsae ) {
|
||||
return null;
|
||||
} catch ( InvalidParameterSpecException ipse) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/* DSAParameters.java --- DSA Parameters Implementation
|
||||
Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.io.ASN1ParsingException;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.der.DERWriter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParametersSpi;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
ASN.1 Encoding for DSA from rfc2459
|
||||
|
||||
id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040)
|
||||
x9cm(4) 1 }
|
||||
|
||||
Dss-Parms ::= SEQUENCE {
|
||||
p INTEGER,
|
||||
q INTEGER,
|
||||
g INTEGER }
|
||||
|
||||
*/
|
||||
public class DSAParameters extends AlgorithmParametersSpi
|
||||
{
|
||||
private BigInteger q; // the small prime
|
||||
private BigInteger p; // the big prime
|
||||
private BigInteger g;
|
||||
|
||||
|
||||
public void engineInit(AlgorithmParameterSpec paramSpec)
|
||||
throws InvalidParameterSpecException
|
||||
{
|
||||
if( paramSpec instanceof DSAParameterSpec ) {
|
||||
DSAParameterSpec dsaParamSpec = (DSAParameterSpec)paramSpec;
|
||||
p = dsaParamSpec.getP();
|
||||
q = dsaParamSpec.getQ();
|
||||
g = dsaParamSpec.getG();
|
||||
}
|
||||
else
|
||||
throw new InvalidParameterSpecException("Only accepts DSAParameterSpec");
|
||||
}
|
||||
|
||||
public void engineInit(byte[] params)
|
||||
throws IOException
|
||||
{
|
||||
DERReader in = new DERReader(params);
|
||||
DERValue val = in.read();
|
||||
if (val.getValue() != DER.CONSTRUCTED_VALUE)
|
||||
throw new ASN1ParsingException("badly formed parameters");
|
||||
try
|
||||
{
|
||||
p = (BigInteger) in.read().getValue();
|
||||
q = (BigInteger) in.read().getValue();
|
||||
g = (BigInteger) in.read().getValue();
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
throw new ASN1ParsingException("badly formed parameters");
|
||||
}
|
||||
}
|
||||
|
||||
public void engineInit(byte[] params, String format)
|
||||
throws IOException
|
||||
{
|
||||
if( !format.equals("ASN.1") )
|
||||
throw new IOException("Invalid Format: Only accepts ASN.1");
|
||||
engineInit( params );
|
||||
}
|
||||
|
||||
public AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec)
|
||||
throws InvalidParameterSpecException
|
||||
{
|
||||
if( paramSpec.isAssignableFrom(DSAParameterSpec.class) )
|
||||
return new DSAParameterSpec(p, q, g);
|
||||
else
|
||||
throw new InvalidParameterSpecException("Only accepts DSAParameterSpec");
|
||||
}
|
||||
|
||||
public byte[] engineGetEncoded()
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
ArrayList seq = new ArrayList(3);
|
||||
seq.add(new DERValue(DER.INTEGER, p));
|
||||
seq.add(new DERValue(DER.INTEGER, q));
|
||||
seq.add(new DERValue(DER.INTEGER, g));
|
||||
DERWriter.write(bout, new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, seq));
|
||||
return bout.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
public byte[] engineGetEncoded(String format)
|
||||
throws IOException
|
||||
{
|
||||
if( !format.equals("ASN.1") )
|
||||
throw new IOException("Invalid Format: Only accepts ASN.1");
|
||||
return engineGetEncoded();
|
||||
}
|
||||
|
||||
public String engineToString()
|
||||
{
|
||||
return ("q: " + q + " p: " + p + " g: " + g);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/* DSASignature.java --
|
||||
Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.der.DERWriter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SignatureException;
|
||||
import java.security.SignatureSpi;
|
||||
import java.security.interfaces.DSAPrivateKey;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
public class DSASignature extends SignatureSpi
|
||||
{
|
||||
private DSAPublicKey publicKey;
|
||||
private DSAPrivateKey privateKey;
|
||||
private final MessageDigest digest;
|
||||
private final SecureRandom random;
|
||||
|
||||
public DSASignature() throws NoSuchAlgorithmException
|
||||
{
|
||||
random = new SecureRandom();
|
||||
digest = MessageDigest.getInstance ("SHA1");
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
digest.reset();
|
||||
}
|
||||
|
||||
public void engineInitVerify (PublicKey publicKey)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
if (publicKey instanceof DSAPublicKey)
|
||||
this.publicKey = (DSAPublicKey) publicKey;
|
||||
else
|
||||
throw new InvalidKeyException();
|
||||
init();
|
||||
}
|
||||
|
||||
public void engineInitSign (PrivateKey privateKey)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
if (privateKey instanceof DSAPrivateKey)
|
||||
this.privateKey = (DSAPrivateKey) privateKey;
|
||||
else
|
||||
throw new InvalidKeyException ("not a DSA private key");
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public void engineInitSign (PrivateKey privateKey,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
if (privateKey instanceof DSAPrivateKey)
|
||||
this.privateKey = (DSAPrivateKey) privateKey;
|
||||
else
|
||||
throw new InvalidKeyException ("not a DSA private key");
|
||||
|
||||
appRandom = random;
|
||||
init();
|
||||
}
|
||||
|
||||
public void engineUpdate(byte b)
|
||||
throws SignatureException
|
||||
{
|
||||
digest.update (b);
|
||||
}
|
||||
|
||||
public void engineUpdate (byte[] b, int off, int len)
|
||||
throws SignatureException
|
||||
{
|
||||
digest.update (b, off, len);
|
||||
}
|
||||
|
||||
public byte[] engineSign() throws SignatureException
|
||||
{
|
||||
if (privateKey == null)
|
||||
throw new SignatureException ("not initialized for signing");
|
||||
|
||||
try
|
||||
{
|
||||
BigInteger g = privateKey.getParams().getG();
|
||||
BigInteger p = privateKey.getParams().getP();
|
||||
BigInteger q = privateKey.getParams().getQ();
|
||||
|
||||
BigInteger x = privateKey.getX();
|
||||
|
||||
BigInteger k = new BigInteger (159, appRandom != null ? appRandom : random);
|
||||
|
||||
BigInteger r = g.modPow(k, p);
|
||||
r = r.mod(q);
|
||||
|
||||
byte bytes[] = digest.digest();
|
||||
BigInteger sha = new BigInteger (1, bytes);
|
||||
|
||||
BigInteger s = sha.add (x.multiply (r));
|
||||
s = s.multiply (k.modInverse(q)).mod (q);
|
||||
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
ArrayList seq = new ArrayList (2);
|
||||
seq.add(0, new DERValue (DER.INTEGER, r));
|
||||
seq.add(1, new DERValue (DER.INTEGER, s));
|
||||
DERWriter.write (bout, new DERValue (DER.CONSTRUCTED | DER.SEQUENCE, seq));
|
||||
return bout.toByteArray();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
SignatureException se = new SignatureException();
|
||||
se.initCause (ioe);
|
||||
throw se;
|
||||
}
|
||||
catch (ArithmeticException ae)
|
||||
{
|
||||
SignatureException se = new SignatureException();
|
||||
se.initCause (ae);
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
|
||||
public int engineSign (byte[] outbuf, int offset, int len)
|
||||
throws SignatureException
|
||||
{
|
||||
byte tmp[] = engineSign();
|
||||
if (tmp.length > len)
|
||||
throw new SignatureException ("output buffer too short");
|
||||
System.arraycopy (tmp, 0, outbuf, offset, tmp.length);
|
||||
return tmp.length;
|
||||
}
|
||||
|
||||
public boolean engineVerify (byte[] sigBytes)
|
||||
throws SignatureException
|
||||
{
|
||||
// Decode sigBytes from ASN.1 DER encoding
|
||||
try
|
||||
{
|
||||
DERReader in = new DERReader (sigBytes);
|
||||
DERValue val = in.read();
|
||||
if (!val.isConstructed())
|
||||
throw new SignatureException ("badly formed signature");
|
||||
BigInteger r = (BigInteger) in.read().getValue();
|
||||
BigInteger s = (BigInteger) in.read().getValue();
|
||||
|
||||
BigInteger g = publicKey.getParams().getG();
|
||||
BigInteger p = publicKey.getParams().getP();
|
||||
BigInteger q = publicKey.getParams().getQ();
|
||||
|
||||
BigInteger y = publicKey.getY();
|
||||
|
||||
BigInteger w = s.modInverse (q);
|
||||
|
||||
byte bytes[] = digest.digest();
|
||||
BigInteger sha = new BigInteger (1, bytes);
|
||||
|
||||
BigInteger u1 = w.multiply (sha).mod ( q );
|
||||
|
||||
BigInteger u2 = r.multiply (w).mod(q);
|
||||
|
||||
BigInteger v = g.modPow (u1, p).multiply (y.modPow (u2, p)).mod (p).mod (q);
|
||||
|
||||
if (v.equals (r))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
SignatureException se = new SignatureException ("badly formed signature");
|
||||
se.initCause (ioe);
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
|
||||
public void engineSetParameter (String param,
|
||||
Object value)
|
||||
throws InvalidParameterException
|
||||
{
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
|
||||
public void engineSetParameter (AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
throw new InvalidParameterException();
|
||||
|
||||
}
|
||||
|
||||
public Object engineGetParameter (String param)
|
||||
throws InvalidParameterException
|
||||
{
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
|
||||
public Object clone() throws CloneNotSupportedException
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/* DefaultPolicy.java --
|
||||
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.AllPermission;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.security.Policy;
|
||||
|
||||
/**
|
||||
* This is just a stub policy implementation which grants all permissions
|
||||
* to any code source. FIXME: This should be replaced with a real
|
||||
* implementation that reads the policy configuration from a file, like
|
||||
* $JAVA_HOME/jre/lib/security/java.security.
|
||||
*/
|
||||
public class DefaultPolicy extends Policy
|
||||
{
|
||||
static Permission allPermission = new AllPermission();
|
||||
|
||||
public PermissionCollection getPermissions(CodeSource codesource)
|
||||
{
|
||||
Permissions perms = new Permissions();
|
||||
perms.add(allPermission);
|
||||
return perms;
|
||||
}
|
||||
|
||||
public void refresh()
|
||||
{
|
||||
// Nothing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/* EncodedKeyFactory.java -- encoded key factory.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.BitString;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactorySpi;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.RSAPrivateCrtKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
|
||||
/**
|
||||
* A factory for keys encoded in either the X.509 format (for public
|
||||
* keys) or the PKCS#8 format (for private keys).
|
||||
*
|
||||
* @author Casey Marshall (rsdio@metastatic.org)
|
||||
*/
|
||||
public class EncodedKeyFactory extends KeyFactorySpi
|
||||
{
|
||||
|
||||
// Constants.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
|
||||
private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
|
||||
private static final OID ID_DH = new OID("1.2.840.10046.2.1");
|
||||
|
||||
// Instance methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public PublicKey engineGeneratePublic(KeySpec spec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if (!(spec instanceof X509EncodedKeySpec))
|
||||
throw new InvalidKeySpecException("only supports X.509 key specs");
|
||||
DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded());
|
||||
try
|
||||
{
|
||||
DERValue spki = der.read();
|
||||
if (!spki.isConstructed())
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
DERValue alg = der.read();
|
||||
if (!alg.isConstructed())
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
DERValue val = der.read();
|
||||
if (!(val.getValue() instanceof OID))
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
OID algId = (OID) val.getValue();
|
||||
byte[] algParams = null;
|
||||
if (alg.getLength() > val.getEncodedLength())
|
||||
{
|
||||
val = der.read();
|
||||
algParams = val.getEncoded();
|
||||
if (val.isConstructed())
|
||||
der.skip(val.getLength());
|
||||
}
|
||||
val = der.read();
|
||||
if (!(val.getValue() instanceof BitString))
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
byte[] publicKey = ((BitString) val.getValue()).toByteArray();
|
||||
if (algId.equals(ID_DSA))
|
||||
{
|
||||
BigInteger p = null, g = null, q = null, Y;
|
||||
if (algParams != null)
|
||||
{
|
||||
DERReader dsaParams = new DERReader(algParams);
|
||||
val = dsaParams.read();
|
||||
if (!val.isConstructed())
|
||||
throw new InvalidKeySpecException("malformed DSA parameters");
|
||||
val = dsaParams.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DSA parameters");
|
||||
p = (BigInteger) val.getValue();
|
||||
val = dsaParams.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DSA parameters");
|
||||
q = (BigInteger) val.getValue();
|
||||
val = dsaParams.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DSA parameters");
|
||||
g = (BigInteger) val.getValue();
|
||||
}
|
||||
DERReader dsaPub = new DERReader(publicKey);
|
||||
val = dsaPub.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DSA parameters");
|
||||
Y = (BigInteger) val.getValue();
|
||||
return new GnuDSAPublicKey(Y, p, q, g);
|
||||
}
|
||||
else if (algId.equals(ID_RSA))
|
||||
{
|
||||
DERReader rsaParams = new DERReader(publicKey);
|
||||
if (!rsaParams.read().isConstructed())
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
return new GnuRSAPublicKey(new RSAPublicKeySpec(
|
||||
(BigInteger) rsaParams.read().getValue(),
|
||||
(BigInteger) rsaParams.read().getValue()));
|
||||
}
|
||||
else if (algId.equals(ID_DH))
|
||||
{
|
||||
if (algParams == null)
|
||||
throw new InvalidKeySpecException("missing DH parameters");
|
||||
DERReader dhParams = new DERReader(algParams);
|
||||
val = dhParams.read();
|
||||
BigInteger p, g, q, Y;
|
||||
if (!val.isConstructed())
|
||||
throw new InvalidKeySpecException("malformed DH parameters");
|
||||
val = dhParams.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DH parameters");
|
||||
p = (BigInteger) val.getValue();
|
||||
val = dhParams.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DH parameters");
|
||||
g = (BigInteger) val.getValue();
|
||||
val = dhParams.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DH parameters");
|
||||
q = (BigInteger) val.getValue();
|
||||
DERReader dhPub = new DERReader(publicKey);
|
||||
val = dhPub.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
throw new InvalidKeySpecException("malformed DH parameters");
|
||||
Y = (BigInteger) val.getValue();
|
||||
return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q);
|
||||
}
|
||||
else
|
||||
throw new InvalidKeySpecException("unknown algorithm: " + algId);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new InvalidKeySpecException(ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public PrivateKey engineGeneratePrivate(KeySpec spec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if (!(spec instanceof PKCS8EncodedKeySpec))
|
||||
{
|
||||
throw new InvalidKeySpecException("only supports PKCS8 key specs");
|
||||
}
|
||||
DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded());
|
||||
try
|
||||
{
|
||||
DERValue pki = der.read();
|
||||
if (!pki.isConstructed())
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
DERValue val = der.read();
|
||||
if (!(val.getValue() instanceof BigInteger))
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
DERValue alg = der.read();
|
||||
if (!alg.isConstructed())
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
val = der.read();
|
||||
if (!(val.getValue() instanceof OID))
|
||||
{
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
}
|
||||
OID algId = (OID) val.getValue();
|
||||
byte[] algParams = null;
|
||||
if (alg.getLength() > val.getEncodedLength())
|
||||
{
|
||||
val = der.read();
|
||||
algParams = val.getEncoded();
|
||||
if (val.isConstructed())
|
||||
der.skip(val.getLength());
|
||||
}
|
||||
byte[] privateKey = (byte[]) der.read().getValue();
|
||||
if (algId.equals(ID_DSA))
|
||||
{
|
||||
if (algParams == null)
|
||||
{
|
||||
throw new InvalidKeySpecException("missing DSA parameters");
|
||||
}
|
||||
AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
|
||||
params.init(algParams);
|
||||
DSAParameterSpec dsaSpec = (DSAParameterSpec)
|
||||
params.getParameterSpec(DSAParameterSpec.class);
|
||||
DERReader dsaPriv = new DERReader(privateKey);
|
||||
return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(),
|
||||
dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG());
|
||||
}
|
||||
else if (algId.equals(ID_RSA))
|
||||
{
|
||||
DERReader rsaParams = new DERReader(privateKey);
|
||||
if (!rsaParams.read().isConstructed())
|
||||
throw new InvalidKeySpecException("malformed encoded key");
|
||||
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
|
||||
(BigInteger) rsaParams.read().getValue(), // n
|
||||
(BigInteger) rsaParams.read().getValue(), // e
|
||||
(BigInteger) rsaParams.read().getValue(), // d
|
||||
(BigInteger) rsaParams.read().getValue(), // p
|
||||
(BigInteger) rsaParams.read().getValue(), // q
|
||||
(BigInteger) rsaParams.read().getValue(), // d mod (p - 1)
|
||||
(BigInteger) rsaParams.read().getValue(), // d mod (q - 1)
|
||||
(BigInteger) rsaParams.read().getValue())); // (inv q) mod p
|
||||
}
|
||||
else
|
||||
throw new InvalidKeySpecException("unknown algorithm: " + algId);
|
||||
}
|
||||
catch (InvalidParameterSpecException iapse)
|
||||
{
|
||||
throw new InvalidKeySpecException(iapse.getMessage());
|
||||
}
|
||||
catch (NoSuchAlgorithmException nsae)
|
||||
{
|
||||
throw new InvalidKeySpecException(nsae.getMessage());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new InvalidKeySpecException(ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public KeySpec engineGetKeySpec(Key key, Class speClass)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8")
|
||||
&& speClass.isAssignableFrom(PKCS8EncodedKeySpec.class))
|
||||
return new PKCS8EncodedKeySpec(key.getEncoded());
|
||||
else if ((key instanceof PublicKey) && key.getFormat().equals("X.509")
|
||||
&& speClass.isAssignableFrom(X509EncodedKeySpec.class))
|
||||
return new X509EncodedKeySpec(key.getEncoded());
|
||||
else
|
||||
throw new InvalidKeySpecException();
|
||||
}
|
||||
|
||||
public Key engineTranslateKey(Key key) throws InvalidKeyException
|
||||
{
|
||||
throw new InvalidKeyException("translating keys not supported");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/* Gnu.java --- Gnu provider main class
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.Provider;
|
||||
|
||||
public final class Gnu extends Provider
|
||||
{
|
||||
public Gnu()
|
||||
{
|
||||
super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, RSA, X.509 Certificates and CRLs, PKIX certificate path validators, Collection cert stores");
|
||||
|
||||
AccessController.doPrivileged (new PrivilegedAction()
|
||||
{
|
||||
public Object run()
|
||||
{
|
||||
// Note that all implementation class names are referenced by using
|
||||
// Class.getName(). That way when we staticly link the Gnu provider
|
||||
// we automatically get all the implementation classes.
|
||||
|
||||
// Signature
|
||||
put("Signature.SHA1withDSA",
|
||||
gnu.java.security.provider.DSASignature.class.getName());
|
||||
|
||||
put("Alg.Alias.Signature.DSS", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.DSA", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.DSAwithSHA", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
|
||||
put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
|
||||
|
||||
put("Signature.MD2withRSA", MD2withRSA.class.getName());
|
||||
put("Signature.MD2withRSA ImplementedIn", "Software");
|
||||
put("Alg.Alias.Signature.md2WithRSAEncryption", "MD2withRSA");
|
||||
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", "MD2withRSA");
|
||||
put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA");
|
||||
|
||||
put("Signature.MD4withRSA", MD4withRSA.class.getName());
|
||||
put("Signature.MD4withRSA ImplementedIn", "Software");
|
||||
put("Alg.Alias.Signature.md4WithRSAEncryption", "MD4withRSA");
|
||||
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.3", "MD4withRSA");
|
||||
put("Alg.Alias.Signature.1.2.840.113549.1.1.3", "MD4withRSA");
|
||||
|
||||
put("Signature.MD5withRSA", MD5withRSA.class.getName());
|
||||
put("Signature.MD5withRSA ImplementedIn", "Software");
|
||||
put("Alg.Alias.Signature.md5WithRSAEncryption", "MD5withRSA");
|
||||
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA");
|
||||
put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
|
||||
|
||||
put("Signature.SHA1withRSA", SHA1withRSA.class.getName());
|
||||
put("Signature.SHA1withRSA ImplementedIn", "Software");
|
||||
put("Alg.Alias.Signature.sha-1WithRSAEncryption", "SHA1withRSA");
|
||||
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA");
|
||||
put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
|
||||
|
||||
// Key Pair Generator
|
||||
put("KeyPairGenerator.DSA",
|
||||
gnu.java.security.provider.DSAKeyPairGenerator.class.getName());
|
||||
|
||||
put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
|
||||
put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
|
||||
put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
|
||||
|
||||
// Key Factory
|
||||
put("KeyFactory.DSA",
|
||||
gnu.java.security.provider.DSAKeyFactory.class.getName());
|
||||
|
||||
put("KeyFactory.Encoded", EncodedKeyFactory.class.getName());
|
||||
put("KeyFactory.Encoded ImplementedIn", "Software");
|
||||
put("Alg.Alias.KeyFactory.X.509", "Encoded");
|
||||
put("Alg.Alias.KeyFactory.X509", "Encoded");
|
||||
put("Alg.Alias.KeyFactory.PKCS#8", "Encoded");
|
||||
put("Alg.Alias.KeyFactory.PKCS8", "Encoded");
|
||||
|
||||
put("KeyFactory.RSA", RSAKeyFactory.class.getName());
|
||||
|
||||
put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
|
||||
put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
|
||||
put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
|
||||
|
||||
// Message Digests
|
||||
put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName());
|
||||
put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName());
|
||||
|
||||
// Format "Alias", "Actual Name"
|
||||
put("Alg.Alias.MessageDigest.SHA1", "SHA");
|
||||
put("Alg.Alias.MessageDigest.SHA-1", "SHA");
|
||||
put("Alg.Alias.MessageDigest.SHA-160", "SHA");
|
||||
|
||||
// Algorithm Parameters
|
||||
put("AlgorithmParameters.DSA",
|
||||
gnu.java.security.provider.DSAParameters.class.getName());
|
||||
|
||||
put("Alg.Alias.AlgorithmParameters.DSS", "DSA");
|
||||
put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSA");
|
||||
put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSA");
|
||||
put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSA");
|
||||
|
||||
// Algorithm Parameter Generator
|
||||
put("AlgorithmParameterGenerator.DSA",
|
||||
gnu.java.security.provider.DSAParameterGenerator.class.getName());
|
||||
|
||||
// SecureRandom
|
||||
put("SecureRandom.SHA1PRNG",
|
||||
gnu.java.security.provider.SHA1PRNG.class.getName());
|
||||
|
||||
// CertificateFactory
|
||||
put("CertificateFactory.X509", X509CertificateFactory.class.getName());
|
||||
|
||||
put("CertificateFactory.X509 ImplementedIn", "Software");
|
||||
put("Alg.Alias.CertificateFactory.X.509", "X509");
|
||||
|
||||
// CertPathValidator
|
||||
put("CertPathValidator.PKIX", PKIXCertPathValidatorImpl.class.getName());
|
||||
put("CertPathValidator.PKIX ImplementedIn", "Software");
|
||||
|
||||
// CertStore
|
||||
put("CertStore.Collection", CollectionCertStoreImpl.class.getName());
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/* GnuDHPublicKey.java -- A Diffie-Hellman public key.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.BitString;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.crypto.interfaces.DHPublicKey;
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
|
||||
public class GnuDHPublicKey implements DHPublicKey
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private byte[] encoded;
|
||||
private final DHParameterSpec params;
|
||||
private final BigInteger Y;
|
||||
private final BigInteger q;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public GnuDHPublicKey(DHParameterSpec params, BigInteger Y, BigInteger q)
|
||||
{
|
||||
this.params = params;
|
||||
this.Y = Y;
|
||||
this.q = q;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public BigInteger getY()
|
||||
{
|
||||
return Y;
|
||||
}
|
||||
|
||||
public DHParameterSpec getParams()
|
||||
{
|
||||
return params;
|
||||
}
|
||||
|
||||
public String getAlgorithm()
|
||||
{
|
||||
return "DH";
|
||||
}
|
||||
|
||||
public String getFormat()
|
||||
{
|
||||
return "X.509";
|
||||
}
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encoded != null)
|
||||
return (byte[]) encoded.clone();
|
||||
ArrayList spki = new ArrayList(2);
|
||||
ArrayList alg = new ArrayList(2);
|
||||
alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.10046.2.1")));
|
||||
ArrayList param = new ArrayList(3);
|
||||
param.add(new DERValue(DER.INTEGER, params.getP()));
|
||||
param.add(new DERValue(DER.INTEGER, params.getG()));
|
||||
param.add(new DERValue(DER.INTEGER, q));
|
||||
alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, param));
|
||||
spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
|
||||
spki.add(new DERValue(DER.BIT_STRING, new BitString(Y.toByteArray())));
|
||||
encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki).getEncoded();
|
||||
if (encoded != null)
|
||||
return (byte[]) encoded.clone();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/* GnuDSAPrivateKey.java --- Gnu DSA Private Key
|
||||
Copyright (C) 1999,2003,2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.der.DERWriter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPrivateKey;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GnuDSAPrivateKey implements DSAPrivateKey
|
||||
{
|
||||
private byte[] encodedKey;
|
||||
BigInteger x;
|
||||
BigInteger p;
|
||||
BigInteger q;
|
||||
BigInteger g;
|
||||
|
||||
public GnuDSAPrivateKey(BigInteger x, BigInteger p, BigInteger q, BigInteger g )
|
||||
{
|
||||
this.x = x;
|
||||
this.p = p;
|
||||
this.q = q;
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
public String getAlgorithm()
|
||||
{
|
||||
return "DSA";
|
||||
}
|
||||
|
||||
public String getFormat()
|
||||
{
|
||||
return "PKCS#8";
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this key as a <code>PrivateKeyInfo</code>, as described in
|
||||
* PKCS #8. The ASN.1 specification for this structure is:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* PrivateKeyInfo ::= SEQUENCE {
|
||||
* version Version,
|
||||
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
|
||||
* privateKey PrivateKey,
|
||||
* attributes [0] IMPLICIT Attributes OPTIONAL }
|
||||
*
|
||||
* Version ::= INTEGER
|
||||
*
|
||||
* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
*
|
||||
* PrivateKey ::= OCTET STRING
|
||||
*
|
||||
* Attributes ::= SET OF Attribute
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <p>DSA private keys (in Classpath at least) have no attributes.
|
||||
*/
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encodedKey != null)
|
||||
return (byte[]) encodedKey.clone();
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ArrayList pki = new ArrayList(3);
|
||||
pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
|
||||
ArrayList algId = new ArrayList(2);
|
||||
algId.add(new DERValue(DER.OBJECT_IDENTIFIER,
|
||||
new OID("1.2.840.10040.4.1")));
|
||||
ArrayList algParams = new ArrayList(3);
|
||||
algParams.add(new DERValue(DER.INTEGER, p));
|
||||
algParams.add(new DERValue(DER.INTEGER, q));
|
||||
algParams.add(new DERValue(DER.INTEGER, g));
|
||||
algId.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, algParams));
|
||||
pki.add(new DERValue(DER.OCTET_STRING, x.toByteArray()));
|
||||
DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, pki));
|
||||
return (byte[]) (encodedKey = out.toByteArray()).clone();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public DSAParams getParams()
|
||||
{
|
||||
return (DSAParams)(new DSAParameterSpec(p,q,g));
|
||||
}
|
||||
|
||||
public BigInteger getX()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "GnuDSAPrivateKey: x="
|
||||
+ (x != null ? x.toString(16) : "null") + " p="
|
||||
+ (p != null ? p.toString(16) : "null") + " q="
|
||||
+ (q != null ? q.toString(16) : "null") + " g="
|
||||
+ (g != null ? g.toString(16) : "null");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/* GnuDSAPublicKey.java --- Gnu DSA Public Key
|
||||
Copyright (C) 1999,2003,2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.BitString;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.der.DERWriter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GnuDSAPublicKey implements DSAPublicKey
|
||||
{
|
||||
private byte[] encodedKey;
|
||||
BigInteger y;
|
||||
BigInteger p;
|
||||
BigInteger q;
|
||||
BigInteger g;
|
||||
|
||||
public GnuDSAPublicKey(BigInteger y, BigInteger p, BigInteger q, BigInteger g )
|
||||
{
|
||||
this.y = y;
|
||||
this.p = p;
|
||||
this.q = q;
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
public String getAlgorithm()
|
||||
{
|
||||
return "DSA";
|
||||
}
|
||||
|
||||
public String getFormat()
|
||||
{
|
||||
return "X.509";
|
||||
}
|
||||
|
||||
/**
|
||||
* The encoded form of DSA public keys is:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING }
|
||||
* </pre></blockquote>
|
||||
*/
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encodedKey != null)
|
||||
return (byte[]) encodedKey.clone();
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ArrayList spki = new ArrayList(2);
|
||||
ArrayList alg = new ArrayList(2);
|
||||
alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
|
||||
new OID("1.2.840.113549.1.1.1")));
|
||||
ArrayList params = new ArrayList(3);
|
||||
params.add(new DERValue(DER.INTEGER, p));
|
||||
params.add(new DERValue(DER.INTEGER, q));
|
||||
params.add(new DERValue(DER.INTEGER, g));
|
||||
alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, params));
|
||||
spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
|
||||
spki.add(new DERValue(DER.BIT_STRING, new BitString(y.toByteArray())));
|
||||
DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki));
|
||||
return (byte[]) (encodedKey = out.toByteArray()).clone();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public DSAParams getParams()
|
||||
{
|
||||
if (p == null || q == null || g == null)
|
||||
return null;
|
||||
return (DSAParams)(new DSAParameterSpec(p,q,g));
|
||||
}
|
||||
|
||||
public BigInteger getY()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return
|
||||
"GnuDSAPublicKey: y=" + (y != null ? y.toString(16) : "(null)") +
|
||||
" p=" + (p != null ? p.toString(16) : "(null)") +
|
||||
" q=" + (q != null ? q.toString(16) : "(null)") +
|
||||
" g=" + (g != null ? g.toString(16) : "(null)");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/* GnuRSAPrivateKey.java -- GNU RSA private key.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.interfaces.RSAPrivateCrtKey;
|
||||
import java.security.spec.RSAPrivateCrtKeySpec;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class GnuRSAPrivateKey implements RSAPrivateCrtKey
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private final RSAPrivateCrtKeySpec spec;
|
||||
private byte[] encodedKey;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public GnuRSAPrivateKey(RSAPrivateCrtKeySpec spec)
|
||||
{
|
||||
this.spec = spec;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public BigInteger getModulus()
|
||||
{
|
||||
return spec.getModulus();
|
||||
}
|
||||
|
||||
public BigInteger getPrivateExponent()
|
||||
{
|
||||
return spec.getPrivateExponent();
|
||||
}
|
||||
|
||||
public BigInteger getCrtCoefficient()
|
||||
{
|
||||
return spec.getCrtCoefficient();
|
||||
}
|
||||
|
||||
public BigInteger getPrimeExponentP()
|
||||
{
|
||||
return spec.getPrimeExponentP();
|
||||
}
|
||||
|
||||
public BigInteger getPrimeExponentQ()
|
||||
{
|
||||
return spec.getPrimeExponentQ();
|
||||
}
|
||||
|
||||
public BigInteger getPrimeP()
|
||||
{
|
||||
return spec.getPrimeP();
|
||||
}
|
||||
|
||||
public BigInteger getPrimeQ()
|
||||
{
|
||||
return spec.getPrimeQ();
|
||||
}
|
||||
|
||||
public BigInteger getPublicExponent()
|
||||
{
|
||||
return spec.getPublicExponent();
|
||||
}
|
||||
|
||||
public String getAlgorithm()
|
||||
{
|
||||
return "RSA";
|
||||
}
|
||||
|
||||
public String getFormat()
|
||||
{
|
||||
return "PKCS#8";
|
||||
}
|
||||
|
||||
/**
|
||||
* The encoded form is:
|
||||
*
|
||||
* <pre>
|
||||
* RSAPrivateKey ::= SEQUENCE {
|
||||
* version Version,
|
||||
* modulus INTEGER, -- n
|
||||
* publicExponent INTEGER, -- e
|
||||
* privateExponent INTEGER, -- d
|
||||
* prime1 INTEGER, -- p
|
||||
* prime2 INTEGER, -- q
|
||||
* exponent1 INTEGER, -- d mod (p-1)
|
||||
* exponent2 INTEGER, -- d mod (q-1)
|
||||
* coefficient INTEGER -- (inverse of q) mod p }
|
||||
* </pre>
|
||||
*
|
||||
* <p>Which is in turn encoded in a PrivateKeyInfo structure from PKCS#8.
|
||||
*/
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encodedKey != null)
|
||||
return (byte[]) encodedKey.clone();
|
||||
ArrayList key = new ArrayList(9);
|
||||
key.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
|
||||
key.add(new DERValue(DER.INTEGER, getModulus()));
|
||||
key.add(new DERValue(DER.INTEGER, getPublicExponent()));
|
||||
key.add(new DERValue(DER.INTEGER, getPrivateExponent()));
|
||||
key.add(new DERValue(DER.INTEGER, getPrimeP()));
|
||||
key.add(new DERValue(DER.INTEGER, getPrimeQ()));
|
||||
key.add(new DERValue(DER.INTEGER, getPrimeExponentP()));
|
||||
key.add(new DERValue(DER.INTEGER, getPrimeExponentQ()));
|
||||
key.add(new DERValue(DER.INTEGER, getCrtCoefficient()));
|
||||
DERValue pk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key);
|
||||
ArrayList pki = new ArrayList(3);
|
||||
pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
|
||||
ArrayList alg = new ArrayList(2);
|
||||
alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
|
||||
new OID("1.2.840.113549.1.1.1")));
|
||||
alg.add(new DERValue(DER.NULL, null));
|
||||
pki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
|
||||
pki.add(new DERValue(DER.OCTET_STRING, pk.getEncoded()));
|
||||
encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, pki).getEncoded();
|
||||
return (byte[]) encodedKey.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/* GnuRSAPublicKey.java -- GNU RSA public key.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.BitString;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class GnuRSAPublicKey implements RSAPublicKey
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private final RSAPublicKeySpec spec;
|
||||
private byte[] encodedKey;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public GnuRSAPublicKey(RSAPublicKeySpec spec)
|
||||
{
|
||||
this.spec = spec;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public BigInteger getModulus()
|
||||
{
|
||||
return spec.getModulus();
|
||||
}
|
||||
|
||||
public BigInteger getPublicExponent()
|
||||
{
|
||||
return spec.getPublicExponent();
|
||||
}
|
||||
|
||||
public String getAlgorithm()
|
||||
{
|
||||
return "RSA";
|
||||
}
|
||||
|
||||
public String getFormat()
|
||||
{
|
||||
return "X.509";
|
||||
}
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encodedKey != null)
|
||||
return (byte[]) encodedKey.clone();
|
||||
ArrayList key = new ArrayList(2);
|
||||
key.add(new DERValue(DER.INTEGER, getModulus()));
|
||||
key.add(new DERValue(DER.INTEGER, getPublicExponent()));
|
||||
DERValue rsapk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key);
|
||||
ArrayList alg = new ArrayList(2);
|
||||
alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
|
||||
new OID("1.2.840.113549.1.1.1")));
|
||||
alg.add(new DERValue(DER.NULL, null));
|
||||
ArrayList spki = new ArrayList(2);
|
||||
spki.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, alg));
|
||||
spki.add(new DERValue(DER.BIT_STRING, new BitString(rsapk.getEncoded())));
|
||||
encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, spki).getEncoded();
|
||||
return (byte[]) encodedKey.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* MD2withRSA.java -- MD2 with RSA encryption signatures.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD2withRSA extends RSA
|
||||
{
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public MD2withRSA() throws NoSuchAlgorithmException
|
||||
{
|
||||
super(MessageDigest.getInstance("MD2"), DIGEST_ALGORITHM.getChild(2));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* MD4withRSA.java -- MD4 with RSA encryption signatures.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD4withRSA extends RSA
|
||||
{
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public MD4withRSA() throws NoSuchAlgorithmException
|
||||
{
|
||||
super(MessageDigest.getInstance("MD4"), DIGEST_ALGORITHM.getChild(4));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
/* MD5.java -- Class implementing the MD5 algorithm as specified in RFC1321.
|
||||
Copyright (C) 1999, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
This class implements the MD5 algorithm as described in RFC1321.
|
||||
|
||||
@see java.security.MessageDigest
|
||||
*/
|
||||
public class MD5 extends MessageDigest implements Cloneable
|
||||
{
|
||||
private final int W[] = new int[16];
|
||||
private long bytecount;
|
||||
private int A;
|
||||
private int B;
|
||||
private int C;
|
||||
private int D;
|
||||
|
||||
public MD5()
|
||||
{
|
||||
super("MD5");
|
||||
engineReset ();
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
return new MD5 (this);
|
||||
}
|
||||
|
||||
private MD5 (MD5 copy)
|
||||
{
|
||||
this ();
|
||||
bytecount = copy.bytecount;
|
||||
A = copy.A;
|
||||
B = copy.B;
|
||||
C = copy.C;
|
||||
D = copy.D;
|
||||
System.arraycopy (copy.W, 0, W, 0, 16);
|
||||
}
|
||||
|
||||
public int engineGetDigestLength()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
// Intialize the A,B,C,D needed for the hash
|
||||
public void engineReset()
|
||||
{
|
||||
bytecount = 0;
|
||||
A = 0x67452301;
|
||||
B = 0xefcdab89;
|
||||
C = 0x98badcfe;
|
||||
D = 0x10325476;
|
||||
for(int i = 0; i < 16; i++)
|
||||
W[i] = 0;
|
||||
}
|
||||
|
||||
public void engineUpdate (byte b)
|
||||
{
|
||||
int i = (int)bytecount % 64;
|
||||
int shift = (3 - i % 4) * 8;
|
||||
int idx = i / 4;
|
||||
|
||||
// if you could index ints, this would be: W[idx][shift/8] = b
|
||||
W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift);
|
||||
|
||||
// if we've filled up a block, then process it
|
||||
if ((++ bytecount) % 64 == 0)
|
||||
munch ();
|
||||
}
|
||||
|
||||
public void engineUpdate (byte bytes[], int off, int len)
|
||||
{
|
||||
if (len < 0)
|
||||
throw new ArrayIndexOutOfBoundsException ();
|
||||
|
||||
int end = off + len;
|
||||
while (off < end)
|
||||
engineUpdate (bytes[off++]);
|
||||
}
|
||||
|
||||
public byte[] engineDigest()
|
||||
{
|
||||
long bitcount = bytecount * 8;
|
||||
engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding
|
||||
|
||||
// add the rest of the padding to fill this block out, but leave 8
|
||||
// bytes to put in the original bytecount
|
||||
while ((int)bytecount % 64 != 56)
|
||||
engineUpdate ((byte)0);
|
||||
|
||||
// add the length of the original, unpadded block to the end of
|
||||
// the padding
|
||||
W[14] = SWAP((int)(0xffffffff & bitcount));
|
||||
W[15] = SWAP((int)(0xffffffff & (bitcount >>> 32)));
|
||||
bytecount += 8;
|
||||
|
||||
// digest the fully padded block
|
||||
munch ();
|
||||
|
||||
A = SWAP(A);
|
||||
B = SWAP(B);
|
||||
C = SWAP(C);
|
||||
D = SWAP(D);
|
||||
byte[] result = new byte[] {(byte)(A >>> 24), (byte)(A >>> 16),
|
||||
(byte)(A >>> 8), (byte)A,
|
||||
(byte)(B >>> 24), (byte)(B >>> 16),
|
||||
(byte)(B >>> 8), (byte)B,
|
||||
(byte)(C >>> 24), (byte)(C >>> 16),
|
||||
(byte)(C >>> 8), (byte)C,
|
||||
(byte)(D >>> 24), (byte)(D >>> 16),
|
||||
(byte)(D >>> 8), (byte)D};
|
||||
|
||||
engineReset ();
|
||||
return result;
|
||||
}
|
||||
|
||||
private int F( int X, int Y, int Z)
|
||||
{
|
||||
return ((X & Y) | (~X & Z));
|
||||
}
|
||||
|
||||
private int G( int X, int Y, int Z)
|
||||
{
|
||||
return ((X & Z) | (Y & ~Z));
|
||||
}
|
||||
|
||||
private int H( int X, int Y, int Z)
|
||||
{
|
||||
return (X ^ Y ^ Z);
|
||||
}
|
||||
|
||||
private int I( int X, int Y, int Z)
|
||||
{
|
||||
return (Y ^ (X | ~Z));
|
||||
}
|
||||
|
||||
private int rotateLeft( int i, int count)
|
||||
{
|
||||
//Taken from FIPS 180-1
|
||||
return ( (i << count) | (i >>> (32 - count)) ) ;
|
||||
}
|
||||
|
||||
/* Round 1. */
|
||||
private int FF( int a, int b, int c, int d, int k, int s, int i)
|
||||
{
|
||||
/* Let [abcd k s i] denote the operation */
|
||||
a += F(b,c,d) + k + i;
|
||||
return b + rotateLeft(a, s);
|
||||
}
|
||||
/* Round 2. */
|
||||
private int GG( int a, int b, int c, int d, int k, int s, int i)
|
||||
{
|
||||
/* Let [abcd k s i] denote the operation */
|
||||
a += G(b,c,d) + k + i;
|
||||
return b + rotateLeft(a, s);
|
||||
}
|
||||
/* Round 3. */
|
||||
private int HH( int a, int b, int c, int d, int k, int s, int i)
|
||||
{
|
||||
/* Let [abcd k s t] denote the operation */
|
||||
a += H(b,c,d) + k + i;
|
||||
return b + rotateLeft(a, s);
|
||||
}
|
||||
|
||||
/* Round 4. */
|
||||
private int II( int a, int b, int c, int d, int k, int s, int i)
|
||||
{
|
||||
/* Let [abcd k s t] denote the operation */
|
||||
a += I(b,c,d) + k + i;
|
||||
return b + rotateLeft(a, s);
|
||||
}
|
||||
|
||||
private int SWAP(int n)
|
||||
{
|
||||
//Copied from md5.c in FSF Gnu Privacy Guard 0.9.2
|
||||
return (( (0xff & n) << 24) | ((n & 0xff00) << 8) | ((n >>> 8) & 0xff00) | (n >>> 24));
|
||||
}
|
||||
|
||||
private void munch()
|
||||
{
|
||||
int AA,BB,CC,DD, j;
|
||||
int X[] = new int[16];
|
||||
|
||||
/* Copy block i into X. */
|
||||
for(j = 0; j < 16; j++)
|
||||
X[j] = SWAP(W[j]);
|
||||
|
||||
/* Save A as AA, B as BB, C as CC, and D as DD. */
|
||||
AA = A;
|
||||
BB = B;
|
||||
CC = C;
|
||||
DD = D;
|
||||
|
||||
/* The hex constants are from md5.c
|
||||
in FSF Gnu Privacy Guard 0.9.2 */
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Do the following 16 operations. */
|
||||
A = FF(A,B,C,D, X[0], 7, 0xd76aa478);
|
||||
D = FF(D,A,B,C, X[1], 12, 0xe8c7b756);
|
||||
C = FF(C,D,A,B, X[2], 17, 0x242070db);
|
||||
B = FF(B,C,D,A, X[3], 22, 0xc1bdceee);
|
||||
|
||||
A = FF(A,B,C,D, X[4], 7, 0xf57c0faf);
|
||||
D = FF(D,A,B,C, X[5], 12, 0x4787c62a);
|
||||
C = FF(C,D,A,B, X[6], 17, 0xa8304613);
|
||||
B = FF(B,C,D,A, X[7], 22, 0xfd469501);
|
||||
|
||||
A = FF(A,B,C,D, X[8], 7, 0x698098d8);
|
||||
D = FF(D,A,B,C, X[9], 12, 0x8b44f7af);
|
||||
C = FF(C,D,A,B, X[10], 17, 0xffff5bb1);
|
||||
B = FF(B,C,D,A, X[11], 22, 0x895cd7be);
|
||||
|
||||
A = FF(A,B,C,D, X[12], 7, 0x6b901122);
|
||||
D = FF(D,A,B,C, X[13], 12, 0xfd987193);
|
||||
C = FF(C,D,A,B, X[14], 17, 0xa679438e);
|
||||
B = FF(B,C,D,A, X[15], 22, 0x49b40821);
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Do the following 16 operations. */
|
||||
A = GG(A,B,C,D, X[1], 5, 0xf61e2562);
|
||||
D = GG(D,A,B,C, X[6], 9, 0xc040b340);
|
||||
C = GG(C,D,A,B, X[11], 14, 0x265e5a51);
|
||||
B = GG(B,C,D,A, X[0], 20, 0xe9b6c7aa);
|
||||
|
||||
A = GG(A,B,C,D, X[5], 5, 0xd62f105d);
|
||||
D = GG(D,A,B,C, X[10], 9, 0x02441453);
|
||||
C = GG(C,D,A,B, X[15], 14, 0xd8a1e681);
|
||||
B = GG(B,C,D,A, X[4], 20, 0xe7d3fbc8);
|
||||
|
||||
A = GG(A,B,C,D, X[9], 5, 0x21e1cde6);
|
||||
D = GG(D,A,B,C, X[14], 9, 0xc33707d6);
|
||||
C = GG(C,D,A,B, X[3], 14, 0xf4d50d87);
|
||||
B = GG(B,C,D,A, X[8], 20, 0x455a14ed);
|
||||
|
||||
A = GG(A,B,C,D, X[13], 5, 0xa9e3e905);
|
||||
D = GG(D,A,B,C, X[2], 9, 0xfcefa3f8);
|
||||
C = GG(C,D,A,B, X[7], 14, 0x676f02d9);
|
||||
B = GG(B,C,D,A, X[12], 20, 0x8d2a4c8a);
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Do the following 16 operations. */
|
||||
A = HH(A,B,C,D, X[5], 4, 0xfffa3942);
|
||||
D = HH(D,A,B,C, X[8], 11, 0x8771f681);
|
||||
C = HH(C,D,A,B, X[11], 16, 0x6d9d6122);
|
||||
B = HH(B,C,D,A, X[14], 23, 0xfde5380c);
|
||||
|
||||
A = HH(A,B,C,D, X[1], 4, 0xa4beea44);
|
||||
D = HH(D,A,B,C, X[4], 11, 0x4bdecfa9);
|
||||
C = HH(C,D,A,B, X[7], 16, 0xf6bb4b60);
|
||||
B = HH(B,C,D,A, X[10], 23, 0xbebfbc70);
|
||||
|
||||
A = HH(A,B,C,D, X[13], 4, 0x289b7ec6);
|
||||
D = HH(D,A,B,C, X[0], 11, 0xeaa127fa);
|
||||
C = HH(C,D,A,B, X[3], 16, 0xd4ef3085);
|
||||
B = HH(B,C,D,A, X[6], 23, 0x04881d05);
|
||||
|
||||
A = HH(A,B,C,D, X[9], 4, 0xd9d4d039);
|
||||
D = HH(D,A,B,C, X[12], 11, 0xe6db99e5);
|
||||
C = HH(C,D,A,B, X[15], 16, 0x1fa27cf8);
|
||||
B = HH(B,C,D,A, X[2], 23, 0xc4ac5665);
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Do the following 16 operations. */
|
||||
A = II(A,B,C,D, X[0], 6, 0xf4292244);
|
||||
D = II(D,A,B,C, X[7], 10, 0x432aff97);
|
||||
C = II(C,D,A,B, X[14], 15, 0xab9423a7);
|
||||
B = II(B,C,D,A, X[5], 21, 0xfc93a039);
|
||||
|
||||
A = II(A,B,C,D, X[12], 6, 0x655b59c3);
|
||||
D = II(D,A,B,C, X[3], 10, 0x8f0ccc92);
|
||||
C = II(C,D,A,B, X[10], 15, 0xffeff47d);
|
||||
B = II(B,C,D,A, X[1], 21, 0x85845dd1);
|
||||
|
||||
A = II(A,B,C,D, X[8], 6, 0x6fa87e4f);
|
||||
D = II(D,A,B,C, X[15], 10, 0xfe2ce6e0);
|
||||
C = II(C,D,A,B, X[6], 15, 0xa3014314);
|
||||
B = II(B,C,D,A, X[13], 21, 0x4e0811a1);
|
||||
|
||||
A = II(A,B,C,D, X[4], 6, 0xf7537e82);
|
||||
D = II(D,A,B,C, X[11], 10, 0xbd3af235);
|
||||
C = II(C,D,A,B, X[2], 15, 0x2ad7d2bb);
|
||||
B = II(B,C,D,A, X[9], 21, 0xeb86d391);
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
A = A + AA;
|
||||
B = B + BB;
|
||||
C = C + CC;
|
||||
D = D + DD;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* MD5withRSA.java -- MD5 with RSA encryption signatures.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5withRSA extends RSA
|
||||
{
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public MD5withRSA() throws NoSuchAlgorithmException
|
||||
{
|
||||
super(MessageDigest.getInstance("MD5"), DIGEST_ALGORITHM.getChild(5));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,701 @@
|
||||
/* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.x509.GnuPKIExtension;
|
||||
import gnu.java.security.x509.PolicyNodeImpl;
|
||||
import gnu.java.security.x509.X509CRLSelectorImpl;
|
||||
import gnu.java.security.x509.X509CertSelectorImpl;
|
||||
import gnu.java.security.x509.ext.BasicConstraints;
|
||||
import gnu.java.security.x509.ext.CertificatePolicies;
|
||||
import gnu.java.security.x509.ext.Extension;
|
||||
import gnu.java.security.x509.ext.KeyUsage;
|
||||
import gnu.java.security.x509.ext.PolicyConstraint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CRL;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertPathParameters;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertPathValidatorResult;
|
||||
import java.security.cert.CertPathValidatorSpi;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.PKIXCertPathValidatorResult;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509CRL;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An implementation of the Public Key Infrastructure's X.509
|
||||
* certificate path validation algorithm.
|
||||
*
|
||||
* <p>See <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
|
||||
* Internet X.509 Public Key Infrastructure Certificate and
|
||||
* Certificate Revocation List (CRL) Profile</a>.
|
||||
*
|
||||
* @author Casey Marshall (rsdio@metastatic.org)
|
||||
*/
|
||||
public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
|
||||
{
|
||||
|
||||
// Constants.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static void debug (String msg)
|
||||
{
|
||||
System.err.print (">> PKIXCertPathValidatorImpl: ");
|
||||
System.err.println (msg);
|
||||
}
|
||||
|
||||
public static final String ANY_POLICY = "2.5.29.32.0";
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public PKIXCertPathValidatorImpl()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public CertPathValidatorResult engineValidate(CertPath path,
|
||||
CertPathParameters params)
|
||||
throws CertPathValidatorException, InvalidAlgorithmParameterException
|
||||
{
|
||||
if (!(params instanceof PKIXParameters))
|
||||
throw new InvalidAlgorithmParameterException("not a PKIXParameters object");
|
||||
|
||||
// First check if the certificate path is valid.
|
||||
//
|
||||
// This means that:
|
||||
//
|
||||
// (a) for all x in {1, ..., n-1}, the subject of certificate x is
|
||||
// the issuer of certificate x+1;
|
||||
//
|
||||
// (b) for all x in {1, ..., n}, the certificate was valid at the
|
||||
// time in question.
|
||||
//
|
||||
// Because this is the X.509 algorithm, we also check if all
|
||||
// cerificates are of type X509Certificate.
|
||||
|
||||
PolicyNodeImpl rootNode = new PolicyNodeImpl();
|
||||
Set initPolicies = ((PKIXParameters) params).getInitialPolicies();
|
||||
rootNode.setValidPolicy(ANY_POLICY);
|
||||
rootNode.setCritical(false);
|
||||
rootNode.setDepth(0);
|
||||
if (initPolicies != null)
|
||||
rootNode.addAllExpectedPolicies(initPolicies);
|
||||
else
|
||||
rootNode.addExpectedPolicy(ANY_POLICY);
|
||||
List checks = ((PKIXParameters) params).getCertPathCheckers();
|
||||
List l = path.getCertificates();
|
||||
if (l == null || l.size() == 0)
|
||||
throw new CertPathValidatorException();
|
||||
X509Certificate[] p = null;
|
||||
try
|
||||
{
|
||||
p = (X509Certificate[]) l.toArray(new X509Certificate[l.size()]);
|
||||
}
|
||||
catch (ClassCastException cce)
|
||||
{
|
||||
throw new CertPathValidatorException("invalid certificate path");
|
||||
}
|
||||
|
||||
String sigProvider = ((PKIXParameters) params).getSigProvider();
|
||||
PublicKey prevKey = null;
|
||||
Date now = ((PKIXParameters) params).getDate();
|
||||
if (now == null)
|
||||
now = new Date();
|
||||
LinkedList policyConstraints = new LinkedList();
|
||||
for (int i = p.length - 1; i >= 0; i--)
|
||||
{
|
||||
try
|
||||
{
|
||||
p[i].checkValidity(now);
|
||||
}
|
||||
catch (CertificateException ce)
|
||||
{
|
||||
throw new CertPathValidatorException(ce.toString());
|
||||
}
|
||||
Set uce = getCritExts(p[i]);
|
||||
for (Iterator check = checks.iterator(); check.hasNext(); )
|
||||
{
|
||||
try
|
||||
{
|
||||
((PKIXCertPathChecker) check.next()).check(p[i], uce);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
PolicyConstraint constr = null;
|
||||
if (p[i] instanceof GnuPKIExtension)
|
||||
{
|
||||
Extension pcx =
|
||||
((GnuPKIExtension) p[i]).getExtension (PolicyConstraint.ID);
|
||||
if (pcx != null)
|
||||
constr = (PolicyConstraint) pcx.getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] pcx = p[i].getExtensionValue (PolicyConstraint.ID.toString());
|
||||
if (pcx != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
constr = new PolicyConstraint (pcx);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
if (constr != null && constr.getRequireExplicitPolicy() >= 0)
|
||||
{
|
||||
policyConstraints.add (new int[]
|
||||
{ p.length-i, constr.getRequireExplicitPolicy() });
|
||||
}
|
||||
|
||||
updatePolicyTree(p[i], rootNode, p.length-i, (PKIXParameters) params,
|
||||
checkExplicitPolicy (p.length-i, policyConstraints));
|
||||
|
||||
// The rest of the tests involve this cert's relationship with the
|
||||
// next in the path. If this cert is the end entity, we can stop.
|
||||
if (i == 0)
|
||||
break;
|
||||
|
||||
basicSanity(p, i);
|
||||
PublicKey pubKey = null;
|
||||
try
|
||||
{
|
||||
pubKey = p[i].getPublicKey();
|
||||
if (pubKey instanceof DSAPublicKey)
|
||||
{
|
||||
DSAParams dsa = ((DSAPublicKey) pubKey).getParams();
|
||||
// If the DSA public key is missing its parameters, use those
|
||||
// from the previous cert's key.
|
||||
if (dsa == null || dsa.getP() == null || dsa.getG() == null
|
||||
|| dsa.getQ() == null)
|
||||
{
|
||||
if (prevKey == null)
|
||||
throw new InvalidKeyException("DSA keys not chainable");
|
||||
if (!(prevKey instanceof DSAPublicKey))
|
||||
throw new InvalidKeyException("DSA keys not chainable");
|
||||
dsa = ((DSAPublicKey) prevKey).getParams();
|
||||
pubKey = new GnuDSAPublicKey(((DSAPublicKey) pubKey).getY(),
|
||||
dsa.getP(), dsa.getQ(), dsa.getG());
|
||||
}
|
||||
}
|
||||
if (sigProvider == null)
|
||||
p[i-1].verify(pubKey);
|
||||
else
|
||||
p[i-1].verify(pubKey, sigProvider);
|
||||
prevKey = pubKey;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertPathValidatorException(e.toString());
|
||||
}
|
||||
if (!p[i].getSubjectDN().equals(p[i-1].getIssuerDN()))
|
||||
throw new CertPathValidatorException("issuer DN mismatch");
|
||||
boolean[] issuerUid = p[i-1].getIssuerUniqueID();
|
||||
boolean[] subjectUid = p[i].getSubjectUniqueID();
|
||||
if (issuerUid != null && subjectUid != null)
|
||||
if (!Arrays.equals(issuerUid, subjectUid))
|
||||
throw new CertPathValidatorException("UID mismatch");
|
||||
|
||||
// Check the certificate against the revocation lists.
|
||||
if (((PKIXParameters) params).isRevocationEnabled())
|
||||
{
|
||||
X509CRLSelectorImpl selector = new X509CRLSelectorImpl();
|
||||
try
|
||||
{
|
||||
selector.addIssuerName(p[i].getSubjectDN());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new CertPathValidatorException("error selecting CRLs");
|
||||
}
|
||||
List certStores = ((PKIXParameters) params).getCertStores();
|
||||
List crls = new LinkedList();
|
||||
for (Iterator it = certStores.iterator(); it.hasNext(); )
|
||||
{
|
||||
CertStore cs = (CertStore) it.next();
|
||||
try
|
||||
{
|
||||
Collection c = cs.getCRLs(selector);
|
||||
crls.addAll(c);
|
||||
}
|
||||
catch (CertStoreException cse)
|
||||
{
|
||||
}
|
||||
}
|
||||
if (crls.isEmpty())
|
||||
throw new CertPathValidatorException("no CRLs for issuer");
|
||||
boolean certOk = false;
|
||||
for (Iterator it = crls.iterator(); it.hasNext(); )
|
||||
{
|
||||
CRL crl = (CRL) it.next();
|
||||
if (!(crl instanceof X509CRL))
|
||||
continue;
|
||||
X509CRL xcrl = (X509CRL) crl;
|
||||
if (!checkCRL(xcrl, p, now, p[i], pubKey, certStores))
|
||||
continue;
|
||||
if (xcrl.isRevoked(p[i-1]))
|
||||
throw new CertPathValidatorException("certificate is revoked");
|
||||
else
|
||||
certOk = true;
|
||||
}
|
||||
if (!certOk)
|
||||
throw new CertPathValidatorException("certificate's validity could not be determined");
|
||||
}
|
||||
}
|
||||
rootNode.setReadOnly();
|
||||
|
||||
// Now ensure that the first certificate in the chain was issued
|
||||
// by a trust anchor.
|
||||
Exception cause = null;
|
||||
Set anchors = ((PKIXParameters) params).getTrustAnchors();
|
||||
for (Iterator i = anchors.iterator(); i.hasNext(); )
|
||||
{
|
||||
TrustAnchor anchor = (TrustAnchor) i.next();
|
||||
X509Certificate anchorCert = null;
|
||||
PublicKey anchorKey = null;
|
||||
if (anchor.getTrustedCert() != null)
|
||||
{
|
||||
anchorCert = anchor.getTrustedCert();
|
||||
anchorKey = anchorCert.getPublicKey();
|
||||
}
|
||||
else
|
||||
anchorKey = anchor.getCAPublicKey();
|
||||
if (anchorKey == null)
|
||||
continue;
|
||||
try
|
||||
{
|
||||
if (anchorCert == null)
|
||||
anchorCert.checkValidity(now);
|
||||
p[p.length-1].verify(anchorKey);
|
||||
if (anchorCert != null && anchorCert.getBasicConstraints() >= 0
|
||||
&& anchorCert.getBasicConstraints() < p.length)
|
||||
continue;
|
||||
|
||||
if (((PKIXParameters) params).isRevocationEnabled())
|
||||
{
|
||||
X509CRLSelectorImpl selector = new X509CRLSelectorImpl();
|
||||
if (anchorCert != null)
|
||||
try
|
||||
{
|
||||
selector.addIssuerName(anchorCert.getSubjectDN());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
else
|
||||
selector.addIssuerName(anchor.getCAName());
|
||||
List certStores = ((PKIXParameters) params).getCertStores();
|
||||
List crls = new LinkedList();
|
||||
for (Iterator it = certStores.iterator(); it.hasNext(); )
|
||||
{
|
||||
CertStore cs = (CertStore) it.next();
|
||||
try
|
||||
{
|
||||
Collection c = cs.getCRLs(selector);
|
||||
crls.addAll(c);
|
||||
}
|
||||
catch (CertStoreException cse)
|
||||
{
|
||||
}
|
||||
}
|
||||
if (crls.isEmpty())
|
||||
continue;
|
||||
for (Iterator it = crls.iterator(); it.hasNext(); )
|
||||
{
|
||||
CRL crl = (CRL) it.next();
|
||||
if (!(crl instanceof X509CRL))
|
||||
continue;
|
||||
X509CRL xcrl = (X509CRL) crl;
|
||||
try
|
||||
{
|
||||
xcrl.verify(anchorKey);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Date nextUpdate = xcrl.getNextUpdate();
|
||||
if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
|
||||
continue;
|
||||
if (xcrl.isRevoked(p[p.length-1]))
|
||||
throw new CertPathValidatorException("certificate is revoked");
|
||||
}
|
||||
}
|
||||
|
||||
// The chain is valid; return the result.
|
||||
return new PKIXCertPathValidatorResult(anchor, rootNode,
|
||||
p[0].getPublicKey());
|
||||
}
|
||||
catch (Exception ignored)
|
||||
{
|
||||
cause = ignored;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The path is not valid.
|
||||
CertPathValidatorException cpve =
|
||||
new CertPathValidatorException("path validation failed");
|
||||
if (cause != null)
|
||||
cpve.initCause (cause);
|
||||
throw cpve;
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Check if a given CRL is acceptable for checking the revocation status
|
||||
* of certificates in the path being checked.
|
||||
*
|
||||
* <p>The CRL is accepted iff:</p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>The <i>nextUpdate</i> field (if present) is in the future.</li>
|
||||
* <li>The CRL does not contain any unsupported critical extensions.</li>
|
||||
* <li>The CRL is signed by one of the certificates in the path, or,</li>
|
||||
* <li>The CRL is signed by the given public key and was issued by the
|
||||
* public key's subject, or,</li>
|
||||
* <li>The CRL is signed by a certificate in the given cert stores, and
|
||||
* that cert is signed by one of the certificates in the path.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param crl The CRL being checked.
|
||||
* @param path The path this CRL is being checked against.
|
||||
* @param now The value to use as 'now'.
|
||||
* @param pubKeySubject The subject of the public key.
|
||||
* @param pubKey The public key to check.
|
||||
* @return True if the CRL is acceptable.
|
||||
*/
|
||||
private static boolean checkCRL(X509CRL crl, X509Certificate[] path, Date now,
|
||||
X509Certificate pubKeyCert, PublicKey pubKey,
|
||||
List certStores)
|
||||
{
|
||||
Date nextUpdate = crl.getNextUpdate();
|
||||
if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
|
||||
return false;
|
||||
if (crl.hasUnsupportedCriticalExtension())
|
||||
return false;
|
||||
for (int i = 0; i < path.length; i++)
|
||||
{
|
||||
if (!path[i].getSubjectDN().equals(crl.getIssuerDN()))
|
||||
continue;
|
||||
boolean[] keyUsage = path[i].getKeyUsage();
|
||||
if (keyUsage != null)
|
||||
{
|
||||
if (!keyUsage[KeyUsage.CRL_SIGN])
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
crl.verify(path[i].getPublicKey());
|
||||
return true;
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
if (crl.getIssuerDN().equals(pubKeyCert.getSubjectDN()))
|
||||
{
|
||||
try
|
||||
{
|
||||
boolean[] keyUsage = pubKeyCert.getKeyUsage();
|
||||
if (keyUsage != null)
|
||||
{
|
||||
if (!keyUsage[KeyUsage.CRL_SIGN])
|
||||
throw new Exception();
|
||||
}
|
||||
crl.verify(pubKey);
|
||||
return true;
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
X509CertSelectorImpl select = new X509CertSelectorImpl();
|
||||
select.addSubjectName(crl.getIssuerDN());
|
||||
List certs = new LinkedList();
|
||||
for (Iterator it = certStores.iterator(); it.hasNext(); )
|
||||
{
|
||||
CertStore cs = (CertStore) it.next();
|
||||
try
|
||||
{
|
||||
certs.addAll(cs.getCertificates(select));
|
||||
}
|
||||
catch (CertStoreException cse)
|
||||
{
|
||||
}
|
||||
}
|
||||
for (Iterator it = certs.iterator(); it.hasNext(); )
|
||||
{
|
||||
X509Certificate c = (X509Certificate) it.next();
|
||||
for (int i = 0; i < path.length; i++)
|
||||
{
|
||||
if (!c.getIssuerDN().equals(path[i].getSubjectDN()))
|
||||
continue;
|
||||
boolean[] keyUsage = c.getKeyUsage();
|
||||
if (keyUsage != null)
|
||||
{
|
||||
if (!keyUsage[KeyUsage.CRL_SIGN])
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
c.verify(path[i].getPublicKey());
|
||||
crl.verify(c.getPublicKey());
|
||||
return true;
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
if (c.getIssuerDN().equals(pubKeyCert.getSubjectDN()))
|
||||
{
|
||||
c.verify(pubKey);
|
||||
crl.verify(c.getPublicKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Set getCritExts(X509Certificate cert)
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
if (cert instanceof GnuPKIExtension)
|
||||
{
|
||||
Collection exts = ((GnuPKIExtension) cert).getExtensions();
|
||||
for (Iterator it = exts.iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension ext = (Extension) it.next();
|
||||
if (ext.isCritical() && !ext.isSupported())
|
||||
s.add(ext.getOid().toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
s.addAll(cert.getCriticalExtensionOIDs());
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a basic sanity check on the CA certificate at <code>index</code>.
|
||||
*/
|
||||
private static void basicSanity(X509Certificate[] path, int index)
|
||||
throws CertPathValidatorException
|
||||
{
|
||||
X509Certificate cert = path[index];
|
||||
int pathLen = 0;
|
||||
for (int i = index - 1; i > 0; i--)
|
||||
{
|
||||
if (!path[i].getIssuerDN().equals(path[i].getSubjectDN()))
|
||||
pathLen++;
|
||||
}
|
||||
Extension e = null;
|
||||
if (cert instanceof GnuPKIExtension)
|
||||
{
|
||||
e = ((GnuPKIExtension) cert).getExtension(BasicConstraints.ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
e = new Extension(cert.getExtensionValue(BasicConstraints.ID.toString()));
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
if (e == null)
|
||||
throw new CertPathValidatorException("no basicConstraints");
|
||||
BasicConstraints bc = (BasicConstraints) e.getValue();
|
||||
if (!bc.isCA())
|
||||
throw new CertPathValidatorException("certificate cannot be used to verify signatures");
|
||||
if (bc.getPathLengthConstraint() >= 0 && bc.getPathLengthConstraint() < pathLen)
|
||||
throw new CertPathValidatorException("path is too long");
|
||||
|
||||
boolean[] keyUsage = cert.getKeyUsage();
|
||||
if (keyUsage != null)
|
||||
{
|
||||
if (!keyUsage[KeyUsage.KEY_CERT_SIGN])
|
||||
throw new CertPathValidatorException("certificate cannot be used to sign certificates");
|
||||
}
|
||||
}
|
||||
|
||||
private static void updatePolicyTree(X509Certificate cert, PolicyNodeImpl root,
|
||||
int depth, PKIXParameters params,
|
||||
boolean explicitPolicy)
|
||||
throws CertPathValidatorException
|
||||
{
|
||||
if (DEBUG) debug("updatePolicyTree depth == " + depth);
|
||||
Set nodes = new HashSet();
|
||||
LinkedList stack = new LinkedList();
|
||||
Iterator current = null;
|
||||
stack.addLast(Collections.singleton(root).iterator());
|
||||
do
|
||||
{
|
||||
current = (Iterator) stack.removeLast();
|
||||
while (current.hasNext())
|
||||
{
|
||||
PolicyNodeImpl p = (PolicyNodeImpl) current.next();
|
||||
if (DEBUG) debug("visiting node == " + p);
|
||||
if (p.getDepth() == depth - 1)
|
||||
{
|
||||
if (DEBUG) debug("added node");
|
||||
nodes.add(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG) debug("skipped node");
|
||||
stack.addLast(current);
|
||||
current = p.getChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!stack.isEmpty());
|
||||
|
||||
Extension e = null;
|
||||
CertificatePolicies policies = null;
|
||||
List qualifierInfos = null;
|
||||
if (cert instanceof GnuPKIExtension)
|
||||
{
|
||||
e = ((GnuPKIExtension) cert).getExtension(CertificatePolicies.ID);
|
||||
if (e != null)
|
||||
policies = (CertificatePolicies) e.getValue();
|
||||
}
|
||||
|
||||
List cp = null;
|
||||
if (policies != null)
|
||||
cp = policies.getPolicies();
|
||||
else
|
||||
cp = Collections.EMPTY_LIST;
|
||||
boolean match = false;
|
||||
if (DEBUG) debug("nodes are == " + nodes);
|
||||
if (DEBUG) debug("cert policies are == " + cp);
|
||||
for (Iterator it = nodes.iterator(); it.hasNext(); )
|
||||
{
|
||||
PolicyNodeImpl parent = (PolicyNodeImpl) it.next();
|
||||
if (DEBUG) debug("adding policies to " + parent);
|
||||
for (Iterator it2 = cp.iterator(); it2.hasNext(); )
|
||||
{
|
||||
OID policy = (OID) it2.next();
|
||||
if (DEBUG) debug("trying to add policy == " + policy);
|
||||
if (policy.toString().equals(ANY_POLICY) &&
|
||||
params.isAnyPolicyInhibited())
|
||||
continue;
|
||||
PolicyNodeImpl child = new PolicyNodeImpl();
|
||||
child.setValidPolicy(policy.toString());
|
||||
child.addExpectedPolicy(policy.toString());
|
||||
if (parent.getExpectedPolicies().contains(policy.toString()))
|
||||
{
|
||||
parent.addChild(child);
|
||||
match = true;
|
||||
}
|
||||
else if (parent.getExpectedPolicies().contains(ANY_POLICY))
|
||||
{
|
||||
parent.addChild(child);
|
||||
match = true;
|
||||
}
|
||||
else if (ANY_POLICY.equals (policy.toString()))
|
||||
{
|
||||
parent.addChild (child);
|
||||
match = true;
|
||||
}
|
||||
if (match && policies != null)
|
||||
{
|
||||
List qualifiers = policies.getPolicyQualifierInfos (policy);
|
||||
if (qualifiers != null)
|
||||
child.addAllPolicyQualifiers (qualifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!match && (params.isExplicitPolicyRequired() || explicitPolicy))
|
||||
throw new CertPathValidatorException("policy tree building failed");
|
||||
}
|
||||
|
||||
private boolean checkExplicitPolicy (int depth, List explicitPolicies)
|
||||
{
|
||||
if (DEBUG) debug ("checkExplicitPolicy depth=" + depth);
|
||||
for (Iterator it = explicitPolicies.iterator(); it.hasNext(); )
|
||||
{
|
||||
int[] i = (int[]) it.next();
|
||||
int caDepth = i[0];
|
||||
int limit = i[1];
|
||||
if (DEBUG) debug (" caDepth=" + caDepth + " limit=" + limit);
|
||||
if (depth - caDepth >= limit)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/* RSA.java -- RSA PKCS#1 signatures.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.der.DERWriter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SignatureException;
|
||||
import java.security.SignatureSpi;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class RSA extends SignatureSpi implements Cloneable
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* digestAlgorithm OBJECT IDENTIFIER ::=
|
||||
* { iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) }
|
||||
*/
|
||||
protected static final OID DIGEST_ALGORITHM = new OID("1.2.840.113549.2");
|
||||
|
||||
protected final OID digestAlgorithm;
|
||||
protected final MessageDigest md;
|
||||
protected RSAPrivateKey signerKey;
|
||||
protected RSAPublicKey verifierKey;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected RSA(MessageDigest md, OID digestAlgorithm)
|
||||
{
|
||||
super();
|
||||
this.md = md;
|
||||
this.digestAlgorithm = digestAlgorithm;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Object clone() throws CloneNotSupportedException
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
protected Object engineGetParameter(String param)
|
||||
{
|
||||
throw new UnsupportedOperationException("deprecated");
|
||||
}
|
||||
|
||||
protected void engineSetParameter(String param, Object value)
|
||||
{
|
||||
throw new UnsupportedOperationException("deprecated");
|
||||
}
|
||||
|
||||
protected void engineInitSign(PrivateKey privateKey)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
if (!(privateKey instanceof RSAPrivateKey))
|
||||
throw new InvalidKeyException();
|
||||
verifierKey = null;
|
||||
signerKey = (RSAPrivateKey) privateKey;
|
||||
}
|
||||
|
||||
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
// This class does not need random bytes.
|
||||
engineInitSign(privateKey);
|
||||
}
|
||||
|
||||
protected void engineInitVerify(PublicKey publicKey)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
if (!(publicKey instanceof RSAPublicKey))
|
||||
throw new InvalidKeyException();
|
||||
signerKey = null;
|
||||
verifierKey = (RSAPublicKey) publicKey;
|
||||
}
|
||||
|
||||
protected void engineUpdate(byte b) throws SignatureException
|
||||
{
|
||||
if (signerKey == null && verifierKey == null)
|
||||
throw new SignatureException("not initialized");
|
||||
md.update(b);
|
||||
}
|
||||
|
||||
protected void engineUpdate(byte[] buf, int off, int len)
|
||||
throws SignatureException
|
||||
{
|
||||
if (signerKey == null && verifierKey == null)
|
||||
throw new SignatureException("not initialized");
|
||||
md.update(buf, off, len);
|
||||
}
|
||||
|
||||
protected byte[] engineSign() throws SignatureException
|
||||
{
|
||||
if (signerKey == null)
|
||||
throw new SignatureException("not initialized for signing");
|
||||
//
|
||||
// The signature will be the RSA encrypted BER representation of
|
||||
// the following:
|
||||
//
|
||||
// DigestInfo ::= SEQUENCE {
|
||||
// digestAlgorithm DigestAlgorithmIdentifier,
|
||||
// digest Digest }
|
||||
//
|
||||
// DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
//
|
||||
// Digest ::= OCTET STRING
|
||||
//
|
||||
ArrayList digestAlg = new ArrayList(2);
|
||||
digestAlg.add(new DERValue(DER.OBJECT_IDENTIFIER, digestAlgorithm));
|
||||
digestAlg.add(new DERValue(DER.NULL, null));
|
||||
ArrayList digestInfo = new ArrayList(2);
|
||||
digestInfo.add(new DERValue(DER.SEQUENCE, digestAlg));
|
||||
digestInfo.add(new DERValue(DER.OCTET_STRING, md.digest()));
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
try
|
||||
{
|
||||
DERWriter.write(out, new DERValue(DER.SEQUENCE, digestInfo));
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new SignatureException(ioe.toString());
|
||||
}
|
||||
byte[] buf = out.toByteArray();
|
||||
md.reset();
|
||||
|
||||
// k = octect length of the modulus.
|
||||
int k = signerKey.getModulus().bitLength();
|
||||
k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
|
||||
if (buf.length < k - 3)
|
||||
{
|
||||
throw new SignatureException("RSA modulus too small");
|
||||
}
|
||||
byte[] d = new byte[k];
|
||||
|
||||
// Padding type 1:
|
||||
// 00 | 01 | FF | ... | FF | 00 | D
|
||||
d[1] = 0x01;
|
||||
for (int i = 2; i < k - buf.length - 1; i++)
|
||||
d[i] = (byte) 0xFF;
|
||||
System.arraycopy(buf, 0, d, k - buf.length, buf.length);
|
||||
|
||||
BigInteger eb = new BigInteger(d);
|
||||
|
||||
byte[] ed = eb.modPow(signerKey.getPrivateExponent(),
|
||||
signerKey.getModulus()).toByteArray();
|
||||
|
||||
// Ensure output is k octets long.
|
||||
if (ed.length < k)
|
||||
{
|
||||
byte[] b = new byte[k];
|
||||
System.arraycopy(eb, 0, b, k - ed.length, ed.length);
|
||||
ed = b;
|
||||
}
|
||||
else if (ed.length > k)
|
||||
{
|
||||
if (ed.length != k + 1)
|
||||
{
|
||||
throw new SignatureException("modPow result is larger than the modulus");
|
||||
}
|
||||
// Maybe an extra 00 octect.
|
||||
byte[] b = new byte[k];
|
||||
System.arraycopy(ed, 1, b, 0, k);
|
||||
ed = b;
|
||||
}
|
||||
|
||||
return ed;
|
||||
}
|
||||
|
||||
protected int engineSign(byte[] out, int off, int len)
|
||||
throws SignatureException
|
||||
{
|
||||
if (out == null || off < 0 || len < 0 || off+len > out.length)
|
||||
throw new SignatureException("illegal output argument");
|
||||
byte[] result = engineSign();
|
||||
if (result.length > len)
|
||||
throw new SignatureException("not enough space for signature");
|
||||
System.arraycopy(result, 0, out, off, result.length);
|
||||
return result.length;
|
||||
}
|
||||
|
||||
protected boolean engineVerify(byte[] sig) throws SignatureException
|
||||
{
|
||||
if (verifierKey == null)
|
||||
throw new SignatureException("not initialized for verifying");
|
||||
if (sig == null)
|
||||
throw new SignatureException("no signature specified");
|
||||
int k = verifierKey.getModulus().bitLength();
|
||||
k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
|
||||
if (sig.length != k)
|
||||
throw new SignatureException("signature is the wrong size (expecting "
|
||||
+ k + " bytes, got " + sig.length + ")");
|
||||
BigInteger ed = new BigInteger(1, sig);
|
||||
byte[] eb = ed.modPow(verifierKey.getPublicExponent(),
|
||||
verifierKey.getModulus()).toByteArray();
|
||||
|
||||
int i = 0;
|
||||
if (eb[0] == 0x00)
|
||||
{
|
||||
for (i = 1; i < eb.length && eb[i] == 0x00; i++);
|
||||
if (i == 1)
|
||||
throw new SignatureException("wrong RSA padding");
|
||||
i--;
|
||||
}
|
||||
else if (eb[0] == 0x01)
|
||||
{
|
||||
for (i = 1; i < eb.length && eb[i] != 0x00; i++)
|
||||
if (eb[i] != (byte) 0xFF)
|
||||
throw new IllegalArgumentException("wrong RSA padding");
|
||||
}
|
||||
else
|
||||
throw new SignatureException("wrong RSA padding type");
|
||||
|
||||
byte[] d = new byte[eb.length-i-1];
|
||||
System.arraycopy(eb, i+1, d, 0, eb.length-i-1);
|
||||
|
||||
DERReader der = new DERReader(d);
|
||||
try
|
||||
{
|
||||
DERValue val = der.read();
|
||||
if (val.getTag() != DER.SEQUENCE)
|
||||
throw new SignatureException("failed to parse DigestInfo");
|
||||
val = der.read();
|
||||
if (val.getTag() != DER.SEQUENCE)
|
||||
throw new SignatureException("failed to parse DigestAlgorithmIdentifier");
|
||||
boolean sequenceIsBer = val.getLength() == 0;
|
||||
val = der.read();
|
||||
if (val.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new SignatureException("failed to parse object identifier");
|
||||
if (!val.getValue().equals(digestAlgorithm))
|
||||
throw new SignatureException("digest algorithms do not match");
|
||||
val = der.read();
|
||||
// We should never see parameters here, since they are never used.
|
||||
if (val.getTag() != DER.NULL)
|
||||
throw new SignatureException("cannot handle digest parameters");
|
||||
if (sequenceIsBer)
|
||||
der.skip(1); // end-of-sequence byte.
|
||||
val = der.read();
|
||||
if (val.getTag() != DER.OCTET_STRING)
|
||||
throw new SignatureException("failed to parse Digest");
|
||||
return MessageDigest.isEqual(md.digest(), (byte[]) val.getValue());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new SignatureException(ioe.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean engineVerify(byte[] sig, int off, int len)
|
||||
throws SignatureException
|
||||
{
|
||||
if (sig == null || off < 0 || len < 0 || off+len > sig.length)
|
||||
throw new SignatureException("illegal parameter");
|
||||
byte[] buf = new byte[len];
|
||||
System.arraycopy(sig, off, buf, 0, len);
|
||||
return engineVerify(buf);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/* RSAKeyFactory.java -- RSA key factory.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactorySpi;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import java.security.interfaces.RSAPrivateCrtKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.RSAPrivateCrtKeySpec;
|
||||
import java.security.spec.RSAPrivateKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
public class RSAKeyFactory extends KeyFactorySpi
|
||||
{
|
||||
|
||||
// Default constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected PrivateKey engineGeneratePrivate(KeySpec spec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if (spec instanceof RSAPrivateCrtKeySpec)
|
||||
{
|
||||
return new GnuRSAPrivateKey((RSAPrivateCrtKeySpec) spec);
|
||||
}
|
||||
if (spec instanceof RSAPrivateKeySpec)
|
||||
{
|
||||
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
|
||||
((RSAPrivateKeySpec) spec).getModulus(), null,
|
||||
((RSAPrivateKeySpec) spec).getPrivateExponent(), null,
|
||||
null, null, null, null));
|
||||
}
|
||||
if (spec instanceof PKCS8EncodedKeySpec)
|
||||
{
|
||||
EncodedKeyFactory ekf = new EncodedKeyFactory();
|
||||
PrivateKey pk = ekf.engineGeneratePrivate(spec);
|
||||
if (pk instanceof RSAPrivateKey)
|
||||
return pk;
|
||||
}
|
||||
throw new InvalidKeySpecException();
|
||||
}
|
||||
|
||||
protected PublicKey engineGeneratePublic(KeySpec spec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if (spec instanceof RSAPublicKeySpec)
|
||||
{
|
||||
return new GnuRSAPublicKey((RSAPublicKeySpec) spec);
|
||||
}
|
||||
if (spec instanceof X509EncodedKeySpec)
|
||||
{
|
||||
EncodedKeyFactory ekf = new EncodedKeyFactory();
|
||||
PublicKey pk = ekf.engineGeneratePublic(spec);
|
||||
if (pk instanceof RSAPublicKey)
|
||||
return pk;
|
||||
}
|
||||
throw new InvalidKeySpecException();
|
||||
}
|
||||
|
||||
protected KeySpec engineGetKeySpec(Key key, Class keySpec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
if (keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class)
|
||||
&& (key instanceof RSAPrivateCrtKey))
|
||||
{
|
||||
return new RSAPrivateCrtKeySpec(
|
||||
((RSAPrivateCrtKey) key).getModulus(),
|
||||
((RSAPrivateCrtKey) key).getPublicExponent(),
|
||||
((RSAPrivateCrtKey) key).getPrivateExponent(),
|
||||
((RSAPrivateCrtKey) key).getPrimeP(),
|
||||
((RSAPrivateCrtKey) key).getPrimeQ(),
|
||||
((RSAPrivateCrtKey) key).getPrimeExponentP(),
|
||||
((RSAPrivateCrtKey) key).getPrimeExponentQ(),
|
||||
((RSAPrivateCrtKey) key).getCrtCoefficient());
|
||||
}
|
||||
if (keySpec.isAssignableFrom(RSAPrivateKeySpec.class)
|
||||
&& (key instanceof RSAPrivateKey))
|
||||
{
|
||||
return new RSAPrivateKeySpec(
|
||||
((RSAPrivateCrtKey) key).getModulus(),
|
||||
((RSAPrivateCrtKey) key).getPrivateExponent());
|
||||
}
|
||||
if (keySpec.isAssignableFrom(RSAPublicKeySpec.class)
|
||||
&& (key instanceof RSAPublicKey))
|
||||
{
|
||||
return new RSAPublicKeySpec(
|
||||
((RSAPrivateCrtKey) key).getModulus(),
|
||||
((RSAPrivateCrtKey) key).getPublicExponent());
|
||||
}
|
||||
if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)
|
||||
&& key.getFormat().equalsIgnoreCase("PKCS#8"))
|
||||
{
|
||||
return new PKCS8EncodedKeySpec(key.getEncoded());
|
||||
}
|
||||
if (keySpec.isAssignableFrom(X509EncodedKeySpec.class)
|
||||
&& key.getFormat().equalsIgnoreCase("X.509"))
|
||||
{
|
||||
return new X509EncodedKeySpec(key.getEncoded());
|
||||
}
|
||||
throw new InvalidKeySpecException();
|
||||
}
|
||||
|
||||
protected Key engineTranslateKey(Key key) throws InvalidKeyException
|
||||
{
|
||||
if (key instanceof RSAPrivateCrtKey)
|
||||
{
|
||||
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
|
||||
((RSAPrivateCrtKey) key).getModulus(),
|
||||
((RSAPrivateCrtKey) key).getPublicExponent(),
|
||||
((RSAPrivateCrtKey) key).getPrivateExponent(),
|
||||
((RSAPrivateCrtKey) key).getPrimeP(),
|
||||
((RSAPrivateCrtKey) key).getPrimeQ(),
|
||||
((RSAPrivateCrtKey) key).getPrimeExponentP(),
|
||||
((RSAPrivateCrtKey) key).getPrimeExponentQ(),
|
||||
((RSAPrivateCrtKey) key).getCrtCoefficient()));
|
||||
}
|
||||
if (key instanceof RSAPrivateKey)
|
||||
{
|
||||
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
|
||||
((RSAPrivateKey) key).getModulus(), null,
|
||||
((RSAPrivateKey) key).getPrivateExponent(), null,
|
||||
null, null, null, null));
|
||||
}
|
||||
if (key instanceof RSAPublicKey)
|
||||
{
|
||||
return new GnuRSAPublicKey(new RSAPublicKeySpec(
|
||||
((RSAPrivateCrtKey) key).getModulus(),
|
||||
((RSAPrivateCrtKey) key).getPublicExponent()));
|
||||
}
|
||||
throw new InvalidKeyException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
/* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1].
|
||||
Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
This class implements the SHA-1 algorithm as described in [1].
|
||||
|
||||
[1] Federal Information Processing Standards Publication 180-1.
|
||||
Specifications for the Secure Hash Standard. April 17, 1995.
|
||||
|
||||
@see java.security.MessageDigest
|
||||
*/
|
||||
public class SHA extends MessageDigest implements Cloneable
|
||||
{
|
||||
public SHA ()
|
||||
{
|
||||
super("SHA");
|
||||
engineReset ();
|
||||
}
|
||||
|
||||
public int engineGetDigestLength()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
public void engineUpdate (byte b)
|
||||
{
|
||||
int i = ((int)bytecount) & 0x3f; //wgs
|
||||
int shift = (3 - i % 4) << 3;
|
||||
int idx = i / 4;
|
||||
|
||||
i = (int)b;
|
||||
W[idx] = (W[idx] & ~(0xff << shift)) | ((i & 0xff) << shift);
|
||||
|
||||
// if we've filled up a block, then process it
|
||||
if (((++bytecount) & 0x3f) == 0)
|
||||
munch ();
|
||||
}
|
||||
|
||||
// This could be optimized.
|
||||
public void engineUpdate (byte bytes[], int off, int len)
|
||||
{
|
||||
if (len < 0)
|
||||
throw new ArrayIndexOutOfBoundsException ();
|
||||
|
||||
int end = off + len;
|
||||
while (off < end)
|
||||
engineUpdate (bytes[off++]);
|
||||
}
|
||||
|
||||
public void engineReset ()
|
||||
{
|
||||
bytecount = 0;
|
||||
// magic numbers from [1] p. 10.
|
||||
H0 = 0x67452301;
|
||||
H1 = 0xefcdab89;
|
||||
H2 = 0x98badcfe;
|
||||
H3 = 0x10325476;
|
||||
H4 = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
public byte[] engineDigest ()
|
||||
{
|
||||
long bitcount = bytecount << 3;
|
||||
engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding
|
||||
|
||||
// add the rest of the padding to fill this block out, but leave 8
|
||||
// bytes to put in the original bytecount
|
||||
while ((bytecount & 0x3f) != 56)
|
||||
engineUpdate ((byte)0);
|
||||
|
||||
// add the length of the original, unpadded block to the end of
|
||||
// the padding
|
||||
W[14] = (int)(bitcount >>> 32);
|
||||
W[15] = (int)bitcount;
|
||||
bytecount += 8;
|
||||
|
||||
// digest the fully padded block
|
||||
munch ();
|
||||
|
||||
byte[] result
|
||||
= new byte[] {(byte)(H0 >>> 24), (byte)(H0 >>> 16),
|
||||
(byte)(H0 >>> 8), (byte)H0,
|
||||
(byte)(H1 >>> 24), (byte)(H1 >>> 16),
|
||||
(byte)(H1 >>> 8), (byte)H1,
|
||||
(byte)(H2 >>> 24), (byte)(H2 >>> 16),
|
||||
(byte)(H2 >>> 8), (byte)H2,
|
||||
(byte)(H3 >>> 24), (byte)(H3 >>> 16),
|
||||
(byte)(H3 >>> 8), (byte)H3,
|
||||
(byte)(H4 >>> 24), (byte)(H4 >>> 16),
|
||||
(byte)(H4 >>> 8), (byte)H4};
|
||||
|
||||
engineReset ();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Process a single block. This is pretty much copied verbatim from
|
||||
// [1] pp. 9, 10.
|
||||
private void munch ()
|
||||
{
|
||||
for (int t = 16; t < 80; ++ t)
|
||||
{
|
||||
int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
|
||||
W[t] = Wt << 1 | Wt >>> 31;
|
||||
}
|
||||
|
||||
int A = H0;
|
||||
int B = H1;
|
||||
int C = H2;
|
||||
int D = H3;
|
||||
int E = H4;
|
||||
|
||||
for (int t = 0; t < 20; ++ t)
|
||||
{
|
||||
int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
||||
+ ((B & C) | (~B & D)) // f_t(B,C,D)
|
||||
+ E + W[t]
|
||||
+ 0x5a827999; // K_t
|
||||
|
||||
E = D;
|
||||
D = C;
|
||||
C = B << 30 | B >>> 2; // S^30(B)
|
||||
B = A;
|
||||
A = TEMP;
|
||||
}
|
||||
|
||||
for (int t = 20; t < 40; ++ t)
|
||||
{
|
||||
int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
||||
+ (B ^ C ^ D) // f_t(B,C,D)
|
||||
+ E + W[t]
|
||||
+ 0x6ed9eba1; // K_t
|
||||
|
||||
E = D;
|
||||
D = C;
|
||||
C = B << 30 | B >>> 2; // S^30(B)
|
||||
B = A;
|
||||
A = TEMP;
|
||||
}
|
||||
|
||||
for (int t = 40; t < 60; ++ t)
|
||||
{
|
||||
int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
||||
+ (B & C | B & D | C & D) // f_t(B,C,D)
|
||||
+ E + W[t]
|
||||
+ 0x8f1bbcdc; // K_t
|
||||
|
||||
E = D;
|
||||
D = C;
|
||||
C = B << 30 | B >>> 2; // S^30(B)
|
||||
B = A;
|
||||
A = TEMP;
|
||||
}
|
||||
|
||||
for (int t = 60; t < 80; ++ t)
|
||||
{
|
||||
int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
||||
+ (B ^ C ^ D) // f_t(B,C,D)
|
||||
+ E + W[t]
|
||||
+ 0xca62c1d6; // K_t
|
||||
|
||||
E = D;
|
||||
D = C;
|
||||
C = B << 30 | B >>> 2; // S^30(B)
|
||||
B = A;
|
||||
A = TEMP;
|
||||
}
|
||||
|
||||
H0 += A;
|
||||
H1 += B;
|
||||
H2 += C;
|
||||
H3 += D;
|
||||
H4 += E;
|
||||
|
||||
// Reset W by clearing it.
|
||||
for (int t = 0; t < 80; ++ t)
|
||||
W[t] = 0;
|
||||
}
|
||||
|
||||
public Object clone ()
|
||||
{
|
||||
return new SHA (this);
|
||||
}
|
||||
|
||||
private SHA (SHA copy)
|
||||
{
|
||||
this ();
|
||||
bytecount = copy.bytecount;
|
||||
H0 = copy.H0;
|
||||
H1 = copy.H1;
|
||||
H2 = copy.H2;
|
||||
H3 = copy.H3;
|
||||
H4 = copy.H4;
|
||||
System.arraycopy (copy.W, 0, W, 0, 80);
|
||||
}
|
||||
|
||||
private final int W[] = new int[80];
|
||||
private long bytecount;
|
||||
private int H0;
|
||||
private int H1;
|
||||
private int H2;
|
||||
private int H3;
|
||||
private int H4;
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/* SHA1PRNG.java --- Secure Random SPI SHA1PRNG
|
||||
Copyright (C) 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandomSpi;
|
||||
import java.util.Random;
|
||||
|
||||
public class SHA1PRNG extends SecureRandomSpi implements Serializable
|
||||
{
|
||||
MessageDigest digest;
|
||||
byte seed[];
|
||||
byte data[];
|
||||
int seedpos;
|
||||
int datapos;
|
||||
private boolean seeded = false; // set to true when we seed this
|
||||
/**
|
||||
* The size of seed.
|
||||
*/
|
||||
private static final int SEED_SIZE = 20;
|
||||
/**
|
||||
* The size of data.
|
||||
*/
|
||||
private static final int DATA_SIZE = 40;
|
||||
|
||||
/**
|
||||
* Create a new SHA-1 pseudo-random number generator.
|
||||
*/
|
||||
public SHA1PRNG()
|
||||
{
|
||||
try {
|
||||
digest = MessageDigest.getInstance("SHA");
|
||||
} catch ( NoSuchAlgorithmException nsae) {
|
||||
// System.out.println("Failed to find SHA Message Digest: " + nsae);
|
||||
// nsae.printStackTrace();
|
||||
throw new InternalError ("no SHA implementation found");
|
||||
}
|
||||
|
||||
seed = new byte[SEED_SIZE];
|
||||
seedpos = 0;
|
||||
data = new byte[DATA_SIZE];
|
||||
datapos = SEED_SIZE; // try to force hashing a first block
|
||||
}
|
||||
|
||||
public void engineSetSeed(byte[] seed)
|
||||
{
|
||||
for(int i = 0; i < seed.length; i++)
|
||||
this.seed[seedpos++ % SEED_SIZE] ^= seed[i];
|
||||
seedpos %= SEED_SIZE;
|
||||
|
||||
}
|
||||
|
||||
public void engineNextBytes(byte[] bytes)
|
||||
{
|
||||
ensureIsSeeded ();
|
||||
int loc = 0;
|
||||
while (loc < bytes.length)
|
||||
{
|
||||
int copy = Math.min (bytes.length - loc, SEED_SIZE - datapos);
|
||||
|
||||
if (copy > 0)
|
||||
{
|
||||
System.arraycopy (data, datapos, bytes, loc, copy);
|
||||
datapos += copy;
|
||||
loc += copy;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No data ready for copying, so refill our buffer.
|
||||
System.arraycopy( seed, 0, data, SEED_SIZE, SEED_SIZE);
|
||||
byte[] digestdata = digest.digest( data );
|
||||
System.arraycopy( digestdata, 0, data, 0, SEED_SIZE);
|
||||
datapos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] engineGenerateSeed(int numBytes)
|
||||
{
|
||||
byte tmp[] = new byte[numBytes];
|
||||
|
||||
engineNextBytes( tmp );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private void ensureIsSeeded()
|
||||
{
|
||||
if (!seeded)
|
||||
{
|
||||
new Random(0L).nextBytes(seed);
|
||||
|
||||
byte[] digestdata = digest.digest(data);
|
||||
System.arraycopy(digestdata, 0, data, 0, SEED_SIZE);
|
||||
|
||||
seeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* SHA1withRSA.java -- SHA-1 with RSA encryption signatures.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class SHA1withRSA extends RSA
|
||||
{
|
||||
|
||||
// Constant.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static final OID SHA1 = new OID("1.3.14.3.2.26");
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public SHA1withRSA() throws NoSuchAlgorithmException
|
||||
{
|
||||
super(MessageDigest.getInstance("SHA-160"), SHA1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
/* X509CertificateFactory.java -- generates X.509 certificates.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.provider;
|
||||
|
||||
import gnu.java.io.Base64InputStream;
|
||||
import gnu.java.security.x509.X509CRL;
|
||||
import gnu.java.security.x509.X509CertPath;
|
||||
import gnu.java.security.x509.X509Certificate;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.cert.CRL;
|
||||
import java.security.cert.CRLException;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactorySpi;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class X509CertificateFactory extends CertificateFactorySpi
|
||||
{
|
||||
|
||||
// Constants.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----";
|
||||
public static final String END_CERTIFICATE = "-----END CERTIFICATE-----";
|
||||
public static final String BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
|
||||
public static final String END_X509_CRL = "-----END X509 CRL-----";
|
||||
|
||||
// Constructors.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public X509CertificateFactory()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public Certificate engineGenerateCertificate(InputStream inStream)
|
||||
throws CertificateException
|
||||
{
|
||||
try
|
||||
{
|
||||
return generateCert(inStream);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
CertificateException ce = new CertificateException(ioe.getMessage());
|
||||
ce.initCause (ioe);
|
||||
throw ce;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection engineGenerateCertificates(InputStream inStream)
|
||||
throws CertificateException
|
||||
{
|
||||
LinkedList certs = new LinkedList();
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
certs.add(generateCert(inStream));
|
||||
}
|
||||
catch (EOFException eof)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
CertificateException ce = new CertificateException(ioe.getMessage());
|
||||
ce.initCause (ioe);
|
||||
throw ce;
|
||||
}
|
||||
}
|
||||
return certs;
|
||||
}
|
||||
|
||||
public CRL engineGenerateCRL(InputStream inStream) throws CRLException
|
||||
{
|
||||
try
|
||||
{
|
||||
return generateCRL(inStream);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
CRLException crle = new CRLException(ioe.getMessage());
|
||||
crle.initCause (ioe);
|
||||
throw crle;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection engineGenerateCRLs(InputStream inStream)
|
||||
throws CRLException
|
||||
{
|
||||
LinkedList crls = new LinkedList();
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
crls.add(generateCRL(inStream));
|
||||
}
|
||||
catch (EOFException eof)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
CRLException crle = new CRLException(ioe.getMessage());
|
||||
crle.initCause (ioe);
|
||||
throw crle;
|
||||
}
|
||||
}
|
||||
return crls;
|
||||
}
|
||||
|
||||
public CertPath engineGenerateCertPath(List certs)
|
||||
{
|
||||
return new X509CertPath(certs);
|
||||
}
|
||||
|
||||
public CertPath engineGenerateCertPath(InputStream in)
|
||||
throws CertificateEncodingException
|
||||
{
|
||||
return new X509CertPath(in);
|
||||
}
|
||||
|
||||
public CertPath engineGenerateCertPath(InputStream in, String encoding)
|
||||
throws CertificateEncodingException
|
||||
{
|
||||
return new X509CertPath(in, encoding);
|
||||
}
|
||||
|
||||
public Iterator engineGetCertPathEncodings()
|
||||
{
|
||||
return X509CertPath.ENCODINGS.iterator();
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private X509Certificate generateCert(InputStream inStream)
|
||||
throws IOException, CertificateException
|
||||
{
|
||||
if (inStream == null)
|
||||
throw new CertificateException("missing input stream");
|
||||
if (!inStream.markSupported())
|
||||
inStream = new BufferedInputStream(inStream, 8192);
|
||||
inStream.mark(20);
|
||||
int i = inStream.read();
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
|
||||
// If the input is in binary DER format, the first byte MUST be
|
||||
// 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
|
||||
// UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
|
||||
//
|
||||
// So if we do not see 0x30 here we will assume it is in Base-64.
|
||||
if (i != 0x30)
|
||||
{
|
||||
inStream.reset();
|
||||
StringBuffer line = new StringBuffer(80);
|
||||
do
|
||||
{
|
||||
line.setLength(0);
|
||||
do
|
||||
{
|
||||
i = inStream.read();
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
if (i != '\n' && i != '\r')
|
||||
line.append((char) i);
|
||||
}
|
||||
while (i != '\n' && i != '\r');
|
||||
}
|
||||
while (!line.toString().equals(BEGIN_CERTIFICATE));
|
||||
X509Certificate ret = new X509Certificate(
|
||||
new BufferedInputStream(new Base64InputStream(inStream), 8192));
|
||||
line.setLength(0);
|
||||
line.append('-'); // Base64InputStream will eat this.
|
||||
do
|
||||
{
|
||||
i = inStream.read();
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
if (i != '\n' && i != '\r')
|
||||
line.append((char) i);
|
||||
}
|
||||
while (i != '\n' && i != '\r');
|
||||
// XXX ???
|
||||
if (!line.toString().equals(END_CERTIFICATE))
|
||||
throw new CertificateException("no end-of-certificate marker");
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
inStream.reset();
|
||||
return new X509Certificate(inStream);
|
||||
}
|
||||
}
|
||||
|
||||
private X509CRL generateCRL(InputStream inStream)
|
||||
throws IOException, CRLException
|
||||
{
|
||||
if (inStream == null)
|
||||
throw new CRLException("missing input stream");
|
||||
if (!inStream.markSupported())
|
||||
inStream = new BufferedInputStream(inStream, 8192);
|
||||
inStream.mark(20);
|
||||
int i = inStream.read();
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
|
||||
// If the input is in binary DER format, the first byte MUST be
|
||||
// 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
|
||||
// UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
|
||||
//
|
||||
// So if we do not see 0x30 here we will assume it is in Base-64.
|
||||
if (i != 0x30)
|
||||
{
|
||||
inStream.reset();
|
||||
StringBuffer line = new StringBuffer(80);
|
||||
do
|
||||
{
|
||||
line.setLength(0);
|
||||
do
|
||||
{
|
||||
i = inStream.read();
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
if (i != '\n' && i != '\r')
|
||||
line.append((char) i);
|
||||
}
|
||||
while (i != '\n' && i != '\r');
|
||||
}
|
||||
while (!line.toString().startsWith(BEGIN_X509_CRL));
|
||||
X509CRL ret = new X509CRL(
|
||||
new BufferedInputStream(new Base64InputStream(inStream), 8192));
|
||||
line.setLength(0);
|
||||
line.append('-'); // Base64InputStream will eat this.
|
||||
do
|
||||
{
|
||||
i = inStream.read();
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
if (i != '\n' && i != '\r')
|
||||
line.append((char) i);
|
||||
}
|
||||
while (i != '\n' && i != '\r');
|
||||
// XXX ???
|
||||
if (!line.toString().startsWith(END_X509_CRL))
|
||||
throw new CRLException("no end-of-CRL marker");
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
inStream.reset();
|
||||
return new X509CRL(inStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.provider package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.provider</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,164 @@
|
||||
/* Prime.java --- Prime number generation utilities
|
||||
Copyright (C) 1999, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.util;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
//import java.security.SecureRandom;
|
||||
|
||||
public final class Prime
|
||||
{
|
||||
|
||||
/*
|
||||
See IEEE P1363 A.15.4 (10/05/98 Draft)
|
||||
*/
|
||||
public static BigInteger generateRandomPrime( int pmin, int pmax, BigInteger f )
|
||||
{
|
||||
BigInteger d;
|
||||
|
||||
//Step 1 - generate prime
|
||||
BigInteger p = new BigInteger( (pmax + pmin)/2, new Random() );
|
||||
if( p.compareTo( BigInteger.valueOf( 1 ).shiftLeft( pmin ) ) <= 0 )
|
||||
{
|
||||
p = p.add( BigInteger.valueOf( 1 ).shiftLeft( pmin ).subtract( p ) );
|
||||
}
|
||||
|
||||
//Step 2 - test for even
|
||||
if( p.mod( BigInteger.valueOf(2) ).compareTo( BigInteger.valueOf( 0 )) == 0)
|
||||
p = p.add( BigInteger.valueOf( 1 ) );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//Step 3
|
||||
if( p.compareTo( BigInteger.valueOf( 1 ).shiftLeft( pmax)) > 0)
|
||||
{
|
||||
//Step 3.1
|
||||
p = p.subtract( BigInteger.valueOf( 1 ).shiftLeft( pmax) );
|
||||
p = p.add( BigInteger.valueOf( 1 ).shiftLeft( pmin) );
|
||||
p = p.subtract( BigInteger.valueOf( 1 ) );
|
||||
|
||||
//Step 3.2
|
||||
// put step 2 code here so looping code is cleaner
|
||||
//Step 2 - test for even
|
||||
if( p.mod( BigInteger.valueOf(2) ).compareTo( BigInteger.valueOf( 0 )) == 0)
|
||||
p = p.add( BigInteger.valueOf( 1 ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
//Step 4 - compute GCD
|
||||
d = p.subtract( BigInteger.valueOf(1) );
|
||||
d = d.gcd( f );
|
||||
|
||||
//Step 5 - test d
|
||||
if( d.compareTo( BigInteger.valueOf( 1 ) ) == 0)
|
||||
{
|
||||
//Step 5.1 - test primality
|
||||
if( p.isProbablePrime( 1 ) == true )
|
||||
{
|
||||
//Step 5.2;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
//Step 6
|
||||
p = p.add( BigInteger.valueOf( 2 ) );
|
||||
|
||||
//Step 7
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
See IEEE P1363 A.15.5 (10/05/98 Draft)
|
||||
*/
|
||||
public static BigInteger generateRandomPrime( BigInteger r, BigInteger a, int pmin, int pmax, BigInteger f )
|
||||
{
|
||||
BigInteger d, w;
|
||||
|
||||
//Step 1 - generate prime
|
||||
BigInteger p = new BigInteger( (pmax + pmin)/2, new Random() );
|
||||
|
||||
steptwo:{ //Step 2
|
||||
w = p.mod( r.multiply( BigInteger.valueOf(2) ));
|
||||
|
||||
//Step 3
|
||||
p = p.add( r.multiply( BigInteger.valueOf(2) ) );
|
||||
p = p.subtract( w );
|
||||
p = p.add(a);
|
||||
|
||||
//Step 4 - test for even
|
||||
if( p.mod( BigInteger.valueOf(2) ).compareTo( BigInteger.valueOf( 0 )) == 0)
|
||||
p = p.add( r );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//Step 5
|
||||
if( p.compareTo( BigInteger.valueOf( 1 ).shiftLeft( pmax)) > 0)
|
||||
{
|
||||
//Step 5.1
|
||||
p = p.subtract( BigInteger.valueOf( 1 ).shiftLeft( pmax) );
|
||||
p = p.add( BigInteger.valueOf( 1 ).shiftLeft( pmin) );
|
||||
p = p.subtract( BigInteger.valueOf( 1 ) );
|
||||
|
||||
//Step 5.2 - goto to Step 2
|
||||
break steptwo;
|
||||
}
|
||||
|
||||
//Step 6
|
||||
d = p.subtract( BigInteger.valueOf(1) );
|
||||
d = d.gcd( f );
|
||||
|
||||
//Step 7 - test d
|
||||
if( d.compareTo( BigInteger.valueOf( 1 ) ) == 0)
|
||||
{
|
||||
//Step 7.1 - test primality
|
||||
if( p.isProbablePrime( 1 ) == true )
|
||||
{
|
||||
//Step 7.2;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
//Step 8
|
||||
p = p.add( r.multiply( BigInteger.valueOf(2) ) );
|
||||
|
||||
//Step 9
|
||||
}
|
||||
}
|
||||
//Should never reach here but makes the compiler happy
|
||||
return BigInteger.valueOf(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.util package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.util</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,59 @@
|
||||
/* GnuPKIExtension.java -- interface for GNU PKI extensions.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.x509.ext.Extension;
|
||||
|
||||
import java.security.cert.X509Extension;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface GnuPKIExtension extends X509Extension
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the extension object for the given object identifier.
|
||||
*
|
||||
* @param oid The OID of the extension to get.
|
||||
* @return The extension, or null if there is no such extension.
|
||||
*/
|
||||
Extension getExtension(OID oid);
|
||||
|
||||
Collection getExtensions();
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/* PolicyNodeImpl.java -- An implementation of a policy tree node.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import java.security.cert.PolicyNode;
|
||||
import java.security.cert.PolicyQualifierInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public final class PolicyNodeImpl implements PolicyNode
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private String policy;
|
||||
private final Set expectedPolicies;
|
||||
private final Set qualifiers;
|
||||
private final Set children;
|
||||
private PolicyNodeImpl parent;
|
||||
private int depth;
|
||||
private boolean critical;
|
||||
private boolean readOnly;
|
||||
|
||||
// Constructors.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public PolicyNodeImpl()
|
||||
{
|
||||
expectedPolicies = new HashSet();
|
||||
qualifiers = new HashSet();
|
||||
children = new HashSet();
|
||||
readOnly = false;
|
||||
critical = false;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public void addChild(PolicyNodeImpl node)
|
||||
{
|
||||
if (readOnly)
|
||||
throw new IllegalStateException("read only");
|
||||
if (node.getParent() != null)
|
||||
throw new IllegalStateException("already a child node");
|
||||
node.parent = this;
|
||||
node.setDepth(depth + 1);
|
||||
children.add(node);
|
||||
}
|
||||
|
||||
public Iterator getChildren()
|
||||
{
|
||||
return Collections.unmodifiableSet(children).iterator();
|
||||
}
|
||||
|
||||
public int getDepth()
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
|
||||
public void setDepth(int depth)
|
||||
{
|
||||
if (readOnly)
|
||||
throw new IllegalStateException("read only");
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
public void addAllExpectedPolicies(Set policies)
|
||||
{
|
||||
if (readOnly)
|
||||
throw new IllegalStateException("read only");
|
||||
expectedPolicies.addAll(policies);
|
||||
}
|
||||
|
||||
public void addExpectedPolicy(String policy)
|
||||
{
|
||||
if (readOnly)
|
||||
throw new IllegalStateException("read only");
|
||||
expectedPolicies.add(policy);
|
||||
}
|
||||
|
||||
public Set getExpectedPolicies()
|
||||
{
|
||||
return Collections.unmodifiableSet(expectedPolicies);
|
||||
}
|
||||
|
||||
public PolicyNode getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void addAllPolicyQualifiers (Collection qualifiers)
|
||||
{
|
||||
for (Iterator it = qualifiers.iterator(); it.hasNext(); )
|
||||
{
|
||||
if (!(it.next() instanceof PolicyQualifierInfo))
|
||||
throw new IllegalArgumentException ("can only add PolicyQualifierInfos");
|
||||
}
|
||||
qualifiers.addAll (qualifiers);
|
||||
}
|
||||
|
||||
public void addPolicyQualifier (PolicyQualifierInfo qualifier)
|
||||
{
|
||||
if (readOnly)
|
||||
throw new IllegalStateException("read only");
|
||||
qualifiers.add(qualifier);
|
||||
}
|
||||
|
||||
public Set getPolicyQualifiers()
|
||||
{
|
||||
return Collections.unmodifiableSet(qualifiers);
|
||||
}
|
||||
|
||||
public String getValidPolicy()
|
||||
{
|
||||
return policy;
|
||||
}
|
||||
|
||||
public void setValidPolicy(String policy)
|
||||
{
|
||||
if (readOnly)
|
||||
throw new IllegalStateException("read only");
|
||||
this.policy = policy;
|
||||
}
|
||||
|
||||
public boolean isCritical()
|
||||
{
|
||||
return critical;
|
||||
}
|
||||
|
||||
public void setCritical(boolean critical)
|
||||
{
|
||||
if (readOnly)
|
||||
throw new IllegalStateException("read only");
|
||||
this.critical = critical;
|
||||
}
|
||||
|
||||
public void setReadOnly()
|
||||
{
|
||||
if (readOnly)
|
||||
return;
|
||||
readOnly = true;
|
||||
for (Iterator it = getChildren(); it.hasNext(); )
|
||||
((PolicyNodeImpl) it.next()).setReadOnly();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 0; i < depth; i++)
|
||||
buf.append(" ");
|
||||
buf.append("(");
|
||||
buf.append(PolicyNodeImpl.class.getName());
|
||||
buf.append(" (oid ");
|
||||
buf.append(policy);
|
||||
buf.append(") (depth ");
|
||||
buf.append(depth);
|
||||
buf.append(") (qualifiers ");
|
||||
buf.append(qualifiers);
|
||||
buf.append(") (critical ");
|
||||
buf.append(critical);
|
||||
buf.append(") (expectedPolicies ");
|
||||
buf.append(expectedPolicies);
|
||||
buf.append(") (children (");
|
||||
final String nl = System.getProperty("line.separator");
|
||||
for (Iterator it = getChildren(); it.hasNext(); )
|
||||
{
|
||||
buf.append(nl);
|
||||
buf.append(it.next().toString());
|
||||
}
|
||||
buf.append(")))");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/* Util.java -- Miscellaneous utility methods.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
/**
|
||||
* A collection of useful class methods.
|
||||
*
|
||||
* @author Casey Marshall (rsdio@metastatic.org)
|
||||
*/
|
||||
public final class Util
|
||||
{
|
||||
|
||||
// Constants.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final String HEX = "0123456789abcdef";
|
||||
|
||||
// Class methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Convert a byte array to a hexadecimal string, as though it were a
|
||||
* big-endian arbitrarily-sized integer.
|
||||
*
|
||||
* @param buf The bytes to format.
|
||||
* @param off The offset to start at.
|
||||
* @param len The number of bytes to format.
|
||||
* @return A hexadecimal representation of the specified bytes.
|
||||
*/
|
||||
public static String toHexString(byte[] buf, int off, int len)
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
|
||||
str.append(HEX.charAt(buf[i+off] & 0x0F));
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #toHexString(byte[],int,int)}.
|
||||
*/
|
||||
public static String toHexString(byte[] buf)
|
||||
{
|
||||
return Util.toHexString(buf, 0, buf.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a byte array to a hexadecimal string, separating octets
|
||||
* with the given character.
|
||||
*
|
||||
* @param buf The bytes to format.
|
||||
* @param off The offset to start at.
|
||||
* @param len The number of bytes to format.
|
||||
* @param sep The character to insert between octets.
|
||||
* @return A hexadecimal representation of the specified bytes.
|
||||
*/
|
||||
public static String toHexString(byte[] buf, int off, int len, char sep)
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
|
||||
str.append(HEX.charAt(buf[i+off] & 0x0F));
|
||||
if (i < len - 1)
|
||||
str.append(sep);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #toHexString(byte[],int,int,char)}.
|
||||
*/
|
||||
public static String toHexString(byte[] buf, char sep)
|
||||
{
|
||||
return Util.toHexString(buf, 0, buf.length, sep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a representation of the given byte array similar to the
|
||||
* output of `hexdump -C', which is
|
||||
*
|
||||
* <p><pre>OFFSET SIXTEEN-BYTES-IN-HEX PRINTABLE-BYTES</pre>
|
||||
*
|
||||
* <p>The printable bytes show up as-is if they are printable and
|
||||
* not a newline character, otherwise showing as '.'.
|
||||
*
|
||||
* @param buf The bytes to format.
|
||||
* @param off The offset to start at.
|
||||
* @param len The number of bytes to encode.
|
||||
* @return The formatted string.
|
||||
*/
|
||||
public static String hexDump(byte[] buf, int off, int len, String prefix)
|
||||
{
|
||||
String nl = System.getProperty("line.separator");
|
||||
StringBuffer str = new StringBuffer();
|
||||
int i = 0;
|
||||
while (i < len)
|
||||
{
|
||||
str.append(prefix);
|
||||
str.append(Util.formatInt(i+off, 16, 8));
|
||||
str.append(" ");
|
||||
String s = Util.toHexString(buf, i+off, Math.min(16, len-i), ' ');
|
||||
str.append(s);
|
||||
for (int j = 56 - (56 - s.length()); j < 56; j++)
|
||||
str.append(" ");
|
||||
for (int j = 0; j < Math.min(16, len - i); j++)
|
||||
{
|
||||
if ((buf[i+off+j] & 0xFF) < 0x20 || (buf[i+off+j] & 0xFF) > 0x7E)
|
||||
str.append('.');
|
||||
else
|
||||
str.append((char) (buf[i+off+j] & 0xFF));
|
||||
}
|
||||
str.append(nl);
|
||||
i += 16;
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #hexDump(byte[],int,int)}.
|
||||
*/
|
||||
public static String hexDump(byte[] buf, String prefix)
|
||||
{
|
||||
return hexDump(buf, 0, buf.length, prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format an integer into the specified radix, zero-filled.
|
||||
*
|
||||
* @param i The integer to format.
|
||||
* @param radix The radix to encode to.
|
||||
* @param len The target length of the string. The string is
|
||||
* zero-padded to this length, but may be longer.
|
||||
* @return The formatted integer.
|
||||
*/
|
||||
public static String formatInt(int i, int radix, int len)
|
||||
{
|
||||
String s = Integer.toString(i, radix);
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int j = 0; j < len - s.length(); j++)
|
||||
buf.append("0");
|
||||
buf.append(s);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a hexadecimal string into its byte representation.
|
||||
*
|
||||
* @param hex The hexadecimal string.
|
||||
* @return The converted bytes.
|
||||
*/
|
||||
public static byte[] toByteArray(String hex)
|
||||
{
|
||||
hex = hex.toLowerCase();
|
||||
byte[] buf = new byte[hex.length() / 2];
|
||||
int j = 0;
|
||||
for (int i = 0; i < buf.length; i++)
|
||||
{
|
||||
buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) |
|
||||
Character.digit(hex.charAt(j++), 16));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
/* X500DistinguishedName.java -- X.500 distinguished name.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class X500DistinguishedName implements Principal
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID CN = new OID("2.5.4.3");
|
||||
public static final OID C = new OID("2.5.4.6");
|
||||
public static final OID L = new OID("2.5.4.7");
|
||||
public static final OID ST = new OID("2.5.4.8");
|
||||
public static final OID STREET = new OID("2.5.4.9");
|
||||
public static final OID O = new OID("2.5.4.10");
|
||||
public static final OID OU = new OID("2.5.4.11");
|
||||
public static final OID T = new OID("2.5.4.12");
|
||||
public static final OID DNQ = new OID("2.5.4.46");
|
||||
public static final OID NAME = new OID("2.5.4.41");
|
||||
public static final OID GIVENNAME = new OID("2.5.4.42");
|
||||
public static final OID INITIALS = new OID("2.5.4.43");
|
||||
public static final OID GENERATION = new OID("2.5.4.44");
|
||||
public static final OID EMAIL = new OID("1.2.840.113549.1.9.1");
|
||||
public static final OID DC = new OID("0.9.2342.19200300.100.1.25");
|
||||
public static final OID UID = new OID("0.9.2342.19200300.100.1.1");
|
||||
|
||||
private List components;
|
||||
private Map currentRdn;
|
||||
private boolean fixed;
|
||||
private String stringRep;
|
||||
private byte[] encoded;
|
||||
|
||||
// Constructors.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public X500DistinguishedName()
|
||||
{
|
||||
components = new LinkedList();
|
||||
currentRdn = new LinkedHashMap();
|
||||
components.add(currentRdn);
|
||||
}
|
||||
|
||||
public X500DistinguishedName(String name)
|
||||
{
|
||||
this();
|
||||
try
|
||||
{
|
||||
parseString(name);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new IllegalArgumentException(ioe.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public X500DistinguishedName(byte[] encoded) throws IOException
|
||||
{
|
||||
this();
|
||||
parseDer(new DERReader(encoded));
|
||||
}
|
||||
|
||||
public X500DistinguishedName(InputStream encoded) throws IOException
|
||||
{
|
||||
this();
|
||||
parseDer(new DERReader(encoded));
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return toString();
|
||||
}
|
||||
|
||||
public void newRelativeDistinguishedName()
|
||||
{
|
||||
if (fixed || currentRdn.isEmpty()) return;
|
||||
currentRdn = new LinkedHashMap();
|
||||
components.add(currentRdn);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return components.size();
|
||||
}
|
||||
|
||||
public int countComponents()
|
||||
{
|
||||
int count = 0;
|
||||
for (Iterator it = components.iterator(); it.hasNext(); )
|
||||
{
|
||||
count += ((Map) it.next()).size();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public boolean containsComponent(OID oid, String value)
|
||||
{
|
||||
for (Iterator it = components.iterator(); it.hasNext(); )
|
||||
{
|
||||
Map rdn = (Map) it.next();
|
||||
String s = (String) rdn.get(oid);
|
||||
if (s == null)
|
||||
continue;
|
||||
if (compressWS(value).equalsIgnoreCase(compressWS(s)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getComponent(OID oid)
|
||||
{
|
||||
for (Iterator it = components.iterator(); it.hasNext(); )
|
||||
{
|
||||
Map rdn = (Map) it.next();
|
||||
if (rdn.containsKey(oid))
|
||||
return (String) rdn.get(oid);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getComponent(OID oid, int rdn)
|
||||
{
|
||||
if (rdn >= size())
|
||||
return null;
|
||||
return (String) ((Map) components.get(rdn)).get(oid);
|
||||
}
|
||||
|
||||
public void putComponent(OID oid, String value)
|
||||
{
|
||||
currentRdn.put(oid, value);
|
||||
}
|
||||
|
||||
public void putComponent(String name, String value)
|
||||
{
|
||||
name = name.trim().toLowerCase();
|
||||
if (name.equals("cn"))
|
||||
putComponent(CN, value);
|
||||
else if (name.equals("c"))
|
||||
putComponent(C, value);
|
||||
else if (name.equals("l"))
|
||||
putComponent(L, value);
|
||||
else if (name.equals("street"))
|
||||
putComponent(STREET, value);
|
||||
else if (name.equals("st"))
|
||||
putComponent(ST, value);
|
||||
else if (name.equals("t"))
|
||||
putComponent(T, value);
|
||||
else if (name.equals("dnq"))
|
||||
putComponent(DNQ, value);
|
||||
else if (name.equals("name"))
|
||||
putComponent(NAME, value);
|
||||
else if (name.equals("givenname"))
|
||||
putComponent(GIVENNAME, value);
|
||||
else if (name.equals("initials"))
|
||||
putComponent(INITIALS, value);
|
||||
else if (name.equals("generation"))
|
||||
putComponent(GENERATION, value);
|
||||
else if (name.equals("email"))
|
||||
putComponent(EMAIL, value);
|
||||
else if (name.equals("dc"))
|
||||
putComponent(DC, value);
|
||||
else if (name.equals("uid"))
|
||||
putComponent(UID, value);
|
||||
else
|
||||
putComponent(new OID(name), value);
|
||||
}
|
||||
|
||||
public void setUnmodifiable()
|
||||
{
|
||||
if (fixed) return;
|
||||
fixed = true;
|
||||
List newComps = new ArrayList(components.size());
|
||||
for (Iterator it = components.iterator(); it.hasNext(); )
|
||||
{
|
||||
Map rdn = (Map) it.next();
|
||||
rdn = Collections.unmodifiableMap(rdn);
|
||||
newComps.add(rdn);
|
||||
}
|
||||
components = Collections.unmodifiableList(newComps);
|
||||
currentRdn = Collections.EMPTY_MAP;
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int sum = 0;
|
||||
for (Iterator it = components.iterator(); it.hasNext(); )
|
||||
{
|
||||
Map m = (Map) it.next();
|
||||
for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
|
||||
{
|
||||
Map.Entry e = (Map.Entry) it2.next();
|
||||
sum += e.getKey().hashCode();
|
||||
sum += e.getValue().hashCode();
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (!(o instanceof X500DistinguishedName))
|
||||
return false;
|
||||
if (size() != ((X500DistinguishedName) o).size())
|
||||
return false;
|
||||
for (int i = 0; i < size(); i++)
|
||||
{
|
||||
Map m = (Map) components.get(i);
|
||||
for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
|
||||
{
|
||||
Map.Entry e = (Map.Entry) it2.next();
|
||||
OID oid = (OID) e.getKey();
|
||||
String v1 = (String) e.getValue();
|
||||
String v2 = ((X500DistinguishedName) o).getComponent(oid, i);
|
||||
if (!compressWS(v1).equalsIgnoreCase(compressWS(v2)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
if (fixed && stringRep != null)
|
||||
return stringRep;
|
||||
StringBuffer str = new StringBuffer();
|
||||
for (Iterator it = components.iterator(); it.hasNext(); )
|
||||
{
|
||||
Map m = (Map) it.next();
|
||||
for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) it2.next();
|
||||
OID oid = (OID) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
if (oid.equals(CN))
|
||||
str.append("CN");
|
||||
else if (oid.equals(C))
|
||||
str.append("C");
|
||||
else if (oid.equals(L))
|
||||
str.append("L");
|
||||
else if (oid.equals(ST))
|
||||
str.append("ST");
|
||||
else if (oid.equals(STREET))
|
||||
str.append("STREET");
|
||||
else if (oid.equals(O))
|
||||
str.append("O");
|
||||
else if (oid.equals(OU))
|
||||
str.append("OU");
|
||||
else if (oid.equals(T))
|
||||
str.append("T");
|
||||
else if (oid.equals(DNQ))
|
||||
str.append("DNQ");
|
||||
else if (oid.equals(NAME))
|
||||
str.append("NAME");
|
||||
else
|
||||
str.append(oid.toString());
|
||||
str.append('=');
|
||||
str.append(value);
|
||||
if (it2.hasNext())
|
||||
str.append("+");
|
||||
}
|
||||
if (it.hasNext())
|
||||
str.append(',');
|
||||
}
|
||||
return (stringRep = str.toString());
|
||||
}
|
||||
|
||||
public byte[] getDer()
|
||||
{
|
||||
if (fixed && encoded != null)
|
||||
return (byte[]) encoded.clone();
|
||||
ArrayList name = new ArrayList(components.size());
|
||||
for (Iterator it = components.iterator(); it.hasNext(); )
|
||||
{
|
||||
Map m = (Map) it.next();
|
||||
if (m.isEmpty())
|
||||
continue;
|
||||
Set rdn = new HashSet();
|
||||
for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
|
||||
{
|
||||
Map.Entry e = (Map.Entry) it.next();
|
||||
ArrayList atav = new ArrayList(2);
|
||||
atav.add(new DERValue(DER.OBJECT_IDENTIFIER, e.getKey()));
|
||||
atav.add(new DERValue(DER.UTF8_STRING, e.getValue()));
|
||||
rdn.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, atav));
|
||||
}
|
||||
name.add(new DERValue(DER.SET|DER.CONSTRUCTED, rdn));
|
||||
}
|
||||
DERValue val = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, name);
|
||||
return (byte[]) (encoded = val.getEncoded()).clone();
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private int sep;
|
||||
|
||||
private void parseString(String str) throws IOException
|
||||
{
|
||||
Reader in = new StringReader(str);
|
||||
while (true)
|
||||
{
|
||||
String key = readAttributeType(in);
|
||||
if (key == null)
|
||||
break;
|
||||
String value = readAttributeValue(in);
|
||||
putComponent(key, value);
|
||||
if (sep == ',')
|
||||
newRelativeDistinguishedName();
|
||||
}
|
||||
setUnmodifiable();
|
||||
}
|
||||
|
||||
private String readAttributeType(Reader in) throws IOException
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int ch;
|
||||
while ((ch = in.read()) != '=')
|
||||
{
|
||||
if (ch == -1)
|
||||
{
|
||||
if (buf.length() > 0)
|
||||
throw new EOFException();
|
||||
return null;
|
||||
}
|
||||
if (ch > 127)
|
||||
throw new IOException("Invalid char: " + (char) ch);
|
||||
if (Character.isLetterOrDigit((char) ch) || ch == '-' || ch == '.')
|
||||
buf.append((char) ch);
|
||||
else
|
||||
throw new IOException("Invalid char: " + (char) ch);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String readAttributeValue(Reader in) throws IOException
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int ch = in.read();
|
||||
if (ch == '#')
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
ch = in.read();
|
||||
if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
|
||||
|| Character.isDigit((char) ch))
|
||||
buf.append((char) ch);
|
||||
else if (ch == '+' || ch == ',')
|
||||
{
|
||||
sep = ch;
|
||||
String hex = buf.toString();
|
||||
return new String(Util.toByteArray(hex));
|
||||
}
|
||||
else
|
||||
throw new IOException("illegal character: " + (char) ch);
|
||||
}
|
||||
}
|
||||
else if (ch == '"')
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
ch = in.read();
|
||||
if (ch == '"')
|
||||
break;
|
||||
else if (ch == '\\')
|
||||
{
|
||||
ch = in.read();
|
||||
if (ch == -1)
|
||||
throw new EOFException();
|
||||
if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
|
||||
|| Character.isDigit((char) ch))
|
||||
{
|
||||
int i = Character.digit((char) ch, 16) << 4;
|
||||
ch = in.read();
|
||||
if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
|
||||
|| Character.isDigit((char) ch)))
|
||||
throw new IOException("illegal hex char");
|
||||
i |= Character.digit((char) ch, 16);
|
||||
buf.append((char) i);
|
||||
}
|
||||
else
|
||||
buf.append((char) ch);
|
||||
}
|
||||
else
|
||||
buf.append((char) ch);
|
||||
}
|
||||
sep = in.read();
|
||||
if (sep != '+' || sep != ',')
|
||||
throw new IOException("illegal character: " + (char) ch);
|
||||
return buf.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case '+':
|
||||
case ',':
|
||||
sep = ch;
|
||||
return buf.toString();
|
||||
case '\\':
|
||||
ch = in.read();
|
||||
if (ch == -1)
|
||||
throw new EOFException();
|
||||
if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
|
||||
|| Character.isDigit((char) ch))
|
||||
{
|
||||
int i = Character.digit((char) ch, 16) << 4;
|
||||
ch = in.read();
|
||||
if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
|
||||
|| Character.isDigit((char) ch)))
|
||||
throw new IOException("illegal hex char");
|
||||
i |= Character.digit((char) ch, 16);
|
||||
buf.append((char) i);
|
||||
}
|
||||
else
|
||||
buf.append((char) ch);
|
||||
break;
|
||||
case '=':
|
||||
case '<':
|
||||
case '>':
|
||||
case '#':
|
||||
case ';':
|
||||
throw new IOException("illegal character: " + (char) ch);
|
||||
case -1:
|
||||
throw new EOFException();
|
||||
default:
|
||||
buf.append((char) ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDer(DERReader der) throws IOException
|
||||
{
|
||||
DERValue name = der.read();
|
||||
if (!name.isConstructed())
|
||||
throw new IOException("malformed Name");
|
||||
encoded = name.getEncoded();
|
||||
int len = 0;
|
||||
while (len < name.getLength())
|
||||
{
|
||||
DERValue rdn = der.read();
|
||||
if (!rdn.isConstructed())
|
||||
throw new IOException("badly formed RDNSequence");
|
||||
int len2 = 0;
|
||||
while (len2 < rdn.getLength())
|
||||
{
|
||||
DERValue atav = der.read();
|
||||
if (!atav.isConstructed())
|
||||
throw new IOException("badly formed AttributeTypeAndValue");
|
||||
DERValue val = der.read();
|
||||
if (val.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new IOException("badly formed AttributeTypeAndValue");
|
||||
OID oid = (OID) val.getValue();
|
||||
val = der.read();
|
||||
if (!(val.getValue() instanceof String))
|
||||
throw new IOException("badly formed AttributeTypeAndValue");
|
||||
String value = (String) val.getValue();
|
||||
putComponent(oid, value);
|
||||
len2 += atav.getEncodedLength();
|
||||
}
|
||||
len += rdn.getEncodedLength();
|
||||
if (len < name.getLength())
|
||||
newRelativeDistinguishedName();
|
||||
}
|
||||
setUnmodifiable();
|
||||
}
|
||||
|
||||
private static String compressWS(String str)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
char lastChar = 0;
|
||||
for (int i = 0; i < str.length(); i++)
|
||||
{
|
||||
char c = str.charAt(i);
|
||||
if (Character.isWhitespace(c))
|
||||
{
|
||||
if (!Character.isWhitespace(lastChar))
|
||||
buf.append(' ');
|
||||
}
|
||||
else
|
||||
buf.append(c);
|
||||
lastChar = c;
|
||||
}
|
||||
return buf.toString().trim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
/* X509CRL.java -- X.509 certificate revocation list.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.BitString;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.x509.ext.Extension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Principal;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.CRLException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
/**
|
||||
* X.509 certificate revocation lists.
|
||||
*
|
||||
* @author Casey Marshall (rsdio@metastatic.org)
|
||||
*/
|
||||
public class X509CRL extends java.security.cert.X509CRL
|
||||
implements GnuPKIExtension
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static void debug(String msg)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.err.print(">> X509CRL: ");
|
||||
System.err.println(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
|
||||
private static final OID ID_DSA_WITH_SHA1 = new OID("1.2.840.10040.4.3");
|
||||
private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
|
||||
private static final OID ID_RSA_WITH_MD2 = new OID("1.2.840.113549.1.1.2");
|
||||
private static final OID ID_RSA_WITH_MD5 = new OID("1.2.840.113549.1.1.4");
|
||||
private static final OID ID_RSA_WITH_SHA1 = new OID("1.2.840.113549.1.1.5");
|
||||
|
||||
private byte[] encoded;
|
||||
|
||||
private byte[] tbsCRLBytes;
|
||||
private int version;
|
||||
private OID algId;
|
||||
private byte[] algParams;
|
||||
private Date thisUpdate;
|
||||
private Date nextUpdate;
|
||||
private X500DistinguishedName issuerDN;
|
||||
private HashMap revokedCerts;
|
||||
private HashMap extensions;
|
||||
|
||||
private OID sigAlg;
|
||||
private byte[] sigAlgParams;
|
||||
private byte[] rawSig;
|
||||
private byte[] signature;
|
||||
|
||||
// Constructors.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new X.509 CRL.
|
||||
*
|
||||
* @param encoded The DER encoded CRL.
|
||||
* @throws CRLException If the input bytes are incorrect.
|
||||
* @throws IOException If the input bytes cannot be read.
|
||||
*/
|
||||
public X509CRL(InputStream encoded) throws CRLException, IOException
|
||||
{
|
||||
super();
|
||||
revokedCerts = new HashMap();
|
||||
extensions = new HashMap();
|
||||
try
|
||||
{
|
||||
parse(encoded);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
ioe.printStackTrace();
|
||||
throw ioe;
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
x.printStackTrace();
|
||||
throw new CRLException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// X509CRL methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (!(o instanceof X509CRL))
|
||||
return false;
|
||||
return ((X509CRL) o).getRevokedCertificates().equals(revokedCerts.values());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return revokedCerts.hashCode();
|
||||
}
|
||||
|
||||
public byte[] getEncoded() throws CRLException
|
||||
{
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public void verify(PublicKey key)
|
||||
throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
|
||||
NoSuchProviderException, SignatureException
|
||||
{
|
||||
Signature sig = Signature.getInstance(sigAlg.toString());
|
||||
doVerify(sig, key);
|
||||
}
|
||||
|
||||
public void verify(PublicKey key, String provider)
|
||||
throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
|
||||
NoSuchProviderException, SignatureException
|
||||
{
|
||||
Signature sig = Signature.getInstance(sigAlg.toString(), provider);
|
||||
doVerify(sig, key);
|
||||
}
|
||||
|
||||
public int getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
public Principal getIssuerDN()
|
||||
{
|
||||
return issuerDN;
|
||||
}
|
||||
|
||||
public X500Principal getIssuerX500Principal()
|
||||
{
|
||||
return new X500Principal(issuerDN.getDer());
|
||||
}
|
||||
|
||||
public Date getThisUpdate()
|
||||
{
|
||||
return (Date) thisUpdate.clone();
|
||||
}
|
||||
|
||||
public Date getNextUpdate()
|
||||
{
|
||||
if (nextUpdate != null)
|
||||
return (Date) nextUpdate.clone();
|
||||
return null;
|
||||
}
|
||||
|
||||
public java.security.cert.X509CRLEntry getRevokedCertificate(BigInteger serialNo)
|
||||
{
|
||||
return (java.security.cert.X509CRLEntry) revokedCerts.get(serialNo);
|
||||
}
|
||||
|
||||
public Set getRevokedCertificates()
|
||||
{
|
||||
return Collections.unmodifiableSet(new HashSet(revokedCerts.values()));
|
||||
}
|
||||
|
||||
public byte[] getTBSCertList() throws CRLException
|
||||
{
|
||||
return (byte[]) tbsCRLBytes.clone();
|
||||
}
|
||||
|
||||
public byte[] getSignature()
|
||||
{
|
||||
return (byte[]) rawSig.clone();
|
||||
}
|
||||
|
||||
public String getSigAlgName()
|
||||
{
|
||||
if (sigAlg.equals(ID_DSA_WITH_SHA1))
|
||||
return "SHA1withDSA";
|
||||
if (sigAlg.equals(ID_RSA_WITH_MD2))
|
||||
return "MD2withRSA";
|
||||
if (sigAlg.equals(ID_RSA_WITH_MD5))
|
||||
return "MD5withRSA";
|
||||
if (sigAlg.equals(ID_RSA_WITH_SHA1))
|
||||
return "SHA1withRSA";
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public String getSigAlgOID()
|
||||
{
|
||||
return sigAlg.toString();
|
||||
}
|
||||
|
||||
public byte[] getSigAlgParams()
|
||||
{
|
||||
if (sigAlgParams != null)
|
||||
return (byte[]) sigAlgParams.clone();
|
||||
return null;
|
||||
}
|
||||
|
||||
// X509Extension methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public boolean hasUnsupportedCriticalExtension()
|
||||
{
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (e.isCritical() && !e.isSupported())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set getCriticalExtensionOIDs()
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (e.isCritical())
|
||||
s.add(e.getOid().toString());
|
||||
}
|
||||
return Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
public Set getNonCriticalExtensionOIDs()
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (!e.isCritical())
|
||||
s.add(e.getOid().toString());
|
||||
}
|
||||
return Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
public byte[] getExtensionValue(String oid)
|
||||
{
|
||||
Extension e = getExtension(new OID(oid));
|
||||
if (e != null)
|
||||
{
|
||||
return e.getValue().getEncoded();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// GnuPKIExtension method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Extension getExtension(OID oid)
|
||||
{
|
||||
return (Extension) extensions.get(oid);
|
||||
}
|
||||
|
||||
public Collection getExtensions()
|
||||
{
|
||||
return extensions.values();
|
||||
}
|
||||
|
||||
// CRL methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return X509CRL.class.getName();
|
||||
}
|
||||
|
||||
public boolean isRevoked(Certificate cert)
|
||||
{
|
||||
if (!(cert instanceof java.security.cert.X509Certificate))
|
||||
throw new IllegalArgumentException("not a X.509 certificate");
|
||||
BigInteger certSerial =
|
||||
((java.security.cert.X509Certificate) cert).getSerialNumber();
|
||||
X509CRLEntry ent = (X509CRLEntry) revokedCerts.get(certSerial);
|
||||
if (ent == null)
|
||||
return false;
|
||||
return ent.getRevocationDate().compareTo(new Date()) < 0;
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private void doVerify(Signature sig, PublicKey key)
|
||||
throws CRLException, InvalidKeyException, SignatureException
|
||||
{
|
||||
sig.initVerify(key);
|
||||
sig.update(tbsCRLBytes);
|
||||
if (!sig.verify(signature))
|
||||
throw new CRLException("signature not verified");
|
||||
}
|
||||
|
||||
private void parse(InputStream in) throws Exception
|
||||
{
|
||||
// CertificateList ::= SEQUENCE {
|
||||
DERReader der = new DERReader(in);
|
||||
DERValue val = der.read();
|
||||
debug("start CertificateList len == " + val.getLength());
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed CertificateList");
|
||||
encoded = val.getEncoded();
|
||||
|
||||
// tbsCertList ::= SEQUENCE { -- TBSCertList
|
||||
val = der.read();
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed TBSCertList");
|
||||
debug("start tbsCertList len == " + val.getLength());
|
||||
tbsCRLBytes = val.getEncoded();
|
||||
|
||||
// version Version OPTIONAL,
|
||||
// -- If present must be v2
|
||||
val = der.read();
|
||||
if (val.getValue() instanceof BigInteger)
|
||||
{
|
||||
version = ((BigInteger) val.getValue()).intValue() + 1;
|
||||
val = der.read();
|
||||
}
|
||||
else
|
||||
version = 1;
|
||||
debug("read version == " + version);
|
||||
|
||||
// signature AlgorithmIdentifier,
|
||||
debug("start AlgorithmIdentifier len == " + val.getLength());
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed AlgorithmIdentifier");
|
||||
DERValue algIdVal = der.read();
|
||||
algId = (OID) algIdVal.getValue();
|
||||
debug("read object identifier == " + algId);
|
||||
if (val.getLength() > algIdVal.getEncodedLength())
|
||||
{
|
||||
val = der.read();
|
||||
debug("read parameters len == " + val.getEncodedLength());
|
||||
algParams = val.getEncoded();
|
||||
if (val.isConstructed())
|
||||
in.skip(val.getLength());
|
||||
}
|
||||
|
||||
// issuer Name,
|
||||
val = der.read();
|
||||
issuerDN = new X500DistinguishedName(val.getEncoded());
|
||||
der.skip(val.getLength());
|
||||
debug("read issuer == " + issuerDN);
|
||||
|
||||
// thisUpdate Time,
|
||||
thisUpdate = (Date) der.read().getValue();
|
||||
debug("read thisUpdate == " + thisUpdate);
|
||||
|
||||
// nextUpdate Time OPTIONAL,
|
||||
val = der.read();
|
||||
if (val.getValue() instanceof Date)
|
||||
{
|
||||
nextUpdate = (Date) val.getValue();
|
||||
debug("read nextUpdate == " + nextUpdate);
|
||||
val = der.read();
|
||||
}
|
||||
|
||||
// revokedCertificates SEQUENCE OF SEQUENCE {
|
||||
// -- X509CRLEntry objects...
|
||||
// } OPTIONAL,
|
||||
if (val.getTag() != 0)
|
||||
{
|
||||
int len = 0;
|
||||
while (len < val.getLength())
|
||||
{
|
||||
X509CRLEntry entry = new X509CRLEntry(version, der);
|
||||
revokedCerts.put(entry.getSerialNumber(), entry);
|
||||
len += entry.getEncoded().length;
|
||||
}
|
||||
val = der.read();
|
||||
}
|
||||
|
||||
// crlExtensions [0] EXPLICIT Extensions OPTIONAL
|
||||
// -- if present MUST be v2
|
||||
if (val.getTagClass() != DER.UNIVERSAL && val.getTag() == 0)
|
||||
{
|
||||
if (version < 2)
|
||||
throw new IOException("extra data in CRL");
|
||||
DERValue exts = der.read();
|
||||
if (!exts.isConstructed())
|
||||
throw new IOException("malformed Extensions");
|
||||
debug("start Extensions len == " + exts.getLength());
|
||||
int len = 0;
|
||||
while (len < exts.getLength())
|
||||
{
|
||||
DERValue ext = der.read();
|
||||
if (!ext.isConstructed())
|
||||
throw new IOException("malformed Extension");
|
||||
Extension e = new Extension(ext.getEncoded());
|
||||
extensions.put(e.getOid(), e);
|
||||
der.skip(ext.getLength());
|
||||
len += ext.getEncodedLength();
|
||||
debug("current count == " + len);
|
||||
}
|
||||
val = der.read();
|
||||
}
|
||||
|
||||
debug("read tag == " + val.getTag());
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed AlgorithmIdentifier");
|
||||
debug("start AlgorithmIdentifier len == " + val.getLength());
|
||||
DERValue sigAlgVal = der.read();
|
||||
debug("read tag == " + sigAlgVal.getTag());
|
||||
if (sigAlgVal.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new IOException("malformed AlgorithmIdentifier");
|
||||
sigAlg = (OID) sigAlgVal.getValue();
|
||||
debug("signature id == " + sigAlg);
|
||||
debug("sigAlgVal length == " + sigAlgVal.getEncodedLength());
|
||||
if (val.getLength() > sigAlgVal.getEncodedLength())
|
||||
{
|
||||
val = der.read();
|
||||
debug("sig params tag = " + val.getTag() + " len == " + val.getEncodedLength());
|
||||
sigAlgParams = (byte[]) val.getEncoded();
|
||||
if (val.isConstructed())
|
||||
in.skip(val.getLength());
|
||||
}
|
||||
val = der.read();
|
||||
debug("read tag = " + val.getTag());
|
||||
rawSig = val.getEncoded();
|
||||
signature = ((BitString) val.getValue()).toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
/* X509CRLEntry.java -- an entry in a X.509 CRL.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.x509.ext.Extension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.cert.CRLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A single entry in a X.509 certificate revocation list.
|
||||
*
|
||||
* @see X509CRL
|
||||
* @author Casey Marshall
|
||||
*/
|
||||
class X509CRLEntry extends java.security.cert.X509CRLEntry
|
||||
implements GnuPKIExtension
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static void debug(String msg)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.err.print(">> X509CRLEntry: ");
|
||||
System.err.println(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/** The DER encoded form of this CRL entry. */
|
||||
private byte[] encoded;
|
||||
|
||||
/** The revoked certificate's serial number. */
|
||||
private BigInteger serialNo;
|
||||
|
||||
/** The date the certificate was revoked. */
|
||||
private Date revocationDate;
|
||||
|
||||
/** The CRL entry extensions. */
|
||||
private HashMap extensions;
|
||||
|
||||
// Constructor.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new X.509 certificate revocation list entry from the given
|
||||
* input stream and CRL version number.
|
||||
*
|
||||
* @param version The CRL version.
|
||||
* @param encoded The stream of DER bytes.
|
||||
* @throws CRLException If the ASN.1 structure is invalid.
|
||||
* @throws IOException If the bytes cannot be read.
|
||||
*/
|
||||
X509CRLEntry(int version, DERReader encoded)
|
||||
throws CRLException, IOException
|
||||
{
|
||||
super();
|
||||
extensions = new HashMap();
|
||||
try
|
||||
{
|
||||
parse(version, encoded);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw ioe;
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
throw new CRLException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// X509CRLEntry methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (!(o instanceof X509CRLEntry))
|
||||
return false;
|
||||
return ((X509CRLEntry) o).getSerialNumber().equals(serialNo) &&
|
||||
((X509CRLEntry) o).getRevocationDate().equals(revocationDate);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return serialNo.hashCode();
|
||||
}
|
||||
|
||||
public byte[] getEncoded() throws CRLException
|
||||
{
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public BigInteger getSerialNumber()
|
||||
{
|
||||
return serialNo;
|
||||
}
|
||||
|
||||
public Date getRevocationDate()
|
||||
{
|
||||
return (Date) revocationDate.clone();
|
||||
}
|
||||
|
||||
public boolean hasExtensions()
|
||||
{
|
||||
return ! extensions.isEmpty();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "X509CRLEntry serial=" + serialNo + " revocation date="
|
||||
+ revocationDate + " ext=" + extensions;
|
||||
}
|
||||
|
||||
// X509Extension methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public boolean hasUnsupportedCriticalExtension()
|
||||
{
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (e.isCritical() && !e.isSupported())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set getCriticalExtensionOIDs()
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (e.isCritical())
|
||||
s.add(e.getOid().toString());
|
||||
}
|
||||
return Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
public Set getNonCriticalExtensionOIDs()
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (!e.isCritical())
|
||||
s.add(e.getOid().toString());
|
||||
}
|
||||
return Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
public byte[] getExtensionValue(String oid)
|
||||
{
|
||||
Extension e = getExtension(new OID(oid));
|
||||
if (e != null)
|
||||
{
|
||||
return e.getValue().getEncoded();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// GnuPKIExtension method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Extension getExtension(OID oid)
|
||||
{
|
||||
return (Extension) extensions.get(oid);
|
||||
}
|
||||
|
||||
public Collection getExtensions()
|
||||
{
|
||||
return extensions.values();
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private void parse(int version, DERReader der) throws Exception
|
||||
{
|
||||
// RevokedCertificate ::= SEQUENCE {
|
||||
DERValue entry = der.read();
|
||||
debug("start CRL entry len == " + entry.getLength());
|
||||
if (!entry.isConstructed())
|
||||
throw new IOException("malformed revokedCertificate");
|
||||
encoded = entry.getEncoded();
|
||||
int len = 0;
|
||||
|
||||
debug("encoded entry:\n" + Util.hexDump(encoded, ">>>> "));
|
||||
|
||||
// userCertificate CertificateSerialNumber,
|
||||
DERValue val = der.read();
|
||||
serialNo = (BigInteger) val.getValue();
|
||||
len += val.getEncodedLength();
|
||||
debug("userCertificate == " + serialNo + " current count == " + len);
|
||||
|
||||
// revocationDate Time,
|
||||
val = der.read();
|
||||
revocationDate = (Date) val.getValue();
|
||||
len += val.getEncodedLength();
|
||||
debug("revocationDate == " + revocationDate + " current count == " + len);
|
||||
|
||||
// crlEntryExtensions Extensions OPTIONAL
|
||||
// -- if present MUST be v2
|
||||
if (len < entry.getLength())
|
||||
{
|
||||
if (version < 2)
|
||||
throw new IOException("extra data in CRL entry");
|
||||
DERValue exts = der.read();
|
||||
if (!exts.isConstructed())
|
||||
throw new IOException("malformed Extensions");
|
||||
debug("start Extensions len == " + exts.getLength());
|
||||
len = 0;
|
||||
while (len < exts.getLength())
|
||||
{
|
||||
val = der.read();
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed Extension");
|
||||
debug("start Extension len == " + val.getLength());
|
||||
Extension e = new Extension(val.getEncoded());
|
||||
extensions.put(e.getOid(), e);
|
||||
der.skip(val.getLength());
|
||||
len += val.getEncodedLength();
|
||||
debug("current count == " + len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/* X509CRLSelectorImpl.java -- implementation of an X509CRLSelector.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.security.cert.CRL;
|
||||
import java.security.cert.CRLSelector;
|
||||
import java.security.cert.X509CRL;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
/**
|
||||
* Sun's implementation of X509CRLSelector sucks. This one tries to work
|
||||
* better.
|
||||
*/
|
||||
public class X509CRLSelectorImpl implements CRLSelector
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private Set issuerNames;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public X509CRLSelectorImpl()
|
||||
{
|
||||
issuerNames = new HashSet();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public void addIssuerName(byte[] issuerName) throws IOException
|
||||
{
|
||||
issuerNames.add(new X500DistinguishedName(issuerName));
|
||||
}
|
||||
|
||||
public void addIssuerName(String issuerName)
|
||||
{
|
||||
issuerNames.add(new X500DistinguishedName(issuerName));
|
||||
}
|
||||
|
||||
public void addIssuerName(Principal issuerName) throws IOException
|
||||
{
|
||||
if (issuerName instanceof X500DistinguishedName)
|
||||
issuerNames.add(issuerName);
|
||||
else if (issuerName instanceof X500Principal)
|
||||
issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded()));
|
||||
else
|
||||
issuerNames.add(new X500DistinguishedName(issuerName.getName()));
|
||||
}
|
||||
|
||||
public Collection getIssuerNames()
|
||||
{
|
||||
return Collections.unmodifiableSet(issuerNames);
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
X509CRLSelectorImpl copy = new X509CRLSelectorImpl();
|
||||
copy.issuerNames.addAll(issuerNames);
|
||||
return copy;
|
||||
}
|
||||
|
||||
public boolean match(CRL crl)
|
||||
{
|
||||
if (!(crl instanceof X509CRL))
|
||||
return false;
|
||||
try
|
||||
{
|
||||
Principal p = ((X509CRL) crl).getIssuerDN();
|
||||
X500DistinguishedName thisName = null;
|
||||
if (p instanceof X500DistinguishedName)
|
||||
thisName = (X500DistinguishedName) p;
|
||||
else if (p instanceof X500Principal)
|
||||
thisName = new X500DistinguishedName(((X500Principal) p).getEncoded());
|
||||
else
|
||||
thisName = new X500DistinguishedName(p.getName());
|
||||
for (Iterator it = issuerNames.iterator(); it.hasNext(); )
|
||||
{
|
||||
X500DistinguishedName name = (X500DistinguishedName) it.next();
|
||||
if (thisName.equals(name))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
/* X509CertPath.java -- an X.509 certificate path.
|
||||
Copyright (C) 2004 Free Software Fonudation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DEREncodingException;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A certificate path (or certificate chain) of X509Certificates.
|
||||
*
|
||||
* @author Casey Marshall (rsdio@metastatic.org)
|
||||
*/
|
||||
public class X509CertPath extends CertPath
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final List ENCODINGS = Collections.unmodifiableList(
|
||||
Arrays.asList(new String[] { "PkiPath", "PKCS7" }));
|
||||
|
||||
private static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2");
|
||||
private static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1");
|
||||
|
||||
/** The certificate path. */
|
||||
private List path;
|
||||
|
||||
/** The cached PKCS #7 encoded bytes. */
|
||||
private byte[] pkcs_encoded;
|
||||
|
||||
/** The cached PkiPath encoded bytes. */
|
||||
private byte[] pki_encoded;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public X509CertPath(List path)
|
||||
{
|
||||
super("X.509");
|
||||
this.path = Collections.unmodifiableList(path);
|
||||
}
|
||||
|
||||
public X509CertPath(InputStream in) throws CertificateEncodingException
|
||||
{
|
||||
this(in, (String) ENCODINGS.get(0));
|
||||
}
|
||||
|
||||
public X509CertPath(InputStream in, String encoding)
|
||||
throws CertificateEncodingException
|
||||
{
|
||||
super("X.509");
|
||||
try
|
||||
{
|
||||
parse(in, encoding);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new CertificateEncodingException();
|
||||
}
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public List getCertificates()
|
||||
{
|
||||
return path; // already unmodifiable
|
||||
}
|
||||
|
||||
public byte[] getEncoded() throws CertificateEncodingException
|
||||
{
|
||||
return getEncoded((String) ENCODINGS.get(0));
|
||||
}
|
||||
|
||||
public byte[] getEncoded(String encoding) throws CertificateEncodingException
|
||||
{
|
||||
if (encoding.equalsIgnoreCase("PkiPath"))
|
||||
{
|
||||
if (pki_encoded == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
pki_encoded = encodePki();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new CertificateEncodingException();
|
||||
}
|
||||
}
|
||||
return (byte[]) pki_encoded.clone();
|
||||
}
|
||||
else if (encoding.equalsIgnoreCase("PKCS7"))
|
||||
{
|
||||
if (pkcs_encoded == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
pkcs_encoded = encodePKCS();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new CertificateEncodingException();
|
||||
}
|
||||
}
|
||||
return (byte[]) pkcs_encoded.clone();
|
||||
}
|
||||
else
|
||||
throw new CertificateEncodingException("unknown encoding: " + encoding);
|
||||
}
|
||||
|
||||
public Iterator getEncodings()
|
||||
{
|
||||
return ENCODINGS.iterator(); // already unmodifiable
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private void parse(InputStream in, String encoding)
|
||||
throws CertificateEncodingException, IOException
|
||||
{
|
||||
DERReader der = new DERReader(in);
|
||||
DERValue path = null;
|
||||
if (encoding.equalsIgnoreCase("PkiPath"))
|
||||
{
|
||||
// PKI encoding is just a SEQUENCE of X.509 certificates.
|
||||
path = der.read();
|
||||
if (!path.isConstructed())
|
||||
throw new DEREncodingException("malformed PkiPath");
|
||||
}
|
||||
else if (encoding.equalsIgnoreCase("PKCS7"))
|
||||
{
|
||||
// PKCS #7 encoding means that the certificates are contained in a
|
||||
// SignedData PKCS #7 type.
|
||||
//
|
||||
// ContentInfo ::= SEQUENCE {
|
||||
// contentType ::= ContentType,
|
||||
// content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
|
||||
//
|
||||
// ContentType ::= OBJECT IDENTIFIER
|
||||
//
|
||||
// SignedData ::= SEQUENCE {
|
||||
// version Version,
|
||||
// digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
// contentInfo ContentInfo,
|
||||
// certificates [0] IMPLICIT ExtendedCertificatesAndCertificates
|
||||
// OPTIONAL,
|
||||
// crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
|
||||
// signerInfos SignerInfos }
|
||||
//
|
||||
// Version ::= INTEGER
|
||||
//
|
||||
DERValue value = der.read();
|
||||
if (!value.isConstructed())
|
||||
throw new DEREncodingException("malformed ContentInfo");
|
||||
value = der.read();
|
||||
if (!(value.getValue() instanceof OID) ||
|
||||
((OID) value.getValue()).equals(PKCS7_SIGNED_DATA))
|
||||
throw new DEREncodingException("not a SignedData");
|
||||
value = der.read();
|
||||
if (!value.isConstructed() || value.getTag() != 0)
|
||||
throw new DEREncodingException("malformed content");
|
||||
value = der.read();
|
||||
if (value.getTag() != DER.INTEGER)
|
||||
throw new DEREncodingException("malformed Version");
|
||||
value = der.read();
|
||||
if (!value.isConstructed() || value.getTag() != DER.SET)
|
||||
throw new DEREncodingException("malformed DigestAlgorithmIdentifiers");
|
||||
der.skip(value.getLength());
|
||||
value = der.read();
|
||||
if (!value.isConstructed())
|
||||
throw new DEREncodingException("malformed ContentInfo");
|
||||
der.skip(value.getLength());
|
||||
path = der.read();
|
||||
if (!path.isConstructed() || path.getTag() != 0)
|
||||
throw new DEREncodingException("no certificates");
|
||||
}
|
||||
else
|
||||
throw new CertificateEncodingException("unknown encoding: " + encoding);
|
||||
|
||||
LinkedList certs = new LinkedList();
|
||||
int len = 0;
|
||||
while (len < path.getLength())
|
||||
{
|
||||
DERValue cert = der.read();
|
||||
try
|
||||
{
|
||||
certs.add(new X509Certificate(new ByteArrayInputStream(cert.getEncoded())));
|
||||
}
|
||||
catch (CertificateException ce)
|
||||
{
|
||||
throw new CertificateEncodingException(ce.getMessage());
|
||||
}
|
||||
len += cert.getEncodedLength();
|
||||
der.skip(cert.getLength());
|
||||
}
|
||||
|
||||
this.path = Collections.unmodifiableList(certs);
|
||||
}
|
||||
|
||||
private byte[] encodePki()
|
||||
throws CertificateEncodingException, IOException
|
||||
{
|
||||
synchronized (path)
|
||||
{
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
for (Iterator i = path.iterator(); i.hasNext(); )
|
||||
{
|
||||
out.write(((Certificate) i.next()).getEncoded());
|
||||
}
|
||||
byte[] b = out.toByteArray();
|
||||
DERValue val = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
|
||||
b.length, b, null);
|
||||
return val.getEncoded();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] encodePKCS()
|
||||
throws CertificateEncodingException, IOException
|
||||
{
|
||||
synchronized (path)
|
||||
{
|
||||
ArrayList signedData = new ArrayList(5);
|
||||
signedData.add(new DERValue(DER.INTEGER, BigInteger.ONE));
|
||||
signedData.add(new DERValue(DER.CONSTRUCTED | DER.SET,
|
||||
Collections.EMPTY_SET));
|
||||
signedData.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
|
||||
Collections.singletonList(
|
||||
new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_DATA))));
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
for (Iterator i = path.iterator(); i.hasNext(); )
|
||||
{
|
||||
out.write(((Certificate) i.next()).getEncoded());
|
||||
}
|
||||
byte[] b = out.toByteArray();
|
||||
signedData.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT,
|
||||
b.length, b, null));
|
||||
DERValue sdValue = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
|
||||
signedData);
|
||||
|
||||
ArrayList contentInfo = new ArrayList(2);
|
||||
contentInfo.add(new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_SIGNED_DATA));
|
||||
contentInfo.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT, sdValue));
|
||||
return new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
|
||||
contentInfo).getEncoded();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/* X509CertSelectorImpl.java -- implementation of an X509CertSelector.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.CertSelector;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
/**
|
||||
* Sun's implementation of X509CertSelector sucks. This one tries to work
|
||||
* better.
|
||||
*/
|
||||
public class X509CertSelectorImpl implements CertSelector
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private Set issuerNames;
|
||||
private Set subjectNames;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public X509CertSelectorImpl()
|
||||
{
|
||||
issuerNames = new HashSet();
|
||||
subjectNames = new HashSet();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public void addIssuerName(byte[] issuerName) throws IOException
|
||||
{
|
||||
issuerNames.add(new X500DistinguishedName(issuerName));
|
||||
}
|
||||
|
||||
public void addIssuerName(String issuerName)
|
||||
{
|
||||
issuerNames.add(new X500DistinguishedName(issuerName));
|
||||
}
|
||||
|
||||
public void addIssuerName(Principal issuerName) throws IOException
|
||||
{
|
||||
if (issuerName instanceof X500DistinguishedName)
|
||||
issuerNames.add(issuerName);
|
||||
else if (issuerName instanceof X500Principal)
|
||||
issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded()));
|
||||
else
|
||||
issuerNames.add(new X500DistinguishedName(issuerName.getName()));
|
||||
}
|
||||
|
||||
public Collection getIssuerNames()
|
||||
{
|
||||
return Collections.unmodifiableSet(issuerNames);
|
||||
}
|
||||
|
||||
public void addSubjectName(byte[] subjectName) throws IOException
|
||||
{
|
||||
subjectNames.add(new X500DistinguishedName(subjectName));
|
||||
}
|
||||
|
||||
public void addSubjectName(String subjectName) throws IOException
|
||||
{
|
||||
subjectNames.add(new X500DistinguishedName(subjectName));
|
||||
}
|
||||
|
||||
public void addSubjectName(Principal subjectName) throws IOException
|
||||
{
|
||||
if (subjectName instanceof X500DistinguishedName)
|
||||
subjectNames.add(subjectName);
|
||||
else if (subjectName instanceof X500Principal)
|
||||
subjectNames.add(new X500DistinguishedName(((X500Principal) subjectName).getEncoded()));
|
||||
else
|
||||
subjectNames.add(new X500DistinguishedName(subjectName.getName()));
|
||||
}
|
||||
|
||||
public Collection getSubjectNames()
|
||||
{
|
||||
return Collections.unmodifiableSet(subjectNames);
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
X509CertSelectorImpl copy = new X509CertSelectorImpl();
|
||||
copy.issuerNames.addAll(issuerNames);
|
||||
copy.subjectNames.addAll(subjectNames);
|
||||
return copy;
|
||||
}
|
||||
|
||||
public boolean match(Certificate cert)
|
||||
{
|
||||
if (!(cert instanceof X509Certificate))
|
||||
return false;
|
||||
boolean matchIssuer = false;
|
||||
boolean matchSubject = false;
|
||||
try
|
||||
{
|
||||
Principal p = ((X509Certificate) cert).getIssuerDN();
|
||||
X500DistinguishedName thisName = null;
|
||||
if (p instanceof X500DistinguishedName)
|
||||
thisName = (X500DistinguishedName) p;
|
||||
else if (p instanceof X500Principal)
|
||||
thisName = new X500DistinguishedName(((X500Principal) p).getEncoded());
|
||||
else
|
||||
thisName = new X500DistinguishedName(p.getName());
|
||||
if (issuerNames.isEmpty())
|
||||
matchIssuer = true;
|
||||
else
|
||||
{
|
||||
for (Iterator it = issuerNames.iterator(); it.hasNext(); )
|
||||
{
|
||||
X500DistinguishedName name = (X500DistinguishedName) it.next();
|
||||
if (thisName.equals(name))
|
||||
{
|
||||
matchIssuer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p = ((X509Certificate) cert).getSubjectDN();
|
||||
thisName = null;
|
||||
if (p instanceof X500DistinguishedName)
|
||||
thisName = (X500DistinguishedName) p;
|
||||
else if (p instanceof X500Principal)
|
||||
thisName = new X500DistinguishedName(((X500Principal) p).getEncoded());
|
||||
else
|
||||
thisName = new X500DistinguishedName(p.getName());
|
||||
if (subjectNames.isEmpty())
|
||||
matchSubject = true;
|
||||
else
|
||||
{
|
||||
for (Iterator it = subjectNames.iterator(); it.hasNext(); )
|
||||
{
|
||||
X500DistinguishedName name = (X500DistinguishedName) it.next();
|
||||
if (thisName.equals(name))
|
||||
{
|
||||
matchSubject = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
}
|
||||
return matchIssuer && matchSubject;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,745 @@
|
||||
/* X509Certificate.java -- X.509 certificate.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509;
|
||||
|
||||
import gnu.classpath.debug.Component;
|
||||
import gnu.classpath.debug.SystemLogger;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.BitString;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.x509.ext.BasicConstraints;
|
||||
import gnu.java.security.x509.ext.ExtendedKeyUsage;
|
||||
import gnu.java.security.x509.ext.Extension;
|
||||
import gnu.java.security.x509.ext.IssuerAlternativeNames;
|
||||
import gnu.java.security.x509.ext.KeyUsage;
|
||||
import gnu.java.security.x509.ext.SubjectAlternativeNames;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Principal;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.CertificateParsingException;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
/**
|
||||
* An implementation of X.509 certificates.
|
||||
*
|
||||
* @author Casey Marshall (rsdio@metastatic.org)
|
||||
*/
|
||||
public class X509Certificate extends java.security.cert.X509Certificate
|
||||
implements Serializable, GnuPKIExtension
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static final Logger logger = SystemLogger.SYSTEM;
|
||||
|
||||
protected static final OID ID_DSA = new OID ("1.2.840.10040.4.1");
|
||||
protected static final OID ID_DSA_WITH_SHA1 = new OID ("1.2.840.10040.4.3");
|
||||
protected static final OID ID_RSA = new OID ("1.2.840.113549.1.1.1");
|
||||
protected static final OID ID_RSA_WITH_MD2 = new OID ("1.2.840.113549.1.1.2");
|
||||
protected static final OID ID_RSA_WITH_MD5 = new OID ("1.2.840.113549.1.1.4");
|
||||
protected static final OID ID_RSA_WITH_SHA1 = new OID ("1.2.840.113549.1.1.5");
|
||||
protected static final OID ID_ECDSA_WITH_SHA1 = new OID ("1.2.840.10045.4.1");
|
||||
|
||||
// This object SHOULD be serialized with an instance of
|
||||
// java.security.cert.Certificate.CertificateRep, thus all fields are
|
||||
// transient.
|
||||
|
||||
// The encoded certificate.
|
||||
protected transient byte[] encoded;
|
||||
|
||||
// TBSCertificate part.
|
||||
protected transient byte[] tbsCertBytes;
|
||||
protected transient int version;
|
||||
protected transient BigInteger serialNo;
|
||||
protected transient OID algId;
|
||||
protected transient byte[] algVal;
|
||||
protected transient X500DistinguishedName issuer;
|
||||
protected transient Date notBefore;
|
||||
protected transient Date notAfter;
|
||||
protected transient X500DistinguishedName subject;
|
||||
protected transient PublicKey subjectKey;
|
||||
protected transient BitString issuerUniqueId;
|
||||
protected transient BitString subjectUniqueId;
|
||||
protected transient Map extensions;
|
||||
|
||||
// Signature.
|
||||
protected transient OID sigAlgId;
|
||||
protected transient byte[] sigAlgVal;
|
||||
protected transient byte[] signature;
|
||||
|
||||
// Constructors.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new X.509 certificate from the encoded data. The input
|
||||
* data are expected to be the ASN.1 DER encoding of the certificate.
|
||||
*
|
||||
* @param encoded The encoded certificate data.
|
||||
* @throws IOException If the certificate cannot be read, possibly
|
||||
* from a formatting error.
|
||||
* @throws CertificateException If the data read is not an X.509
|
||||
* certificate.
|
||||
*/
|
||||
public X509Certificate(InputStream encoded)
|
||||
throws CertificateException, IOException
|
||||
{
|
||||
super();
|
||||
extensions = new HashMap();
|
||||
try
|
||||
{
|
||||
parse(encoded);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
logger.log (Component.X509, "", ioe);
|
||||
throw ioe;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.log (Component.X509, "", e);
|
||||
CertificateException ce = new CertificateException(e.getMessage());
|
||||
ce.initCause (e);
|
||||
throw ce;
|
||||
}
|
||||
}
|
||||
|
||||
protected X509Certificate()
|
||||
{
|
||||
extensions = new HashMap();
|
||||
}
|
||||
|
||||
// X509Certificate methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public void checkValidity()
|
||||
throws CertificateExpiredException, CertificateNotYetValidException
|
||||
{
|
||||
checkValidity(new Date());
|
||||
}
|
||||
|
||||
public void checkValidity(Date date)
|
||||
throws CertificateExpiredException, CertificateNotYetValidException
|
||||
{
|
||||
if (date.compareTo(notBefore) < 0)
|
||||
{
|
||||
throw new CertificateNotYetValidException();
|
||||
}
|
||||
if (date.compareTo(notAfter) > 0)
|
||||
{
|
||||
throw new CertificateExpiredException();
|
||||
}
|
||||
}
|
||||
|
||||
public int getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
public BigInteger getSerialNumber()
|
||||
{
|
||||
return serialNo;
|
||||
}
|
||||
|
||||
public Principal getIssuerDN()
|
||||
{
|
||||
return issuer;
|
||||
}
|
||||
|
||||
public X500Principal getIssuerX500Principal()
|
||||
{
|
||||
return new X500Principal(issuer.getDer());
|
||||
}
|
||||
|
||||
public Principal getSubjectDN()
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
|
||||
public X500Principal getSubjectX500Principal()
|
||||
{
|
||||
return new X500Principal(subject.getDer());
|
||||
}
|
||||
|
||||
public Date getNotBefore()
|
||||
{
|
||||
return (Date) notBefore.clone();
|
||||
}
|
||||
|
||||
public Date getNotAfter()
|
||||
{
|
||||
return (Date) notAfter.clone();
|
||||
}
|
||||
|
||||
public byte[] getTBSCertificate() throws CertificateEncodingException
|
||||
{
|
||||
return (byte[]) tbsCertBytes.clone();
|
||||
}
|
||||
|
||||
public byte[] getSignature()
|
||||
{
|
||||
return (byte[]) signature.clone();
|
||||
}
|
||||
|
||||
public String getSigAlgName()
|
||||
{
|
||||
if (sigAlgId.equals(ID_DSA_WITH_SHA1))
|
||||
{
|
||||
return "SHA1withDSA";
|
||||
}
|
||||
if (sigAlgId.equals(ID_RSA_WITH_MD2))
|
||||
{
|
||||
return "MD2withRSA";
|
||||
}
|
||||
if (sigAlgId.equals(ID_RSA_WITH_MD5))
|
||||
{
|
||||
return "MD5withRSA";
|
||||
}
|
||||
if (sigAlgId.equals(ID_RSA_WITH_SHA1))
|
||||
{
|
||||
return "SHA1withRSA";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public String getSigAlgOID()
|
||||
{
|
||||
return sigAlgId.toString();
|
||||
}
|
||||
|
||||
public byte[] getSigAlgParams()
|
||||
{
|
||||
return (byte[]) sigAlgVal.clone();
|
||||
}
|
||||
|
||||
public boolean[] getIssuerUniqueID()
|
||||
{
|
||||
if (issuerUniqueId != null)
|
||||
{
|
||||
return issuerUniqueId.toBooleanArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean[] getSubjectUniqueID()
|
||||
{
|
||||
if (subjectUniqueId != null)
|
||||
{
|
||||
return subjectUniqueId.toBooleanArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean[] getKeyUsage()
|
||||
{
|
||||
Extension e = getExtension(KeyUsage.ID);
|
||||
if (e != null)
|
||||
{
|
||||
KeyUsage ku = (KeyUsage) e.getValue();
|
||||
boolean[] result = new boolean[9];
|
||||
boolean[] b = ku.getKeyUsage().toBooleanArray();
|
||||
System.arraycopy(b, 0, result, 0, b.length);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List getExtendedKeyUsage() throws CertificateParsingException
|
||||
{
|
||||
Extension e = getExtension(ExtendedKeyUsage.ID);
|
||||
if (e != null)
|
||||
{
|
||||
List a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds();
|
||||
List b = new ArrayList(a.size());
|
||||
for (Iterator it = a.iterator(); it.hasNext(); )
|
||||
{
|
||||
b.add(it.next().toString());
|
||||
}
|
||||
return Collections.unmodifiableList(b);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getBasicConstraints()
|
||||
{
|
||||
Extension e = getExtension(BasicConstraints.ID);
|
||||
if (e != null)
|
||||
{
|
||||
return ((BasicConstraints) e.getValue()).getPathLengthConstraint();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Collection getSubjectAlternativeNames()
|
||||
throws CertificateParsingException
|
||||
{
|
||||
Extension e = getExtension(SubjectAlternativeNames.ID);
|
||||
if (e != null)
|
||||
{
|
||||
return ((SubjectAlternativeNames) e.getValue()).getNames();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection getIssuerAlternativeNames()
|
||||
throws CertificateParsingException
|
||||
{
|
||||
Extension e = getExtension(IssuerAlternativeNames.ID);
|
||||
if (e != null)
|
||||
{
|
||||
return ((IssuerAlternativeNames) e.getValue()).getNames();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// X509Extension methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public boolean hasUnsupportedCriticalExtension()
|
||||
{
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (e.isCritical() && !e.isSupported())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set getCriticalExtensionOIDs()
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (e.isCritical())
|
||||
s.add(e.getOid().toString());
|
||||
}
|
||||
return Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
public Set getNonCriticalExtensionOIDs()
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
Extension e = (Extension) it.next();
|
||||
if (!e.isCritical())
|
||||
s.add(e.getOid().toString());
|
||||
}
|
||||
return Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
public byte[] getExtensionValue(String oid)
|
||||
{
|
||||
Extension e = getExtension(new OID(oid));
|
||||
if (e != null)
|
||||
{
|
||||
return e.getValue().getEncoded();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// GnuPKIExtension method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Extension getExtension(OID oid)
|
||||
{
|
||||
return (Extension) extensions.get(oid);
|
||||
}
|
||||
|
||||
public Collection getExtensions()
|
||||
{
|
||||
return extensions.values();
|
||||
}
|
||||
|
||||
// Certificate methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public byte[] getEncoded() throws CertificateEncodingException
|
||||
{
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public void verify(PublicKey key)
|
||||
throws CertificateException, NoSuchAlgorithmException,
|
||||
InvalidKeyException, NoSuchProviderException, SignatureException
|
||||
{
|
||||
Signature sig = Signature.getInstance(sigAlgId.toString());
|
||||
doVerify(sig, key);
|
||||
}
|
||||
|
||||
public void verify(PublicKey key, String provider)
|
||||
throws CertificateException, NoSuchAlgorithmException,
|
||||
InvalidKeyException, NoSuchProviderException, SignatureException
|
||||
{
|
||||
Signature sig = Signature.getInstance(sigAlgId.toString(), provider);
|
||||
doVerify(sig, key);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringWriter str = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(str);
|
||||
out.println(X509Certificate.class.getName() + " {");
|
||||
out.println(" TBSCertificate {");
|
||||
out.println(" version = " + version + ";");
|
||||
out.println(" serialNo = " + serialNo + ";");
|
||||
out.println(" signature = {");
|
||||
out.println(" algorithm = " + getSigAlgName() + ";");
|
||||
out.print(" parameters =");
|
||||
if (sigAlgVal != null)
|
||||
{
|
||||
out.println();
|
||||
out.print(Util.hexDump(sigAlgVal, " "));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.println(" null;");
|
||||
}
|
||||
out.println(" }");
|
||||
out.println(" issuer = " + issuer.getName() + ";");
|
||||
out.println(" validity = {");
|
||||
out.println(" notBefore = " + notBefore + ";");
|
||||
out.println(" notAfter = " + notAfter + ";");
|
||||
out.println(" }");
|
||||
out.println(" subject = " + subject.getName() + ";");
|
||||
out.println(" subjectPublicKeyInfo = {");
|
||||
out.println(" algorithm = " + subjectKey.getAlgorithm());
|
||||
out.println(" key =");
|
||||
out.print(Util.hexDump(subjectKey.getEncoded(), " "));
|
||||
out.println(" };");
|
||||
out.println(" issuerUniqueId = " + issuerUniqueId + ";");
|
||||
out.println(" subjectUniqueId = " + subjectUniqueId + ";");
|
||||
out.println(" extensions = {");
|
||||
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
out.println(" " + it.next());
|
||||
}
|
||||
out.println(" }");
|
||||
out.println(" }");
|
||||
out.println(" signatureAlgorithm = " + getSigAlgName() + ";");
|
||||
out.println(" signatureValue =");
|
||||
out.print(Util.hexDump(signature, " "));
|
||||
out.println("}");
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey()
|
||||
{
|
||||
return subjectKey;
|
||||
}
|
||||
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (!(other instanceof X509Certificate))
|
||||
return false;
|
||||
try
|
||||
{
|
||||
if (other instanceof X509Certificate)
|
||||
return Arrays.equals(encoded, ((X509Certificate) other).encoded);
|
||||
byte[] enc = ((X509Certificate) other).getEncoded();
|
||||
if (enc == null)
|
||||
return false;
|
||||
return Arrays.equals(encoded, enc);
|
||||
}
|
||||
catch (CertificateEncodingException cee)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Verify this certificate's signature.
|
||||
*/
|
||||
private void doVerify(Signature sig, PublicKey key)
|
||||
throws CertificateException, InvalidKeyException, SignatureException
|
||||
{
|
||||
logger.log (Component.X509, "verifying sig={0} key={1}",
|
||||
new Object[] { sig, key });
|
||||
sig.initVerify(key);
|
||||
sig.update(tbsCertBytes);
|
||||
if (!sig.verify(signature))
|
||||
{
|
||||
throw new CertificateException("signature not validated");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a DER stream into an X.509 certificate.
|
||||
*
|
||||
* @param encoded The encoded bytes.
|
||||
*/
|
||||
private void parse(InputStream encoded) throws Exception
|
||||
{
|
||||
DERReader der = new DERReader(encoded);
|
||||
|
||||
// Certificate ::= SEQUENCE {
|
||||
DERValue cert = der.read();
|
||||
logger.log (Component.X509, "start Certificate len == {0}",
|
||||
new Integer (cert.getLength()));
|
||||
|
||||
this.encoded = cert.getEncoded();
|
||||
if (!cert.isConstructed())
|
||||
{
|
||||
throw new IOException("malformed Certificate");
|
||||
}
|
||||
|
||||
// TBSCertificate ::= SEQUENCE {
|
||||
DERValue tbsCert = der.read();
|
||||
if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE)
|
||||
{
|
||||
throw new IOException("malformed TBSCertificate");
|
||||
}
|
||||
tbsCertBytes = tbsCert.getEncoded();
|
||||
logger.log (Component.X509, "start TBSCertificate len == {0}",
|
||||
new Integer (tbsCert.getLength()));
|
||||
|
||||
// Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }
|
||||
DERValue val = der.read();
|
||||
if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0)
|
||||
{
|
||||
version = ((BigInteger) der.read().getValue()).intValue() + 1;
|
||||
val = der.read();
|
||||
}
|
||||
else
|
||||
{
|
||||
version = 1;
|
||||
}
|
||||
logger.log (Component.X509, "read version == {0}",
|
||||
new Integer (version));
|
||||
|
||||
// SerialNumber ::= INTEGER
|
||||
serialNo = (BigInteger) val.getValue();
|
||||
logger.log (Component.X509, "read serial number == {0}", serialNo);
|
||||
|
||||
// AlgorithmIdentifier ::= SEQUENCE {
|
||||
val = der.read();
|
||||
if (!val.isConstructed())
|
||||
{
|
||||
throw new IOException("malformed AlgorithmIdentifier");
|
||||
}
|
||||
int certAlgLen = val.getLength();
|
||||
logger.log (Component.X509, "start AlgorithmIdentifier len == {0}",
|
||||
new Integer (certAlgLen));
|
||||
val = der.read();
|
||||
|
||||
// algorithm OBJECT IDENTIFIER,
|
||||
algId = (OID) val.getValue();
|
||||
logger.log (Component.X509, "read algorithm ID == {0}", algId);
|
||||
|
||||
// parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||
if (certAlgLen > val.getEncodedLength())
|
||||
{
|
||||
val = der.read();
|
||||
if (val == null)
|
||||
{
|
||||
algVal = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
algVal = val.getEncoded();
|
||||
|
||||
if (val.isConstructed())
|
||||
encoded.skip(val.getLength());
|
||||
}
|
||||
logger.log (Component.X509, "read algorithm parameters == {0}", algVal);
|
||||
}
|
||||
|
||||
// issuer Name,
|
||||
val = der.read();
|
||||
issuer = new X500DistinguishedName(val.getEncoded());
|
||||
der.skip(val.getLength());
|
||||
logger.log (Component.X509, "read issuer == {0}", issuer);
|
||||
|
||||
// Validity ::= SEQUENCE {
|
||||
// notBefore Time,
|
||||
// notAfter Time }
|
||||
if (!der.read().isConstructed())
|
||||
{
|
||||
throw new IOException("malformed Validity");
|
||||
}
|
||||
notBefore = (Date) der.read().getValue();
|
||||
logger.log (Component.X509, "read notBefore == {0}", notBefore);
|
||||
notAfter = (Date) der.read().getValue();
|
||||
logger.log (Component.X509, "read notAfter == {0}", notAfter);
|
||||
|
||||
// subject Name,
|
||||
val = der.read();
|
||||
subject = new X500DistinguishedName(val.getEncoded());
|
||||
der.skip(val.getLength());
|
||||
logger.log (Component.X509, "read subject == {0}", subject);
|
||||
|
||||
// SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
// algorithm AlgorithmIdentifier,
|
||||
// subjectPublicKey BIT STRING }
|
||||
DERValue spki = der.read();
|
||||
if (!spki.isConstructed())
|
||||
{
|
||||
throw new IOException("malformed SubjectPublicKeyInfo");
|
||||
}
|
||||
KeyFactory spkFac = KeyFactory.getInstance("X.509");
|
||||
subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));
|
||||
der.skip(spki.getLength());
|
||||
logger.log (Component.X509, "read subjectPublicKey == {0}", subjectKey);
|
||||
|
||||
if (version > 1)
|
||||
{
|
||||
val = der.read();
|
||||
}
|
||||
if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1)
|
||||
{
|
||||
byte[] b = (byte[]) val.getValue();
|
||||
issuerUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
|
||||
logger.log (Component.X509, "read issuerUniqueId == {0}", issuerUniqueId);
|
||||
val = der.read();
|
||||
}
|
||||
if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2)
|
||||
{
|
||||
byte[] b = (byte[]) val.getValue();
|
||||
subjectUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
|
||||
logger.log (Component.X509, "read subjectUniqueId == {0}", subjectUniqueId);
|
||||
val = der.read();
|
||||
}
|
||||
if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3)
|
||||
{
|
||||
val = der.read();
|
||||
logger.log (Component.X509, "start Extensions len == {0}",
|
||||
new Integer (val.getLength()));
|
||||
int len = 0;
|
||||
while (len < val.getLength())
|
||||
{
|
||||
DERValue ext = der.read();
|
||||
logger.log (Component.X509, "start extension len == {0}",
|
||||
new Integer (ext.getLength()));
|
||||
Extension e = new Extension(ext.getEncoded());
|
||||
extensions.put(e.getOid(), e);
|
||||
der.skip(ext.getLength());
|
||||
len += ext.getEncodedLength();
|
||||
logger.log (Component.X509, "read extension {0} == {1}",
|
||||
new Object[] { e.getOid (), e });
|
||||
logger.log (Component.X509, "count == {0}", new Integer (len));
|
||||
}
|
||||
|
||||
val = der.read ();
|
||||
}
|
||||
|
||||
logger.log (Component.X509, "read value {0}", val);
|
||||
if (!val.isConstructed())
|
||||
{
|
||||
throw new CertificateException ("malformed AlgorithmIdentifier");
|
||||
}
|
||||
int sigAlgLen = val.getLength();
|
||||
logger.log (Component.X509, "start AlgorithmIdentifier len == {0}",
|
||||
new Integer (sigAlgLen));
|
||||
val = der.read();
|
||||
sigAlgId = (OID) val.getValue();
|
||||
logger.log (Component.X509, "read algorithm id == {0}", sigAlgId);
|
||||
if (sigAlgLen > val.getEncodedLength())
|
||||
{
|
||||
val = der.read();
|
||||
if (val.getValue() == null)
|
||||
{
|
||||
if (subjectKey instanceof DSAPublicKey)
|
||||
{
|
||||
AlgorithmParameters params =
|
||||
AlgorithmParameters.getInstance("DSA");
|
||||
DSAParams dsap = ((DSAPublicKey) subjectKey).getParams();
|
||||
DSAParameterSpec spec =
|
||||
new DSAParameterSpec(dsap.getP(), dsap.getQ(), dsap.getG());
|
||||
params.init(spec);
|
||||
sigAlgVal = params.getEncoded();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sigAlgVal = (byte[]) val.getEncoded();
|
||||
}
|
||||
if (val.isConstructed())
|
||||
{
|
||||
encoded.skip(val.getLength());
|
||||
}
|
||||
logger.log (Component.X509, "read parameters == {0}", sigAlgVal);
|
||||
}
|
||||
signature = ((BitString) der.read().getValue()).toByteArray();
|
||||
logger.log (Component.X509, "read signature ==\n{0}", Util.hexDump(signature, ">>>> "));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/* AuthorityKeyIdentifier.java -- Authority key identifier extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.x509.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class AuthorityKeyIdentifier extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.35");
|
||||
|
||||
private final byte[] keyIdentifier;
|
||||
private final GeneralNames authorityCertIssuer;
|
||||
private final BigInteger authorityCertSerialNumber;
|
||||
|
||||
// Contstructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public AuthorityKeyIdentifier(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERReader der = new DERReader(encoded);
|
||||
|
||||
// AuthorityKeyIdentifier ::= SEQUENCE {
|
||||
DERValue val = der.read();
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed AuthorityKeyIdentifier");
|
||||
if (val.getLength() > 0)
|
||||
val = der.read();
|
||||
|
||||
// keyIdentifier [0] KeyIdentifier OPTIONAL,
|
||||
// KeyIdentifier ::= OCTET STRING
|
||||
if (val.getTagClass() == DER.APPLICATION && val.getTag() == 0)
|
||||
{
|
||||
keyIdentifier = (byte[]) val.getValue();
|
||||
val = der.read();
|
||||
}
|
||||
else
|
||||
keyIdentifier = null;
|
||||
|
||||
// authorityCertIssuer [1] GeneralNames OPTIONAL,
|
||||
if (val.getTagClass() == DER.APPLICATION && val.getTag() == 1)
|
||||
{
|
||||
byte[] b = val.getEncoded();
|
||||
b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
|
||||
authorityCertIssuer = new GeneralNames(b);
|
||||
der.skip(val.getLength());
|
||||
val = der.read();
|
||||
}
|
||||
else
|
||||
authorityCertIssuer = null;
|
||||
|
||||
// authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
|
||||
if (val.getTagClass() == DER.APPLICATION && val.getTag() == 2)
|
||||
{
|
||||
authorityCertSerialNumber = new BigInteger((byte[]) val.getValue());
|
||||
}
|
||||
else
|
||||
authorityCertSerialNumber = null;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public byte[] getKeyIdentifier()
|
||||
{
|
||||
return keyIdentifier != null ? (byte[]) keyIdentifier.clone() : null;
|
||||
}
|
||||
|
||||
public GeneralNames getAuthorityCertIssuer()
|
||||
{
|
||||
return authorityCertIssuer;
|
||||
}
|
||||
|
||||
public BigInteger getAuthorityCertSerialNumber()
|
||||
{
|
||||
return authorityCertSerialNumber;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return AuthorityKeyIdentifier.class.getName() + " [ keyId=" +
|
||||
(keyIdentifier != null ? Util.toHexString (keyIdentifier, ':') : "nil") +
|
||||
" authorityCertIssuer=" + authorityCertIssuer +
|
||||
" authorityCertSerialNumbe=" + authorityCertSerialNumber + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/* BasicConstraints.java -- the basic constraints extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BasicConstraints extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.19");
|
||||
|
||||
private final boolean ca;
|
||||
private final int pathLenConstraint;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public BasicConstraints(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERReader der = new DERReader(encoded);
|
||||
DERValue bc = der.read();
|
||||
if (!bc.isConstructed())
|
||||
throw new IOException("malformed BasicConstraints");
|
||||
DERValue val = bc;
|
||||
if (bc.getLength() > 0)
|
||||
val = der.read();
|
||||
if (val.getTag() == DER.BOOLEAN)
|
||||
{
|
||||
ca = ((Boolean) val.getValue()).booleanValue();
|
||||
if (val.getEncodedLength() < bc.getLength())
|
||||
val = der.read();
|
||||
}
|
||||
else
|
||||
ca = false;
|
||||
if (val.getTag() == DER.INTEGER)
|
||||
{
|
||||
pathLenConstraint = ((BigInteger) val.getValue()).intValue();
|
||||
}
|
||||
else
|
||||
pathLenConstraint = -1;
|
||||
}
|
||||
|
||||
public BasicConstraints (final boolean ca, final int pathLenConstraint)
|
||||
{
|
||||
this.ca = ca;
|
||||
this.pathLenConstraint = pathLenConstraint;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public boolean isCA()
|
||||
{
|
||||
return ca;
|
||||
}
|
||||
|
||||
public int getPathLengthConstraint()
|
||||
{
|
||||
return pathLenConstraint;
|
||||
}
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encoded == null)
|
||||
{
|
||||
List bc = new ArrayList (2);
|
||||
bc.add (new DERValue (DER.BOOLEAN, new Boolean (ca)));
|
||||
if (pathLenConstraint >= 0)
|
||||
bc.add (new DERValue (DER.INTEGER,
|
||||
BigInteger.valueOf ((long) pathLenConstraint)));
|
||||
encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, bc).getEncoded();
|
||||
}
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return BasicConstraints.class.getName() + " [ isCA=" + ca +
|
||||
" pathLen=" + pathLenConstraint + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/* CRLNumber.java -- CRL number extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class CRLNumber extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.20");
|
||||
|
||||
private final BigInteger number;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public CRLNumber(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERValue val = DERReader.read(encoded);
|
||||
if (val.getTag() != DER.INTEGER)
|
||||
throw new IOException("malformed CRLNumber");
|
||||
number = (BigInteger) val.getValue();
|
||||
}
|
||||
|
||||
public CRLNumber (final BigInteger number)
|
||||
{
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
// Instance method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public BigInteger getNumber()
|
||||
{
|
||||
return number;
|
||||
}
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encoded == null)
|
||||
{
|
||||
encoded = new DERValue (DER.INTEGER, number).getEncoded();
|
||||
}
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return CRLNumber.class.getName() + " [ " + number + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/* CertificatePolicies.java -- certificate policy extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.PolicyQualifierInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CertificatePolicies extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.32");
|
||||
|
||||
private final List policies;
|
||||
private final Map policyQualifierInfos;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public CertificatePolicies(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERReader der = new DERReader(encoded);
|
||||
DERValue pol = der.read();
|
||||
if (!pol.isConstructed())
|
||||
throw new IOException("malformed CertificatePolicies");
|
||||
|
||||
int len = 0;
|
||||
LinkedList policyList = new LinkedList();
|
||||
HashMap qualifierMap = new HashMap();
|
||||
while (len < pol.getLength())
|
||||
{
|
||||
DERValue policyInfo = der.read();
|
||||
if (!policyInfo.isConstructed())
|
||||
throw new IOException("malformed PolicyInformation");
|
||||
DERValue val = der.read();
|
||||
if (val.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new IOException("malformed CertPolicyId");
|
||||
OID policyId = (OID) val.getValue();
|
||||
policyList.add(policyId);
|
||||
if (val.getEncodedLength() < policyInfo.getLength())
|
||||
{
|
||||
DERValue qual = der.read();
|
||||
int len2 = 0;
|
||||
LinkedList quals = new LinkedList();
|
||||
while (len2 < qual.getLength())
|
||||
{
|
||||
val = der.read();
|
||||
quals.add(new PolicyQualifierInfo(val.getEncoded()));
|
||||
der.skip(val.getLength());
|
||||
len2 += val.getEncodedLength();
|
||||
}
|
||||
qualifierMap.put(policyId, quals);
|
||||
}
|
||||
len += policyInfo.getEncodedLength();
|
||||
}
|
||||
|
||||
policies = Collections.unmodifiableList(policyList);
|
||||
policyQualifierInfos = Collections.unmodifiableMap(qualifierMap);
|
||||
}
|
||||
|
||||
public CertificatePolicies (final List policies,
|
||||
final Map policyQualifierInfos)
|
||||
{
|
||||
for (Iterator it = policies.iterator(); it.hasNext(); )
|
||||
if (!(it.next() instanceof OID))
|
||||
throw new IllegalArgumentException ("policies must be OIDs");
|
||||
for (Iterator it = policyQualifierInfos.entrySet().iterator(); it.hasNext();)
|
||||
{
|
||||
Map.Entry e = (Map.Entry) it.next();
|
||||
if (!(e.getKey() instanceof OID) || !policies.contains (e.getKey()))
|
||||
throw new IllegalArgumentException
|
||||
("policyQualifierInfos keys must be OIDs");
|
||||
if (!(e.getValue() instanceof List))
|
||||
throw new IllegalArgumentException
|
||||
("policyQualifierInfos values must be Lists of PolicyQualifierInfos");
|
||||
for (Iterator it2 = ((List) e.getValue()).iterator(); it.hasNext(); )
|
||||
if (!(it2.next() instanceof PolicyQualifierInfo))
|
||||
throw new IllegalArgumentException
|
||||
("policyQualifierInfos values must be Lists of PolicyQualifierInfos");
|
||||
}
|
||||
this.policies = Collections.unmodifiableList (new ArrayList (policies));
|
||||
this.policyQualifierInfos = Collections.unmodifiableMap
|
||||
(new HashMap (policyQualifierInfos));
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public List getPolicies()
|
||||
{
|
||||
return policies;
|
||||
}
|
||||
|
||||
public List getPolicyQualifierInfos(OID oid)
|
||||
{
|
||||
return (List) policyQualifierInfos.get(oid);
|
||||
}
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encoded == null)
|
||||
{
|
||||
List pol = new ArrayList (policies.size());
|
||||
for (Iterator it = policies.iterator(); it.hasNext(); )
|
||||
{
|
||||
OID policy = (OID) it.next();
|
||||
List qualifiers = getPolicyQualifierInfos (policy);
|
||||
List l = new ArrayList (qualifiers == null ? 1 : 2);
|
||||
l.add (new DERValue (DER.OBJECT_IDENTIFIER, policy));
|
||||
if (qualifiers != null)
|
||||
{
|
||||
List ll = new ArrayList (qualifiers.size());
|
||||
for (Iterator it2 = qualifiers.iterator(); it.hasNext(); )
|
||||
{
|
||||
PolicyQualifierInfo info = (PolicyQualifierInfo) it2.next();
|
||||
try
|
||||
{
|
||||
ll.add (DERReader.read (info.getEncoded()));
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
l.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ll));
|
||||
}
|
||||
pol.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, l));
|
||||
}
|
||||
encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded();
|
||||
}
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return CertificatePolicies.class.getName() + " [ policies=" + policies +
|
||||
" policyQualifierInfos=" + policyQualifierInfos + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/* ExtendedKeyUsage.java -- the extended key usage extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExtendedKeyUsage extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.37");
|
||||
|
||||
private final List purposeIds;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public ExtendedKeyUsage(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERReader der = new DERReader(encoded);
|
||||
DERValue usageList = der.read();
|
||||
if (!usageList.isConstructed())
|
||||
throw new IOException("malformed ExtKeyUsageSyntax");
|
||||
int len = 0;
|
||||
purposeIds = new LinkedList();
|
||||
while (len < usageList.getLength())
|
||||
{
|
||||
DERValue val = der.read();
|
||||
if (val.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new IOException("malformed KeyPurposeId");
|
||||
purposeIds.add(val.getValue());
|
||||
len += val.getEncodedLength();
|
||||
}
|
||||
}
|
||||
|
||||
// Instance method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public List getPurposeIds()
|
||||
{
|
||||
return Collections.unmodifiableList(purposeIds);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return ExtendedKeyUsage.class.getName() + " [ " + purposeIds + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/* Extension.java -- an X.509 certificate or CRL extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.x509.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Extension
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static void debug(String msg)
|
||||
{
|
||||
System.err.print(">> Extension: ");
|
||||
System.err.println(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension's object identifier.
|
||||
*/
|
||||
protected final OID oid;
|
||||
|
||||
/**
|
||||
* The criticality flag.
|
||||
*/
|
||||
protected final boolean critical;
|
||||
|
||||
/**
|
||||
* Whether or not this extension is locally supported.
|
||||
*/
|
||||
protected boolean isSupported;
|
||||
|
||||
/**
|
||||
* The extension value.
|
||||
*/
|
||||
protected final Value value;
|
||||
|
||||
/**
|
||||
* The DER encoded form.
|
||||
*/
|
||||
protected byte[] encoded;
|
||||
|
||||
// Constructors.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Extension(byte[] encoded) throws IOException
|
||||
{
|
||||
this.encoded = (byte[]) encoded.clone();
|
||||
DERReader der = new DERReader(encoded);
|
||||
|
||||
// Extension ::= SEQUENCE {
|
||||
DERValue val = der.read();
|
||||
if (DEBUG) debug("read val tag == " + val.getTag() + " len == " + val.getLength());
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed Extension");
|
||||
|
||||
// extnID OBJECT IDENTIFIER,
|
||||
val = der.read();
|
||||
if (val.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new IOException("expecting OBJECT IDENTIFIER");
|
||||
oid = (OID) val.getValue();
|
||||
if (DEBUG) debug("read oid == " + oid);
|
||||
|
||||
// critical BOOLEAN DEFAULT FALSE,
|
||||
val = der.read();
|
||||
if (val.getTag() == DER.BOOLEAN)
|
||||
{
|
||||
critical = ((Boolean) val.getValue()).booleanValue();
|
||||
val = der.read();
|
||||
}
|
||||
else
|
||||
critical = false;
|
||||
if (DEBUG) debug("is critical == " + critical);
|
||||
|
||||
// extnValue OCTET STRING }
|
||||
if (val.getTag() != DER.OCTET_STRING)
|
||||
throw new IOException("expecting OCTET STRING");
|
||||
byte[] encval = (byte[]) val.getValue();
|
||||
isSupported = true;
|
||||
if (oid.equals(AuthorityKeyIdentifier.ID))
|
||||
{
|
||||
value = new AuthorityKeyIdentifier(encval);
|
||||
}
|
||||
else if (oid.equals(SubjectKeyIdentifier.ID))
|
||||
{
|
||||
value = new SubjectKeyIdentifier(encval);
|
||||
}
|
||||
else if (oid.equals(KeyUsage.ID))
|
||||
{
|
||||
value = new KeyUsage(encval);
|
||||
}
|
||||
else if (oid.equals(PrivateKeyUsagePeriod.ID))
|
||||
{
|
||||
value = new PrivateKeyUsagePeriod(encval);
|
||||
}
|
||||
else if (oid.equals(CertificatePolicies.ID))
|
||||
{
|
||||
value = new CertificatePolicies(encval);
|
||||
}
|
||||
else if (oid.equals (PolicyConstraint.ID))
|
||||
{
|
||||
value = new PolicyConstraint (encval);
|
||||
}
|
||||
else if (oid.equals(PolicyMappings.ID))
|
||||
{
|
||||
value = new PolicyMappings(encval);
|
||||
}
|
||||
else if (oid.equals(SubjectAlternativeNames.ID))
|
||||
{
|
||||
value = new SubjectAlternativeNames(encval);
|
||||
}
|
||||
else if (oid.equals(IssuerAlternativeNames.ID))
|
||||
{
|
||||
value = new IssuerAlternativeNames(encval);
|
||||
}
|
||||
else if (oid.equals(BasicConstraints.ID))
|
||||
{
|
||||
value = new BasicConstraints(encval);
|
||||
}
|
||||
else if (oid.equals(ExtendedKeyUsage.ID))
|
||||
{
|
||||
value = new ExtendedKeyUsage(encval);
|
||||
}
|
||||
else if (oid.equals(CRLNumber.ID))
|
||||
{
|
||||
value = new CRLNumber(encval);
|
||||
}
|
||||
else if (oid.equals(ReasonCode.ID))
|
||||
{
|
||||
value = new ReasonCode(encval);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = new Value(encval);
|
||||
isSupported = false;
|
||||
}
|
||||
if (DEBUG) debug("read value == " + value);
|
||||
}
|
||||
|
||||
public Extension (final OID oid, final Value value, final boolean critical)
|
||||
{
|
||||
this.oid = oid;
|
||||
this.value = value;
|
||||
this.critical = critical;
|
||||
isSupported = true;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public OID getOid()
|
||||
{
|
||||
return oid;
|
||||
}
|
||||
|
||||
public boolean isCritical()
|
||||
{
|
||||
return critical;
|
||||
}
|
||||
|
||||
public boolean isSupported()
|
||||
{
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public Value getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
if (encoded == null)
|
||||
encode();
|
||||
return (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return Extension.class.getName() + " [ id=" + oid + " critical=" +
|
||||
critical + " value=" + value + " ]";
|
||||
}
|
||||
|
||||
public DERValue getDerValue()
|
||||
{
|
||||
List ext = new ArrayList (3);
|
||||
ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid));
|
||||
ext.add (new DERValue (DER.BOOLEAN, new Boolean (critical)));
|
||||
ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded()));
|
||||
return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext);
|
||||
}
|
||||
|
||||
// Own methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private void encode()
|
||||
{
|
||||
encoded = getDerValue().getEncoded();
|
||||
}
|
||||
|
||||
// Inner class.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static class Value
|
||||
{
|
||||
|
||||
// Fields.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
protected byte[] encoded;
|
||||
|
||||
// Constructor.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
public Value(byte[] encoded)
|
||||
{
|
||||
this.encoded = (byte[]) encoded.clone();
|
||||
}
|
||||
|
||||
protected Value() { }
|
||||
|
||||
// Instance methods.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
public byte[] getEncoded()
|
||||
{
|
||||
return (byte[]) encoded;
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (!(o instanceof Value))
|
||||
return false;
|
||||
return Arrays.equals(encoded, ((Value) o).encoded);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return Util.toHexString(encoded, ':');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/* GeneralNames.java -- the GeneralNames object
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.x509.X500DistinguishedName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class GeneralNames
|
||||
{
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final int OTHER_NAME = 0;
|
||||
public static final int RFC822_NAME = 1;
|
||||
public static final int DNS_NAME = 2;
|
||||
public static final int X400_ADDRESS = 3;
|
||||
public static final int DIRECTORY_NAME = 4;
|
||||
public static final int EDI_PARTY_NAME = 5;
|
||||
public static final int URI = 6;
|
||||
public static final int IP_ADDRESS = 7;
|
||||
public static final int REGISTERED_ID = 8;
|
||||
|
||||
private List names;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public GeneralNames(final byte[] encoded) throws IOException
|
||||
{
|
||||
names = new LinkedList();
|
||||
DERReader der = new DERReader(encoded);
|
||||
DERValue nameList = der.read();
|
||||
if (!nameList.isConstructed())
|
||||
throw new IOException("malformed GeneralNames");
|
||||
int len = 0;
|
||||
while (len < nameList.getLength())
|
||||
{
|
||||
DERValue name = der.read();
|
||||
List namePair = new ArrayList(2);
|
||||
if (name.getTagClass() != DER.APPLICATION)
|
||||
throw new IOException("malformed GeneralName");
|
||||
namePair.add(new Integer(name.getTag()));
|
||||
DERValue val = null;
|
||||
switch (name.getTag())
|
||||
{
|
||||
case RFC822_NAME:
|
||||
case DNS_NAME:
|
||||
case X400_ADDRESS:
|
||||
case URI:
|
||||
namePair.add(new String((byte[]) name.getValue()));
|
||||
break;
|
||||
|
||||
case OTHER_NAME:
|
||||
case EDI_PARTY_NAME:
|
||||
namePair.add(name.getValue());
|
||||
break;
|
||||
|
||||
case DIRECTORY_NAME:
|
||||
byte[] b = name.getEncoded();
|
||||
b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
|
||||
namePair.add(new X500DistinguishedName(b).toString());
|
||||
break;
|
||||
|
||||
case IP_ADDRESS:
|
||||
namePair.add(InetAddress.getByAddress((byte[]) name.getValue())
|
||||
.getHostAddress());
|
||||
break;
|
||||
|
||||
case REGISTERED_ID:
|
||||
byte[] bb = name.getEncoded();
|
||||
bb[0] = (byte) DER.OBJECT_IDENTIFIER;
|
||||
namePair.add(new OID(bb).toString());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IOException("unknown tag " + name.getTag());
|
||||
}
|
||||
names.add(namePair);
|
||||
len += name.getEncodedLength();
|
||||
}
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public List getNames()
|
||||
{
|
||||
List l = new ArrayList(names.size());
|
||||
for (Iterator it = names.iterator(); it.hasNext(); )
|
||||
{
|
||||
List ll = (List) it.next();
|
||||
List pair = new ArrayList(2);
|
||||
pair.add(ll.get(0));
|
||||
if (ll.get(1) instanceof byte[])
|
||||
pair.add(((byte[]) ll.get(1)).clone());
|
||||
else
|
||||
pair.add(ll.get(1));
|
||||
l.add(Collections.unmodifiableList(pair));
|
||||
}
|
||||
return Collections.unmodifiableList(l);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return GeneralNames.class.getName() + " [ " + names + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* IssuerAlternatuveNames.java -- issuer alternative names extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class IssuerAlternativeNames extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.18");
|
||||
|
||||
private final GeneralNames names;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public IssuerAlternativeNames(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
names = new GeneralNames(encoded);
|
||||
}
|
||||
|
||||
// Instance method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public List getNames()
|
||||
{
|
||||
return names.getNames();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return IssuerAlternativeNames.class.getName() + " [ " + names + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/* KeyUsage.java -- the key usage extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.BitString;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class KeyUsage extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.15");
|
||||
public static final int DIGITAL_SIGNATURE = 0;
|
||||
public static final int NON_REPUDIATION = 1;
|
||||
public static final int KEY_ENCIPHERMENT = 2;
|
||||
public static final int DATA_ENCIPHERMENT = 3;
|
||||
public static final int KEY_AGREEMENT = 4;
|
||||
public static final int KEY_CERT_SIGN = 5;
|
||||
public static final int CRL_SIGN = 6;
|
||||
public static final int ENCIPHER_ONLY = 7;
|
||||
public static final int DECIPHER_ONLY = 8;
|
||||
|
||||
private final BitString keyUsage;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public KeyUsage(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERValue val = DERReader.read(encoded);
|
||||
if (val.getTag() != DER.BIT_STRING)
|
||||
throw new IOException("malformed KeyUsage");
|
||||
keyUsage = (BitString) val.getValue();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public BitString getKeyUsage()
|
||||
{
|
||||
return keyUsage;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return KeyUsage.class.getName() + " [ " + keyUsage + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/* PolicyConstraint.java -- policyConstraint extension
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class PolicyConstraint extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID ("2.5.29.36");
|
||||
|
||||
private final int requireExplicitPolicy;
|
||||
private final int inhibitPolicyMapping;
|
||||
|
||||
// Constructors.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public PolicyConstraint (final byte[] encoded) throws IOException
|
||||
{
|
||||
super (encoded);
|
||||
int rpc = -1, ipm = -1;
|
||||
DERReader der = new DERReader(encoded);
|
||||
DERValue pc = der.read();
|
||||
if (!pc.isConstructed())
|
||||
throw new IOException("malformed PolicyConstraints");
|
||||
DERValue val;
|
||||
int len = pc.getLength();
|
||||
while (len > 0)
|
||||
{
|
||||
val = der.read();
|
||||
if (val.getTag() == 0)
|
||||
rpc = new BigInteger ((byte[]) val.getValue()).intValue();
|
||||
else if (val.getTag() == 1)
|
||||
ipm = new BigInteger ((byte[]) val.getValue()).intValue();
|
||||
else
|
||||
throw new IOException ("invalid policy constraint");
|
||||
len -= val.getEncodedLength();
|
||||
}
|
||||
|
||||
requireExplicitPolicy = rpc;
|
||||
inhibitPolicyMapping = ipm;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public int getRequireExplicitPolicy()
|
||||
{
|
||||
return requireExplicitPolicy;
|
||||
}
|
||||
|
||||
public int getInhibitPolicyMapping()
|
||||
{
|
||||
return inhibitPolicyMapping;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return PolicyConstraint.class.getName() + " [ requireExplicitPolicy=" +
|
||||
requireExplicitPolicy + " inhibitPolicyMapping=" + inhibitPolicyMapping
|
||||
+ " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/* PolicyMappings.java -- policy mappings extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PolicyMappings extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.33");
|
||||
|
||||
private final Map mappings;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public PolicyMappings(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERReader der = new DERReader(encoded);
|
||||
DERValue maps = der.read();
|
||||
if (!maps.isConstructed())
|
||||
throw new IOException("malformed PolicyMappings");
|
||||
int len = 0;
|
||||
HashMap _mappings = new HashMap();
|
||||
while (len < maps.getLength())
|
||||
{
|
||||
DERValue map = der.read();
|
||||
if (!map.isConstructed())
|
||||
throw new IOException("malformed PolicyMapping");
|
||||
DERValue val = der.read();
|
||||
if (val.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new IOException("malformed PolicyMapping");
|
||||
OID issuerPolicy = (OID) val.getValue();
|
||||
val = der.read();
|
||||
if (val.getTag() != DER.OBJECT_IDENTIFIER)
|
||||
throw new IOException("malformed PolicyMapping");
|
||||
OID subjectPolicy = (OID) val.getValue();
|
||||
_mappings.put(issuerPolicy, subjectPolicy);
|
||||
len += map.getEncodedLength();
|
||||
}
|
||||
mappings = Collections.unmodifiableMap(_mappings);
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public OID getSubjectDomainPolicy(OID issuerDomainPolicy)
|
||||
{
|
||||
return (OID) mappings.get(issuerDomainPolicy);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return PolicyMappings.class.getName() + " [ " + mappings + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/* PrivateKeyUsagePeriod.java -- private key usage period extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
public class PrivateKeyUsagePeriod extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.16");
|
||||
|
||||
private final Date notBefore;
|
||||
private final Date notAfter;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public PrivateKeyUsagePeriod(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERReader der = new DERReader(encoded);
|
||||
DERValue val = der.read();
|
||||
if (!val.isConstructed())
|
||||
throw new IOException("malformed PrivateKeyUsagePeriod");
|
||||
if (val.getLength() > 0)
|
||||
val = der.read();
|
||||
if (val.getTagClass() == DER.APPLICATION || val.getTag() == 0)
|
||||
{
|
||||
notBefore = (Date) val.getValueAs (DER.GENERALIZED_TIME);
|
||||
val = der.read();
|
||||
}
|
||||
else
|
||||
notBefore = null;
|
||||
if (val.getTagClass() == DER.APPLICATION || val.getTag() == 1)
|
||||
{
|
||||
notAfter = (Date) val.getValueAs (DER.GENERALIZED_TIME);
|
||||
}
|
||||
else
|
||||
notAfter = null;
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Date getNotBefore()
|
||||
{
|
||||
return notBefore != null ? (Date) notBefore.clone() : null;
|
||||
}
|
||||
|
||||
public Date getNotAfter()
|
||||
{
|
||||
return notAfter != null ? (Date) notAfter.clone() : null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return PrivateKeyUsagePeriod.class.getName() + " [ notBefore=" + notBefore
|
||||
+ " notAfter=" + notAfter + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/* ReasonCode.java -- a reason code for a certificate revocation.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class ReasonCode extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.21");
|
||||
|
||||
public final int reason;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public ReasonCode(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERValue val = DERReader.read(encoded);
|
||||
if (val.getTag() != DER.ENUMERATED)
|
||||
throw new IOException("malformed CRLReason");
|
||||
reason = ((BigInteger) val.getValue()).intValue();
|
||||
if (reason < 0 || reason == 7 || reason > 10)
|
||||
throw new IOException("illegal reason: " + reason);
|
||||
}
|
||||
|
||||
// Instance method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public int getReasonCode()
|
||||
{
|
||||
return reason;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return ReasonCode.class.getName() + " [ " + reason + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* SubjectAlternatuveNames.java -- subject alternative names extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class SubjectAlternativeNames extends Extension.Value
|
||||
{
|
||||
|
||||
// Constants and fields.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.17");
|
||||
|
||||
private final GeneralNames names;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public SubjectAlternativeNames(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
names = new GeneralNames(encoded);
|
||||
}
|
||||
|
||||
// Instance method.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public List getNames()
|
||||
{
|
||||
return names.getNames();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return SubjectAlternativeNames.class.getName() + " [ " + names + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/* SubjectKeyIdentifier.java -- subject key identifier extension.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.security.x509.ext;
|
||||
|
||||
import gnu.java.security.OID;
|
||||
import gnu.java.security.der.DER;
|
||||
import gnu.java.security.der.DERReader;
|
||||
import gnu.java.security.der.DERValue;
|
||||
import gnu.java.security.x509.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SubjectKeyIdentifier extends Extension.Value
|
||||
{
|
||||
|
||||
// Constant.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final OID ID = new OID("2.5.29.14");
|
||||
|
||||
private final byte[] keyIdentifier;
|
||||
|
||||
// Constructor.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public SubjectKeyIdentifier(final byte[] encoded) throws IOException
|
||||
{
|
||||
super(encoded);
|
||||
DERValue val = DERReader.read(encoded);
|
||||
if (val.getTag() != DER.OCTET_STRING)
|
||||
throw new IOException("malformed SubjectKeyIdentifier");
|
||||
keyIdentifier = (byte[]) val.getValue();
|
||||
}
|
||||
|
||||
// Instance methods.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public byte[] getKeyIdentifier()
|
||||
{
|
||||
return (byte[]) keyIdentifier.clone();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return SubjectKeyIdentifier.class.getName() + " [ " +
|
||||
Util.toHexString (keyIdentifier, ':') + " ]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.x509.ext package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.x509.ext</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.security.x509 package.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.security.x509</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user