Index: modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyCertGenerator.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyCertGenerator.java (revision 447324) +++ modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyCertGenerator.java (working copy) @@ -46,6 +46,7 @@ import org.apache.harmony.security.provider.cert.X509CertImpl; import org.apache.harmony.security.x501.Name; import org.apache.harmony.security.x509.AlgorithmIdentifier; +import org.apache.harmony.security.x509.BasicConstraints; import org.apache.harmony.security.x509.Extension; import org.apache.harmony.security.x509.Extensions; import org.apache.harmony.security.x509.SubjectPublicKeyInfo; @@ -434,12 +435,9 @@ if (version == 1 || version == 2) { // generate extensions - ArrayList basicConstraints = new ArrayList(2); - basicConstraints.add(new Boolean(isCA)); - basicConstraints.add(BigInteger.valueOf(Integer.MAX_VALUE)); extensions = new Extensions(Collections - .singletonList(new Extension.BasicConstraints( - basicConstraints, false))); + .singletonList(new Extension("2.5.29.19", false, + new BasicConstraints(isCA, Integer.MAX_VALUE)))); } // generate the TBSCertificate to put it into the X.509 cert TBSCertificate tbsCertificate = new TBSCertificate( Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CertImplTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CertImplTest.java (revision 447324) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CertImplTest.java (working copy) @@ -150,35 +150,25 @@ // Supported critical extensions (as specified in rfc 3280 // http://www.ietf.org/rfc/rfc3280.txt): // Key Usage - new Extension("2.5.29.15", true, - ASN1BitString.getInstance() - .encode(new BitString(extnKeyUsage))), + new Extension("2.5.29.15", true, new KeyUsage(extnKeyUsage)), // Basic Constraints - new Extension("2.5.29.19", true, - Extension.BasicConstraints.ASN1.encode( - new Object[] - {Boolean.TRUE, BigInteger.valueOf(extnBCLen)})), + new Extension("2.5.29.19", true, new BasicConstraints(true, extnBCLen)), // Certificate Policies with ANY policy new Extension("2.5.29.32", true, - new CertificatePolicies(Arrays.asList(new Object[] { - new PolicyInformation("2.5.29.32.0")})) - .getEncoded()),//extValEncoding), + new CertificatePolicies() + .addPolicyInformation(new PolicyInformation("2.5.29.32.0"))), // Subject Alternative Name new Extension("2.5.29.17", true, - GeneralNames.ASN1.encode(extnSANames)), + new AlternativeName(AlternativeName.SUBJECT, extnSANames)), // Name Constraints new Extension("2.5.29.30", true, new NameConstraints().getEncoded()), // Policy Constraints - new Extension("2.5.29.36", true, - new PolicyConstraints().getEncoded()), + new Extension("2.5.29.36", true, new PolicyConstraints(1, 2)), // Extended Key Usage - new Extension("2.5.29.37", true, - Extension.ExtendedKeyUsage.ASN1.encode( - extnExtendedKeyUsage)), + new Extension("2.5.29.37", true, new ExtendedKeyUsage(extnExtendedKeyUsage)), // Inhibit Any-Policy - new Extension("2.5.29.54", true, - ASN1Integer.getInstance().encode(ASN1Integer.fromIntValue(1))), + new Extension("2.5.29.54", true, new InhibitAnyPolicy(1)), // Unsupported critical extensions: @@ -190,7 +180,7 @@ // Issuer Alternative Name new Extension("2.5.29.18", false, - GeneralNames.ASN1.encode(extnSANames)), + new AlternativeName(AlternativeName.ISSUER, extnSANames)), // CRL Distribution Points new Extension("2.5.29.31", false, new ASN1Sequence(new ASN1Type[] {}) { @@ -198,9 +188,14 @@ } }.encode(null)), // Authority Key Identifier - new Extension("2.5.29.35", false, extValEncoding), + new Extension("2.5.29.35", false, + new AuthorityKeyIdentifier( + // random value for key identifier + new byte[] {1, 2, 3, 4, 5}, extnSANames, serialNumber)), // Subject Key Identifier - new Extension("2.5.29.14", false, extValEncoding), + new Extension("2.5.29.14", false, + // random value for key identifier + new SubjectKeyIdentifier(new byte[] {1, 2, 3, 4, 5})), // Policy Mappings new Extension("2.5.29.33", false, extValEncoding), }; @@ -237,7 +232,7 @@ keyEncoding = subjectPublicKeyInfo.getEncoded(); Extensions exts = new Extensions(Arrays.asList(extensions)); - + TBSCertificate tbsCertificate = new TBSCertificate(version, serialNumber, signature, issuer, validity, subject, subjectPublicKeyInfo, Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CRLImplTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CRLImplTest.java (revision 447324) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CRLImplTest.java (working copy) @@ -48,11 +48,14 @@ import org.apache.harmony.security.x509.AlgorithmIdentifier; import org.apache.harmony.security.x509.AuthorityKeyIdentifier; import org.apache.harmony.security.x509.Certificate; +import org.apache.harmony.security.x509.CertificateIssuer; import org.apache.harmony.security.x509.CertificateList; import org.apache.harmony.security.x509.Extension; import org.apache.harmony.security.x509.Extensions; import org.apache.harmony.security.x509.GeneralName; import org.apache.harmony.security.x509.GeneralNames; +import org.apache.harmony.security.x509.InvalidityDate; +import org.apache.harmony.security.x509.ReasonCode; import org.apache.harmony.security.x509.SubjectPublicKeyInfo; import org.apache.harmony.security.x509.TBSCertList; import org.apache.harmony.security.x509.TBSCertificate; @@ -90,11 +93,13 @@ private static Extensions crlEntryExtensions = new Extensions(); static { // Reason Code - crlEntryExtensions.addExtension(new Extension.ReasonCode(1)); + crlEntryExtensions.addExtension( + new Extension("2.5.29.21", Extension.NON_CRITICAL, + new ReasonCode(ReasonCode.KEY_COMPROMISE))); // Invalidity Date Extension crlEntryExtensions.addExtension( - new Extension.InvalidityDate(new Date()) - ); + new Extension("2.5.29.24", Extension.NON_CRITICAL, + new InvalidityDate(new Date()))); // add the Certificate Issuer Extension to check if implementation // support indirect CRLs. As says rfc 3280 (p.62): // "If used by conforming CRL issuers, this extension MUST always be @@ -103,9 +108,10 @@ // RECOMMENDS that implementations recognize this extension." try { crlEntryExtensions.addExtension( - new Extension.CertificateIssuer( + new Extension("2.5.29.29", true, + new CertificateIssuer( new GeneralName(new Name(certIssuerName)) - ) + )) ); } catch (Exception e) { e.printStackTrace(); @@ -132,14 +138,17 @@ ASN1Integer.getInstance().encode( BigInteger.valueOf(4444).toByteArray())), // Authority Key Identifier - new Extension.AuthKeyId( + new Extension("2.5.29.35", false, new AuthorityKeyIdentifier( - new byte[] {1, 2, 3, 4, 5}, // keyIdentifier (random value) - new GeneralNames(Arrays.asList(new GeneralName[] { - new GeneralName(new Name(certIssuerName)) - })), // authorityCertIssuer - certSerialNumber2 // authorityCertSerialNumber - )) + // keyIdentifier (random value) + new byte[] {1, 2, 3, 4, 5}, + // authorityCertIssuer + new GeneralNames( + Arrays.asList(new GeneralName[] { + new GeneralName(new Name(certIssuerName)) + })), + // authorityCertSerialNumber + certSerialNumber2)), })); } catch (Exception e) { e.printStackTrace(); Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CertFactoryPerfTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CertFactoryPerfTest.java (revision 447324) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CertFactoryPerfTest.java (working copy) @@ -153,31 +153,23 @@ ASN1BitString.getInstance() .encode(new BitString(extnKeyUsage))), // Basic Constraints - new Extension("2.5.29.19", true, - Extension.BasicConstraints.ASN1.encode( - new Object[] - {Boolean.TRUE, BigInteger.valueOf(extnBCLen)})), + new Extension("2.5.29.19", true, new BasicConstraints(true, extnBCLen)), // Certificate Policies with ANY policy new Extension("2.5.29.32", true, - new CertificatePolicies(Arrays.asList(new Object[] { - new PolicyInformation("2.5.29.32.0")})) - .getEncoded()),//extValEncoding), + new CertificatePolicies() + .addPolicyInformation(new PolicyInformation("2.5.29.32.0"))), // Subject Alternative Name new Extension("2.5.29.17", true, - GeneralNames.ASN1.encode(extnSANames)), + new AlternativeName(AlternativeName.SUBJECT, extnSANames)), // Name Constraints new Extension("2.5.29.30", true, new NameConstraints().getEncoded()), // Policy Constraints - new Extension("2.5.29.36", true, - new PolicyConstraints().getEncoded()), + new Extension("2.5.29.36", true, new PolicyConstraints(1, 2)), // Extended Key Usage - new Extension("2.5.29.37", true, - Extension.ExtendedKeyUsage.ASN1.encode( - extnExtendedKeyUsage)), + new Extension("2.5.29.37", true, new ExtendedKeyUsage(extnExtendedKeyUsage)), // Inhibit Any-Policy - new Extension("2.5.29.54", true, - ASN1Integer.getInstance().encode(ASN1Integer.fromIntValue(1))), + new Extension("2.5.29.54", true, new InhibitAnyPolicy(1)), // Unsupported critical extensions: new Extension("1.2.77.777", true, extValEncoding), @@ -187,7 +179,7 @@ // Issuer Alternative Name new Extension("2.5.29.18", false, - GeneralNames.ASN1.encode(extnSANames)), + new AlternativeName(AlternativeName.ISSUER, extnSANames)), // CRL Distribution Points new Extension("2.5.29.31", false, new ASN1Sequence(new ASN1Type[] {}) { @@ -195,9 +187,14 @@ } }.encode(null)), // Authority Key Identifier - new Extension("2.5.29.35", false, extValEncoding), + new Extension("2.5.29.35", false, + new AuthorityKeyIdentifier( + // random value for key identifier + new byte[] {1, 2, 3, 4, 5}, extnSANames, serialNumber)), // Subject Key Identifier - new Extension("2.5.29.14", false, extValEncoding), + new Extension("2.5.29.14", false, + // random value for key identifier + new SubjectKeyIdentifier(new byte[] {1, 2, 3, 4, 5})), // Policy Mappings new Extension("2.5.29.33", false, extValEncoding), }; Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CRLEntryImplTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CRLEntryImplTest.java (revision 447324) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/cert/X509CRLEntryImplTest.java (working copy) @@ -28,6 +28,7 @@ import org.apache.harmony.security.provider.cert.X509CRLEntryImpl; import org.apache.harmony.security.x509.Extension; import org.apache.harmony.security.x509.Extensions; +import org.apache.harmony.security.x509.ReasonCode; import org.apache.harmony.security.x509.TBSCertList; import junit.framework.Test; @@ -52,7 +53,9 @@ Extensions crlEntryExtensions = new Extensions(); // add reason code extension which OID is 2.5.29.21 // see RFC 3280 http://www.ietf.org/rfc/rfc3280.txt - crlEntryExtensions.addExtension(new Extension.ReasonCode(1)); + crlEntryExtensions.addExtension( + new Extension("2.5.29.21", Extension.NON_CRITICAL, + new ReasonCode(ReasonCode.KEY_COMPROMISE))); // crl entry X509CRLEntryImpl crlEntry = new X509CRLEntryImpl( new TBSCertList.RevokedCertificate( Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/Extensions.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/Extensions.java (revision 447324) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/Extensions.java (working copy) @@ -58,7 +58,7 @@ "2.5.29.30", "2.5.29.36", "2.5.29.37", "2.5.29.54"}); // the values of extensions of the structure - private List extensions; + private List extensions; private Set critical; private Set noncritical; // the flag showing is there any unsupported critical extension @@ -200,10 +200,11 @@ */ public boolean[] valueOfKeyUsage() { Extension extn = getExtensionByOID("2.5.29.15"); - if (extn == null) { + KeyUsage kUsage = null; + if ((extn == null) || ((kUsage = extn.getKeyUsageValue()) == null)) { return null; } - return ((Extension.KeyUsage) extn).getKeyUsage(); + return kUsage.getKeyUsage(); } /** @@ -228,7 +229,8 @@ if (extn == null) { return null; } - return (List) Extension.ExtendedKeyUsage.ASN1.decode(extn.getExtnValue()); + return ((ExtendedKeyUsage) + extn.getDecodedExtensionValue()).getExtendedKeyUsage(); } /** @@ -250,10 +252,12 @@ */ public int valueOfBasicConstrains() { Extension extn = getExtensionByOID("2.5.29.19"); - if (extn == null) { + BasicConstraints bc = null; + if ((extn == null) + || ((bc = extn.getBasicConstraintsValue()) == null)) { return Integer.MAX_VALUE; } - return ((Extension.BasicConstraints) extn).getPathLenConstraint(); + return bc.getPathLenConstraint(); } /** @@ -300,8 +304,8 @@ if (extn == null) { return null; } - return ((GeneralNames) GeneralNames.ASN1.decode(extn.getExtnValue())) - .getPairsList(); + return ((GeneralNames) + GeneralNames.ASN1.decode(extn.getExtnValue())).getPairsList(); } /** @@ -323,8 +327,8 @@ if (extn == null) { return null; } - return (X500Principal) - Extension.CertificateIssuer.ASN1.decode(extn.getExtnValue()); + return ((CertificateIssuer) + extn.getDecodedExtensionValue()).getIssuer(); } /** Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/ExtensionValue.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/ExtensionValue.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/ExtensionValue.java (revision 0) @@ -0,0 +1,66 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import org.apache.harmony.security.utils.Array; + +/** + * Base class for extension value structures. + */ +public class ExtensionValue { + + /** + * Encoded form of the extension. + */ + protected byte[] encoding; + + /** + * Default constructor. + */ + public ExtensionValue() { } + + /** + * Creates the object on the base of its encoded form. + */ + public ExtensionValue(byte[] encoding) { + this.encoding = encoding; + } + + /** + * Returns encoded form of the object. + */ + public byte[] getEncoded() { + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("Unparseable extension value:\n"); + if (encoding == null) { + encoding = getEncoded(); + } + if (encoding == null) { + buffer.append("NULL\n"); + } else { + buffer.append(Array.toString(encoding, "")); + } + }; +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/CertificatePolicies.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/CertificatePolicies.java (revision 447324) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/CertificatePolicies.java (working copy) @@ -21,6 +21,7 @@ package org.apache.harmony.security.x509; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -43,7 +44,7 @@ * */ -public class CertificatePolicies { +public class CertificatePolicies extends ExtensionValue { // the values of policyInformation field of the structure private List policyInformations; @@ -62,6 +63,13 @@ public CertificatePolicies(List policyInformations) { this.policyInformations = policyInformations; } + + public static CertificatePolicies decode(byte[] encoding) + throws IOException { + CertificatePolicies cps = ((CertificatePolicies) ASN1.decode(encoding)); + cps.encoding = encoding; + return cps; + } // // TODO @@ -86,12 +94,14 @@ * @param policyInformation: PolicyInformation * @return */ - public void addPolicyInformation(PolicyInformation policyInformation) { + public CertificatePolicies addPolicyInformation( + PolicyInformation policyInformation) { encoding = null; if (policyInformations == null) { policyInformations = new ArrayList(); } policyInformations.add(policyInformation); + return this; } /** Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/SubjectKeyIdentifier.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/SubjectKeyIdentifier.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/SubjectKeyIdentifier.java (revision 0) @@ -0,0 +1,82 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; + +import org.apache.harmony.security.asn1.ASN1OctetString; +import org.apache.harmony.security.utils.Array; + +/** + * Subject Key Identifier Extension (OID = 2.5.29.14). + * + * The ASN.1 definitionn for extension is: + * + *
+ *  id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
+ *
+ *  SubjectKeyIdentifier ::= KeyIdentifier
+ *
+ *  KeyIdentifier ::= OCTET STRING
+ * 
+ * (as specified in RFC 3280 http://www.ietf.org/rfc/rfc3280.txt) + */ +public class SubjectKeyIdentifier extends ExtensionValue { + + // the value of key identifier + private final byte[] keyIdentifier; + + /** + * Creates the object on the base of the value of key identifier. + */ + public SubjectKeyIdentifier(byte[] keyIdentifier) { + this.keyIdentifier = keyIdentifier; + } + + /** + * Creates an object on the base of its encoded form. + */ + public static SubjectKeyIdentifier decode(byte[] encoding) + throws IOException { + SubjectKeyIdentifier res = new SubjectKeyIdentifier((byte[]) + ASN1OctetString.getInstance().decode(encoding)); + res.encoding = encoding; + return res; + } + + /** + * Returns ASN.1 encoded form of extension. + * @return a byte array containing ASN.1 encoded form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1OctetString.getInstance().encode(keyIdentifier); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("SubjectKeyIdentifier: [\n"); + buffer.append(Array.toString(keyIdentifier, "")); + buffer.append("]\n"); + } +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/Extension.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/Extension.java (revision 447324) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/Extension.java (working copy) @@ -41,6 +41,7 @@ import org.apache.harmony.security.asn1.BitString; import org.apache.harmony.security.asn1.ObjectIdentifier; import org.apache.harmony.security.x501.Name; +import org.apache.harmony.security.utils.Array; /** * The class incapsulates the ASN.1 DER encoding/decoding work @@ -66,18 +67,32 @@ // constants: the extension OIDs // certificate extensions: - public static final int[] KEY_USAGE = new int[] {2, 5, 29, 15}; - public static final int[] EXTENDED_KEY_USAGE = new int[] {2, 5, 29, 37}; - public static final int[] BASIC_CONSTRAINTS = new int[] {2, 5, 29, 19}; - public static final int[] SUBJECT_ALT_NAME = new int[] {2, 5, 29, 17}; - public static final int[] CRL_DISTR_POINTS = new int[] {2, 5, 29, 31}; - public static final int[] AUTH_KEY_ID = new int[] {2, 5, 29, 35}; + public static final int[] SUBJ_DIRECTORY_ATTRS = {2, 5, 29, 9}; + public static final int[] SUBJ_KEY_ID = {2, 5, 29, 14}; + public static final int[] KEY_USAGE = {2, 5, 29, 15}; + public static final int[] PRIVATE_KEY_USAGE_PERIOD = {2, 5, 29, 16}; + public static final int[] SUBJECT_ALT_NAME = {2, 5, 29, 17}; + public static final int[] ISSUER_ALTERNATIVE_NAME = {2, 5, 29, 18}; + public static final int[] BASIC_CONSTRAINTS = {2, 5, 29, 19}; + public static final int[] NAME_CONSTRAINTS = {2, 5, 29, 30}; + public static final int[] CRL_DISTR_POINTS = {2, 5, 29, 31}; + public static final int[] CERTIFICATE_POLICIES = {2, 5, 29, 32}; + public static final int[] POLICY_MAPPINGS = {2, 5, 29, 33}; + public static final int[] AUTH_KEY_ID = {2, 5, 29, 35}; + public static final int[] POLICY_CONSTRAINTS = {2, 5, 29, 36}; + public static final int[] EXTENDED_KEY_USAGE = {2, 5, 29, 37}; + public static final int[] FRESHEST_CRL = {2, 5, 29, 46}; + public static final int[] INHIBIT_ANY_POLICY = {2, 5, 29, 54}; + public static final int[] AUTHORITY_INFO_ACCESS = + {1, 3, 6, 1, 5, 5, 7, 1, 1}; + public static final int[] SUBJECT_INFO_ACCESS = + {1, 3, 6, 1, 5, 5, 7, 1, 11}; // crl extensions: - public static final int[] ISSUING_DISTR_POINT = new int[] {2, 5, 29, 28}; + public static final int[] ISSUING_DISTR_POINT = {2, 5, 29, 28}; // crl entry extensions: - public static final int[] CERTIFICATE_ISSUER = new int[] {2, 5, 29, 29}; - public static final int[] INVALIDITY_DATE = new int[] {2, 5, 29, 24}; - public static final int[] REASON_CODE = new int[] {2, 5, 29, 21}; + public static final int[] CERTIFICATE_ISSUER = {2, 5, 29, 29}; + public static final int[] INVALIDITY_DATE = {2, 5, 29, 24}; + public static final int[] REASON_CODE = {2, 5, 29, 21}; // the value of extnID field of the structure private final int[] extnID; @@ -90,6 +105,10 @@ private byte[] encoding; // the raw (not decoded) value of extnValue field of the structure private byte[] rawExtnValue; + // the decoded extension value + protected ExtensionValue extnValueObject; + // tells whether extension value has been decoded or not + private boolean valueDecoded = false; /** * TODO @@ -97,6 +116,22 @@ * @param critical: boolean * @param extnValue: byte[] */ + public Extension(String extnID, boolean critical, + ExtensionValue extnValueObject) { + this.extnID_str = extnID; + this.extnID = ObjectIdentifier.toIntArray(extnID); + this.critical = critical; + this.extnValueObject = extnValueObject; + this.valueDecoded = true; + this.extnValue = extnValueObject.getEncoded(); + } + + /** + * TODO + * @param extnID: String + * @param critical: boolean + * @param extnValue: byte[] + */ public Extension(String extnID, boolean critical, byte[] extnValue) { this.extnID_str = extnID; this.extnID = ObjectIdentifier.toIntArray(extnID); @@ -142,10 +177,13 @@ // @param encoding: byte[] // private Extension(int[] extnID, boolean critical, byte[] extnValue, - byte[] rawExtnValue, byte[] encoding) { + byte[] rawExtnValue, byte[] encoding, + ExtensionValue decodedExtValue) { this(extnID, critical, extnValue); this.rawExtnValue = rawExtnValue; this.encoding = encoding; + this.extnValueObject = decodedExtValue; + this.valueDecoded = (decodedExtValue != null); } /** @@ -207,388 +245,74 @@ && (critical == extn.critical) && Arrays.equals(extnValue, extn.extnValue); } - - // ------------------------------------------------------------------------- - // - // The values of some extensions should be decoded on the certificate - // decoding stage. Following are the classes of such extensions. - // - - /** - * Key Usage Extension (OID = 2.5.29.15). - * - * The ASN.1 definitionn for Key Usage Extension is: - * - *
-     * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
-     *
-     * KeyUsage ::= BIT STRING {
-     *     digitalSignature        (0),
-     *     nonRepudiation          (1),
-     *     keyEncipherment         (2),
-     *     dataEncipherment        (3),
-     *     keyAgreement            (4),
-     *     keyCertSign             (5),
-     *     cRLSign                 (6),
-     *     encipherOnly            (7),
-     *     decipherOnly            (8) 
-     * }
-     * (as specified in RFC 3280)
-     * 
- */ - public static class KeyUsage extends Extension { - // the value of extension - private final boolean[] keyUsage; - public static final ASN1Type ASN1 = new ASN1BitString.ASN1NamedBitList(9); - - - public KeyUsage(boolean[] keyUsage) { - super(KEY_USAGE, true, - ASN1BitString.getInstance().encode(new BitString(keyUsage))); - this.keyUsage = keyUsage; - } - private KeyUsage(byte[] extnValue, byte[] rawExtnValue, byte[] encoding) - throws IOException { - super(KEY_USAGE, true, extnValue, - rawExtnValue, encoding); - this.keyUsage = (boolean[]) ASN1.decode(extnValue); + public ExtensionValue getDecodedExtensionValue() throws IOException { + if (!valueDecoded) { + decodeExtensionValue(); } - - public boolean[] getKeyUsage() { - return keyUsage; - } + return extnValueObject; } - - /** - * Extended Key Usage Extension (OID == 2.5.29.37). - * - * The ASN.1 definitionn for Extended Key Usage Extension is: - * - *
 
-     *  id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
-     *  
-     *  ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
-     *  
-     *  KeyPurposeId ::= OBJECT IDENTIFIER
-     * 
- * (as specified in RFC 3280) - */ - public static class ExtendedKeyUsage extends Extension { - // the value of extension - private final List keys; - - public ExtendedKeyUsage(List keys, boolean critical) { - super(EXTENDED_KEY_USAGE, critical, - ASN1BitString.getInstance().encode(ASN1.encode(keys))); - this.keys = keys; - } - public List getExtendedKeyUsage() { - return keys; + public KeyUsage getKeyUsageValue() { + if (!valueDecoded) { + try { + decodeExtensionValue(); + } catch (IOException e) { } } - - public static ASN1Type ASN1 = - new ASN1SequenceOf(new ASN1Oid() { - - public Object getDecodedObject(BerInputStream in) - throws IOException { - int[] oid = (int[]) super.getDecodedObject(in); - return ObjectIdentifier.toString(oid); - } - - }); - } - - - /** - * Basic Constraints Extension (OID == 2.5.29.19). - * - * The ASN.1 definitionn for Basic Constraints Extension is: - * - *
 
-     *   id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
-     *
-     *   BasicConstraints ::= SEQUENCE {
-     *        cA                      BOOLEAN DEFAULT FALSE,
-     *        pathLenConstraint       INTEGER (0..MAX) OPTIONAL 
-     *   }
-     * 
- * (as specified in RFC 3280) - */ - public static class BasicConstraints extends Extension { - // the value of extension - private boolean cA = false; - - private int pathLenConstraint = Integer.MAX_VALUE; - - // Constructor for creating the extension without - // encoding provided - public BasicConstraints(List keys, boolean critical) { - super(BASIC_CONSTRAINTS, critical, - ASN1.encode(keys.toArray())); // make extnValue + if (extnValueObject instanceof KeyUsage) { + return (KeyUsage) extnValueObject; + } else { + return null; } - - private BasicConstraints(byte[] extnValue, byte[] rawExtnValue, - byte[] encoding) throws IOException { - super(BASIC_CONSTRAINTS, true, - extnValue, rawExtnValue, encoding); - Object[] values = (Object[]) ASN1.decode(extnValue); - cA = ((Boolean) values[0]).booleanValue(); - if (values[1] != null) { - pathLenConstraint = new BigInteger((byte[]) values[1]).intValue(); - } - } - - public boolean getCA() { - return cA; - } - - public int getPathLenConstraint() { - return pathLenConstraint; - } - - public static ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] { - ASN1Boolean.getInstance(), ASN1Integer.getInstance() }) { - { - setDefault(Boolean.FALSE, 0); - setOptional(1); - } - - public Object getDecodedObject(BerInputStream in) - throws IOException { - return in.content; - } - - protected void getValues(Object object, Object[] values) { - Object[] vals = (Object[]) object; - values[0] = vals[0]; - values[1] = ((BigInteger) vals[1]).toByteArray(); - } - - }; } - /* - * CRL Distribution Points Extension (OID = 2.5.29.31). - *
-     *  id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 }
-     *
-     *  CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
-     * 
-     *  DistributionPoint ::= SEQUENCE {
-     *       distributionPoint       [0]     DistributionPointName OPTIONAL,
-     *       reasons                 [1]     ReasonFlags OPTIONAL,
-     *       cRLIssuer               [2]     GeneralNames OPTIONAL }
-     *
-     *  DistributionPointName ::= CHOICE {
-     *       fullName                [0]     GeneralNames,
-     *       nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
-     *  
-     *  ReasonFlags ::= BIT STRING {
-     *       unused                  (0),
-     *       keyCompromise           (1),
-     *       cACompromise            (2),
-     *       affiliationChanged      (3),
-     *       superseded              (4),
-     *       cessationOfOperation    (5),
-     *       certificateHold         (6),
-     *       privilegeWithdrawn      (7),
-     *       aACompromise            (8) 
-     *  }
-     *
-     * 
- * (as specified in RFC 3280) - public static class CRLDistributionPoints extends Extension { - - private final CRLDistributionPoints distr_points; - - public CRLDistributionPoints(CRLDistributionPoints distr_points) { - super(CRL_DISTR_POINTS, NON_CRITICAL, - distr_points.getEncoded()); - this.distr_points = distr_points; + public BasicConstraints getBasicConstraintsValue() { + if (!valueDecoded) { + try { + decodeExtensionValue(); + } catch (IOException e) { } } - - public static ASN1Type ASN1 = CRLDistributionPoints.ASN1; - } - */ - - - /* - * Subject Alternative Name Extension (OID == 2.5.29.17). - * - * The ASN.1 definitionn for Subject Alternative Name is: - * - *
 
-     *  id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
-     *  
-     *  SubjectAltName ::= GeneralNames
-     * 
- * (as specified in RFC 3280) - public static class SubjectAlternativeNames extends Extension { - // the value of extension - private GeneralNames generalNames; - - // TODO: Constructor for creating the extension without - // encoding provided - - private SubjectAlternativeNames(byte[] extnValue, - byte[] encoding) throws IOException { - super(ASN1Oid.toString(SUBJECT_ALT_NAME), true, - extnValue, encoding); - generalNames = (GeneralNames) GeneralNames.ASN1.decode(extnValue); + if (extnValueObject instanceof BasicConstraints) { + return (BasicConstraints) extnValueObject; + } else { + return null; } - - public List getGeneralNames() { - return generalNames.getPairsList(); - } } - */ - - /** - * Authority Key Identifier Extension (OID = 2.5.29.35). - *
-     *   id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
-     *
-     *   AuthorityKeyIdentifier ::= SEQUENCE {
-     *      keyIdentifier             [0] KeyIdentifier           OPTIONAL,
-     *      authorityCertIssuer       [1] GeneralNames            OPTIONAL,
-     *      authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
-     *
-     *   KeyIdentifier ::= OCTET STRING
-     * 
- * (as specified in RFC 3280) - */ - public static class AuthKeyId extends Extension { - public AuthKeyId(AuthorityKeyIdentifier authKeyID) { - super(AUTH_KEY_ID, NON_CRITICAL, authKeyID.getEncoded()); + private void decodeExtensionValue() throws IOException { + if (valueDecoded) { + return; } - } - - /** - * CRL Entry's Certificate Issuer Extension (OID = 2.5.29.29). - * It is a CRL entry extension and contains the GeneralNames describing - * the issuer of revoked certificate. Its ASN.1 notation is as follows: - *
-     *   id-ce-certificateIssuer   OBJECT IDENTIFIER ::= { id-ce 29 }
-     *
-     *   certificateIssuer ::=     GeneralNames
-     * 
- * (as specified in RFC 3280) - * In java implementation it is presumed that GeneralNames cansist of - * one element and its type is directoryName. - */ - public static class CertificateIssuer extends Extension { - - public CertificateIssuer(GeneralName issuer) { - super(CERTIFICATE_ISSUER, CRITICAL, ASN1.encode(issuer)); + valueDecoded = true; + if (oidEquals(extnID, SUBJ_KEY_ID)) { + extnValueObject = SubjectKeyIdentifier.decode(extnValue); + } else if (oidEquals(extnID, KEY_USAGE)) { + extnValueObject = new KeyUsage(extnValue); + } else if (oidEquals(extnID, SUBJECT_ALT_NAME)) { + extnValueObject = new AlternativeName( + AlternativeName.SUBJECT, extnValue); + } else if (oidEquals(extnID, ISSUER_ALTERNATIVE_NAME)) { + extnValueObject = new AlternativeName( + AlternativeName.SUBJECT, extnValue); + } else if (oidEquals(extnID, BASIC_CONSTRAINTS)) { + extnValueObject = new BasicConstraints(extnValue); + } else if (oidEquals(extnID, CERTIFICATE_POLICIES)) { + extnValueObject = CertificatePolicies.decode(extnValue); + } else if (oidEquals(extnID, AUTH_KEY_ID)) { + extnValueObject = AuthorityKeyIdentifier.decode(extnValue); + } else if (oidEquals(extnID, POLICY_CONSTRAINTS)) { + extnValueObject = new PolicyConstraints(extnValue); + } else if (oidEquals(extnID, EXTENDED_KEY_USAGE)) { + extnValueObject = new ExtendedKeyUsage(extnValue); + } else if (oidEquals(extnID, INHIBIT_ANY_POLICY)) { + extnValueObject = new InhibitAnyPolicy(extnValue); + } else if (oidEquals(extnID, CERTIFICATE_ISSUER)) { + extnValueObject = new CertificateIssuer(extnValue); + } else if (oidEquals(extnID, CERTIFICATE_ISSUER)) { + extnValueObject = new ReasonCode(extnValue); } - - public static ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] { - GeneralName.ASN1 - }) { - public Object getDecodedObject(BerInputStream in) { - return ((Name) ((GeneralName) ((Object[]) in.content)[0]) - .getName()).getX500Principal(); - } - - protected void getValues(Object object, Object[] values) { - values[0] = object; - } - }; } - - /** - * CRL Entry's Invalidity Date Extension (OID = 2.5.29.24). - *
-     *   id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
-     *
-     *   invalidityDate ::=  GeneralizedTime
-     * 
- * (as specified in RFC 3280) - */ - public static class InvalidityDate extends Extension { - public InvalidityDate(Date date) { - super(INVALIDITY_DATE, NON_CRITICAL, ASN1.encode(date)); - } - - public static ASN1Type ASN1 = ASN1GeneralizedTime.getInstance(); - } - - /** - * CRL Entry's Reason Code Extension (OID = 2.5.29.21). - *
-     *  id-ce-cRLReason OBJECT IDENTIFIER ::= { id-ce 21 }
-     *  
-     *  -- reasonCode ::= { CRLReason }
-     *  CRLReason ::= ENUMERATED {
-     *       unspecified             (0),
-     *       keyCompromise           (1),
-     *       cACompromise            (2),
-     *       affiliationChanged      (3),
-     *       superseded              (4),
-     *       cessationOfOperation    (5),
-     *       certificateHold         (6),
-     *       removeFromCRL           (8),
-     *       privilegeWithdrawn      (9),
-     *       aACompromise           (10) 
-     *  }
-     * 
- * (as specified in RFC 3280) - */ - public static class ReasonCode extends Extension { - - public ReasonCode(int code) { - super(REASON_CODE, NON_CRITICAL, - ASN1.encode(new byte[] {(byte) code})); - } - - public static ASN1Type ASN1 = ASN1Enumerated.getInstance(); - } - - /* - * CRL's Issuing Distribution Point Extension (OID = 2.5.29.28). - *
-     *   id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
-     *
-     *   issuingDistributionPoint ::= SEQUENCE {
-     *      distributionPoint          [0] DistributionPointName OPTIONAL,
-     *      onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
-     *      onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
-     *      onlySomeReasons            [3] ReasonFlags OPTIONAL,
-     *      indirectCRL                [4] BOOLEAN DEFAULT FALSE,
-     *      onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE 
-     *   }
-     * 
- * (as specified in RFC 3280) - public static class IssuingDistributionPoint extends Extension { - - private final int code; - - public IssuingDistributionPoint(int code) { - super(ISSUING_DISTR_POINT, CRITICAL, - ASN1.encode(new byte[] {(byte) code})); - this.code = code; - } - - public static ASN1Type ASN1 = new ASN1Sequence( - new ASN1Type[] { - new ASN1Implicit(0, DistributionPointName.ASN1), - new ASN1Implicit(1, ASN1Boolean.getInstance()), - new ASN1Implicit(2, ASN1Boolean.getInstance()), - new ASN1Implicit(3, ReasonFlags.ASN1), - new ASN1Implicit(4, ASN1Boolean.getInstance()), - new ASN1Implicit(5, ASN1Boolean.getInstance()) - }) { - // TODO: tbd - }; - } - */ - - - // Compares two OIDs private static boolean oidEquals(int[] oid1, int[] oid2) { int length = oid1.length; @@ -630,17 +354,18 @@ byte[] extnValue = (byte[]) ((Object[]) values[2])[0]; byte[] rawExtnValue = (byte[]) ((Object[]) values[2])[1]; + ExtensionValue decodedExtValue = null; + // decode Key Usage and Basic Constraints extension values if (oidEquals(oid, KEY_USAGE)) { - return new KeyUsage(extnValue, rawExtnValue, in.getEncoded()); + decodedExtValue = new KeyUsage(extnValue); } else if (oidEquals(oid, BASIC_CONSTRAINTS)) { - return new BasicConstraints( - extnValue, rawExtnValue, in.getEncoded()); + decodedExtValue = new BasicConstraints(extnValue); } return new Extension((int[]) values[0], ((Boolean) values[1]).booleanValue(), - extnValue, rawExtnValue, in.getEncoded()); + extnValue, rawExtnValue, in.getEncoded(), decodedExtValue); } protected void getValues(Object object, Object[] values) { Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/CRLDistributionPoints.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/CRLDistributionPoints.java (revision 447324) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/CRLDistributionPoints.java (working copy) @@ -64,7 +64,7 @@ * } * */ -public class CRLDistributionPoints { +public class CRLDistributionPoints extends ExtensionValue { private List distributionPoints; private byte[] encoding; Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/CertificateIssuer.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/CertificateIssuer.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/CertificateIssuer.java (revision 0) @@ -0,0 +1,101 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import javax.security.auth.x500.X500Principal; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.ASN1Sequence; +import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.x501.Name; + +/** + * CRL Entry's Certificate Issuer Extension (OID = 2.5.29.29). + * It is a CRL entry extension and contains the GeneralNames describing + * the issuer of revoked certificate. Its ASN.1 notation is as follows: + *
+ *   id-ce-certificateIssuer   OBJECT IDENTIFIER ::= { id-ce 29 }
+ *
+ *   certificateIssuer ::=     GeneralNames
+ * 
+ * (as specified in RFC 3280) + * In java implementation it is presumed that GeneralNames cansist of + * one element and its type is directoryName. + */ +public class CertificateIssuer extends ExtensionValue { + + // certificate issuer value + private X500Principal issuer; + + /** + * Creates an object on the base of GeneralName structure. + */ + public CertificateIssuer(GeneralName issuer) { + super(ASN1.encode(issuer)); + } + + /** + * Creates an object on the base of its encoded form. + */ + public CertificateIssuer(byte[] encoding) { + super(encoding); + } + + /** + * Returns the issuer. + */ + public X500Principal getIssuer() throws IOException { + if (issuer == null) { + issuer = (X500Principal) ASN1.decode(getEncoded()); + } + return issuer; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("Certificate Issuer: "); + if (issuer == null) { + try { + issuer = getIssuer(); + } catch (IOException e) { + // incorrect extension value encoding + buffer.append("Unparseable (incorrect!) extension value:\n"); + super.dumpValue(buffer); + } + } + buffer.append(issuer).append("\n"); + } + + /** + * ASN.1 Encoder/Decoder. + */ + public static ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] { + GeneralName.ASN1 + }) { + public Object getDecodedObject(BerInputStream in) { + return ((Name) ((GeneralName) ((Object[]) in.content)[0]) + .getName()).getX500Principal(); + } + + protected void getValues(Object object, Object[] values) { + values[0] = object; + } + }; +} Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/InhibitAnyPolicy.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/InhibitAnyPolicy.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/InhibitAnyPolicy.java (revision 0) @@ -0,0 +1,83 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import java.math.BigInteger; +import org.apache.harmony.security.asn1.ASN1Integer; + +/** + * InhibitAnyPolicy Certificate Extension (OID = 2.5.29.54) + * Its ASN.1 notation is as follows: + *
+ *  id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 }
+ *
+ *  InhibitAnyPolicy ::= SkipCerts
+ *
+ *  SkipCerts ::= INTEGER (0..MAX)
+ * 
+ * (as specified in RFC 3280 http://www.ietf.org/rfc/rfc3280.txt). + */ +public class InhibitAnyPolicy extends ExtensionValue { + + // the value of the extension + private int skipCerts; + + /** + * Create the object on the base of SkipCerts value. + */ + public InhibitAnyPolicy(int skipCerts) { + this.skipCerts = skipCerts; + } + + /** + * Creates an object on the base of its encoded form. + */ + public InhibitAnyPolicy(byte[] encoding) throws IOException { + super(encoding); + this.skipCerts = new BigInteger((byte[]) + ASN1Integer.getInstance().decode(encoding)).intValue(); + } + + /** + * Return the value of the extension. + */ + public int getSkipCerts() { + return skipCerts; + } + + /** + * Returns ASN.1 encoded form of the object. + * @return a byte array containing ASN.1 encoded form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1Integer.getInstance() + .encode(ASN1Integer.fromIntValue(skipCerts)); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("Inhibit Any-Policy: ").append(skipCerts).append("\n"); + } +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/AlternativeName.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/AlternativeName.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/AlternativeName.java (revision 0) @@ -0,0 +1,100 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +/** + * This class implements the values of Subject Alternative Name + * (OID is 2.5.29.17) and Issuer Alternative Name extensions + * (OID is 2.5.29.18).
+ * For more information about these extensions see RFC 3280 + * at http://www.ietf.org/rfc/rfc3280.txt + */ +public class AlternativeName extends ExtensionValue { + + // constants indicating which alternative name is presented + // by this object + public static final boolean ISSUER = false; + public static final boolean SUBJECT = true; + + // indicating which alternative name is presented by this object + private boolean which; + // the alternative names + private GeneralNames alternativeNames; + + /** + * Creates the extension object for given alternative names. + * @param which specifies which alternative names are given + * (Subject's or Issuer's) + */ + public AlternativeName(boolean which, GeneralNames alternativeNames) { + this.which = which; + this.alternativeNames = alternativeNames; + } + + /** + * Creates the extension object on the base of its encoded form. + * @param which specifies which alternative names are given + * (Subject's or Issuer's) + */ + public AlternativeName(boolean which, byte[] encoding) throws IOException { + super(encoding); + this.which = which; + this.alternativeNames = + (GeneralNames) GeneralNames.ASN1.decode(encoding); + } + + /** + * Returns the list of alternative names. + * The list is in the collection of pairs:
+ * [Integer (tag of GeneralName), Object (name value)] + */ + public List getAlternativeNames() { + return alternativeNames.getPairsList(); + } + + /** + * Returns ASN.1 encoded form of this X.509 AlternativeName value. + * @return a byte array containing ASN.1 encode form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = GeneralNames.ASN1.encode(alternativeNames); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append((which) ? "Subject" : "Issuer") + .append(" Alternative Names [\n"); + for (Iterator it=alternativeNames.generalNames.iterator(); + it.hasNext();) { + buffer.append(" "); + buffer.append(it.next()); + buffer.append("\n"); + } + buffer.append("]\n"); + } +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/PolicyConstraints.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/PolicyConstraints.java (revision 447324) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/PolicyConstraints.java (working copy) @@ -21,6 +21,7 @@ package org.apache.harmony.security.x509; +import java.io.IOException; import java.math.BigInteger; import org.apache.harmony.security.asn1.ASN1Implicit; @@ -52,7 +53,7 @@ * @see org.apache.harmony.security.x509.GeneralSubtree * @see org.apache.harmony.security.x509.GeneralName */ -public class PolicyConstraints { +public class PolicyConstraints extends ExtensionValue { // the value of requireExplicitPolicy field of the structure private final BigInteger requireExplicitPolicy; @@ -79,6 +80,24 @@ this.inhibitPolicyMapping = inhibitPolicyMapping; } + /** + * TODO + * @param requireExplicitPolicy: GeneralSubtrees + * @param inhibitPolicyMapping: GeneralSubtrees + */ + public PolicyConstraints(int requireExplicitPolicy, + int inhibitPolicyMapping) { + this.requireExplicitPolicy = BigInteger.valueOf(requireExplicitPolicy); + this.inhibitPolicyMapping = BigInteger.valueOf(inhibitPolicyMapping); + } + + public PolicyConstraints(byte[] encoding) throws IOException { + super(encoding); + PolicyConstraints pc = (PolicyConstraints) ASN1.decode(encoding); + this.requireExplicitPolicy = pc.requireExplicitPolicy; + this.inhibitPolicyMapping = pc.inhibitPolicyMapping; + } + // // TODO // @param requireExplicitPolicy: GeneralSubtrees @@ -132,8 +151,8 @@ PolicyConstraints pc = (PolicyConstraints) object; - values[0] = pc.requireExplicitPolicy; - values[1] = pc.inhibitPolicyMapping; + values[0] = pc.requireExplicitPolicy.toByteArray(); + values[1] = pc.inhibitPolicyMapping.toByteArray(); } }; } Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/IssuingDistributionPoint.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/IssuingDistributionPoint.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/IssuingDistributionPoint.java (revision 0) @@ -0,0 +1,228 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; + +import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.asn1.ASN1Boolean; +import org.apache.harmony.security.asn1.ASN1Implicit; +import org.apache.harmony.security.asn1.ASN1Sequence; +import org.apache.harmony.security.asn1.ASN1Type; + +/** + * CRL's Issuing Distribution Point Extension (OID = 2.5.29.28). + *
+ *   id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
+ *
+ *   issuingDistributionPoint ::= SEQUENCE {
+ *      distributionPoint          [0] DistributionPointName OPTIONAL,
+ *      onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
+ *      onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
+ *      onlySomeReasons            [3] ReasonFlags OPTIONAL,
+ *      indirectCRL                [4] BOOLEAN DEFAULT FALSE,
+ *      onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE
+ *   }
+ * 
+ * (as specified in RFC 3280 http://www.ietf.org/rfc/rfc3280.txt) + */ +public class IssuingDistributionPoint extends ExtensionValue { + + // values of the fields of the structure + private DistributionPointName distributionPoint; + private boolean onlyContainsUserCerts = false; + private boolean onlyContainsCACerts = false; + private ReasonFlags onlySomeReasons; + private boolean indirectCRL = false; + private boolean onlyContainsAttributeCerts = false; + + /** + * Constructs the object on the base of its distributionPoint and + * onlySomeReasons fields values. + */ + public IssuingDistributionPoint(DistributionPointName distributionPoint, + ReasonFlags onlySomeReasons) { + this.distributionPoint = distributionPoint; + this.onlySomeReasons = onlySomeReasons; + } + + /** + * Creates the extension object on the base of its encoded form. + */ + public IssuingDistributionPoint(byte[] encoding) throws IOException { + super(encoding); + IssuingDistributionPoint idp = + (IssuingDistributionPoint) ASN1.decode(encoding); + this.distributionPoint = idp.distributionPoint; + this.onlyContainsUserCerts = idp.onlyContainsUserCerts; + this.onlyContainsCACerts = idp.onlyContainsCACerts; + this.onlySomeReasons = idp.onlySomeReasons; + this.indirectCRL = idp.indirectCRL; + this.onlyContainsAttributeCerts = idp.onlyContainsAttributeCerts; + } + + /** + * Sets the value of onlyContainsUserCerts field of the structure. + */ + public void setOnlyContainsUserCerts(boolean onlyContainsUserCerts) { + this.onlyContainsUserCerts = onlyContainsUserCerts; + } + + /** + * Sets the value of onlyContainsCACerts field of the structure. + */ + public void setOnlyContainsCACerts(boolean onlyContainsCACerts) { + this.onlyContainsCACerts = onlyContainsCACerts; + } + + /** + * Sets the value of indirectCRL field of the structure. + */ + public void setIndirectCRL(boolean indirectCRL) { + this.indirectCRL = indirectCRL; + } + + /** + * Sets the value of onlyContainsAttributeCerts field of the structure. + */ + public void setOnlyContainsAttributeCerts( + boolean onlyContainsAttributeCerts) { + this.onlyContainsAttributeCerts = onlyContainsAttributeCerts; + } + + /** + * Returns value of distributionPoint field of the structure. + */ + public DistributionPointName getDistributionPoint() { + return distributionPoint; + } + + /** + * Returns value of onlyContainsUserCerts field of the structure. + */ + public boolean getOnlyContainsUserCerts() { + return onlyContainsUserCerts; + } + + /** + * Returns value of onlyContainsCACerts field of the structure. + */ + public boolean getOnlyContainsCACerts() { + return onlyContainsCACerts; + } + + /** + * Returns value of onlySomeReasons field of the structure. + */ + public ReasonFlags getOnlySomeReasons() { + return onlySomeReasons; + } + + /** + * Returns value of indirectCRL field of the structure. + */ + public boolean getIndirectCRL() { + return indirectCRL; + } + + /** + * Returns value of onlyContainsAttributeCerts field of the structure. + */ + public boolean getOnlyContainsAttributeCerts() { + return onlyContainsAttributeCerts; + } + + /** + * Returns ASN.1 encoded form of this X.509 IssuingDistributionPoint value. + * @return a byte array containing ASN.1 encoded form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(this); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("Invalidity Date\n"); + super.dumpValue(buffer); + } + + /** + * ASN.1 Encoder/Decoder. + */ + public static ASN1Type ASN1 = new ASN1Sequence( + new ASN1Type[] { + new ASN1Implicit(0, DistributionPointName.ASN1), + new ASN1Implicit(1, ASN1Boolean.getInstance()), + new ASN1Implicit(2, ASN1Boolean.getInstance()), + new ASN1Implicit(3, ReasonFlags.ASN1), + new ASN1Implicit(4, ASN1Boolean.getInstance()), + new ASN1Implicit(5, ASN1Boolean.getInstance()) + }) { + { + setOptional(0); + setOptional(3); + setDefault(Boolean.FALSE, 1); + setDefault(Boolean.FALSE, 2); + setDefault(Boolean.FALSE, 4); + setDefault(Boolean.FALSE, 5); + } + + protected Object getDecodedObject(BerInputStream in) { + Object[] values = (Object[]) in.content; + IssuingDistributionPoint idp = + new IssuingDistributionPoint( + (DistributionPointName) values[0], + (ReasonFlags) values[3]); + idp.encoding = in.getEncoded(); + if (values[1] != null) { + idp.setOnlyContainsUserCerts( + ((Boolean) values[1]).booleanValue()); + } + if (values[2] != null) { + idp.setOnlyContainsCACerts( + ((Boolean) values[2]).booleanValue()); + } + if (values[4] != null) { + idp.setIndirectCRL( + ((Boolean) values[4]).booleanValue()); + } + if (values[5] != null) { + idp.setOnlyContainsAttributeCerts( + ((Boolean) values[5]).booleanValue()); + } + return idp; + } + + protected void getValues(Object object, Object[] values) { + IssuingDistributionPoint idp = (IssuingDistributionPoint) object; + values[0] = idp.distributionPoint; + values[1] = (idp.onlyContainsUserCerts) ? Boolean.TRUE : null; + values[2] = (idp.onlyContainsCACerts) ? Boolean.TRUE : null; + values[3] = idp.onlySomeReasons; + values[4] = (idp.indirectCRL) ? Boolean.TRUE : null; + values[5] = (idp.onlyContainsAttributeCerts) ? Boolean.TRUE : null; + } + }; + +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/GeneralNames.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/GeneralNames.java (revision 447324) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/GeneralNames.java (working copy) @@ -50,7 +50,7 @@ public class GeneralNames { // the values of GeneralName - private List generalNames; + protected List generalNames; // the ASN.1 encoded form of GeneralNames private byte[] encoding; Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/AuthorityKeyIdentifier.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/AuthorityKeyIdentifier.java (revision 447324) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/AuthorityKeyIdentifier.java (working copy) @@ -50,12 +50,11 @@ * KeyIdentifier ::= OCTET STRING * */ -public class AuthorityKeyIdentifier { +public class AuthorityKeyIdentifier extends ExtensionValue { private final byte[] keyIdentifier; private final GeneralNames authorityCertIssuer; private final BigInteger authorityCertSerialNumber; - private byte[] encoding; public AuthorityKeyIdentifier(byte[] keyIdentifier, GeneralNames authorityCertIssuer, @@ -64,6 +63,14 @@ this.authorityCertIssuer = authorityCertIssuer; this.authorityCertSerialNumber = authorityCertSerialNumber; } + + public static AuthorityKeyIdentifier decode(byte[] encoding) + throws IOException { + AuthorityKeyIdentifier aki = + (AuthorityKeyIdentifier) ASN1.decode(encoding); + aki.encoding = encoding; + return aki; + } public byte[] getEncoded() { if (encoding == null) { @@ -71,7 +78,7 @@ } return encoding; } - + public static ASN1Type ASN1 = new ASN1Sequence( new ASN1Type[] { new ASN1Implicit(0, ASN1OctetString.getInstance()), Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/BasicConstraints.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/BasicConstraints.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/BasicConstraints.java (revision 0) @@ -0,0 +1,124 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import java.math.BigInteger; +import org.apache.harmony.security.asn1.ASN1Boolean; +import org.apache.harmony.security.asn1.ASN1Integer; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.ASN1Sequence; +import org.apache.harmony.security.asn1.BerInputStream; + +/** + * Basic Constraints Extension (OID == 2.5.29.19). + * + * The ASN.1 definitionn for Basic Constraints Extension is: + * + *
+ *   id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
+ *
+ *   BasicConstraints ::= SEQUENCE {
+ *        cA                      BOOLEAN DEFAULT FALSE,
+ *        pathLenConstraint       INTEGER (0..MAX) OPTIONAL
+ *   }
+ * 
+ * (as specified in RFC 3280) + */ +public class BasicConstraints extends ExtensionValue { + + // is CA + private boolean cA = false; + // path len constraint + private int pathLenConstraint = Integer.MAX_VALUE; + + // Constructor for creating the extension without + // encoding provided + /** + * Creates the extension object on the base of the values of + * fields of the structure.. + */ + public BasicConstraints(boolean cA, int pathLenConstraint) { + this.cA = cA; + this.pathLenConstraint = pathLenConstraint; + } + + /** + * Creates the extension object on the base of its encoded form. + */ + public BasicConstraints(byte[] encoding) throws IOException { + super(encoding); + Object[] values = (Object[]) ASN1.decode(encoding); + cA = ((Boolean) values[0]).booleanValue(); + if (values[1] != null) { + pathLenConstraint = new BigInteger((byte[]) values[1]).intValue(); + } + } + + public boolean getCA() { + return cA; + } + + public int getPathLenConstraint() { + return pathLenConstraint; + } + + /** + * Returns the encoded form of the object. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode( + new Object[] {Boolean.valueOf(cA), + BigInteger.valueOf(pathLenConstraint)}); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("BasicConstraints [\n CA: ").append(cA) + .append("\n pathLenConstraint: ").append(pathLenConstraint) + .append("\n]\n"); + } + + /** + * ASN.1 Encoder/Decoder. + */ + public static ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] { + ASN1Boolean.getInstance(), ASN1Integer.getInstance() }) { + { + setDefault(Boolean.FALSE, 0); + setOptional(1); + } + + public Object getDecodedObject(BerInputStream in) + throws IOException { + return in.content; + } + + protected void getValues(Object object, Object[] values) { + Object[] vals = (Object[]) object; + values[0] = (Boolean) vals[0]; + values[1] = ((BigInteger) vals[1]).toByteArray(); + } + + }; +} Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/InvalidityDate.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/InvalidityDate.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/InvalidityDate.java (revision 0) @@ -0,0 +1,85 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import java.util.Date; + +import org.apache.harmony.security.asn1.ASN1GeneralizedTime; +import org.apache.harmony.security.asn1.ASN1Type; + +/** + * CRL Entry's Invalidity Date Extension (OID = 2.5.29.24). + *
+ *   id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
+ *
+ *   invalidityDate ::=  GeneralizedTime
+ * 
+ * (as specified in RFC 3280 http://www.ietf.org/rfc/rfc3280.txt) + */ +public class InvalidityDate extends ExtensionValue { + + // invalidity date value + private static Date date; + + /** + * Constructs the object on the base of the invalidity date value. + */ + public InvalidityDate(Date date) { + this.date = date; + } + + /** + * Constructs the object on the base of its encoded form. + */ + public InvalidityDate(byte[] encoding) throws IOException { + super(encoding); + date = (Date) ASN1.decode(encoding); + } + + /** + * Returns the invalidity date. + */ + public Date getDate() { + return date; + } + + /** + * Returns ASN.1 encoded form of this X.509 InvalidityDate value. + * @return a byte array containing ASN.1 encoded form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(date); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("Invalidity Date [\n ").append(date).append("\n]\n"); + } + + /** + * ASN.1 Encoder/Decoder. + */ + public static ASN1Type ASN1 = ASN1GeneralizedTime.getInstance(); +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/KeyUsage.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/KeyUsage.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/KeyUsage.java (revision 0) @@ -0,0 +1,114 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.ASN1BitString; + +/** + * Key Usage Extension (OID = 2.5.29.15). + * + * The ASN.1 definitionn for Key Usage Extension is: + * + *
+ * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
+ *
+ * KeyUsage ::= BIT STRING {
+ *     digitalSignature        (0),
+ *     nonRepudiation          (1),
+ *     keyEncipherment         (2),
+ *     dataEncipherment        (3),
+ *     keyAgreement            (4),
+ *     keyCertSign             (5),
+ *     cRLSign                 (6),
+ *     encipherOnly            (7),
+ *     decipherOnly            (8)
+ * }
+ * 
+ * (as specified in RFC 3280 http://www.ietf.org/rfc/rfc3280.txt) + */ +public class KeyUsage extends ExtensionValue { + + /** + * The names of the usages. + */ + private static final String[] USAGES = { + "digitalSignature", + "nonRepudiation", + "keyEncipherment", + "dataEncipherment", + "keyAgreement", + "keyCertSign", + "cRLSign", + "encipherOnly", + "decipherOnly", + }; + + // the value of extension + private final boolean[] keyUsage; + + /** + * Creates the extension object corresponding to the given key usage. + */ + public KeyUsage(boolean[] keyUsage) { + this.keyUsage = keyUsage; + } + + /** + * Creates the extension object on the base of its encoded form. + */ + public KeyUsage(byte[] encoding) throws IOException { + super(encoding); + this.keyUsage = (boolean[]) ASN1.decode(encoding); + } + + public boolean[] getKeyUsage() { + return keyUsage; + } + + /** + * Returns the encoded of the object. + * @return a byte array containing ASN.1 encoded form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(keyUsage); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("KeyUsage [\n"); + for (int i=0; i + * id-ce-cRLReason OBJECT IDENTIFIER ::= { id-ce 21 } + * + * -- reasonCode ::= { CRLReason } + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8), + * privilegeWithdrawn (9), + * aACompromise (10) + * } + * + * (as specified in RFC 3280 http://www.ietf.org/rfc/rfc3280.txt) + */ +public class ReasonCode extends ExtensionValue { + + // predefined reason code values + public static final byte UNSPECIFIED = 0; + public static final byte KEY_COMPROMISE = 1; + public static final byte CA_COMPROMISE = 2; + public static final byte AFFILIATION_CHANGED = 3; + public static final byte SUPERSEDED = 4; + public static final byte CESSATION_OF_OPERATION = 5; + public static final byte CERTIFICATE_HOLD = 6; + public static final byte REMOVE_FROM_CRL = 8; + public static final byte PRIVILEGE_WITHDRAWN = 9; + public static final byte AA_COMPROMISE = 10; + + // the reason code value + private final byte code; + + public ReasonCode(byte code) { + this.code = code; + } + + public ReasonCode(byte[] encoding) throws IOException { + super(encoding); + this.code = ((byte[]) ASN1.decode(encoding))[0]; + } + + public int getCode() { + return code; + } + + /** + * Returns ASN.1 encoded form of this X.509 ReasonCode value. + * @return a byte array containing ASN.1 encode form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(new byte[] {(byte) code}); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("Reason Code [\n "); + switch (code) { + case UNSPECIFIED: + buffer.append("unspecified"); + break; + case KEY_COMPROMISE: + buffer.append("keyCompromise"); + break; + case CA_COMPROMISE: + buffer.append("cACompromise"); + break; + case AFFILIATION_CHANGED: + buffer.append("affiliationChanged"); + break; + case SUPERSEDED: + buffer.append("superseded"); + break; + case CESSATION_OF_OPERATION: + buffer.append("cessationOfOperation"); + break; + case CERTIFICATE_HOLD: + buffer.append("certificateHold"); + break; + case REMOVE_FROM_CRL: + buffer.append("removeFromCRL"); + break; + case PRIVILEGE_WITHDRAWN: + buffer.append("privilegeWithdrawn"); + break; + case AA_COMPROMISE: + buffer.append("aACompromise"); + break; + } + buffer.append("\n]\n"); + } + + /** + * ASN.1 Encoder/Decoder. + */ + public static ASN1Type ASN1 = ASN1Enumerated.getInstance(); +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/ExtendedKeyUsage.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/ExtendedKeyUsage.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/ExtendedKeyUsage.java (revision 0) @@ -0,0 +1,121 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.ASN1SequenceOf; +import org.apache.harmony.security.asn1.ASN1Oid; +import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.asn1.ObjectIdentifier; + +/** + * Extended Key Usage Extension (OID == 2.5.29.37). + * + * The ASN.1 definitionn for Extended Key Usage Extension is: + * + *
+ *  id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
+ *
+ *  ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+ *
+ *  KeyPurposeId ::= OBJECT IDENTIFIER
+ * 
+ * (as specified in RFC 3280 http://www.ietf.org/rfc/rfc3280.txt + */ +public class ExtendedKeyUsage extends ExtensionValue { + + // the value of extension + private List keys; + + /** + * Creates an object on the base of list of integer arrays representing + * key purpose IDs. + */ + public ExtendedKeyUsage(List keys) { + this.keys = keys; + } + + /** + * Creates the extension object on the base of its encoded form. + */ + public ExtendedKeyUsage(byte[] encoding) { + super(encoding); + } + + /** + * Returns the list of string representation of OIDs corresponding + * to key purpose IDs. + */ + public List getExtendedKeyUsage() throws IOException { + if (keys == null) { + keys = (List) ASN1.decode(getEncoded()); + } + return keys; + } + + /** + * Returns the encoded form of the object. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(keys); + } + return encoding; + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer) { + buffer.append("Extended Key Usage: "); + if (keys == null) { + try { + keys = getExtendedKeyUsage(); + } catch (IOException e) { + // incorrect extension value encoding + super.dumpValue(buffer); + return; + } + } + buffer.append("["); + for (Iterator it=keys.iterator(); it.hasNext();) { + buffer.append(" \"").append(it.next()).append("\""); + if (it.hasNext()) { + buffer.append(","); + } + } + buffer.append(" ]\n"); + } + + /** + * ASN.1 Encoder/Decoder. + */ + public static ASN1Type ASN1 = + new ASN1SequenceOf(new ASN1Oid() { + + public Object getDecodedObject(BerInputStream in) + throws IOException { + int[] oid = (int[]) super.getDecodedObject(in); + return ObjectIdentifier.toString(oid); + } + + }); +}