Save This Page
Home » openjdk-7 » java » security » cert » [javadoc | source]
    1   /*
    2    * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.security.cert;
   27   
   28   import java.io.IOException;
   29   import java.math.BigInteger;
   30   import java.security.PublicKey;
   31   import java.util;
   32   import javax.security.auth.x500.X500Principal;
   33   
   34   import sun.misc.HexDumpEncoder;
   35   import sun.security.util.Debug;
   36   import sun.security.util.DerInputStream;
   37   import sun.security.util.DerValue;
   38   import sun.security.util.ObjectIdentifier;
   39   import sun.security.x509;
   40   
   41   /**
   42    * A <code>CertSelector</code> that selects <code>X509Certificates</code> that
   43    * match all specified criteria. This class is particularly useful when
   44    * selecting certificates from a <code>CertStore</code> to build a
   45    * PKIX-compliant certification path.
   46    * <p>
   47    * When first constructed, an <code>X509CertSelector</code> has no criteria
   48    * enabled and each of the <code>get</code> methods return a default value
   49    * (<code>null</code>, or <code>-1</code> for the {@link #getBasicConstraints
   50    * getBasicConstraints} method). Therefore, the {@link #match match}
   51    * method would return <code>true</code> for any <code>X509Certificate</code>.
   52    * Typically, several criteria are enabled (by calling
   53    * {@link #setIssuer setIssuer} or
   54    * {@link #setKeyUsage setKeyUsage}, for instance) and then the
   55    * <code>X509CertSelector</code> is passed to
   56    * {@link CertStore#getCertificates CertStore.getCertificates} or some similar
   57    * method.
   58    * <p>
   59    * Several criteria can be enabled (by calling {@link #setIssuer setIssuer}
   60    * and {@link #setSerialNumber setSerialNumber},
   61    * for example) such that the <code>match</code> method
   62    * usually uniquely matches a single <code>X509Certificate</code>. We say
   63    * usually, since it is possible for two issuing CAs to have the same
   64    * distinguished name and each issue a certificate with the same serial
   65    * number. Other unique combinations include the issuer, subject,
   66    * subjectKeyIdentifier and/or the subjectPublicKey criteria.
   67    * <p>
   68    * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
   69    * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a> for
   70    * definitions of the X.509 certificate extensions mentioned below.
   71    * <p>
   72    * <b>Concurrent Access</b>
   73    * <p>
   74    * Unless otherwise specified, the methods defined in this class are not
   75    * thread-safe. Multiple threads that need to access a single
   76    * object concurrently should synchronize amongst themselves and
   77    * provide the necessary locking. Multiple threads each manipulating
   78    * separate objects need not synchronize.
   79    *
   80    * @see CertSelector
   81    * @see X509Certificate
   82    *
   83    * @since       1.4
   84    * @author      Steve Hanna
   85    */
   86   public class X509CertSelector implements CertSelector {
   87   
   88       private static final Debug debug = Debug.getInstance("certpath");
   89   
   90       private final static ObjectIdentifier ANY_EXTENDED_KEY_USAGE =
   91           ObjectIdentifier.newInternal(new int[] {2, 5, 29, 37, 0});
   92   
   93       static {
   94           CertPathHelperImpl.initialize();
   95       }
   96   
   97       private BigInteger serialNumber;
   98       private X500Principal issuer;
   99       private X500Principal subject;
  100       private byte[] subjectKeyID;
  101       private byte[] authorityKeyID;
  102       private Date certificateValid;
  103       private Date privateKeyValid;
  104       private ObjectIdentifier subjectPublicKeyAlgID;
  105       private PublicKey subjectPublicKey;
  106       private byte[] subjectPublicKeyBytes;
  107       private boolean[] keyUsage;
  108       private Set<String> keyPurposeSet;
  109       private Set<ObjectIdentifier> keyPurposeOIDSet;
  110       private Set<List<?>> subjectAlternativeNames;
  111       private Set<GeneralNameInterface> subjectAlternativeGeneralNames;
  112       private CertificatePolicySet policy;
  113       private Set<String> policySet;
  114       private Set<List<?>> pathToNames;
  115       private Set<GeneralNameInterface> pathToGeneralNames;
  116       private NameConstraintsExtension nc;
  117       private byte[] ncBytes;
  118       private int basicConstraints = -1;
  119       private X509Certificate x509Cert;
  120       private boolean matchAllSubjectAltNames = true;
  121   
  122       private static final Boolean FALSE = Boolean.FALSE;
  123   
  124       private static final int PRIVATE_KEY_USAGE_ID = 0;
  125       private static final int SUBJECT_ALT_NAME_ID = 1;
  126       private static final int NAME_CONSTRAINTS_ID = 2;
  127       private static final int CERT_POLICIES_ID = 3;
  128       private static final int EXTENDED_KEY_USAGE_ID = 4;
  129       private static final int NUM_OF_EXTENSIONS = 5;
  130       private static final String[] EXTENSION_OIDS = new String[NUM_OF_EXTENSIONS];
  131   
  132       static {
  133           EXTENSION_OIDS[PRIVATE_KEY_USAGE_ID]  = "2.5.29.16";
  134           EXTENSION_OIDS[SUBJECT_ALT_NAME_ID]   = "2.5.29.17";
  135           EXTENSION_OIDS[NAME_CONSTRAINTS_ID]   = "2.5.29.30";
  136           EXTENSION_OIDS[CERT_POLICIES_ID]      = "2.5.29.32";
  137           EXTENSION_OIDS[EXTENDED_KEY_USAGE_ID] = "2.5.29.37";
  138       };
  139   
  140       /* Constants representing the GeneralName types */
  141       static final int NAME_ANY = 0;
  142       static final int NAME_RFC822 = 1;
  143       static final int NAME_DNS = 2;
  144       static final int NAME_X400 = 3;
  145       static final int NAME_DIRECTORY = 4;
  146       static final int NAME_EDI = 5;
  147       static final int NAME_URI = 6;
  148       static final int NAME_IP = 7;
  149       static final int NAME_OID = 8;
  150   
  151       /**
  152        * Creates an <code>X509CertSelector</code>. Initially, no criteria are set
  153        * so any <code>X509Certificate</code> will match.
  154        */
  155       public X509CertSelector() {
  156           // empty
  157       }
  158   
  159       /**
  160        * Sets the certificateEquals criterion. The specified
  161        * <code>X509Certificate</code> must be equal to the
  162        * <code>X509Certificate</code> passed to the <code>match</code> method.
  163        * If <code>null</code>, then this check is not applied.
  164        *
  165        * <p>This method is particularly useful when it is necessary to
  166        * match a single certificate. Although other criteria can be specified
  167        * in conjunction with the certificateEquals criterion, it is usually not
  168        * practical or necessary.
  169        *
  170        * @param cert the <code>X509Certificate</code> to match (or
  171        * <code>null</code>)
  172        * @see #getCertificate
  173        */
  174       public void setCertificate(X509Certificate cert) {
  175           x509Cert = cert;
  176       }
  177   
  178       /**
  179        * Sets the serialNumber criterion. The specified serial number
  180        * must match the certificate serial number in the
  181        * <code>X509Certificate</code>. If <code>null</code>, any certificate
  182        * serial number will do.
  183        *
  184        * @param serial the certificate serial number to match
  185        *        (or <code>null</code>)
  186        * @see #getSerialNumber
  187        */
  188       public void setSerialNumber(BigInteger serial) {
  189           serialNumber = serial;
  190       }
  191   
  192       /**
  193        * Sets the issuer criterion. The specified distinguished name
  194        * must match the issuer distinguished name in the
  195        * <code>X509Certificate</code>. If <code>null</code>, any issuer
  196        * distinguished name will do.
  197        *
  198        * @param issuer a distinguished name as X500Principal
  199        *                 (or <code>null</code>)
  200        * @since 1.5
  201        */
  202       public void setIssuer(X500Principal issuer) {
  203           this.issuer = issuer;
  204       }
  205   
  206       /**
  207        * <strong>Denigrated</strong>, use {@linkplain #setIssuer(X500Principal)}
  208        * or {@linkplain #setIssuer(byte[])} instead. This method should not be
  209        * relied on as it can fail to match some certificates because of a loss of
  210        * encoding information in the
  211        * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> String form
  212        * of some distinguished names.
  213        * <p>
  214        * Sets the issuer criterion. The specified distinguished name
  215        * must match the issuer distinguished name in the
  216        * <code>X509Certificate</code>. If <code>null</code>, any issuer
  217        * distinguished name will do.
  218        * <p>
  219        * If <code>issuerDN</code> is not <code>null</code>, it should contain a
  220        * distinguished name, in RFC 2253 format.
  221        *
  222        * @param issuerDN a distinguished name in RFC 2253 format
  223        *                 (or <code>null</code>)
  224        * @throws IOException if a parsing error occurs (incorrect form for DN)
  225        */
  226       public void setIssuer(String issuerDN) throws IOException {
  227           if (issuerDN == null) {
  228               issuer = null;
  229           } else {
  230               issuer = new X500Name(issuerDN).asX500Principal();
  231           }
  232       }
  233   
  234       /**
  235        * Sets the issuer criterion. The specified distinguished name
  236        * must match the issuer distinguished name in the
  237        * <code>X509Certificate</code>. If <code>null</code> is specified,
  238        * the issuer criterion is disabled and any issuer distinguished name will
  239        * do.
  240        * <p>
  241        * If <code>issuerDN</code> is not <code>null</code>, it should contain a
  242        * single DER encoded distinguished name, as defined in X.501. The ASN.1
  243        * notation for this structure is as follows.
  244        * <pre><code>
  245        * Name ::= CHOICE {
  246        *   RDNSequence }
  247        *
  248        * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  249        *
  250        * RelativeDistinguishedName ::=
  251        *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
  252        *
  253        * AttributeTypeAndValue ::= SEQUENCE {
  254        *   type     AttributeType,
  255        *   value    AttributeValue }
  256        *
  257        * AttributeType ::= OBJECT IDENTIFIER
  258        *
  259        * AttributeValue ::= ANY DEFINED BY AttributeType
  260        * ....
  261        * DirectoryString ::= CHOICE {
  262        *       teletexString           TeletexString (SIZE (1..MAX)),
  263        *       printableString         PrintableString (SIZE (1..MAX)),
  264        *       universalString         UniversalString (SIZE (1..MAX)),
  265        *       utf8String              UTF8String (SIZE (1.. MAX)),
  266        *       bmpString               BMPString (SIZE (1..MAX)) }
  267        * </code></pre>
  268        * <p>
  269        * Note that the byte array specified here is cloned to protect against
  270        * subsequent modifications.
  271        *
  272        * @param issuerDN a byte array containing the distinguished name
  273        *                 in ASN.1 DER encoded form (or <code>null</code>)
  274        * @throws IOException if an encoding error occurs (incorrect form for DN)
  275        */
  276       public void setIssuer(byte[] issuerDN) throws IOException {
  277           try {
  278               issuer = (issuerDN == null ? null : new X500Principal(issuerDN));
  279           } catch (IllegalArgumentException e) {
  280               throw (IOException)new IOException("Invalid name").initCause(e);
  281           }
  282       }
  283   
  284       /**
  285        * Sets the subject criterion. The specified distinguished name
  286        * must match the subject distinguished name in the
  287        * <code>X509Certificate</code>. If <code>null</code>, any subject
  288        * distinguished name will do.
  289        *
  290        * @param subject a distinguished name as X500Principal
  291        *                  (or <code>null</code>)
  292        * @since 1.5
  293        */
  294       public void setSubject(X500Principal subject) {
  295           this.subject = subject;
  296       }
  297   
  298       /**
  299        * <strong>Denigrated</strong>, use {@linkplain #setSubject(X500Principal)}
  300        * or {@linkplain #setSubject(byte[])} instead. This method should not be
  301        * relied on as it can fail to match some certificates because of a loss of
  302        * encoding information in the RFC 2253 String form of some distinguished
  303        * names.
  304        * <p>
  305        * Sets the subject criterion. The specified distinguished name
  306        * must match the subject distinguished name in the
  307        * <code>X509Certificate</code>. If <code>null</code>, any subject
  308        * distinguished name will do.
  309        * <p>
  310        * If <code>subjectDN</code> is not <code>null</code>, it should contain a
  311        * distinguished name, in RFC 2253 format.
  312        *
  313        * @param subjectDN a distinguished name in RFC 2253 format
  314        *                  (or <code>null</code>)
  315        * @throws IOException if a parsing error occurs (incorrect form for DN)
  316        */
  317       public void setSubject(String subjectDN) throws IOException {
  318           if (subjectDN == null) {
  319               subject = null;
  320           } else {
  321               subject = new X500Name(subjectDN).asX500Principal();
  322           }
  323       }
  324   
  325       /**
  326        * Sets the subject criterion. The specified distinguished name
  327        * must match the subject distinguished name in the
  328        * <code>X509Certificate</code>. If <code>null</code>, any subject
  329        * distinguished name will do.
  330        * <p>
  331        * If <code>subjectDN</code> is not <code>null</code>, it should contain a
  332        * single DER encoded distinguished name, as defined in X.501. For the ASN.1
  333        * notation for this structure, see
  334        * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.
  335        *
  336        * @param subjectDN a byte array containing the distinguished name in
  337        *                  ASN.1 DER format (or <code>null</code>)
  338        * @throws IOException if an encoding error occurs (incorrect form for DN)
  339        */
  340       public void setSubject(byte[] subjectDN) throws IOException {
  341           try {
  342               subject = (subjectDN == null ? null : new X500Principal(subjectDN));
  343           } catch (IllegalArgumentException e) {
  344               throw (IOException)new IOException("Invalid name").initCause(e);
  345           }
  346       }
  347   
  348       /**
  349        * Sets the subjectKeyIdentifier criterion. The
  350        * <code>X509Certificate</code> must contain a SubjectKeyIdentifier
  351        * extension for which the contents of the extension
  352        * matches the specified criterion value.
  353        * If the criterion value is <code>null</code>, no
  354        * subjectKeyIdentifier check will be done.
  355        * <p>
  356        * If <code>subjectKeyID</code> is not <code>null</code>, it
  357        * should contain a single DER encoded value corresponding to the contents
  358        * of the extension value (not including the object identifier,
  359        * criticality setting, and encapsulating OCTET STRING)
  360        * for a SubjectKeyIdentifier extension.
  361        * The ASN.1 notation for this structure follows.
  362        * <p>
  363        * <pre><code>
  364        * SubjectKeyIdentifier ::= KeyIdentifier
  365        *
  366        * KeyIdentifier ::= OCTET STRING
  367        * </code></pre>
  368        * <p>
  369        * Since the format of subject key identifiers is not mandated by
  370        * any standard, subject key identifiers are not parsed by the
  371        * <code>X509CertSelector</code>. Instead, the values are compared using
  372        * a byte-by-byte comparison.
  373        * <p>
  374        * Note that the byte array supplied here is cloned to protect against
  375        * subsequent modifications.
  376        *
  377        * @param subjectKeyID the subject key identifier (or <code>null</code>)
  378        * @see #getSubjectKeyIdentifier
  379        */
  380       public void setSubjectKeyIdentifier(byte[] subjectKeyID) {
  381           if (subjectKeyID == null) {
  382               this.subjectKeyID = null;
  383           } else {
  384               this.subjectKeyID = subjectKeyID.clone();
  385           }
  386       }
  387   
  388       /**
  389        * Sets the authorityKeyIdentifier criterion. The
  390        * <code>X509Certificate</code> must contain an
  391        * AuthorityKeyIdentifier extension for which the contents of the
  392        * extension value matches the specified criterion value.
  393        * If the criterion value is <code>null</code>, no
  394        * authorityKeyIdentifier check will be done.
  395        * <p>
  396        * If <code>authorityKeyID</code> is not <code>null</code>, it
  397        * should contain a single DER encoded value corresponding to the contents
  398        * of the extension value (not including the object identifier,
  399        * criticality setting, and encapsulating OCTET STRING)
  400        * for an AuthorityKeyIdentifier extension.
  401        * The ASN.1 notation for this structure follows.
  402        * <p>
  403        * <pre><code>
  404        * AuthorityKeyIdentifier ::= SEQUENCE {
  405        *    keyIdentifier             [0] KeyIdentifier           OPTIONAL,
  406        *    authorityCertIssuer       [1] GeneralNames            OPTIONAL,
  407        *    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
  408        *
  409        * KeyIdentifier ::= OCTET STRING
  410        * </code></pre>
  411        * <p>
  412        * Authority key identifiers are not parsed by the
  413        * <code>X509CertSelector</code>.  Instead, the values are
  414        * compared using a byte-by-byte comparison.
  415        * <p>
  416        * When the <code>keyIdentifier</code> field of
  417        * <code>AuthorityKeyIdentifier</code> is populated, the value is
  418        * usually taken from the <code>SubjectKeyIdentifier</code> extension
  419        * in the issuer's certificate.  Note, however, that the result of
  420        * <code>X509Certificate.getExtensionValue(&lt;SubjectKeyIdentifier Object
  421        * Identifier&gt;)</code> on the issuer's certificate may NOT be used
  422        * directly as the input to <code>setAuthorityKeyIdentifier</code>.
  423        * This is because the SubjectKeyIdentifier contains
  424        * only a KeyIdentifier OCTET STRING, and not a SEQUENCE of
  425        * KeyIdentifier, GeneralNames, and CertificateSerialNumber.
  426        * In order to use the extension value of the issuer certificate's
  427        * <code>SubjectKeyIdentifier</code>
  428        * extension, it will be necessary to extract the value of the embedded
  429        * <code>KeyIdentifier</code> OCTET STRING, then DER encode this OCTET
  430        * STRING inside a SEQUENCE.
  431        * For more details on SubjectKeyIdentifier, see
  432        * {@link #setSubjectKeyIdentifier(byte[] subjectKeyID)}.
  433        * <p>
  434        * Note also that the byte array supplied here is cloned to protect against
  435        * subsequent modifications.
  436        *
  437        * @param authorityKeyID the authority key identifier
  438        *        (or <code>null</code>)
  439        * @see #getAuthorityKeyIdentifier
  440        */
  441       public void setAuthorityKeyIdentifier(byte[] authorityKeyID) {
  442           if (authorityKeyID == null) {
  443               this.authorityKeyID = null;
  444           } else {
  445               this.authorityKeyID = authorityKeyID.clone();
  446           }
  447       }
  448   
  449       /**
  450        * Sets the certificateValid criterion. The specified date must fall
  451        * within the certificate validity period for the
  452        * <code>X509Certificate</code>. If <code>null</code>, no certificateValid
  453        * check will be done.
  454        * <p>
  455        * Note that the <code>Date</code> supplied here is cloned to protect
  456        * against subsequent modifications.
  457        *
  458        * @param certValid the <code>Date</code> to check (or <code>null</code>)
  459        * @see #getCertificateValid
  460        */
  461       public void setCertificateValid(Date certValid) {
  462           if (certValid == null) {
  463               certificateValid = null;
  464           } else {
  465               certificateValid = (Date)certValid.clone();
  466           }
  467       }
  468   
  469       /**
  470        * Sets the privateKeyValid criterion. The specified date must fall
  471        * within the private key validity period for the
  472        * <code>X509Certificate</code>. If <code>null</code>, no privateKeyValid
  473        * check will be done.
  474        * <p>
  475        * Note that the <code>Date</code> supplied here is cloned to protect
  476        * against subsequent modifications.
  477        *
  478        * @param privateKeyValid the <code>Date</code> to check (or
  479        *                        <code>null</code>)
  480        * @see #getPrivateKeyValid
  481        */
  482       public void setPrivateKeyValid(Date privateKeyValid) {
  483           if (privateKeyValid == null) {
  484               this.privateKeyValid = null;
  485           } else {
  486               this.privateKeyValid = (Date)privateKeyValid.clone();
  487           }
  488       }
  489   
  490       /**
  491        * Sets the subjectPublicKeyAlgID criterion. The
  492        * <code>X509Certificate</code> must contain a subject public key
  493        * with the specified algorithm. If <code>null</code>, no
  494        * subjectPublicKeyAlgID check will be done.
  495        *
  496        * @param oid The object identifier (OID) of the algorithm to check
  497        *            for (or <code>null</code>). An OID is represented by a
  498        *            set of nonnegative integers separated by periods.
  499        * @throws IOException if the OID is invalid, such as
  500        * the first component being not 0, 1 or 2 or the second component
  501        * being greater than 39.
  502        *
  503        * @see #getSubjectPublicKeyAlgID
  504        */
  505       public void setSubjectPublicKeyAlgID(String oid) throws IOException {
  506           if (oid == null) {
  507               subjectPublicKeyAlgID = null;
  508           } else {
  509               subjectPublicKeyAlgID = new ObjectIdentifier(oid);
  510           }
  511       }
  512   
  513       /**
  514        * Sets the subjectPublicKey criterion. The
  515        * <code>X509Certificate</code> must contain the specified subject public
  516        * key. If <code>null</code>, no subjectPublicKey check will be done.
  517        *
  518        * @param key the subject public key to check for (or <code>null</code>)
  519        * @see #getSubjectPublicKey
  520        */
  521       public void setSubjectPublicKey(PublicKey key) {
  522           if (key == null) {
  523               subjectPublicKey = null;
  524               subjectPublicKeyBytes = null;
  525           } else {
  526               subjectPublicKey = key;
  527               subjectPublicKeyBytes = key.getEncoded();
  528           }
  529       }
  530   
  531       /**
  532        * Sets the subjectPublicKey criterion. The <code>X509Certificate</code>
  533        * must contain the specified subject public key. If <code>null</code>,
  534        * no subjectPublicKey check will be done.
  535        * <p>
  536        * Because this method allows the public key to be specified as a byte
  537        * array, it may be used for unknown key types.
  538        * <p>
  539        * If <code>key</code> is not <code>null</code>, it should contain a
  540        * single DER encoded SubjectPublicKeyInfo structure, as defined in X.509.
  541        * The ASN.1 notation for this structure is as follows.
  542        * <pre><code>
  543        * SubjectPublicKeyInfo  ::=  SEQUENCE  {
  544        *   algorithm            AlgorithmIdentifier,
  545        *   subjectPublicKey     BIT STRING  }
  546        *
  547        * AlgorithmIdentifier  ::=  SEQUENCE  {
  548        *   algorithm               OBJECT IDENTIFIER,
  549        *   parameters              ANY DEFINED BY algorithm OPTIONAL  }
  550        *                              -- contains a value of the type
  551        *                              -- registered for use with the
  552        *                              -- algorithm object identifier value
  553        * </code></pre>
  554        * <p>
  555        * Note that the byte array supplied here is cloned to protect against
  556        * subsequent modifications.
  557        *
  558        * @param key a byte array containing the subject public key in ASN.1 DER
  559        *            form (or <code>null</code>)
  560        * @throws IOException if an encoding error occurs (incorrect form for
  561        * subject public key)
  562        * @see #getSubjectPublicKey
  563        */
  564       public void setSubjectPublicKey(byte[] key) throws IOException {
  565           if (key == null) {
  566               subjectPublicKey = null;
  567               subjectPublicKeyBytes = null;
  568           } else {
  569               subjectPublicKeyBytes = key.clone();
  570               subjectPublicKey = X509Key.parse(new DerValue(subjectPublicKeyBytes));
  571           }
  572       }
  573   
  574       /**
  575        * Sets the keyUsage criterion. The <code>X509Certificate</code>
  576        * must allow the specified keyUsage values. If <code>null</code>, no
  577        * keyUsage check will be done. Note that an <code>X509Certificate</code>
  578        * that has no keyUsage extension implicitly allows all keyUsage values.
  579        * <p>
  580        * Note that the boolean array supplied here is cloned to protect against
  581        * subsequent modifications.
  582        *
  583        * @param keyUsage a boolean array in the same format as the boolean
  584        *                 array returned by
  585        * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}.
  586        *                 Or <code>null</code>.
  587        * @see #getKeyUsage
  588        */
  589       public void setKeyUsage(boolean[] keyUsage) {
  590           if (keyUsage == null) {
  591               this.keyUsage = null;
  592           } else {
  593               this.keyUsage = keyUsage.clone();
  594           }
  595       }
  596   
  597       /**
  598        * Sets the extendedKeyUsage criterion. The <code>X509Certificate</code>
  599        * must allow the specified key purposes in its extended key usage
  600        * extension. If <code>keyPurposeSet</code> is empty or <code>null</code>,
  601        * no extendedKeyUsage check will be done. Note that an
  602        * <code>X509Certificate</code> that has no extendedKeyUsage extension
  603        * implicitly allows all key purposes.
  604        * <p>
  605        * Note that the <code>Set</code> is cloned to protect against
  606        * subsequent modifications.
  607        *
  608        * @param keyPurposeSet a <code>Set</code> of key purpose OIDs in string
  609        * format (or <code>null</code>). Each OID is represented by a set of
  610        * nonnegative integers separated by periods.
  611        * @throws IOException if the OID is invalid, such as
  612        * the first component being not 0, 1 or 2 or the second component
  613        * being greater than 39.
  614        * @see #getExtendedKeyUsage
  615        */
  616       public void setExtendedKeyUsage(Set<String> keyPurposeSet) throws IOException {
  617           if ((keyPurposeSet == null) || keyPurposeSet.isEmpty()) {
  618               this.keyPurposeSet = null;
  619               keyPurposeOIDSet = null;
  620           } else {
  621               this.keyPurposeSet =
  622                   Collections.unmodifiableSet(new HashSet<String>(keyPurposeSet));
  623               keyPurposeOIDSet = new HashSet<ObjectIdentifier>();
  624               for (String s : this.keyPurposeSet) {
  625                   keyPurposeOIDSet.add(new ObjectIdentifier(s));
  626               }
  627           }
  628       }
  629   
  630       /**
  631        * Enables/disables matching all of the subjectAlternativeNames
  632        * specified in the {@link #setSubjectAlternativeNames
  633        * setSubjectAlternativeNames} or {@link #addSubjectAlternativeName
  634        * addSubjectAlternativeName} methods. If enabled,
  635        * the <code>X509Certificate</code> must contain all of the
  636        * specified subject alternative names. If disabled, the
  637        * <code>X509Certificate</code> must contain at least one of the
  638        * specified subject alternative names.
  639        *
  640        * <p>The matchAllNames flag is <code>true</code> by default.
  641        *
  642        * @param matchAllNames if <code>true</code>, the flag is enabled;
  643        * if <code>false</code>, the flag is disabled.
  644        * @see #getMatchAllSubjectAltNames
  645        */
  646       public void setMatchAllSubjectAltNames(boolean matchAllNames) {
  647           this.matchAllSubjectAltNames = matchAllNames;
  648       }
  649   
  650       /**
  651        * Sets the subjectAlternativeNames criterion. The
  652        * <code>X509Certificate</code> must contain all or at least one of the
  653        * specified subjectAlternativeNames, depending on the value of
  654        * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames
  655        * setMatchAllSubjectAltNames}).
  656        * <p>
  657        * This method allows the caller to specify, with a single method call,
  658        * the complete set of subject alternative names for the
  659        * subjectAlternativeNames criterion. The specified value replaces
  660        * the previous value for the subjectAlternativeNames criterion.
  661        * <p>
  662        * The <code>names</code> parameter (if not <code>null</code>) is a
  663        * <code>Collection</code> with one
  664        * entry for each name to be included in the subject alternative name
  665        * criterion. Each entry is a <code>List</code> whose first entry is an
  666        * <code>Integer</code> (the name type, 0-8) and whose second
  667        * entry is a <code>String</code> or a byte array (the name, in
  668        * string or ASN.1 DER encoded form, respectively).
  669        * There can be multiple names of the same type. If <code>null</code>
  670        * is supplied as the value for this argument, no
  671        * subjectAlternativeNames check will be performed.
  672        * <p>
  673        * Each subject alternative name in the <code>Collection</code>
  674        * may be specified either as a <code>String</code> or as an ASN.1 encoded
  675        * byte array. For more details about the formats used, see
  676        * {@link #addSubjectAlternativeName(int type, String name)
  677        * addSubjectAlternativeName(int type, String name)} and
  678        * {@link #addSubjectAlternativeName(int type, byte [] name)
  679        * addSubjectAlternativeName(int type, byte [] name)}.
  680        * <p>
  681        * <strong>Note:</strong> for distinguished names, specify the byte
  682        * array form instead of the String form. See the note in
  683        * {@link #addSubjectAlternativeName(int, String)} for more information.
  684        * <p>
  685        * Note that the <code>names</code> parameter can contain duplicate
  686        * names (same name and name type), but they may be removed from the
  687        * <code>Collection</code> of names returned by the
  688        * {@link #getSubjectAlternativeNames getSubjectAlternativeNames} method.
  689        * <p>
  690        * Note that a deep copy is performed on the <code>Collection</code> to
  691        * protect against subsequent modifications.
  692        *
  693        * @param names a <code>Collection</code> of names (or <code>null</code>)
  694        * @throws IOException if a parsing error occurs
  695        * @see #getSubjectAlternativeNames
  696        */
  697       public void setSubjectAlternativeNames(Collection<List<?>> names)
  698               throws IOException {
  699           if (names == null) {
  700               subjectAlternativeNames = null;
  701               subjectAlternativeGeneralNames = null;
  702           } else {
  703               if (names.isEmpty()) {
  704                   subjectAlternativeNames = null;
  705                   subjectAlternativeGeneralNames = null;
  706                   return;
  707               }
  708               Set<List<?>> tempNames = cloneAndCheckNames(names);
  709               // Ensure that we either set both of these or neither
  710               subjectAlternativeGeneralNames = parseNames(tempNames);
  711               subjectAlternativeNames = tempNames;
  712           }
  713       }
  714   
  715       /**
  716        * Adds a name to the subjectAlternativeNames criterion. The
  717        * <code>X509Certificate</code> must contain all or at least one
  718        * of the specified subjectAlternativeNames, depending on the value of
  719        * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames
  720        * setMatchAllSubjectAltNames}).
  721        * <p>
  722        * This method allows the caller to add a name to the set of subject
  723        * alternative names.
  724        * The specified name is added to any previous value for the
  725        * subjectAlternativeNames criterion. If the specified name is a
  726        * duplicate, it may be ignored.
  727        * <p>
  728        * The name is provided in string format.
  729        * <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
  730        * names use the well-established string formats for those types (subject to
  731        * the restrictions included in RFC 3280). IPv4 address names are
  732        * supplied using dotted quad notation. OID address names are represented
  733        * as a series of nonnegative integers separated by periods. And
  734        * directory names (distinguished names) are supplied in RFC 2253 format.
  735        * No standard string format is defined for otherNames, X.400 names,
  736        * EDI party names, IPv6 address names, or any other type of names. They
  737        * should be specified using the
  738        * {@link #addSubjectAlternativeName(int type, byte [] name)
  739        * addSubjectAlternativeName(int type, byte [] name)}
  740        * method.
  741        * <p>
  742        * <strong>Note:</strong> for distinguished names, use
  743        * {@linkplain #addSubjectAlternativeName(int, byte[])} instead.
  744        * This method should not be relied on as it can fail to match some
  745        * certificates because of a loss of encoding information in the RFC 2253
  746        * String form of some distinguished names.
  747        *
  748        * @param type the name type (0-8, as specified in
  749        *             RFC 3280, section 4.2.1.7)
  750        * @param name the name in string form (not <code>null</code>)
  751        * @throws IOException if a parsing error occurs
  752        */
  753       public void addSubjectAlternativeName(int type, String name)
  754               throws IOException {
  755           addSubjectAlternativeNameInternal(type, name);
  756       }
  757   
  758       /**
  759        * Adds a name to the subjectAlternativeNames criterion. The
  760        * <code>X509Certificate</code> must contain all or at least one
  761        * of the specified subjectAlternativeNames, depending on the value of
  762        * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames
  763        * setMatchAllSubjectAltNames}).
  764        * <p>
  765        * This method allows the caller to add a name to the set of subject
  766        * alternative names.
  767        * The specified name is added to any previous value for the
  768        * subjectAlternativeNames criterion. If the specified name is a
  769        * duplicate, it may be ignored.
  770        * <p>
  771        * The name is provided as a byte array. This byte array should contain
  772        * the DER encoded name, as it would appear in the GeneralName structure
  773        * defined in RFC 3280 and X.509. The encoded byte array should only contain
  774        * the encoded value of the name, and should not include the tag associated
  775        * with the name in the GeneralName structure. The ASN.1 definition of this
  776        * structure appears below.
  777        * <pre><code>
  778        *  GeneralName ::= CHOICE {
  779        *       otherName                       [0]     OtherName,
  780        *       rfc822Name                      [1]     IA5String,
  781        *       dNSName                         [2]     IA5String,
  782        *       x400Address                     [3]     ORAddress,
  783        *       directoryName                   [4]     Name,
  784        *       ediPartyName                    [5]     EDIPartyName,
  785        *       uniformResourceIdentifier       [6]     IA5String,
  786        *       iPAddress                       [7]     OCTET STRING,
  787        *       registeredID                    [8]     OBJECT IDENTIFIER}
  788        * </code></pre>
  789        * <p>
  790        * Note that the byte array supplied here is cloned to protect against
  791        * subsequent modifications.
  792        *
  793        * @param type the name type (0-8, as listed above)
  794        * @param name a byte array containing the name in ASN.1 DER encoded form
  795        * @throws IOException if a parsing error occurs
  796        */
  797       public void addSubjectAlternativeName(int type, byte[] name)
  798               throws IOException {
  799           // clone because byte arrays are modifiable
  800           addSubjectAlternativeNameInternal(type, name.clone());
  801       }
  802   
  803       /**
  804        * A private method that adds a name (String or byte array) to the
  805        * subjectAlternativeNames criterion. The <code>X509Certificate</code>
  806        * must contain the specified subjectAlternativeName.
  807        *
  808        * @param type the name type (0-8, as specified in
  809        *             RFC 3280, section 4.2.1.7)
  810        * @param name the name in string or byte array form
  811        * @throws IOException if a parsing error occurs
  812        */
  813       private void addSubjectAlternativeNameInternal(int type, Object name)
  814               throws IOException {
  815           // First, ensure that the name parses
  816           GeneralNameInterface tempName = makeGeneralNameInterface(type, name);
  817           if (subjectAlternativeNames == null) {
  818               subjectAlternativeNames = new HashSet<List<?>>();
  819           }
  820           if (subjectAlternativeGeneralNames == null) {
  821               subjectAlternativeGeneralNames = new HashSet<GeneralNameInterface>();
  822           }
  823           List<Object> list = new ArrayList<Object>(2);
  824           list.add(Integer.valueOf(type));
  825           list.add(name);
  826           subjectAlternativeNames.add(list);
  827           subjectAlternativeGeneralNames.add(tempName);
  828       }
  829   
  830       /**
  831        * Parse an argument of the form passed to setSubjectAlternativeNames,
  832        * returning a <code>Collection</code> of
  833        * <code>GeneralNameInterface</code>s.
  834        * Throw an IllegalArgumentException or a ClassCastException
  835        * if the argument is malformed.
  836        *
  837        * @param names a Collection with one entry per name.
  838        *              Each entry is a <code>List</code> whose first entry
  839        *              is an Integer (the name type, 0-8) and whose second
  840        *              entry is a String or a byte array (the name, in
  841        *              string or ASN.1 DER encoded form, respectively).
  842        *              There can be multiple names of the same type. Null is
  843        *              not an acceptable value.
  844        * @return a Set of <code>GeneralNameInterface</code>s
  845        * @throws IOException if a parsing error occurs
  846        */
  847       private static Set<GeneralNameInterface> parseNames(Collection<List<?>> names) throws IOException {
  848           Set<GeneralNameInterface> genNames = new HashSet<GeneralNameInterface>();
  849           for (List<?> nameList : names) {
  850               if (nameList.size() != 2) {
  851                   throw new IOException("name list size not 2");
  852               }
  853               Object o =  nameList.get(0);
  854               if (!(o instanceof Integer)) {
  855                   throw new IOException("expected an Integer");
  856               }
  857               int nameType = ((Integer)o).intValue();
  858               o = nameList.get(1);
  859               genNames.add(makeGeneralNameInterface(nameType, o));
  860           }
  861   
  862           return genNames;
  863       }
  864   
  865       /**
  866        * Compare for equality two objects of the form passed to
  867        * setSubjectAlternativeNames (or X509CRLSelector.setIssuerNames).
  868        * Throw an <code>IllegalArgumentException</code> or a
  869        * <code>ClassCastException</code> if one of the objects is malformed.
  870        *
  871        * @param object1 a Collection containing the first object to compare
  872        * @param object2 a Collection containing the second object to compare
  873        * @return true if the objects are equal, false otherwise
  874        */
  875       static boolean equalNames(Collection object1, Collection object2) {
  876           if ((object1 == null) || (object2 == null)) {
  877               return object1 == object2;
  878           }
  879           return object1.equals(object2);
  880       }
  881   
  882       /**
  883        * Make a <code>GeneralNameInterface</code> out of a name type (0-8) and an
  884        * Object that may be a byte array holding the ASN.1 DER encoded
  885        * name or a String form of the name.  Except for X.509
  886        * Distinguished Names, the String form of the name must not be the
  887        * result from calling toString on an existing GeneralNameInterface
  888        * implementing class.  The output of toString is not compatible
  889        * with the String constructors for names other than Distinguished
  890        * Names.
  891        *
  892        * @param type name type (0-8)
  893        * @param name name as ASN.1 Der-encoded byte array or String
  894        * @return a GeneralNameInterface name
  895        * @throws IOException if a parsing error occurs
  896        */
  897       static GeneralNameInterface makeGeneralNameInterface(int type, Object name)
  898               throws IOException {
  899           GeneralNameInterface result;
  900           if (debug != null) {
  901               debug.println("X509CertSelector.makeGeneralNameInterface("
  902                   + type + ")...");
  903           }
  904   
  905           if (name instanceof String) {
  906               if (debug != null) {
  907                   debug.println("X509CertSelector.makeGeneralNameInterface() "
  908                       + "name is String: " + name);
  909               }
  910               switch (type) {
  911               case NAME_RFC822:
  912                   result = new RFC822Name((String)name);
  913                   break;
  914               case NAME_DNS:
  915                   result = new DNSName((String)name);
  916                   break;
  917               case NAME_DIRECTORY:
  918                   result = new X500Name((String)name);
  919                   break;
  920               case NAME_URI:
  921                   result = new URIName((String)name);
  922                   break;
  923               case NAME_IP:
  924                   result = new IPAddressName((String)name);
  925                   break;
  926               case NAME_OID:
  927                   result = new OIDName((String)name);
  928                   break;
  929               default:
  930                   throw new IOException("unable to parse String names of type "
  931                                         + type);
  932               }
  933               if (debug != null) {
  934                   debug.println("X509CertSelector.makeGeneralNameInterface() "
  935                       + "result: " + result.toString());
  936               }
  937           } else if (name instanceof byte[]) {
  938               DerValue val = new DerValue((byte[]) name);
  939               if (debug != null) {
  940                   debug.println
  941                       ("X509CertSelector.makeGeneralNameInterface() is byte[]");
  942               }
  943   
  944               switch (type) {
  945               case NAME_ANY:
  946                   result = new OtherName(val);
  947                   break;
  948               case NAME_RFC822:
  949                   result = new RFC822Name(val);
  950                   break;
  951               case NAME_DNS:
  952                   result = new DNSName(val);
  953                   break;
  954               case NAME_X400:
  955                   result = new X400Address(val);
  956                   break;
  957               case NAME_DIRECTORY:
  958                   result = new X500Name(val);
  959                   break;
  960               case NAME_EDI:
  961                   result = new EDIPartyName(val);
  962                   break;
  963               case NAME_URI:
  964                   result = new URIName(val);
  965                   break;
  966               case NAME_IP:
  967                   result = new IPAddressName(val);
  968                   break;
  969               case NAME_OID:
  970                   result = new OIDName(val);
  971                   break;
  972               default:
  973                   throw new IOException("unable to parse byte array names of "
  974                       + "type " + type);
  975               }
  976               if (debug != null) {
  977                   debug.println("X509CertSelector.makeGeneralNameInterface() result: "
  978                       + result.toString());
  979               }
  980           } else {
  981               if (debug != null) {
  982                   debug.println("X509CertSelector.makeGeneralName() input name "
  983                       + "not String or byte array");
  984               }
  985               throw new IOException("name not String or byte array");
  986           }
  987           return result;
  988       }
  989   
  990   
  991       /**
  992        * Sets the name constraints criterion. The <code>X509Certificate</code>
  993        * must have subject and subject alternative names that
  994        * meet the specified name constraints.
  995        * <p>
  996        * The name constraints are specified as a byte array. This byte array
  997        * should contain the DER encoded form of the name constraints, as they
  998        * would appear in the NameConstraints structure defined in RFC 3280
  999        * and X.509. The ASN.1 definition of this structure appears below.
 1000        *
 1001        * <pre><code>
 1002        *  NameConstraints ::= SEQUENCE {
 1003        *       permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
 1004        *       excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
 1005        *
 1006        *  GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
 1007        *
 1008        *  GeneralSubtree ::= SEQUENCE {
 1009        *       base                    GeneralName,
 1010        *       minimum         [0]     BaseDistance DEFAULT 0,
 1011        *       maximum         [1]     BaseDistance OPTIONAL }
 1012        *
 1013        *  BaseDistance ::= INTEGER (0..MAX)
 1014        *
 1015        *  GeneralName ::= CHOICE {
 1016        *       otherName                       [0]     OtherName,
 1017        *       rfc822Name                      [1]     IA5String,
 1018        *       dNSName                         [2]     IA5String,
 1019        *       x400Address                     [3]     ORAddress,
 1020        *       directoryName                   [4]     Name,
 1021        *       ediPartyName                    [5]     EDIPartyName,
 1022        *       uniformResourceIdentifier       [6]     IA5String,
 1023        *       iPAddress                       [7]     OCTET STRING,
 1024        *       registeredID                    [8]     OBJECT IDENTIFIER}
 1025        * </code></pre>
 1026        * <p>
 1027        * Note that the byte array supplied here is cloned to protect against
 1028        * subsequent modifications.
 1029        *
 1030        * @param bytes a byte array containing the ASN.1 DER encoding of
 1031        *              a NameConstraints extension to be used for checking
 1032        *              name constraints. Only the value of the extension is
 1033        *              included, not the OID or criticality flag. Can be
 1034        *              <code>null</code>,
 1035        *              in which case no name constraints check will be performed.
 1036        * @throws IOException if a parsing error occurs
 1037        * @see #getNameConstraints
 1038        */
 1039       public void setNameConstraints(byte[] bytes) throws IOException {
 1040           if (bytes == null) {
 1041               ncBytes = null;
 1042               nc = null;
 1043           } else {
 1044               ncBytes = bytes.clone();
 1045               nc = new NameConstraintsExtension(FALSE, bytes);
 1046           }
 1047       }
 1048   
 1049       /**
 1050        * Sets the basic constraints constraint. If the value is greater than or
 1051        * equal to zero, <code>X509Certificates</code> must include a
 1052        * basicConstraints extension with
 1053        * a pathLen of at least this value. If the value is -2, only end-entity
 1054        * certificates are accepted. If the value is -1, no check is done.
 1055        * <p>
 1056        * This constraint is useful when building a certification path forward
 1057        * (from the target toward the trust anchor. If a partial path has been
 1058        * built, any candidate certificate must have a maxPathLen value greater
 1059        * than or equal to the number of certificates in the partial path.
 1060        *
 1061        * @param minMaxPathLen the value for the basic constraints constraint
 1062        * @throws IllegalArgumentException if the value is less than -2
 1063        * @see #getBasicConstraints
 1064        */
 1065       public void setBasicConstraints(int minMaxPathLen) {
 1066           if (minMaxPathLen < -2) {
 1067               throw new IllegalArgumentException("basic constraints less than -2");
 1068           }
 1069           basicConstraints = minMaxPathLen;
 1070       }
 1071   
 1072       /**
 1073        * Sets the policy constraint. The <code>X509Certificate</code> must
 1074        * include at least one of the specified policies in its certificate
 1075        * policies extension. If <code>certPolicySet</code> is empty, then the
 1076        * <code>X509Certificate</code> must include at least some specified policy
 1077        * in its certificate policies extension. If <code>certPolicySet</code> is
 1078        * <code>null</code>, no policy check will be performed.
 1079        * <p>
 1080        * Note that the <code>Set</code> is cloned to protect against
 1081        * subsequent modifications.
 1082        *
 1083        * @param certPolicySet a <code>Set</code> of certificate policy OIDs in
 1084        *                      string format (or <code>null</code>). Each OID is
 1085        *                      represented by a set of nonnegative integers
 1086        *                    separated by periods.
 1087        * @throws IOException if a parsing error occurs on the OID such as
 1088        * the first component is not 0, 1 or 2 or the second component is
 1089        * greater than 39.
 1090        * @see #getPolicy
 1091        */
 1092       public void setPolicy(Set<String> certPolicySet) throws IOException {
 1093           if (certPolicySet == null) {
 1094               policySet = null;
 1095               policy = null;
 1096           } else {
 1097               // Snapshot set and parse it
 1098               Set<String> tempSet = Collections.unmodifiableSet
 1099                                           (new HashSet<String>(certPolicySet));
 1100               /* Convert to Vector of ObjectIdentifiers */
 1101               Iterator<String> i = tempSet.iterator();
 1102               Vector<CertificatePolicyId> polIdVector = new Vector<CertificatePolicyId>();
 1103               while (i.hasNext()) {
 1104                   Object o = i.next();
 1105                   if (!(o instanceof String)) {
 1106                       throw new IOException("non String in certPolicySet");
 1107                   }
 1108                   polIdVector.add(new CertificatePolicyId(new ObjectIdentifier(
 1109                     (String)o)));
 1110               }
 1111               // If everything went OK, make the changes
 1112               policySet = tempSet;
 1113               policy = new CertificatePolicySet(polIdVector);
 1114           }
 1115       }
 1116   
 1117       /**
 1118        * Sets the pathToNames criterion. The <code>X509Certificate</code> must
 1119        * not include name constraints that would prohibit building a
 1120        * path to the specified names.
 1121        * <p>
 1122        * This method allows the caller to specify, with a single method call,
 1123        * the complete set of names which the <code>X509Certificates</code>'s
 1124        * name constraints must permit. The specified value replaces
 1125        * the previous value for the pathToNames criterion.
 1126        * <p>
 1127        * This constraint is useful when building a certification path forward
 1128        * (from the target toward the trust anchor. If a partial path has been
 1129        * built, any candidate certificate must not include name constraints that
 1130        * would prohibit building a path to any of the names in the partial path.
 1131        * <p>
 1132        * The <code>names</code> parameter (if not <code>null</code>) is a
 1133        * <code>Collection</code> with one
 1134        * entry for each name to be included in the pathToNames
 1135        * criterion. Each entry is a <code>List</code> whose first entry is an
 1136        * <code>Integer</code> (the name type, 0-8) and whose second
 1137        * entry is a <code>String</code> or a byte array (the name, in
 1138        * string or ASN.1 DER encoded form, respectively).
 1139        * There can be multiple names of the same type. If <code>null</code>
 1140        * is supplied as the value for this argument, no
 1141        * pathToNames check will be performed.
 1142        * <p>
 1143        * Each name in the <code>Collection</code>
 1144        * may be specified either as a <code>String</code> or as an ASN.1 encoded
 1145        * byte array. For more details about the formats used, see
 1146        * {@link #addPathToName(int type, String name)
 1147        * addPathToName(int type, String name)} and
 1148        * {@link #addPathToName(int type, byte [] name)
 1149        * addPathToName(int type, byte [] name)}.
 1150        * <p>
 1151        * <strong>Note:</strong> for distinguished names, specify the byte
 1152        * array form instead of the String form. See the note in
 1153        * {@link #addPathToName(int, String)} for more information.
 1154        * <p>
 1155        * Note that the <code>names</code> parameter can contain duplicate
 1156        * names (same name and name type), but they may be removed from the
 1157        * <code>Collection</code> of names returned by the
 1158        * {@link #getPathToNames getPathToNames} method.
 1159        * <p>
 1160        * Note that a deep copy is performed on the <code>Collection</code> to
 1161        * protect against subsequent modifications.
 1162        *
 1163        * @param names a <code>Collection</code> with one entry per name
 1164        *              (or <code>null</code>)
 1165        * @throws IOException if a parsing error occurs
 1166        * @see #getPathToNames
 1167        */
 1168       public void setPathToNames(Collection<List<?>> names) throws IOException {
 1169           if ((names == null) || names.isEmpty()) {
 1170               pathToNames = null;
 1171               pathToGeneralNames = null;
 1172           } else {
 1173               Set<List<?>> tempNames = cloneAndCheckNames(names);
 1174               pathToGeneralNames = parseNames(tempNames);
 1175               // Ensure that we either set both of these or neither
 1176               pathToNames = tempNames;
 1177           }
 1178       }
 1179   
 1180       // called from CertPathHelper
 1181       void setPathToNamesInternal(Set<GeneralNameInterface> names) {
 1182           // set names to non-null dummy value
 1183           // this breaks getPathToNames()
 1184           pathToNames = Collections.<List<?>>emptySet();
 1185           pathToGeneralNames = names;
 1186       }
 1187   
 1188       /**
 1189        * Adds a name to the pathToNames criterion. The <code>X509Certificate</code>
 1190        * must not include name constraints that would prohibit building a
 1191        * path to the specified name.
 1192        * <p>
 1193        * This method allows the caller to add a name to the set of names which
 1194        * the <code>X509Certificates</code>'s name constraints must permit.
 1195        * The specified name is added to any previous value for the
 1196        * pathToNames criterion.  If the name is a duplicate, it may be ignored.
 1197        * <p>
 1198        * The name is provided in string format. RFC 822, DNS, and URI names
 1199        * use the well-established string formats for those types (subject to
 1200        * the restrictions included in RFC 3280). IPv4 address names are
 1201        * supplied using dotted quad notation. OID address names are represented
 1202        * as a series of nonnegative integers separated by periods. And
 1203        * directory names (distinguished names) are supplied in RFC 2253 format.
 1204        * No standard string format is defined for otherNames, X.400 names,
 1205        * EDI party names, IPv6 address names, or any other type of names. They
 1206        * should be specified using the
 1207        * {@link #addPathToName(int type, byte [] name)
 1208        * addPathToName(int type, byte [] name)} method.
 1209        * <p>
 1210        * <strong>Note:</strong> for distinguished names, use
 1211        * {@linkplain #addPathToName(int, byte[])} instead.
 1212        * This method should not be relied on as it can fail to match some
 1213        * certificates because of a loss of encoding information in the RFC 2253
 1214        * String form of some distinguished names.
 1215        *
 1216        * @param type the name type (0-8, as specified in
 1217        *             RFC 3280, section 4.2.1.7)
 1218        * @param name the name in string form
 1219        * @throws IOException if a parsing error occurs
 1220        */
 1221       public void addPathToName(int type, String name) throws IOException {
 1222           addPathToNameInternal(type, name);
 1223       }
 1224   
 1225       /**
 1226        * Adds a name to the pathToNames criterion. The <code>X509Certificate</code>
 1227        * must not include name constraints that would prohibit building a
 1228        * path to the specified name.
 1229        * <p>
 1230        * This method allows the caller to add a name to the set of names which
 1231        * the <code>X509Certificates</code>'s name constraints must permit.
 1232        * The specified name is added to any previous value for the
 1233        * pathToNames criterion. If the name is a duplicate, it may be ignored.
 1234        * <p>
 1235        * The name is provided as a byte array. This byte array should contain
 1236        * the DER encoded name, as it would appear in the GeneralName structure
 1237        * defined in RFC 3280 and X.509. The ASN.1 definition of this structure
 1238        * appears in the documentation for
 1239        * {@link #addSubjectAlternativeName(int type, byte [] name)
 1240        * addSubjectAlternativeName(int type, byte [] name)}.
 1241        * <p>
 1242        * Note that the byte array supplied here is cloned to protect against
 1243        * subsequent modifications.
 1244        *
 1245        * @param type the name type (0-8, as specified in
 1246        *             RFC 3280, section 4.2.1.7)
 1247        * @param name a byte array containing the name in ASN.1 DER encoded form
 1248        * @throws IOException if a parsing error occurs
 1249        */
 1250       public void addPathToName(int type, byte [] name) throws IOException {
 1251           // clone because byte arrays are modifiable
 1252           addPathToNameInternal(type, name.clone());
 1253       }
 1254   
 1255       /**
 1256        * A private method that adds a name (String or byte array) to the
 1257        * pathToNames criterion. The <code>X509Certificate</code> must contain
 1258        * the specified pathToName.
 1259        *
 1260        * @param type the name type (0-8, as specified in
 1261        *             RFC 3280, section 4.2.1.7)
 1262        * @param name the name in string or byte array form
 1263        * @throws IOException if an encoding error occurs (incorrect form for DN)
 1264        */
 1265       private void addPathToNameInternal(int type, Object name)
 1266               throws IOException {
 1267           // First, ensure that the name parses
 1268           GeneralNameInterface tempName = makeGeneralNameInterface(type, name);
 1269           if (pathToGeneralNames == null) {
 1270               pathToNames = new HashSet<List<?>>();
 1271               pathToGeneralNames = new HashSet<GeneralNameInterface>();
 1272           }
 1273           List<Object> list = new ArrayList<Object>(2);
 1274           list.add(Integer.valueOf(type));
 1275           list.add(name);
 1276           pathToNames.add(list);
 1277           pathToGeneralNames.add(tempName);
 1278       }
 1279   
 1280       /**
 1281        * Returns the certificateEquals criterion. The specified
 1282        * <code>X509Certificate</code> must be equal to the
 1283        * <code>X509Certificate</code> passed to the <code>match</code> method.
 1284        * If <code>null</code>, this check is not applied.
 1285        *
 1286        * @return the <code>X509Certificate</code> to match (or <code>null</code>)
 1287        * @see #setCertificate
 1288        */
 1289       public X509Certificate getCertificate() {
 1290           return x509Cert;
 1291       }
 1292   
 1293       /**
 1294        * Returns the serialNumber criterion. The specified serial number
 1295        * must match the certificate serial number in the
 1296        * <code>X509Certificate</code>. If <code>null</code>, any certificate
 1297        * serial number will do.
 1298        *
 1299        * @return the certificate serial number to match
 1300        *                (or <code>null</code>)
 1301        * @see #setSerialNumber
 1302        */
 1303       public BigInteger getSerialNumber() {
 1304           return serialNumber;
 1305       }
 1306   
 1307       /**
 1308        * Returns the issuer criterion as an <code>X500Principal</code>. This
 1309        * distinguished name must match the issuer distinguished name in the
 1310        * <code>X509Certificate</code>. If <code>null</code>, the issuer criterion
 1311        * is disabled and any issuer distinguished name will do.
 1312        *
 1313        * @return the required issuer distinguished name as X500Principal
 1314        *         (or <code>null</code>)
 1315        * @since 1.5
 1316        */
 1317       public X500Principal getIssuer() {
 1318           return issuer;
 1319       }
 1320   
 1321       /**
 1322        * <strong>Denigrated</strong>, use {@linkplain #getIssuer()} or
 1323        * {@linkplain #getIssuerAsBytes()} instead. This method should not be
 1324        * relied on as it can fail to match some certificates because of a loss of
 1325        * encoding information in the RFC 2253 String form of some distinguished
 1326        * names.
 1327        * <p>
 1328        * Returns the issuer criterion as a <code>String</code>. This
 1329        * distinguished name must match the issuer distinguished name in the
 1330        * <code>X509Certificate</code>. If <code>null</code>, the issuer criterion
 1331        * is disabled and any issuer distinguished name will do.
 1332        * <p>
 1333        * If the value returned is not <code>null</code>, it is a
 1334        * distinguished name, in RFC 2253 format.
 1335        *
 1336        * @return the required issuer distinguished name in RFC 2253 format
 1337        *         (or <code>null</code>)
 1338        */
 1339       public String getIssuerAsString() {
 1340           return (issuer == null ? null : issuer.getName());
 1341       }
 1342   
 1343       /**
 1344        * Returns the issuer criterion as a byte array. This distinguished name
 1345        * must match the issuer distinguished name in the
 1346        * <code>X509Certificate</code>. If <code>null</code>, the issuer criterion
 1347        * is disabled and any issuer distinguished name will do.
 1348        * <p>
 1349        * If the value returned is not <code>null</code>, it is a byte
 1350        * array containing a single DER encoded distinguished name, as defined in
 1351        * X.501. The ASN.1 notation for this structure is supplied in the
 1352        * documentation for
 1353        * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.
 1354        * <p>
 1355        * Note that the byte array returned is cloned to protect against
 1356        * subsequent modifications.
 1357        *
 1358        * @return a byte array containing the required issuer distinguished name
 1359        *         in ASN.1 DER format (or <code>null</code>)
 1360        * @throws IOException if an encoding error occurs
 1361        */
 1362       public byte[] getIssuerAsBytes() throws IOException {
 1363           return (issuer == null ? null: issuer.getEncoded());
 1364       }
 1365   
 1366       /**
 1367        * Returns the subject criterion as an <code>X500Principal</code>. This
 1368        * distinguished name must match the subject distinguished name in the
 1369        * <code>X509Certificate</code>. If <code>null</code>, the subject criterion
 1370        * is disabled and any subject distinguished name will do.
 1371        *
 1372        * @return the required subject distinguished name as X500Principal
 1373        *         (or <code>null</code>)
 1374        * @since 1.5
 1375        */
 1376       public X500Principal getSubject() {
 1377           return subject;
 1378       }
 1379   
 1380       /**
 1381        * <strong>Denigrated</strong>, use {@linkplain #getSubject()} or
 1382        * {@linkplain #getSubjectAsBytes()} instead. This method should not be
 1383        * relied on as it can fail to match some certificates because of a loss of
 1384        * encoding information in the RFC 2253 String form of some distinguished
 1385        * names.
 1386        * <p>
 1387        * Returns the subject criterion as a <code>String</code>. This
 1388        * distinguished name must match the subject distinguished name in the
 1389        * <code>X509Certificate</code>. If <code>null</code>, the subject criterion
 1390        * is disabled and any subject distinguished name will do.
 1391        * <p>
 1392        * If the value returned is not <code>null</code>, it is a
 1393        * distinguished name, in RFC 2253 format.
 1394        *
 1395        * @return the required subject distinguished name in RFC 2253 format
 1396        *         (or <code>null</code>)
 1397        */
 1398       public String getSubjectAsString() {
 1399           return (subject == null ? null : subject.getName());
 1400       }
 1401   
 1402       /**
 1403        * Returns the subject criterion as a byte array. This distinguished name
 1404        * must match the subject distinguished name in the
 1405        * <code>X509Certificate</code>. If <code>null</code>, the subject criterion
 1406        * is disabled and any subject distinguished name will do.
 1407        * <p>
 1408        * If the value returned is not <code>null</code>, it is a byte
 1409        * array containing a single DER encoded distinguished name, as defined in
 1410        * X.501. The ASN.1 notation for this structure is supplied in the
 1411        * documentation for
 1412        * {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.
 1413        * <p>
 1414        * Note that the byte array returned is cloned to protect against
 1415        * subsequent modifications.
 1416        *
 1417        * @return a byte array containing the required subject distinguished name
 1418        *         in ASN.1 DER format (or <code>null</code>)
 1419        * @throws IOException if an encoding error occurs
 1420        */
 1421       public byte[] getSubjectAsBytes() throws IOException {
 1422           return (subject == null ? null : subject.getEncoded());
 1423       }
 1424   
 1425       /**
 1426        * Returns the subjectKeyIdentifier criterion. The
 1427        * <code>X509Certificate</code> must contain a SubjectKeyIdentifier
 1428        * extension with the specified value. If <code>null</code>, no
 1429        * subjectKeyIdentifier check will be done.
 1430        * <p>
 1431        * Note that the byte array returned is cloned to protect against
 1432        * subsequent modifications.
 1433        *
 1434        * @return the key identifier (or <code>null</code>)
 1435        * @see #setSubjectKeyIdentifier
 1436        */
 1437       public byte[] getSubjectKeyIdentifier() {
 1438           if (subjectKeyID == null) {
 1439               return null;
 1440           }
 1441           return subjectKeyID.clone();
 1442       }
 1443   
 1444       /**
 1445        * Returns the authorityKeyIdentifier criterion. The
 1446        * <code>X509Certificate</code> must contain a AuthorityKeyIdentifier
 1447        * extension with the specified value. If <code>null</code>, no
 1448        * authorityKeyIdentifier check will be done.
 1449        * <p>
 1450        * Note that the byte array returned is cloned to protect against
 1451        * subsequent modifications.
 1452        *
 1453        * @return the key identifier (or <code>null</code>)
 1454        * @see #setAuthorityKeyIdentifier
 1455        */
 1456       public byte[] getAuthorityKeyIdentifier() {
 1457           if (authorityKeyID == null) {
 1458             return null;
 1459           }
 1460           return authorityKeyID.clone();
 1461       }
 1462   
 1463       /**
 1464        * Returns the certificateValid criterion. The specified date must fall
 1465        * within the certificate validity period for the
 1466        * <code>X509Certificate</code>. If <code>null</code>, no certificateValid
 1467        * check will be done.
 1468        * <p>
 1469        * Note that the <code>Date</code> returned is cloned to protect against
 1470        * subsequent modifications.
 1471        *
 1472        * @return the <code>Date</code> to check (or <code>null</code>)
 1473        * @see #setCertificateValid
 1474        */
 1475       public Date getCertificateValid() {
 1476           if (certificateValid == null) {
 1477               return null;
 1478           }
 1479           return (Date)certificateValid.clone();
 1480       }
 1481   
 1482       /**
 1483        * Returns the privateKeyValid criterion. The specified date must fall
 1484        * within the private key validity period for the
 1485        * <code>X509Certificate</code>. If <code>null</code>, no privateKeyValid
 1486        * check will be done.
 1487        * <p>
 1488        * Note that the <code>Date</code> returned is cloned to protect against
 1489        * subsequent modifications.
 1490        *
 1491        * @return the <code>Date</code> to check (or <code>null</code>)
 1492        * @see #setPrivateKeyValid
 1493        */
 1494       public Date getPrivateKeyValid() {
 1495           if (privateKeyValid == null) {
 1496               return null;
 1497           }
 1498           return (Date)privateKeyValid.clone();
 1499       }
 1500   
 1501       /**
 1502        * Returns the subjectPublicKeyAlgID criterion. The
 1503        * <code>X509Certificate</code> must contain a subject public key
 1504        * with the specified algorithm. If <code>null</code>, no
 1505        * subjectPublicKeyAlgID check will be done.
 1506        *
 1507        * @return the object identifier (OID) of the signature algorithm to check
 1508        *         for (or <code>null</code>). An OID is represented by a set of
 1509        *         nonnegative integers separated by periods.
 1510        * @see #setSubjectPublicKeyAlgID
 1511        */
 1512       public String getSubjectPublicKeyAlgID() {
 1513           if (subjectPublicKeyAlgID == null) {
 1514               return null;
 1515           }
 1516           return subjectPublicKeyAlgID.toString();
 1517       }
 1518   
 1519       /**
 1520        * Returns the subjectPublicKey criterion. The
 1521        * <code>X509Certificate</code> must contain the specified subject
 1522        * public key. If <code>null</code>, no subjectPublicKey check will be done.
 1523        *
 1524        * @return the subject public key to check for (or <code>null</code>)
 1525        * @see #setSubjectPublicKey
 1526        */
 1527       public PublicKey getSubjectPublicKey() {
 1528           return subjectPublicKey;
 1529       }
 1530   
 1531       /**
 1532        * Returns the keyUsage criterion. The <code>X509Certificate</code>
 1533        * must allow the specified keyUsage values. If null, no keyUsage
 1534        * check will be done.
 1535        * <p>
 1536        * Note that the boolean array returned is cloned to protect against
 1537        * subsequent modifications.
 1538        *
 1539        * @return a boolean array in the same format as the boolean
 1540        *                 array returned by
 1541        * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}.
 1542        *                 Or <code>null</code>.
 1543        * @see #setKeyUsage
 1544        */
 1545       public boolean[] getKeyUsage() {
 1546           if (keyUsage == null) {
 1547               return null;
 1548           }
 1549           return keyUsage.clone();
 1550       }
 1551   
 1552       /**
 1553        * Returns the extendedKeyUsage criterion. The <code>X509Certificate</code>
 1554        * must allow the specified key purposes in its extended key usage
 1555        * extension. If the <code>keyPurposeSet</code> returned is empty or
 1556        * <code>null</code>, no extendedKeyUsage check will be done. Note that an
 1557        * <code>X509Certificate</code> that has no extendedKeyUsage extension
 1558        * implicitly allows all key purposes.
 1559        *
 1560        * @return an immutable <code>Set</code> of key purpose OIDs in string
 1561        * format (or <code>null</code>)
 1562        * @see #setExtendedKeyUsage
 1563        */
 1564       public Set<String> getExtendedKeyUsage() {
 1565           return keyPurposeSet;
 1566       }
 1567   
 1568       /**
 1569        * Indicates if the <code>X509Certificate</code> must contain all
 1570        * or at least one of the subjectAlternativeNames
 1571        * specified in the {@link #setSubjectAlternativeNames
 1572        * setSubjectAlternativeNames} or {@link #addSubjectAlternativeName
 1573        * addSubjectAlternativeName} methods. If <code>true</code>,
 1574        * the <code>X509Certificate</code> must contain all of the
 1575        * specified subject alternative names. If <code>false</code>, the
 1576        * <code>X509Certificate</code> must contain at least one of the
 1577        * specified subject alternative names.
 1578        *
 1579        * @return <code>true</code> if the flag is enabled;
 1580        * <code>false</code> if the flag is disabled. The flag is
 1581        * <code>true</code> by default.
 1582        * @see #setMatchAllSubjectAltNames
 1583        */
 1584       public boolean getMatchAllSubjectAltNames() {
 1585           return matchAllSubjectAltNames;
 1586       }
 1587   
 1588       /**
 1589        * Returns a copy of the subjectAlternativeNames criterion.
 1590        * The <code>X509Certificate</code> must contain all or at least one
 1591        * of the specified subjectAlternativeNames, depending on the value
 1592        * of the matchAllNames flag (see {@link #getMatchAllSubjectAltNames
 1593        * getMatchAllSubjectAltNames}). If the value returned is
 1594        * <code>null</code>, no subjectAlternativeNames check will be performed.
 1595        * <p>
 1596        * If the value returned is not <code>null</code>, it is a
 1597        * <code>Collection</code> with
 1598        * one entry for each name to be included in the subject alternative name
 1599        * criterion. Each entry is a <code>List</code> whose first entry is an
 1600        * <code>Integer</code> (the name type, 0-8) and whose second
 1601        * entry is a <code>String</code> or a byte array (the name, in
 1602        * string or ASN.1 DER encoded form, respectively).
 1603        * There can be multiple names of the same type.  Note that the
 1604        * <code>Collection</code> returned may contain duplicate names (same name
 1605        * and name type).
 1606        * <p>
 1607        * Each subject alternative name in the <code>Collection</code>
 1608        * may be specified either as a <code>String</code> or as an ASN.1 encoded
 1609        * byte array. For more details about the formats used, see
 1610        * {@link #addSubjectAlternativeName(int type, String name)
 1611        * addSubjectAlternativeName(int type, String name)} and
 1612        * {@link #addSubjectAlternativeName(int type, byte [] name)
 1613        * addSubjectAlternativeName(int type, byte [] name)}.
 1614        * <p>
 1615        * Note that a deep copy is performed on the <code>Collection</code> to
 1616        * protect against subsequent modifications.
 1617        *
 1618        * @return a <code>Collection</code> of names (or <code>null</code>)
 1619        * @see #setSubjectAlternativeNames
 1620        */
 1621       public Collection<List<?>> getSubjectAlternativeNames() {
 1622           if (subjectAlternativeNames == null) {
 1623               return null;
 1624           }
 1625           return cloneNames(subjectAlternativeNames);
 1626       }
 1627   
 1628       /**
 1629        * Clone an object of the form passed to
 1630        * setSubjectAlternativeNames and setPathToNames.
 1631        * Throw a <code>RuntimeException</code> if the argument is malformed.
 1632        * <p>
 1633        * This method wraps cloneAndCheckNames, changing any
 1634        * <code>IOException</code> into a <code>RuntimeException</code>. This
 1635        * method should be used when the object being
 1636        * cloned has already been checked, so there should never be any exceptions.
 1637        *
 1638        * @param names a <code>Collection</code> with one entry per name.
 1639        *              Each entry is a <code>List</code> whose first entry
 1640        *              is an Integer (the name type, 0-8) and whose second
 1641        *              entry is a String or a byte array (the name, in
 1642        *              string or ASN.1 DER encoded form, respectively).
 1643        *              There can be multiple names of the same type. Null
 1644        *              is not an acceptable value.
 1645        * @return a deep copy of the specified <code>Collection</code>
 1646        * @throws RuntimeException if a parsing error occurs
 1647        */
 1648       private static Set<List<?>> cloneNames(Collection<List<?>> names) {
 1649           try {
 1650               return cloneAndCheckNames(names);
 1651           } catch (IOException e) {
 1652               throw new RuntimeException("cloneNames encountered IOException: " +
 1653                                          e.getMessage());
 1654           }
 1655       }
 1656   
 1657       /**
 1658        * Clone and check an argument of the form passed to
 1659        * setSubjectAlternativeNames and setPathToNames.
 1660        * Throw an <code>IOException</code> if the argument is malformed.
 1661        *
 1662        * @param names a <code>Collection</code> with one entry per name.
 1663        *              Each entry is a <code>List</code> whose first entry
 1664        *              is an Integer (the name type, 0-8) and whose second
 1665        *              entry is a String or a byte array (the name, in
 1666        *              string or ASN.1 DER encoded form, respectively).
 1667        *              There can be multiple names of the same type.
 1668        *              <code>null</code> is not an acceptable value.
 1669        * @return a deep copy of the specified <code>Collection</code>
 1670        * @throws IOException if a parsing error occurs
 1671        */
 1672       private static Set<List<?>> cloneAndCheckNames(Collection<List<?>> names) throws IOException {
 1673           // Copy the Lists and Collection
 1674           Set<List<?>> namesCopy = new HashSet<List<?>>();
 1675           Iterator<List<?>> i = names.iterator();
 1676           while (i.hasNext()) {
 1677               Object o = i.next();
 1678               if (!(o instanceof List)) {
 1679                   throw new IOException("expected a List");
 1680               }
 1681               namesCopy.add(new ArrayList<Object>((List<?>)o));
 1682           }
 1683   
 1684           // Check the contents of the Lists and clone any byte arrays
 1685           i = namesCopy.iterator();
 1686           while (i.hasNext()) {
 1687               List<Object> nameList = (List<Object>)i.next();
 1688               if (nameList.size() != 2) {
 1689                   throw new IOException("name list size not 2");
 1690               }
 1691               Object o = nameList.get(0);
 1692               if (!(o instanceof Integer)) {
 1693                   throw new IOException("expected an Integer");
 1694               }
 1695               int nameType = ((Integer)o).intValue();
 1696               if ((nameType < 0) || (nameType > 8)) {
 1697                   throw new IOException("name type not 0-8");
 1698               }
 1699               Object nameObject = nameList.get(1);
 1700               if (!(nameObject instanceof byte[]) &&
 1701                   !(nameObject instanceof String)) {
 1702                   if (debug != null) {
 1703                       debug.println("X509CertSelector.cloneAndCheckNames() "
 1704                           + "name not byte array");
 1705                   }
 1706                   throw new IOException("name not byte array or String");
 1707               }
 1708               if (nameObject instanceof byte[]) {
 1709                   nameList.set(1, ((byte[]) nameObject).clone());
 1710               }
 1711           }
 1712           return namesCopy;
 1713       }
 1714   
 1715       /**
 1716        * Returns the name constraints criterion. The <code>X509Certificate</code>
 1717        * must have subject and subject alternative names that
 1718        * meet the specified name constraints.
 1719        * <p>
 1720        * The name constraints are returned as a byte array. This byte array
 1721        * contains the DER encoded form of the name constraints, as they
 1722        * would appear in the NameConstraints structure defined in RFC 3280
 1723        * and X.509. The ASN.1 notation for this structure is supplied in the
 1724        * documentation for
 1725        * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
 1726        * <p>
 1727        * Note that the byte array returned is cloned to protect against
 1728        * subsequent modifications.
 1729        *
 1730        * @return a byte array containing the ASN.1 DER encoding of
 1731        *         a NameConstraints extension used for checking name constraints.
 1732        *         <code>null</code> if no name constraints check will be performed.
 1733        * @see #setNameConstraints
 1734        */
 1735       public byte[] getNameConstraints() {
 1736           if (ncBytes == null) {
 1737               return null;
 1738           } else {
 1739               return ncBytes.clone();
 1740           }
 1741       }
 1742   
 1743       /**
 1744        * Returns the basic constraints constraint. If the value is greater than
 1745        * or equal to zero, the <code>X509Certificates</code> must include a
 1746        * basicConstraints extension with a pathLen of at least this value.
 1747        * If the value is -2, only end-entity certificates are accepted. If
 1748        * the value is -1, no basicConstraints check is done.
 1749        *
 1750        * @return the value for the basic constraints constraint
 1751        * @see #setBasicConstraints
 1752        */
 1753       public int getBasicConstraints() {
 1754           return basicConstraints;
 1755       }
 1756   
 1757       /**
 1758        * Returns the policy criterion. The <code>X509Certificate</code> must
 1759        * include at least one of the specified policies in its certificate policies
 1760        * extension. If the <code>Set</code> returned is empty, then the
 1761        * <code>X509Certificate</code> must include at least some specified policy
 1762        * in its certificate policies extension. If the <code>Set</code> returned is
 1763        * <code>null</code>, no policy check will be performed.
 1764        *
 1765        * @return an immutable <code>Set</code> of certificate policy OIDs in
 1766        *         string format (or <code>null</code>)
 1767        * @see #setPolicy
 1768        */
 1769       public Set<String> getPolicy() {
 1770           return policySet;
 1771       }
 1772   
 1773       /**
 1774        * Returns a copy of the pathToNames criterion. The
 1775        * <code>X509Certificate</code> must not include name constraints that would
 1776        * prohibit building a path to the specified names. If the value
 1777        * returned is <code>null</code>, no pathToNames check will be performed.
 1778        * <p>
 1779        * If the value returned is not <code>null</code>, it is a
 1780        * <code>Collection</code> with one
 1781        * entry for each name to be included in the pathToNames
 1782        * criterion. Each entry is a <code>List</code> whose first entry is an
 1783        * <code>Integer</code> (the name type, 0-8) and whose second
 1784        * entry is a <code>String</code> or a byte array (the name, in
 1785        * string or ASN.1 DER encoded form, respectively).
 1786        * There can be multiple names of the same type. Note that the
 1787        * <code>Collection</code> returned may contain duplicate names (same
 1788        * name and name type).
 1789        * <p>
 1790        * Each name in the <code>Collection</code>
 1791        * may be specified either as a <code>String</code> or as an ASN.1 encoded
 1792        * byte array. For more details about the formats used, see
 1793        * {@link #addPathToName(int type, String name)
 1794        * addPathToName(int type, String name)} and
 1795        * {@link #addPathToName(int type, byte [] name)
 1796        * addPathToName(int type, byte [] name)}.
 1797        * <p>
 1798        * Note that a deep copy is performed on the <code>Collection</code> to
 1799        * protect against subsequent modifications.
 1800        *
 1801        * @return a <code>Collection</code> of names (or <code>null</code>)
 1802        * @see #setPathToNames
 1803        */
 1804       public Collection<List<?>> getPathToNames() {
 1805           if (pathToNames == null) {
 1806               return null;
 1807           }
 1808           return cloneNames(pathToNames);
 1809       }
 1810   
 1811       /**
 1812        * Return a printable representation of the <code>CertSelector</code>.
 1813        *
 1814        * @return a <code>String</code> describing the contents of the
 1815        *         <code>CertSelector</code>
 1816        */
 1817       public String toString() {
 1818           StringBuffer sb = new StringBuffer();
 1819           sb.append("X509CertSelector: [\n");
 1820           if (x509Cert != null) {
 1821               sb.append("  Certificate: " + x509Cert.toString() + "\n");
 1822           }
 1823           if (serialNumber != null) {
 1824               sb.append("  Serial Number: " + serialNumber.toString() + "\n");
 1825           }
 1826           if (issuer != null) {
 1827               sb.append("  Issuer: " + getIssuerAsString() + "\n");
 1828           }
 1829           if (subject != null) {
 1830               sb.append("  Subject: " + getSubjectAsString() + "\n");
 1831           }
 1832           sb.append("  matchAllSubjectAltNames flag: "
 1833                     + String.valueOf(matchAllSubjectAltNames) + "\n");
 1834           if (subjectAlternativeNames != null) {
 1835               sb.append("  SubjectAlternativeNames:\n");
 1836               Iterator<List<?>> i = subjectAlternativeNames.iterator();
 1837               while (i.hasNext()) {
 1838                   List<?> list = i.next();
 1839                   sb.append("    type " + list.get(0) +
 1840                             ", name " + list.get(1) + "\n");
 1841               }
 1842           }
 1843           if (subjectKeyID != null) {
 1844               HexDumpEncoder enc = new HexDumpEncoder();
 1845               sb.append("  Subject Key Identifier: " +
 1846                         enc.encodeBuffer(subjectKeyID) + "\n");
 1847           }
 1848           if (authorityKeyID != null) {
 1849               HexDumpEncoder enc = new HexDumpEncoder();
 1850               sb.append("  Authority Key Identifier: " +
 1851                         enc.encodeBuffer(authorityKeyID) + "\n");
 1852           }
 1853           if (certificateValid != null) {
 1854               sb.append("  Certificate Valid: " +
 1855                         certificateValid.toString() + "\n");
 1856           }
 1857           if (privateKeyValid != null) {
 1858               sb.append("  Private Key Valid: " +
 1859                         privateKeyValid.toString() + "\n");
 1860           }
 1861           if (subjectPublicKeyAlgID != null) {
 1862               sb.append("  Subject Public Key AlgID: " +
 1863                         subjectPublicKeyAlgID.toString() + "\n");
 1864           }
 1865           if (subjectPublicKey != null) {
 1866               sb.append("  Subject Public Key: " +
 1867                         subjectPublicKey.toString() + "\n");
 1868           }
 1869           if (keyUsage != null) {
 1870               sb.append("  Key Usage: " + keyUsageToString(keyUsage) + "\n");
 1871           }
 1872           if (keyPurposeSet != null) {
 1873               sb.append("  Extended Key Usage: " +
 1874                         keyPurposeSet.toString() + "\n");
 1875           }
 1876           if (policy != null) {
 1877               sb.append("  Policy: " + policy.toString() + "\n");
 1878           }
 1879           if (pathToGeneralNames != null) {
 1880               sb.append("  Path to names:\n");
 1881               Iterator<GeneralNameInterface> i = pathToGeneralNames.iterator();
 1882               while (i.hasNext()) {
 1883                   sb.append("    " + i.next() + "\n");
 1884               }
 1885           }
 1886           sb.append("]");
 1887           return sb.toString();
 1888       }
 1889   
 1890       // Copied from sun.security.x509.KeyUsageExtension
 1891       // (without calling the superclass)
 1892       /**
 1893        * Returns a printable representation of the KeyUsage.
 1894        */
 1895       private static String keyUsageToString(boolean[] k) {
 1896           String s = "KeyUsage [\n";
 1897           try {
 1898               if (k[0]) {
 1899                   s += "  DigitalSignature\n";
 1900               }
 1901               if (k[1]) {
 1902                   s += "  Non_repudiation\n";
 1903               }
 1904               if (k[2]) {
 1905                   s += "  Key_Encipherment\n";
 1906               }
 1907               if (k[3]) {
 1908                   s += "  Data_Encipherment\n";
 1909               }
 1910               if (k[4]) {
 1911                   s += "  Key_Agreement\n";
 1912               }
 1913               if (k[5]) {
 1914                   s += "  Key_CertSign\n";
 1915               }
 1916               if (k[6]) {
 1917                   s += "  Crl_Sign\n";
 1918               }
 1919               if (k[7]) {
 1920                   s += "  Encipher_Only\n";
 1921               }
 1922               if (k[8]) {
 1923                   s += "  Decipher_Only\n";
 1924               }
 1925           } catch (ArrayIndexOutOfBoundsException ex) {}
 1926   
 1927           s += "]\n";
 1928   
 1929           return (s);
 1930       }
 1931   
 1932       /**
 1933        * Returns an Extension object given any X509Certificate and extension oid.
 1934        * Throw an <code>IOException</code> if the extension byte value is
 1935        * malformed.
 1936        *
 1937        * @param cert a <code>X509Certificate</code>
 1938        * @param extId an <code>integer</code> which specifies the extension index.
 1939        * Currently, the supported extensions are as follows:
 1940        * index 0 - PrivateKeyUsageExtension
 1941        * index 1 - SubjectAlternativeNameExtension
 1942        * index 2 - NameConstraintsExtension
 1943        * index 3 - CertificatePoliciesExtension
 1944        * index 4 - ExtendedKeyUsageExtension
 1945        * @return an <code>Extension</code> object whose real type is as specified
 1946        * by the extension oid.
 1947        * @throws IOException if cannot construct the <code>Extension</code>
 1948        * object with the extension encoding retrieved from the passed in
 1949        * <code>X509Certificate</code>.
 1950        */
 1951       private static Extension getExtensionObject(X509Certificate cert, int extId)
 1952               throws IOException {
 1953           if (cert instanceof X509CertImpl) {
 1954               X509CertImpl impl = (X509CertImpl)cert;
 1955               switch (extId) {
 1956               case PRIVATE_KEY_USAGE_ID:
 1957                   return impl.getPrivateKeyUsageExtension();
 1958               case SUBJECT_ALT_NAME_ID:
 1959                   return impl.getSubjectAlternativeNameExtension();
 1960               case NAME_CONSTRAINTS_ID:
 1961                   return impl.getNameConstraintsExtension();
 1962               case CERT_POLICIES_ID:
 1963                   return impl.getCertificatePoliciesExtension();
 1964               case EXTENDED_KEY_USAGE_ID:
 1965                   return impl.getExtendedKeyUsageExtension();
 1966               default:
 1967                   return null;
 1968               }
 1969           }
 1970           byte[] rawExtVal = cert.getExtensionValue(EXTENSION_OIDS[extId]);
 1971           if (rawExtVal == null) {
 1972               return null;
 1973           }
 1974           DerInputStream in = new DerInputStream(rawExtVal);
 1975           byte[] encoded = in.getOctetString();
 1976           switch (extId) {
 1977           case PRIVATE_KEY_USAGE_ID:
 1978               try {
 1979                   return new PrivateKeyUsageExtension(FALSE, encoded);
 1980               } catch (CertificateException ex) {
 1981                   throw new IOException(ex.getMessage());
 1982               }
 1983           case SUBJECT_ALT_NAME_ID:
 1984               return new SubjectAlternativeNameExtension(FALSE, encoded);
 1985           case NAME_CONSTRAINTS_ID:
 1986               return new NameConstraintsExtension(FALSE, encoded);
 1987           case CERT_POLICIES_ID:
 1988               return new CertificatePoliciesExtension(FALSE, encoded);
 1989           case EXTENDED_KEY_USAGE_ID:
 1990               return new ExtendedKeyUsageExtension(FALSE, encoded);
 1991           default:
 1992               return null;
 1993           }
 1994       }
 1995   
 1996       /**
 1997        * Decides whether a <code>Certificate</code> should be selected.
 1998        *
 1999        * @param cert the <code>Certificate</code> to be checked
 2000        * @return <code>true</code> if the <code>Certificate</code> should be
 2001        *         selected, <code>false</code> otherwise
 2002        */
 2003       public boolean match(Certificate cert) {
 2004           if (!(cert instanceof X509Certificate)) {
 2005               return false;
 2006           }
 2007           X509Certificate xcert = (X509Certificate)cert;
 2008   
 2009           if (debug != null) {
 2010               debug.println("X509CertSelector.match(SN: "
 2011                   + (xcert.getSerialNumber()).toString(16) + "\n  Issuer: "
 2012                   + xcert.getIssuerDN() + "\n  Subject: " + xcert.getSubjectDN()
 2013                   + ")");
 2014           }
 2015   
 2016           /* match on X509Certificate */
 2017           if (x509Cert != null) {
 2018               if (!x509Cert.equals(xcert)) {
 2019                   if (debug != null) {
 2020                       debug.println("X509CertSelector.match: "
 2021                           + "certs don't match");
 2022                   }
 2023                   return false;
 2024               }
 2025           }
 2026   
 2027           /* match on serial number */
 2028           if (serialNumber != null) {
 2029               if (!serialNumber.equals(xcert.getSerialNumber())) {
 2030                   if (debug != null) {
 2031                       debug.println("X509CertSelector.match: "
 2032                           + "serial numbers don't match");
 2033                   }
 2034                   return false;
 2035               }
 2036           }
 2037   
 2038           /* match on issuer name */
 2039           if (issuer != null) {
 2040               if (!issuer.equals(xcert.getIssuerX500Principal())) {
 2041                   if (debug != null) {
 2042                       debug.println("X509CertSelector.match: "
 2043                           + "issuer DNs don't match");
 2044                   }
 2045                   return false;
 2046               }
 2047           }
 2048   
 2049           /* match on subject name */
 2050           if (subject != null) {
 2051               if (!subject.equals(xcert.getSubjectX500Principal())) {
 2052                   if (debug != null) {
 2053                       debug.println("X509CertSelector.match: "
 2054                           + "subject DNs don't match");
 2055                   }
 2056                   return false;
 2057               }
 2058           }
 2059   
 2060           /* match on certificate validity range */
 2061           if (certificateValid != null) {
 2062               try {
 2063                   xcert.checkValidity(certificateValid);
 2064               } catch (CertificateException e) {
 2065                   if (debug != null) {
 2066                       debug.println("X509CertSelector.match: "
 2067                           + "certificate not within validity period");
 2068                   }
 2069                   return false;
 2070               }
 2071           }
 2072   
 2073           /* match on subject public key */
 2074           if (subjectPublicKeyBytes != null) {
 2075               byte[] certKey = xcert.getPublicKey().getEncoded();
 2076               if (!Arrays.equals(subjectPublicKeyBytes, certKey)) {
 2077                   if (debug != null) {
 2078                       debug.println("X509CertSelector.match: "
 2079                           + "subject public keys don't match");
 2080                   }
 2081                   return false;
 2082               }
 2083           }
 2084   
 2085           boolean result = matchBasicConstraints(xcert)
 2086                         && matchKeyUsage(xcert)
 2087                         && matchExtendedKeyUsage(xcert)
 2088                         && matchSubjectKeyID(xcert)
 2089                         && matchAuthorityKeyID(xcert)
 2090                         && matchPrivateKeyValid(xcert)
 2091                         && matchSubjectPublicKeyAlgID(xcert)
 2092                         && matchPolicy(xcert)
 2093                         && matchSubjectAlternativeNames(xcert)
 2094                         && matchPathToNames(xcert)
 2095                         && matchNameConstraints(xcert);
 2096   
 2097           if (result && (debug != null)) {
 2098               debug.println("X509CertSelector.match returning: true");
 2099           }
 2100           return result;
 2101       }
 2102   
 2103       /* match on subject key identifier extension value */
 2104       private boolean matchSubjectKeyID(X509Certificate xcert) {
 2105           if (subjectKeyID == null) {
 2106               return true;
 2107           }
 2108           try {
 2109               byte[] extVal = xcert.getExtensionValue("2.5.29.14");
 2110               if (extVal == null) {
 2111                   if (debug != null) {
 2112                       debug.println("X509CertSelector.match: "
 2113                           + "no subject key ID extension");
 2114                   }
 2115                   return false;
 2116               }
 2117               DerInputStream in = new DerInputStream(extVal);
 2118               byte[] certSubjectKeyID = in.getOctetString();
 2119               if (certSubjectKeyID == null ||
 2120                       !Arrays.equals(subjectKeyID, certSubjectKeyID)) {
 2121                   if (debug != null) {
 2122                       debug.println("X509CertSelector.match: "
 2123                           + "subject key IDs don't match");
 2124                   }
 2125                   return false;
 2126               }
 2127           } catch (IOException ex) {
 2128               if (debug != null) {
 2129                   debug.println("X509CertSelector.match: "
 2130                       + "exception in subject key ID check");
 2131               }
 2132               return false;
 2133           }
 2134           return true;
 2135       }
 2136   
 2137       /* match on authority key identifier extension value */
 2138       private boolean matchAuthorityKeyID(X509Certificate xcert) {
 2139           if (authorityKeyID == null) {
 2140               return true;
 2141           }
 2142           try {
 2143               byte[] extVal = xcert.getExtensionValue("2.5.29.35");
 2144               if (extVal == null) {
 2145                   if (debug != null) {
 2146                       debug.println("X509CertSelector.match: "
 2147                           + "no authority key ID extension");
 2148                   }
 2149                   return false;
 2150               }
 2151               DerInputStream in = new DerInputStream(extVal);
 2152               byte[] certAuthKeyID = in.getOctetString();
 2153               if (certAuthKeyID == null ||
 2154                       !Arrays.equals(authorityKeyID, certAuthKeyID)) {
 2155                   if (debug != null) {
 2156                       debug.println("X509CertSelector.match: "
 2157                           + "authority key IDs don't match");
 2158                   }
 2159                   return false;
 2160               }
 2161           } catch (IOException ex) {
 2162               if (debug != null) {
 2163                   debug.println("X509CertSelector.match: "
 2164