diff options
Diffstat (limited to 'libraries/spongycastle/prov/src/main/jdk1.3/org/spongycastle/jce/cert/X509CertSelector.java')
-rw-r--r-- | libraries/spongycastle/prov/src/main/jdk1.3/org/spongycastle/jce/cert/X509CertSelector.java | 2468 |
1 files changed, 0 insertions, 2468 deletions
diff --git a/libraries/spongycastle/prov/src/main/jdk1.3/org/spongycastle/jce/cert/X509CertSelector.java b/libraries/spongycastle/prov/src/main/jdk1.3/org/spongycastle/jce/cert/X509CertSelector.java deleted file mode 100644 index 0f1f814dd..000000000 --- a/libraries/spongycastle/prov/src/main/jdk1.3/org/spongycastle/jce/cert/X509CertSelector.java +++ /dev/null @@ -1,2468 +0,0 @@ -package org.spongycastle.jce.cert; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.PublicKey; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.spongycastle.asn1.ASN1InputStream; -import org.spongycastle.asn1.ASN1Object; -import org.spongycastle.asn1.ASN1ObjectIdentifier; -import org.spongycastle.asn1.ASN1OctetString; -import org.spongycastle.asn1.ASN1Sequence; -import org.spongycastle.asn1.ASN1TaggedObject; -import org.spongycastle.asn1.DERGeneralizedTime; -import org.spongycastle.asn1.DEROutputStream; -import org.spongycastle.asn1.util.ASN1Dump; -import org.spongycastle.asn1.x509.AlgorithmIdentifier; -import org.spongycastle.asn1.x509.ExtendedKeyUsage; -import org.spongycastle.asn1.x509.KeyPurposeId; -import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; -import org.spongycastle.asn1.x509.X509Extensions; -import org.spongycastle.asn1.x509.X509Name; -import org.spongycastle.jce.PrincipalUtil; -import org.spongycastle.util.Integers; - -/** - * A <code>CertSelector</code> that selects - * <code>X509Certificates that match all - * specified criteria. This class is particularly useful when - * selecting certificates from a CertStore to build a PKIX-compliant - * certification path.<br /> - * <br /> - * When first constructed, an <code>X509CertSelector</code> has no criteria enabled - * and each of the get methods return a default value (<code>null</code>, or -1 for - * the {@link #getBasicConstraints} method). Therefore, the {@link #match} method would - * return true for any <code>X509Certificate</code>. Typically, several criteria - * are enabled (by calling {@link #setIssuer} or {@link #setKeyUsage}, for instance) and - * then the <code>X509CertSelector</code> is passed to {@link CertStore#getCertificates} or - * some similar method.<br /> - * <br /> - * Several criteria can be enabled (by calling {@link #setIssuer} and - * {@link #setSerialNumber}, for example) such that the match method usually - * uniquely matches a single <code>X509Certificate</code>. We say usually, since it - * is possible for two issuing CAs to have the same distinguished name - * and each issue a certificate with the same serial number. Other - * unique combinations include the issuer, subject, - * subjectKeyIdentifier and/or the subjectPublicKey criteria.<br /> - * <br /> - * Please refer to RFC 2459 for definitions of the X.509 certificate - * extensions mentioned below.<br /> - * <br /> - * <b>Concurrent Access</b><br /> - * <br /> - * Unless otherwise specified, the methods defined in this class are - * not thread-safe. Multiple threads that need to access a single - * object concurrently should synchronize amongst themselves and - * provide the necessary locking. Multiple threads each manipulating - * separate objects need not synchronize.<br /> - * <br /> - * <b>TODO: implement name constraints</b> - * <b>TODO: implement match check for path to names</b><br /> - * <br /> - * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence}, - * {@link org.spongycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, - * {@link org.spongycastle.asn1.DEROutputStream DEROutputStream}, - * {@link org.spongycastle.asn1.ASN1Object ASN1Object}, - * {@link org.spongycastle.asn1.OIDTokenizer OIDTokenizer}, - * {@link org.spongycastle.asn1.x509.X509Name X509Name}, - * {@link org.spongycastle.asn1.x509.X509Extensions X509Extensions}, - * {@link org.spongycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, - * {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId}, - * {@link org.spongycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo}, - * {@link org.spongycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier} - */ -public class X509CertSelector implements CertSelector -{ - private static final Hashtable keyPurposeIdMap = new Hashtable(); - static - { - keyPurposeIdMap.put(KeyPurposeId.id_kp_serverAuth.getId(), - KeyPurposeId.id_kp_serverAuth); - keyPurposeIdMap.put(KeyPurposeId.id_kp_clientAuth.getId(), - KeyPurposeId.id_kp_clientAuth); - keyPurposeIdMap.put(KeyPurposeId.id_kp_codeSigning.getId(), - KeyPurposeId.id_kp_codeSigning); - keyPurposeIdMap.put(KeyPurposeId.id_kp_emailProtection.getId(), - KeyPurposeId.id_kp_emailProtection); - keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecEndSystem.getId(), - KeyPurposeId.id_kp_ipsecEndSystem); - keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecTunnel.getId(), - KeyPurposeId.id_kp_ipsecTunnel); - keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecUser.getId(), - KeyPurposeId.id_kp_ipsecUser); - keyPurposeIdMap.put(KeyPurposeId.id_kp_timeStamping.getId(), - KeyPurposeId.id_kp_timeStamping); - } - - private X509Certificate x509Cert = null; - - private BigInteger serialNumber = null; - - private Object issuerDN = null; - - private X509Name issuerDNX509 = null; - - private Object subjectDN = null; - - private X509Name subjectDNX509 = null; - - private byte[] subjectKeyID = null; - - private byte[] authorityKeyID = null; - - private Date certValid = null; - - private Date privateKeyValid = null; - - private ASN1ObjectIdentifier subjectKeyAlgID = null; - - private PublicKey subjectPublicKey = null; - - private byte[] subjectPublicKeyByte = null; - - private boolean[] keyUsage = null; - - private Set keyPurposeSet = null; - - private boolean matchAllSubjectAltNames = true; - - private Set subjectAltNames = null; - - private Set subjectAltNamesByte = null; - - private int minMaxPathLen = -1; - - private Set policy = null; - - private Set policyOID = null; - - private Set pathToNames = null; - - private Set pathToNamesByte = null; - - /** - * Creates an <code>X509CertSelector</code>. Initially, no criteria are - * set so any <code>X509Certificate</code> will match. - */ - public X509CertSelector() - { - } - - /** - * Sets the certificateEquals criterion. The specified - * <code>X509Certificate</code> must be equal to the - * <code>X509Certificate</code> passed to the match method. If - * <code>null</code>, then this check is not applied.<br /> - * <br /> - * This method is particularly useful when it is necessary to match a single - * certificate. Although other criteria can be specified in conjunction with - * the certificateEquals criterion, it is usually not practical or - * necessary. - * - * @param cert - * the X509Certificate to match (or <code>null</code>) - * - * @see #getCertificate() - */ - public void setCertificate(X509Certificate cert) - { - x509Cert = cert; - } - - /** - * Sets the serialNumber criterion. The specified serial number must match - * the certificate serial number in the <code>X509Certificate</code>. If - * <code>null</code>, any certificate serial number will do. - * - * @param serial - * the certificate serial number to match (or <code>null</code>) - * - * @see #getSerialNumber() - */ - public void setSerialNumber(BigInteger serial) - { - serialNumber = serial; - } - - /** - * Sets the issuer criterion. The specified distinguished name must match - * the issuer distinguished name in the <code>X509Certificate</code>. If - * <code>null</code>, any issuer distinguished name will do.<br /> - * <br /> - * If <code>issuerDN</code> is not <code>null</code>, it should contain - * a distinguished name, in RFC 2253 format.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for parsing the - * issuerDN. - * - * @param issuerDN - * a distinguished name in RFC 2253 format (or <code>null</code>) - * - * @exception IOException - * if a parsing error occurs (incorrect form for DN) - */ - public void setIssuer(String issuerDN) throws IOException - { - if (issuerDN == null) - { - this.issuerDN = null; - this.issuerDNX509 = null; - } - else - { - X509Name nameX509; - try - { - nameX509 = new X509Name(issuerDN); - } - catch (IllegalArgumentException ex) - { - throw new IOException(ex.getMessage()); - } - this.issuerDNX509 = nameX509; - this.issuerDN = issuerDN; - } - } - - /** - * Sets the issuer criterion. The specified distinguished name must match - * the issuer distinguished name in the <code>X509Certificate</code>. If - * null is specified, the issuer criterion is disabled and any issuer - * distinguished name will do.<br /> - * <br /> - * If <code>issuerDN</code> is not <code>null</code>, it should contain - * a single DER encoded distinguished name, as defined in X.501. The ASN.1 - * notation for this structure is as follows.<br /> - * <br /> - * - * <pre> - * Name ::= CHOICE { - * RDNSequence } - * - * RDNSequence ::= SEQUENCE OF RDN - * - * RDN ::= - * SET SIZE (1 .. MAX) OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - * .... - * DirectoryString ::= CHOICE { - * teletexString TeletexString (SIZE (1..MAX)), - * printableString PrintableString (SIZE (1..MAX)), - * universalString UniversalString (SIZE (1..MAX)), - * utf8String UTF8String (SIZE (1.. MAX)), - * bmpString BMPString (SIZE (1..MAX)) } - * </pre> - * - * <br /> - * <br /> - * Note that the byte array specified here is cloned to protect against - * subsequent modifications.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.spongycastle.asn1.ASN1Object ASN1Object}, - * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence}, - * {@link org.spongycastle.asn1.x509.X509Name X509Name} - * - * @param issuerDN - - * a byte array containing the distinguished name in ASN.1 DER - * encoded form (or <code>null</code>) - * - * @exception IOException - * if an encoding error occurs (incorrect form for DN) - */ - public void setIssuer(byte[] issuerDN) throws IOException - { - if (issuerDN == null) - { - this.issuerDN = null; - this.issuerDNX509 = null; - } - else - { - ByteArrayInputStream inStream = new ByteArrayInputStream(issuerDN); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object obj = derInStream.readObject(); - if (obj instanceof ASN1Sequence) - { - this.issuerDNX509 = new X509Name((ASN1Sequence)obj); - } - else - { - throw new IOException("parsing error"); - } - this.issuerDN = (byte[])issuerDN.clone(); - } - } - - /** - * Sets the subject criterion. The specified distinguished name must match - * the subject distinguished name in the <code>X509Certificate</code>. If - * null, any subject distinguished name will do.<br /> - * <br /> - * If <code>subjectDN</code> is not <code>null</code>, it should - * contain a distinguished name, in RFC 2253 format.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for parsing the - * subjectDN. - * - * @param subjectDN - * a distinguished name in RFC 2253 format (or <code>null</code>) - * - * @exception IOException - * if a parsing error occurs (incorrect form for DN) - */ - public void setSubject(String subjectDN) throws IOException - { - if (subjectDN == null) - { - this.subjectDN = null; - this.subjectDNX509 = null; - } - else - { - X509Name nameX509; - try - { - nameX509 = new X509Name(subjectDN); - } - catch (IllegalArgumentException ex) - { - throw new IOException(ex.getMessage()); - } - - this.subjectDNX509 = nameX509; - this.subjectDN = subjectDN; - } - } - - /** - * Sets the subject criterion. The specified distinguished name must match - * the subject distinguished name in the <code>X509Certificate</code>. If - * null, any subject distinguished name will do.<br /> - * <br /> - * If <code>subjectDN</code> is not <code>null</code>, it should - * contain a single DER encoded distinguished name, as defined in X.501. For - * the ASN.1 notation for this structure, see - * {@link #setIssuer(byte []) setIssuer(byte [] issuerDN)}.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.spongycastle.asn1.ASN1Object ASN1Object}, - * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence}, - * {@link org.spongycastle.asn1.x509.X509Name X509Name} - * - * @param subjectDN - * a byte array containing the distinguished name in ASN.1 DER - * format (or <code>null</code>) - * - * @exception IOException - * if an encoding error occurs (incorrect form for DN) - */ - public void setSubject(byte[] subjectDN) throws IOException - { - if (subjectDN == null) - { - this.subjectDN = null; - this.subjectDNX509 = null; - } - else - { - ByteArrayInputStream inStream = new ByteArrayInputStream(subjectDN); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object obj = derInStream.readObject(); - - if (obj instanceof ASN1Sequence) - { - this.subjectDNX509 = new X509Name((ASN1Sequence)obj); - } - else - { - throw new IOException("parsing error"); - } - this.subjectDN = (byte[])subjectDN.clone(); - } - } - - /** - * Sets the subjectKeyIdentifier criterion. The <code>X509Certificate</code> - * must contain a SubjectKeyIdentifier extension for which the contents of - * the extension matches the specified criterion value. If the criterion - * value is null, no subjectKeyIdentifier check will be done.<br /> - * <br /> - * If <code>subjectKeyID</code> is not <code>null</code>, it should - * contain a single DER encoded value corresponding to the contents of the - * extension value (not including the object identifier, criticality - * setting, and encapsulating OCTET STRING) for a SubjectKeyIdentifier - * extension. The ASN.1 notation for this structure follows.<br /> - * <br /> - * - * <pre> - * SubjectKeyIdentifier ::= KeyIdentifier - * - * KeyIdentifier ::= OCTET STRING - * </pre> - * - * <br /> - * <br /> - * Since the format of subject key identifiers is not mandated by any - * standard, subject key identifiers are not parsed by the - * <code>X509CertSelector</code>. Instead, the values are compared using - * a byte-by-byte comparison.<br /> - * <br /> - * Note that the byte array supplied here is cloned to protect against - * subsequent modifications. - * - * @param subjectKeyID - - * the subject key identifier (or <code>null</code>) - * - * @see #getSubjectKeyIdentifier() - */ - public void setSubjectKeyIdentifier(byte[] subjectKeyID) - { - if (subjectKeyID == null) - { - this.subjectKeyID = null; - } - else - { - this.subjectKeyID = (byte[])subjectKeyID.clone(); - } - } - - /** - * Sets the authorityKeyIdentifier criterion. The - * <code>X509Certificate</code> must contain an AuthorityKeyIdentifier - * extension for which the contents of the extension value matches the - * specified criterion value. If the criterion value is <code>null</code>, - * no authorityKeyIdentifier check will be done.<br /> - * <br /> - * If <code>authorityKeyID</code> is not <code>null</code>, it should - * contain a single DER encoded value corresponding to the contents of the - * extension value (not including the object identifier, criticality - * setting, and encapsulating OCTET STRING) for an AuthorityKeyIdentifier - * extension. The ASN.1 notation for this structure follows.<br /> - * <br /> - * - * <pre> - * AuthorityKeyIdentifier ::= SEQUENCE { - * keyIdentifier [0] KeyIdentifier OPTIONAL, - * authorityCertIssuer [1] GeneralNames OPTIONAL, - * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } - * - * KeyIdentifier ::= OCTET STRING - * </pre> - * - * <br /> - * <br /> - * Authority key identifiers are not parsed by the - * <code>X509CertSelector</code>. Instead, the values are compared using - * a byte-by-byte comparison.<br /> - * <br /> - * When the <code>keyIdentifier</code> field of - * <code>AuthorityKeyIdentifier</code> is populated, the value is usually - * taken from the SubjectKeyIdentifier extension in the issuer's - * certificate. Note, however, that the result of - * X509Certificate.getExtensionValue(<SubjectKeyIdentifier Object - * Identifier>) on the issuer's certificate may NOT be used directly as the - * input to setAuthorityKeyIdentifier. This is because the - * SubjectKeyIdentifier contains only a KeyIdentifier OCTET STRING, and not - * a SEQUENCE of KeyIdentifier, GeneralNames, and CertificateSerialNumber. - * In order to use the extension value of the issuer certificate's - * SubjectKeyIdentifier extension, it will be necessary to extract the value - * of the embedded KeyIdentifier OCTET STRING, then DER encode this OCTET - * STRING inside a SEQUENCE. For more details on SubjectKeyIdentifier, see - * {@link #setSubjectKeyIdentifier(byte[]) setSubjectKeyIdentifier(byte[] subjectKeyID }).<br /> - * <br /> - * Note also that the byte array supplied here is cloned to protect against - * subsequent modifications. - * - * @param authorityKeyID - * the authority key identifier (or <code>null</code>) - * - * @see #getAuthorityKeyIdentifier() - */ - public void setAuthorityKeyIdentifier(byte[] authorityKeyID) - { - if (authorityKeyID == null) - { - this.authorityKeyID = null; - } - else - { - this.authorityKeyID = (byte[])authorityKeyID.clone(); - } - } - - /** - * Sets the certificateValid criterion. The specified date must fall within - * the certificate validity period for the X509Certificate. If - * <code>null</code>, no certificateValid check will be done.<br /> - * <br /> - * Note that the Date supplied here is cloned to protect against subsequent - * modifications. - * - * @param certValid - * the Date to check (or <code>null</code>) - * - * @see #getCertificateValid() - */ - public void setCertificateValid(Date certValid) - { - if (certValid == null) - { - this.certValid = null; - } - else - { - this.certValid = new Date(certValid.getTime()); - } - } - - /** - * Sets the privateKeyValid criterion. The specified date must fall within - * the private key validity period for the X509Certificate. If - * <code>null</code>, no privateKeyValid check will be done.<br /> - * <br /> - * Note that the Date supplied here is cloned to protect against subsequent - * modifications. - * - * @param privateKeyValid - * the Date to check (or <code>null</code>) - * - * @see #getPrivateKeyValid() - */ - public void setPrivateKeyValid(Date privateKeyValid) - { - if (privateKeyValid == null) - { - this.privateKeyValid = null; - } - else - { - this.privateKeyValid = new Date(privateKeyValid.getTime()); - } - } - - /** - * Sets the subjectPublicKeyAlgID criterion. The X509Certificate must - * contain a subject public key with the specified algorithm. If - * <code>null</code>, no subjectPublicKeyAlgID check will be done. - * - * @param oid - * The object identifier (OID) of the algorithm to check for (or - * <code>null</code>). An OID is represented by a set of - * nonnegative integers separated by periods. - * - * @exception IOException - * if the OID is invalid, such as the first component being - * not 0, 1 or 2 or the second component being greater than - * 39. - * - * @see #getSubjectPublicKeyAlgID() - */ - public void setSubjectPublicKeyAlgID(String oid) throws IOException - { - if (oid != null) - { - CertUtil.parseOID(oid); - subjectKeyAlgID = new ASN1ObjectIdentifier(oid); - } - else - { - subjectKeyAlgID = null; - } - } - - /** - * Sets the subjectPublicKey criterion. The X509Certificate must contain the - * specified subject public key. If null, no subjectPublicKey check will be - * done. - * - * @param key - * the subject public key to check for (or null) - * - * @see #getSubjectPublicKey() - */ - public void setSubjectPublicKey(PublicKey key) - { - if (key == null) - { - subjectPublicKey = null; - subjectPublicKeyByte = null; - } - else - { - subjectPublicKey = key; - subjectPublicKeyByte = key.getEncoded(); - } - } - - /** - * Sets the subjectPublicKey criterion. The <code>X509Certificate</code> - * must contain the specified subject public key. If <code>null</code>, - * no subjectPublicKey check will be done.<br /> - * <br /> - * Because this method allows the public key to be specified as a byte - * array, it may be used for unknown key types.<br /> - * <br /> - * If key is not <code>null</code>, it should contain a single DER - * encoded SubjectPublicKeyInfo structure, as defined in X.509. The ASN.1 - * notation for this structure is as follows.<br /> - * <br /> - * - * <pre> - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - * -- contains a value of the type - * -- registered for use with the - * -- algorithm object identifier value - * </pre> - * - * <br /> - * <br /> - * Note that the byte array supplied here is cloned to protect against - * subsequent modifications. - * - * @param key - * a byte array containing the subject public key in ASN.1 DER - * form (or <code>null</code>) - * - * @exception IOException - * if an encoding error occurs (incorrect form for subject - * public key) - * - * @see #getSubjectPublicKey() - */ - public void setSubjectPublicKey(byte[] key) throws IOException - { - if (key == null) - { - subjectPublicKey = null; - subjectPublicKeyByte = null; - } - else - { - subjectPublicKey = null; - subjectPublicKeyByte = (byte[])key.clone(); - // TODO - // try to generyte PublicKey Object from subjectPublicKeyByte - } - } - - /** - * Sets the keyUsage criterion. The X509Certificate must allow the specified - * keyUsage values. If null, no keyUsage check will be done. Note that an - * X509Certificate that has no keyUsage extension implicitly allows all - * keyUsage values.<br /> - * <br /> - * Note that the boolean array supplied here is cloned to protect against - * subsequent modifications. - * - * @param keyUsage - * a boolean array in the same format as the boolean array - * returned by X509Certificate.getKeyUsage(). Or - * <code>null</code>. - * - * @see #getKeyUsage() - */ - public void setKeyUsage(boolean[] keyUsage) - { - if (keyUsage == null) - { - this.keyUsage = null; - } - else - { - this.keyUsage = (boolean[])keyUsage.clone(); - } - } - - /** - * Sets the extendedKeyUsage criterion. The <code>X509Certificate</code> - * must allow the specified key purposes in its extended key usage - * extension. If <code>keyPurposeSet</code> is empty or <code>null</code>, - * no extendedKeyUsage check will be done. Note that an - * <code>X509Certificate</code> that has no extendedKeyUsage extension - * implicitly allows all key purposes.<br /> - * <br /> - * Note that the Set is cloned to protect against subsequent modifications.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId} - * - * @param keyPurposeSet - * a <code>Set</code> of key purpose OIDs in string format (or - * <code>null</code>). Each OID is represented by a set of - * nonnegative integers separated by periods. - * - * @exception IOException - * if the OID is invalid, such as the first component being - * not 0, 1 or 2 or the second component being greater than - * 39. - * - * @see #getExtendedKeyUsage() - */ - public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException - { - if (keyPurposeSet == null || keyPurposeSet.isEmpty()) - { - this.keyPurposeSet = keyPurposeSet; - } - else - { - this.keyPurposeSet = new HashSet(); - Iterator iter = keyPurposeSet.iterator(); - Object obj; - KeyPurposeId purposeID; - while (iter.hasNext()) - { - obj = iter.next(); - if (obj instanceof String) - { - purposeID = (KeyPurposeId)keyPurposeIdMap.get((String)obj); - if (purposeID == null) - { - throw new IOException("unknown purposeID " - + (String)obj); - } - this.keyPurposeSet.add(purposeID); - } - } - } - } - - /** - * Enables/disables matching all of the subjectAlternativeNames specified in - * the {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or - * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If - * enabled, the <code>X509Certificate</code> must contain all of the - * specified subject alternative names. If disabled, the X509Certificate - * must contain at least one of the specified subject alternative names.<br /> - * <br /> - * The matchAllNames flag is <code>true</code> by default. - * - * @param matchAllNames - * if <code>true</code>, the flag is enabled; if - * <code>false</code>, the flag is disabled. - * - * @see #getMatchAllSubjectAltNames() - */ - public void setMatchAllSubjectAltNames(boolean matchAllNames) - { - matchAllSubjectAltNames = matchAllNames; - } - - /** - * Sets the subjectAlternativeNames criterion. The - * <code>X509Certificate</code> must contain all or at least one of the - * specified subjectAlternativeNames, depending on the value of the - * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).<br /> - * <br /> - * This method allows the caller to specify, with a single method call, the - * complete set of subject alternative names for the subjectAlternativeNames - * criterion. The specified value replaces the previous value for the - * subjectAlternativeNames criterion.<br /> - * <br /> - * The <code>names</code> parameter (if not <code>null</code>) is a - * <code>Collection</code> with one entry for each name to be included in - * the subject alternative name criterion. Each entry is a <code>List</code> - * whose first entry is an <code>Integer</code> (the name type, 0-8) and - * whose second entry is a <code>String</code> or a byte array (the name, - * in string or ASN.1 DER encoded form, respectively). There can be multiple - * names of the same type. If <code>null</code> is supplied as the value - * for this argument, no subjectAlternativeNames check will be performed.<br /> - * <br /> - * Each subject alternative name in the <code>Collection</code> may be - * specified either as a <code>String</code> or as an ASN.1 encoded byte - * array. For more details about the formats used, see - * {@link #addSubjectAlternativeName(int, String) addSubjectAlternativeName(int type, String name)} - * and - * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name}).<br /> - * <br /> - * Note that the <code>names</code> parameter can contain duplicate names - * (same name and name type), but they may be removed from the - * <code>Collection</code> of names returned by the - * {@link #getSubjectAlternativeNames} method.<br /> - * <br /> - * Note that a deep copy is performed on the Collection to protect against - * subsequent modifications. - * - * @param names - - * a Collection of names (or null) - * - * @exception IOException - * if a parsing error occurs - * - * @see #getSubjectAlternativeNames() - */ - public void setSubjectAlternativeNames(Collection names) throws IOException - { - try - { - if (names == null || names.isEmpty()) - { - subjectAltNames = null; - subjectAltNamesByte = null; - } - else - { - subjectAltNames = new HashSet(); - subjectAltNamesByte = new HashSet(); - Iterator iter = names.iterator(); - List item; - int type; - Object data; - while (iter.hasNext()) - { - item = (List)iter.next(); - type = ((Integer)item.get(0)).intValue(); - data = item.get(1); - if (data instanceof String) - { - addSubjectAlternativeName(type, (String)data); - } - else if (data instanceof byte[]) - { - addSubjectAlternativeName(type, (byte[])data); - } - else - { - throw new IOException( - "parsing error: unknown data type"); - } - } - } - } - catch (Exception ex) - { - throw new IOException("parsing exception:\n" + ex.toString()); - } - } - - /** - * Adds a name to the subjectAlternativeNames criterion. The - * <code>X509Certificate</code> must contain all or at least one of the - * specified subjectAlternativeNames, depending on the value of the - * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).<br /> - * <br /> - * This method allows the caller to add a name to the set of subject - * alternative names. The specified name is added to any previous value for - * the subjectAlternativeNames criterion. If the specified name is a - * duplicate, it may be ignored.<br /> - * <br /> - * The name is provided in string format. RFC 822, DNS, and URI names use - * the well-established string formats for those types (subject to the - * restrictions included in RFC 2459). IPv4 address names are supplied using - * dotted quad notation. OID address names are represented as a series of - * nonnegative integers separated by periods. And directory names - * (distinguished names) are supplied in RFC 2253 format. No standard string - * format is defined for otherNames, X.400 names, EDI party names, IPv6 - * address names, or any other type of names. They should be specified using - * the - * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name)} - * method. - * - * @param type - * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) - * @param name - - * the name in string form (not null) - * - * @exception IOException - * if a parsing error occurs - */ - public void addSubjectAlternativeName(int type, String name) - throws IOException - { - // TODO full implementation of CertUtil.parseGeneralName - byte[] encoded = CertUtil.parseGeneralName(type, name); - List tmpList = new ArrayList(); - tmpList.add(Integers.valueOf(type)); - tmpList.add(name); - subjectAltNames.add(tmpList); - tmpList.set(1, encoded); - subjectAltNamesByte.add(tmpList); - } - - /** - * Adds a name to the subjectAlternativeNames criterion. The - * <code>X509Certificate</code> must contain all or at least one of the - * specified subjectAlternativeNames, depending on the value of the - * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).<br /> - * <br /> - * This method allows the caller to add a name to the set of subject - * alternative names. The specified name is added to any previous value for - * the subjectAlternativeNames criterion. If the specified name is a - * duplicate, it may be ignored.<br /> - * <br /> - * The name is provided as a byte array. This byte array should contain the - * DER encoded name, as it would appear in the GeneralName structure defined - * in RFC 2459 and X.509. The encoded byte array should only contain the - * encoded value of the name, and should not include the tag associated with - * the name in the GeneralName structure. The ASN.1 definition of this - * structure appears below.<br /> - * <br /> - * - * <pre> - * GeneralName ::= CHOICE { - * otherName [0] OtherName, - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * iPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER} - * </pre> - * - * <br /> - * <br /> - * Note that the byte array supplied here is cloned to protect against - * subsequent modifications.<br /> - * <br /> - * <b>TODO: check encoded format</b> - * - * @param type - * the name type (0-8, as listed above) - * @param name - * a byte array containing the name in ASN.1 DER encoded form - * - * @exception IOException - * if a parsing error occurs - */ - public void addSubjectAlternativeName(int type, byte[] name) - throws IOException - { - // TODO check encoded format - List tmpList = new ArrayList(); - tmpList.add(Integers.valueOf(type)); - tmpList.add(name.clone()); - subjectAltNames.add(tmpList); - subjectAltNamesByte.add(tmpList); - } - - /** - * Sets the name constraints criterion. The <code>X509Certificate</code> - * must have subject and subject alternative names that meet the specified - * name constraints.<br /> - * <br /> - * The name constraints are specified as a byte array. This byte array - * should contain the DER encoded form of the name constraints, as they - * would appear in the NameConstraints structure defined in RFC 2459 and - * X.509. The ASN.1 definition of this structure appears below.<br /> - * <br /> - * - * <pre> - * NameConstraints ::= SEQUENCE { - * permittedSubtrees [0] GeneralSubtrees OPTIONAL, - * excludedSubtrees [1] GeneralSubtrees OPTIONAL } - * - * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree - * - * GeneralSubtree ::= SEQUENCE { - * base GeneralName, - * minimum [0] BaseDistance DEFAULT 0, - * maximum [1] BaseDistance OPTIONAL } - * - * BaseDistance ::= INTEGER (0..MAX) - * - * GeneralName ::= CHOICE { - * otherName [0] OtherName, - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * iPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER} - * </pre> - * - * <br /> - * <br /> - * Note that the byte array supplied here is cloned to protect against - * subsequent modifications.<br /> - * <br /> - * <b>TODO: implement this</b> - * - * @param bytes - * a byte array containing the ASN.1 DER encoding of a - * NameConstraints extension to be used for checking name - * constraints. Only the value of the extension is included, not - * the OID or criticality flag. Can be <code>null</code>, in - * which case no name constraints check will be performed - * - * @exception IOException - * if a parsing error occurs - * @exception UnsupportedOperationException - * because this method is not supported - * @see #getNameConstraints() - */ - public void setNameConstraints(byte[] bytes) throws IOException - { - throw new UnsupportedOperationException(); - } - - /** - * Sets the basic constraints constraint. If the value is greater than or - * equal to zero, <code>X509Certificates</code> must include a - * basicConstraints extension with a pathLen of at least this value. If the - * value is -2, only end-entity certificates are accepted. If the value is - * -1, no check is done.<br /> - * <br /> - * This constraint is useful when building a certification path forward - * (from the target toward the trust anchor. If a partial path has been - * built, any candidate certificate must have a maxPathLen value greater - * than or equal to the number of certificates in the partial path. - * - * @param minMaxPathLen - * the value for the basic constraints constraint - * - * @exception IllegalArgumentException - * if the value is less than -2 - * - * @see #getBasicConstraints() - */ - public void setBasicConstraints(int minMaxPathLen) - { - if (minMaxPathLen < -2) - { - throw new IllegalArgumentException("minMaxPathLen must be >= -2"); - } - - this.minMaxPathLen = minMaxPathLen; - } - - /** - * Sets the policy constraint. The X509Certificate must include at least one - * of the specified policies in its certificate policies extension. If - * certPolicySet is empty, then the X509Certificate must include at least - * some specified policy in its certificate policies extension. If - * certPolicySet is null, no policy check will be performed.<br /> - * <br /> - * Note that the Set is cloned to protect against subsequent modifications.<br /> - * <br /> - * <b>TODO: implement match check for this</b> - * - * @param certPolicySet - * a Set of certificate policy OIDs in string format (or null). - * Each OID is represented by a set of nonnegative integers - * separated by periods. - * - * @exception IOException - * if a parsing error occurs on the OID such as the first - * component is not 0, 1 or 2 or the second component is - * greater than 39. - * - * @see #getPolicy() - */ - public void setPolicy(Set certPolicySet) throws IOException - { - if (certPolicySet == null) - { - policy = null; - policyOID = null; - } - else - { - policyOID = new HashSet(); - Iterator iter = certPolicySet.iterator(); - Object item; - while (iter.hasNext()) - { - item = iter.next(); - if (item instanceof String) - { - CertUtil.parseOID((String)item); - policyOID.add(new ASN1ObjectIdentifier((String)item)); - } - else - { - throw new IOException( - "certPolicySet contains null values or non String objects"); - } - } - policy = new HashSet(certPolicySet); - } - } - - /** - * Sets the pathToNames criterion. The <code>X509Certificate</code> must - * not include name constraints that would prohibit building a path to the - * specified names.<br /> - * <br /> - * This method allows the caller to specify, with a single method call, the - * complete set of names which the <code>X509Certificates</code>'s name - * constraints must permit. The specified value replaces the previous value - * for the pathToNames criterion.<br /> - * <br /> - * This constraint is useful when building a certification path forward - * (from the target toward the trust anchor. If a partial path has been - * built, any candidate certificate must not include name constraints that - * would prohibit building a path to any of the names in the partial path.<br /> - * <br /> - * The names parameter (if not <code>null</code>) is a - * <code>Collection</code> with one entry for each name to be included in - * the pathToNames criterion. Each entry is a <code>List</code> whose - * first entry is an Integer (the name type, 0-8) and whose second entry is - * a <code>String</code> or a byte array (the name, in string or ASN.1 DER - * encoded form, respectively). There can be multiple names of the same - * type. If <code>null</code> is supplied as the value for this argument, - * no pathToNames check will be performed.<br /> - * <br /> - * Each name in the Collection may be specified either as a String or as an - * ASN.1 encoded byte array. For more details about the formats used, see - * {@link #addPathToName(int, String) addPathToName(int type, String name)} - * and - * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)}.<br /> - * <br /> - * Note that the names parameter can contain duplicate names (same name and - * name type), but they may be removed from the Collection of names returned - * by the {@link #getPathToNames} method.<br /> - * <br /> - * Note that a deep copy is performed on the Collection to protect against - * subsequent modifications.<br /> - * <br /> - * <b>TODO: implement this match check for this</b> - * - * @param names - * a Collection with one entry per name (or <code>null</code>) - * - * @exception IOException - * if a parsing error occurs - * @exception UnsupportedOperationException - * because this method is not supported - * - * @see #getPathToNames() - */ - public void setPathToNames(Collection names) throws IOException - { - try - { - if (names == null || names.isEmpty()) - { - pathToNames = null; - pathToNamesByte = null; - } - else - { - pathToNames = new HashSet(); - pathToNamesByte = new HashSet(); - Iterator iter = names.iterator(); - List item; - int type; - Object data; - - while (iter.hasNext()) - { - item = (List)iter.next(); - type = ((Integer)item.get(0)).intValue(); - data = item.get(1); - if (data instanceof String) - { - addPathToName(type, (String)data); - } - else if (data instanceof byte[]) - { - addPathToName(type, (byte[])data); - } - else - { - throw new IOException( - "parsing error: unknown data type"); - } - } - } - } - catch (Exception ex) - { - throw new IOException("parsing exception:\n" + ex.toString()); - } - } - - /** - * Adds a name to the pathToNames criterion. The - * <code>X509Certificate</code> must not include name constraints that - * would prohibit building a path to the specified name.<br /> - * <br /> - * This method allows the caller to add a name to the set of names which the - * <code>X509Certificates</code>'s name constraints must permit. The - * specified name is added to any previous value for the pathToNames - * criterion. If the name is a duplicate, it may be ignored.<br /> - * <br /> - * The name is provided in string format. RFC 822, DNS, and URI names use - * the well-established string formats for those types (subject to the - * restrictions included in RFC 2459). IPv4 address names are supplied using - * dotted quad notation. OID address names are represented as a series of - * nonnegative integers separated by periods. And directory names - * (distinguished names) are supplied in RFC 2253 format. No standard string - * format is defined for otherNames, X.400 names, EDI party names, IPv6 - * address names, or any other type of names. They should be specified using - * the - * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)} - * method.<br /> - * <br /> - * <b>TODO: implement this match check for this</b> - * - * @param type - * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) - * @param name - * the name in string form - * - * @exceptrion IOException if a parsing error occurs - */ - public void addPathToName(int type, String name) throws IOException - { - // TODO full implementation of CertUtil.parseGeneralName - byte[] encoded = CertUtil.parseGeneralName(type, name); - List tmpList = new ArrayList(); - tmpList.add(Integers.valueOf(type)); - tmpList.add(name); - pathToNames.add(tmpList); - tmpList.set(1, encoded); - pathToNamesByte.add(tmpList); - throw new UnsupportedOperationException(); - } - - /** - * Adds a name to the pathToNames criterion. The - * <code>X509Certificate</code> must not include name constraints that - * would prohibit building a path to the specified name.<br /> - * <br /> - * This method allows the caller to add a name to the set of names which the - * <code>X509Certificates</code>'s name constraints must permit. The - * specified name is added to any previous value for the pathToNames - * criterion. If the name is a duplicate, it may be ignored.<br /> - * <br /> - * The name is provided as a byte array. This byte array should contain the - * DER encoded name, as it would appear in the GeneralName structure defined - * in RFC 2459 and X.509. The ASN.1 definition of this structure appears in - * the documentation for - * {@link #addSubjectAlternativeName(int,byte[]) addSubjectAlternativeName(int type, byte[] name)}.<br /> - * <br /> - * Note that the byte array supplied here is cloned to protect against - * subsequent modifications.<br /> - * <br /> - * <b>TODO: implement this match check for this</b> - * - * @param type - * the name type (0-8, as specified in RFC 2459, section 4.2.1.7) - * @param name - * a byte array containing the name in ASN.1 DER encoded form - * - * @exception IOException - * if a parsing error occurs - */ - public void addPathToName(int type, byte[] name) throws IOException - { - // TODO check encoded format - List tmpList = new ArrayList(); - tmpList.add(Integers.valueOf(type)); - tmpList.add(name.clone()); - pathToNames.add(tmpList); - pathToNamesByte.add(tmpList); - } - - /** - * Returns the certificateEquals criterion. The specified - * <code>X509Certificate</code> must be equal to the - * <code>X509Certificate</code> passed to the match method. If - * <code>null</code>, this check is not applied. - * - * @retrun the <code>X509Certificate</code> to match (or <code>null</code>) - * - * @see #setCertificate(java.security.cert.X509Certificate) - */ - public X509Certificate getCertificate() - { - return x509Cert; - } - - /** - * Returns the serialNumber criterion. The specified serial number must - * match the certificate serial number in the <code>X509Certificate</code>. - * If <code>null</code>, any certificate serial number will do. - * - * @return the certificate serial number to match (or <code>null</code>) - * - * @see #setSerialNumber(java.math.BigInteger) - */ - public BigInteger getSerialNumber() - { - return serialNumber; - } - - /** - * Returns the issuer criterion as a String. This distinguished name must - * match the issuer distinguished name in the <code>X509Certificate</code>. - * If <code>null</code>, the issuer criterion is disabled and any issuer - * distinguished name will do.<br /> - * <br /> - * If the value returned is not <code>null</code>, it is a distinguished - * name, in RFC 2253 format.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for formatiing - * byte[] issuerDN to String. - * - * @return the required issuer distinguished name in RFC 2253 format (or - * <code>null</code>) - */ - public String getIssuerAsString() - { - if (issuerDN instanceof String) - { - return new String((String)issuerDN); - } - else if (issuerDNX509 != null) - { - return issuerDNX509.toString(); - } - - return null; - } - - /** - * Returns the issuer criterion as a byte array. This distinguished name - * must match the issuer distinguished name in the - * <code>X509Certificate</code>. If <code>null</code>, the issuer - * criterion is disabled and any issuer distinguished name will do.<br /> - * <br /> - * If the value returned is not <code>null</code>, it is a byte array - * containing a single DER encoded distinguished name, as defined in X.501. - * The ASN.1 notation for this structure is supplied in the documentation - * for {@link #setIssuer(byte[]) setIssuer(byte [] issuerDN)}.<br /> - * <br /> - * Note that the byte array returned is cloned to protect against subsequent - * modifications.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.DEROutputStream DEROutputStream}, - * {@link org.spongycastle.asn1.x509.X509Name X509Name} to gnerate byte[] - * output for String issuerDN. - * - * @return a byte array containing the required issuer distinguished name in - * ASN.1 DER format (or <code>null</code>) - * - * @exception IOException - * if an encoding error occurs - */ - public byte[] getIssuerAsBytes() throws IOException - { - if (issuerDN instanceof byte[]) - { - return (byte[])((byte[])issuerDN).clone(); - } - else if (issuerDNX509 != null) - { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - DEROutputStream derOutStream = new DEROutputStream(outStream); - - derOutStream.writeObject(issuerDNX509.toASN1Primitive()); - derOutStream.close(); - - return outStream.toByteArray(); - } - - return null; - } - - /** - * Returns the subject criterion as a String. This distinguished name must - * match the subject distinguished name in the <code>X509Certificate</code>. - * If <code>null</code>, the subject criterion is disabled and any - * subject distinguished name will do.<br /> - * <br /> - * If the value returned is not <code>null</code>, it is a distinguished - * name, in RFC 2253 format.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for formatiing - * byte[] subjectDN to String. - * - * @return the required subject distinguished name in RFC 2253 format (or - * <code>null</code>) - */ - public String getSubjectAsString() - { - if (subjectDN instanceof String) - { - return new String((String)subjectDN); - } - else if (subjectDNX509 != null) - { - return subjectDNX509.toString(); - } - - return null; - } - - /** - * Returns the subject criterion as a byte array. This distinguished name - * must match the subject distinguished name in the - * <code>X509Certificate</code>. If <code>null</code>, the subject - * criterion is disabled and any subject distinguished name will do.<br /> - * <br /> - * If the value returned is not <code>null</code>, it is a byte array - * containing a single DER encoded distinguished name, as defined in X.501. - * The ASN.1 notation for this structure is supplied in the documentation - * for {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.<br /> - * <br /> - * Note that the byte array returned is cloned to protect against subsequent - * modifications.<br /> - * <br /> - * Uses {@link org.spongycastle.asn1.DEROutputStream DEROutputStream}, - * {@link org.spongycastle.asn1.x509.X509Name X509Name} to gnerate byte[] - * output for String subjectDN. - * - * @return a byte array containing the required subject distinguished name - * in ASN.1 DER format (or <code>null</code>) - * - * @exception IOException - * if an encoding error occurs - */ - public byte[] getSubjectAsBytes() throws IOException - { - if (subjectDN instanceof byte[]) - { - return (byte[])((byte[])subjectDN).clone(); - } - else if (subjectDNX509 != null) - { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - DEROutputStream derOutStream = new DEROutputStream(outStream); - - derOutStream.writeObject(subjectDNX509.toASN1Primitive()); - derOutStream.close(); - - return outStream.toByteArray(); - } - - return null; - } - - /** - * Returns the subjectKeyIdentifier criterion. The - * <code>X509Certificate</code> must contain a SubjectKeyIdentifier - * extension with the specified value. If <code>null</code>, no - * subjectKeyIdentifier check will be done.<br /> - * <br /> - * Note that the byte array returned is cloned to protect against subsequent - * modifications. - * - * @return the key identifier (or <code>null</code>) - * - * @see #setSubjectKeyIdentifier - */ - public byte[] getSubjectKeyIdentifier() - { - if (subjectKeyID != null) - { - return (byte[])subjectKeyID.clone(); - } - - return null; - } - - /** - * Returns the authorityKeyIdentifier criterion. The - * <code>X509Certificate</code> must contain a AuthorityKeyIdentifier - * extension with the specified value. If <code>null</code>, no - * authorityKeyIdentifier check will be done.<br /> - * <br /> - * Note that the byte array returned is cloned to protect against subsequent - * modifications. - * - * @return the key identifier (or <code>null</code>) - * - * @see #setAuthorityKeyIdentifier - */ - public byte[] getAuthorityKeyIdentifier() - { - if (authorityKeyID != null) - { - return (byte[])authorityKeyID.clone(); - } - - return null; - } - - /** - * Returns the certificateValid criterion. The specified date must fall - * within the certificate validity period for the - * <code>X509Certificate</code>. If <code>null</code>, no - * certificateValid check will be done.<br /> - * <br /> - * Note that the <code>Date</code> returned is cloned to protect against - * subsequent modifications. - * - * @return the <code>Date</code> to check (or <code>null</code>) - * - * @see #setCertificateValid - */ - public Date getCertificateValid() - { - if (certValid != null) - { - return new Date(certValid.getTime()); - } - - return null; - } - - /** - * Returns the privateKeyValid criterion. The specified date must fall - * within the private key validity period for the - * <code>X509Certificate</code>. If <code>null</code>, no - * privateKeyValid check will be done.<br /> - * <br /> - * Note that the <code>Date</code> returned is cloned to protect against - * subsequent modifications. - * - * @return the <code>Date</code> to check (or <code>null</code>) - * - * @see #setPrivateKeyValid - */ - public Date getPrivateKeyValid() - { - if (privateKeyValid != null) - { - return new Date(privateKeyValid.getTime()); - } - - return null; - } - - /** - * Returns the subjectPublicKeyAlgID criterion. The - * <code>X509Certificate</code> must contain a subject public key with the - * specified algorithm. If <code>null</code>, no subjectPublicKeyAlgID - * check will be done. - * - * @return the object identifier (OID) of the signature algorithm to check - * for (or <code>null</code>). An OID is represented by a set of - * nonnegative integers separated by periods. - * - * @see #setSubjectPublicKeyAlgID - */ - public String getSubjectPublicKeyAlgID() - { - if (subjectKeyAlgID != null) - { - return subjectKeyAlgID.toString(); - } - - return null; - } - - /** - * Returns the subjectPublicKey criterion. The <code>X509Certificate</code> - * must contain the specified subject public key. If <code>null</code>, - * no subjectPublicKey check will be done. - * - * @return the subject public key to check for (or <code>null</code>) - * - * @see #setSubjectPublicKey - */ - public PublicKey getSubjectPublicKey() - { - return subjectPublicKey; - } - - /** - * Returns the keyUsage criterion. The <code>X509Certificate</code> must - * allow the specified keyUsage values. If null, no keyUsage check will be - * done.<br /> - * <br /> - * Note that the boolean array returned is cloned to protect against - * subsequent modifications. - * - * @return a boolean array in the same format as the boolean array returned - * by - * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. - * Or <code>null</code>. - * - * @see #setKeyUsage - */ - public boolean[] getKeyUsage() - { - if (keyUsage != null) - { - return (boolean[])keyUsage.clone(); - } - - return null; - } - - /** - * Returns the extendedKeyUsage criterion. The <code>X509Certificate</code> - * must allow the specified key purposes in its extended key usage - * extension. If the <code>keyPurposeSet</code> returned is empty or - * <code>null</code>, no extendedKeyUsage check will be done. Note that - * an <code>X509Certificate</code> that has no extendedKeyUsage extension - * implicitly allows all key purposes. - * - * @return an immutable <code>Set</code> of key purpose OIDs in string - * format (or <code>null</code>) - * @see #setExtendedKeyUsage - */ - public Set getExtendedKeyUsage() - { - if (keyPurposeSet == null || keyPurposeSet.isEmpty()) - { - return keyPurposeSet; - } - - Set returnSet = new HashSet(); - Iterator iter = keyPurposeSet.iterator(); - while (iter.hasNext()) - { - returnSet.add(iter.next().toString()); - } - - return Collections.unmodifiableSet(returnSet); - } - - /** - * Indicates if the <code>X509Certificate</code> must contain all or at - * least one of the subjectAlternativeNames specified in the - * {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or - * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If - * <code>true</code>, the <code>X509Certificate</code> must contain all - * of the specified subject alternative names. If <code>false</code>, the - * <code>X509Certificate</code> must contain at least one of the specified - * subject alternative names. - * - * @return <code>true</code> if the flag is enabled; <code>false</code> - * if the flag is disabled. The flag is <code>true</code> by - * default. - * - * @see #setMatchAllSubjectAltNames - */ - public boolean getMatchAllSubjectAltNames() - { - return matchAllSubjectAltNames; - } - - /** - * Returns a copy of the subjectAlternativeNames criterion. The - * <code>X509Certificate</code> must contain all or at least one of the - * specified subjectAlternativeNames, depending on the value of the - * matchAllNames flag (see {@link #getMatchAllSubjectAltNames - * getMatchAllSubjectAltNames}). If the value returned is <code>null</code>, - * no subjectAlternativeNames check will be performed.<br /> - * <br /> - * If the value returned is not <code>null</code>, it is a - * <code>Collection</code> with one entry for each name to be included in - * the subject alternative name criterion. Each entry is a <code>List</code> - * whose first entry is an <code>Integer</code> (the name type, 0-8) and - * whose second entry is a <code>String</code> or a byte array (the name, - * in string or ASN.1 DER encoded form, respectively). There can be multiple - * names of the same type. Note that the <code>Collection</code> returned - * may contain duplicate names (same name and name type).<br /> - * <br /> - * Each subject alternative name in the <code>Collection</code> may be - * specified either as a <code>String</code> or as an ASN.1 encoded byte - * array. For more details about the formats used, see - * {@link #addSubjectAlternativeName(int type, String name) - * addSubjectAlternativeName(int type, String name)} and - * {@link #addSubjectAlternativeName(int type, byte [] name) - * addSubjectAlternativeName(int type, byte [] name)}.<br /> - * <br /> - * Note that a deep copy is performed on the <code>Collection</code> to - * protect against subsequent modifications. - * - * @return a <code>Collection</code> of names (or <code>null</code>) - * - * @see #setSubjectAlternativeNames - */ - public Collection getSubjectAlternativeNames() - { - if (subjectAltNames != null) - { - return null; - } - - Set returnAltNames = new HashSet(); - List returnList; - Iterator iter = subjectAltNames.iterator(); - List obj; - while (iter.hasNext()) - { - obj = (List)iter.next(); - returnList = new ArrayList(); - returnList.add(obj.get(0)); - if (obj.get(1) instanceof byte[]) - { - returnList.add(((byte[])obj.get(1)).clone()); - } - else - { - returnList.add(obj.get(1)); - } - returnAltNames.add(returnList); - } - - return returnAltNames; - } - - /** - * Returns the name constraints criterion. The <code>X509Certificate</code> - * must have subject and subject alternative names that meet the specified - * name constraints.<br /> - * <br /> - * The name constraints are returned as a byte array. This byte array - * contains the DER encoded form of the name constraints, as they would - * appear in the NameConstraints structure defined in RFC 2459 and X.509. - * The ASN.1 notation for this structure is supplied in the documentation - * for - * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.<br /> - * <br /> - * Note that the byte array returned is cloned to protect against subsequent - * modifications.<br /> - * <br /> - * <b>TODO: implement this</b> - * - * @return a byte array containing the ASN.1 DER encoding of a - * NameConstraints extension used for checking name constraints. - * <code>null</code> if no name constraints check will be - * performed. - * - * @exception UnsupportedOperationException - * because this method is not supported - * - * @see #setNameConstraints - */ - public byte[] getNameConstraints() - { - throw new UnsupportedOperationException(); - } - - /** - * Returns the basic constraints constraint. If the value is greater than or - * equal to zero, the <code>X509Certificates</code> must include a - * basicConstraints extension with a pathLen of at least this value. If the - * value is -2, only end-entity certificates are accepted. If the value is - * -1, no basicConstraints check is done. - * - * @return the value for the basic constraints constraint - * - * @see #setBasicConstraints - */ - public int getBasicConstraints() - { - return minMaxPathLen; - } - - /** - * Returns the policy criterion. The <code>X509Certificate</code> must - * include at least one of the specified policies in its certificate - * policies extension. If the <code>Set</code> returned is empty, then the - * <code>X509Certificate</code> must include at least some specified - * policy in its certificate policies extension. If the <code>Set</code> - * returned is <code>null</code>, no policy check will be performed. - * - * @return an immutable <code>Set</code> of certificate policy OIDs in - * string format (or <code>null</code>) - * - * @see #setPolicy - */ - public Set getPolicy() - { - if (policy == null) - { - return null; - } - - return Collections.unmodifiableSet(policy); - } - - /** - * Returns a copy of the pathToNames criterion. The - * <code>X509Certificate</code> must not include name constraints that - * would prohibit building a path to the specified names. If the value - * returned is <code>null</code>, no pathToNames check will be performed.<br /> - * <br /> - * If the value returned is not <code>null</code>, it is a - * <code>Collection</code> with one entry for each name to be included in - * the pathToNames criterion. Each entry is a <code>List</code> whose - * first entry is an <code>Integer</code> (the name type, 0-8) and whose - * second entry is a <code>String</code> or a byte array (the name, in - * string or ASN.1 DER encoded form, respectively). There can be multiple - * names of the same type. Note that the <code>Collection</code> returned - * may contain duplicate names (same name and name type).<br /> - * <br /> - * Each name in the <code>Collection</code> may be specified either as a - * <code>String</code> or as an ASN.1 encoded byte array. For more details - * about the formats used, see {@link #addPathToName(int type, String name) - * addPathToName(int type, String name)} and - * {@link #addPathToName(int type, byte [] name) addPathToName(int type, - * byte [] name)}.<br /> - * <br /> - * Note that a deep copy is performed on the <code>Collection</code> to - * protect against subsequent modifications. - * - * @return a <code>Collection</code> of names (or <code>null</code>) - * - * @see #setPathToNames - */ - public Collection getPathToNames() - { - if (pathToNames == null) - { - return null; - } - - Set returnPathToNames = new HashSet(); - List returnList; - Iterator iter = pathToNames.iterator(); - List obj; - - while (iter.hasNext()) - { - obj = (List)iter.next(); - returnList = new ArrayList(); - returnList.add(obj.get(0)); - if (obj.get(1) instanceof byte[]) - { - returnList.add(((byte[])obj.get(1)).clone()); - } - else - { - returnList.add(obj.get(1)); - } - returnPathToNames.add(returnList); - } - - return returnPathToNames; - } - - /** - * Return a printable representation of the <code>CertSelector</code>.<br /> - * <br /> - * <b>TODO: implement output for currently unsupported options(name - * constraints)</b><br /> - * <br /> - * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.spongycastle.asn1.ASN1Object ASN1Object}, - * {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId} - * - * @return a <code>String</code> describing the contents of the - * <code>CertSelector</code> - */ - public String toString() - { - StringBuffer sb = new StringBuffer(); - sb.append("X509CertSelector: [\n"); - if (x509Cert != null) - { - sb.append(" Certificate: ").append(x509Cert).append('\n'); - } - if (serialNumber != null) - { - sb.append(" Serial Number: ").append(serialNumber).append('\n'); - } - if (issuerDN != null) - { - sb.append(" Issuer: ").append(getIssuerAsString()).append('\n'); - } - if (subjectDN != null) - { - sb.append(" Subject: ").append(getSubjectAsString()).append('\n'); - } - try - { - if (subjectKeyID != null) - { - ByteArrayInputStream inStream = new ByteArrayInputStream( - subjectKeyID); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); - sb.append(" Subject Key Identifier: ") - .append(ASN1Dump.dumpAsString(derObject)).append('\n'); - } - if (authorityKeyID != null) - { - ByteArrayInputStream inStream = new ByteArrayInputStream( - authorityKeyID); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); - sb.append(" Authority Key Identifier: ") - .append(ASN1Dump.dumpAsString(derObject)).append('\n'); - } - } - catch (IOException ex) - { - sb.append(ex.getMessage()).append('\n'); - } - if (certValid != null) - { - sb.append(" Certificate Valid: ").append(certValid).append('\n'); - } - if (privateKeyValid != null) - { - sb.append(" Private Key Valid: ").append(privateKeyValid) - .append('\n'); - } - if (subjectKeyAlgID != null) - { - sb.append(" Subject Public Key AlgID: ") - .append(subjectKeyAlgID).append('\n'); - } - if (subjectPublicKey != null) - { - sb.append(" Subject Public Key: ").append(subjectPublicKey) - .append('\n'); - } - if (keyUsage != null) - { - sb.append(" Key Usage: ").append(keyUsage).append('\n'); - } - if (keyPurposeSet != null) - { - sb.append(" Extended Key Usage: ").append(keyPurposeSet) - .append('\n'); - } - if (policy != null) - { - sb.append(" Policy: ").append(policy).append('\n'); - } - sb.append(" matchAllSubjectAltNames flag: ") - .append(matchAllSubjectAltNames).append('\n'); - if (subjectAltNamesByte != null) - { - sb.append(" SubjectAlternativNames: \n["); - Iterator iter = subjectAltNamesByte.iterator(); - List obj; - try - { - while (iter.hasNext()) - { - obj = (List)iter.next(); - ByteArrayInputStream inStream = new ByteArrayInputStream( - (byte[])obj.get(1)); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); - sb.append(" Type: ").append(obj.get(0)).append(" Data: ") - .append(ASN1Dump.dumpAsString(derObject)).append('\n'); - } - } - catch (IOException ex) - { - sb.append(ex.getMessage()).append('\n'); - } - sb.append("]\n"); - } - if (pathToNamesByte != null) - { - sb.append(" PathToNamesNames: \n["); - Iterator iter = pathToNamesByte.iterator(); - List obj; - try - { - while (iter.hasNext()) - { - obj = (List)iter.next(); - ByteArrayInputStream inStream = new ByteArrayInputStream( - (byte[])obj.get(1)); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); - sb.append(" Type: ").append(obj.get(0)).append(" Data: ") - .append(ASN1Dump.dumpAsString(derObject)).append('\n'); - } - } - catch (IOException ex) - { - sb.append(ex.getMessage()).append('\n'); - } - sb.append("]\n"); - } - sb.append(']'); - return sb.toString(); - } - - /** - * Decides whether a <code>Certificate</code> should be selected.<br /> - * <br /> - * <b>TODO: implement missing tests (name constraints and path to names)</b><br /> - * <br /> - * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence}, - * {@link org.spongycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, - * {@link org.spongycastle.asn1.ASN1Object ASN1Object}, - * {@link org.spongycastle.asn1.DERGeneralizedTime DERGeneralizedTime}, - * {@link org.spongycastle.asn1.x509.X509Name X509Name}, - * {@link org.spongycastle.asn1.x509.X509Extensions X509Extensions}, - * {@link org.spongycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, - * {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId}, - * {@link org.spongycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo}, - * {@link org.spongycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier} - * to access X509 extensions - * - * @param cert - * the <code>Certificate</code> to be checked - * - * @return <code>true</code> if the <code>Certificate</code> should be - * selected, <code>false</code> otherwise - */ - public boolean match(Certificate cert) - { - boolean[] booleanArray; - List tempList; - Iterator tempIter; - - if (!(cert instanceof X509Certificate)) - { - return false; - } - X509Certificate certX509 = (X509Certificate)cert; - - if (x509Cert != null && !x509Cert.equals(certX509)) - { - return false; - } - if (serialNumber != null - && !serialNumber.equals(certX509.getSerialNumber())) - { - return false; - } - try - { - if (issuerDNX509 != null) - { - if (!issuerDNX509.equals(PrincipalUtil - .getIssuerX509Principal(certX509), true)) - { - return false; - } - } - if (subjectDNX509 != null) - { - if (!subjectDNX509.equals(PrincipalUtil - .getSubjectX509Principal(certX509), true)) - { - return false; - } - } - } - catch (Exception ex) - { - return false; - } - if (subjectKeyID != null) - { - byte[] data = certX509 - .getExtensionValue(X509Extensions.SubjectKeyIdentifier - .getId()); - if (data == null) - { - return false; - } - try - { - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - byte[] testData = ((ASN1OctetString)derInputStream.readObject()) - .getOctets(); - if (!Arrays.equals(subjectKeyID, testData)) - { - return false; - } - } - catch (IOException ex) - { - return false; - } - } - if (authorityKeyID != null) - { - byte[] data = certX509 - .getExtensionValue(X509Extensions.AuthorityKeyIdentifier - .getId()); - if (data == null) - { - return false; - } - try - { - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - byte[] testData = ((ASN1OctetString)derInputStream.readObject()) - .getOctets(); - if (!Arrays.equals(authorityKeyID, testData)) - { - return false; - } - } - catch (IOException ex) - { - return false; - } - } - if (certValid != null) - { - if (certX509.getNotAfter() != null - && certValid.after(certX509.getNotAfter())) - { - return false; - } - if (certX509.getNotBefore() != null - && certValid.before(certX509.getNotBefore())) - { - return false; - } - } - if (privateKeyValid != null) - { - try - { - byte[] data = certX509 - .getExtensionValue(X509Extensions.PrivateKeyUsagePeriod - .getId()); - if (data != null) - { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); - // TODO fix this, Sequence contains tagged objects - ASN1Sequence derObject = (ASN1Sequence)derInputStream - .readObject(); - DERGeneralizedTime derDate = DERGeneralizedTime - .getInstance(derObject.getObjectAt(0)); - SimpleDateFormat dateF = new SimpleDateFormat( - "yyyyMMddHHmmssZ"); - if (privateKeyValid.before(dateF.parse(derDate.getTime()))) - { - return false; - } - derDate = DERGeneralizedTime.getInstance(derObject - .getObjectAt(1)); - if (privateKeyValid.after(dateF.parse(derDate.getTime()))) - { - return false; - } - } - } - catch (Exception ex) - { - return false; - } - } - if (subjectKeyAlgID != null) - { - try - { - ByteArrayInputStream inStream = new ByteArrayInputStream( - certX509.getPublicKey().getEncoded()); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo( - (ASN1Sequence)derInputStream.readObject()); - AlgorithmIdentifier algInfo = publicKeyInfo.getAlgorithmId(); - if (!algInfo.getObjectId().equals(subjectKeyAlgID)) - { - return false; - } - } - catch (Exception ex) - { - return false; - } - } - if (subjectPublicKeyByte != null) - { - if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey() - .getEncoded())) - { - return false; - } - } - if (subjectPublicKey != null) - { - if (!subjectPublicKey.equals(certX509.getPublicKey())) - { - return false; - } - } - if (keyUsage != null) - { - booleanArray = certX509.getKeyUsage(); - if (booleanArray != null) - { - for (int i = 0; i < keyUsage.length; i++) - { - if (keyUsage[i] - && (booleanArray.length <= i || !booleanArray[i])) - { - return false; - } - } - } - } - if (keyPurposeSet != null && !keyPurposeSet.isEmpty()) - { - try - { - byte[] data = certX509 - .getExtensionValue(X509Extensions.ExtendedKeyUsage - .getId()); - if (data != null) - { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance( - derInputStream.readObject()); - tempIter = keyPurposeSet.iterator(); - while (tempIter.hasNext()) - { - if (!extendedKeyUsage - .hasKeyPurposeId((KeyPurposeId)tempIter.next())) - { - return false; - } - } - } - } - catch (Exception ex) - { - return false; - } - } - if (minMaxPathLen != -1) - { - if (minMaxPathLen == -2 && certX509.getBasicConstraints() != -1) - { - return false; - } - if (minMaxPathLen >= 0 - && certX509.getBasicConstraints() < minMaxPathLen) - { - return false; - } - } - if (policyOID != null) - { - try - { - byte[] data = certX509 - .getExtensionValue(X509Extensions.CertificatePolicies - .getId()); - if (data == null) - { - return false; - } - if (!policyOID.isEmpty()) - { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); - Enumeration policySequence = ((ASN1Sequence)derInputStream - .readObject()).getObjects(); - ASN1Sequence policyObject; - boolean test = false; - while (policySequence.hasMoreElements() && !test) - { - policyObject = (ASN1Sequence)policySequence - .nextElement(); - if (policyOID.contains(policyObject.getObjectAt(0))) - { - test = true; - } - } - if (!test) - { - return false; - } - } - } - catch (Exception ex) - { - ex.printStackTrace(); - return false; - } - } - if (subjectAltNamesByte != null) - { - try - { - byte[] data = certX509 - .getExtensionValue(X509Extensions.SubjectAlternativeName - .getId()); - if (data == null) - { - return false; - } - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); - Enumeration altNamesSequence = ((ASN1Sequence)derInputStream - .readObject()).getObjects(); - ASN1TaggedObject altNameObject; - boolean test = false; - Set testSet = new HashSet(subjectAltNamesByte); - List testList; - ASN1Object derData; - ByteArrayOutputStream outStream; - DEROutputStream derOutStream; - while (altNamesSequence.hasMoreElements() && !test) - { - altNameObject = (ASN1TaggedObject)altNamesSequence - .nextElement(); - testList = new ArrayList(2); - testList.add(Integers.valueOf(altNameObject.getTagNo())); - derData = altNameObject.getObject(); - outStream = new ByteArrayOutputStream(); - derOutStream = new DEROutputStream(outStream); - derOutStream.writeObject(derData); - derOutStream.close(); - testList.add(outStream.toByteArray()); - - if (testSet.remove(testList)) - { - test = true; - } - - if (matchAllSubjectAltNames && !testSet.isEmpty()) - { - test = false; - } - } - if (!test) - { - return false; - } - } - catch (Exception ex) - { - ex.printStackTrace(); - return false; - } - } - - return true; - } - - /** - * Returns a copy of this object. - * - * @return the copy - */ - public Object clone() - { - try - { - X509CertSelector copy = (X509CertSelector)super.clone(); - if (issuerDN instanceof byte[]) - { - copy.issuerDN = ((byte[])issuerDN).clone(); - } - if (subjectDN instanceof byte[]) - { - copy.subjectDN = ((byte[])subjectDN).clone(); - } - if (subjectKeyID != null) - { - copy.subjectKeyID = (byte[])subjectKeyID.clone(); - } - if (authorityKeyID != null) - { - copy.authorityKeyID = (byte[])authorityKeyID.clone(); - } - if (subjectPublicKeyByte != null) - { - copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte - .clone(); - } - if (keyUsage != null) - { - copy.keyUsage = (boolean[])keyUsage.clone(); - } - if (keyPurposeSet != null) - { - copy.keyPurposeSet = new HashSet(keyPurposeSet); - } - if (policy != null) - { - copy.policy = new HashSet(policy); - copy.policyOID = new HashSet(); - Iterator iter = policyOID.iterator(); - while (iter.hasNext()) - { - copy.policyOID.add(new ASN1ObjectIdentifier( - ((ASN1ObjectIdentifier)iter.next()).getId())); - } - } - if (subjectAltNames != null) - { - copy.subjectAltNames = new HashSet(getSubjectAlternativeNames()); - Iterator iter = subjectAltNamesByte.iterator(); - List obj; - List cloneObj; - while (iter.hasNext()) - { - obj = (List)iter.next(); - cloneObj = new ArrayList(); - cloneObj.add(obj.get(0)); - cloneObj.add(((byte[])obj.get(1)).clone()); - copy.subjectAltNamesByte.add(cloneObj); - } - } - if (pathToNames != null) - { - copy.pathToNames = new HashSet(getPathToNames()); - Iterator iter = pathToNamesByte.iterator(); - List obj; - List cloneObj; - while (iter.hasNext()) - { - obj = (List)iter.next(); - cloneObj = new ArrayList(); - cloneObj.add(obj.get(0)); - cloneObj.add(((byte[])obj.get(1)).clone()); - copy.pathToNamesByte.add(cloneObj); - } - } - return copy; - } - catch (CloneNotSupportedException e) - { - /* Cannot happen */ - throw new InternalError(e.toString()); - } - } -} |