summaryrefslogtreecommitdiff
path: root/gnu/java/security
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/java/security')
-rw-r--r--gnu/java/security/Engine.java212
-rw-r--r--gnu/java/security/OID.java24
-rw-r--r--gnu/java/security/PolicyFile.java19
-rw-r--r--gnu/java/security/Registry.java12
-rw-r--r--gnu/java/security/key/dss/DSSKey.java45
-rw-r--r--gnu/java/security/key/dss/DSSKeyPairX509Codec.java92
-rw-r--r--gnu/java/security/key/dss/DSSPrivateKey.java6
-rw-r--r--gnu/java/security/key/dss/DSSPublicKey.java6
-rw-r--r--gnu/java/security/key/rsa/GnuRSAKey.java6
-rw-r--r--gnu/java/security/key/rsa/GnuRSAPrivateKey.java6
-rw-r--r--gnu/java/security/key/rsa/GnuRSAPublicKey.java6
-rw-r--r--gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java11
-rw-r--r--gnu/java/security/util/ByteArray.java109
-rw-r--r--gnu/java/security/util/IntegerUtil.java109
14 files changed, 499 insertions, 164 deletions
diff --git a/gnu/java/security/Engine.java b/gnu/java/security/Engine.java
index f3be45075..44318af8e 100644
--- a/gnu/java/security/Engine.java
+++ b/gnu/java/security/Engine.java
@@ -42,6 +42,7 @@ import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+import java.util.Enumeration;
/**
* Generic implementation of the getInstance methods in the various
@@ -78,145 +79,170 @@ public final class Engine
/** 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.
+ * Return 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.
+ * @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 is null.
*/
public static Object getInstance(String service, String algorithm,
Provider provider)
- throws InvocationTargetException, NoSuchAlgorithmException
+ 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.
+ * Return 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.
+ * @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 is
+ * <code>null</code> or if either <code>service</code>, or
+ * <code>algorithm</code> is an empty string.
*/
public static Object getInstance(String service, String algorithm,
Provider provider, Object[] initArgs)
- throws InvocationTargetException, NoSuchAlgorithmException
+ throws InvocationTargetException, NoSuchAlgorithmException
{
- if (service != null)
- service = service.trim();
+ if (service == null)
+ throw new IllegalArgumentException("service MUST NOT be null");
+ service = service.trim();
+ if (service.length() == 0)
+ throw new IllegalArgumentException("service MUST NOT be empty");
+ if (algorithm == null)
+ throw new IllegalArgumentException("algorithm MUST NOT be null");
+ algorithm = algorithm.trim();
+ if (algorithm.length() == 0)
+ throw new IllegalArgumentException("algorithm MUST NOT be empty");
+ if (provider == null)
+ throw new IllegalArgumentException("provider MUST NOT be null");
+ if (initArgs == null)
+ throw new IllegalArgumentException("Constructor's parameters MUST NOT be null");
- if (algorithm != null)
- algorithm = algorithm.trim();
-
- if (service == null || service.length() == 0
- || algorithm == null || algorithm.length() == 0
- || provider == null || initArgs == null)
- throw new IllegalArgumentException();
-
- // If there is no property "service.algorithm"
- if (provider.getProperty(service + "." + algorithm) == null)
+ Enumeration enumer = provider.propertyNames();
+ String key;
+ String alias;
+ int count = 0;
+ boolean algorithmFound = false;
+ StringBuilder sb = new StringBuilder();
+ while (enumer.hasMoreElements())
{
- // 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)
+ key = (String) enumer.nextElement();
+ if (key.equalsIgnoreCase(service + "." + algorithm))
+ {
+ // remove the service portion from the key
+ algorithm = key.substring(service.length() + 1);
+ algorithmFound = true;
+ break;
+ }
+ else if (key.equalsIgnoreCase(ALG_ALIAS + service + "." + algorithm))
{
- if (algorithm.equals(alias)) // Refers to itself!
- break;
- algorithm = alias;
- if (count++ > MAX_ALIASES)
- throw new NoSuchAlgorithmException("too many aliases");
+ alias = (String) provider.getProperty(key);
+ if (! algorithm.equalsIgnoreCase(alias)) // does not refer to itself
+ {
+ algorithm = alias;
+ if (count++ > MAX_ALIASES)
+ {
+ sb.append("Algorithm [").append(algorithm)
+ .append("] of type [").append(service)
+ .append("] from provider [").append(provider)
+ .append("] has too many aliases");
+ throw new NoSuchAlgorithmException(sb.toString());
+ }
+ // need to reset enumeration to now look for the alias
+ enumer = provider.propertyNames();
+ }
}
- if (provider.getProperty(service + "." + algorithm) == null)
- throw new NoSuchAlgorithmException(algorithm);
}
- // Find and instantiate the implementation.
+ if (! algorithmFound)
+ {
+ sb.append("Algorithm [").append(algorithm).append("] of type [")
+ .append(service).append("] from provider [")
+ .append(provider).append("] is not found");
+ throw new NoSuchAlgorithmException(sb.toString());
+ }
+
+ // Find and instantiate the implementation
Class clazz = null;
ClassLoader loader = provider.getClass().getClassLoader();
Constructor constructor = null;
- String error = algorithm;
- Throwable cause;
-
+ String className = provider.getProperty(service + "." + algorithm);
+ sb.append("Class [").append(className).append("] for algorithm [")
+ .append(algorithm).append("] of type [").append(service)
+ .append("] from provider [").append(provider).append("] ");
+ Throwable cause = null;
try
{
if (loader != null)
- clazz = loader.loadClass(provider.getProperty(service+"."+algorithm));
+ clazz = loader.loadClass(className);
else
- clazz = Class.forName(provider.getProperty(service+"."+algorithm));
+ clazz = Class.forName(className);
constructor = getCompatibleConstructor(clazz, initArgs);
return constructor.newInstance(initArgs);
}
- catch (ClassNotFoundException cnfe)
+ catch (ClassNotFoundException x)
{
- error = "class not found: " + algorithm;
- cause = cnfe;
+ sb.append("cannot not be found");
+ cause = x;
}
- catch (IllegalAccessException iae)
+ catch (IllegalAccessException x)
{
- error = "illegal access: " + iae.getMessage();
- cause = iae;
+ sb.append("cannot be accessed");
+ cause = x;
}
- catch (InstantiationException ie)
+ catch (InstantiationException x)
{
- error = "instantiation exception: " + ie.getMessage();
- cause = ie;
+ sb.append("cannot be instantiated");
+ cause = x;
}
- catch (ExceptionInInitializerError eiie)
+ catch (ExceptionInInitializerError x)
{
- error = "exception in initializer: " + eiie.getMessage();
- cause = eiie;
+ sb.append("cannot be initialized");
+ cause = x;
}
- catch (SecurityException se)
+ catch (SecurityException x)
{
- error = "security exception: " + se.getMessage();
- cause = se;
+ sb.append("caused a security violation");
+ cause = x;
}
- catch (NoSuchMethodException nsme)
+ catch (NoSuchMethodException x)
{
- error = "no appropriate constructor found";
- cause = nsme;
+ sb.append("does not have/expose an appropriate constructor");
+ cause = x;
}
- NoSuchAlgorithmException nsae = new NoSuchAlgorithmException(error);
- nsae.initCause(cause);
-
- throw nsae;
+ NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
+ x.initCause(cause);
+ throw x;
}
- // Own methods.
- // ------------------------------------------------------------------------
-
/**
* Find a constructor in the given class that can take the specified
* argument list, allowing any of which to be null.
diff --git a/gnu/java/security/OID.java b/gnu/java/security/OID.java
index 822ca3427..f61cf0fc3 100644
--- a/gnu/java/security/OID.java
+++ b/gnu/java/security/OID.java
@@ -71,6 +71,9 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
// Fields.
// ------------------------------------------------------------------------
+ /* Serial version id for serialization. */
+ static final long serialVersionUID = 5722492029044597779L;
+
/**
* The numeric ID structure.
*/
@@ -229,13 +232,6 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
}
}
- /**
- * Our private constructor.
- */
- private OID()
- {
- }
-
// Instance methods.
// ------------------------------------------------------------------------
@@ -325,10 +321,16 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
*/
public Object clone()
{
- OID oid = new OID();
- oid.components = this.components;
- oid.strRep = this.strRep;
- return oid;
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException cnse)
+ {
+ InternalError ie = new InternalError();
+ ie.initCause(cnse);
+ throw ie;
+ }
}
/* Nice idea, but possibly too expensive for whatever benefit it
diff --git a/gnu/java/security/PolicyFile.java b/gnu/java/security/PolicyFile.java
index 8404eeb98..8da3a7d72 100644
--- a/gnu/java/security/PolicyFile.java
+++ b/gnu/java/security/PolicyFile.java
@@ -37,9 +37,9 @@ exception statement from your version. */
package gnu.java.security;
-import gnu.classpath.SystemProperties;
import gnu.classpath.debug.Component;
import gnu.classpath.debug.SystemLogger;
+import gnu.java.security.action.GetPropertyAction;
import java.io.File;
import java.io.IOException;
@@ -149,15 +149,16 @@ public final class PolicyFile extends Policy
// -------------------------------------------------------------------------
protected static final Logger logger = SystemLogger.SYSTEM;
-
+ // Added to cut redundant AccessController.doPrivileged calls
+ private static GetPropertyAction prop = new GetPropertyAction("file.seperator");
+ private static final String fs = (String) AccessController.doPrivileged(prop);
+
private static final String DEFAULT_POLICY =
- SystemProperties.getProperty("java.home")
- + SystemProperties.getProperty("file.separator") + "lib"
- + SystemProperties.getProperty("file.separator") + "security"
- + SystemProperties.getProperty("file.separator") + "java.policy";
+ (String) AccessController.doPrivileged(prop.setParameters("java.home"))
+ + fs + "lib" + fs + "security" + fs + "java.policy";
private static final String DEFAULT_USER_POLICY =
- SystemProperties.getProperty ("user.home") +
- SystemProperties.getProperty ("file.separator") + ".java.policy";
+ (String) AccessController.doPrivileged(prop.setParameters("user.home")) +
+ fs + ".java.policy";
private final Map cs2pc;
@@ -216,7 +217,7 @@ public final class PolicyFile extends Policy
String allow = Security.getProperty ("policy.allowSystemProperty");
if (allow == null || Boolean.getBoolean (allow))
{
- String s = SystemProperties.getProperty ("java.security.policy");
+ String s = System.getProperty ("java.security.policy");
logger.log (Component.POLICY, "java.security.policy={0}", s);
if (s != null)
{
diff --git a/gnu/java/security/Registry.java b/gnu/java/security/Registry.java
index b3df24c9e..053d71778 100644
--- a/gnu/java/security/Registry.java
+++ b/gnu/java/security/Registry.java
@@ -89,6 +89,18 @@ public interface Registry
String CAST_128_CIPHER = "cast-128";
+ // Key Wrapping Algorithm names and synonyms ...............................
+
+ String KWA_PREFIX = "kw-";
+ String AES_KWA = KWA_PREFIX + AES_CIPHER;
+ String AES128_KWA = AES_KWA + "128";
+ String AES192_KWA = AES_KWA + "192";
+ String AES256_KWA = AES_KWA + "256";
+ String RIJNDAEL_KWA = KWA_PREFIX + RIJNDAEL_CIPHER;
+
+ String TRIPLEDES_KWA = KWA_PREFIX + TRIPLEDES_CIPHER;
+ String DESEDE_KWA = KWA_PREFIX + DESEDE_CIPHER;
+
// Message digest algorithms and synonyms...................................
String WHIRLPOOL_HASH = "whirlpool";
diff --git a/gnu/java/security/key/dss/DSSKey.java b/gnu/java/security/key/dss/DSSKey.java
index 29205605b..657de8dd0 100644
--- a/gnu/java/security/key/dss/DSSKey.java
+++ b/gnu/java/security/key/dss/DSSKey.java
@@ -38,11 +38,12 @@ exception statement from your version. */
package gnu.java.security.key.dss;
-import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
+import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.util.FormatUtil;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.Key;
import java.security.interfaces.DSAKey;
import java.security.interfaces.DSAParams;
@@ -59,6 +60,10 @@ import java.security.spec.DSAParameterSpec;
* of the byte sequences and the implementation details are given in each of the
* relevant <code>getEncoded()</code> methods of each of the private and
* public keys.
+ * <p>
+ * <b>IMPORTANT</b>: Under certain circumstances (e.g. in an X.509 certificate
+ * with inherited AlgorithmIdentifier's parameters of a SubjectPublicKeyInfo
+ * element) these three MPIs may be <code>null</code>.
*
* @see DSSPrivateKey#getEncoded
* @see DSSPublicKey#getEncoded
@@ -144,6 +149,11 @@ public abstract class DSSKey
* Returns <code>true</code> if the designated object is an instance of
* {@link DSAKey} and has the same DSS (Digital Signature Standard) parameter
* values as this one.
+ * <p>
+ * Always returns <code>false</code> if the MPIs of this key are
+ * <i>inherited</i>. This may be the case when the key is re-constructed from
+ * an X.509 certificate with absent or NULL AlgorithmIdentifier's parameters
+ * field.
*
* @param obj the other non-null DSS key to compare to.
* @return <code>true</code> if the designated object is of the same type
@@ -151,6 +161,9 @@ public abstract class DSSKey
*/
public boolean equals(Object obj)
{
+ if (hasInheritedParameters())
+ return false;
+
if (obj == null)
return false;
@@ -167,16 +180,32 @@ public abstract class DSSKey
{
if (str == null)
{
- String ls = SystemProperties.getProperty("line.separator");
- str = new StringBuilder(ls)
- .append("defaultFormat=").append(defaultFormat).append(",").append(ls)
- .append("p=0x").append(p.toString(16)).append(",").append(ls)
- .append("q=0x").append(q.toString(16)).append(",").append(ls)
- .append("g=0x").append(g.toString(16))
- .toString();
+ String ls = (String) AccessController.doPrivileged(new GetPropertyAction("line.separator"));
+ StringBuilder sb = new StringBuilder(ls)
+ .append("defaultFormat=").append(defaultFormat).append(",")
+ .append(ls);
+ if (hasInheritedParameters())
+ sb.append("p=inherited,").append(ls)
+ .append("q=inherited,").append(ls)
+ .append("g=inherited");
+ else
+ sb.append("p=0x").append(p.toString(16)).append(",").append(ls)
+ .append("q=0x").append(q.toString(16)).append(",").append(ls)
+ .append("g=0x").append(g.toString(16));
+ str = sb.toString();
}
return str;
}
public abstract byte[] getEncoded(int format);
+
+ /**
+ * @return <code>true</code> if <code>p</code>, <code>q</code> and
+ * <code>g</code> are all <code>null</code>. Returns
+ * <code>false</code> otherwise.
+ */
+ public boolean hasInheritedParameters()
+ {
+ return p == null && q == null && g == null;
+ }
}
diff --git a/gnu/java/security/key/dss/DSSKeyPairX509Codec.java b/gnu/java/security/key/dss/DSSKeyPairX509Codec.java
index 5ddd6e0d6..a5e8e9d47 100644
--- a/gnu/java/security/key/dss/DSSKeyPairX509Codec.java
+++ b/gnu/java/security/key/dss/DSSKeyPairX509Codec.java
@@ -94,9 +94,15 @@ public class DSSKeyPairX509Codec
* g INTEGER
* }
* </pre>
- *
- * <p>The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the
- * DER-encoded form of the DSA public key as an INTEGER.</p>
+ * <p>
+ * Note that RFC-3280 (page 79) implies that some certificates MAY have an
+ * absent, or NULL, parameters field in their AlgorithmIdentifier element,
+ * implying that those parameters MUST be <i>inherited</i> from another
+ * certificate. This implementation, encodes a <i>NULL</i> element as the DER
+ * value of the parameters field when such is the case.
+ * <p>
+ * The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the
+ * DER-encoded form of the DSA public key as an INTEGER.
*
* <pre>
* DSAPublicKey ::= INTEGER -- public key, Y
@@ -118,20 +124,25 @@ public class DSSKeyPairX509Codec
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, DSA_ALG_OID);
DSSPublicKey dssKey = (DSSPublicKey) key;
- BigInteger p = dssKey.getParams().getP();
- BigInteger q = dssKey.getParams().getQ();
- BigInteger g = dssKey.getParams().getG();
- BigInteger y = dssKey.getY();
-
- DERValue derP = new DERValue(DER.INTEGER, p);
- DERValue derQ = new DERValue(DER.INTEGER, q);
- DERValue derG = new DERValue(DER.INTEGER, g);
-
- ArrayList params = new ArrayList(3);
- params.add(derP);
- params.add(derQ);
- params.add(derG);
- DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
+ DERValue derParams;
+ if (dssKey.hasInheritedParameters())
+ derParams = new DERValue(DER.NULL, null);
+ else
+ {
+ BigInteger p = dssKey.getParams().getP();
+ BigInteger q = dssKey.getParams().getQ();
+ BigInteger g = dssKey.getParams().getG();
+
+ DERValue derP = new DERValue(DER.INTEGER, p);
+ DERValue derQ = new DERValue(DER.INTEGER, q);
+ DERValue derG = new DERValue(DER.INTEGER, g);
+
+ ArrayList params = new ArrayList(3);
+ params.add(derP);
+ params.add(derQ);
+ params.add(derG);
+ derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
+ }
ArrayList algorithmID = new ArrayList(2);
algorithmID.add(derOID);
@@ -139,6 +150,7 @@ public class DSSKeyPairX509Codec
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
+ BigInteger y = dssKey.getY();
DERValue derDSAPublicKey = new DERValue(DER.INTEGER, y);
byte[] yBytes = derDSAPublicKey.getEncoded();
DERValue derSPK = new DERValue(DER.BIT_STRING, new BitString(yBytes));
@@ -185,7 +197,10 @@ public class DSSKeyPairX509Codec
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
- BigInteger p, g, q, y;
+ BigInteger p = null;
+ BigInteger g = null;
+ BigInteger q = null;
+ BigInteger y;
DERReader der = new DERReader(input);
try
{
@@ -203,20 +218,35 @@ public class DSSKeyPairX509Codec
if (! algOID.equals(DSA_ALG_OID))
throw new InvalidParameterException("Unexpected OID: " + algOID);
- DERValue derParams = der.read();
- DerUtil.checkIsConstructed(derParams, "Wrong DSS Parameters field");
-
DERValue val = der.read();
- DerUtil.checkIsBigInteger(val, "Wrong P field");
- p = (BigInteger) val.getValue();
- val = der.read();
- DerUtil.checkIsBigInteger(val, "Wrong Q field");
- q = (BigInteger) val.getValue();
- val = der.read();
- DerUtil.checkIsBigInteger(val, "Wrong G field");
- g = (BigInteger) val.getValue();
-
- val = der.read();
+ // RFC-3280, page 79 states: "If the subjectPublicKeyInfo field of the
+ // certificate contains an algorithm field with null parameters or
+ // parameters are omitted, compare the certificate subjectPublicKey
+ // algorithm to the working_public_key_algorithm. If the certificate
+ // subjectPublicKey algorithm and the working_public_key_algorithm are
+ // different, set the working_public_key_parameters to null."
+ // in other words, the parameters field of an AlgorithmIdentifier
+ // element MAY NOT be present at all, or if present MAY be NULL!
+ // the Mauve test ValidDSAParameterInheritenceTest5, in
+ // gnu.testlet.java.security.cert.pkix.pkits, is/was failing because
+ // of this.
+ if (val.getTag() == DER.NULL)
+ val = der.read();
+ else if (val.isConstructed())
+ {
+ val = der.read();
+ DerUtil.checkIsBigInteger(val, "Wrong P field");
+ p = (BigInteger) val.getValue();
+ val = der.read();
+ DerUtil.checkIsBigInteger(val, "Wrong Q field");
+ q = (BigInteger) val.getValue();
+ val = der.read();
+ DerUtil.checkIsBigInteger(val, "Wrong G field");
+ g = (BigInteger) val.getValue();
+
+ val = der.read();
+ }
+
if (! (val.getValue() instanceof BitString))
throw new InvalidParameterException("Wrong SubjectPublicKey field");
diff --git a/gnu/java/security/key/dss/DSSPrivateKey.java b/gnu/java/security/key/dss/DSSPrivateKey.java
index 6c64987bc..6ed8de846 100644
--- a/gnu/java/security/key/dss/DSSPrivateKey.java
+++ b/gnu/java/security/key/dss/DSSPrivateKey.java
@@ -39,11 +39,12 @@ exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Configuration;
-import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
+import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.PrivateKey;
import java.security.interfaces.DSAPrivateKey;
@@ -188,7 +189,8 @@ public class DSSPrivateKey
{
if (str == null)
{
- String ls = SystemProperties.getProperty("line.separator");
+ String ls = (String) AccessController.doPrivileged
+ (new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append("x=0x").append(Configuration.DEBUG ? x.toString(16)
diff --git a/gnu/java/security/key/dss/DSSPublicKey.java b/gnu/java/security/key/dss/DSSPublicKey.java
index fa3ad04d0..9e1c4cf0a 100644
--- a/gnu/java/security/key/dss/DSSPublicKey.java
+++ b/gnu/java/security/key/dss/DSSPublicKey.java
@@ -38,11 +38,12 @@ exception statement from your version. */
package gnu.java.security.key.dss;
-import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
+import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
@@ -187,7 +188,8 @@ public class DSSPublicKey
{
if (str == null)
{
- String ls = SystemProperties.getProperty("line.separator");
+ String ls = (String) AccessController.doPrivileged
+ (new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append("y=0x").append(y.toString(16)).append(ls)
diff --git a/gnu/java/security/key/rsa/GnuRSAKey.java b/gnu/java/security/key/rsa/GnuRSAKey.java
index 6ff740184..4bdce4011 100644
--- a/gnu/java/security/key/rsa/GnuRSAKey.java
+++ b/gnu/java/security/key/rsa/GnuRSAKey.java
@@ -38,11 +38,12 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
-import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
+import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.util.FormatUtil;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.Key;
import java.security.interfaces.RSAKey;
@@ -160,7 +161,8 @@ public abstract class GnuRSAKey
{
if (str == null)
{
- String ls = SystemProperties.getProperty("line.separator");
+ String ls = (String) AccessController.doPrivileged
+ (new GetPropertyAction("line.separator"));
str = new StringBuilder(ls)
.append("defaultFormat=").append(defaultFormat).append(",").append(ls)
.append("n=0x").append(n.toString(16)).append(",").append(ls)
diff --git a/gnu/java/security/key/rsa/GnuRSAPrivateKey.java b/gnu/java/security/key/rsa/GnuRSAPrivateKey.java
index ef466d020..00a1b822a 100644
--- a/gnu/java/security/key/rsa/GnuRSAPrivateKey.java
+++ b/gnu/java/security/key/rsa/GnuRSAPrivateKey.java
@@ -39,11 +39,12 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Configuration;
-import gnu.classpath.SystemProperties;
+import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
@@ -286,7 +287,8 @@ public class GnuRSAPrivateKey
{
if (str == null)
{
- String ls = SystemProperties.getProperty("line.separator");
+ String ls = (String) AccessController.doPrivileged
+ (new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append("d=0x").append(Configuration.DEBUG ? d.toString(16)
diff --git a/gnu/java/security/key/rsa/GnuRSAPublicKey.java b/gnu/java/security/key/rsa/GnuRSAPublicKey.java
index 1bbca4fa2..fe28d0ba3 100644
--- a/gnu/java/security/key/rsa/GnuRSAPublicKey.java
+++ b/gnu/java/security/key/rsa/GnuRSAPublicKey.java
@@ -38,11 +38,12 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
-import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
+import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
@@ -175,7 +176,8 @@ public class GnuRSAPublicKey
{
if (str == null)
{
- String ls = SystemProperties.getProperty("line.separator");
+ String ls = (String) AccessController.doPrivileged
+ (new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append(")")
diff --git a/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java b/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java
index 7fa9d0102..7a51d0a0d 100644
--- a/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java
+++ b/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java
@@ -98,6 +98,9 @@ public class RSAKeyPairPKCS8Codec
* }
* </pre>
* <p>
+ * As indicated in RFC-2459: "The parameters field shall have ASN.1 type NULL
+ * for this algorithm identifier.".
+ * <p>
* The <i>privateKey</i> field, which is an OCTET STRING, contains the
* DER-encoded form of the RSA private key defined as:
* <pre>
@@ -140,8 +143,9 @@ public class RSAKeyPairPKCS8Codec
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, RSA_ALG_OID);
- ArrayList algorithmID = new ArrayList(1);
+ ArrayList algorithmID = new ArrayList(2);
algorithmID.add(derOID);
+ algorithmID.add(new DERValue(DER.NULL, null));
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
@@ -238,9 +242,12 @@ public class RSAKeyPairPKCS8Codec
if (! algOID.equals(RSA_ALG_OID))
throw new InvalidParameterException("Unexpected OID: " + algOID);
+ // rfc-2459 states that this field is OPTIONAL but NULL if/when present
DERValue val = der.read();
- byte[] pkBytes = (byte[]) val.getValue();
+ if (val.getTag() == DER.NULL)
+ val = der.read();
+ byte[] pkBytes = (byte[]) val.getValue();
der = new DERReader(pkBytes);
DERValue derRSAPrivateKey = der.read();
DerUtil.checkIsConstructed(derRSAPrivateKey, "Wrong RSAPrivateKey field");
diff --git a/gnu/java/security/util/ByteArray.java b/gnu/java/security/util/ByteArray.java
new file mode 100644
index 000000000..0d04d9127
--- /dev/null
+++ b/gnu/java/security/util/ByteArray.java
@@ -0,0 +1,109 @@
+/* ByteArray.java -- wrapper around a byte array, with nice toString output.
+ 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. */
+
+
+package gnu.java.security.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public final class ByteArray
+{
+ private final byte[] value;
+
+ public ByteArray (final byte[] value)
+ {
+ this.value = value;
+ }
+
+ public byte[] getValue ()
+ {
+ return value;
+ }
+
+ public String toString ()
+ {
+ StringWriter str = new StringWriter ();
+ PrintWriter out = new PrintWriter (str);
+ int i = 0;
+ int len = value.length;
+ while (i < len)
+ {
+ out.print (formatInt (i, 16, 8));
+ out.print (" ");
+ int l = Math.min (16, len - i);
+ String s = toHexString (value, i, l, ' ');
+ out.print (s);
+ for (int j = 56 - (56 - s.length ()); j < 56; j++)
+ out.print (" ");
+ for (int j = 0; j < l; j++)
+ {
+ byte b = value[i+j];
+ if ((b & 0xFF) < 0x20 || (b & 0xFF) > 0x7E)
+ out.print (".");
+ else
+ out.print ((char) (b & 0xFF));
+ }
+ out.println ();
+ i += 16;
+ }
+ return str.toString ();
+ }
+
+ 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 (Character.forDigit (buf[i+off] >>> 4 & 0x0F, 16));
+ str.append (Character.forDigit (buf[i+off] & 0x0F, 16));
+ if (i < len - 1)
+ str.append(sep);
+ }
+ return str.toString();
+ }
+
+ public static String formatInt (int value, int radix, int len)
+ {
+ String s = Integer.toString (value, radix);
+ StringBuffer buf = new StringBuffer ();
+ for (int j = 0; j < len - s.length(); j++)
+ buf.append ("0");
+ buf.append (s);
+ return buf.toString();
+ }
+}
diff --git a/gnu/java/security/util/IntegerUtil.java b/gnu/java/security/util/IntegerUtil.java
new file mode 100644
index 000000000..f07130808
--- /dev/null
+++ b/gnu/java/security/util/IntegerUtil.java
@@ -0,0 +1,109 @@
+/* IntegerUtil.java -- JDK 5 Integer methods with 1.4 API
+ Copyright (C) 2006 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.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Utility class which offers Integer related methods found in RI's version 5
+ * but written with RI's 1.4 API.
+ */
+public abstract class IntegerUtil
+{
+ /** Maximum size of our cache of constructed Integers. */
+ private static final int CACHE_SIZE = 100;
+ /** LRU (Least Recently Used) cache, of the last accessed 100 Integers. */
+ private static final Map cache = new LinkedHashMap(CACHE_SIZE + 1, 0.75F, true)
+ {
+ public boolean removeEldestEntry(Map.Entry entry)
+ {
+ return size() > CACHE_SIZE;
+ }
+ };
+
+ /** Trivial private constructor to enforce Singleton usage. */
+ private IntegerUtil()
+ {
+ super();
+ }
+
+ /**
+ * Similar to {@link Integer#valueOf(String)} except it caches the result in
+ * a local LRU cache of 100 elements, organized by access order.
+ * <p>
+ * This method MUST be used in the gnu.java.security and gnu.javax.crypto
+ * packages to ensure they would work with a version 1.4 only of the Java
+ * class library API.
+ *
+ * @param aString a string representation of an integer.
+ * @return the {@link Integer} object representing the designated string.
+ */
+ public static final Integer valueOf(String aString)
+ {
+ Integer result;
+ synchronized (cache)
+ {
+ result = (Integer) cache.get(aString);
+ if (result == null)
+ {
+ result = Integer.valueOf(aString);
+ cache.put(aString, result);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Simulates the <code>valueOf(int)</code> method found in {@link Integer} of
+ * the RI's version 1.5 using a local LRU cache of 100 elements, organized by
+ * access order.
+ * <p>
+ * This method MUST be used in the gnu.java.security and gnu.javax.crypto
+ * packages to ensure they would work with a version 1.4 only of the Java
+ * class library API.
+ *
+ * @param anInt a decimal integer.
+ * @return the {@link Integer} object representing the designated primitive.
+ */
+ public static final Integer valueOf(int anInt)
+ {
+ return valueOf(Integer.toString(anInt, 10));
+ }
+}