FileDocCategorySizeDatePackage
X509CertSelector.javaAPI DocJava SE 5 API97556Fri Aug 26 14:57:18 BST 2005java.security.cert

X509CertSelector

public class X509CertSelector extends Object implements CertSelector
A CertSelector that selects X509Certificates that match all specified criteria. This class is particularly useful when selecting certificates from a CertStore to build a PKIX-compliant certification path.

When first constructed, an X509CertSelector has no criteria enabled and each of the get methods return a default value (null, or -1 for the {@link #getBasicConstraints getBasicConstraints} method). Therefore, the {@link #match match} method would return true for any X509Certificate. Typically, several criteria are enabled (by calling {@link #setIssuer setIssuer} or {@link #setKeyUsage setKeyUsage}, for instance) and then the X509CertSelector is passed to {@link CertStore#getCertificates CertStore.getCertificates} or some similar method.

Several criteria can be enabled (by calling {@link #setIssuer setIssuer} and {@link #setSerialNumber setSerialNumber}, for example) such that the match method usually uniquely matches a single X509Certificate. We say usually, since it is possible for two issuing CAs to have the same distinguished name and each issue a certificate with the same serial number. Other unique combinations include the issuer, subject, subjectKeyIdentifier and/or the subjectPublicKey criteria.

Please refer to RFC 2459 for definitions of the X.509 certificate extensions mentioned below.

Concurrent Access

Unless otherwise specified, the methods defined in this class are not thread-safe. Multiple threads that need to access a single object concurrently should synchronize amongst themselves and provide the necessary locking. Multiple threads each manipulating separate objects need not synchronize.

see
CertSelector
see
X509Certificate
version
1.20, 06/08/04
since
1.4
author
Steve Hanna

Fields Summary
private static final Debug
debug
private static final ObjectIdentifier
ANY_EXTENDED_KEY_USAGE
private BigInteger
serialNumber
private X500Principal
issuer
private X500Principal
subject
private byte[]
subjectKeyID
private byte[]
authorityKeyID
private Date
certificateValid
private Date
privateKeyValid
private ObjectIdentifier
subjectPublicKeyAlgID
private PublicKey
subjectPublicKey
private byte[]
subjectPublicKeyBytes
private boolean[]
keyUsage
private Set
keyPurposeSet
private Set
keyPurposeOIDSet
private Set
subjectAlternativeNames
private Set
subjectAlternativeGeneralNames
private CertificatePolicySet
policy
private Set
policySet
private Set
pathToNames
private Set
pathToGeneralNames
private NameConstraintsExtension
nc
private byte[]
ncBytes
private int
basicConstraints
private X509Certificate
x509Cert
private boolean
matchAllSubjectAltNames
private static final Boolean
FALSE
private static final int
PRIVATE_KEY_USAGE_ID
private static final int
SUBJECT_ALT_NAME_ID
private static final int
NAME_CONSTRAINTS_ID
private static final int
CERT_POLICIES_ID
private static final int
EXTENDED_KEY_USAGE_ID
private static final int
NUM_OF_EXTENSIONS
private static final String[]
EXTENSION_OIDS
static final int
NAME_ANY
static final int
NAME_RFC822
static final int
NAME_DNS
static final int
NAME_X400
static final int
NAME_DIRECTORY
static final int
NAME_EDI
static final int
NAME_URI
static final int
NAME_IP
static final int
NAME_OID
Constructors Summary
public X509CertSelector()
Creates an X509CertSelector. Initially, no criteria are set so any X509Certificate will match.


                      
      
	// empty
    
Methods Summary
public voidaddPathToName(int type, java.lang.String name)
Adds a name to the pathToNames criterion. The X509Certificate must not include name constraints that would prohibit building a path to the specified name.

This method allows the caller to add a name to the set of names which the X509Certificates's name constraints must permit. The specified name is added to any previous value for the pathToNames criterion. If the name is a duplicate, it may be ignored.

The name is provided in string format. RFC 822, DNS, and URI names use the well-established string formats for those types (subject to the restrictions included in RFC 2459). IPv4 address names are supplied using dotted quad notation. OID address names are represented as a series of nonnegative integers separated by periods. And directory names (distinguished names) are supplied in RFC 2253 format. No standard string format is defined for otherNames, X.400 names, EDI party names, IPv6 address names, or any other type of names. They should be specified using the {@link #addPathToName(int type, byte [] name) addPathToName(int type, byte [] name)} method.

Note: for distinguished names, use {@linkplain #addPathToName(int, byte[])} instead. This method should not be relied on as it can fail to match some certificates because of a loss of encoding information in the RFC 2253 String form of some distinguished names.

param
type the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
param
name the name in string form
throws
IOException if a parsing error occurs

	addPathToNameInternal(type, name);
    
public voidaddPathToName(int type, byte[] name)
Adds a name to the pathToNames criterion. The X509Certificate must not include name constraints that would prohibit building a path to the specified name.

This method allows the caller to add a name to the set of names which the X509Certificates's name constraints must permit. The specified name is added to any previous value for the pathToNames criterion. If the name is a duplicate, it may be ignored.

The name is provided as a byte array. This byte array should contain the DER encoded name, as it would appear in the GeneralName structure defined in RFC 2459 and X.509. The ASN.1 definition of this structure appears in the documentation for {@link #addSubjectAlternativeName(int type, byte [] name) addSubjectAlternativeName(int type, byte [] name)}.

Note that the byte array supplied here is cloned to protect against subsequent modifications.

param
type the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
param
name a byte array containing the name in ASN.1 DER encoded form
throws
IOException if a parsing error occurs

	// clone because byte arrays are modifiable
	addPathToNameInternal(type, name.clone());
    
private voidaddPathToNameInternal(int type, java.lang.Object name)
A private method that adds a name (String or byte array) to the pathToNames criterion. The X509Certificate must contain the specified pathToName.

param
type the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
param
name the name in string or byte array form
throws
IOException if an encoding error occurs (incorrect form for DN)

	// First, ensure that the name parses
	GeneralNameInterface tempName = makeGeneralNameInterface(type, name);
	if (pathToGeneralNames == null) {
	    pathToNames = new HashSet<List<?>>();
	    pathToGeneralNames = new HashSet<GeneralNameInterface>();
	}
	List<Object> list = new ArrayList<Object>(2);
	list.add(Integer.valueOf(type));
	list.add(name);
	pathToNames.add(list);
	pathToGeneralNames.add(tempName);
    
public voidaddSubjectAlternativeName(int type, java.lang.String name)
Adds a name to the subjectAlternativeNames criterion. The X509Certificate must contain all or at least one of the specified subjectAlternativeNames, depending on the value of the matchAllNames flag (see {@link #setMatchAllSubjectAltNames setMatchAllSubjectAltNames}).

This method allows the caller to add a name to the set of subject alternative names. The specified name is added to any previous value for the subjectAlternativeNames criterion. If the specified name is a duplicate, it may be ignored.

The name is provided in string format. RFC 822, DNS, and URI names use the well-established string formats for those types (subject to the restrictions included in RFC 2459). IPv4 address names are supplied using dotted quad notation. OID address names are represented as a series of nonnegative integers separated by periods. And directory names (distinguished names) are supplied in RFC 2253 format. No standard string format is defined for otherNames, X.400 names, EDI party names, IPv6 address names, or any other type of names. They should be specified using the {@link #addSubjectAlternativeName(int type, byte [] name) addSubjectAlternativeName(int type, byte [] name)} method.

Note: for distinguished names, use {@linkplain #addSubjectAlternativeName(int, byte[])} instead. This method should not be relied on as it can fail to match some certificates because of a loss of encoding information in the RFC 2253 String form of some distinguished names.

param
type the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
param
name the name in string form (not null)
throws
IOException if a parsing error occurs

	addSubjectAlternativeNameInternal(type, name);
    
public voidaddSubjectAlternativeName(int type, byte[] name)
Adds a name to the subjectAlternativeNames criterion. The X509Certificate must contain all or at least one of the specified subjectAlternativeNames, depending on the value of the matchAllNames flag (see {@link #setMatchAllSubjectAltNames setMatchAllSubjectAltNames}).

This method allows the caller to add a name to the set of subject alternative names. The specified name is added to any previous value for the subjectAlternativeNames criterion. If the specified name is a duplicate, it may be ignored.

The name is provided as a byte array. This byte array should contain the DER encoded name, as it would appear in the GeneralName structure defined in RFC 2459 and X.509. The encoded byte array should only contain the encoded value of the name, and should not include the tag associated with the name in the GeneralName structure. The ASN.1 definition of this structure appears below.


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}

Note that the byte array supplied here is cloned to protect against subsequent modifications.

param
type the name type (0-8, as listed above)
param
name a byte array containing the name in ASN.1 DER encoded form
throws
IOException if a parsing error occurs

	// clone because byte arrays are modifiable
	addSubjectAlternativeNameInternal(type, name.clone());
    
private voidaddSubjectAlternativeNameInternal(int type, java.lang.Object name)
A private method that adds a name (String or byte array) to the subjectAlternativeNames criterion. The X509Certificate must contain the specified subjectAlternativeName.

param
type the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
param
name the name in string or byte array form
throws
IOException if a parsing error occurs

	// First, ensure that the name parses
	GeneralNameInterface tempName = makeGeneralNameInterface(type, name);
	if (subjectAlternativeNames == null) {
	    subjectAlternativeNames = new HashSet<List<?>>();
	}
	if (subjectAlternativeGeneralNames == null) {
	    subjectAlternativeGeneralNames = new HashSet<GeneralNameInterface>();
	}
	List<Object> list = new ArrayList<Object>(2);
	list.add(Integer.valueOf(type));
	list.add(name);
	subjectAlternativeNames.add(list);
	subjectAlternativeGeneralNames.add(tempName);
    
public java.lang.Objectclone()
Returns a copy of this object.

return
the copy

	try {
	    X509CertSelector copy = (X509CertSelector)super.clone();
	    // Must clone these because addPathToName et al. modify them
	    if (subjectAlternativeNames != null) {
		copy.subjectAlternativeNames = 
			(Set<List<?>>)cloneSet(subjectAlternativeNames);
		copy.subjectAlternativeGeneralNames = 
			(Set<GeneralNameInterface>)cloneSet
				(subjectAlternativeGeneralNames);
	    }
	    if (pathToGeneralNames != null) {
		copy.pathToNames = 
			(Set<List<?>>)cloneSet(pathToNames);
		copy.pathToGeneralNames = 
			(Set<GeneralNameInterface>)cloneSet
				(pathToGeneralNames);
	    }
	    return copy;
	} catch (CloneNotSupportedException e) {
	    /* Cannot happen */
	    throw new InternalError(e.toString());
	}
    
private static java.util.SetcloneAndCheckNames(java.util.Collection names)
Clone and check an argument of the form passed to setSubjectAlternativeNames and setPathToNames. Throw an IOException if the argument is malformed.

param
names a Collection with one entry per name. Each entry is a List whose first entry is an Integer (the name type, 0-8) and whose second entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). There can be multiple names of the same type. null is not an acceptable value.
return
a deep copy of the specified Collection
throws
IOException if a parsing error occurs

	// Copy the Lists and Collection
	Set<List<?>> namesCopy = new HashSet<List<?>>();
	Iterator<List<?>> i = names.iterator();
	while (i.hasNext()) {
	    Object o = i.next();
	    if (!(o instanceof List)) {
		throw new IOException("expected a List");
	    }
	    namesCopy.add(new ArrayList<Object>((List<?>)o));
	}
    
	// Check the contents of the Lists and clone any byte arrays
	i = namesCopy.iterator();
	while (i.hasNext()) {
	    List<Object> nameList = (List<Object>)i.next();
	    if (nameList.size() != 2) {
		throw new IOException("name list size not 2");
	    }
	    Object o = nameList.get(0);
	    if (!(o instanceof Integer)) {
		throw new IOException("expected an Integer");
	    }
	    int nameType = ((Integer) o).intValue();
	    if ((nameType < 0) || (nameType > 8)) {
		throw new IOException("name type not 0-8");
	    }
	    Object nameObject = nameList.get(1);
	    if (!(nameObject instanceof byte[]) &&
		!(nameObject instanceof String)) {
		if (debug != null) {
		    debug.println("X509CertSelector.cloneAndCheckNames() "
		        + "name not byte array");
		}
		throw new IOException("name not byte array or String");
	    }
	    if (nameObject instanceof byte[]) {
		nameList.set(1, ((byte[]) nameObject).clone());
	    }
	}
	return namesCopy;
    
private static java.util.SetcloneNames(java.util.Collection names)
Clone an object of the form passed to setSubjectAlternativeNames and setPathToNames. Throw a RuntimeException if the argument is malformed.

This method wraps cloneAndCheckNames, changing any IOException into a RuntimeException. This method should be used when the object being cloned has already been checked, so there should never be any exceptions.

param
names a Collection with one entry per name. Each entry is a List whose first entry is an Integer (the name type, 0-8) and whose second entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). There can be multiple names of the same type. Null is not an acceptable value.
return
a deep copy of the specified Collection
throws
RuntimeException if a parsing error occurs

	try {
	    return cloneAndCheckNames(names);
	} catch (IOException e) {
	    throw new RuntimeException("cloneNames encountered IOException: " +
				       e.getMessage());
	}
    
private static java.util.SetcloneSet(java.util.Set set)

	if (set instanceof HashSet) {
	    Object clone = ((HashSet<?>)set).clone();
	    return (Set<?>)clone;
	} else {
	    return new HashSet<Object>(set);
	}
    
static booleanequalNames(java.util.Collection object1, java.util.Collection object2)
Compare for equality two objects of the form passed to setSubjectAlternativeNames (or X509CRLSelector.setIssuerNames). Throw an IllegalArgumentException or a ClassCastException if one of the objects is malformed.

param
object1 a Collection containing the first object to compare
param
object2 a Collection containing the second object to compare
return
true if the objects are equal, false otherwise

	if ((object1 == null) || (object2 == null)) {
	    return object1 == object2;
	}
	return object1.equals(object2);
    
public byte[]getAuthorityKeyIdentifier()
Returns the authorityKeyIdentifier criterion. The X509Certificate must contain a AuthorityKeyIdentifier extension with the specified value. If null, no authorityKeyIdentifier check will be done.

Note that the byte array returned is cloned to protect against subsequent modifications.

return
the key identifier (or null)
see
#setAuthorityKeyIdentifier

	if (authorityKeyID == null) {
	  return null;
	}
	return (byte[])authorityKeyID.clone();
    
public intgetBasicConstraints()
Returns the basic constraints constraint. If the value is greater than or equal to zero, the X509Certificates must include a basicConstraints extension with a pathLen of at least this value. If the value is -2, only end-entity certificates are accepted. If the value is -1, no basicConstraints check is done.

return
the value for the basic constraints constraint
see
#setBasicConstraints

	return basicConstraints;
    
public java.security.cert.X509CertificategetCertificate()
Returns the certificateEquals criterion. The specified X509Certificate must be equal to the X509Certificate passed to the match method. If null, this check is not applied.

return
the X509Certificate to match (or null)
see
#setCertificate

	return x509Cert;
    
public java.util.DategetCertificateValid()
Returns the certificateValid criterion. The specified date must fall within the certificate validity period for the X509Certificate. If null, no certificateValid check will be done.

Note that the Date returned is cloned to protect against subsequent modifications.

return
the Date to check (or null)
see
#setCertificateValid

	if (certificateValid == null) {
	    return null;
	}
	return (Date)certificateValid.clone();
    
public java.util.SetgetExtendedKeyUsage()
Returns the extendedKeyUsage criterion. The X509Certificate must allow the specified key purposes in its extended key usage extension. If the keyPurposeSet returned is empty or null, no extendedKeyUsage check will be done. Note that an X509Certificate that has no extendedKeyUsage extension implicitly allows all key purposes.

return
an immutable Set of key purpose OIDs in string format (or null)
see
#setExtendedKeyUsage

	return keyPurposeSet;
    
private static java.security.cert.ExtensiongetExtensionObject(java.security.cert.X509Certificate cert, int extId)
Returns an Extension object given any X509Certificate and extension oid. Throw an IOException if the extension byte value is malformed.

param
cert a X509Certificate
param
extId an integer which specifies the extension index. Currently, the supported extensions are as follows: index 0 - PrivateKeyUsageExtension index 1 - SubjectAlternativeNameExtension index 2 - NameConstraintsExtension index 3 - CertificatePoliciesExtension index 4 - ExtendedKeyUsageExtension
return
an Extension object whose real type is as specified by the extension oid.
throws
IOException if cannot construct the Extension object with the extension encoding retrieved from the passed in X509Certificate.

	if (cert instanceof X509CertImpl) {
	    X509CertImpl impl = (X509CertImpl)cert;
	    switch (extId) {
	    case PRIVATE_KEY_USAGE_ID:
		return impl.getPrivateKeyUsageExtension();
	    case SUBJECT_ALT_NAME_ID:
		return impl.getSubjectAlternativeNameExtension();
	    case NAME_CONSTRAINTS_ID:
		return impl.getNameConstraintsExtension();
	    case CERT_POLICIES_ID:
		return impl.getCertificatePoliciesExtension();
	    case EXTENDED_KEY_USAGE_ID:
		return impl.getExtendedKeyUsageExtension();
	    default:
		return null;
	    }
	}
	byte[] rawExtVal = cert.getExtensionValue(EXTENSION_OIDS[extId]);
	if (rawExtVal == null) {
	    return null;
	}
	DerInputStream in = new DerInputStream(rawExtVal);
	byte[] encoded = in.getOctetString();
	switch (extId) {
	case PRIVATE_KEY_USAGE_ID:
	    try {
		return new PrivateKeyUsageExtension(FALSE, encoded);
	    } catch (CertificateException ex) {
		throw new IOException(ex.getMessage());
	    }
	case SUBJECT_ALT_NAME_ID:
	    return new SubjectAlternativeNameExtension(FALSE, encoded);
	case NAME_CONSTRAINTS_ID:
	    return new NameConstraintsExtension(FALSE, encoded);
	case CERT_POLICIES_ID:
	    return new CertificatePoliciesExtension(FALSE, encoded);
	case EXTENDED_KEY_USAGE_ID:
	    return new ExtendedKeyUsageExtension(FALSE, encoded);
	default:
	    return null;
	}
    
public javax.security.auth.x500.X500PrincipalgetIssuer()
Returns the issuer criterion as an X500Principal. This distinguished name must match the issuer distinguished name in the X509Certificate. If null, the issuer criterion is disabled and any issuer distinguished name will do.

return
the required issuer distinguished name as X500Principal (or null)
since
1.5

	return issuer;
    
public byte[]getIssuerAsBytes()
Returns the issuer criterion as a byte array. This distinguished name must match the issuer distinguished name in the X509Certificate. If null, the issuer criterion is disabled and any issuer distinguished name will do.

If the value returned is not null, it is a byte array containing a single DER encoded distinguished name, as defined in X.501. The ASN.1 notation for this structure is supplied in the documentation for {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.

Note that the byte array returned is cloned to protect against subsequent modifications.

return
a byte array containing the required issuer distinguished name in ASN.1 DER format (or null)
throws
IOException if an encoding error occurs

	return (issuer == null ? null: issuer.getEncoded()); 
    
public java.lang.StringgetIssuerAsString()
Denigrated, use {@linkplain #getIssuer()} or {@linkplain #getIssuerAsBytes()} instead. This method should not be relied on as it can fail to match some certificates because of a loss of encoding information in the RFC 2253 String form of some distinguished names.

Returns the issuer criterion as a String. This distinguished name must match the issuer distinguished name in the X509Certificate. If null, the issuer criterion is disabled and any issuer distinguished name will do.

If the value returned is not null, it is a distinguished name, in RFC 2253 format.

return
the required issuer distinguished name in RFC 2253 format (or null)

	return (issuer == null ? null : issuer.getName());
    
public boolean[]getKeyUsage()
Returns the keyUsage criterion. The X509Certificate must allow the specified keyUsage values. If null, no keyUsage check will be done.

Note that the boolean array returned is cloned to protect against subsequent modifications.

return
a boolean array in the same format as the boolean array returned by {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. Or null.
see
#setKeyUsage

	if (keyUsage == null) {
	    return null;
	}
	return (boolean[])keyUsage.clone();
    
public booleangetMatchAllSubjectAltNames()
Indicates if the X509Certificate must contain all or at least one of the subjectAlternativeNames specified in the {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If true, the X509Certificate must contain all of the specified subject alternative names. If false, the X509Certificate must contain at least one of the specified subject alternative names.

return
true if the flag is enabled; false if the flag is disabled. The flag is true by default.
see
#setMatchAllSubjectAltNames

	return matchAllSubjectAltNames;
    
public byte[]getNameConstraints()
Returns the name constraints criterion. The X509Certificate must have subject and subject alternative names that meet the specified name constraints.

The name constraints are returned as a byte array. This byte array contains the DER encoded form of the name constraints, as they would appear in the NameConstraints structure defined in RFC 2459 and X.509. The ASN.1 notation for this structure is supplied in the documentation for {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.

Note that the byte array returned is cloned to protect against subsequent modifications.

return
a byte array containing the ASN.1 DER encoding of a NameConstraints extension used for checking name constraints. null if no name constraints check will be performed.
see
#setNameConstraints

	if (ncBytes == null) {
	    return null;
	} else {
	    return (byte[]) ncBytes.clone();
	}
    
public java.util.CollectiongetPathToNames()
Returns a copy of the pathToNames criterion. The X509Certificate must not include name constraints that would prohibit building a path to the specified names. If the value returned is null, no pathToNames check will be performed.

If the value returned is not null, it is a Collection with one entry for each name to be included in the pathToNames criterion. Each entry is a List whose first entry is an Integer (the name type, 0-8) and whose second entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). There can be multiple names of the same type. Note that the Collection returned may contain duplicate names (same name and name type).

Each name in the Collection may be specified either as a String or as an ASN.1 encoded byte array. For more details about the formats used, see {@link #addPathToName(int type, String name) addPathToName(int type, String name)} and {@link #addPathToName(int type, byte [] name) addPathToName(int type, byte [] name)}.

Note that a deep copy is performed on the Collection to protect against subsequent modifications.

return
a Collection of names (or null)
see
#setPathToNames

	if (pathToNames == null) {
	    return null;
	}
	return cloneNames(pathToNames);
    
public java.util.SetgetPolicy()
Returns the policy criterion. The X509Certificate must include at least one of the specified policies in its certificate policies extension. If the Set returned is empty, then the X509Certificate must include at least some specified policy in its certificate policies extension. If the Set returned is null, no policy check will be performed.

return
an immutable Set of certificate policy OIDs in string format (or null)
see
#setPolicy

	return policySet;
    
public java.util.DategetPrivateKeyValid()
Returns the privateKeyValid criterion. The specified date must fall within the private key validity period for the X509Certificate. If null, no privateKeyValid check will be done.

Note that the Date returned is cloned to protect against subsequent modifications.

return
the Date to check (or null)
see
#setPrivateKeyValid

	if (privateKeyValid == null) {
	    return null;
	}
	return (Date)privateKeyValid.clone();
    
public java.math.BigIntegergetSerialNumber()
Returns the serialNumber criterion. The specified serial number must match the certificate serial number in the X509Certificate. If null, any certificate serial number will do.

return
the certificate serial number to match (or null)
see
#setSerialNumber

	return serialNumber;
    
public javax.security.auth.x500.X500PrincipalgetSubject()
Returns the subject criterion as an X500Principal. This distinguished name must match the subject distinguished name in the X509Certificate. If null, the subject criterion is disabled and any subject distinguished name will do.

return
the required subject distinguished name as X500Principal (or null)
since
1.5

	return subject;
    
public java.util.CollectiongetSubjectAlternativeNames()
Returns a copy of the subjectAlternativeNames criterion. The X509Certificate must contain all or at least one of the specified subjectAlternativeNames, depending on the value of the matchAllNames flag (see {@link #getMatchAllSubjectAltNames getMatchAllSubjectAltNames}). If the value returned is null, no subjectAlternativeNames check will be performed.

If the value returned is not null, it is a Collection with one entry for each name to be included in the subject alternative name criterion. Each entry is a List whose first entry is an Integer (the name type, 0-8) and whose second entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). There can be multiple names of the same type. Note that the Collection returned may contain duplicate names (same name and name type).

Each subject alternative name in the Collection may be specified either as a String or as an ASN.1 encoded byte array. For more details about the formats used, see {@link #addSubjectAlternativeName(int type, String name) addSubjectAlternativeName(int type, String name)} and {@link #addSubjectAlternativeName(int type, byte [] name) addSubjectAlternativeName(int type, byte [] name)}.

Note that a deep copy is performed on the Collection to protect against subsequent modifications.

return
a Collection of names (or null)
see
#setSubjectAlternativeNames

	if (subjectAlternativeNames == null) {
	    return null;
	}
	return cloneNames(subjectAlternativeNames);
    
public byte[]getSubjectAsBytes()
Returns the subject criterion as a byte array. This distinguished name must match the subject distinguished name in the X509Certificate. If null, the subject criterion is disabled and any subject distinguished name will do.

If the value returned is not null, it is a byte array containing a single DER encoded distinguished name, as defined in X.501. The ASN.1 notation for this structure is supplied in the documentation for {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.

Note that the byte array returned is cloned to protect against subsequent modifications.

return
a byte array containing the required subject distinguished name in ASN.1 DER format (or null)
throws
IOException if an encoding error occurs

	return (subject == null ? null : subject.getEncoded());
    
public java.lang.StringgetSubjectAsString()
Denigrated, use {@linkplain #getSubject()} or {@linkplain #getSubjectAsBytes()} instead. This method should not be relied on as it can fail to match some certificates because of a loss of encoding information in the RFC 2253 String form of some distinguished names.

Returns the subject criterion as a String. This distinguished name must match the subject distinguished name in the X509Certificate. If null, the subject criterion is disabled and any subject distinguished name will do.

If the value returned is not null, it is a distinguished name, in RFC 2253 format.

return
the required subject distinguished name in RFC 2253 format (or null)

	return (subject == null ? null : subject.getName());
    
public byte[]getSubjectKeyIdentifier()
Returns the subjectKeyIdentifier criterion. The X509Certificate must contain a SubjectKeyIdentifier extension with the specified value. If null, no subjectKeyIdentifier check will be done.

Note that the byte array returned is cloned to protect against subsequent modifications.

return
the key identifier (or null)
see
#setSubjectKeyIdentifier

	if (subjectKeyID == null) {
	    return null;
	}
	return (byte[])subjectKeyID.clone();
    
public java.security.PublicKeygetSubjectPublicKey()
Returns the subjectPublicKey criterion. The X509Certificate must contain the specified subject public key. If null, no subjectPublicKey check will be done.

return
the subject public key to check for (or null)
see
#setSubjectPublicKey

	return subjectPublicKey;
    
public java.lang.StringgetSubjectPublicKeyAlgID()
Returns the subjectPublicKeyAlgID criterion. The X509Certificate must contain a subject public key with the specified algorithm. If null, no subjectPublicKeyAlgID check will be done.

return
the object identifier (OID) of the signature algorithm to check for (or null). An OID is represented by a set of nonnegative integers separated by periods.
see
#setSubjectPublicKeyAlgID

	if (subjectPublicKeyAlgID == null) {
	    return null;
	}
	return subjectPublicKeyAlgID.toString();
    
private static java.lang.StringkeyUsageToString(boolean[] k)
Returns a printable representation of the KeyUsage.

	String s = "KeyUsage [\n";
	try {
	    if (k[0]) {
		s += "  DigitalSignature\n";
	    }
	    if (k[1]) {
		s += "  Non_repudiation\n";
	    }
	    if (k[2]) {
		s += "  Key_Encipherment\n";
	    }
	    if (k[3]) {
		s += "  Data_Encipherment\n";
	    }
	    if (k[4]) {
		s += "  Key_Agreement\n";
	    }
	    if (k[5]) {
		s += "  Key_CertSign\n";
	    }
	    if (k[6]) {
		s += "  Crl_Sign\n";
	    }
	    if (k[7]) {
		s += "  Encipher_Only\n";
	    }
	    if (k[8]) {
		s += "  Decipher_Only\n";
	    }
	} catch (ArrayIndexOutOfBoundsException ex) {}
    
	s += "]\n";
    
	return (s);
    
static sun.security.x509.GeneralNameInterfacemakeGeneralNameInterface(int type, java.lang.Object name)
Make a GeneralNameInterface out of a name type (0-8) and an Object that may be a byte array holding the ASN.1 DER encoded name or a String form of the name. Except for X.509 Distinguished Names, the String form of the name must not be the result from calling toString on an existing GeneralNameInterface implementing class. The output of toString is not compatible with the String constructors for names other than Distinguished Names.

param
type name type (0-8)
param
name name as ASN.1 Der-encoded byte array or String
return
a GeneralNameInterface name
throws
IOException if a parsing error occurs

	GeneralNameInterface result;
	if (debug != null) {
	    debug.println("X509CertSelector.makeGeneralNameInterface("
	        + type + ")...");
	}
  
	if (name instanceof String) {
	    if (debug != null) {
		debug.println("X509CertSelector.makeGeneralNameInterface() "
		    + "name is String: " + name);
	    }
	    switch (type) {
	    case NAME_RFC822:
		result = new RFC822Name((String)name);
		break;
	    case NAME_DNS:
		result = new DNSName((String)name);
		break;
	    case NAME_DIRECTORY:
		result = new X500Name((String)name);
		break;
	    case NAME_URI:
		result = new URIName((String)name);
		break;
	    case NAME_IP:
		result = new IPAddressName((String)name);
		break;
	    case NAME_OID:
		result = new OIDName((String)name);
		break;
	    default:
		throw new IOException("unable to parse String names of type "
				      + type);
	    }
	    if (debug != null) {
		debug.println("X509CertSelector.makeGeneralNameInterface() "
		    + "result: " + result.toString());
	    }
	} else if (name instanceof byte[]) {
	    DerValue val = new DerValue((byte[]) name);
	    if (debug != null) {
		debug.println
		    ("X509CertSelector.makeGeneralNameInterface() is byte[]");
	    }
    
	    switch (type) {
	    case NAME_ANY:
		result = new OtherName(val);
		break;
	    case NAME_RFC822:
		result = new RFC822Name(val);
		break;
	    case NAME_DNS:
		result = new DNSName(val);
		break;
	    case NAME_X400:
		result = new X400Address(val);
		break;
	    case NAME_DIRECTORY:
		result = new X500Name(val);
		break;
	    case NAME_EDI:
		result = new EDIPartyName(val);
		break;
	    case NAME_URI:
		result = new URIName(val);
		break;
	    case NAME_IP:
		result = new IPAddressName(val);
		break;
	    case NAME_OID:
		result = new OIDName(val);
		break;
	    default:
		throw new IOException("unable to parse byte array names of "
		    + "type " + type);
	    }
	    if (debug != null) {
		debug.println("X509CertSelector.makeGeneralNameInterface() result: "
		    + result.toString());
	    }
	} else {
	    if (debug != null) {
		debug.println("X509CertSelector.makeGeneralName() input name "
		    + "not String or byte array");
	    }
	    throw new IOException("name not String or byte array");
	}
	return result;
    
public booleanmatch(java.security.cert.Certificate cert)
Decides whether a Certificate should be selected.

param
cert the Certificate to be checked
return
true if the Certificate should be selected, false otherwise

	if (!(cert instanceof X509Certificate)) {
	    return false;
	}
	X509Certificate xcert = (X509Certificate)cert;
    
	if (debug != null) {
	    debug.println("X509CertSelector.match(SN: " 
		+ (xcert.getSerialNumber()).toString(16) + "\n  Issuer: " 
		+ xcert.getIssuerDN() + "\n  Subject: " + xcert.getSubjectDN() 
		+ ")");
	}
    
	/* match on X509Certificate */
	if (x509Cert != null) {
	    if (!x509Cert.equals(xcert)) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "certs don't match");
		}
		return false;
	    }
	}
	
	/* match on serial number */
	if (serialNumber != null) {
	    if (!serialNumber.equals(xcert.getSerialNumber())) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "serial numbers don't match");
		}
		return false;
	    }
	}
    
	/* match on issuer name */
	if (issuer != null) {
	    if (!issuer.equals(xcert.getIssuerX500Principal())) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "issuer DNs don't match");
		}
		return false;
	    }
	}
    
	/* match on subject name */
	if (subject != null) {
	    if (!subject.equals(xcert.getSubjectX500Principal())) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "subject DNs don't match");
		}
		return false;
	    }
	}
    
	/* match on certificate validity range */
	if (certificateValid != null) {
	    try {
		xcert.checkValidity(certificateValid);
	    } catch (CertificateException e) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "certificate not within validity period");
		}
		return false;
	    }
	}
    
	/* match on subject public key */
	if (subjectPublicKeyBytes != null) {
	    byte[] certKey = xcert.getPublicKey().getEncoded();
	    if (!Arrays.equals(subjectPublicKeyBytes, certKey)) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "subject public keys don't match");
		}
		return false;
	    }
	}
	
	boolean result = matchBasicConstraints(xcert)
		      && matchKeyUsage(xcert)
		      && matchExtendedKeyUsage(xcert)
		      && matchSubjectKeyID(xcert)
		      && matchAuthorityKeyID(xcert)
		      && matchPrivateKeyValid(xcert)
		      && matchSubjectPublicKeyAlgID(xcert)
		      && matchPolicy(xcert)
		      && matchSubjectAlternativeNames(xcert)
		      && matchPathToNames(xcert)
		      && matchNameConstraints(xcert);
    
	if (result && (debug != null)) {
	    debug.println("X509CertSelector.match returning: true");
	}
	return result;
    
private booleanmatchAuthorityKeyID(java.security.cert.X509Certificate xcert)

	if (authorityKeyID == null) {
	    return true;
	}
	try {
	    byte[] extVal = xcert.getExtensionValue("2.5.29.35");
	    if (extVal == null) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "no authority key ID extension");
		}
		return false;
	    }
	    DerInputStream in = new DerInputStream(extVal);
	    byte[] certAuthKeyID = in.getOctetString();
	    if (certAuthKeyID == null || 
	    	    !Arrays.equals(authorityKeyID, certAuthKeyID)) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "authority key IDs don't match");
		}
		return false;
	    }
	} catch (IOException ex) {
	    if (debug != null) {
		debug.println("X509CertSelector.match: "
		    + "exception in authority key ID check");
	    }
	    return false;
	}
	return true;
    
private booleanmatchBasicConstraints(java.security.cert.X509Certificate xcert)

	if (basicConstraints == -1) {
	    return true;
	}
	int maxPathLen = xcert.getBasicConstraints();
	if (basicConstraints == -2) {
	    if (maxPathLen != -1) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: not an EE cert");
		}
		return false;
	    }
	} else {
	    if (maxPathLen < basicConstraints) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: maxPathLen too small (" 
			+ maxPathLen + " < " + basicConstraints + ")"); 
		}
		return false;
	    }
	}
	return true;
    
private booleanmatchExcluded(sun.security.x509.GeneralSubtrees excluded)

	/* 
	 * Enumerate through excluded and compare each entry
	 * to all pathToNames. If any pathToName is within any of the
	 * subtrees listed in excluded, return false.
	 */
	for (Iterator t = excluded.iterator(); t.hasNext(); ) {
	    GeneralSubtree tree = (GeneralSubtree)t.next();
	    GeneralNameInterface excludedName = tree.getName().getName();
	    Iterator i = pathToGeneralNames.iterator();
	    while (i.hasNext()) {
		GeneralNameInterface pathToName = (GeneralNameInterface) i.next();
		if (excludedName.getType() == pathToName.getType()) {
		    switch (pathToName.constrains(excludedName)) {
		    case GeneralNameInterface.NAME_WIDENS:
		    case GeneralNameInterface.NAME_MATCH:
			if (debug != null) {
			    debug.println("X509CertSelector.match: name constraints "
				+ "inhibit path to specified name");
			    debug.println("X509CertSelector.match: excluded name: " +
				pathToName);
			}
			return false;
		    default:
		    }
		}
	    }
	}
	return true;
    
private booleanmatchExtendedKeyUsage(java.security.cert.X509Certificate xcert)

	if ((keyPurposeSet == null) || keyPurposeSet.isEmpty()) {
	    return true;
	}
	try {
	    ExtendedKeyUsageExtension ext = 
		(ExtendedKeyUsageExtension)getExtensionObject(xcert, 
						EXTENDED_KEY_USAGE_ID);
	    if (ext != null) {
		Vector<ObjectIdentifier> certKeyPurposeVector = 
		    (Vector<ObjectIdentifier>)ext.get(ExtendedKeyUsageExtension.USAGES);
		if (!certKeyPurposeVector.contains(ANY_EXTENDED_KEY_USAGE) 
		        && !certKeyPurposeVector.containsAll(keyPurposeOIDSet)) {
		    if (debug != null) {
			debug.println("X509CertSelector.match: cert failed "
			    + "extendedKeyUsage criterion");
		    }
		    return false;
		}
	    }
	} catch (IOException ex) {
	    if (debug != null) {
		debug.println("X509CertSelector.match: "
		    + "IOException in extended key usage check");
	    }
	    return false;
	}
	return true;
    
private booleanmatchKeyUsage(java.security.cert.X509Certificate xcert)

	if (keyUsage == null) {
	    return true;
	}
	boolean[] certKeyUsage = xcert.getKeyUsage();
	if (certKeyUsage != null) {
	    for (int keyBit = 0; keyBit < keyUsage.length; keyBit++) {
		if (keyUsage[keyBit] &&
		    ((keyBit >= certKeyUsage.length) || !certKeyUsage[keyBit])) {
		    if (debug != null) {
			debug.println("X509CertSelector.match: "
			    + "key usage bits don't match");
		    }
		    return false;
		}
	    }
	}
	return true;
    
private booleanmatchNameConstraints(java.security.cert.X509Certificate xcert)

	if (nc == null) {
	    return true;
	}
	try {
	    if (!nc.verify(xcert)) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		        + "name constraints not satisfied");
		}
		return false;
	    }
	} catch (IOException e) { 
	    if (debug != null) {
		debug.println("X509CertSelector.match: "
		    + "IOException in name constraints check");
	    }
	    return false; 
	}
	return true;
    
private booleanmatchPathToNames(java.security.cert.X509Certificate xcert)

	if (pathToGeneralNames == null) {
	    return true;
	}
	try {
	    NameConstraintsExtension ext = (NameConstraintsExtension)
	    	getExtensionObject(xcert, NAME_CONSTRAINTS_ID);
	    if (ext == null) {
		return true;
	    }
	    if ((debug != null) && debug.isOn("certpath")) {
		debug.println("X509CertSelector.match pathToNames:\n");
		Iterator i = pathToGeneralNames.iterator();
		while (i.hasNext()) {
		    debug.println("    " + i.next() + "\n");
		}
	    }
    
	    GeneralSubtrees permitted = (GeneralSubtrees)
		ext.get(NameConstraintsExtension.PERMITTED_SUBTREES);
	    GeneralSubtrees excluded = (GeneralSubtrees)
		ext.get(NameConstraintsExtension.EXCLUDED_SUBTREES);
	    if (excluded != null) {
		if (matchExcluded(excluded) == false) {
		    return false;
		}
	    }
	    if (permitted != null) {
		if (matchPermitted(permitted) == false) {
		    return false;
		}
	    }
	} catch (IOException ex) {
	    if (debug != null) {
		debug.println("X509CertSelector.match: "
		    + "IOException in name constraints check");
	    }
	    return false;
	}
	return true;
    
private booleanmatchPermitted(sun.security.x509.GeneralSubtrees permitted)

	/*
	 * Enumerate through pathToNames, checking that each pathToName
	 * is in at least one of the subtrees listed in permitted.
	 * If not, return false. However, if no subtrees of a given type
	 * are listed, all names of that type are permitted.
	 */
	Iterator i = pathToGeneralNames.iterator();
	while (i.hasNext()) {
	    GeneralNameInterface pathToName = (GeneralNameInterface)i.next();
	    Iterator t = permitted.iterator();
	    boolean permittedNameFound = false;
	    boolean nameTypeFound = false;
	    String names = "";
	    while (t.hasNext() && !permittedNameFound) {
		GeneralSubtree tree = (GeneralSubtree)t.next();
		GeneralNameInterface permittedName = tree.getName().getName();
		if (permittedName.getType() == pathToName.getType()) {
		    nameTypeFound = true;
		    names = names + "  " + permittedName;
		    switch (pathToName.constrains(permittedName)) {
		    case GeneralNameInterface.NAME_WIDENS:
		    case GeneralNameInterface.NAME_MATCH:
			permittedNameFound = true;
			break;
		    default:
		    }
		}
	    }
	    if (!permittedNameFound && nameTypeFound) {
		if (debug != null)
		  debug.println("X509CertSelector.match: " + 
			    "name constraints inhibit path to specified name; " +
			    "permitted names of type " + pathToName.getType() +
			    ": " + names);
		return false;
	    }
	}
	return true;
    
private booleanmatchPolicy(java.security.cert.X509Certificate xcert)

	if (policy == null) {
	    return true;
	}
	try {
	    CertificatePoliciesExtension ext = (CertificatePoliciesExtension)
	    	getExtensionObject(xcert, CERT_POLICIES_ID);
	    if (ext == null) {
		if (debug != null) {
		  debug.println("X509CertSelector.match: "
		      + "no certificate policy extension");
		}
		return false;
	    }
	    List<PolicyInformation> policies = (List<PolicyInformation>)ext.get(CertificatePoliciesExtension.POLICIES);
	    /*
	     * Convert the Vector of PolicyInformation to a Vector 
	     * of CertificatePolicyIds for easier comparison.
	     */
	    List<CertificatePolicyId> policyIDs = new ArrayList<CertificatePolicyId>(policies.size());
	    for (PolicyInformation info : policies) {
		policyIDs.add(info.getPolicyIdentifier());
	    }
	    if (policy != null) {
		boolean foundOne = false;
		/*
		 * if the user passes in an empty policy Set, then
		 * we just want to make sure that the candidate certificate
		 * has some policy OID in its CertPoliciesExtension
		 */
		if (policy.getCertPolicyIds().isEmpty()) {
		    if (policyIDs.isEmpty()) {
			if (debug != null) {
			    debug.println("X509CertSelector.match: "
			        + "cert failed policyAny criterion");
			}
			return false;
		    }
		} else {
		    for (CertificatePolicyId id : policy.getCertPolicyIds()) {
			if (policyIDs.contains(id)) {
			    foundOne = true;
			    break;
			}
		    }
		    if (!foundOne) {
			if (debug != null) {
			    debug.println("X509CertSelector.match: "
			        + "cert failed policyAny criterion");
			}
			return false;
		    }
		}
	    }
	} catch (IOException ex) {
	    if (debug != null) {
	        debug.println("X509CertSelector.match: "
		    + "IOException in certificate policy ID check");
	    }
	    return false;
	}
	return true;
    
private booleanmatchPrivateKeyValid(java.security.cert.X509Certificate xcert)

	if (privateKeyValid == null) {
	    return true;
	}
	PrivateKeyUsageExtension ext = null;
	try {
	    ext = (PrivateKeyUsageExtension) 
		getExtensionObject(xcert, PRIVATE_KEY_USAGE_ID);
	    if (ext != null) {
	        ext.valid(privateKeyValid);
	    }
	} catch (CertificateExpiredException e1) {
	    if (debug != null) {
	        String time = "n/a";
		try {
		    Date notAfter = 
		    	(Date)ext.get(PrivateKeyUsageExtension.NOT_AFTER);
		    time = notAfter.toString();
		} catch (CertificateException ex) {
		    // not able to retrieve notAfter value
		}
		debug.println("X509CertSelector.match: private key usage not "
		    + "within validity date; ext.NOT_After: " 
		    + time + "; X509CertSelector: " 
		    + this.toString());
		e1.printStackTrace();
	    }
	    return false;
	} catch (CertificateNotYetValidException e2) {
	    if (debug != null) {
		String time = "n/a";
		try {
		    Date notBefore = (Date) 
			ext.get(PrivateKeyUsageExtension.NOT_BEFORE);
		    time = notBefore.toString();
		} catch (CertificateException ex) {
		    // not able to retrieve notBefore value
		}
		debug.println("X509CertSelector.match: private key usage not "
		    + "within validity date; ext.NOT_BEFORE: " 
		    + time + "; X509CertSelector: " 
		    + this.toString());
		e2.printStackTrace();
	    }
	    return false;
	} catch (CertificateException e3) {
	    if (debug != null) {
	        debug.println("X509CertSelector.match: CertificateException "
		    + "in private key usage check; X509CertSelector: " 
		    + this.toString());
	        e3.printStackTrace();
	    }
	    return false;
	} catch (IOException e4) {
	    if (debug != null) {
	        debug.println("X509CertSelector.match: IOException in "
		    + "private key usage check; X509CertSelector: " 
		    + this.toString());
	        e4.printStackTrace();
	    }
	    return false;
	}
	return true;
    
private booleanmatchSubjectAlternativeNames(java.security.cert.X509Certificate xcert)

	if ((subjectAlternativeNames == null) || subjectAlternativeNames.isEmpty()) {
	    return true;
	}
	try {
	    SubjectAlternativeNameExtension sanExt = 
		(SubjectAlternativeNameExtension) getExtensionObject(xcert, 
						      SUBJECT_ALT_NAME_ID); 
	    if (sanExt == null) {
		if (debug != null) {
		  debug.println("X509CertSelector.match: "
		      + "no subject alternative name extension");
		}
		return false;
	    }
	    GeneralNames certNames = (GeneralNames) 
		sanExt.get(SubjectAlternativeNameExtension.SUBJECT_NAME);
	    Iterator i = subjectAlternativeGeneralNames.iterator();
	    while (i.hasNext()) {
		GeneralNameInterface matchName = (GeneralNameInterface) i.next();
		boolean found = false;
		for (Iterator t = certNames.iterator(); t.hasNext() && !found; ) {
		    GeneralNameInterface certName =
			((GeneralName)t.next()).getName();
		    found = certName.equals(matchName);
		}
		if (!found && (matchAllSubjectAltNames || !i.hasNext())) {
		    if (debug != null) {
		      debug.println("X509CertSelector.match: subject alternative "
			  + "name " + matchName + " not found"); 
		    }
		    return false;
		} else if (found && !matchAllSubjectAltNames) {
		    break;
		}
	    }
	} catch (IOException ex) {
	    if (debug != null)
		debug.println("X509CertSelector.match: IOException in subject "
		    + "alternative name check");
	    return false;
	}
	return true;
    
private booleanmatchSubjectKeyID(java.security.cert.X509Certificate xcert)

	if (subjectKeyID == null) {
	    return true;
	}
	try {
	    byte[] extVal = xcert.getExtensionValue("2.5.29.14");
	    if (extVal == null) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "no subject key ID extension");
		}
		return false;
	    }
	    DerInputStream in = new DerInputStream(extVal);
	    byte[] certSubjectKeyID = in.getOctetString();
	    if (certSubjectKeyID == null || 
	            !Arrays.equals(subjectKeyID, certSubjectKeyID)) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "subject key IDs don't match");
		}
		return false;
	    }
	} catch (IOException ex) {
	    if (debug != null) {
		debug.println("X509CertSelector.match: "
		    + "exception in subject key ID check");
	    }
	    return false;
	}
	return true;
    
private booleanmatchSubjectPublicKeyAlgID(java.security.cert.X509Certificate xcert)

	if (subjectPublicKeyAlgID == null) {
	    return true;
	}
	try {
	    byte[] encodedKey = xcert.getPublicKey().getEncoded();
	    DerValue val = new DerValue(encodedKey);
	    if (val.tag != DerValue.tag_Sequence) {
		throw new IOException("invalid key format");
	    }
  
	    AlgorithmId algID = AlgorithmId.parse(val.data.getDerValue());
	    if (debug != null) {
		debug.println("X509CertSelector.match: subjectPublicKeyAlgID = " 
		    + subjectPublicKeyAlgID + ", xcert subjectPublicKeyAlgID = " 
		    + algID.getOID()); 
	    }
	    if (!subjectPublicKeyAlgID.equals(algID.getOID())) {
		if (debug != null) {
		    debug.println("X509CertSelector.match: "
		    	+ "subject public key alg IDs don't match");
		}
		return false;
	    }
	} catch (IOException e5) {
	    if (debug != null) {
		debug.println("X509CertSelector.match: IOException in subject "
		    + "public key algorithm OID check");
	    }
	    return false;
	}
	return true;
    
private static java.util.SetparseNames(java.util.Collection names)
Parse an argument of the form passed to setSubjectAlternativeNames, returning a Collection of GeneralNameInterfaces. Throw an IllegalArgumentException or a ClassCastException if the argument is malformed.

param
names a Collection with one entry per name. Each entry is a List whose first entry is an Integer (the name type, 0-8) and whose second entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). There can be multiple names of the same type. Null is not an acceptable value.
return
a Set of GeneralNameInterfaces
throws
IOException if a parsing error occurs

	Set<GeneralNameInterface> genNames = new HashSet<GeneralNameInterface>();
	Iterator<List<?>> i = names.iterator();
	while (i.hasNext()) {
	    Object o = i.next();
	    if (!(o instanceof List)) {
		throw new IOException("expected List");
	    }
	    List<Object> nameList = (List<Object>)o;
	    if (nameList.size() != 2) {
		throw new IOException("name list size not 2");
	    }
	    o =  nameList.get(0);
	    if (!(o instanceof Integer)) {
		throw new IOException("expected an Integer");
	    }
	    int nameType = ((Integer)o).intValue();
	    o = nameList.get(1);
	    genNames.add(makeGeneralNameInterface(nameType, o));
	}
	return genNames;
    
public voidsetAuthorityKeyIdentifier(byte[] authorityKeyID)
Sets the authorityKeyIdentifier criterion. The X509Certificate must contain an AuthorityKeyIdentifier extension for which the contents of the extension value matches the specified criterion value. If the criterion value is null, no authorityKeyIdentifier check will be done.

If authorityKeyID is not null, it should contain a single DER encoded value corresponding to the contents of the extension value (not including the object identifier, criticality setting, and encapsulating OCTET STRING) for an AuthorityKeyIdentifier extension. The ASN.1 notation for this structure follows.


AuthorityKeyIdentifier ::= SEQUENCE {
keyIdentifier [0] KeyIdentifier OPTIONAL,
authorityCertIssuer [1] GeneralNames OPTIONAL,
authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }

KeyIdentifier ::= OCTET STRING

Authority key identifiers are not parsed by the X509CertSelector. Instead, the values are compared using a byte-by-byte comparison.

When the keyIdentifier field of AuthorityKeyIdentifier is populated, the value is usually taken from the SubjectKeyIdentifier extension in the issuer's certificate. Note, however, that the result of X509Certificate.getExtensionValue(<SubjectKeyIdentifier Object Identifier>) on the issuer's certificate may NOT be used directly as the input to setAuthorityKeyIdentifier. This is because the SubjectKeyIdentifier contains only a KeyIdentifier OCTET STRING, and not a SEQUENCE of KeyIdentifier, GeneralNames, and CertificateSerialNumber. In order to use the extension value of the issuer certificate's SubjectKeyIdentifier extension, it will be necessary to extract the value of the embedded KeyIdentifier OCTET STRING, then DER encode this OCTET STRING inside a SEQUENCE. For more details on SubjectKeyIdentifier, see {@link #setSubjectKeyIdentifier(byte[] subjectKeyID)}.

Note also that the byte array supplied here is cloned to protect against subsequent modifications.

param
authorityKeyID the authority key identifier (or null)
see
#getAuthorityKeyIdentifier

	if (authorityKeyID == null) {
	    this.authorityKeyID = null;
	} else {
	    this.authorityKeyID = (byte[])authorityKeyID.clone();
	}
    
public voidsetBasicConstraints(int minMaxPathLen)
Sets the basic constraints constraint. If the value is greater than or equal to zero, X509Certificates must include a basicConstraints extension with a pathLen of at least this value. If the value is -2, only end-entity certificates are accepted. If the value is -1, no check is done.

This constraint is useful when building a certification path forward (from the target toward the trust anchor. If a partial path has been built, any candidate certificate must have a maxPathLen value greater than or equal to the number of certificates in the partial path.

param
minMaxPathLen the value for the basic constraints constraint
throws
IllegalArgumentException if the value is less than -2
see
#getBasicConstraints

	if (minMaxPathLen < -2) {
	    throw new IllegalArgumentException("basic constraints less than -2");
	}
	basicConstraints = minMaxPathLen;
    
public voidsetCertificate(java.security.cert.X509Certificate cert)
Sets the certificateEquals criterion. The specified X509Certificate must be equal to the X509Certificate passed to the match method. If null, then this check is not applied.

This method is particularly useful when it is necessary to match a single certificate. Although other criteria can be specified in conjunction with the certificateEquals criterion, it is usually not practical or necessary.

param
cert the X509Certificate to match (or null)
see
#getCertificate

	x509Cert = cert;
    
public voidsetCertificateValid(java.util.Date certValid)
Sets the certificateValid criterion. The specified date must fall within the certificate validity period for the X509Certificate. If null, no certificateValid check will be done.

Note that the Date supplied here is cloned to protect against subsequent modifications.

param
certValid the Date to check (or null)
see
#getCertificateValid

	if (certValid == null) {
	    certificateValid = null;
	} else {
	    certificateValid = (Date)certValid.clone();
	}
    
public voidsetExtendedKeyUsage(java.util.Set keyPurposeSet)
Sets the extendedKeyUsage criterion. The X509Certificate must allow the specified key purposes in its extended key usage extension. If keyPurposeSet is empty or null, no extendedKeyUsage check will be done. Note that an X509Certificate that has no extendedKeyUsage extension implicitly allows all key purposes.

Note that the Set is cloned to protect against subsequent modifications.

param
keyPurposeSet a Set of key purpose OIDs in string format (or null). Each OID is represented by a set of nonnegative integers separated by periods.
throws
IOException if the OID is invalid, such as the first component being not 0, 1 or 2 or the second component being greater than 39.
see
#getExtendedKeyUsage

	if ((keyPurposeSet == null) || keyPurposeSet.isEmpty()) {
	    this.keyPurposeSet = null;
	    keyPurposeOIDSet = null;
	} else {
	    this.keyPurposeSet = 
		Collections.unmodifiableSet(new HashSet<String>(keyPurposeSet));
	    keyPurposeOIDSet = new HashSet<ObjectIdentifier>();
	    for (String s : this.keyPurposeSet) {
		keyPurposeOIDSet.add(new ObjectIdentifier(s));
	    }
	}
    
public voidsetIssuer(javax.security.auth.x500.X500Principal issuer)
Sets the issuer criterion. The specified distinguished name must match the issuer distinguished name in the X509Certificate. If null, any issuer distinguished name will do.

param
issuer a distinguished name as X500Principal (or null)
since
1.5

	this.issuer = issuer;
    
public voidsetIssuer(java.lang.String issuerDN)
Denigrated, use {@linkplain #setIssuer(X500Principal)} or {@linkplain #setIssuer(byte[])} instead. This method should not be relied on as it can fail to match some certificates because of a loss of encoding information in the RFC 2253 String form of some distinguished names.

Sets the issuer criterion. The specified distinguished name must match the issuer distinguished name in the X509Certificate. If null, any issuer distinguished name will do.

If issuerDN is not null, it should contain a distinguished name, in RFC 2253 format.

param
issuerDN a distinguished name in RFC 2253 format (or null)
throws
IOException if a parsing error occurs (incorrect form for DN)

	if (issuerDN == null) {
	    issuer = null;
	} else {
	    issuer = new X500Name(issuerDN).asX500Principal();
	}
    
public voidsetIssuer(byte[] issuerDN)
Sets the issuer criterion. The specified distinguished name must match the issuer distinguished name in the X509Certificate. If null is specified, the issuer criterion is disabled and any issuer distinguished name will do.

If issuerDN is not null, it should contain a single DER encoded distinguished name, as defined in X.501. The ASN.1 notation for this structure is as follows.


Name ::= CHOICE {
RDNSequence }

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::=
SET SIZE (1 .. MAX) OF AttributeTypeAndValue

AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue }

AttributeType ::= OBJECT IDENTIFIER

AttributeValue ::= ANY DEFINED BY AttributeType
....
DirectoryString ::= CHOICE {
teletexString TeletexString (SIZE (1..MAX)),
printableString PrintableString (SIZE (1..MAX)),
universalString UniversalString (SIZE (1..MAX)),
utf8String UTF8String (SIZE (1.. MAX)),
bmpString BMPString (SIZE (1..MAX)) }

Note that the byte array specified here is cloned to protect against subsequent modifications.

param
issuerDN a byte array containing the distinguished name in ASN.1 DER encoded form (or null)
throws
IOException if an encoding error occurs (incorrect form for DN)

	try {
	    issuer = (issuerDN == null ? null : new X500Principal(issuerDN));
	} catch (IllegalArgumentException e) {
	    throw (IOException)new IOException("Invalid name").initCause(e);
	}
    
public voidsetKeyUsage(boolean[] keyUsage)
Sets the keyUsage criterion. The X509Certificate must allow the specified keyUsage values. If null, no keyUsage check will be done. Note that an X509Certificate that has no keyUsage extension implicitly allows all keyUsage values.

Note that the boolean array supplied here is cloned to protect against subsequent modifications.

param
keyUsage a boolean array in the same format as the boolean array returned by {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. Or null.
see
#getKeyUsage

	if (keyUsage == null) {
	    this.keyUsage = null;
	} else {
	    this.keyUsage = (boolean[])keyUsage.clone();
	}
    
public voidsetMatchAllSubjectAltNames(boolean matchAllNames)
Enables/disables matching all of the subjectAlternativeNames specified in the {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If enabled, the X509Certificate must contain all of the specified subject alternative names. If disabled, the X509Certificate must contain at least one of the specified subject alternative names.

The matchAllNames flag is true by default.

param
matchAllNames if true, the flag is enabled; if false, the flag is disabled.
see
#getMatchAllSubjectAltNames

	this.matchAllSubjectAltNames = matchAllNames;
    
public voidsetNameConstraints(byte[] bytes)
Sets the name constraints criterion. The X509Certificate must have subject and subject alternative names that meet the specified name constraints.

The name constraints are specified as a byte array. This byte array should contain the DER encoded form of the name constraints, as they would appear in the NameConstraints structure defined in RFC 2459 and X.509. The ASN.1 definition of this structure appears below.


NameConstraints ::= SEQUENCE {
permittedSubtrees [0] GeneralSubtrees OPTIONAL,
excludedSubtrees [1] GeneralSubtrees OPTIONAL }

GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree

GeneralSubtree ::= SEQUENCE {
base GeneralName,
minimum [0] BaseDistance DEFAULT 0,
maximum [1] BaseDistance OPTIONAL }

BaseDistance ::= INTEGER (0..MAX)

GeneralName ::= CHOICE {
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER}

Note that the byte array supplied here is cloned to protect against subsequent modifications.

param
bytes a byte array containing the ASN.1 DER encoding of a NameConstraints extension to be used for checking name constraints. Only the value of the extension is included, not the OID or criticality flag. Can be null, in which case no name constraints check will be performed.
throws
IOException if a parsing error occurs
see
#getNameConstraints

	if (bytes == null) {
	    ncBytes = null;
	    nc = null;
	} else {
	    ncBytes = (byte[])bytes.clone();
	    nc = new NameConstraintsExtension(FALSE, bytes);
	}
    
public voidsetPathToNames(java.util.Collection names)
Sets the pathToNames criterion. The X509Certificate must not include name constraints that would prohibit building a path to the specified names.

This method allows the caller to specify, with a single method call, the complete set of names which the X509Certificates's name constraints must permit. The specified value replaces the previous value for the pathToNames criterion.

This constraint is useful when building a certification path forward (from the target toward the trust anchor. If a partial path has been built, any candidate certificate must not include name constraints that would prohibit building a path to any of the names in the partial path.

The names parameter (if not null) is a Collection with one entry for each name to be included in the pathToNames criterion. Each entry is a List whose first entry is an Integer (the name type, 0-8) and whose second entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). There can be multiple names of the same type. If null is supplied as the value for this argument, no pathToNames check will be performed.

Each name in the Collection may be specified either as a String or as an ASN.1 encoded byte array. For more details about the formats used, see {@link #addPathToName(int type, String name) addPathToName(int type, String name)} and {@link #addPathToName(int type, byte [] name) addPathToName(int type, byte [] name)}.

Note: for distinguished names, specify the byte array form instead of the String form. See the note in {@link #addPathToName(int, String)} for more information.

Note that the names parameter can contain duplicate names (same name and name type), but they may be removed from the Collection of names returned by the {@link #getPathToNames getPathToNames} method.

Note that a deep copy is performed on the Collection to protect against subsequent modifications.

param
names a Collection with one entry per name (or null)
throws
IOException if a parsing error occurs
see
#getPathToNames

	if ((names == null) || names.isEmpty()) {
	    pathToNames = null;
	    pathToGeneralNames = null;
	} else {
	    Set<List<?>> tempNames = cloneAndCheckNames(names);
	    pathToGeneralNames = parseNames(tempNames);
	    // Ensure that we either set both of these or neither
	    pathToNames = tempNames;
	}
    
voidsetPathToNamesInternal(java.util.Set names)

	// set names to non-null dummy value
	// this breaks getPathToNames()
	pathToNames = Collections.<List<?>>emptySet();
	pathToGeneralNames = names;
    
public voidsetPolicy(java.util.Set certPolicySet)
Sets the policy constraint. The X509Certificate must include at least one of the specified policies in its certificate policies extension. If certPolicySet is empty, then the X509Certificate must include at least some specified policy in its certificate policies extension. If certPolicySet is null, no policy check will be performed.

Note that the Set is cloned to protect against subsequent modifications.

param
certPolicySet a Set of certificate policy OIDs in string format (or null). Each OID is represented by a set of nonnegative integers separated by periods.
throws
IOException if a parsing error occurs on the OID such as the first component is not 0, 1 or 2 or the second component is greater than 39.
see
#getPolicy

	if (certPolicySet == null) {
	    policySet = null;
	    policy = null;
	} else {
	    // Snapshot set and parse it
	    Set<String> tempSet = Collections.unmodifiableSet
	    				(new HashSet<String>(certPolicySet));
	    /* Convert to Vector of ObjectIdentifiers */
	    Iterator i = tempSet.iterator();
	    Vector<CertificatePolicyId> polIdVector = new Vector<CertificatePolicyId>();
	    while (i.hasNext()) {
		Object o = i.next();
		if (!(o instanceof String)) {
		    throw new IOException("non String in certPolicySet");
		}
		polIdVector.add(new CertificatePolicyId(new ObjectIdentifier(
		  (String)o)));
	    }
	    // If everything went OK, make the changes
	    policySet = tempSet;
	    policy = new CertificatePolicySet(polIdVector);
	}
    
public voidsetPrivateKeyValid(java.util.Date privateKeyValid)
Sets the privateKeyValid criterion. The specified date must fall within the private key validity period for the X509Certificate. If null, no privateKeyValid check will be done.

Note that the Date supplied here is cloned to protect against subsequent modifications.

param
privateKeyValid the Date to check (or null)
see
#getPrivateKeyValid

	if (privateKeyValid == null) {
	    this.privateKeyValid = null;
	} else {
	    this.privateKeyValid = (Date)privateKeyValid.clone();
	}
    
public voidsetSerialNumber(java.math.BigInteger serial)
Sets the serialNumber criterion. The specified serial number must match the certificate serial number in the X509Certificate. If null, any certificate serial number will do.

param
serial the certificate serial number to match (or null)
see
#getSerialNumber

	serialNumber = serial;
    
public voidsetSubject(javax.security.auth.x500.X500Principal subject)
Sets the subject criterion. The specified distinguished name must match the subject distinguished name in the X509Certificate. If null, any subject distinguished name will do.

param
subject a distinguished name as X500Principal (or null)
since
1.5

	this.subject = subject;
    
public voidsetSubject(java.lang.String subjectDN)
Denigrated, use {@linkplain #setSubject(X500Principal)} or {@linkplain #setSubject(byte[])} instead. This method should not be relied on as it can fail to match some certificates because of a loss of encoding information in the RFC 2253 String form of some distinguished names.

Sets the subject criterion. The specified distinguished name must match the subject distinguished name in the X509Certificate. If null, any subject distinguished name will do.

If subjectDN is not null, it should contain a distinguished name, in RFC 2253 format.

param
subjectDN a distinguished name in RFC 2253 format (or null)
throws
IOException if a parsing error occurs (incorrect form for DN)

	if (subjectDN == null) {
	    subject = null;
	} else {
	    subject = new X500Name(subjectDN).asX500Principal();
	}
    
public voidsetSubject(byte[] subjectDN)
Sets the subject criterion. The specified distinguished name must match the subject distinguished name in the X509Certificate. If null, any subject distinguished name will do.

If subjectDN is not null, it should contain a single DER encoded distinguished name, as defined in X.501. For the ASN.1 notation for this structure, see {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.

param
subjectDN a byte array containing the distinguished name in ASN.1 DER format (or null)
throws
IOException if an encoding error occurs (incorrect form for DN)

	try {
	    subject = (subjectDN == null ? null : new X500Principal(subjectDN));
	} catch (IllegalArgumentException e) {
	    throw (IOException)new IOException("Invalid name").initCause(e);
	}
    
public voidsetSubjectAlternativeNames(java.util.Collection names)
Sets the subjectAlternativeNames criterion. The X509Certificate must contain all or at least one of the specified subjectAlternativeNames, depending on the value of the matchAllNames flag (see {@link #setMatchAllSubjectAltNames setMatchAllSubjectAltNames}).

This method allows the caller to specify, with a single method call, the complete set of subject alternative names for the subjectAlternativeNames criterion. The specified value replaces the previous value for the subjectAlternativeNames criterion.

The names parameter (if not null) is a Collection with one entry for each name to be included in the subject alternative name criterion. Each entry is a List whose first entry is an Integer (the name type, 0-8) and whose second entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). There can be multiple names of the same type. If null is supplied as the value for this argument, no subjectAlternativeNames check will be performed.

Each subject alternative name in the Collection may be specified either as a String or as an ASN.1 encoded byte array. For more details about the formats used, see {@link #addSubjectAlternativeName(int type, String name) addSubjectAlternativeName(int type, String name)} and {@link #addSubjectAlternativeName(int type, byte [] name) addSubjectAlternativeName(int type, byte [] name)}.

Note: for distinguished names, specify the byte array form instead of the String form. See the note in {@link #addSubjectAlternativeName(int, String)} for more information.

Note that the names parameter can contain duplicate names (same name and name type), but they may be removed from the Collection of names returned by the {@link #getSubjectAlternativeNames getSubjectAlternativeNames} method.

Note that a deep copy is performed on the Collection to protect against subsequent modifications.

param
names a Collection of names (or null)
throws
IOException if a parsing error occurs
see
#getSubjectAlternativeNames

	if (names == null) {
	    subjectAlternativeNames = null;
	    subjectAlternativeGeneralNames = null;
	} else {
	    if (names.isEmpty()) {
		subjectAlternativeNames = null;
		subjectAlternativeGeneralNames = null;
		return;
	    }
	    Set<List<?>> tempNames = cloneAndCheckNames(names);
	    // Ensure that we either set both of these or neither
	    subjectAlternativeGeneralNames = parseNames(tempNames);
	    subjectAlternativeNames = tempNames;
	}
    
public voidsetSubjectKeyIdentifier(byte[] subjectKeyID)
Sets the subjectKeyIdentifier criterion. The X509Certificate must contain a SubjectKeyIdentifier extension for which the contents of the extension matches the specified criterion value. If the criterion value is null, no subjectKeyIdentifier check will be done.

If subjectKeyID is not null, it should contain a single DER encoded value corresponding to the contents of the extension value (not including the object identifier, criticality setting, and encapsulating OCTET STRING) for a SubjectKeyIdentifier extension. The ASN.1 notation for this structure follows.


SubjectKeyIdentifier ::= KeyIdentifier

KeyIdentifier ::= OCTET STRING

Since the format of subject key identifiers is not mandated by any standard, subject key identifiers are not parsed by the X509CertSelector. Instead, the values are compared using a byte-by-byte comparison.

Note that the byte array supplied here is cloned to protect against subsequent modifications.

param
subjectKeyID the subject key identifier (or null)
see
#getSubjectKeyIdentifier

	if (subjectKeyID == null) {
	    this.subjectKeyID = null;
	} else {
	    this.subjectKeyID = (byte[])subjectKeyID.clone();
	}
    
public voidsetSubjectPublicKey(java.security.PublicKey key)
Sets the subjectPublicKey criterion. The X509Certificate must contain the specified subject public key. If null, no subjectPublicKey check will be done.

param
key the subject public key to check for (or null)
see
#getSubjectPublicKey

	if (key == null) {
	    subjectPublicKey = null;
	    subjectPublicKeyBytes = null;
	} else {
	    subjectPublicKey = key;
	    subjectPublicKeyBytes = key.getEncoded();
	}
    
public voidsetSubjectPublicKey(byte[] key)
Sets the subjectPublicKey criterion. The X509Certificate must contain the specified subject public key. If null, no subjectPublicKey check will be done.

Because this method allows the public key to be specified as a byte array, it may be used for unknown key types.

If key is not null, it should contain a single DER encoded SubjectPublicKeyInfo structure, as defined in X.509. The ASN.1 notation for this structure is as follows.


SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }

AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL }
-- contains a value of the type
-- registered for use with the
-- algorithm object identifier value

Note that the byte array supplied here is cloned to protect against subsequent modifications.

param
key a byte array containing the subject public key in ASN.1 DER form (or null)
throws
IOException if an encoding error occurs (incorrect form for subject public key)
see
#getSubjectPublicKey

	if (key == null) {
	    subjectPublicKey = null;
	    subjectPublicKeyBytes = null;
	} else {
	    subjectPublicKeyBytes = (byte[])key.clone();
	    subjectPublicKey = X509Key.parse(new DerValue(subjectPublicKeyBytes));
	}
    
public voidsetSubjectPublicKeyAlgID(java.lang.String oid)
Sets the subjectPublicKeyAlgID criterion. The X509Certificate must contain a subject public key with the specified algorithm. If null, no subjectPublicKeyAlgID check will be done.

param
oid The object identifier (OID) of the algorithm to check for (or null). An OID is represented by a set of nonnegative integers separated by periods.
throws
IOException if the OID is invalid, such as the first component being not 0, 1 or 2 or the second component being greater than 39.
see
#getSubjectPublicKeyAlgID

	if (oid == null) {
	    subjectPublicKeyAlgID = null;
	} else {
	    subjectPublicKeyAlgID = new ObjectIdentifier(oid);
	}
    
public java.lang.StringtoString()
Return a printable representation of the CertSelector.

return
a String describing the contents of the CertSelector

	StringBuffer sb = new StringBuffer();
	sb.append("X509CertSelector: [\n");
	if (x509Cert != null) {
	    sb.append("  Certificate: " + x509Cert.toString() + "\n");
	}
	if (serialNumber != null) {
	    sb.append("  Serial Number: " + serialNumber.toString() + "\n");
	}
	if (issuer != null) {
	    sb.append("  Issuer: " + getIssuerAsString() + "\n");
	}
	if (subject != null) {
	    sb.append("  Subject: " + getSubjectAsString() + "\n");
	}
	sb.append("  matchAllSubjectAltNames flag: " 
		  + String.valueOf(matchAllSubjectAltNames) + "\n");
	if (subjectAlternativeNames != null) {
	    sb.append("  SubjectAlternativeNames:\n");
	    Iterator i = subjectAlternativeNames.iterator();
	    while (i.hasNext()) {
		List list = (List) i.next();
		sb.append("    type " + list.get(0) +
			  ", name " + list.get(1) + "\n");
	    }
	}
	if (subjectKeyID != null) {
	    HexDumpEncoder enc = new HexDumpEncoder();
	    sb.append("  Subject Key Identifier: " + 
		      enc.encodeBuffer(subjectKeyID) + "\n");
	}
	if (authorityKeyID != null) {
	    HexDumpEncoder enc = new HexDumpEncoder();
	    sb.append("  Authority Key Identifier: " + 
		      enc.encodeBuffer(authorityKeyID) + "\n");
	}
	if (certificateValid != null) {
	    sb.append("  Certificate Valid: " + 
		      certificateValid.toString() + "\n");
	}
	if (privateKeyValid != null) {
	    sb.append("  Private Key Valid: " + 
		      privateKeyValid.toString() + "\n");
	}
	if (subjectPublicKeyAlgID != null) {
	    sb.append("  Subject Public Key AlgID: " + 
		      subjectPublicKeyAlgID.toString() + "\n");
	}
	if (subjectPublicKey != null) {
	    sb.append("  Subject Public Key: " + 
		      subjectPublicKey.toString() + "\n");
	}
	if (keyUsage != null) {
	    sb.append("  Key Usage: " + keyUsageToString(keyUsage) + "\n");
	}
	if (keyPurposeSet != null) {
	    sb.append("  Extended Key Usage: " + 
		      keyPurposeSet.toString() + "\n");
	}
	if (policy != null) {
	    sb.append("  Policy: " + policy.toString() + "\n");
	}
	if (pathToGeneralNames != null) {
	    sb.append("  Path to names:\n");
	    Iterator i = pathToGeneralNames.iterator();
	    while (i.hasNext()) {
		sb.append("    " + i.next() + "\n");
	    }
	}
	sb.append("]");
	return sb.toString();