diff options
author | Raif S. Naffah <raif@swiftdsl.com.au> | 2006-08-05 03:23:27 +0000 |
---|---|---|
committer | Raif S. Naffah <raif@swiftdsl.com.au> | 2006-08-05 03:23:27 +0000 |
commit | 48fb1b9a43f9cfc7905173e6cd92d3af1ed5e281 (patch) | |
tree | 655f354f6835ba591847875aed5a2c3852a73cc5 | |
parent | 7691a1e86427f362930cf4f48357b073249d7fba (diff) | |
download | classpath-48fb1b9a43f9cfc7905173e6cd92d3af1ed5e281.tar.gz |
2006-08-05 Raif S. Naffah <raif@swiftdsl.com.au>
* gnu/java/security/key/dss/DSSKey.java: Updated documentation.
(hasInheritedParameters): New method.
(equals): Updated documentation.
Take into consideration the outcome of hasInheritedParameters invocation.
(toString): Call hasInheritedParameters and adjust the result accordingly.
* gnu/java/security/key/dss/DSSKeyPairX509Codec.java (encodePublicKey):
Updated documentation.
Handle case of public keys with null p, q, and g MPIs.
(decodePublicKey): Handle case of absent or NULL p, q and g MPIs.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | gnu/java/security/key/dss/DSSKey.java | 43 | ||||
-rw-r--r-- | gnu/java/security/key/dss/DSSKeyPairX509Codec.java | 92 |
3 files changed, 108 insertions, 39 deletions
@@ -1,5 +1,17 @@ 2006-08-05 Raif S. Naffah <raif@swiftdsl.com.au> + * gnu/java/security/key/dss/DSSKey.java: Updated documentation. + (hasInheritedParameters): New method. + (equals): Updated documentation. + Take into consideration the outcome of hasInheritedParameters invocation. + (toString): Call hasInheritedParameters and adjust the result accordingly. + * gnu/java/security/key/dss/DSSKeyPairX509Codec.java (encodePublicKey): + Updated documentation. + Handle case of public keys with null p, q, and g MPIs. + (decodePublicKey): Handle case of absent or NULL p, q and g MPIs. + +2006-08-05 Raif S. Naffah <raif@swiftdsl.com.au> + * configure.ac: Better handling of default-preferences-peer option. 2006-08-04 Andreas Tobler <a.tobler@schweiz.ch> diff --git a/gnu/java/security/key/dss/DSSKey.java b/gnu/java/security/key/dss/DSSKey.java index c0cd10f30..657de8dd0 100644 --- a/gnu/java/security/key/dss/DSSKey.java +++ b/gnu/java/security/key/dss/DSSKey.java @@ -60,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 @@ -145,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 @@ -152,6 +161,9 @@ public abstract class DSSKey */ public boolean equals(Object obj) { + if (hasInheritedParameters()) + return false; + if (obj == null) return false; @@ -168,17 +180,32 @@ public abstract class DSSKey { if (str == null) { - String ls = (String) AccessController.doPrivileged - (new GetPropertyAction("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"); |