diff options
Diffstat (limited to 'pki/base/util/src/netscape/security/pkcs')
11 files changed, 2045 insertions, 1941 deletions
diff --git a/pki/base/util/src/netscape/security/pkcs/ContentInfo.java b/pki/base/util/src/netscape/security/pkcs/ContentInfo.java index 2427ec46b..f09f4b621 100644 --- a/pki/base/util/src/netscape/security/pkcs/ContentInfo.java +++ b/pki/base/util/src/netscape/security/pkcs/ContentInfo.java @@ -26,127 +26,130 @@ import netscape.security.util.ObjectIdentifier; /** * A ContentInfo type, as defined in PKCS#7. - * + * * @version 1.12 - * @author Benjamin Renaud + * @author Benjamin Renaud */ public class ContentInfo { // pkcs7 pre-defined content types - private static int[] pkcs7 = { 1, 2, 840, 113549, 1, 7 }; - private static int[] data = { 1, 2, 840, 113549, 1, 7, 1 }; - private static int[] sdata = { 1, 2, 840, 113549, 1, 7, 2 }; - private static int[] edata = { 1, 2, 840, 113549, 1, 7, 3 }; - private static int[] sedata = { 1, 2, 840, 113549, 1, 7, 4 }; - private static int[] ddata = { 1, 2, 840, 113549, 1, 7, 5 }; - private static int[] crdata = { 1, 2, 840, 113549, 1, 7, 6 }; - - public static final ObjectIdentifier PKCS7_OID = new ObjectIdentifier(pkcs7); - - public static final ObjectIdentifier DATA_OID = new ObjectIdentifier(data); - - public static final ObjectIdentifier SIGNED_DATA_OID = new ObjectIdentifier( - sdata); - - public static final ObjectIdentifier ENVELOPED_DATA_OID = new ObjectIdentifier( - edata); - - public static final ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID = new ObjectIdentifier( - sedata); - - public static final ObjectIdentifier DIGESTED_DATA_OID = new ObjectIdentifier( - ddata); - - public static final ObjectIdentifier ENCRYPTED_DATA_OID = new ObjectIdentifier( - crdata); + private static int[] pkcs7 = {1, 2, 840, 113549, 1, 7}; + private static int[] data = {1, 2, 840, 113549, 1, 7, 1}; + private static int[] sdata = {1, 2, 840, 113549, 1, 7, 2}; + private static int[] edata = {1, 2, 840, 113549, 1, 7, 3}; + private static int[] sedata = {1, 2, 840, 113549, 1, 7, 4}; + private static int[] ddata = {1, 2, 840, 113549, 1, 7, 5}; + private static int[] crdata = {1, 2, 840, 113549, 1, 7, 6}; + + public static final ObjectIdentifier PKCS7_OID = + new ObjectIdentifier(pkcs7); + + public static final ObjectIdentifier DATA_OID = + new ObjectIdentifier(data); + + public static final ObjectIdentifier SIGNED_DATA_OID = + new ObjectIdentifier(sdata); + + public static final ObjectIdentifier ENVELOPED_DATA_OID = + new ObjectIdentifier(edata); + + public static final ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID = + new ObjectIdentifier(sedata); + + public static final ObjectIdentifier DIGESTED_DATA_OID = + new ObjectIdentifier(ddata); + + public static final ObjectIdentifier ENCRYPTED_DATA_OID = + new ObjectIdentifier(crdata); ObjectIdentifier contentType; DerValue content; // OPTIONAL public ContentInfo(ObjectIdentifier contentType, DerValue content) { - this.contentType = contentType; - this.content = content; + this.contentType = contentType; + this.content = content; } /** * Make a contentInfo of type data. */ public ContentInfo(byte[] bytes) { - DerValue octetString = new DerValue(DerValue.tag_OctetString, bytes); - this.contentType = DATA_OID; - this.content = octetString; + DerValue octetString = new DerValue(DerValue.tag_OctetString, bytes); + this.contentType = DATA_OID; + this.content = octetString; } - public ContentInfo(DerInputStream derin) throws IOException, - ParsingException { + public ContentInfo(DerInputStream derin) + throws IOException, ParsingException { DerInputStream disType; - DerInputStream disTaggedContent; - DerValue type; - DerValue taggedContent; - DerValue[] typeAndContent; - DerValue[] contents; - - typeAndContent = derin.getSequence(2); - - // Parse the content type - type = typeAndContent[0]; - disType = new DerInputStream(type.toByteArray()); - contentType = disType.getOID(); - - // Parse the content (OPTIONAL field). - // Skip the [0] EXPLICIT tag by pretending that the content is the one - // and only element in an implicitly tagged set - if (typeAndContent.length > 1) { // content is OPTIONAL - taggedContent = typeAndContent[1]; - disTaggedContent = new DerInputStream(taggedContent.toByteArray()); - contents = disTaggedContent.getSet(1, true); - content = contents[0]; - } + DerInputStream disTaggedContent; + DerValue type; + DerValue taggedContent; + DerValue[] typeAndContent; + DerValue[] contents; + + typeAndContent = derin.getSequence(2); + + // Parse the content type + type = typeAndContent[0]; + disType = new DerInputStream(type.toByteArray()); + contentType = disType.getOID(); + + // Parse the content (OPTIONAL field). + // Skip the [0] EXPLICIT tag by pretending that the content is the one + // and only element in an implicitly tagged set + if (typeAndContent.length > 1) { // content is OPTIONAL + taggedContent = typeAndContent[1]; + disTaggedContent = new DerInputStream(taggedContent.toByteArray()); + contents = disTaggedContent.getSet(1, true); + content = contents[0]; + } } public DerValue getContent() { - return content; + return content; } public byte[] getData() throws IOException { - if (contentType.equals(DATA_OID)) { - return content.getOctetString(); - } - throw new IOException("content type is not DATA: " + contentType); + if (contentType.equals(DATA_OID)) { + return content.getOctetString(); + } + throw new IOException("content type is not DATA: " + contentType); } public void encode(DerOutputStream out) throws IOException { - DerOutputStream contentDerCode; - DerOutputStream seq; - DerValue taggedContent; + DerOutputStream contentDerCode; + DerOutputStream seq; + DerValue taggedContent; - contentDerCode = new DerOutputStream(); - content.encode(contentDerCode); - // Add the [0] EXPLICIT tag in front of the content encoding - taggedContent = new DerValue((byte) 0xA0, contentDerCode.toByteArray()); + contentDerCode = new DerOutputStream(); + content.encode(contentDerCode); + // Add the [0] EXPLICIT tag in front of the content encoding + taggedContent = new DerValue((byte)0xA0, + contentDerCode.toByteArray()); - seq = new DerOutputStream(); - seq.putOID(contentType); - seq.putDerValue(taggedContent); + seq = new DerOutputStream(); + seq.putOID(contentType); + seq.putDerValue(taggedContent); - out.write(DerValue.tag_Sequence, seq); + out.write(DerValue.tag_Sequence, seq); } /** - * Returns a byte array representation of the data held in the content - * field. + * Returns a byte array representation of the data held in + * the content field. */ public byte[] getContentBytes() throws IOException { - DerInputStream dis = new DerInputStream(content.toByteArray()); - return dis.getOctetString(); + DerInputStream dis = new DerInputStream(content.toByteArray()); + return dis.getOctetString(); } - + public String toString() { - String out = ""; - - out += "Content Info Sequence\n\tContent type: " + contentType + "\n"; - out += "\tContent: " + content; - return out; + String out = ""; + + out += "Content Info Sequence\n\tContent type: " + contentType + "\n"; + out += "\tContent: " + content; + return out; } } diff --git a/pki/base/util/src/netscape/security/pkcs/EncodingException.java b/pki/base/util/src/netscape/security/pkcs/EncodingException.java index cb495e990..6ccd1d403 100644 --- a/pki/base/util/src/netscape/security/pkcs/EncodingException.java +++ b/pki/base/util/src/netscape/security/pkcs/EncodingException.java @@ -24,10 +24,10 @@ public class EncodingException extends Exception { private static final long serialVersionUID = -6126764125859196917L; public EncodingException() { - super(); + super(); } public EncodingException(String s) { - super(s); + super(s); } } diff --git a/pki/base/util/src/netscape/security/pkcs/PKCS10.java b/pki/base/util/src/netscape/security/pkcs/PKCS10.java index dcd2e0880..dc28c7e9c 100644 --- a/pki/base/util/src/netscape/security/pkcs/PKCS10.java +++ b/pki/base/util/src/netscape/security/pkcs/PKCS10.java @@ -37,23 +37,22 @@ import netscape.security.x509.X509Key; /** * PKCS #10 certificate requests are created and sent to Certificate - * Authorities, which then create X.509 certificates and return them to the - * entity which created the certificate request. These cert requests basically - * consist of the subject's X.500 name and public key, signed using the - * corresponding private key. - * + * Authorities, which then create X.509 certificates and return them to + * the entity which created the certificate request. These cert requests + * basically consist of the subject's X.500 name and public key, signed + * using the corresponding private key. + * * The ASN.1 syntax for a Certification Request is: - * * <pre> * CertificationRequest ::= SEQUENCE { * certificationRequestInfo CertificationRequestInfo, * signatureAlgorithm SignatureAlgorithmIdentifier, * signature Signature * } - * + * * SignatureAlgorithmIdentifier ::= AlgorithmIdentifier * Signature ::= BIT STRING - * + * * CertificationRequestInfo ::= SEQUENCE { * version Version, * subject Name, @@ -62,281 +61,298 @@ import netscape.security.x509.X509Key; * } * Attributes ::= SET OF Attribute * </pre> - * + * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.28 */ -public class PKCS10 { +public class PKCS10 +{ /** - * Constructs an unsigned PKCS #10 certificate request. Before this request - * may be used, it must be encoded and signed. Then it must be retrieved in - * some conventional format (e.g. string). + * Constructs an unsigned PKCS #10 certificate request. Before this + * request may be used, it must be encoded and signed. Then it + * must be retrieved in some conventional format (e.g. string). * - * @param publicKey the public key that should be placed into the - * certificate generated by the CA. + * @param publicKey the public key that should be placed + * into the certificate generated by the CA. */ - public PKCS10(X509Key publicKey) { - subjectPublicKeyInfo = publicKey; - attributeSet = new PKCS10Attributes(); + public PKCS10 (X509Key publicKey) + { + subjectPublicKeyInfo = publicKey; + attributeSet = new PKCS10Attributes(); } + /** - * Constructs an unsigned PKCS #10 certificate request. Before this request - * may be used, it must be encoded and signed. Then it must be retrieved in - * some conventional format (e.g. string). + * Constructs an unsigned PKCS #10 certificate request. Before this + * request may be used, it must be encoded and signed. Then it + * must be retrieved in some conventional format (e.g. string). * - * @param publicKey the public key that should be placed into the - * certificate generated by the CA. - * @param attributes additonal set of PKCS10 attributes requested for in the - * certificate. + * @param publicKey the public key that should be placed + * into the certificate generated by the CA. + * @param attributes additonal set of PKCS10 attributes requested + * for in the certificate. */ - public PKCS10(X509Key publicKey, PKCS10Attributes attributes) { - subjectPublicKeyInfo = publicKey; - if (attributes != null) - attributeSet = attributes; - else - attributeSet = new PKCS10Attributes(); + public PKCS10 (X509Key publicKey, PKCS10Attributes attributes) + { + subjectPublicKeyInfo = publicKey; + if (attributes != null) + attributeSet = attributes; + else + attributeSet = new PKCS10Attributes(); } + /** - * Parses an encoded, signed PKCS #10 certificate request, verifying the - * request's signature as it does so. This constructor would typically be - * used by a Certificate Authority, from which a new certificate would then - * be constructed. - * + * Parses an encoded, signed PKCS #10 certificate request, verifying + * the request's signature as it does so. This constructor would + * typically be used by a Certificate Authority, from which a new + * certificate would then be constructed. + * * @param data the DER-encoded PKCS #10 request. * @param sigver boolean specifies signature verification enabled or not * @exception IOException for low level errors reading the data * @exception SignatureException when the signature is invalid - * @exception NoSuchAlgorithmException when the signature algorithm is not - * supported in this environment + * @exception NoSuchAlgorithmException when the signature + * algorithm is not supported in this environment */ - public PKCS10(byte data[], boolean sigver) throws IOException, - SignatureException, NoSuchAlgorithmException, - java.security.NoSuchProviderException { - DerInputStream in; - DerValue seq[]; - AlgorithmId id; - byte sigData[]; - Signature sig; - - certificateRequest = data; - - // - // Outer sequence: request, signature algorithm, signature. - // Parse, and prepare to verify later. - // - in = new DerInputStream(data); - seq = in.getSequence(3); - - if (seq.length != 3) - throw new IllegalArgumentException("not a PKCS #10 request"); - - data = seq[0].toByteArray(); // reusing this variable - certRequestInfo = seq[0].toByteArray(); // make a copy - id = AlgorithmId.parse(seq[1]); - sigData = seq[2].getBitString(); - - // - // Inner sequence: version, name, key, attributes - // - BigInt serial; - DerValue val; - - serial = seq[0].data.getInteger(); - /* - * if (serial.toInt () != 0) throw new IllegalArgumentException - * ("not PKCS #10 v1"); - */ - - subject = new X500Name(seq[0].data); - - byte val1[] = seq[0].data.getDerValue().toByteArray(); - subjectPublicKeyInfo = X509Key.parse(new DerValue(val1)); - PublicKey publicKey = X509Key.parsePublicKey(new DerValue(val1)); - - String keystr = subjectPublicKeyInfo.toString(); - - // Cope with a somewhat common illegal PKCS #10 format - if (seq[0].data.available() != 0) - attributeSet = new PKCS10Attributes(seq[0].data); - else - attributeSet = new PKCS10Attributes(); - - // - // OK, we parsed it all ... validate the signature using the - // key and signature algorithm we found. - // temporary commented out - try { - String idName = id.getName(); - if (idName.equals("MD5withRSA")) - idName = "MD5/RSA"; - else if (idName.equals("MD2withRSA")) - idName = "MD2/RSA"; - else if (idName.equals("SHA1withRSA")) - idName = "SHA1/RSA"; - else if (idName.equals("SHA1withDSA")) - idName = "SHA1/DSA"; - else if (idName.equals("SHA1withEC")) - idName = "SHA1/EC"; - else if (idName.equals("SHA256withEC")) - idName = "SHA256/EC"; - else if (idName.equals("SHA384withEC")) - idName = "SHA384/EC"; - else if (idName.equals("SHA512withEC")) - idName = "SHA512/EC"; - - if (sigver) { - sig = Signature.getInstance(idName, "Mozilla-JSS"); - - sig.initVerify(publicKey); - sig.update(data); - if (!sig.verify(sigData)) - throw new SignatureException("Invalid PKCS #10 signature"); - } - } catch (InvalidKeyException e) { - throw new SignatureException("invalid key"); + public PKCS10 (byte data [], boolean sigver) + throws IOException, SignatureException, NoSuchAlgorithmException,java.security.NoSuchProviderException + { + DerInputStream in; + DerValue seq []; + AlgorithmId id; + byte sigData []; + Signature sig; + + certificateRequest = data; + + // + // Outer sequence: request, signature algorithm, signature. + // Parse, and prepare to verify later. + // + in = new DerInputStream (data); + seq = in.getSequence (3); + + if (seq.length != 3) + throw new IllegalArgumentException ("not a PKCS #10 request"); + + data = seq [0].toByteArray (); // reusing this variable + certRequestInfo = seq[0].toByteArray(); // make a copy + id = AlgorithmId.parse (seq [1]); + sigData = seq [2].getBitString (); + + // + // Inner sequence: version, name, key, attributes + // + BigInt serial; + DerValue val; + + serial = seq [0].data.getInteger (); +/* + if (serial.toInt () != 0) + throw new IllegalArgumentException ("not PKCS #10 v1"); +*/ + + subject = new X500Name (seq [0].data); + + + byte val1[] = seq [0].data.getDerValue ().toByteArray(); + subjectPublicKeyInfo = X509Key.parse (new DerValue(val1)); + PublicKey publicKey = X509Key.parsePublicKey (new DerValue(val1)); + + String keystr = subjectPublicKeyInfo.toString(); + + // Cope with a somewhat common illegal PKCS #10 format + if (seq [0].data.available () != 0) + attributeSet = new PKCS10Attributes(seq [0].data); + else + attributeSet = new PKCS10Attributes(); + + // + // OK, we parsed it all ... validate the signature using the + // key and signature algorithm we found. + // temporary commented out + try { + String idName = id.getName (); + if(idName.equals("MD5withRSA")) + idName = "MD5/RSA"; + else if(idName.equals("MD2withRSA")) + idName = "MD2/RSA"; + else if(idName.equals("SHA1withRSA")) + idName = "SHA1/RSA"; + else if(idName.equals("SHA1withDSA")) + idName = "SHA1/DSA"; + else if(idName.equals("SHA1withEC")) + idName = "SHA1/EC"; + else if(idName.equals("SHA256withEC")) + idName = "SHA256/EC"; + else if(idName.equals("SHA384withEC")) + idName = "SHA384/EC"; + else if(idName.equals("SHA512withEC")) + idName = "SHA512/EC"; + + if (sigver) { + sig = Signature.getInstance(idName,"Mozilla-JSS"); + + sig.initVerify (publicKey); + sig.update (data); + if (!sig.verify (sigData)) + throw new SignatureException ("Invalid PKCS #10 signature"); } + } catch (InvalidKeyException e) { + throw new SignatureException ("invalid key"); + } } - public PKCS10(byte data[]) throws IOException, SignatureException, - NoSuchAlgorithmException, java.security.NoSuchProviderException { + public PKCS10 (byte data []) + throws IOException, SignatureException, NoSuchAlgorithmException,java.security.NoSuchProviderException + { this(data, true); } /** - * Create the signed certificate request. This will later be retrieved in - * either string or binary format. - * - * @param requester identifies the signer (by X.500 name) and provides the - * private key used to sign. + * Create the signed certificate request. This will later be + * retrieved in either string or binary format. + * + * @param requester identifies the signer (by X.500 name) + * and provides the private key used to sign. * @exception IOException on errors. * @exception CertificateException on certificate handling errors. * @exception SignatureException on signature handling errors. */ - public void encodeAndSign(X500Signer requester) - throws CertificateException, IOException, SignatureException { - DerOutputStream out, scratch; - byte certificateRequestInfo[]; - byte sig[]; - - if (certificateRequest != null) - throw new SignatureException("request is already signed"); - - subject = requester.getSigner(); - - /* - * Encode cert request info, wrap in a sequence for signing - */ - scratch = new DerOutputStream(); - scratch.putInteger(new BigInt(0)); // version zero - subject.encode(scratch); // X.500 name - subjectPublicKeyInfo.encode(scratch); // public key - attributeSet.encode(scratch); - - out = new DerOutputStream(); - out.write(DerValue.tag_Sequence, scratch); // wrap it! - certificateRequestInfo = out.toByteArray(); - scratch = out; - - /* - * Sign it ... - */ - requester.update(certificateRequestInfo, 0, - certificateRequestInfo.length); - sig = requester.sign(); - - /* - * Build guts of SIGNED macro - */ - requester.getAlgorithmId().encode(scratch); // sig algorithm - scratch.putBitString(sig); // sig - - /* - * Wrap those guts in a sequence - */ - out = new DerOutputStream(); - out.write(DerValue.tag_Sequence, scratch); - certificateRequest = out.toByteArray(); + public void encodeAndSign (X500Signer requester) + throws CertificateException, IOException, SignatureException + { + DerOutputStream out, scratch; + byte certificateRequestInfo []; + byte sig []; + + if (certificateRequest != null) + throw new SignatureException ("request is already signed"); + + subject = requester.getSigner (); + + /* + * Encode cert request info, wrap in a sequence for signing + */ + scratch = new DerOutputStream (); + scratch.putInteger (new BigInt (0)); // version zero + subject.encode (scratch); // X.500 name + subjectPublicKeyInfo.encode (scratch); // public key + attributeSet.encode (scratch); + + out = new DerOutputStream (); + out.write (DerValue.tag_Sequence, scratch); // wrap it! + certificateRequestInfo = out.toByteArray (); + scratch = out; + + /* + * Sign it ... + */ + requester.update (certificateRequestInfo, 0, + certificateRequestInfo.length); + sig = requester.sign (); + + /* + * Build guts of SIGNED macro + */ + requester.getAlgorithmId ().encode (scratch); // sig algorithm + scratch.putBitString (sig); // sig + + /* + * Wrap those guts in a sequence + */ + out = new DerOutputStream (); + out.write (DerValue.tag_Sequence, scratch); + certificateRequest = out.toByteArray (); } + /** * Returns the subject's name. */ - public X500Name getSubjectName() { - return subject; - } + public X500Name getSubjectName () + { return subject; } + /** * Returns the subject's public key. */ - public X509Key getSubjectPublicKeyInfo() { - return subjectPublicKeyInfo; - } + public X509Key getSubjectPublicKeyInfo () + { return subjectPublicKeyInfo; } + /** * Returns the additional attributes requested. */ - public PKCS10Attributes getAttributes() { - return attributeSet; - } + public PKCS10Attributes getAttributes () + { return attributeSet; } /** - * Returns the encoded and signed certificate request as a DER-encoded byte - * array. - * - * @return the certificate request, or null if encodeAndSign() has not yet - * been called. + * Returns the encoded and signed certificate request as a + * DER-encoded byte array. + * + * @return the certificate request, or null if encodeAndSign() + * has not yet been called. */ - public byte[] toByteArray() { - return certificateRequest; + public byte [] toByteArray () + { + return certificateRequest; } + /** * Prints an E-Mailable version of the certificate request on the print - * stream passed. The format is a common base64 encoded one, supported by - * most Certificate Authorities because Netscape web servers have used this - * for some time. Some certificate authorities expect some more information, - * in particular contact information for the web server administrator. - * - * @param out the print stream where the certificate request will be - * printed. + * stream passed. The format is a common base64 encoded one, supported + * by most Certificate Authorities because Netscape web servers have + * used this for some time. Some certificate authorities expect some + * more information, in particular contact information for the web + * server administrator. + * + * @param out the print stream where the certificate request + * will be printed. * @exception IOException when an output operation failed - * @exception SignatureException when the certificate request was not yet - * signed. + * @exception SignatureException when the certificate request was + * not yet signed. */ - public void print(PrintStream out) throws IOException, SignatureException { - if (certificateRequest == null) - throw new SignatureException("Cert request was not signed"); - - out.println("-----BEGIN NEW CERTIFICATE REQUEST-----"); - out.println(com.netscape.osutil.OSUtil.BtoA(certificateRequest)); - out.println("-----END NEW CERTIFICATE REQUEST-----"); + public void print (PrintStream out) + throws IOException, SignatureException + { + if (certificateRequest == null) + throw new SignatureException ("Cert request was not signed"); + + + out.println ("-----BEGIN NEW CERTIFICATE REQUEST-----"); + out.println (com.netscape.osutil.OSUtil.BtoA(certificateRequest)); + out.println ("-----END NEW CERTIFICATE REQUEST-----"); } /** * Provides a short description of this request. */ - public String toString() { - return "[PKCS #10 certificate request:\n" - + subjectPublicKeyInfo.toString() + " subject: <" + subject - + ">" + "\n" + " attributes: " + attributeSet.toString() - + "\n]"; + public String toString () + { + return "[PKCS #10 certificate request:\n" + + subjectPublicKeyInfo.toString() + + " subject: <" + subject + ">" + "\n" + + " attributes: " + attributeSet.toString() + + "\n]"; } /** * Retrieve the PKCS10 CertificateRequestInfo as a byte array */ - public byte[] getCertRequestInfo() { - return certRequestInfo; + public byte[] getCertRequestInfo() + { + return certRequestInfo; } - private X500Name subject; - private X509Key subjectPublicKeyInfo; - private PKCS10Attributes attributeSet; + private X500Name subject; + private X509Key subjectPublicKeyInfo; + private PKCS10Attributes attributeSet; - private byte certificateRequest[]; // signed - private byte certRequestInfo[]; // inner content signed + private byte certificateRequest []; // signed + private byte certRequestInfo []; // inner content signed } diff --git a/pki/base/util/src/netscape/security/pkcs/PKCS10Attribute.java b/pki/base/util/src/netscape/security/pkcs/PKCS10Attribute.java index b2752cb71..e3eee8099 100644 --- a/pki/base/util/src/netscape/security/pkcs/PKCS10Attribute.java +++ b/pki/base/util/src/netscape/security/pkcs/PKCS10Attribute.java @@ -35,21 +35,19 @@ import netscape.security.x509.CertAttrSet; import netscape.security.x509.Extensions; import netscape.security.x509.OIDMap; + /** * Represent a PKCS Attribute. - * - * <p> - * Attributes are addiitonal attributes which can be inserted in a PKCS + * + * <p>Attributes are addiitonal attributes which can be inserted in a PKCS * certificate request. For example a "Driving License Certificate" could have * the driving license number as a attribute. - * - * <p> - * Attributes are represented as a sequence of the attribute identifier (Object - * Identifier) and a set of DER encoded attribute values. The current + * + * <p>Attributes are represented as a sequence of the attribute identifier + * (Object Identifier) and a set of DER encoded attribute values. The current * implementation only supports one value per attribute. - * + * * ASN.1 definition of Attribute: - * * <pre> * Attribute :: SEQUENCE { * type AttributeValue, @@ -57,7 +55,7 @@ import netscape.security.x509.OIDMap; * } * AttributeValue ::= ANY * </pre> - * + * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.13 @@ -67,11 +65,11 @@ public class PKCS10Attribute implements DerEncoder, Serializable { * */ private static final long serialVersionUID = 2002480042340316170L; - protected ObjectIdentifier attributeId = null; - protected CertAttrSet attributeValue = null; + protected ObjectIdentifier attributeId = null; + protected CertAttrSet attributeValue = null; /** - * Default constructor. Used only by sub-classes. + * Default constructor. Used only by sub-classes. */ public PKCS10Attribute() { } @@ -81,63 +79,64 @@ public class PKCS10Attribute implements DerEncoder, Serializable { */ public PKCS10Attribute(DerValue derVal) throws IOException { if (derVal.tag != DerValue.tag_Sequence) { - throw new IOException("Sequence tag missing for PKCS10Attribute."); - } + throw new IOException("Sequence tag missing for PKCS10Attribute."); + } DerInputStream in = derVal.toDerInputStream(); // Object identifier attributeId = in.getOID(); - // System.out.println("attribute ID in pkcs10 "+attributeId.toString()); - - // Rest of the stuff is attribute value(s), wrapped in a SET. - // For now, assume there is only one attribute value present. - DerValue[] inAttrValues = in.getSet(1); - int attrValueNum = inAttrValues.length; - if (attrValueNum > 1) { - throw new IOException( - "More than one value per attribute not supported"); - } - - // Read the first attribute value - DerValue inAttrValue = inAttrValues[0]; - - if (attributeId.equals(PKCS9Attribute.EXTENSION_REQUEST_OID)) { - // pkcs9 extensionAttr - try { - // remove the tag - // DerValue dv = inAttrValue.data.getDerValue(); - // hack. toDerInputStream only gives one extension. - DerInputStream fi = new DerInputStream( - inAttrValue.toByteArray()); - attributeValue = (CertAttrSet) new Extensions(fi); - // CertificateExtensions(fi); - return; - } catch (Exception e) { - throw new IOException(e.toString()); - } - } - byte[] val = inAttrValue.toByteArray(); + // System.out.println("attribute ID in pkcs10 "+attributeId.toString()); + + // Rest of the stuff is attribute value(s), wrapped in a SET. + // For now, assume there is only one attribute value present. + DerValue[] inAttrValues = in.getSet(1); + int attrValueNum = inAttrValues.length; + if (attrValueNum > 1) { + throw new IOException("More than one value per attribute not supported"); + } + + // Read the first attribute value + DerValue inAttrValue = inAttrValues[0]; + + if (attributeId.equals(PKCS9Attribute.EXTENSION_REQUEST_OID)) { + //pkcs9 extensionAttr + try{ + // remove the tag + //DerValue dv = inAttrValue.data.getDerValue(); + // hack. toDerInputStream only gives one extension. + DerInputStream fi = new DerInputStream(inAttrValue.toByteArray()); + attributeValue = (CertAttrSet) new + Extensions(fi); + //CertificateExtensions(fi); + return; + } catch(Exception e) { + throw new IOException(e.toString()); + } + } + byte[] val = inAttrValue.toByteArray(); Class[] params = { Object.class }; try { - Class extClass = OIDMap.getClass(attributeId); - if (extClass != null) { - Constructor cons = extClass.getConstructor(params); - Object value = Array.newInstance(byte.class, val.length); - for (int i = 0; i < val.length; i++) { - Array.setByte(value, i, val[i]); - } - Object[] passed = new Object[] { value }; - attributeValue = (CertAttrSet) cons.newInstance(passed); - } else { - // attribute classes are usable for PKCS10 attributes. - // this is used where the attributes are not actual - // implemented extensions. - attributeValue = new ACertAttrSet(inAttrValue); - } - } catch (InvocationTargetException invk) { - throw new IOException(invk.getTargetException().getMessage()); - } catch (Exception e) { - throw new IOException(e.toString()); + Class extClass = OIDMap.getClass(attributeId); + if (extClass != null) { + Constructor cons = extClass.getConstructor(params); + Object value = Array.newInstance(byte.class,val.length); + for (int i = 0; i < val.length; i++) { + Array.setByte(value,i,val[i]); + } + Object[] passed = new Object[] {value}; + attributeValue = (CertAttrSet) cons.newInstance(passed); + } else { + // attribute classes are usable for PKCS10 attributes. + // this is used where the attributes are not actual + // implemented extensions. + attributeValue = new ACertAttrSet(inAttrValue); + } + } + catch (InvocationTargetException invk) { + throw new IOException(invk.getTargetException().getMessage()); + } + catch (Exception e) { + throw new IOException(e.toString()); } } @@ -149,14 +148,14 @@ public class PKCS10Attribute implements DerEncoder, Serializable { * @param attributeValue the CertAttrSet. */ public PKCS10Attribute(ObjectIdentifier attributeId, - CertAttrSet attributeValue) { + CertAttrSet attributeValue) { this.attributeId = attributeId; this.attributeValue = attributeValue; } /** - * Constructs an attribute from another attribute. To be used for creating - * decoded subclasses. + * Constructs an attribute from another attribute. To be used for + * creating decoded subclasses. * * @param attr the attribute to create from. */ @@ -167,50 +166,52 @@ public class PKCS10Attribute implements DerEncoder, Serializable { /** * Write the output to the DerOutputStream. - * + * * @param out the OutputStream to write the attribute to. * @exception CertificateException on certificate encoding errors. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws CertificateException, - IOException { + public void encode(OutputStream out) + throws CertificateException, IOException { // Encode the attribute value - DerOutputStream outAttrValue = new DerOutputStream(); - attributeValue.encode(outAttrValue); + DerOutputStream outAttrValue = new DerOutputStream(); + attributeValue.encode(outAttrValue); - // Wrap the encoded attribute value into a SET - DerValue outAttrValueSet = new DerValue(DerValue.tag_Set, - outAttrValue.toByteArray()); + // Wrap the encoded attribute value into a SET + DerValue outAttrValueSet = new DerValue(DerValue.tag_Set, + outAttrValue.toByteArray()); - // Create the attribute + // Create the attribute DerOutputStream outAttr = new DerOutputStream(); outAttr.putOID(attributeId); - outAttr.putDerValue(outAttrValueSet); + outAttr.putDerValue(outAttrValueSet); - // Wrap the OID and the set of attribute values into a SEQUENCE + // Wrap the OID and the set of attribute values into a SEQUENCE DerOutputStream tmp = new DerOutputStream(); tmp.write(DerValue.tag_Sequence, outAttr); - // write the results to out - out.write(tmp.toByteArray()); + // write the results to out + out.write(tmp.toByteArray()); } /** - * DER encode this object onto an output stream. Implements the - * <code>DerEncoder</code> interface. - * - * @param out the OutputStream on which to write the DER encoding. - * + * DER encode this object onto an output stream. + * Implements the <code>DerEncoder</code> interface. + * + * @param out + * the OutputStream on which to write the DER encoding. + * * @exception IOException on encoding errors. */ - public void derEncode(OutputStream out) throws IOException { - try { - encode(out); - } catch (CertificateException ce) { - IOException ioe = new IOException(ce.toString()); - ioe.fillInStackTrace(); - throw ioe; - } + public void derEncode (OutputStream out) throws IOException + { + try { + encode(out); + } catch (CertificateException ce) { + IOException ioe = new IOException(ce.toString()); + ioe.fillInStackTrace(); + throw ioe; + } } /** @@ -232,8 +233,11 @@ public class PKCS10Attribute implements DerEncoder, Serializable { */ public String toString() { String s = "AttributeId: " + attributeId.toString() + "\n"; - s += "AttributeValue: " + attributeValue.toString(); + s += "AttributeValue: " + attributeValue.toString(); return (s); } } + + + diff --git a/pki/base/util/src/netscape/security/pkcs/PKCS10Attributes.java b/pki/base/util/src/netscape/security/pkcs/PKCS10Attributes.java index 66fce8196..441d7da29 100644 --- a/pki/base/util/src/netscape/security/pkcs/PKCS10Attributes.java +++ b/pki/base/util/src/netscape/security/pkcs/PKCS10Attributes.java @@ -30,7 +30,7 @@ import netscape.security.util.DerValue; /** * This class defines the PKCS10 attributes for the request. - * + * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.10 @@ -52,52 +52,55 @@ public class PKCS10Attributes extends Vector implements DerEncoder { /** * Create the object, decoding the values from the passed DER stream. - * + * * @param in the DerInputStream to read the attributes from. * @exception IOException on decoding errors. */ - public PKCS10Attributes(DerInputStream in) throws IOException { + public PKCS10Attributes(DerInputStream in) + throws IOException { map = new Hashtable(); - DerValue[] attrs = in.getSet(5, true); - - if (attrs != null) { - for (int i = 0; i < attrs.length; i++) { - PKCS10Attribute attr = new PKCS10Attribute(attrs[i]); - addElement(attr); - map.put(attr.getAttributeValue().getName(), attr); - } - } + DerValue [] attrs = in.getSet(5,true); + + if (attrs != null) { + for (int i = 0; i < attrs.length; i++) { + PKCS10Attribute attr = new PKCS10Attribute(attrs[i]); + addElement(attr); + map.put(attr.getAttributeValue().getName(),attr); + } + } } + /** * Encode the attributes in DER form to the stream. - * + * * @param out the OutputStream to marshal the contents to. - * + * * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - derEncode(out); - } + public void encode(OutputStream out) + throws IOException { + derEncode(out); + } /** - * Encode the attributes in DER form to the stream. Implements the - * <code>DerEncoder</code> interface. - * + * Encode the attributes in DER form to the stream. + * Implements the <code>DerEncoder</code> interface. + * * @param out the OutputStream to marshal the contents to. * @exception IOException on encoding errors. */ - public void derEncode(OutputStream out) throws IOException { + public void derEncode(OutputStream out) + throws IOException { - // first copy the elements into an array - PKCS10Attribute[] attribs = new PKCS10Attribute[size()]; - copyInto(attribs); + // first copy the elements into an array + PKCS10Attribute[] attribs = new PKCS10Attribute[size()]; + copyInto(attribs); - DerOutputStream attrOut = new DerOutputStream(); - attrOut.putOrderedSetOf( - DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), - attribs); + DerOutputStream attrOut = new DerOutputStream(); + attrOut.putOrderedSetOf(DerValue.createTag(DerValue.TAG_CONTEXT,true,(byte)0), + attribs); out.write(attrOut.toByteArray()); } @@ -106,7 +109,7 @@ public class PKCS10Attributes extends Vector implements DerEncoder { * Set the attribute value. */ public void setAttribute(String name, Object obj) throws IOException { - map.put(name, obj); + map.put(name,obj); addElement(obj); } @@ -115,10 +118,11 @@ public class PKCS10Attributes extends Vector implements DerEncoder { */ public Object getAttribute(String name) throws IOException { Object obj = map.get(name); - /* - * if (obj == null) { throw new - * IOException("No attribute found with name " + name); } - */ + /* + if (obj == null) { + throw new IOException("No attribute found with name " + name); + } + */ return (obj); } @@ -138,7 +142,7 @@ public class PKCS10Attributes extends Vector implements DerEncoder { * Return an enumeration of names of attributes existing within this * attribute. */ - public Enumeration getElements() { + public Enumeration getElements () { return (map.elements()); } } diff --git a/pki/base/util/src/netscape/security/pkcs/PKCS7.java b/pki/base/util/src/netscape/security/pkcs/PKCS7.java index 869995f3c..c31e12456 100644 --- a/pki/base/util/src/netscape/security/pkcs/PKCS7.java +++ b/pki/base/util/src/netscape/security/pkcs/PKCS7.java @@ -38,13 +38,14 @@ import netscape.security.x509.X500Name; import netscape.security.x509.X509CertImpl; /** - * PKCS7 as defined in RSA Laboratories PKCS7 Technical Note. Profile Supports - * only <tt>SignedData</tt> ContentInfo type, where to the type of data signed - * is plain Data. For signedData, <tt>crls</tt>, <tt>attributes</tt> and PKCS#6 - * Extended Certificates are not supported. - * + * PKCS7 as defined in RSA Laboratories PKCS7 Technical Note. Profile + * Supports only <tt>SignedData</tt> ContentInfo + * type, where to the type of data signed is plain Data. + * For signedData, <tt>crls</tt>, <tt>attributes</tt> and + * PKCS#6 Extended Certificates are not supported. + * * @version 1.33 97/12/10 - * @author Benjamin Renaud + * @author Benjamin Renaud */ public class PKCS7 { @@ -58,383 +59,392 @@ public class PKCS7 { private SignerInfo[] signerInfos; /** - * Unmarshals a PKCS7 block from its encoded form, parsing the encoded bytes - * from the InputStream. - * + * Unmarshals a PKCS7 block from its encoded form, parsing the + * encoded bytes from the InputStream. + * * @param in an input stream holding at least one PKCS7 block. * @exception ParsingException on parsing errors. * @exception IOException on other errors. */ public PKCS7(InputStream in) throws ParsingException, IOException { - DataInputStream dis = new DataInputStream(in); - - int len = 0; - byte[] newbuf = new byte[len]; - byte[] oldbuf = new byte[len]; - byte[] data = new byte[len]; - - do { - newbuf = new byte[dis.available()]; - len += dis.available(); - dis.readFully(newbuf); - data = new byte[len]; - - System.arraycopy(oldbuf, 0, data, 0, oldbuf.length); - System.arraycopy(newbuf, 0, data, oldbuf.length, newbuf.length); - oldbuf = new byte[len]; - System.arraycopy(data, 0, oldbuf, 0, data.length); - - } while (dis.available() > 0); - - parse(new DerInputStream(data)); + DataInputStream dis = new DataInputStream(in); + + int len = 0; + byte[] newbuf = new byte[len]; + byte[] oldbuf = new byte[len]; + byte[] data = new byte[len]; + + do { + newbuf = new byte[dis.available()]; + len += dis.available(); + dis.readFully(newbuf); + data = new byte[len]; + + System.arraycopy(oldbuf, 0, data, 0, oldbuf.length); + System.arraycopy(newbuf, 0, data, oldbuf.length, newbuf.length); + oldbuf = new byte[len]; + System.arraycopy(data, 0, oldbuf, 0, data.length); + + } while (dis.available() > 0); + + parse(new DerInputStream(data)); } - + /** - * Unmarshals a PKCS7 block from its encoded form, parsing the encoded bytes - * from the DerInputStream. - * + * Unmarshals a PKCS7 block from its encoded form, parsing the + * encoded bytes from the DerInputStream. + * * @param derin a DerInputStream holding at least one PKCS7 block. * @exception ParsingException on parsing errors. */ public PKCS7(DerInputStream derin) throws ParsingException { - parse(derin); + parse(derin); } /** - * Unmarshals a PKCS7 block from its encoded form, parsing the encoded - * bytes. - * + * Unmarshals a PKCS7 block from its encoded form, parsing the + * encoded bytes. + * * @param bytes the encoded bytes. * @exception ParsingException on parsing errors. */ public PKCS7(byte[] bytes) throws ParsingException { - DerInputStream derin = new DerInputStream(bytes); - parse(derin); + DerInputStream derin = new DerInputStream(bytes); + parse(derin); } private void parse(DerInputStream derin) throws ParsingException { - try { - ContentInfo contentInfo = new ContentInfo(derin); - contentType = contentInfo.contentType; - if (contentType.equals(ContentInfo.SIGNED_DATA_OID)) { - parseSignedData(contentInfo.getContent()); - } else { - throw new ParsingException("content type " + contentType - + " not supported."); - } - } catch (IOException e) { - ParsingException pe = new ParsingException("IOException: " - + e.getMessage()); - pe.fillInStackTrace(); - throw pe; - } + try { + ContentInfo contentInfo = new ContentInfo(derin); + contentType = contentInfo.contentType; + if (contentType.equals(ContentInfo.SIGNED_DATA_OID)) { + parseSignedData(contentInfo.getContent()); + } else { + throw new ParsingException("content type " + contentType + + " not supported."); + } + } catch (IOException e) { + ParsingException pe = + new ParsingException("IOException: " + e.getMessage()); + pe.fillInStackTrace(); + throw pe; + } } /** - * Construct an initialized PKCS7 block. - * + * Construct an initialized PKCS7 block. + * * @param digestAlgorithmIds the message digest algorithm identifiers. * @param contentInfo the content information. * @param certificates an array of X.509 certificates. * @param signerInfos an array of signer information. */ - public PKCS7(AlgorithmId[] digestAlgorithmIds, ContentInfo contentInfo, - X509Certificate[] certificates, SignerInfo[] signerInfos) { - - version = new BigInt(1); - this.digestAlgorithmIds = digestAlgorithmIds; - this.contentInfo = contentInfo; - this.certificates = certificates; - this.signerInfos = signerInfos; + public PKCS7(AlgorithmId[] digestAlgorithmIds, + ContentInfo contentInfo, + X509Certificate[] certificates, + SignerInfo[] signerInfos) { + + version = new BigInt(1); + this.digestAlgorithmIds = digestAlgorithmIds; + this.contentInfo = contentInfo; + this.certificates = certificates; + this.signerInfos = signerInfos; } - private void parseSignedData(DerValue val) throws ParsingException, - IOException { - - DerInputStream dis = val.toDerInputStream(); - - // Version - version = dis.getInteger(); - - // digestAlgorithmIds - DerValue[] digestAlgorithmIdVals = dis.getSet(1); - int len = digestAlgorithmIdVals.length; - digestAlgorithmIds = new AlgorithmId[len]; - try { - for (int i = 0; i < len; i++) { - DerValue oid = digestAlgorithmIdVals[i]; - digestAlgorithmIds[i] = AlgorithmId.parse(oid); - } - - } catch (IOException e) { - ParsingException pe = new ParsingException( - "Error parsing digest AlgorithmId IDs: " + e.getMessage()); - pe.fillInStackTrace(); - throw pe; - } - // contentInfo - contentInfo = new ContentInfo(dis); - - /* - * check if certificates (implicit tag) are provided (certificates are - * OPTIONAL) - */ - if ((byte) (dis.peekByte()) == (byte) 0xA0) { - DerValue[] certificateVals = dis.getSet(2, true); - - len = certificateVals.length; - certificates = new X509Certificate[len]; - - for (int i = 0; i < len; i++) { - try { - X509Certificate cert = (X509Certificate) new X509CertImpl( - certificateVals[i]); - certificates[i] = cert; - } catch (CertificateException e) { - ParsingException pe = new ParsingException( - "CertificateException: " + e.getMessage()); - pe.fillInStackTrace(); - throw pe; - } - } - } - - // check if crls (implicit tag) are provided (crls are OPTIONAL) - if ((byte) (dis.peekByte()) == (byte) 0xA1) { - dis.getSet(0, true); - } - - // signerInfos - DerValue[] signerInfoVals = dis.getSet(1); - - len = signerInfoVals.length; - signerInfos = new SignerInfo[len]; - - for (int i = 0; i < len; i++) { - DerInputStream in = signerInfoVals[i].toDerInputStream(); - signerInfos[i] = new SignerInfo(in); - } + private void parseSignedData(DerValue val) + throws ParsingException, IOException { + + DerInputStream dis = val.toDerInputStream(); + + // Version + version = dis.getInteger(); + + // digestAlgorithmIds + DerValue[] digestAlgorithmIdVals = dis.getSet(1); + int len = digestAlgorithmIdVals.length; + digestAlgorithmIds = new AlgorithmId[len]; + try { + for (int i = 0; i < len; i++) { + DerValue oid = digestAlgorithmIdVals[i]; + digestAlgorithmIds[i] = AlgorithmId.parse(oid); + } + + } catch (IOException e) { + ParsingException pe = + new ParsingException("Error parsing digest AlgorithmId IDs: " + + e.getMessage()); + pe.fillInStackTrace(); + throw pe; + } + // contentInfo + contentInfo = new ContentInfo(dis); + + /* + * check if certificates (implicit tag) are provided + * (certificates are OPTIONAL) + */ + if ((byte)(dis.peekByte()) == (byte)0xA0) { + DerValue[] certificateVals = dis.getSet(2, true); + + len = certificateVals.length; + certificates = new X509Certificate[len]; + + for (int i = 0; i < len; i++) { + try { + X509Certificate cert = (X509Certificate) new + X509CertImpl(certificateVals[i]); + certificates[i] = cert; + } catch (CertificateException e) { + ParsingException pe = + new ParsingException("CertificateException: " + + e.getMessage()); + pe.fillInStackTrace(); + throw pe; + } + } + } + + // check if crls (implicit tag) are provided (crls are OPTIONAL) + if ((byte)(dis.peekByte()) == (byte)0xA1) { + dis.getSet(0, true); + } + + // signerInfos + DerValue[] signerInfoVals = dis.getSet(1); + + len = signerInfoVals.length; + signerInfos = new SignerInfo[len]; + + for (int i = 0; i < len; i++) { + DerInputStream in = signerInfoVals[i].toDerInputStream(); + signerInfos[i] = new SignerInfo(in); + } } /** * Encodes the signed data to an output stream. - * + * * @param out the output stream to write the encoded data to. * @exception IOException on encoding errors. */ public void encodeSignedData(OutputStream out) throws IOException { - DerOutputStream derout = new DerOutputStream(); - encodeSignedData(derout, true); - out.write(derout.toByteArray()); + DerOutputStream derout = new DerOutputStream(); + encodeSignedData(derout, true); + out.write(derout.toByteArray()); } /** - * Like method above but not sorted. + * Like method above but not sorted. */ - public void encodeSignedData(OutputStream out, boolean sort) - throws IOException { - DerOutputStream derout = new DerOutputStream(); - encodeSignedData(derout, sort); - out.write(derout.toByteArray()); + public void encodeSignedData(OutputStream out, boolean sort) + throws IOException { + DerOutputStream derout = new DerOutputStream(); + encodeSignedData(derout, sort); + out.write(derout.toByteArray()); } /** * encode signed data, sort certs by default. */ - public void encodeSignedData(DerOutputStream out) throws IOException { - encodeSignedData(out, true); + public void encodeSignedData(DerOutputStream out) + throws IOException { + encodeSignedData(out, true); } /** * Encodes the signed data to a DerOutputStream. - * + * * @param out the DerOutputStream to write the encoded data to. * @exception IOException on encoding errors. */ - public void encodeSignedData(DerOutputStream out, boolean sort) - throws IOException { + public void encodeSignedData(DerOutputStream out, boolean sort) + throws IOException { - DerOutputStream signedData = new DerOutputStream(); + DerOutputStream signedData = new DerOutputStream(); - // version - signedData.putInteger(version); + // version + signedData.putInteger(version); + + // digestAlgorithmIds + signedData.putOrderedSetOf(DerValue.tag_Set, digestAlgorithmIds); - // digestAlgorithmIds - signedData.putOrderedSetOf(DerValue.tag_Set, digestAlgorithmIds); + // contentInfo + contentInfo.encode(signedData); + + // certificates + DerOutputStream certs = new DerOutputStream(); - // contentInfo - contentInfo.encode(signedData); - - // certificates - DerOutputStream certs = new DerOutputStream(); - - // cast to X509CertImpl[] since X509CertImpl implements DerEncoder + // cast to X509CertImpl[] since X509CertImpl implements DerEncoder X509CertImpl implCerts[] = new X509CertImpl[certificates.length]; - try { - for (int i = 0; i < certificates.length; i++) { - implCerts[i] = (X509CertImpl) certificates[i]; + try { + for (int i = 0; i < certificates.length; i++) { + implCerts[i] = (X509CertImpl) certificates[i]; } - } catch (ClassCastException e) { - IOException ioe = new IOException("Certificates in PKCS7 " - + "must be of class " + "netscape.security.X509CertImpl"); - ioe.fillInStackTrace(); - } - - // Add the certificate set (tagged with [0] IMPLICIT) - // to the signed data - if (sort) { - signedData.putOrderedSetOf((byte) 0xA0, implCerts); - } else { - signedData.putSet((byte) 0xA0, implCerts); - } - - // no crls (OPTIONAL field) - - // signerInfos - signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos); - - // making it a signed data block - DerValue signedDataSeq = new DerValue(DerValue.tag_Sequence, - signedData.toByteArray()); - - // making it a content info sequence - ContentInfo block = new ContentInfo(ContentInfo.SIGNED_DATA_OID, - signedDataSeq); - - // writing out the contentInfo sequence - block.encode(out); + } catch (ClassCastException e) { + IOException ioe = + new IOException("Certificates in PKCS7 " + + "must be of class " + + "netscape.security.X509CertImpl"); + ioe.fillInStackTrace(); + } + + // Add the certificate set (tagged with [0] IMPLICIT) + // to the signed data + if (sort) { + signedData.putOrderedSetOf((byte)0xA0, implCerts); + } + else { + signedData.putSet((byte)0xA0, implCerts); + } + + // no crls (OPTIONAL field) + + // signerInfos + signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos); + + // making it a signed data block + DerValue signedDataSeq = new DerValue(DerValue.tag_Sequence, + signedData.toByteArray()); + + // making it a content info sequence + ContentInfo block = new ContentInfo(ContentInfo.SIGNED_DATA_OID, + signedDataSeq); + + // writing out the contentInfo sequence + block.encode(out); } /** * This verifies a given SignerInfo. - * + * * @param info the signer information. * @param bytes the DER encoded content information. - * + * * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception SignatureException on signature handling errors. */ - public SignerInfo verify(SignerInfo info, byte[] bytes) - throws NoSuchAlgorithmException, SignatureException { - return info.verify(this, bytes); + public SignerInfo verify(SignerInfo info, byte[] bytes) + throws NoSuchAlgorithmException, SignatureException { + return info.verify(this, bytes); } - /** + /** * Returns all signerInfos which self-verify. - * + * * @param bytes the DER encoded content information. - * + * * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception SignatureException on signature handling errors. */ - public SignerInfo[] verify(byte[] bytes) throws NoSuchAlgorithmException, - SignatureException { - - Vector intResult = new Vector(); - for (int i = 0; i < signerInfos.length; i++) { - - SignerInfo signerInfo = verify(signerInfos[i], bytes); - if (signerInfo != null) { - intResult.addElement(signerInfo); - } - } - if (intResult.size() != 0) { - - SignerInfo[] result = new SignerInfo[intResult.size()]; - intResult.copyInto(result); - return result; - } - return null; + public SignerInfo[] verify(byte[] bytes) + throws NoSuchAlgorithmException, SignatureException { + + Vector intResult = new Vector(); + for (int i = 0; i < signerInfos.length; i++) { + + SignerInfo signerInfo = verify(signerInfos[i], bytes); + if (signerInfo != null) { + intResult.addElement(signerInfo); + } + } + if (intResult.size() != 0) { + + SignerInfo[] result = new SignerInfo[intResult.size()]; + intResult.copyInto(result); + return result; + } + return null; } - /** + /** * Returns all signerInfos which self-verify. - * + * * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception SignatureException on signature handling errors. */ - public SignerInfo[] verify() throws NoSuchAlgorithmException, - SignatureException { - return verify(null); + public SignerInfo[] verify() + throws NoSuchAlgorithmException, SignatureException { + return verify(null); } - - /** + + /** * Returns the version number of this PKCS7 block. */ - public BigInt getVersion() { - return version; + public BigInt getVersion() { + return version; } - /** + /** * Returns the message digest algorithms specified in this PKCS7 block. */ public AlgorithmId[] getDigestAlgorithmIds() { - return digestAlgorithmIds; + return digestAlgorithmIds; } - /** + /** * Returns the content information specified in this PKCS7 block. */ public ContentInfo getContentInfo() { - return contentInfo; + return contentInfo; } - /** + /** * Returns the X.509 certificates listed in this PKCS7 block. */ public X509Certificate[] getCertificates() { - return certificates; + return certificates; } - /** + /** * Returns the signer's information specified in this PKCS7 block. */ public SignerInfo[] getSignerInfos() { - return signerInfos; + return signerInfos; } - /** - * Returns the X.509 certificate listed in this PKCS7 block which has a - * matching serial number and Issuer name, or null if one is not found. - * + /** + * Returns the X.509 certificate listed in this PKCS7 block + * which has a matching serial number and Issuer name, or + * null if one is not found. + * * @param serial the serial number of the certificate to retrieve. * @param name the Distinguished Name of the Issuer. */ public X509Certificate getCertificate(BigInt serial, X500Name name) { - for (int i = 0; i < certificates.length; i++) { - X509Certificate cert = certificates[i]; - X500Name thisName = (X500Name) cert.getIssuerDN(); - BigInteger tmpSerial = (BigInteger) cert.getSerialNumber(); - BigInt thisSerial = new BigInt(tmpSerial); - if (serial.equals(thisSerial) && name.equals(thisName)) { - return cert; - } - } - return null; + for (int i = 0; i < certificates.length; i++) { + X509Certificate cert = certificates[i]; + X500Name thisName = (X500Name)cert.getIssuerDN(); + BigInteger tmpSerial = (BigInteger)cert.getSerialNumber(); + BigInt thisSerial = new BigInt(tmpSerial); + if (serial.equals(thisSerial) && name.equals(thisName)) { + return cert; + } + } + return null; } - /** + /** * Returns the PKCS7 block in a printable string form. */ public String toString() { - String out = ""; - - out += "PKCS7 :: version: " + version + "\n"; - out += "PKCS7 :: digest AlgorithmIds: \n"; - for (int i = 0; i < digestAlgorithmIds.length; i++) { - out += "\t" + digestAlgorithmIds[i] + "\n"; - } - out += contentInfo + "\n"; - out += "PKCS7 :: certificates: \n"; - for (int i = 0; i < certificates.length; i++) { - out += "\t" + i + ". " + certificates[i] + "\n"; - } - out += "PKCS7 :: signer infos: \n"; - for (int i = 0; i < signerInfos.length; i++) { - out += ("\t" + i + ". " + signerInfos[i] + "\n"); - } - return out; + String out = ""; + + out += "PKCS7 :: version: " + version + "\n"; + out += "PKCS7 :: digest AlgorithmIds: \n"; + for (int i = 0; i < digestAlgorithmIds.length; i++) { + out += "\t" + digestAlgorithmIds[i] + "\n"; + } + out += contentInfo + "\n"; + out += "PKCS7 :: certificates: \n"; + for (int i = 0; i < certificates.length; i++) { + out += "\t" + i + ". " + certificates[i] + "\n"; + } + out += "PKCS7 :: signer infos: \n"; + for (int i = 0; i < signerInfos.length; i++) { + out += ("\t" + i + ". " + signerInfos[i] + "\n"); + } + return out; } } diff --git a/pki/base/util/src/netscape/security/pkcs/PKCS8Key.java b/pki/base/util/src/netscape/security/pkcs/PKCS8Key.java index 5d05b0663..20a788fcb 100644 --- a/pki/base/util/src/netscape/security/pkcs/PKCS8Key.java +++ b/pki/base/util/src/netscape/security/pkcs/PKCS8Key.java @@ -40,7 +40,7 @@ import netscape.security.x509.AlgorithmId; /** * Holds a PKCS#8 key, for example a private key - * + * * @version 1.30, 97/12/10 * @author Dave Brownell * @author Benjamin Renaud @@ -61,385 +61,394 @@ public class PKCS8Key implements PrivateKey { /* The version for this key */ public static final BigInteger VERSION = BigInteger.valueOf(0); - + /** - * Default constructor. The key constructed must have its key and algorithm - * initialized before it may be used, for example by using - * <code>decode</code>. + * Default constructor. The key constructed must have its key + * and algorithm initialized before it may be used, for example + * by using <code>decode</code>. */ - public PKCS8Key() { - } + public PKCS8Key() { } /* - * Build and initialize as a "default" key. All PKCS#8 key data is stored - * and transmitted losslessly, but no knowledge about this particular - * algorithm is available. + * Build and initialize as a "default" key. All PKCS#8 key + * data is stored and transmitted losslessly, but no knowledge + * about this particular algorithm is available. */ - private PKCS8Key(AlgorithmId algid, byte key[]) throws InvalidKeyException { - this.algid = algid; - this.key = key; - encode(); + private PKCS8Key (AlgorithmId algid, byte key []) + throws InvalidKeyException { + this.algid = algid; + this.key = key; + encode(); } /** - * Construct PKCS#8 subject public key from a DER value. If the runtime - * environment is configured with a specific class for this kind of key, a - * subclass is returned. Otherwise, a generic PKCS8Key object is returned. - * - * <P> - * This mechanism gurantees that keys (and algorithms) may be freely - * manipulated and transferred, without risk of losing information. Also, - * when a key (or algorithm) needs some special handling, that specific need - * can be accomodated. + * Construct PKCS#8 subject public key from a DER value. If + * the runtime environment is configured with a specific class for + * this kind of key, a subclass is returned. Otherwise, a generic + * PKCS8Key object is returned. * + * <P>This mechanism gurantees that keys (and algorithms) may be + * freely manipulated and transferred, without risk of losing + * information. Also, when a key (or algorithm) needs some special + * handling, that specific need can be accomodated. + * * @param in the DER-encoded SubjectPublicKeyInfo value * @exception IOException on data format errors */ - public static PKCS8Key parse(DerValue in) throws IOException { - AlgorithmId algorithm; - PKCS8Key subjectKey; - - if (in.tag != DerValue.tag_Sequence) - throw new IOException("corrupt private key"); - - BigInteger parsedVersion = in.data.getInteger().toBigInteger(); - if (!VERSION.equals(parsedVersion)) { - throw new IOException("version mismatch: (supported: " + VERSION - + ", parsed: " + parsedVersion); - } - - algorithm = AlgorithmId.parse(in.data.getDerValue()); - - try { - subjectKey = buildPKCS8Key(algorithm, in.data.getOctetString()); - - } catch (InvalidKeyException e) { - throw new IOException("corrupt private key"); - } - - if (in.data.available() != 0) - throw new IOException("excess private key"); - return subjectKey; + public static PKCS8Key parse (DerValue in) throws IOException + { + AlgorithmId algorithm; + PKCS8Key subjectKey; + + if (in.tag != DerValue.tag_Sequence) + throw new IOException ("corrupt private key"); + + BigInteger parsedVersion = in.data.getInteger().toBigInteger(); + if (!VERSION.equals(parsedVersion)) { + throw new IOException("version mismatch: (supported: " + + VERSION + ", parsed: " + + parsedVersion); + } + + algorithm = AlgorithmId.parse (in.data.getDerValue ()); + + try { + subjectKey = buildPKCS8Key (algorithm, in.data.getOctetString ()); + + } catch (InvalidKeyException e) { + throw new IOException("corrupt private key"); + } + + if (in.data.available () != 0) + throw new IOException ("excess private key"); + return subjectKey; } /** - * Parse the key bits. This may be redefined by subclasses to take advantage - * of structure within the key. For example, RSA public keys encapsulate two - * unsigned integers (modulus and exponent) as DER values within the - * <code>key</code> bits; Diffie-Hellman and DSS/DSA keys encapsulate a - * single unsigned integer. - * - * <P> - * This function is called when creating PKCS#8 SubjectPublicKeyInfo values - * using the PKCS8Key member functions, such as <code>parse</code> and - * <code>decode</code>. - * + * Parse the key bits. This may be redefined by subclasses to take + * advantage of structure within the key. For example, RSA public + * keys encapsulate two unsigned integers (modulus and exponent) as + * DER values within the <code>key</code> bits; Diffie-Hellman and + * DSS/DSA keys encapsulate a single unsigned integer. + * + * <P>This function is called when creating PKCS#8 SubjectPublicKeyInfo + * values using the PKCS8Key member functions, such as <code>parse</code> + * and <code>decode</code>. + * * @exception IOException if a parsing error occurs. * @exception InvalidKeyException if the key encoding is invalid. */ - protected void parseKeyBits() throws IOException, InvalidKeyException { - encode(); + protected void parseKeyBits () throws IOException, InvalidKeyException { + encode(); } /* - * Factory interface, building the kind of key associated with this specific - * algorithm ID or else returning this generic base class. See the - * description above. + * Factory interface, building the kind of key associated with this + * specific algorithm ID or else returning this generic base class. + * See the description above. */ - public static PKCS8Key buildPKCS8Key(AlgorithmId algid, byte[] key) - throws IOException, InvalidKeyException { - /* - * Use the algid and key parameters to produce the ASN.1 encoding of the - * key, which will then be used as the input to the key factory. - */ - DerOutputStream pkcs8EncodedKeyStream = new DerOutputStream(); - encode(pkcs8EncodedKeyStream, algid, key); - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec( - pkcs8EncodedKeyStream.toByteArray()); - - try { - // Instantiate the key factory of the appropriate algorithm - KeyFactory keyFac = KeyFactory.getInstance(algid.getName()); - - // Generate the private key - PrivateKey privKey = keyFac.generatePrivate(pkcs8KeySpec); - - if (privKey instanceof PKCS8Key) { - /* - * Return specialized PKCS8Key, where the structure within the - * key has been parsed - */ - return (PKCS8Key) privKey; - } - } catch (NoSuchAlgorithmException e) { - // Return generic PKCS8Key with opaque key data (see below) - } catch (InvalidKeySpecException e) { - // Return generic PKCS8Key with opaque key data (see below) - } - - /* - * Try again using JDK1.1-style for backwards compatibility. - */ - String classname = ""; - try { - Properties props; - String keytype; - Provider sunProvider; - - sunProvider = Security.getProvider("SUN"); - if (sunProvider == null) - throw new InstantiationException(); - classname = sunProvider.getProperty("PrivateKey.PKCS#8." - + algid.getName()); - if (classname == null) { - throw new InstantiationException(); - } - - Class keyClass = Class.forName(classname); - Object inst; - PKCS8Key result; - - inst = keyClass.newInstance(); - if (inst instanceof PKCS8Key) { - result = (PKCS8Key) inst; - result.algid = algid; - result.key = key; - result.parseKeyBits(); - return result; - } - } catch (ClassNotFoundException e) { - } catch (InstantiationException e) { - } catch (IllegalAccessException e) { - // this should not happen. - throw new IOException(classname + " [internal error]"); - } - - PKCS8Key result = new PKCS8Key(); - result.algid = algid; - result.key = key; - return result; + public static PKCS8Key buildPKCS8Key (AlgorithmId algid, byte[] key) + throws IOException, InvalidKeyException + { + /* + * Use the algid and key parameters to produce the ASN.1 encoding + * of the key, which will then be used as the input to the + * key factory. + */ + DerOutputStream pkcs8EncodedKeyStream = new DerOutputStream(); + encode(pkcs8EncodedKeyStream, algid, key); + PKCS8EncodedKeySpec pkcs8KeySpec + = new PKCS8EncodedKeySpec(pkcs8EncodedKeyStream.toByteArray()); + + try { + // Instantiate the key factory of the appropriate algorithm + KeyFactory keyFac = KeyFactory.getInstance(algid.getName()); + + // Generate the private key + PrivateKey privKey = keyFac.generatePrivate(pkcs8KeySpec); + + if (privKey instanceof PKCS8Key) { + /* + * Return specialized PKCS8Key, where the structure within the + * key has been parsed + */ + return (PKCS8Key)privKey; + } + } catch (NoSuchAlgorithmException e) { + // Return generic PKCS8Key with opaque key data (see below) + } catch (InvalidKeySpecException e) { + // Return generic PKCS8Key with opaque key data (see below) + } + + /* + * Try again using JDK1.1-style for backwards compatibility. + */ + String classname = ""; + try { + Properties props; + String keytype; + Provider sunProvider; + + sunProvider = Security.getProvider("SUN"); + if (sunProvider == null) + throw new InstantiationException(); + classname = sunProvider.getProperty("PrivateKey.PKCS#8." + + algid.getName()); + if (classname == null) { + throw new InstantiationException(); + } + + Class keyClass = Class.forName(classname); + Object inst; + PKCS8Key result; + + inst = keyClass.newInstance(); + if (inst instanceof PKCS8Key) { + result = (PKCS8Key) inst; + result.algid = algid; + result.key = key; + result.parseKeyBits(); + return result; + } + } catch (ClassNotFoundException e) { + } catch (InstantiationException e) { + } catch (IllegalAccessException e) { + // this should not happen. + throw new IOException (classname + " [internal error]"); + } + + PKCS8Key result = new PKCS8Key(); + result.algid = algid; + result.key = key; + return result; } /** * Returns the algorithm to be used with this key. */ - public String getAlgorithm() { - return algid.getName(); + public String getAlgorithm() { + return algid.getName(); } /** * Returns the algorithm ID to be used with this key. */ - public AlgorithmId getAlgorithmId() { - return algid; - } + public AlgorithmId getAlgorithmId () { return algid; } /** * PKCS#8 sequence on the DER output stream. */ - public final void encode(DerOutputStream out) throws IOException { - encode(out, this.algid, this.key); + public final void encode(DerOutputStream out) throws IOException + { + encode(out, this.algid, this.key); } /** * Returns the DER-encoded form of the key as a byte array. */ public synchronized byte[] getEncoded() { - byte[] result = null; - try { - result = encode(); - } catch (InvalidKeyException e) { - } - return result; + byte[] result = null; + try { + result = encode(); + } catch (InvalidKeyException e) { + } + return result; } /** * Returns the format for this key: "PKCS#8" */ public String getFormat() { - return "PKCS#8"; + return "PKCS#8"; } /** * Returns the DER-encoded form of the key as a byte array. - * + * * @exception InvalidKeyException if an encoding error occurs. */ public byte[] encode() throws InvalidKeyException { - if (encodedKey == null) { - try { - DerOutputStream out; - - out = new DerOutputStream(); - encode(out); - encodedKey = out.toByteArray(); - - } catch (IOException e) { - throw new InvalidKeyException("IOException : " + e.getMessage()); - } - } - return copyEncodedKey(encodedKey); + if (encodedKey == null) { + try { + DerOutputStream out; + + out = new DerOutputStream (); + encode (out); + encodedKey = out.toByteArray(); + + } catch (IOException e) { + throw new InvalidKeyException ("IOException : " + + e.getMessage()); + } + } + return copyEncodedKey(encodedKey); } /* * Returns a printable representation of the key */ - public String toString() { - netscape.security.util.PrettyPrintFormat pp = new netscape.security.util.PrettyPrintFormat( - " ", 20); - String keybits = pp.toHexString(key); - - return "algorithm = " + algid.toString() + ", unparsed keybits = \n" - + keybits; + public String toString () + { + netscape.security.util.PrettyPrintFormat pp = + new netscape.security.util.PrettyPrintFormat(" ", 20); + String keybits = pp.toHexString(key); + + return "algorithm = " + algid.toString () + + ", unparsed keybits = \n" + keybits; } - /** - * Initialize an PKCS8Key object from an input stream. The data on that - * input stream must be encoded using DER, obeying the PKCS#8 format: a - * sequence consisting of a version, an algorithm ID and a bit string which - * holds the key. (That bit string is often used to encapsulate another DER - * encoded sequence.) - * - * <P> - * Subclasses should not normally redefine this method; they should instead - * provide a <code>parseKeyBits</code> method to parse any fields inside the - * <code>key</code> member. - * - * @param in an input stream with a DER-encoded PKCS#8 SubjectPublicKeyInfo - * value - * + /** + * Initialize an PKCS8Key object from an input stream. The data + * on that input stream must be encoded using DER, obeying the + * PKCS#8 format: a sequence consisting of a version, an algorithm + * ID and a bit string which holds the key. (That bit string is + * often used to encapsulate another DER encoded sequence.) + * + * <P>Subclasses should not normally redefine this method; they should + * instead provide a <code>parseKeyBits</code> method to parse any + * fields inside the <code>key</code> member. + * + * @param in an input stream with a DER-encoded PKCS#8 + * SubjectPublicKeyInfo value + * * @exception InvalidKeyException if a parsing error occurs. */ - public void decode(InputStream in) throws InvalidKeyException { - DerValue val; - - try { - val = new DerValue(in); - if (val.tag != DerValue.tag_Sequence) - throw new InvalidKeyException("invalid key format"); - - BigInteger version = val.data.getInteger().toBigInteger(); - if (!version.equals(PKCS8Key.VERSION)) { - throw new IOException("version mismatch: (supported: " - + PKCS8Key.VERSION + ", parsed: " + version); - } - algid = AlgorithmId.parse(val.data.getDerValue()); - key = val.data.getOctetString(); - parseKeyBits(); - if (val.data.available() != 0) - throw new InvalidKeyException("excess key data"); - - } catch (IOException e) { - // e.printStackTrace (); - throw new InvalidKeyException("IOException : " + e.getMessage()); - } + public void decode(InputStream in) throws InvalidKeyException + { + DerValue val; + + try { + val = new DerValue (in); + if (val.tag != DerValue.tag_Sequence) + throw new InvalidKeyException ("invalid key format"); + + + BigInteger version = val.data.getInteger().toBigInteger(); + if (!version.equals(PKCS8Key.VERSION)) { + throw new IOException("version mismatch: (supported: " + + PKCS8Key.VERSION + ", parsed: " + + version); + } + algid = AlgorithmId.parse (val.data.getDerValue ()); + key = val.data.getOctetString (); + parseKeyBits (); + if (val.data.available () != 0) + throw new InvalidKeyException ("excess key data"); + + } catch (IOException e) { + // e.printStackTrace (); + throw new InvalidKeyException("IOException : " + + e.getMessage()); + } } public void decode(byte[] encodedKey) throws InvalidKeyException { - decode(new ByteArrayInputStream(encodedKey)); + decode(new ByteArrayInputStream(encodedKey)); } /** - * Serialization write ... PKCS#8 keys serialize as themselves, and they're - * parsed when they get read back. + * Serialization write ... PKCS#8 keys serialize as + * themselves, and they're parsed when they get read back. */ - private synchronized void writeObject(java.io.ObjectOutputStream stream) - throws IOException { - stream.write(getEncoded()); + private synchronized void + writeObject (java.io.ObjectOutputStream stream) + throws IOException { + stream.write(getEncoded()); } /** - * Serialization read ... PKCS#8 keys serialize as themselves, and they're - * parsed when they get read back. + * Serialization read ... PKCS#8 keys serialize as + * themselves, and they're parsed when they get read back. */ - private synchronized void readObject(ObjectInputStream stream) - throws IOException { + private synchronized void readObject (ObjectInputStream stream) + throws IOException { - try { - decode(stream); + try { + decode(stream); - } catch (InvalidKeyException e) { - e.printStackTrace(); - throw new IOException("deserialized key is invalid: " - + e.getMessage()); - } + } catch (InvalidKeyException e) { + e.printStackTrace(); + throw new IOException("deserialized key is invalid: " + + e.getMessage()); + } } /* * Make a copy of the encoded key. */ private byte[] copyEncodedKey(byte[] encodedKey) { - int len = encodedKey.length; - byte[] copy = new byte[len]; - System.arraycopy(encodedKey, 0, copy, 0, len); - return copy; + int len = encodedKey.length; + byte[] copy = new byte[len]; + System.arraycopy(encodedKey, 0, copy, 0, len); + return copy; } /* * Produce PKCS#8 encoding from algorithm id and key material. */ static void encode(DerOutputStream out, AlgorithmId algid, byte[] key) - throws IOException { - DerOutputStream tmp = new DerOutputStream(); - tmp.putInteger(new BigInt(VERSION.toByteArray())); - algid.encode(tmp); - tmp.putOctetString(key); - out.write(DerValue.tag_Sequence, tmp); + throws IOException { + DerOutputStream tmp = new DerOutputStream(); + tmp.putInteger(new BigInt(VERSION.toByteArray())); + algid.encode(tmp); + tmp.putOctetString(key); + out.write(DerValue.tag_Sequence, tmp); } /** - * Compares two private keys. This returns false if the object with which to - * compare is not of type <code>Key</code>. Otherwise, the encoding of this - * key object is compared with the encoding of the given key object. - * + * Compares two private keys. This returns false if the object with which + * to compare is not of type <code>Key</code>. + * Otherwise, the encoding of this key object is compared with the + * encoding of the given key object. + * * @param object the object with which to compare - * @return <code>true</code> if this key has the same encoding as the object - * argument; <code>false</code> otherwise. + * @return <code>true</code> if this key has the same encoding as the + * object argument; <code>false</code> otherwise. */ public boolean equals(Object object) { - if (this == object) { - return true; - } - - if (object instanceof Key) { - - // this encoding - byte[] b1; - if (encodedKey != null) { - b1 = encodedKey; - } else { - b1 = getEncoded(); - } - - // that encoding - byte[] b2 = ((Key) object).getEncoded(); - - // do the comparison - int i; - if (b1.length != b2.length) - return false; - for (i = 0; i < b1.length; i++) { - if (b1[i] != b2[i]) { - return false; - } - } - return true; - } - - return false; + if (this == object) { + return true; + } + + if (object instanceof Key) { + + // this encoding + byte[] b1; + if (encodedKey != null) { + b1 = encodedKey; + } else { + b1 = getEncoded(); + } + + // that encoding + byte[] b2 = ((Key)object).getEncoded(); + + // do the comparison + int i; + if (b1.length != b2.length) + return false; + for (i = 0; i < b1.length; i++) { + if (b1[i] != b2[i]) { + return false; + } + } + return true; + } + + return false; } /** - * Calculates a hash code value for this object. Objects which are equal - * will also have the same hashcode. + * Calculates a hash code value for this object. Objects + * which are equal will also have the same hashcode. */ public int hashCode() { int retval = 0; - byte[] b1 = getEncoded(); + byte[] b1 = getEncoded(); for (int i = 1; i < b1.length; i++) { retval += b1[i] * i; } - return (retval); + return(retval); } } diff --git a/pki/base/util/src/netscape/security/pkcs/PKCS9Attribute.java b/pki/base/util/src/netscape/security/pkcs/PKCS9Attribute.java index 01278f975..683514a7f 100644 --- a/pki/base/util/src/netscape/security/pkcs/PKCS9Attribute.java +++ b/pki/base/util/src/netscape/security/pkcs/PKCS9Attribute.java @@ -31,10 +31,10 @@ import netscape.security.util.ObjectIdentifier; import netscape.security.x509.CertificateExtensions; /** - * Class supporting any PKCS9 attribute except ExtendedCertificateAttribute. - * Supports DER decoding and access to attribute values, but not DER encoding or - * setting of values. - * + * Class supporting any PKCS9 attribute except + * ExtendedCertificateAttribute. Supports DER decoding and access to + * attribute values, but not DER encoding or setting of values. + * * @version 1.2 97/12/10 * @author Douglas Hoover */ @@ -50,17 +50,17 @@ public class PKCS9Attribute implements DerEncoder { /** * Array of attribute OIDs defined in PKCS9, by number. */ - static final ObjectIdentifier[] PKCS9_OIDS = - // new ObjectIdentifier[10]; - // There are some Obsolete(?) attribute identifiers. - // This is mainly for extensionRequest (14) in pkcs10. - // We just add the other 4 as by products. - new ObjectIdentifier[15]; - - static { // static initializer for PKCS9_OIDS - for (int i = 1; i < PKCS9_OIDS.length; i++) { - PKCS9_OIDS[i] = new ObjectIdentifier(PKCS9_str + "." + i); - } + static final ObjectIdentifier[] PKCS9_OIDS = + //new ObjectIdentifier[10]; + // There are some Obsolete(?) attribute identifiers. + // This is mainly for extensionRequest (14) in pkcs10. + // We just add the other 4 as by products. + new ObjectIdentifier[15]; + + static { // static initializer for PKCS9_OIDS + for (int i = 1; i < PKCS9_OIDS.length; i++) { + PKCS9_OIDS[i] = new ObjectIdentifier(PKCS9_str + "." + i); + } } public static final ObjectIdentifier EMAIL_ADDRESS_OID = PKCS9_OIDS[1]; @@ -71,13 +71,19 @@ public class PKCS9Attribute implements DerEncoder { public static final ObjectIdentifier COUNTERSIGNATURE_OID = PKCS9_OIDS[6]; public static final ObjectIdentifier CHALLENGE_PASSWORD_OID = PKCS9_OIDS[7]; public static final ObjectIdentifier UNSTRUCTURED_ADDRESS_OID = PKCS9_OIDS[8]; - public static final ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID = PKCS9_OIDS[9]; - - public static final ObjectIdentifier ISSUER_AND_SERIALNUMBER_OID = PKCS9_OIDS[10]; - public static final ObjectIdentifier PASSWORD_CHECK_OID = PKCS9_OIDS[11]; - public static final ObjectIdentifier PUBLIC_KEY_OID = PKCS9_OIDS[12]; - public static final ObjectIdentifier SIGNING_DESCRIPTION_OID = PKCS9_OIDS[13]; - public static final ObjectIdentifier EXTENSION_REQUEST_OID = PKCS9_OIDS[14]; + public static final ObjectIdentifier + EXTENDED_CERTIFICATE_ATTRIBUTES_OID = PKCS9_OIDS[9]; + + public static final ObjectIdentifier + ISSUER_AND_SERIALNUMBER_OID = PKCS9_OIDS[10]; + public static final ObjectIdentifier + PASSWORD_CHECK_OID = PKCS9_OIDS[11]; + public static final ObjectIdentifier + PUBLIC_KEY_OID = PKCS9_OIDS[12]; + public static final ObjectIdentifier + SIGNING_DESCRIPTION_OID = PKCS9_OIDS[13]; + public static final ObjectIdentifier + EXTENSION_REQUEST_OID = PKCS9_OIDS[14]; public static final String EMAIL_ADDRESS_STR = "EmailAddress"; public static final String UNSTRUCTURED_NAME_STR = "UnstructuredName"; @@ -87,1035 +93,1054 @@ public class PKCS9Attribute implements DerEncoder { public static final String COUNTERSIGNATURE_STR = "Countersignature"; public static final String CHALLENGE_PASSWORD_STR = "ChallengePassword"; public static final String UNSTRUCTURED_ADDRESS_STR = "UnstructuredAddress"; - public static final String EXTENDED_CERTIFICATE_ATTRIBUTES_STR = "ExtendedCertificateAttributes"; - - public static final String ISSUER_AND_SERIALNUMBER_STR = "IssuerAndSerialNumber"; - public static final String PASSWORD_CHECK_STR = "PasswordCheck"; - public static final String PUBLIC_KEY_STR = "PublicKey"; - public static final String SIGNING_DESCRIPTION_STR = "SigningDescription"; - public static final String EXTENSION_REQUEST_STR = "ExtensionRequest"; - - /** - * Hashtable mapping names and variant names of supported attributes to - * their OIDs. This table contains all name forms that occur in PKCS9, in - * lower case. + public static final String + EXTENDED_CERTIFICATE_ATTRIBUTES_STR = "ExtendedCertificateAttributes"; + + public static final String + ISSUER_AND_SERIALNUMBER_STR = "IssuerAndSerialNumber"; + public static final String + PASSWORD_CHECK_STR = "PasswordCheck"; + public static final String + PUBLIC_KEY_STR = "PublicKey"; + public static final String + SIGNING_DESCRIPTION_STR = "SigningDescription"; + public static final String + EXTENSION_REQUEST_STR = "ExtensionRequest"; + + /** + * Hashtable mapping names and variant names of supported + * attributes to their OIDs. This table contains all name forms + * that occur in PKCS9, in lower case. */ private static final Hashtable NAME_OID_TABLE = new Hashtable(28); static { // static initializer for PCKS9_NAMES - NAME_OID_TABLE.put("emailaddress", PKCS9_OIDS[1]); - NAME_OID_TABLE.put("unstructuredname", PKCS9_OIDS[2]); - NAME_OID_TABLE.put("contenttype", PKCS9_OIDS[3]); - NAME_OID_TABLE.put("messagedigest", PKCS9_OIDS[4]); - NAME_OID_TABLE.put("signingtime", PKCS9_OIDS[5]); - NAME_OID_TABLE.put("countersignature", PKCS9_OIDS[6]); - NAME_OID_TABLE.put("challengepassword", PKCS9_OIDS[7]); - NAME_OID_TABLE.put("unstructuredaddress", PKCS9_OIDS[8]); - NAME_OID_TABLE.put("extendedcertificateattributes", PKCS9_OIDS[9]); - - NAME_OID_TABLE.put("issuerandserialNumber", PKCS9_OIDS[10]); - NAME_OID_TABLE.put("passwordcheck", PKCS9_OIDS[11]); - NAME_OID_TABLE.put("publickey", PKCS9_OIDS[12]); - NAME_OID_TABLE.put("signingdescription", PKCS9_OIDS[13]); - NAME_OID_TABLE.put("extensionrequest", PKCS9_OIDS[14]); + NAME_OID_TABLE.put("emailaddress", PKCS9_OIDS[1]); + NAME_OID_TABLE.put("unstructuredname", PKCS9_OIDS[2]); + NAME_OID_TABLE.put("contenttype", PKCS9_OIDS[3]); + NAME_OID_TABLE.put("messagedigest", PKCS9_OIDS[4]); + NAME_OID_TABLE.put("signingtime", PKCS9_OIDS[5]); + NAME_OID_TABLE.put("countersignature", PKCS9_OIDS[6]); + NAME_OID_TABLE.put("challengepassword", PKCS9_OIDS[7]); + NAME_OID_TABLE.put("unstructuredaddress", PKCS9_OIDS[8]); + NAME_OID_TABLE.put("extendedcertificateattributes", PKCS9_OIDS[9]); + + NAME_OID_TABLE.put("issuerandserialNumber", PKCS9_OIDS[10]); + NAME_OID_TABLE.put("passwordcheck", PKCS9_OIDS[11]); + NAME_OID_TABLE.put("publickey", PKCS9_OIDS[12]); + NAME_OID_TABLE.put("signingdescription", PKCS9_OIDS[13]); + NAME_OID_TABLE.put("extensionrequest", PKCS9_OIDS[14]); }; /** - * Hashtable mapping attribute OIDs defined in PKCS9 to the corresponding - * attribute value type. + * Hashtable mapping attribute OIDs defined in PKCS9 to the + * corresponding attribute value type. */ private static final Hashtable OID_NAME_TABLE = new Hashtable(14); - static { - OID_NAME_TABLE.put(PKCS9_OIDS[1], EMAIL_ADDRESS_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[2], UNSTRUCTURED_NAME_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[3], CONTENT_TYPE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[4], MESSAGE_DIGEST_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[5], SIGNING_TIME_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[6], COUNTERSIGNATURE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[7], CHALLENGE_PASSWORD_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[8], UNSTRUCTURED_ADDRESS_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[9], EXTENDED_CERTIFICATE_ATTRIBUTES_STR); - - OID_NAME_TABLE.put(PKCS9_OIDS[10], ISSUER_AND_SERIALNUMBER_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[11], PASSWORD_CHECK_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[12], PUBLIC_KEY_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[13], SIGNING_DESCRIPTION_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[14], EXTENSION_REQUEST_STR); + static { + OID_NAME_TABLE.put(PKCS9_OIDS[1], EMAIL_ADDRESS_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[2], UNSTRUCTURED_NAME_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[3], CONTENT_TYPE_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[4], MESSAGE_DIGEST_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[5], SIGNING_TIME_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[6], COUNTERSIGNATURE_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[7], CHALLENGE_PASSWORD_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[8], UNSTRUCTURED_ADDRESS_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[9], EXTENDED_CERTIFICATE_ATTRIBUTES_STR); + + OID_NAME_TABLE.put(PKCS9_OIDS[10], ISSUER_AND_SERIALNUMBER_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[11], PASSWORD_CHECK_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[12], PUBLIC_KEY_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[13], SIGNING_DESCRIPTION_STR); + OID_NAME_TABLE.put(PKCS9_OIDS[14], EXTENSION_REQUEST_STR); } /** - * Acceptable ASN.1 tags for DER encodings of values of PKCS9 attributes, by - * index in <code>PKCS9_OIDS</code>. Sets of acceptable tags are represented - * as arrays. + * Acceptable ASN.1 tags for DER encodings of values of PKCS9 + * attributes, by index in <code>PKCS9_OIDS</code>. + * Sets of acceptable tags are represented as arrays. */ private static final Byte[][] PKCS9_VALUE_TAGS = { - null, - { Byte.valueOf(DerValue.tag_IA5String) }, // EMailAddress - { Byte.valueOf(DerValue.tag_IA5String) }, // UnstructuredName - { Byte.valueOf(DerValue.tag_ObjectId) }, // ContentType - { Byte.valueOf(DerValue.tag_OctetString) }, // MessageDigest - { Byte.valueOf(DerValue.tag_UtcTime) }, // SigningTime - { Byte.valueOf(DerValue.tag_Sequence) }, // Countersignature - { Byte.valueOf(DerValue.tag_PrintableString), - Byte.valueOf(DerValue.tag_T61String) }, // ChallengePassword - { Byte.valueOf(DerValue.tag_PrintableString), - Byte.valueOf(DerValue.tag_T61String) }, // UnstructuredAddress - { Byte.valueOf(DerValue.tag_SetOf) }, // ExtendedCertificateAttributes - - null, // IssuerAndSerialNumber - null, // PasswordCheck - null, // PublicKey - null, // SigningDescription - { Byte.valueOf(DerValue.tag_Sequence) } // ExtensionRequest + null, + {Byte.valueOf(DerValue.tag_IA5String)}, // EMailAddress + {Byte.valueOf(DerValue.tag_IA5String)}, // UnstructuredName + {Byte.valueOf(DerValue.tag_ObjectId)}, // ContentType + {Byte.valueOf(DerValue.tag_OctetString)}, // MessageDigest + {Byte.valueOf(DerValue.tag_UtcTime)}, // SigningTime + {Byte.valueOf(DerValue.tag_Sequence)}, // Countersignature + {Byte.valueOf(DerValue.tag_PrintableString), + Byte.valueOf(DerValue.tag_T61String)}, // ChallengePassword + {Byte.valueOf(DerValue.tag_PrintableString), + Byte.valueOf(DerValue.tag_T61String)}, // UnstructuredAddress + {Byte.valueOf(DerValue.tag_SetOf)}, // ExtendedCertificateAttributes + + null, //IssuerAndSerialNumber + null, //PasswordCheck + null, //PublicKey + null, //SigningDescription + {Byte.valueOf(DerValue.tag_Sequence)} //ExtensionRequest }; - /** - * Class types required for values for a given PKCS9 attribute type. - * - * <P> - * The following table shows the correspondence between attribute types and - * value component classes. - * + /** + * Class types required for values for a given PKCS9 + * attribute type. + * + * <P> The following table shows the correspondence between + * attribute types and value component classes. + * * <P> * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER> - * + * * <TR> * <TH>OID</TH> * <TH>Attribute Type Name</TH> * <TH>Kind</TH> * <TH>Value Class</TH> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.1</TD> * <TD>EmailAddress</TD> * <TD>Multiple-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.2</TD> * <TD>UnstructuredName</TD> * <TD>Multiple-valued</TD> * <TD><code>String</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.3</TD> * <TD>ContentType</TD> * <TD>Single-valued</TD> * <TD><code>ObjectIdentifier</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.4</TD> * <TD>MessageDigest</TD> * <TD>Single-valued</TD> * <TD><code>byte[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.5</TD> * <TD>SigningTime</TD> * <TD>Single-valued</TD> * <TD><code>Date</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.6</TD> * <TD>Countersignature</TD> * <TD>Multiple-valued</TD> * <TD><code>SignerInfo</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.7</TD> * <TD>ChallengePassword</TD> * <TD>Single-valued</TD> * <TD><code>String</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.8</TD> * <TD>UnstructuredAddress</TD> * <TD>Single-valued</TD> * <TD><code>String</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.9</TD> * <TD>ExtendedCertificateAttributes</TD> * <TD>Multiple-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.10</TD> * <TD>IssuerAndSerialNumber</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.11</TD> * <TD>PasswordCheck</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.12</TD> * <TD>PublicKey</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.13</TD> * <TD>SigningDescription</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.14</TD> * <TD>ExtensionRequest</TD> * <TD>Single-valued</TD> * <TD><code>Sequence</code></TD> * </TR> - * + * * </TABLE> */ private static final Class[] VALUE_CLASSES = new Class[15]; static { - try { - Class str = Class.forName("[Ljava.lang.String;"); - - VALUE_CLASSES[0] = null; // not used - VALUE_CLASSES[1] = str; // EMailAddress - VALUE_CLASSES[2] = str; // UnstructuredName - VALUE_CLASSES[3] = // ContentType - Class.forName("netscape.security.util.ObjectIdentifier"); - VALUE_CLASSES[4] = Class.forName("[B"); // MessageDigest (byte[]) - VALUE_CLASSES[5] = Class.forName("java.util.Date"); // SigningTime - VALUE_CLASSES[6] = // Countersignature - Class.forName("[Lnetscape.security.pkcs.SignerInfo;"); - VALUE_CLASSES[7] = // ChallengePassword - Class.forName("java.lang.String"); - VALUE_CLASSES[8] = str; // UnstructuredAddress - VALUE_CLASSES[9] = null; // ExtendedCertificateAttributes - - VALUE_CLASSES[10] = null; // IssuerAndSerialNumber - VALUE_CLASSES[11] = null; // PasswordCheck - VALUE_CLASSES[12] = null; // PublicKey - VALUE_CLASSES[13] = null; // SigningDescription - VALUE_CLASSES[14] = // ExtensionRequest - Class.forName("netscape.security.x509.CertificateExtensions"); // xxxx - } catch (ClassNotFoundException e) { - throw new ExceptionInInitializerError(e.toString()); - } + try { + Class str = Class.forName("[Ljava.lang.String;"); + + VALUE_CLASSES[0] = null; // not used + VALUE_CLASSES[1] = str; // EMailAddress + VALUE_CLASSES[2] = str; // UnstructuredName + VALUE_CLASSES[3] = // ContentType + Class.forName("netscape.security.util.ObjectIdentifier"); + VALUE_CLASSES[4] = Class.forName("[B"); // MessageDigest (byte[]) + VALUE_CLASSES[5] = Class.forName("java.util.Date"); // SigningTime + VALUE_CLASSES[6] = // Countersignature + Class.forName("[Lnetscape.security.pkcs.SignerInfo;"); + VALUE_CLASSES[7] = // ChallengePassword + Class.forName("java.lang.String"); + VALUE_CLASSES[8] = str; // UnstructuredAddress + VALUE_CLASSES[9] = null; // ExtendedCertificateAttributes + + VALUE_CLASSES[10] = null; // IssuerAndSerialNumber + VALUE_CLASSES[11] = null; // PasswordCheck + VALUE_CLASSES[12] = null; // PublicKey + VALUE_CLASSES[13] = null; // SigningDescription + VALUE_CLASSES[14] = // ExtensionRequest + Class.forName("netscape.security.x509.CertificateExtensions"); //xxxx + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError(e.toString()); + } } /** - * Array indicating which PKCS9 attributes are single-valued, by index in - * <code>PKCS9_OIDS</code>. + * Array indicating which PKCS9 attributes are single-valued, + * by index in <code>PKCS9_OIDS</code>. */ - private static final boolean[] SINGLE_VALUED = { false, false, // EMailAddress - false, // UnstructuredName - true, // ContentType - true, // MessageDigest - true, // SigningTime - false, // Countersignature - true, // ChallengePassword - false, // UnstructuredAddress - false, // ExtendedCertificateAttributes - - true, // IssuerAndSerialNumber - true, // PasswordCheck - true, // PublicKey - true, // SigningDescription - true // ExtensionRequest + private static final boolean[] SINGLE_VALUED = + { false, + false, // EMailAddress + false, // UnstructuredName + true, // ContentType + true, // MessageDigest + true, // SigningTime + false, // Countersignature + true, // ChallengePassword + false, // UnstructuredAddress + false, // ExtendedCertificateAttributes + + true, // IssuerAndSerialNumber + true, // PasswordCheck + true, // PublicKey + true, // SigningDescription + true // ExtensionRequest }; /** * The OID of this attribute is <code>PKCS9_OIDS[index]</code>. */ private int index; - + /** - * Value set of this attribute. Its class is given by + * Value set of this attribute. Its class is given by * <code>VALUE_CLASSES[index]</code>. */ private Object value; - /** - * Construct an attribute object from the attribute's OID and value. If the - * attribute is single-valued, provide only one value. If the attribute is - * multiple-valued, provide an array containing all the values. Arrays of - * length zero are accepted, though probably useless. - * - * <P> - * The following table gives the class that <code>value</code> must have for - * a given attribute. - * + /** + * Construct an attribute object from the attribute's OID and + * value. If the attribute is single-valued, provide only one + * value. If the attribute is + * multiple-valued, provide an array containing all the values. + * Arrays of length zero are accepted, though probably useless. + * + * <P> The following table gives the class that <code>value</code> + * must have for a given attribute. + * * <P> * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER> - * + * * <TR> * <TH>OID</TH> * <TH>Attribute Type Name</TH> * <TH>Kind</TH> * <TH>Value Class</TH> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.1</TD> * <TD>EmailAddress</TD> * <TD>Multiple-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.2</TD> * <TD>UnstructuredName</TD> * <TD>Multiple-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.3</TD> * <TD>ContentType</TD> * <TD>Single-valued</TD> * <TD><code>ObjectIdentifier</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.4</TD> * <TD>MessageDigest</TD> * <TD>Single-valued</TD> * <TD><code>byte[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.5</TD> * <TD>SigningTime</TD> * <TD>Single-valued</TD> * <TD><code>Date</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.6</TD> * <TD>Countersignature</TD> * <TD>Multiple-valued</TD> * <TD><code>SignerInfo[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.7</TD> * <TD>ChallengePassword</TD> * <TD>Single-valued</TD> * <TD><code>String</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.8</TD> * <TD>UnstructuredAddress</TD> * <TD>Single-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.9</TD> * <TD>ExtendedCertificateAttributes</TD> * <TD>Multiple-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.10</TD> * <TD>IssuerAndSerialNumber</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.11</TD> * <TD>PasswordCheck</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.12</TD> * <TD>PublicKey</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.13</TD> * <TD>SigningDescription</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.14</TD> * <TD>ExtensionRequest</TD> * <TD>Single-valued</TD> * <TD><code>Sequence</code></TD> * </TR> - * + * * </TABLE> */ - public PKCS9Attribute(ObjectIdentifier oid, Object value) - throws IllegalArgumentException { + public PKCS9Attribute(ObjectIdentifier oid, Object value) + throws IllegalArgumentException { - init(oid, value); + init(oid, value); } - /** - * Construct an attribute object from the attribute's name and value. If the - * attribute is single-valued, provide only one value. If the attribute is - * multiple-valued, provide an array containing all the values. Arrays of - * length zero are accepted, though probably useless. - * - * <P> - * The following table gives the class that <code>value</code> must have for - * a given attribute. Reasonable variants of these attributes are accepted; - * in particular, case does not matter. - * + /** + * Construct an attribute object from the attribute's name and + * value. If the attribute is single-valued, provide only one + * value. If the attribute is + * multiple-valued, provide an array containing all the values. + * Arrays of length zero are accepted, though probably useless. + * + * <P> The following table gives the class that <code>value</code> + * must have for a given attribute. Reasonable variants of these + * attributes are accepted; in particular, case does not matter. + * * <P> * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER> - * + * * <TR> * <TH>OID</TH> * <TH>Attribute Type Name</TH> * <TH>Kind</TH> * <TH>Value Class</TH> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.1</TD> * <TD>EmailAddress</TD> * <TD>Multiple-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.2</TD> * <TD>UnstructuredName</TD> * <TD>Multiple-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.3</TD> * <TD>ContentType</TD> * <TD>Single-valued</TD> * <TD><code>ObjectIdentifier</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.4</TD> * <TD>MessageDigest</TD> * <TD>Single-valued</TD> * <TD><code>byte[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.5</TD> * <TD>SigningTime</TD> * <TD>Single-valued</TD> * <TD><code>Date</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.6</TD> * <TD>Countersignature</TD> * <TD>Multiple-valued</TD> * <TD><code>SignerInfo[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.7</TD> * <TD>ChallengePassword</TD> * <TD>Single-valued</TD> * <TD><code>String</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.8</TD> * <TD>UnstructuredAddress</TD> * <TD>Single-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.9</TD> * <TD>ExtendedCertificateAttributes</TD> * <TD>Multiple-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.10</TD> * <TD>IssuerAndSerialNumber</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.11</TD> * <TD>PasswordCheck</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.12</TD> * <TD>PublicKey</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.13</TD> * <TD>SigningDescription</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.14</TD> * <TD>ExtensionRequest</TD> * <TD>Single-valued</TD> * <TD><code>Sequence</code></TD> * </TR> - * + * * </TABLE> - * - * @exception IllegalArgumentException if the <code>name</code> is not - * recognized of the <code>value</code> has the wrong type. + * + * @exception IllegalArgumentException + * if the <code>name</code> is not recognized of the + * <code>value</code> has the wrong type. */ - public PKCS9Attribute(String name, Object value) - throws IllegalArgumentException { - ObjectIdentifier oid = getOID(name); + public PKCS9Attribute(String name, Object value) + throws IllegalArgumentException { + ObjectIdentifier oid = getOID(name); - if (oid == null) - throw new IllegalArgumentException("Unrecognized attribute name " - + name + " constructing PKCS9Attribute."); + if (oid == null) + throw new IllegalArgumentException( + "Unrecognized attribute name " + name + + " constructing PKCS9Attribute."); - init(oid, value); + init(oid,value); } - private void init(ObjectIdentifier oid, Object value) - throws IllegalArgumentException { - - index = indexOf(oid, PKCS9_OIDS, 1); - - if (index == -1) - throw new IllegalArgumentException("Unsupported OID " + oid - + " constructing PKCS9Attribute."); - - if (!VALUE_CLASSES[index].isInstance(value)) - throw new IllegalArgumentException("Wrong value class " - + " for attribute " + oid - + " constructing PKCS9Attribute; was " - + value.getClass().toString() + ", should be " - + VALUE_CLASSES[index].toString()); - - this.value = value; + private void init(ObjectIdentifier oid, Object value) + throws IllegalArgumentException { + + index = indexOf(oid,PKCS9_OIDS,1); + + if (index == -1) + throw new IllegalArgumentException( + "Unsupported OID " + oid + + " constructing PKCS9Attribute."); + + if (!VALUE_CLASSES[index].isInstance(value)) + throw new IllegalArgumentException( + "Wrong value class " + + " for attribute " + oid + + " constructing PKCS9Attribute; was " + + value.getClass().toString() + ", should be " + + VALUE_CLASSES[index].toString()); + + this.value = value; } - /** - * Construct a PKCS9Attribute from its encoding on an input stream. - * + + /** + * Construct a PKCS9Attribute from its encoding on an input + * stream. + * * @exception IOException on parsing error. */ public PKCS9Attribute(DerValue derVal) throws IOException { - decode(derVal); + decode(derVal); } /** * Decode a PKCS9 attribute. - * - * @param val the DerValue representing the DER encoding of the attribute. + * + * @param val + * the DerValue representing the DER encoding of the attribute. */ private void decode(DerValue derVal) throws IOException { - DerInputStream derIn = new DerInputStream(derVal.toByteArray()); - DerValue[] val = derIn.getSequence(2); - - if (derIn.available() != 0) - throw new IOException("Excess data parsing PKCS9Attribute"); - - if (val.length != 2) - throw new IOException("PKCS9Attribute doesn't have two components"); - - DerValue[] elems; - - // get the oid - ObjectIdentifier oid = val[0].getOID(); - - index = indexOf(oid, PKCS9_OIDS, 1); - Byte tag; - - if (index == -1) - throw new IOException("Invalid OID for PKCS9 attribute: " + oid); - - elems = new DerInputStream(val[1].toByteArray()).getSet(1); - - // check single valued have only one value - if (SINGLE_VALUED[index] && elems.length > 1) - throwSingleValuedException(); - - // check for illegal element tags - for (int i = 0; i < elems.length; i++) { - tag = Byte.valueOf(elems[i].tag); - - if (indexOf(tag, PKCS9_VALUE_TAGS[index], 0) == -1) - throwTagException(tag); - } - - switch (index) { - case 1: // email address - case 2: // unstructured name - case 8: // unstructured address - { // open scope - String[] values = new String[elems.length]; - - for (int i = 0; i < elems.length; i++) - values[i] = elems[i].getAsString(); - value = values; - } // close scope - break; - - case 3: // content type - value = elems[0].getOID(); - break; - - case 4: // message digest - value = elems[0].getOctetString(); - break; - - case 5: // signing time - value = (new DerInputStream(elems[0].toByteArray())).getUTCTime(); - break; - - case 6: // countersignature - { // open scope - SignerInfo[] values = new SignerInfo[elems.length]; - for (int i = 0; i < elems.length; i++) - values[i] = new SignerInfo(elems[i].toDerInputStream()); - value = values; - } // close scope - break; - - case 7: // challenge password - value = elems[0].getAsString(); - break; - - case 9: // extended-certificate attribute -- not - // supported - throw new IOException("PKCS9 extended-certificate " - + "attribute not supported."); - - case 10: // IssuerAndSerialNumber attribute -- not - // supported - throw new IOException("PKCS9 IssuerAndSerialNumber " - + "attribute not supported."); - - case 11: // passwordCheck attribute -- not - // supported - throw new IOException("PKCS9 passwordCheck " - + "attribute not supported."); - case 12: // PublicKey attribute -- not - // supported - throw new IOException("PKCS9 PublicKey " - + "attribute not supported."); - case 13: // SigningDescription attribute -- not - // supported - throw new IOException("PKCS9 SigningDescription " - + "attribute not supported."); - case 14: // ExtensionRequest attribute - value = new CertificateExtensions(elems[0].toDerInputStream()); - - // break unnecessary - - default: // can't happen - } + DerInputStream derIn = new DerInputStream(derVal.toByteArray()); + DerValue[] val = derIn.getSequence(2); + + if (derIn.available() != 0) + throw new IOException("Excess data parsing PKCS9Attribute"); + + if (val.length != 2) + throw new IOException("PKCS9Attribute doesn't have two components"); + + DerValue[] elems; + + // get the oid + ObjectIdentifier oid = val[0].getOID(); + + index = indexOf(oid,PKCS9_OIDS,1); + Byte tag; + + if (index == -1) + throw new IOException("Invalid OID for PKCS9 attribute: " + + oid); + + elems = new DerInputStream(val[1].toByteArray()).getSet(1); + + // check single valued have only one value + if (SINGLE_VALUED[index] && elems.length > 1) + throwSingleValuedException(); + + // check for illegal element tags + for (int i=0; i < elems.length; i++) { + tag = Byte.valueOf(elems[i].tag); + + if (indexOf(tag, PKCS9_VALUE_TAGS[index], 0) == -1) + throwTagException(tag); + } + + switch (index) { + case 1: // email address + case 2: // unstructured name + case 8: // unstructured address + { // open scope + String[] values = new String[elems.length]; + + for (int i=0; i < elems.length; i++) + values[i] = elems[i].getAsString(); + value = values; + } // close scope + break; + + case 3: // content type + value = elems[0].getOID(); + break; + + case 4: // message digest + value = elems[0].getOctetString(); + break; + + case 5: // signing time + value = (new DerInputStream(elems[0].toByteArray())).getUTCTime(); + break; + + case 6: // countersignature + { // open scope + SignerInfo[] values = new SignerInfo[elems.length]; + for (int i=0; i < elems.length; i++) + values[i] = + new SignerInfo(elems[i].toDerInputStream()); + value = values; + } // close scope + break; + + case 7: // challenge password + value = elems[0].getAsString(); + break; + + case 9: // extended-certificate attribute -- not + // supported + throw new IOException("PKCS9 extended-certificate " + + "attribute not supported."); + + case 10: // IssuerAndSerialNumber attribute -- not + // supported + throw new IOException("PKCS9 IssuerAndSerialNumber " + + "attribute not supported."); + + case 11: // passwordCheck attribute -- not + // supported + throw new IOException("PKCS9 passwordCheck " + + "attribute not supported."); + case 12: // PublicKey attribute -- not + // supported + throw new IOException("PKCS9 PublicKey " + + "attribute not supported."); + case 13: // SigningDescription attribute -- not + // supported + throw new IOException("PKCS9 SigningDescription " + + "attribute not supported."); + case 14: // ExtensionRequest attribute + value = + new CertificateExtensions(elems[0].toDerInputStream()); + + // break unnecessary + + default: // can't happen + } } /** * Write the DER encoding of this attribute to an output stream. * - * <P> - * N.B.: This method always encodes values of ChallengePassword and - * UnstructuredAddress attributes as ASN.1 <code>PrintableString</code>s, - * without checking whether they should be encoded as <code>T61String</code> - * s. + * <P> N.B.: This method always encodes values of + * ChallengePassword and UnstructuredAddress attributes as ASN.1 + * <code>PrintableString</code>s, without checking whether they + * should be encoded as <code>T61String</code>s. */ public void derEncode(OutputStream out) throws IOException { - DerOutputStream temp = new DerOutputStream(); - temp.putOID(getOID()); - switch (index) { - case 1: // email address - case 2: // unstructured name - { // open scope - String[] values = (String[]) value; - DerOutputStream[] temps = new DerOutputStream[values.length]; - - for (int i = 0; i < values.length; i++) { - temps[i] = new DerOutputStream(); - - temps[i].putIA5String(values[i]); - } - temp.putOrderedSetOf(DerValue.tag_Set, temps); - } // close scope - break; - - case 3: // content type - { - DerOutputStream temp2 = new DerOutputStream(); - temp2.putOID((ObjectIdentifier) value); - temp.write(DerValue.tag_Set, temp2.toByteArray()); - } - break; - - case 4: // message digest - { - DerOutputStream temp2 = new DerOutputStream(); - temp2.putOctetString((byte[]) value); - temp.write(DerValue.tag_Set, temp2.toByteArray()); - } - break; - - case 5: // signing time - { - DerOutputStream temp2 = new DerOutputStream(); - temp2.putUTCTime((Date) value); - temp.write(DerValue.tag_Set, temp2.toByteArray()); - } - break; - - case 6: // countersignature - temp.putOrderedSetOf(DerValue.tag_Set, (DerEncoder[]) value); - break; - - case 7: // challenge password - { - DerOutputStream temp2 = new DerOutputStream(); - temp2.putPrintableString((String) value); - temp.write(DerValue.tag_Set, temp2.toByteArray()); - } - break; - - case 8: // unstructured address - { // open scope - String[] values = (String[]) value; - DerOutputStream[] temps = new DerOutputStream[values.length]; - - for (int i = 0; i < values.length; i++) { - temps[i] = new DerOutputStream(); - - temps[i].putPrintableString(values[i]); - } - temp.putOrderedSetOf(DerValue.tag_Set, temps); - } // close scope - break; - - case 9: // extended-certificate attribute -- not - // supported - throw new IOException("PKCS9 extended-certificate " - + "attribute not supported."); - - case 10: // IssuerAndSerialNumber attribute -- not - // supported - throw new IOException("PKCS9 IssuerAndSerialNumber " - + "attribute not supported."); - - case 11: // passwordCheck attribute -- not - // supported - throw new IOException("PKCS9 passwordCheck " - + "attribute not supported."); - case 12: // PublicKey attribute -- not - // supported - throw new IOException("PKCS9 PublicKey " - + "attribute not supported."); - case 13: // SigningDescription attribute -- not - // supported - throw new IOException("PKCS9 SigningDescription " - + "attribute not supported."); - case 14: // ExtensionRequest attribute - try { - DerOutputStream temp2 = new DerOutputStream(); - // temp2.putSequence((CertificateExtensions) value); - ((CertificateExtensions) value).encode(temp2); - temp.write(DerValue.tag_Sequence, temp2.toByteArray()); - } catch (CertificateException e) { - throw new IOException("PKCS9 extension attributes not encoded"); - } - - // break unnecessary - default: // can't happen - } - - DerOutputStream derOut = new DerOutputStream(); - derOut.write(DerValue.tag_Sequence, temp.toByteArray()); - - out.write(derOut.toByteArray()); - + DerOutputStream temp = new DerOutputStream(); + temp.putOID(getOID()); + switch (index) { + case 1: // email address + case 2: // unstructured name + { // open scope + String[] values = (String[]) value; + DerOutputStream[] temps = new + DerOutputStream[values.length]; + + for (int i=0; i < values.length; i++) { + temps[i] = new DerOutputStream(); + + temps[i].putIA5String( values[i]); + } + temp.putOrderedSetOf(DerValue.tag_Set, temps); + } // close scope + break; + + case 3: // content type + { + DerOutputStream temp2 = new DerOutputStream(); + temp2.putOID((ObjectIdentifier) value); + temp.write(DerValue.tag_Set, temp2.toByteArray()); + } + break; + + case 4: // message digest + { + DerOutputStream temp2 = new DerOutputStream(); + temp2.putOctetString((byte[]) value); + temp.write(DerValue.tag_Set, temp2.toByteArray()); + } + break; + + case 5: // signing time + { + DerOutputStream temp2 = new DerOutputStream(); + temp2.putUTCTime((Date) value); + temp.write(DerValue.tag_Set, temp2.toByteArray()); + } + break; + + case 6: // countersignature + temp.putOrderedSetOf(DerValue.tag_Set, (DerEncoder[]) value); + break; + + case 7: // challenge password + { + DerOutputStream temp2 = new DerOutputStream(); + temp2.putPrintableString((String) value); + temp.write(DerValue.tag_Set, temp2.toByteArray()); + } + break; + + case 8: // unstructured address + { // open scope + String[] values = (String[]) value; + DerOutputStream[] temps = new + DerOutputStream[values.length]; + + for (int i=0; i < values.length; i++) { + temps[i] = new DerOutputStream(); + + temps[i].putPrintableString(values[i]); + } + temp.putOrderedSetOf(DerValue.tag_Set, temps); + } // close scope + break; + + case 9: // extended-certificate attribute -- not + // supported + throw new IOException("PKCS9 extended-certificate " + + "attribute not supported."); + + case 10: // IssuerAndSerialNumber attribute -- not + // supported + throw new IOException("PKCS9 IssuerAndSerialNumber " + + "attribute not supported."); + + case 11: // passwordCheck attribute -- not + // supported + throw new IOException("PKCS9 passwordCheck " + + "attribute not supported."); + case 12: // PublicKey attribute -- not + // supported + throw new IOException("PKCS9 PublicKey " + + "attribute not supported."); + case 13: // SigningDescription attribute -- not + // supported + throw new IOException("PKCS9 SigningDescription " + + "attribute not supported."); + case 14: // ExtensionRequest attribute + try { + DerOutputStream temp2 = new DerOutputStream(); + //temp2.putSequence((CertificateExtensions) value); + ((CertificateExtensions)value).encode(temp2); + temp.write(DerValue.tag_Sequence, temp2.toByteArray()); + } catch (CertificateException e) { + throw new IOException("PKCS9 extension attributes not encoded"); + } + + // break unnecessary + default: // can't happen + } + + DerOutputStream derOut = new DerOutputStream(); + derOut.write(DerValue.tag_Sequence, temp.toByteArray()); + + out.write(derOut.toByteArray()); + } /** - * Get the value of this attribute. If the attribute is single-valued, - * return just the one value. If the attribute is multiple-valued, return an - * array containing all the values. It is possible for this array to be of - * length 0. - * - * <P> - * The following table gives the class of the value returned, depending on - * the type of this attribute. - * + * Get the value of this attribute. If the attribute is + * single-valued, return just the one value. If the attribute is + * multiple-valued, return an array containing all the values. + * It is possible for this array to be of length 0. + * + * <P> The following table gives the class of the value returned, + * depending on the type of this attribute. + * <P> * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER> - * + * * <TR> * <TH>OID</TH> * <TH>Attribute Type Name</TH> * <TH>Kind</TH> * <TH>Value Class</TH> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.1</TD> * <TD>EmailAddress</TD> * <TD>Multiple-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.2</TD> * <TD>UnstructuredName</TD> * <TD>Multiple-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.3</TD> * <TD>ContentType</TD> * <TD>Single-valued</TD> * <TD><code>ObjectIdentifier</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.4</TD> * <TD>MessageDigest</TD> * <TD>Single-valued</TD> * <TD><code>byte[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.5</TD> * <TD>SigningTime</TD> * <TD>Single-valued</TD> * <TD><code>Date</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.6</TD> * <TD>Countersignature</TD> * <TD>Multiple-valued</TD> * <TD><code>SignerInfo[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.7</TD> * <TD>ChallengePassword</TD> * <TD>Single-valued</TD> * <TD><code>String</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.8</TD> * <TD>UnstructuredAddress</TD> * <TD>Single-valued</TD> * <TD><code>String[]</code></TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.9</TD> * <TD>ExtendedCertificateAttributes</TD> * <TD>Multiple-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.10</TD> * <TD>IssuerAndSerialNumber</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.11</TD> * <TD>PasswordCheck</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.12</TD> * <TD>PublicKey</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.13</TD> * <TD>SigningDescription</TD> * <TD>Single-valued</TD> * <TD>(not supported)</TD> * </TR> - * + * * <TR> * <TD>1.2.840.113549.1.9.14</TD> * <TD>ExtensionRequest</TD> * <TD>Single-valued</TD> * <TD><code>Sequence</code></TD> * </TR> - * + * * </TABLE> - * + * */ public Object getValue() { - return value; + return value; } - /** + /** * Show whether this attribute is single-valued. */ public boolean isSingleValued() { - return SINGLE_VALUED[index]; + return SINGLE_VALUED[index]; } - /** - * Return the OID of this attribute. + /** + * Return the OID of this attribute. */ public ObjectIdentifier getOID() { - return PKCS9_OIDS[index]; + return PKCS9_OIDS[index]; } - /** - * Return the name of this attribute. + /** + * Return the name of this attribute. */ public String getName() { - return (String) OID_NAME_TABLE.get(PKCS9_OIDS[index]); + return (String) OID_NAME_TABLE.get(PKCS9_OIDS[index]); } - /** + /** * Return the OID for a given attribute name or null if we don't recognize * the name. */ public static ObjectIdentifier getOID(String name) { - return (ObjectIdentifier) NAME_OID_TABLE.get(name.toLowerCase()); + return (ObjectIdentifier) NAME_OID_TABLE.get(name.toLowerCase()); } - /** + /** * Return the attribute name for a given OID or null if we don't recognize * the oid. */ public static String getName(ObjectIdentifier oid) { - return (String) OID_NAME_TABLE.get(oid); + return (String) OID_NAME_TABLE.get(oid); } - /** + /** * Returns a string representation of this attribute. */ public String toString() { - StringBuffer buf = new StringBuffer(100); - - buf.append("["); - - buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index])); - buf.append(": "); - - if (SINGLE_VALUED[index]) { - if (value instanceof byte[]) { // special case for octet string - netscape.security.util.PrettyPrintFormat pp = new netscape.security.util.PrettyPrintFormat( - " ", 20); - String valuebits = pp.toHexString(((byte[]) value)); - buf.append(valuebits); - } else { - buf.append(value.toString()); - } - buf.append("]"); - return buf.toString(); - } else { // multiple-valued - boolean first = true; - Object[] values = (Object[]) value; - - for (int j = 0; j < values.length; j++) { - if (first) - first = false; - else - buf.append(", "); - - buf.append(values[j].toString()); - } - return buf.toString(); - } + StringBuffer buf = new StringBuffer(100); + + buf.append("["); + + buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index])); + buf.append(": "); + + if (SINGLE_VALUED[index]) { + if (value instanceof byte[]) { // special case for octet string + netscape.security.util.PrettyPrintFormat pp = + new netscape.security.util.PrettyPrintFormat(" ", 20); + String valuebits = pp.toHexString(((byte[])value)); + buf.append(valuebits); + } else { + buf.append(value.toString()); + } + buf.append("]"); + return buf.toString(); + } else { // multiple-valued + boolean first = true; + Object[] values = (Object[]) value; + + for (int j=0; j < values.length; j++) { + if (first) + first = false; + else + buf.append(", "); + + buf.append(values[j].toString()); + } + return buf.toString(); + } } - /** - * Beginning the search at <code>start</code>, find the first index - * <code>i</code> such that <code>a[i] = obj</code>. - * + /** + * Beginning the search at <code>start</code>, find the first + * index <code>i</code> such that <code>a[i] = obj</code>. + * * @return the index, if found, and -1 otherwise. */ static int indexOf(Object obj, Object[] a, int start) { - for (int i = start; i < a.length; i++) { - if (obj.equals(a[i])) - return i; - } - return -1; + for (int i=start; i < a.length; i++) { + if (obj.equals(a[i])) return i; + } + return -1; } - /** - * Throw an exception when there are multiple values for a single-valued - * attribute. + /** + * Throw an exception when there are multiple values for + * a single-valued attribute. */ private void throwSingleValuedException() throws IOException { - throw new IOException("Single-value attribute " + getOID() + " (" - + getName() + ")" + " has multiple values."); + throw new IOException("Single-value attribute " + + getOID() + " (" + getName() + ")" + + " has multiple values."); } - /** - * Throw an exception when the tag on a value encoding is wrong for the - * attribute whose value it is. + /** + * Throw an exception when the tag on a value encoding is + * wrong for the attribute whose value it is. */ - private void throwTagException(Byte tag) throws IOException { - Byte[] expectedTags = PKCS9_VALUE_TAGS[index]; - StringBuffer msg = new StringBuffer(100); + private void throwTagException(Byte tag) + throws IOException { + Byte[] expectedTags = PKCS9_VALUE_TAGS[index]; + StringBuffer msg = new StringBuffer(100); msg.append("Value of attribute "); - msg.append(getOID().toString()); - msg.append(" ("); - msg.append(getName()); - msg.append(") has wrong tag: "); - msg.append(tag.toString()); - msg.append(". Expected tags: "); - - msg.append(expectedTags[0].toString()); - - for (int i = 1; i < expectedTags.length; i++) { - msg.append(", "); - msg.append(expectedTags[i].toString()); - } - msg.append("."); - throw new IOException(msg.toString()); + msg.append(getOID().toString()); + msg.append(" ("); + msg.append(getName()); + msg.append(") has wrong tag: "); + msg.append(tag.toString()); + msg.append(". Expected tags: "); + + msg.append(expectedTags[0].toString()); + + for (int i = 1; i < expectedTags.length; i++) { + msg.append(", "); + msg.append(expectedTags[i].toString()); + } + msg.append("."); + throw new IOException(msg.toString()); } } diff --git a/pki/base/util/src/netscape/security/pkcs/PKCS9Attributes.java b/pki/base/util/src/netscape/security/pkcs/PKCS9Attributes.java index 97769308d..aff0ee0f7 100644 --- a/pki/base/util/src/netscape/security/pkcs/PKCS9Attributes.java +++ b/pki/base/util/src/netscape/security/pkcs/PKCS9Attributes.java @@ -27,166 +27,180 @@ import netscape.security.util.DerOutputStream; import netscape.security.util.DerValue; import netscape.security.util.ObjectIdentifier; + /** - * A set of attributes of class PKCS9Attribute. - * + * A set of attributes of class PKCS9Attribute. + * * @version 1.2 97/12/10 * @author Douglas Hoover */ public class PKCS9Attributes { /** - * Attributes in this set indexed by OID. + * Attributes in this set indexed by OID. */ private final Hashtable attributes = new Hashtable(3); /** - * The keys of this hashtable are the OIDs of permitted attributes. + * The keys of this hashtable are the OIDs of permitted attributes. */ private final Hashtable permittedAttributes; /** - * The DER encoding of this attribute set. The tag byte must be + * The DER encoding of this attribute set. The tag byte must be * DerValue.tag_SetOf. - */ + */ private final byte[] derEncoding; /** - * Construct a set of PKCS9 Attributes from its DER encoding on a - * DerInputStream, accepting only attributes with OIDs on the given list. If - * the array is null, accept all attributes supported by class - * PKCS9Attribute. - * - * @param permittedAttributes Array of attribute OIDs that will be accepted. - * @param buf the contents of the DER encoding of the attribute set. - * - * @exception IOException on i/o error, encoding syntax error, unacceptable - * or unsupported attribute, or duplicate attribute. - * + * Construct a set of PKCS9 Attributes from its + * DER encoding on a DerInputStream, accepting only attributes + * with OIDs on the given + * list. If the array is null, accept all attributes supported by + * class PKCS9Attribute. + * + * @param permittedAttributes + * Array of attribute OIDs that will be accepted. + * @param buf + * the contents of the DER encoding of the attribute set. + * + * @exception IOException + * on i/o error, encoding syntax error, unacceptable or + * unsupported attribute, or duplicate attribute. + * * @see PKCS9Attribute */ public PKCS9Attributes(ObjectIdentifier[] permittedAttributes, - DerInputStream in) throws IOException { - if (permittedAttributes != null) { - this.permittedAttributes = new Hashtable(permittedAttributes.length); - - for (int i = 0; i < permittedAttributes.length; i++) - this.permittedAttributes.put(permittedAttributes[i], - permittedAttributes[i]); - } else { - this.permittedAttributes = null; - } - - // derEncoding initialized in <code>decode()</code> - derEncoding = decode(in); + DerInputStream in) throws IOException { + if (permittedAttributes != null) { + this.permittedAttributes = + new Hashtable(permittedAttributes.length); + + for (int i = 0; i < permittedAttributes.length; i++) + this.permittedAttributes.put(permittedAttributes[i], + permittedAttributes[i]); + } else { + this.permittedAttributes = null; + } + + // derEncoding initialized in <code>decode()</code> + derEncoding = decode(in); } /** - * Construct a set of PKCS9 Attributes from its contents of its DER encoding - * on a DerInputStream. Accept all attributes supported by class - * PKCS9Attribute. - * - * @exception IOException on i/o error, encoding syntax error, or - * unsupported or duplicate attribute. - * + * Construct a set of PKCS9 Attributes from its contents of its + * DER encoding on a DerInputStream. Accept all attributes + * supported by class PKCS9Attribute. + * + * @exception IOException + * on i/o error, encoding syntax error, or unsupported or + * duplicate attribute. + * * @see PKCS9Attribute */ public PKCS9Attributes(DerInputStream in) throws IOException { - // anything goes - // derEncoding initialized in <code>decode()</code> - derEncoding = decode(in); - permittedAttributes = null; + // anything goes + // derEncoding initialized in <code>decode()</code> + derEncoding = decode(in); + permittedAttributes = null; } /** - * Construct a set of PKCS9 Attributes from the given array of PCK9 - * attributes. DER encoding on a DerInputStream. All attributes in - * <code>attribs</code> must be supported by class PKCS9Attribute. - * - * @exception IOException on i/o error, encoding syntax error, or - * unsupported or duplicate attribute. - * + * Construct a set of PKCS9 Attributes from the given array of + * PCK9 attributes. + * DER encoding on a DerInputStream. All attributes in + * <code>attribs</code> must be + * supported by class PKCS9Attribute. + * + * @exception IOException + * on i/o error, encoding syntax error, or unsupported or + * duplicate attribute. + * * @see PKCS9Attribute */ - public PKCS9Attributes(PKCS9Attribute[] attribs) - throws IllegalArgumentException, IOException { - ObjectIdentifier oid; - for (int i = 0; i < attribs.length; i++) { - oid = attribs[i].getOID(); - if (attributes.containsKey(oid)) - throw new IllegalArgumentException("PKCSAttribute " - + attribs[i].getOID() - + " duplicated while constructing " - + "PKCS9Attributes."); - - attributes.put(oid, attribs[i]); - } - derEncoding = generateDerEncoding(); - permittedAttributes = null; + public PKCS9Attributes(PKCS9Attribute[] attribs) + throws IllegalArgumentException, IOException { + ObjectIdentifier oid; + for (int i=0; i < attribs.length; i++) { + oid = attribs[i].getOID(); + if (attributes.containsKey(oid)) + throw new IllegalArgumentException( + "PKCSAttribute " + attribs[i].getOID() + + " duplicated while constructing " + + "PKCS9Attributes."); + + attributes.put(oid, attribs[i]); + } + derEncoding = generateDerEncoding(); + permittedAttributes = null; } + /** - * Decode this set of PKCS9 attribute set from the contents of its DER - * encoding. - * - * @param buf the contents of the DER encoding of the attribute set. - * - * @exception IOException on i/o error, encoding syntax error, unacceptable - * or unsupported attribute, or duplicate attribute. + * Decode this set of PKCS9 attribute set from the contents of its + * DER encoding. + * + * @param buf + * the contents of the DER encoding of the attribute set. + * + * @exception IOException + * on i/o error, encoding syntax error, unacceptable or + * unsupported attribute, or duplicate attribute. */ private byte[] decode(DerInputStream in) throws IOException { - DerValue val = in.getDerValue(); + DerValue val = in.getDerValue(); - // save the DER encoding with its proper tag byte. - byte[] derEncoding = val.toByteArray(); - derEncoding[0] = DerValue.tag_SetOf; + // save the DER encoding with its proper tag byte. + byte[] derEncoding = val.toByteArray(); + derEncoding[0] = DerValue.tag_SetOf; - DerInputStream derIn = new DerInputStream(derEncoding); - DerValue[] derVals = derIn.getSet(3, true); + DerInputStream derIn = new DerInputStream(derEncoding); + DerValue[] derVals = derIn.getSet(3,true); - PKCS9Attribute attrib; - ObjectIdentifier oid; - int index; + PKCS9Attribute attrib; + ObjectIdentifier oid; + int index; - for (int i = 0; i < derVals.length; i++) { - attrib = new PKCS9Attribute(derVals[i]); - oid = attrib.getOID(); + for (int i=0; i < derVals.length; i++) { + attrib = new PKCS9Attribute(derVals[i]); + oid = attrib.getOID(); - if (attributes.get(oid) != null) - throw new IOException("Duplicate PKCS9 attribute: " + oid); + if (attributes.get(oid) != null) + throw new IOException("Duplicate PKCS9 attribute: " + oid); - if (permittedAttributes != null - && !permittedAttributes.containsKey(oid)) - throw new IOException("Attribute " + oid - + " not permitted in this attribute set"); - - attributes.put(oid, attrib); - } - return derEncoding; + if (permittedAttributes != null && + !permittedAttributes.containsKey(oid)) + throw new IOException("Attribute " + oid + + " not permitted in this attribute set"); + + attributes.put(oid,attrib); + } + return derEncoding; } /** - * Put the DER encoding of this PKCS9 attribute set on an DerOutputStream, - * tagged with the given implicit tag. - * + * Put the DER encoding of this PKCS9 attribute set on an + * DerOutputStream, tagged with the given implicit tag. + * * @param tag the implicit tag to use in the DER encoding. * @param out the output stream on which to put the DER encoding. - * - * @exception IOException on output error. + * + * @exception IOException on output error. */ public void encode(byte tag, OutputStream out) throws IOException { - out.write(tag); - out.write(derEncoding, 1, derEncoding.length - 1); + out.write(tag); + out.write(derEncoding, 1, derEncoding.length -1); } private byte[] generateDerEncoding() throws IOException { - DerOutputStream out = new DerOutputStream(); - Object[] attribVals = attributes.values().toArray(); - - out.putOrderedSetOf(DerValue.tag_SetOf, castToDerEncoder(attribVals)); - return out.toByteArray(); + DerOutputStream out = new DerOutputStream(); + Object[] attribVals = attributes.values().toArray(); + + out.putOrderedSetOf(DerValue.tag_SetOf, + castToDerEncoder(attribVals)); + return out.toByteArray(); } /** @@ -194,111 +208,113 @@ public class PKCS9Attributes { * DerValue.tag_SetOf. */ public byte[] getDerEncoding() throws IOException { - return (byte[]) derEncoding.clone(); - + return (byte[]) derEncoding.clone(); + } /** * Get an attribute from this set. - */ + */ public PKCS9Attribute getAttribute(ObjectIdentifier oid) { - return (PKCS9Attribute) attributes.get(oid); + return (PKCS9Attribute) attributes.get(oid); } /** * Get an attribute from this set. - */ + */ public PKCS9Attribute getAttribute(String name) { - return (PKCS9Attribute) attributes.get(PKCS9Attribute.getOID(name)); + return (PKCS9Attribute) attributes.get(PKCS9Attribute.getOID(name)); } + /** * Get an array of all attributes in this set, in order of OID. - */ + */ public PKCS9Attribute[] getAttributes() { - PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()]; - ObjectIdentifier oid; - - int j = 0; - for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length - && j < attribs.length; i++) { - attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); - - if (attribs[j] != null) - j++; - } - return attribs; + PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()]; + ObjectIdentifier oid; + + int j = 0; + for (int i=1; i < PKCS9Attribute.PKCS9_OIDS.length && + j < attribs.length; i++) { + attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); + + if (attribs[j] != null) + j++; + } + return attribs; } /** * Get an attribute value by OID. */ - public Object getAttributeValue(ObjectIdentifier oid) throws IOException { - try { - Object value = getAttribute(oid).getValue(); - return value; - } catch (NullPointerException ex) { - throw new IOException("No value found for attribute " + oid); - } + public Object getAttributeValue(ObjectIdentifier oid) + throws IOException { + try { + Object value = getAttribute(oid).getValue(); + return value; + } catch (NullPointerException ex) { + throw new IOException("No value found for attribute " + oid); + } } - /** - * Get an attribute value by type name. + /** + * Get an attribute value by type name. */ - public Object getAttributeValue(String name) throws IOException { - ObjectIdentifier oid = PKCS9Attribute.getOID(name); + public Object getAttributeValue(String name) throws IOException { + ObjectIdentifier oid = PKCS9Attribute.getOID(name); - if (oid == null) - throw new IOException("Attribute name " + name - + " not recognized or not supported."); + if (oid == null) + throw new IOException("Attribute name " + name + + " not recognized or not supported."); - return getAttributeValue(oid); - } + return getAttributeValue(oid); + } - /** + + /** * Returns the PKCS9 block in a printable string form. */ public String toString() { - StringBuffer buf = new StringBuffer(200); - buf.append("PKCS9 Attributes: [\n\t"); - - ObjectIdentifier oid; - PKCS9Attribute value; + StringBuffer buf = new StringBuffer(200); + buf.append("PKCS9 Attributes: [\n\t"); + + ObjectIdentifier oid; + PKCS9Attribute value; - boolean first = true; - for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) { - value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); + boolean first = true; + for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) { + value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); - if (value == null) - continue; + if (value == null) continue; - // we have a value; print it - if (first) - first = false; - else - buf.append(";\n\t"); + // we have a value; print it + if (first) + first = false; + else + buf.append(";\n\t"); - buf.append(value.toString()); - } + buf.append(value.toString()); + } - buf.append("\n\t] (end PKCS9 Attributes)"); + buf.append("\n\t] (end PKCS9 Attributes)"); - return buf.toString(); + return buf.toString(); } - - /** - * Cast an object array whose components are <code>DerEncoder</code>s to - * <code>DerEncoder[]</code>. + + /** + * Cast an object array whose components are + * <code>DerEncoder</code>s to <code>DerEncoder[]</code>. */ static DerEncoder[] castToDerEncoder(Object[] objs) { - DerEncoder[] encoders = new DerEncoder[objs.length]; + DerEncoder[] encoders = new DerEncoder[objs.length]; - for (int i = 0; i < encoders.length; i++) - encoders[i] = (DerEncoder) objs[i]; + for (int i=0; i < encoders.length; i++) + encoders[i] = (DerEncoder) objs[i]; - return encoders; + return encoders; } } diff --git a/pki/base/util/src/netscape/security/pkcs/ParsingException.java b/pki/base/util/src/netscape/security/pkcs/ParsingException.java index 88e91a8db..64f675704 100644 --- a/pki/base/util/src/netscape/security/pkcs/ParsingException.java +++ b/pki/base/util/src/netscape/security/pkcs/ParsingException.java @@ -26,10 +26,10 @@ public class ParsingException extends IOException { private static final long serialVersionUID = -8135726194372647410L; public ParsingException() { - super(); + super(); } public ParsingException(String s) { - super(s); + super(s); } } diff --git a/pki/base/util/src/netscape/security/pkcs/SignerInfo.java b/pki/base/util/src/netscape/security/pkcs/SignerInfo.java index 21061ae2a..d02fb03dd 100644 --- a/pki/base/util/src/netscape/security/pkcs/SignerInfo.java +++ b/pki/base/util/src/netscape/security/pkcs/SignerInfo.java @@ -38,8 +38,8 @@ import netscape.security.x509.X500Name; /** * A SignerInfo, as defined in PKCS#7's signedData type. - * - * @author Benjamin Renaud + * + * @author Benjamin Renaud * @version 1.27 97/12/10 */ public class SignerInfo implements DerEncoder { @@ -54,284 +54,301 @@ public class SignerInfo implements DerEncoder { PKCS9Attributes authenticatedAttributes; PKCS9Attributes unauthenticatedAttributes; - public SignerInfo(X500Name issuerName, BigInt serial, - AlgorithmId digestAlgorithmId, - AlgorithmId digestEncryptionAlgorithmId, byte[] encryptedDigest) { - this.version = new BigInt(1); - this.issuerName = issuerName; - this.certificateSerialNumber = serial; - this.digestAlgorithmId = digestAlgorithmId; - this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId; - this.encryptedDigest = encryptedDigest; + public SignerInfo(X500Name issuerName, + BigInt serial, + AlgorithmId digestAlgorithmId, + AlgorithmId digestEncryptionAlgorithmId, + byte[] encryptedDigest) { + this.version = new BigInt(1); + this.issuerName = issuerName; + this.certificateSerialNumber = serial; + this.digestAlgorithmId = digestAlgorithmId; + this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId; + this.encryptedDigest = encryptedDigest; } - public SignerInfo(X500Name issuerName, BigInt serial, - AlgorithmId digestAlgorithmId, - PKCS9Attributes authenticatedAttributes, - AlgorithmId digestEncryptionAlgorithmId, byte[] encryptedDigest, - PKCS9Attributes unauthenticatedAttributes) { - this.version = new BigInt(1); - this.issuerName = issuerName; - this.certificateSerialNumber = serial; - this.digestAlgorithmId = digestAlgorithmId; - this.authenticatedAttributes = authenticatedAttributes; - this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId; - this.encryptedDigest = encryptedDigest; - this.unauthenticatedAttributes = unauthenticatedAttributes; + public SignerInfo(X500Name issuerName, + BigInt serial, + AlgorithmId digestAlgorithmId, + PKCS9Attributes authenticatedAttributes, + AlgorithmId digestEncryptionAlgorithmId, + byte[] encryptedDigest, + PKCS9Attributes unauthenticatedAttributes) { + this.version = new BigInt(1); + this.issuerName = issuerName; + this.certificateSerialNumber = serial; + this.digestAlgorithmId = digestAlgorithmId; + this.authenticatedAttributes = authenticatedAttributes; + this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId; + this.encryptedDigest = encryptedDigest; + this.unauthenticatedAttributes = unauthenticatedAttributes; } - public SignerInfo(DerInputStream derin) throws IOException, - ParsingException { - - // version - version = derin.getInteger(); - - // issuerAndSerialNumber - DerValue[] issuerAndSerialNumber = derin.getSequence(2); - byte[] issuerBytes = issuerAndSerialNumber[0].toByteArray(); - issuerName = new X500Name(new DerValue(DerValue.tag_Sequence, - issuerBytes)); - certificateSerialNumber = issuerAndSerialNumber[1].getInteger(); - - // digestAlgorithmId - DerValue tmp = derin.getDerValue(); - - digestAlgorithmId = AlgorithmId.parse(tmp); - - /* - * check if set of auth attributes (implicit tag) is provided (auth - * attributes are OPTIONAL) - */ - if ((byte) (derin.peekByte()) == (byte) 0xA0) { - authenticatedAttributes = new PKCS9Attributes(derin); - } - - // digestEncryptionAlgorithmId - little RSA naming scheme - - // signature == encryption... - tmp = derin.getDerValue(); - - digestEncryptionAlgorithmId = AlgorithmId.parse(tmp); - - // encryptedDigest - encryptedDigest = derin.getOctetString(); - - /* - * check if set of unauth attributes (implicit tag) is provided (unauth - * attributes are OPTIONAL) - */ - if (derin.available() != 0 && (byte) (derin.peekByte()) == (byte) 0xA1) { - unauthenticatedAttributes = new PKCS9Attributes(derin); - } - - // all done - if (derin.available() != 0) { - throw new ParsingException("extra data at the end"); - } + public SignerInfo(DerInputStream derin) + throws IOException, ParsingException { + + // version + version = derin.getInteger(); + + // issuerAndSerialNumber + DerValue[] issuerAndSerialNumber = derin.getSequence(2); + byte[] issuerBytes = issuerAndSerialNumber[0].toByteArray(); + issuerName = new X500Name(new DerValue(DerValue.tag_Sequence, + issuerBytes)); + certificateSerialNumber = issuerAndSerialNumber[1].getInteger(); + + // digestAlgorithmId + DerValue tmp = derin.getDerValue(); + + digestAlgorithmId = AlgorithmId.parse(tmp); + + /* + * check if set of auth attributes (implicit tag) is provided + * (auth attributes are OPTIONAL) + */ + if ((byte)(derin.peekByte()) == (byte)0xA0) { + authenticatedAttributes = new PKCS9Attributes(derin); + } + + // digestEncryptionAlgorithmId - little RSA naming scheme - + // signature == encryption... + tmp = derin.getDerValue(); + + digestEncryptionAlgorithmId = AlgorithmId.parse(tmp); + + // encryptedDigest + encryptedDigest = derin.getOctetString(); + + /* + * check if set of unauth attributes (implicit tag) is provided + * (unauth attributes are OPTIONAL) + */ + if (derin.available() != 0 && (byte)(derin.peekByte()) == (byte)0xA1) { + unauthenticatedAttributes = new PKCS9Attributes(derin); + } + + // all done + if (derin.available() != 0) { + throw new ParsingException("extra data at the end"); + } } public void encode(DerOutputStream out) throws IOException { - - derEncode(out); + + derEncode(out); } /** - * DER encode this object onto an output stream. Implements the - * <code>DerEncoder</code> interface. - * - * @param out the output stream on which to write the DER encoding. - * + * DER encode this object onto an output stream. + * Implements the <code>DerEncoder</code> interface. + * + * @param out + * the output stream on which to write the DER encoding. + * * @exception IOException on encoding error. */ public void derEncode(OutputStream out) throws IOException { - DerOutputStream seq = new DerOutputStream(); - seq.putInteger(version); - DerOutputStream issuerAndSerialNumber = new DerOutputStream(); - issuerName.encode(issuerAndSerialNumber); - issuerAndSerialNumber.putInteger(certificateSerialNumber); - seq.write(DerValue.tag_Sequence, issuerAndSerialNumber); - - digestAlgorithmId.encode(seq); - - // encode authenticated attributes if there are any - if (authenticatedAttributes != null) - authenticatedAttributes.encode((byte) 0xA0, seq); - - digestEncryptionAlgorithmId.encode(seq); - - seq.putOctetString(encryptedDigest); - - // encode unauthenticated attributes if there are any - if (unauthenticatedAttributes != null) - unauthenticatedAttributes.encode((byte) 0xA1, seq); - - DerOutputStream tmp = new DerOutputStream(); - tmp.write(DerValue.tag_Sequence, seq); - - out.write(tmp.toByteArray()); + DerOutputStream seq = new DerOutputStream(); + seq.putInteger(version); + DerOutputStream issuerAndSerialNumber = new DerOutputStream(); + issuerName.encode(issuerAndSerialNumber); + issuerAndSerialNumber.putInteger(certificateSerialNumber); + seq.write(DerValue.tag_Sequence, issuerAndSerialNumber); + + digestAlgorithmId.encode(seq); + + // encode authenticated attributes if there are any + if (authenticatedAttributes != null) + authenticatedAttributes.encode((byte)0xA0, seq); + + digestEncryptionAlgorithmId.encode(seq); + + seq.putOctetString(encryptedDigest); + + // encode unauthenticated attributes if there are any + if (unauthenticatedAttributes != null) + unauthenticatedAttributes.encode((byte)0xA1, seq); + + DerOutputStream tmp = new DerOutputStream(); + tmp.write(DerValue.tag_Sequence, seq); + + out.write(tmp.toByteArray()); } - public X509Certificate getCertificate(PKCS7 block) throws IOException { - return block.getCertificate(certificateSerialNumber, issuerName); - } - - /* - * Returns null if verify fails, this signerInfo if verify succeeds. - */ - SignerInfo verify(PKCS7 block, byte[] data) - throws NoSuchAlgorithmException, SignatureException { - - try { - - ContentInfo content = block.getContentInfo(); - if (data == null) { - data = content.getContentBytes(); - } - - String digestAlgname = getDigestAlgorithmId().getName(); - - byte[] dataSigned; - - // if there are authenticate attributes, get the message - // digest and compare it with the digest of data - if (authenticatedAttributes == null) { - dataSigned = data; - } else { - - // first, check content type - ObjectIdentifier contentType = (ObjectIdentifier) authenticatedAttributes - .getAttributeValue(PKCS9Attribute.CONTENT_TYPE_OID); - if (contentType == null - || !contentType.equals(content.contentType)) - return null; // contentType does not match, bad SignerInfo - // now, check message digest - byte[] messageDigest = (byte[]) authenticatedAttributes - .getAttributeValue(PKCS9Attribute.MESSAGE_DIGEST_OID); - if (messageDigest == null) // fail if there is no message digest - return null; - - MessageDigest md = MessageDigest.getInstance(digestAlgname); - byte[] computedMessageDigest = md.digest(data); - - if (messageDigest.length != computedMessageDigest.length) - return null; - for (int i = 0; i < messageDigest.length; i++) { - if (messageDigest[i] != computedMessageDigest[i]) - return null; - } - - // message digest attribute matched - // digest of original data - - // the data actually signed is the DER encoding of - // the authenticated attributes (tagged with - // the "SET OF" tag, not 0xA0). - dataSigned = authenticatedAttributes.getDerEncoding(); - } - - // put together digest algorithm and encryption algorithm - // to form signing algorithm - String encryptionAlgname = getDigestEncryptionAlgorithmId() - .getName(); - - String algname; - if (encryptionAlgname.equals("DSA") - || encryptionAlgname.equals("SHA1withDSA")) { - algname = "DSA"; - } else { - algname = digestAlgname + "/" + encryptionAlgname; - } - - Signature sig = Signature.getInstance(algname); - X509Certificate cert = getCertificate(block); - - if (cert == null) { - return null; - } - - PublicKey key = cert.getPublicKey(); - sig.initVerify(key); - - sig.update(dataSigned); - - if (sig.verify(encryptedDigest)) { - return this; - } - - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" - + e.getMessage()); - - } catch (InvalidKeyException e) { - throw new SignatureException("InvalidKey: " + e.getMessage()); - - } - return null; + public X509Certificate getCertificate(PKCS7 block) + throws IOException { + return block.getCertificate(certificateSerialNumber, issuerName); } + /* Returns null if verify fails, this signerInfo if + verify succeeds. */ + SignerInfo verify(PKCS7 block, byte[] data) + throws NoSuchAlgorithmException, SignatureException { + + try { + + ContentInfo content = block.getContentInfo(); + if (data == null) { + data = content.getContentBytes(); + } + + String digestAlgname = + getDigestAlgorithmId().getName(); + + byte[] dataSigned; + + // if there are authenticate attributes, get the message + // digest and compare it with the digest of data + if (authenticatedAttributes == null) { + dataSigned = data; + } else { + + // first, check content type + ObjectIdentifier contentType = (ObjectIdentifier) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.CONTENT_TYPE_OID); + if (contentType == null || + !contentType.equals(content.contentType)) + return null; // contentType does not match, bad SignerInfo + + // now, check message digest + byte[] messageDigest = (byte[]) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.MESSAGE_DIGEST_OID); + + if (messageDigest == null) // fail if there is no message digest + return null; + + MessageDigest md = MessageDigest.getInstance(digestAlgname); + byte[] computedMessageDigest = md.digest(data); + + if (messageDigest.length != computedMessageDigest.length) + return null; + for (int i = 0; i < messageDigest.length; i++) { + if (messageDigest[i] != computedMessageDigest[i]) + return null; + } + + // message digest attribute matched + // digest of original data + + // the data actually signed is the DER encoding of + // the authenticated attributes (tagged with + // the "SET OF" tag, not 0xA0). + dataSigned = authenticatedAttributes.getDerEncoding(); + } + + // put together digest algorithm and encryption algorithm + // to form signing algorithm + String encryptionAlgname = + getDigestEncryptionAlgorithmId().getName(); + + String algname; + if (encryptionAlgname.equals("DSA") || + encryptionAlgname.equals("SHA1withDSA")) { + algname = "DSA"; + } else { + algname = digestAlgname + "/" + encryptionAlgname; + } + + Signature sig = Signature.getInstance(algname); + X509Certificate cert = getCertificate(block); + + if (cert == null) { + return null; + } + + PublicKey key = cert.getPublicKey(); + sig.initVerify(key); + + sig.update(dataSigned); + + if (sig.verify(encryptedDigest)) { + return this; + } + + } catch (IOException e) { + throw new SignatureException("IO error verifying signature:\n" + + e.getMessage()); + + } catch (InvalidKeyException e) { + throw new SignatureException("InvalidKey: " + e.getMessage()); + + } + return null; + } + /* Verify the content of the pkcs7 block. */ - SignerInfo verify(PKCS7 block) throws NoSuchAlgorithmException, - SignatureException { - return verify(block, null); + SignerInfo verify(PKCS7 block) + throws NoSuchAlgorithmException, SignatureException { + return verify(block, null); } + public BigInt getVersion() { - return version; + return version; } public X500Name getIssuerName() { - return issuerName; + return issuerName; } public BigInt getCertificateSerialNumber() { - return certificateSerialNumber; + return certificateSerialNumber; } public AlgorithmId getDigestAlgorithmId() { - return digestAlgorithmId; + return digestAlgorithmId; } public PKCS9Attributes getAuthenticatedAttributes() { - return authenticatedAttributes; + return authenticatedAttributes; } public AlgorithmId getDigestEncryptionAlgorithmId() { - return digestEncryptionAlgorithmId; + return digestEncryptionAlgorithmId; } public byte[] getEncryptedDigest() { - return encryptedDigest; + return encryptedDigest; } public PKCS9Attributes getUnauthenticatedAttributes() { - return unauthenticatedAttributes; + return unauthenticatedAttributes; } public String toString() { - netscape.security.util.PrettyPrintFormat pp = new netscape.security.util.PrettyPrintFormat( - " ", 20); - String digestbits = pp.toHexString(encryptedDigest); - - String out = ""; - - out += "Signer Info for (issuer): " + issuerName + "\n"; - out += "\tversion: " + version + "\n"; - out += "\tcertificateSerialNumber: " + certificateSerialNumber + "\n"; - out += "\tdigestAlgorithmId: " + digestAlgorithmId + "\n"; - if (authenticatedAttributes != null) { - out += "\tauthenticatedAttributes: " + authenticatedAttributes - + "\n"; - } - out += "\tdigestEncryptionAlgorithmId: " + digestEncryptionAlgorithmId - + "\n"; - - out += "\tencryptedDigest: " + "\n" + digestbits + "\n"; - if (unauthenticatedAttributes != null) { - out += "\tunauthenticatedAttributes: " + unauthenticatedAttributes - + "\n"; - } - return out; + netscape.security.util.PrettyPrintFormat pp = + new netscape.security.util.PrettyPrintFormat(" ", 20); + String digestbits = pp.toHexString(encryptedDigest); + + String out = ""; + + out += "Signer Info for (issuer): " + issuerName + "\n"; + out += "\tversion: " + version + "\n"; + out += "\tcertificateSerialNumber: " + certificateSerialNumber + + "\n"; + out += "\tdigestAlgorithmId: " + digestAlgorithmId + "\n"; + if (authenticatedAttributes != null) { + out += "\tauthenticatedAttributes: " + authenticatedAttributes + + "\n"; + } + out += "\tdigestEncryptionAlgorithmId: " + digestEncryptionAlgorithmId + + "\n"; + + out += "\tencryptedDigest: " + "\n" + + digestbits + "\n"; + if (unauthenticatedAttributes != null) { + out += "\tunauthenticatedAttributes: " + + unauthenticatedAttributes + "\n"; + } + return out; } } + + + + |