summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2006-08-07 22:35:50 +0000
committerMark Wielaard <mark@klomp.org>2006-08-07 22:35:50 +0000
commit50f69a943fc08be8b1e70973e5b7de2b93821183 (patch)
tree56c1fa0d11d72677546f407f274c59626ebc6946
parent4366b4849b3ed205e3688304721473a8df8e4bb7 (diff)
downloadclasspath-50f69a943fc08be8b1e70973e5b7de2b93821183.tar.gz
2006-08-07 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--ChangeLog12
-rw-r--r--gnu/java/security/key/dss/DSSKey.java43
-rw-r--r--gnu/java/security/key/dss/DSSKeyPairX509Codec.java92
3 files changed, 108 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 84caeb3db..54728531e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-08-07 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-07 Tom Tromey <tromey@redhat.com>
PR libgcj/23682:
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");