mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1320 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1320 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Java
		
	
	
	
/* X509CertSelector.java -- selects X.509 certificates by criteria.
 | 
						|
   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
 | 
						|
package java.security.cert;
 | 
						|
 | 
						|
import gnu.classpath.SystemProperties;
 | 
						|
import gnu.java.lang.CPStringBuilder;
 | 
						|
import gnu.java.security.OID;
 | 
						|
import gnu.java.security.x509.GnuPKIExtension;
 | 
						|
import gnu.java.security.x509.ext.CertificatePolicies;
 | 
						|
import gnu.java.security.x509.ext.Extension;
 | 
						|
import gnu.java.security.x509.ext.GeneralName;
 | 
						|
import gnu.java.security.x509.ext.GeneralSubtree;
 | 
						|
import gnu.java.security.x509.ext.NameConstraints;
 | 
						|
import gnu.java.security.x509.ext.GeneralName.Kind;
 | 
						|
 | 
						|
import java.io.IOException;
 | 
						|
import java.math.BigInteger;
 | 
						|
import java.net.InetAddress;
 | 
						|
import java.security.KeyFactory;
 | 
						|
import java.security.PublicKey;
 | 
						|
import java.security.spec.X509EncodedKeySpec;
 | 
						|
import java.util.ArrayList;
 | 
						|
import java.util.Arrays;
 | 
						|
import java.util.Collection;
 | 
						|
import java.util.Collections;
 | 
						|
import java.util.Date;
 | 
						|
import java.util.HashSet;
 | 
						|
import java.util.Iterator;
 | 
						|
import java.util.LinkedList;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Set;
 | 
						|
 | 
						|
import javax.security.auth.x500.X500Principal;
 | 
						|
 | 
						|
/**
 | 
						|
 * A concrete implementation of {@link CertSelector} for X.509 certificates,
 | 
						|
 * which allows a number of criteria to be set when accepting certificates,
 | 
						|
 * from validity dates, to issuer and subject distinguished names, to some
 | 
						|
 * of the various X.509 extensions.
 | 
						|
 *
 | 
						|
 * <p>Use of this class requires extensive knowledge of the Internet
 | 
						|
 * Engineering Task Force's Public Key Infrastructure (X.509). The primary
 | 
						|
 * document describing this standard is <a
 | 
						|
 * href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
 | 
						|
 * Public Key Infrastructure Certificate and Certificate Revocation List
 | 
						|
 * (CRL) Profile</a>.
 | 
						|
 *
 | 
						|
 * <p>Note that this class is not thread-safe. If multiple threads will
 | 
						|
 * use or modify this class then they need to synchronize on the object.
 | 
						|
 *
 | 
						|
 * @author Casey Marshall (csm@gnu.org)
 | 
						|
 * @since 1.4
 | 
						|
 */
 | 
						|
public class X509CertSelector implements CertSelector, Cloneable
 | 
						|
{
 | 
						|
 | 
						|
  // Constants and fields.
 | 
						|
  // -------------------------------------------------------------------------
 | 
						|
 | 
						|
  private static final String AUTH_KEY_ID = "2.5.29.35";
 | 
						|
  private static final String SUBJECT_KEY_ID = "2.5.29.14";
 | 
						|
  private static final String NAME_CONSTRAINTS_ID = "2.5.29.30";
 | 
						|
 | 
						|
  private static boolean checkOid(int[] oid)
 | 
						|
  {
 | 
						|
    return (oid != null && oid.length > 2 &&
 | 
						|
            (oid[0] >= 0 && oid[0] <= 2) && (oid[1] >= 0 && oid[1] <= 39));
 | 
						|
  }
 | 
						|
 | 
						|
  private static GeneralName makeName(int id, String name) throws IOException
 | 
						|
  {
 | 
						|
    byte[] nameBytes = null;
 | 
						|
    GeneralName.Kind kind = GeneralName.Kind.forTag(id);
 | 
						|
    switch (Kind.forTag(id))
 | 
						|
    {
 | 
						|
      case dNSName:
 | 
						|
      case rfc822Name:
 | 
						|
      case uniformResourceIdentifier:
 | 
						|
        nameBytes = name.getBytes("ASCII");
 | 
						|
        break;
 | 
						|
 | 
						|
      case iPAddress:
 | 
						|
        InetAddress addr = InetAddress.getByName(name);
 | 
						|
        nameBytes = addr.getAddress();
 | 
						|
        break;
 | 
						|
 | 
						|
      case registeredId:
 | 
						|
        OID oid = new OID(name);
 | 
						|
        nameBytes = oid.getDER();
 | 
						|
        break;
 | 
						|
 | 
						|
      case directoryName:
 | 
						|
        X500Principal xname = new X500Principal(name);
 | 
						|
        nameBytes = xname.getEncoded();
 | 
						|
        break;
 | 
						|
 | 
						|
      case ediPartyName:
 | 
						|
      case x400Address:
 | 
						|
      case otherName:
 | 
						|
        throw new IOException("cannot decode string representation of "
 | 
						|
                              + kind);
 | 
						|
    }
 | 
						|
    return new GeneralName(kind, nameBytes);
 | 
						|
  }
 | 
						|
 | 
						|
  private int basicConstraints;
 | 
						|
  private X509Certificate cert;
 | 
						|
  private BigInteger serialNo;
 | 
						|
  private X500Principal issuer;
 | 
						|
  private X500Principal subject;
 | 
						|
  private byte[] subjectKeyId;
 | 
						|
  private byte[] authKeyId;
 | 
						|
  private boolean[] keyUsage;
 | 
						|
  private Date certValid;
 | 
						|
  private OID sigId;
 | 
						|
  private PublicKey subjectKey;
 | 
						|
  private X509EncodedKeySpec subjectKeySpec;
 | 
						|
  private Set<String> keyPurposeSet;
 | 
						|
  private List<GeneralName> altNames;
 | 
						|
  private boolean matchAllNames;
 | 
						|
  private byte[] nameConstraints;
 | 
						|
  private Set<OID> policy;
 | 
						|
  private List<GeneralName> pathToNames;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new X.509 certificate selector. The new selector will be
 | 
						|
   * empty, and will accept any certificate (provided that it is an
 | 
						|
   * {@link X509Certificate}).
 | 
						|
   */
 | 
						|
  public X509CertSelector()
 | 
						|
  {
 | 
						|
    basicConstraints = -1;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Add a name to match in the NameConstraints extension. The argument is
 | 
						|
   * the DER-encoded bytes of a GeneralName structure.
 | 
						|
   *
 | 
						|
   * See the method {@link #addSubjectAlternativeName(int, byte[])} for the
 | 
						|
   * format of the GeneralName structure.
 | 
						|
   *
 | 
						|
   * @param id The name identifier. Must be between 0 and 8.
 | 
						|
   * @param name The DER-encoded bytes of the name to match.
 | 
						|
   * @throws IOException If the name DER is malformed.
 | 
						|
   */
 | 
						|
  public void addPathToName(int id, byte[] name) throws IOException
 | 
						|
  {
 | 
						|
    GeneralName generalName = new GeneralName(GeneralName.Kind.forTag(id), name);
 | 
						|
    if (pathToNames == null)
 | 
						|
      pathToNames = new LinkedList<GeneralName>();
 | 
						|
    pathToNames.add(generalName);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Add a name to match in the NameConstraints extension. This method will
 | 
						|
   * only recognize certain types of name that have convenient string
 | 
						|
   * encodings. For robustness, you should use the {@link
 | 
						|
   *  #addPathToName(int, byte[])} method whenever possible.
 | 
						|
   *
 | 
						|
   * @param id The name identifier. Must be between 0 and 8.
 | 
						|
   * @param name The name.
 | 
						|
   * @throws IOException If the name cannot be decoded.
 | 
						|
   */
 | 
						|
  public void addPathToName(int id, String name) throws IOException
 | 
						|
  {
 | 
						|
    GeneralName generalName = makeName(id, name);
 | 
						|
    if (pathToNames == null)
 | 
						|
      pathToNames = new LinkedList<GeneralName>();
 | 
						|
    pathToNames.add(generalName);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Add a name, as DER-encoded bytes, to the subject alternative names
 | 
						|
   * criterion.
 | 
						|
   *
 | 
						|
   * The name is a GeneralName structure, which has the ASN.1 format:
 | 
						|
   *
 | 
						|
   * <pre>
 | 
						|
  GeneralName ::= CHOICE {
 | 
						|
    otherName                       [0]     OtherName,
 | 
						|
    rfc822Name                      [1]     IA5String,
 | 
						|
    dNSName                         [2]     IA5String,
 | 
						|
    x400Address                     [3]     ORAddress,
 | 
						|
    directoryName                   [4]     Name,
 | 
						|
    ediPartyName                    [5]     EDIPartyName,
 | 
						|
    uniformResourceIdentifier       [6]     IA5String,
 | 
						|
    iPAddress                       [7]     OCTET STRING,
 | 
						|
    registeredID                    [8]     OBJECT IDENTIFIER }
 | 
						|
</pre>
 | 
						|
   *
 | 
						|
   * @param id The type of name this is.
 | 
						|
   * @param name The DER-encoded name.
 | 
						|
   * @throws IOException If the name is not a valid DER sequence.
 | 
						|
   */
 | 
						|
  public void addSubjectAlternativeName(int id, byte[] name)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    GeneralName generalName = new GeneralName(GeneralName.Kind.forTag(id), name);
 | 
						|
    if (altNames == null)
 | 
						|
      altNames = new LinkedList<GeneralName>();
 | 
						|
    altNames.add(generalName);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Add a name to the subject alternative names criterion. This method will
 | 
						|
   * only recognize certain types of name that have convenient string
 | 
						|
   * encodings. For robustness, you should use the {@link
 | 
						|
   *  #addSubjectAlternativeName(int, byte[])} method whenever possible.
 | 
						|
   *
 | 
						|
   * This method can only decode certain name kinds of names as strings.
 | 
						|
   *
 | 
						|
   * @param id The type of name this is. Must be in the range [0,8].
 | 
						|
   * @param name The name.
 | 
						|
   * @throws IOException If the id is out of range, or if the name
 | 
						|
   *   is null.
 | 
						|
   */
 | 
						|
  public void addSubjectAlternativeName(int id, String name)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    GeneralName generalName = makeName(id, name);
 | 
						|
    if (altNames == null)
 | 
						|
      altNames = new LinkedList<GeneralName>();
 | 
						|
    altNames.add(generalName);
 | 
						|
  }
 | 
						|
 | 
						|
  public Object clone()
 | 
						|
  {
 | 
						|
    try
 | 
						|
      {
 | 
						|
        return super.clone();
 | 
						|
      }
 | 
						|
    catch (CloneNotSupportedException shouldNotHappen)
 | 
						|
      {
 | 
						|
        throw new Error(shouldNotHappen);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the authority key identifier criterion, or <code>null</code> if
 | 
						|
   * this value was not set. Note that the byte array is cloned to prevent
 | 
						|
   * modification.
 | 
						|
   *
 | 
						|
   * @return The authority key identifier.
 | 
						|
   */
 | 
						|
  public byte[] getAuthorityKeyIdentifier()
 | 
						|
  {
 | 
						|
    if (authKeyId != null)
 | 
						|
      return (byte[]) authKeyId.clone();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the basic constraints criterion, or -1 if this value is not set.
 | 
						|
   *
 | 
						|
   * @return The basic constraints.
 | 
						|
   */
 | 
						|
  public int getBasicConstraints()
 | 
						|
  {
 | 
						|
    return basicConstraints;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the certificate criterion, or <code>null</code> if this value
 | 
						|
   * was not set.
 | 
						|
   *
 | 
						|
   * @return The certificate.
 | 
						|
   */
 | 
						|
  public X509Certificate getCertificate()
 | 
						|
  {
 | 
						|
    return cert;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the date at which certificates must be valid, or <code>null</code>
 | 
						|
   * if this criterion was not set.
 | 
						|
   *
 | 
						|
   * @return The target certificate valitity date.
 | 
						|
   */
 | 
						|
  public Date getCertificateValid()
 | 
						|
  {
 | 
						|
    if (certValid != null)
 | 
						|
      return (Date) certValid.clone();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the set of extended key purpose IDs, as an unmodifiable set
 | 
						|
   * of OID strings. Returns <code>null</code> if this criterion is not
 | 
						|
   * set.
 | 
						|
   *
 | 
						|
   * @return The set of key purpose OIDs (strings).
 | 
						|
   */
 | 
						|
  public Set<String> getExtendedKeyUsage()
 | 
						|
  {
 | 
						|
    if (keyPurposeSet != null)
 | 
						|
      return Collections.unmodifiableSet(keyPurposeSet);
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the issuer criterion as a sequence of DER bytes, or
 | 
						|
   * <code>null</code> if this value was not set.
 | 
						|
   *
 | 
						|
   * @return The issuer.
 | 
						|
   */
 | 
						|
  public byte[] getIssuerAsBytes() throws IOException
 | 
						|
  {
 | 
						|
    if (issuer != null)
 | 
						|
      return issuer.getEncoded();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the issuer criterion as a string, or <code>null</code> if this
 | 
						|
   * value was not set.
 | 
						|
   *
 | 
						|
   * @return The issuer.
 | 
						|
   */
 | 
						|
  public String getIssuerAsString()
 | 
						|
  {
 | 
						|
    if (issuer != null)
 | 
						|
      return issuer.getName();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the public key usage criterion, or <code>null</code> if this
 | 
						|
   * value is not set. Note that the array is cloned to prevent modification.
 | 
						|
   *
 | 
						|
   * @return The public key usage.
 | 
						|
   */
 | 
						|
  public boolean[] getKeyUsage()
 | 
						|
  {
 | 
						|
    if (keyUsage != null)
 | 
						|
      return (boolean[]) keyUsage.clone();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns whether or not all specified alternative names must match.
 | 
						|
   * If false, a certificate is considered a match if <em>one</em> of the
 | 
						|
   * specified alternative names matches.
 | 
						|
   *
 | 
						|
   * @return true if all names must match.
 | 
						|
   */
 | 
						|
  public boolean getMatchAllSubjectAltNames()
 | 
						|
  {
 | 
						|
    return matchAllNames;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the name constraints criterion, or <code>null</code> if this
 | 
						|
   * value is not set. Note that the byte array is cloned to prevent
 | 
						|
   * modification.
 | 
						|
   *
 | 
						|
   * @return The name constraints.
 | 
						|
   */
 | 
						|
  public byte[] getNameConstraints()
 | 
						|
  {
 | 
						|
    if (nameConstraints != null)
 | 
						|
      return (byte[]) nameConstraints.clone();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  public Collection<List<?>> getPathToNames()
 | 
						|
  {
 | 
						|
    if (pathToNames != null)
 | 
						|
      {
 | 
						|
        List<List<?>> names = new ArrayList<List<?>>(pathToNames.size());
 | 
						|
        for (GeneralName name : pathToNames)
 | 
						|
          {
 | 
						|
            List<Object> n = new ArrayList<Object>(2);
 | 
						|
            n.add(name.kind().tag());
 | 
						|
            n.add(name.name());
 | 
						|
            names.add(n);
 | 
						|
          }
 | 
						|
 | 
						|
        return names;
 | 
						|
      }
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the certificate policy extension that will be matched by this
 | 
						|
   * selector, or null if the certificate policy will not be matched.
 | 
						|
   *
 | 
						|
   * @return The policy to be matched, or null.
 | 
						|
   */
 | 
						|
  public Set<String> getPolicy()
 | 
						|
  {
 | 
						|
    Set<OID> p = this.policy;
 | 
						|
    if (p != null)
 | 
						|
      {
 | 
						|
        Set<String> strings = new HashSet<String>(p.size());
 | 
						|
        for (OID o : p)
 | 
						|
          {
 | 
						|
            strings.add(o.toString());
 | 
						|
          }
 | 
						|
        return strings;
 | 
						|
      }
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method, and its related X.509 certificate extension — the
 | 
						|
   * private key usage period — is not supported under the Internet
 | 
						|
   * PKI for X.509 certificates (PKIX), described in RFC 3280. As such, this
 | 
						|
   * method is not supported either.
 | 
						|
   *
 | 
						|
   * <p>Do not use this method. It is not deprecated, as it is not deprecated
 | 
						|
   * in the Java standard, but it is basically a no-operation and simply
 | 
						|
   * returns <code>null</code>.
 | 
						|
   *
 | 
						|
   * @return Null.
 | 
						|
   */
 | 
						|
  public Date getPrivateKeyValid()
 | 
						|
  {
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the serial number criterion, or <code>null</code> if this
 | 
						|
   * value was not set.
 | 
						|
   *
 | 
						|
   * @return The serial number.
 | 
						|
   */
 | 
						|
  public BigInteger getSerialNumber()
 | 
						|
  {
 | 
						|
    return serialNo;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the subject alternative names criterion. The collection returned
 | 
						|
   * is a collection of pairs: the first element is an {@link Integer}
 | 
						|
   * containing the name type, and the second is a byte array containing
 | 
						|
   * the DER-encoded name bytes.
 | 
						|
   *
 | 
						|
   * @return The subject alternative names criterion. Returns null if this
 | 
						|
   *  criterion is not set.
 | 
						|
   */
 | 
						|
  public Collection<List<?>> getSubjectAlternativeNames()
 | 
						|
  {
 | 
						|
    if (altNames != null)
 | 
						|
      {
 | 
						|
        List<List<?>> names = new ArrayList<List<?>>(altNames.size());
 | 
						|
        for (GeneralName name : altNames)
 | 
						|
          {
 | 
						|
            List<Object> n = new ArrayList<Object>(2);
 | 
						|
            n.add(name.kind().tag());
 | 
						|
            n.add(name.name());
 | 
						|
            names.add(n);
 | 
						|
          }
 | 
						|
        return names;
 | 
						|
      }
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the subject criterion as a sequence of DER bytes, or
 | 
						|
   * <code>null</code> if this value is not set.
 | 
						|
   *
 | 
						|
   * @return The subject.
 | 
						|
   */
 | 
						|
  public byte[] getSubjectAsBytes() throws IOException
 | 
						|
  {
 | 
						|
    if (subject != null)
 | 
						|
      return subject.getEncoded();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the subject criterion as a string, of <code>null</code> if
 | 
						|
   * this value was not set.
 | 
						|
   *
 | 
						|
   * @return The subject.
 | 
						|
   */
 | 
						|
  public String getSubjectAsString()
 | 
						|
  {
 | 
						|
    if (subject != null)
 | 
						|
      return subject.getName();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the subject key identifier criterion, or <code>null</code> if
 | 
						|
   * this value was not set. Note that the byte array is cloned to prevent
 | 
						|
   * modification.
 | 
						|
   *
 | 
						|
   * @return The subject key identifier.
 | 
						|
   */
 | 
						|
  public byte[] getSubjectKeyIdentifier()
 | 
						|
  {
 | 
						|
    if (subjectKeyId != null)
 | 
						|
      return (byte[]) subjectKeyId.clone();
 | 
						|
    else
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the subject public key criterion, or <code>null</code> if this
 | 
						|
   * value is not set.
 | 
						|
   *
 | 
						|
   * @return The subject public key.
 | 
						|
   */
 | 
						|
  public PublicKey getSubjectPublicKey()
 | 
						|
  {
 | 
						|
    return subjectKey;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the public key algorithm ID that matching certificates must have,
 | 
						|
   * or <code>null</code> if this criterion was not set.
 | 
						|
   *
 | 
						|
   * @return The public key algorithm ID.
 | 
						|
   */
 | 
						|
  public String getSubjectPublicKeyAlgID()
 | 
						|
  {
 | 
						|
    return String.valueOf(sigId);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Match a certificate. This method will check the given certificate
 | 
						|
   * against all the enabled criteria of this selector, and will return
 | 
						|
   * <code>true</code> if the given certificate matches.
 | 
						|
   *
 | 
						|
   * @param certificate The certificate to check.
 | 
						|
   * @return true if the certificate matches all criteria.
 | 
						|
   */
 | 
						|
  public boolean match(Certificate certificate)
 | 
						|
  {
 | 
						|
    if (!(certificate instanceof X509Certificate))
 | 
						|
      return false;
 | 
						|
    X509Certificate cert = (X509Certificate) certificate;
 | 
						|
    if (this.cert != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            byte[] e1 = this.cert.getEncoded();
 | 
						|
            byte[] e2 = cert.getEncoded();
 | 
						|
            if (!Arrays.equals(e1, e2))
 | 
						|
              return false;
 | 
						|
          }
 | 
						|
        catch (CertificateEncodingException cee)
 | 
						|
          {
 | 
						|
            return false;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    if (serialNo != null)
 | 
						|
      {
 | 
						|
        if (!serialNo.equals(cert.getSerialNumber()))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (certValid != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            cert.checkValidity(certValid);
 | 
						|
          }
 | 
						|
        catch (CertificateException ce)
 | 
						|
          {
 | 
						|
            return false;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    if (issuer != null)
 | 
						|
      {
 | 
						|
        if (!issuer.equals(cert.getIssuerX500Principal()))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (subject != null)
 | 
						|
      {
 | 
						|
        if (!subject.equals(cert.getSubjectX500Principal()))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (sigId != null)
 | 
						|
      {
 | 
						|
        if (!sigId.toString().equals(cert.getSigAlgOID()))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (subjectKeyId != null)
 | 
						|
      {
 | 
						|
        byte[] b = cert.getExtensionValue(SUBJECT_KEY_ID);
 | 
						|
        if (!Arrays.equals(b, subjectKeyId))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (authKeyId != null)
 | 
						|
      {
 | 
						|
        byte[] b = cert.getExtensionValue(AUTH_KEY_ID);
 | 
						|
        if (!Arrays.equals(b, authKeyId))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (keyUsage != null)
 | 
						|
      {
 | 
						|
        boolean[] b = cert.getKeyUsage();
 | 
						|
        if (!Arrays.equals(b, keyUsage))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (basicConstraints >= 0)
 | 
						|
      {
 | 
						|
        if (cert.getBasicConstraints() != basicConstraints)
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
    if (keyPurposeSet != null)
 | 
						|
      {
 | 
						|
        List kp = null;
 | 
						|
        try
 | 
						|
          {
 | 
						|
            kp = cert.getExtendedKeyUsage();
 | 
						|
          }
 | 
						|
        catch (CertificateParsingException cpe)
 | 
						|
          {
 | 
						|
            return false;
 | 
						|
          }
 | 
						|
        if (kp == null)
 | 
						|
          return false;
 | 
						|
        for (Iterator it = keyPurposeSet.iterator(); it.hasNext(); )
 | 
						|
          {
 | 
						|
            if (!kp.contains(it.next()))
 | 
						|
              return false;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    if (altNames != null)
 | 
						|
      {
 | 
						|
        Collection<List<?>> an = null;
 | 
						|
        try
 | 
						|
          {
 | 
						|
            an = cert.getSubjectAlternativeNames();
 | 
						|
          }
 | 
						|
        catch (CertificateParsingException cpe)
 | 
						|
          {
 | 
						|
            return false;
 | 
						|
          }
 | 
						|
        if (an == null)
 | 
						|
          return false;
 | 
						|
        int match = 0;
 | 
						|
        for (GeneralName name : altNames)
 | 
						|
          {
 | 
						|
            for (List<?> list : an)
 | 
						|
              {
 | 
						|
                try
 | 
						|
                  {
 | 
						|
                    Integer id = (Integer) list.get(0);
 | 
						|
                    Object val = list.get(1);
 | 
						|
                    GeneralName n = null;
 | 
						|
                    if (val instanceof String)
 | 
						|
                      n = makeName(id, (String) val);
 | 
						|
                    else if (val instanceof byte[])
 | 
						|
                      {
 | 
						|
                        n = new GeneralName(GeneralName.Kind.forTag(id),
 | 
						|
                                            (byte[]) val);
 | 
						|
                      }
 | 
						|
                    else
 | 
						|
                      continue;
 | 
						|
                    if (name.equals(n))
 | 
						|
                      match++;
 | 
						|
                  }
 | 
						|
                catch (Exception e)
 | 
						|
                  {
 | 
						|
                    continue;
 | 
						|
                  }
 | 
						|
              }
 | 
						|
            if (match == 0 || (matchAllNames && match < altNames.size()))
 | 
						|
              return false;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    if (nameConstraints != null)
 | 
						|
      {
 | 
						|
        byte[] nc = cert.getExtensionValue(NAME_CONSTRAINTS_ID);
 | 
						|
        if (!Arrays.equals(nameConstraints, nc))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
 | 
						|
    if (policy != null)
 | 
						|
      {
 | 
						|
        CertificatePolicies policies = null;
 | 
						|
        if (cert instanceof GnuPKIExtension)
 | 
						|
          {
 | 
						|
            policies = (CertificatePolicies)
 | 
						|
              ((GnuPKIExtension) cert).getExtension(CertificatePolicies.ID).getValue();
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            byte[] policiesDer =
 | 
						|
              cert.getExtensionValue(CertificatePolicies.ID.toString());
 | 
						|
            try
 | 
						|
              {
 | 
						|
                policies = new CertificatePolicies(policiesDer);
 | 
						|
              }
 | 
						|
            catch (IOException ioe)
 | 
						|
              {
 | 
						|
                // ignored
 | 
						|
              }
 | 
						|
          }
 | 
						|
 | 
						|
        if (policies == null)
 | 
						|
          return false;
 | 
						|
        if (!policies.getPolicies().containsAll(policy))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
 | 
						|
    if (pathToNames != null)
 | 
						|
      {
 | 
						|
        NameConstraints nc = null;
 | 
						|
        if (cert instanceof GnuPKIExtension)
 | 
						|
          {
 | 
						|
            Extension e =
 | 
						|
              ((GnuPKIExtension) cert).getExtension(NameConstraints.ID);
 | 
						|
            if (e != null)
 | 
						|
              nc = (NameConstraints) e.getValue();
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            byte[] b = cert.getExtensionValue(NameConstraints.ID.toString());
 | 
						|
            if (b != null)
 | 
						|
              {
 | 
						|
                try
 | 
						|
                  {
 | 
						|
                    nc = new NameConstraints(b);
 | 
						|
                  }
 | 
						|
                catch (IOException ioe)
 | 
						|
                  {
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
 | 
						|
        if (nc == null)
 | 
						|
          return false;
 | 
						|
 | 
						|
        int match = 0;
 | 
						|
        for (GeneralName name : pathToNames)
 | 
						|
          {
 | 
						|
            for (GeneralSubtree subtree : nc.permittedSubtrees())
 | 
						|
              {
 | 
						|
                if (name.equals(subtree.base()))
 | 
						|
                  match++;
 | 
						|
              }
 | 
						|
          }
 | 
						|
        if (match == 0 || (matchAllNames && match < pathToNames.size()))
 | 
						|
          return false;
 | 
						|
      }
 | 
						|
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the authority key identifier criterion, or <code>null</code> to clear
 | 
						|
   * this criterion. Note that the byte array is cloned to prevent modification.
 | 
						|
   *
 | 
						|
   * @param authKeyId The authority key identifier.
 | 
						|
   */
 | 
						|
  public void setAuthorityKeyIdentifier(byte[] authKeyId)
 | 
						|
  {
 | 
						|
    this.authKeyId = authKeyId != null ? (byte[]) authKeyId.clone() : null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the basic constraints criterion. Specify -1 to clear this parameter.
 | 
						|
   *
 | 
						|
   * @param basicConstraints The new basic constraints value.
 | 
						|
   */
 | 
						|
  public void setBasicConstraints(int basicConstraints)
 | 
						|
  {
 | 
						|
    if (basicConstraints < -1)
 | 
						|
      basicConstraints = -1;
 | 
						|
    this.basicConstraints = basicConstraints;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the certificate criterion. If set, only certificates that are
 | 
						|
   * equal to the certificate passed here will be accepted.
 | 
						|
   *
 | 
						|
   * @param cert The certificate.
 | 
						|
   */
 | 
						|
  public void setCertificate(X509Certificate cert)
 | 
						|
  {
 | 
						|
    this.cert = cert;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the date at which certificates must be valid. Specify
 | 
						|
   * <code>null</code> to clear this criterion.
 | 
						|
   *
 | 
						|
   * @param certValid The certificate validity date.
 | 
						|
   */
 | 
						|
  public void setCertificateValid(Date certValid)
 | 
						|
  {
 | 
						|
    this.certValid = certValid != null ? (Date) certValid.clone() : null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the extended key usage criterion, as a set of OID strings. Specify
 | 
						|
   * <code>null</code> to clear this value.
 | 
						|
   *
 | 
						|
   * @param keyPurposeSet The set of key purpose OIDs.
 | 
						|
   * @throws IOException If any element of the set is not a valid OID string.
 | 
						|
   */
 | 
						|
  public void setExtendedKeyUsage(Set<String> keyPurposeSet) throws IOException
 | 
						|
  {
 | 
						|
    if (keyPurposeSet == null)
 | 
						|
      {
 | 
						|
        this.keyPurposeSet = null;
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    Set<String> s = new HashSet<String>();
 | 
						|
    for (Iterator it = keyPurposeSet.iterator(); it.hasNext(); )
 | 
						|
      {
 | 
						|
        Object o = it.next();
 | 
						|
        if (!(o instanceof String))
 | 
						|
          throw new IOException("not a string: " + o);
 | 
						|
        try
 | 
						|
          {
 | 
						|
            OID oid = new OID((String) o);
 | 
						|
            int[] comp = oid.getIDs();
 | 
						|
            if (!checkOid(comp))
 | 
						|
              throw new IOException("malformed OID: " + o);
 | 
						|
          }
 | 
						|
        catch (IllegalArgumentException iae)
 | 
						|
          {
 | 
						|
            IOException ioe = new IOException("malformed OID: " + o);
 | 
						|
            ioe.initCause(iae);
 | 
						|
            throw ioe;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    this.keyPurposeSet = s;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the issuer, specified as the DER encoding of the issuer's
 | 
						|
   * distinguished name. Only certificates issued by this issuer will
 | 
						|
   * be accepted.
 | 
						|
   *
 | 
						|
   * @param name The DER encoding of the issuer's distinguished name.
 | 
						|
   * @throws IOException If the given name is incorrectly formatted.
 | 
						|
   */
 | 
						|
  public void setIssuer(byte[] name) throws IOException
 | 
						|
  {
 | 
						|
    if (name != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            issuer = new X500Principal(name);
 | 
						|
          }
 | 
						|
        catch (IllegalArgumentException iae)
 | 
						|
          {
 | 
						|
            throw new IOException(iae.getMessage());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      issuer = null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the issuer, specified as a string representation of the issuer's
 | 
						|
   * distinguished name. Only certificates issued by this issuer will
 | 
						|
   * be accepted.
 | 
						|
   *
 | 
						|
   * @param name The string representation of the issuer's distinguished name.
 | 
						|
   * @throws IOException If the given name is incorrectly formatted.
 | 
						|
   */
 | 
						|
  public void setIssuer(String name) throws IOException
 | 
						|
  {
 | 
						|
    if (name != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            issuer = new X500Principal(name);
 | 
						|
          }
 | 
						|
        catch (IllegalArgumentException iae)
 | 
						|
          {
 | 
						|
            throw new IOException(iae.getMessage());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      issuer = null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the public key usage criterion. Specify <code>null</code> to clear
 | 
						|
   * this value.
 | 
						|
   *
 | 
						|
   * @param keyUsage The public key usage.
 | 
						|
   */
 | 
						|
  public void setKeyUsage(boolean[] keyUsage)
 | 
						|
  {
 | 
						|
    this.keyUsage = keyUsage != null ? (boolean[]) keyUsage.clone() : null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets whether or not all subject alternative names must be matched.
 | 
						|
   * If false, then a certificate will be considered a match if one
 | 
						|
   * alternative name matches.
 | 
						|
   *
 | 
						|
   * @param matchAllNames Whether or not all alternative names must be
 | 
						|
   *        matched.
 | 
						|
   */
 | 
						|
  public void setMatchAllSubjectAltNames(boolean matchAllNames)
 | 
						|
  {
 | 
						|
    this.matchAllNames = matchAllNames;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the name constraints criterion; specify <code>null</code> to
 | 
						|
   * clear this criterion. Note that if non-null, the argument will be
 | 
						|
   * cloned to prevent modification.
 | 
						|
   *
 | 
						|
   * @param nameConstraints The new name constraints.
 | 
						|
   * @throws IOException If the argument is not a valid DER-encoded
 | 
						|
   *         name constraints.
 | 
						|
   */
 | 
						|
  public void setNameConstraints(byte[] nameConstraints)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    // Check if the input is well-formed...
 | 
						|
    new NameConstraints(nameConstraints);
 | 
						|
 | 
						|
    // But we just compare raw byte arrays.
 | 
						|
    this.nameConstraints = nameConstraints != null
 | 
						|
      ? (byte[]) nameConstraints.clone() : null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the pathToNames criterion. The argument is a collection of
 | 
						|
   * pairs, the first element of which is an {@link Integer} giving
 | 
						|
   * the ID of the name, and the second element is either a {@link String}
 | 
						|
   * or a byte array.
 | 
						|
   *
 | 
						|
   * See {@link #addPathToName(int, byte[])} and {@link #addPathToName(int, String)}
 | 
						|
   * for how these arguments are handled.
 | 
						|
   *
 | 
						|
   * @param names The names.
 | 
						|
   * @throws IOException If any argument is malformed.
 | 
						|
   */
 | 
						|
  public void setPathToNames(Collection<List<?>> names) throws IOException
 | 
						|
  {
 | 
						|
    if (names == null || names.size() == 0)
 | 
						|
      {
 | 
						|
        pathToNames = null;
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        pathToNames = new ArrayList<GeneralName>(names.size());
 | 
						|
        for (List<?> name : names)
 | 
						|
          {
 | 
						|
            Integer id = (Integer) name.get(0);
 | 
						|
            Object name2 = name.get(1);
 | 
						|
            if (name2 instanceof String)
 | 
						|
              addPathToName(id, (String) name2);
 | 
						|
            else if (name2 instanceof byte[])
 | 
						|
              addPathToName(id, (byte[]) name2);
 | 
						|
            else
 | 
						|
              throw new IOException("invalid name type: "
 | 
						|
                                    + name2.getClass().getName());
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the certificate policy to match, or null if this criterion should
 | 
						|
   * not be checked. Each element if the set must be a dotted-decimal form
 | 
						|
   * of certificate policy object identifier.
 | 
						|
   *
 | 
						|
   * @param policy The policy to match.
 | 
						|
   * @throws IOException If some element of the policy is not a valid
 | 
						|
   *  policy extenison OID.
 | 
						|
   */
 | 
						|
  public void setPolicy(Set<String> policy) throws IOException
 | 
						|
  {
 | 
						|
    if (policy != null)
 | 
						|
      {
 | 
						|
        HashSet<OID> p = new HashSet<OID>(policy.size());
 | 
						|
        for (String s : policy)
 | 
						|
          {
 | 
						|
            try
 | 
						|
              {
 | 
						|
                OID oid = new OID(s);
 | 
						|
                int[] i = oid.getIDs();
 | 
						|
                if (!checkOid(i))
 | 
						|
                  throw new IOException("invalid OID");
 | 
						|
                p.add(oid);
 | 
						|
              }
 | 
						|
            catch (IOException ioe)
 | 
						|
              {
 | 
						|
                throw ioe;
 | 
						|
              }
 | 
						|
            catch (Exception x)
 | 
						|
              {
 | 
						|
                IOException ioe = new IOException("invalid OID");
 | 
						|
                ioe.initCause(x);
 | 
						|
                throw ioe;
 | 
						|
              }
 | 
						|
          }
 | 
						|
        this.policy = p;
 | 
						|
      }
 | 
						|
    else
 | 
						|
      this.policy = null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method, and its related X.509 certificate extension — the
 | 
						|
   * private key usage period — is not supported under the Internet
 | 
						|
   * PKI for X.509 certificates (PKIX), described in RFC 3280. As such, this
 | 
						|
   * method is not supported either.
 | 
						|
   *
 | 
						|
   * <p>Do not use this method. It is not deprecated, as it is not deprecated
 | 
						|
   * in the Java standard, but it is basically a no-operation.
 | 
						|
   *
 | 
						|
   * @param UNUSED Is silently ignored.
 | 
						|
   */
 | 
						|
  public void setPrivateKeyValid(Date UNUSED)
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the serial number of the desired certificate. Only certificates that
 | 
						|
   * contain this serial number are accepted.
 | 
						|
   *
 | 
						|
   * @param serialNo The serial number.
 | 
						|
   */
 | 
						|
  public void setSerialNumber(BigInteger serialNo)
 | 
						|
  {
 | 
						|
    this.serialNo = serialNo;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the subject, specified as the DER encoding of the subject's
 | 
						|
   * distinguished name. Only certificates with the given subject will
 | 
						|
   * be accepted.
 | 
						|
   *
 | 
						|
   * @param name The DER encoding of the subject's distinguished name.
 | 
						|
   * @throws IOException If the given name is incorrectly formatted.
 | 
						|
   */
 | 
						|
  public void setSubject(byte[] name) throws IOException
 | 
						|
  {
 | 
						|
    if (name != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            subject = new X500Principal(name);
 | 
						|
          }
 | 
						|
        catch (IllegalArgumentException iae)
 | 
						|
          {
 | 
						|
            throw new IOException(iae.getMessage());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      subject = null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the subject, specified as a string representation of the
 | 
						|
   * subject's distinguished name. Only certificates with the given
 | 
						|
   * subject will be accepted.
 | 
						|
   *
 | 
						|
   * @param name The string representation of the subject's distinguished name.
 | 
						|
   * @throws IOException If the given name is incorrectly formatted.
 | 
						|
   */
 | 
						|
  public void setSubject(String name) throws IOException
 | 
						|
  {
 | 
						|
    if (name != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            subject = new X500Principal(name);
 | 
						|
          }
 | 
						|
        catch (IllegalArgumentException iae)
 | 
						|
          {
 | 
						|
            throw new IOException(iae.getMessage());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      subject = null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the subject alternative names critertion. Each element of the
 | 
						|
   * argument must be a {@link java.util.List} that contains exactly two
 | 
						|
   * elements: the first an {@link Integer}, representing the type of
 | 
						|
   * name, and the second either a {@link String} or a byte array,
 | 
						|
   * representing the name itself.
 | 
						|
   *
 | 
						|
   * @param altNames The alternative names.
 | 
						|
   * @throws IOException If any element of the argument is invalid.
 | 
						|
   */
 | 
						|
  public void setSubjectAlternativeNames(Collection<List<?>> altNames)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    if (altNames == null || altNames.isEmpty())
 | 
						|
      {
 | 
						|
        this.altNames = null;
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    List<GeneralName> l = new ArrayList<GeneralName>(altNames.size());
 | 
						|
    for (List<?> list : altNames)
 | 
						|
      {
 | 
						|
        Integer id = (Integer) list.get(0);
 | 
						|
        Object value = list.get(1);
 | 
						|
        GeneralName name = null;
 | 
						|
        if (value instanceof String)
 | 
						|
          name = makeName(id, (String) value);
 | 
						|
        else if (value instanceof byte[])
 | 
						|
          name = new GeneralName(GeneralName.Kind.forTag(id), (byte[]) value);
 | 
						|
        else
 | 
						|
          throw new IOException("invalid name type: " + value.getClass().getName());
 | 
						|
        l.add(name);
 | 
						|
      }
 | 
						|
    this.altNames = l;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the subject key identifier criterion, or <code>null</code> to clear
 | 
						|
   * this criterion. Note that the byte array is cloned to prevent modification.
 | 
						|
   *
 | 
						|
   * @param subjectKeyId The subject key identifier.
 | 
						|
   */
 | 
						|
  public void setSubjectKeyIdentifier(byte[] subjectKeyId)
 | 
						|
  {
 | 
						|
    this.subjectKeyId = subjectKeyId != null ? (byte[]) subjectKeyId.clone() :
 | 
						|
      null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the subject public key criterion as a DER-encoded key. Specify
 | 
						|
   * <code>null</code> to clear this value.
 | 
						|
   *
 | 
						|
   * @param key The DER-encoded key bytes.
 | 
						|
   * @throws IOException If the argument is not a valid DER-encoded key.
 | 
						|
   */
 | 
						|
  public void setSubjectPublicKey(byte[] key) throws IOException
 | 
						|
  {
 | 
						|
    if (key == null)
 | 
						|
      {
 | 
						|
        subjectKey = null;
 | 
						|
        subjectKeySpec = null;
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    try
 | 
						|
      {
 | 
						|
        subjectKeySpec = new X509EncodedKeySpec(key);
 | 
						|
        KeyFactory enc = KeyFactory.getInstance("X.509");
 | 
						|
        subjectKey = enc.generatePublic(subjectKeySpec);
 | 
						|
      }
 | 
						|
    catch (Exception x)
 | 
						|
      {
 | 
						|
        subjectKey = null;
 | 
						|
        subjectKeySpec = null;
 | 
						|
        IOException ioe = new IOException(x.getMessage());
 | 
						|
        ioe.initCause(x);
 | 
						|
        throw ioe;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the subject public key criterion as an opaque representation.
 | 
						|
   * Specify <code>null</code> to clear this criterion.
 | 
						|
   *
 | 
						|
   * @param key The public key.
 | 
						|
   */
 | 
						|
  public void setSubjectPublicKey(PublicKey key)
 | 
						|
  {
 | 
						|
    this.subjectKey = key;
 | 
						|
    if (key == null)
 | 
						|
      {
 | 
						|
        subjectKeySpec = null;
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    try
 | 
						|
      {
 | 
						|
        KeyFactory enc = KeyFactory.getInstance("X.509");
 | 
						|
        subjectKeySpec = (X509EncodedKeySpec)
 | 
						|
          enc.getKeySpec(key, X509EncodedKeySpec.class);
 | 
						|
      }
 | 
						|
    catch (Exception x)
 | 
						|
      {
 | 
						|
        subjectKey = null;
 | 
						|
        subjectKeySpec = null;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the public key algorithm ID that matching certificates must have.
 | 
						|
   * Specify <code>null</code> to clear this criterion.
 | 
						|
   *
 | 
						|
   * @param sigId The public key ID.
 | 
						|
   * @throws IOException If the specified ID is not a valid object identifier.
 | 
						|
   */
 | 
						|
  public void setSubjectPublicKeyAlgID(String sigId) throws IOException
 | 
						|
  {
 | 
						|
    if (sigId != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            OID oid = new OID(sigId);
 | 
						|
            int[] comp = oid.getIDs();
 | 
						|
            if (!checkOid(comp))
 | 
						|
              throw new IOException("malformed OID: " + sigId);
 | 
						|
            this.sigId = oid;
 | 
						|
          }
 | 
						|
        catch (IllegalArgumentException iae)
 | 
						|
          {
 | 
						|
            IOException ioe = new IOException("malformed OID: " + sigId);
 | 
						|
            ioe.initCause(iae);
 | 
						|
            throw ioe;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      this.sigId = null;
 | 
						|
  }
 | 
						|
 | 
						|
  public String toString()
 | 
						|
  {
 | 
						|
    CPStringBuilder str = new CPStringBuilder(X509CertSelector.class.getName());
 | 
						|
    String nl = SystemProperties.getProperty("line.separator");
 | 
						|
    String eol = ";" + nl;
 | 
						|
    str.append(" {").append(nl);
 | 
						|
    if (cert != null)
 | 
						|
      str.append("  certificate = ").append(cert).append(eol);
 | 
						|
    if (basicConstraints >= 0)
 | 
						|
      str.append("  basic constraints = ").append(basicConstraints).append(eol);
 | 
						|
    if (serialNo != null)
 | 
						|
      str.append("  serial number = ").append(serialNo).append(eol);
 | 
						|
    if (certValid != null)
 | 
						|
      str.append("  valid date = ").append(certValid).append(eol);
 | 
						|
    if (issuer != null)
 | 
						|
      str.append("  issuer = ").append(issuer).append(eol);
 | 
						|
    if (subject != null)
 | 
						|
      str.append("  subject = ").append(subject).append(eol);
 | 
						|
    if (sigId != null)
 | 
						|
      str.append("  signature OID = ").append(sigId).append(eol);
 | 
						|
    if (subjectKey != null)
 | 
						|
      str.append("  subject public key = ").append(subjectKey).append(eol);
 | 
						|
    if (subjectKeyId != null)
 | 
						|
      {
 | 
						|
        str.append("  subject key ID = ");
 | 
						|
        for (int i = 0; i < subjectKeyId.length; i++)
 | 
						|
          {
 | 
						|
            str.append(Character.forDigit((subjectKeyId[i] & 0xF0) >>> 8, 16));
 | 
						|
            str.append(Character.forDigit((subjectKeyId[i] & 0x0F), 16));
 | 
						|
            if (i < subjectKeyId.length - 1)
 | 
						|
              str.append(':');
 | 
						|
          }
 | 
						|
        str.append(eol);
 | 
						|
      }
 | 
						|
    if (authKeyId != null)
 | 
						|
      {
 | 
						|
        str.append("  authority key ID = ");
 | 
						|
        for (int i = 0; i < authKeyId.length; i++)
 | 
						|
          {
 | 
						|
            str.append(Character.forDigit((authKeyId[i] & 0xF0) >>> 8, 16));
 | 
						|
            str.append(Character.forDigit((authKeyId[i] & 0x0F), 16));
 | 
						|
            if (i < authKeyId.length - 1)
 | 
						|
              str.append(':');
 | 
						|
          }
 | 
						|
        str.append(eol);
 | 
						|
      }
 | 
						|
    if (keyUsage != null)
 | 
						|
      {
 | 
						|
        str.append("  key usage = ");
 | 
						|
        for (int i = 0; i < keyUsage.length; i++)
 | 
						|
          str.append(keyUsage[i] ? '1' : '0');
 | 
						|
        str.append(eol);
 | 
						|
      }
 | 
						|
    if (keyPurposeSet != null)
 | 
						|
      str.append("  key purpose = ").append(keyPurposeSet).append(eol);
 | 
						|
    if (altNames != null)
 | 
						|
      str.append("  alternative names = ").append(altNames).append(eol);
 | 
						|
    if (nameConstraints != null)
 | 
						|
      str.append("  name constraints = <blob of data>").append(eol);
 | 
						|
    if (policy != null)
 | 
						|
      str.append("  policy = ").append(policy).append(eol);
 | 
						|
    if (pathToNames != null)
 | 
						|
      str.append("  pathToNames = ").append(pathToNames).append(eol);
 | 
						|
    str.append("}").append(nl);
 | 
						|
    return str.toString();
 | 
						|
  }
 | 
						|
}
 |