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

X509CRLSelector

public class X509CRLSelector extends Object implements CRLSelector
A CRLSelector that selects X509CRLs that match all specified criteria. This class is particularly useful when selecting CRLs from a CertStore to check revocation status of a particular certificate.

When first constructed, an X509CRLSelector has no criteria enabled and each of the get methods return a default value (null). Therefore, the {@link #match match} method would return true for any X509CRL. Typically, several criteria are enabled (by calling {@link #setIssuers setIssuers} or {@link #setDateAndTime setDateAndTime}, for instance) and then the X509CRLSelector is passed to {@link CertStore#getCRLs CertStore.getCRLs} or some similar method.

Please refer to RFC 2459 for definitions of the X.509 CRL fields and 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
CRLSelector
see
X509CRL
version
1.16 07/16/04
since
1.4
author
Steve Hanna

Fields Summary
private static final Debug
debug
private HashSet
issuerNames
private HashSet
issuerX500Principals
private BigInteger
minCRL
private BigInteger
maxCRL
private Date
dateAndTime
private X509Certificate
certChecking
Constructors Summary
public X509CRLSelector()
Creates an X509CRLSelector. Initially, no criteria are set so any X509CRL will match.


                      
      
Methods Summary
public voidaddIssuer(javax.security.auth.x500.X500Principal issuer)
Adds a name to the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names.

This method allows the caller to add a name to the set of issuer names which X509CRLs may contain. The specified name is added to any previous value for the issuerNames criterion. If the specified name is a duplicate, it may be ignored.

param
issuer the issuer as X500Principal
since
1.5

	addIssuerNameInternal(issuer.getEncoded(), issuer);
    
public voidaddIssuerName(java.lang.String name)
Denigrated, use {@linkplain #addIssuer(X500Principal)} or {@linkplain #addIssuerName(byte[])} instead. This method should not be relied on as it can fail to match some CRLs because of a loss of encoding information in the RFC 2253 String form of some distinguished names.

Adds a name to the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names.

This method allows the caller to add a name to the set of issuer names which X509CRLs may contain. The specified name is added to any previous value for the issuerNames criterion. If the specified name is a duplicate, it may be ignored.

param
name the name in RFC 2253 form
throws
IOException if a parsing error occurs

        addIssuerNameInternal(name, new X500Name(name).asX500Principal());
    
public voidaddIssuerName(byte[] name)
Adds a name to the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names.

This method allows the caller to add a name to the set of issuer names which X509CRLs may contain. The specified name is added to any previous value for the issuerNames criterion. If the specified name is a duplicate, it may be ignored. If a name is specified as a byte array, it should contain a single DER encoded distinguished name, as defined in X.501. The ASN.1 notation for this structure is as follows.

The name is provided as a byte array. This byte array should contain a single DER encoded distinguished name, as defined in X.501. The ASN.1 notation for this structure appears in the documentation for {@link #setIssuerNames setIssuerNames(Collection names)}.

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

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
        addIssuerNameInternal(name.clone(), new X500Name(name).asX500Principal());
    
private voidaddIssuerNameInternal(java.lang.Object name, javax.security.auth.x500.X500Principal principal)
A private method that adds a name (String or byte array) to the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names.

param
name the name in string or byte array form
param
principal the name in X500Principal form
throws
IOException if a parsing error occurs

        if (issuerNames == null) {
            issuerNames = new HashSet<Object>();
	}
        if (issuerX500Principals == null) {
            issuerX500Principals = new HashSet<X500Principal>();
	}
        issuerNames.add(name);
        issuerX500Principals.add(principal);
    
public java.lang.Objectclone()
Returns a copy of this object.

return
the copy

        try {
            X509CRLSelector copy = (X509CRLSelector)super.clone();
            if (issuerNames != null) {
                copy.issuerNames = 
			new HashSet<Object>(issuerNames);
                copy.issuerX500Principals = 
			new HashSet<X500Principal>(issuerX500Principals);
            }
            return copy;
        } catch (CloneNotSupportedException e) {
            /* Cannot happen */
            throw new InternalError(e.toString());
        }
    
private static java.util.HashSetcloneAndCheckIssuerNames(java.util.Collection names)
Clone and check an argument of the form passed to setIssuerNames. Throw an IOException if the argument is malformed.

param
names a Collection of names. Each entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). null is not an acceptable value.
return
a deep copy of the specified Collection
throws
IOException if a parsing error occurs

        HashSet<Object> namesCopy = new HashSet<Object>();
        Iterator i = names.iterator();
        while (i.hasNext()) {
            Object nameObject = i.next();
            if (!(nameObject instanceof byte []) &&
	        !(nameObject instanceof String))
	        throw new IOException("name not byte array or String");
            if (nameObject instanceof byte [])
	        namesCopy.add(((byte []) nameObject).clone());
            else
	        namesCopy.add(nameObject);
        }
        return(namesCopy);
    
private static java.util.HashSetcloneIssuerNames(java.util.Collection names)
Clone an argument of the form passed to setIssuerNames. Throw a RuntimeException if the argument is malformed.

This method wraps cloneAndCheckIssuerNames, 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 of names. Each entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). null is not an acceptable value.
return
a deep copy of the specified Collection
throws
RuntimeException if a parsing error occurs

        try {
            return cloneAndCheckIssuerNames(names);
        } catch (IOException ioe) {
	    throw new RuntimeException(ioe);
        }
    
public java.security.cert.X509CertificategetCertificateChecking()
Returns the certificate being checked. This is not a criterion. Rather, it is optional information that may help a CertStore find CRLs that would be relevant when checking revocation for the specified certificate. If the value returned is null, then no such optional information is provided.

return
the certificate being checked (or null)
see
#setCertificateChecking

        return certChecking;
    
public java.util.DategetDateAndTime()
Returns the dateAndTime criterion. The specified date must be equal to or later than the value of the thisUpdate component of the X509CRL and earlier than the value of the nextUpdate component. There is no match if the X509CRL does not contain a nextUpdate component. If null, no dateAndTime check will be done.

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

return
the Date to match against (or null)
see
#setDateAndTime

        if (dateAndTime == null)
            return null;
        return (Date) dateAndTime.clone();
    
public java.util.CollectiongetIssuerNames()
Returns a copy of the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names. If the value returned is null, any issuer distinguished name will do.

If the value returned is not null, it is a Collection of names. Each name is a String or a byte array representing a distinguished name (in RFC 2253 or ASN.1 DER encoded form, respectively). Note that the Collection returned may contain duplicate names.

If a name is specified as a byte array, it should contain a single DER encoded distinguished name, as defined in X.501. The ASN.1 notation for this structure is given in the documentation for {@link #setIssuerNames setIssuerNames(Collection names)}.

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

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

        if (issuerNames == null) {
            return null;
	}
        return cloneIssuerNames(issuerNames);
    
public java.util.CollectiongetIssuers()
Returns the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names. If the value returned is null, any issuer distinguished name will do.

If the value returned is not null, it is a unmodifiable Collection of X500Principals.

return
an unmodifiable Collection of names (or null)
see
#setIssuers
since
1.5

	if (issuerX500Principals == null) {
	    return null;
	}
	return Collections.unmodifiableCollection(issuerX500Principals);
    
public java.math.BigIntegergetMaxCRL()
Returns the maxCRLNumber criterion. The X509CRL must have a CRL number extension whose value is less than or equal to the specified value. If null, no maxCRLNumber check will be done.

return
the maximum CRL number accepted (or null)

        return maxCRL;
    
public java.math.BigIntegergetMinCRL()
Returns the minCRLNumber criterion. The X509CRL must have a CRL number extension whose value is greater than or equal to the specified value. If null, no minCRLNumber check will be done.

return
the minimum CRL number accepted (or null)

        return minCRL;
    
public booleanmatch(java.security.cert.CRL crl)
Decides whether a CRL should be selected.

param
crl the CRL to be checked
return
true if the CRL should be selected, false otherwise

        if (!(crl instanceof X509CRL)) {
            return false;
	}
        X509CRL xcrl = (X509CRL)crl;

        /* match on issuer name */
        if (issuerNames != null) {
            X500Principal issuer = xcrl.getIssuerX500Principal();
            Iterator i = issuerX500Principals.iterator();
            boolean found = false;
            while (!found && i.hasNext()) {
	        if (i.next().equals(issuer)) {
	            found = true;
		}
	    }
            if (!found) {
	        if (debug != null) {
	    	    debug.println("X509CRLSelector.match: issuer DNs "
			+ "don't match");
		}
	        return false;
            }
        }
	
	if ((minCRL != null) || (maxCRL != null)) {
	    /* Get CRL number extension from CRL */
	    byte[] crlNumExtVal = xcrl.getExtensionValue("2.5.29.20");
	    if (crlNumExtVal == null) {
		if (debug != null) {
		    debug.println("X509CRLSelector.match: no CRLNumber");
		}
	    }
	    BigInteger crlNum;
	    try {
		DerInputStream in = new DerInputStream(crlNumExtVal);
		byte[] encoded = in.getOctetString();
		CRLNumberExtension crlNumExt = 
		    new CRLNumberExtension(Boolean.FALSE, encoded);
		crlNum = (BigInteger)crlNumExt.get(CRLNumberExtension.NUMBER);
	    } catch (IOException ex) {
		if (debug != null) {
		    debug.println("X509CRLSelector.match: exception in "
			+ "decoding CRL number");
		}
		return false;
	    }
    
	    /* match on minCRLNumber */
	    if (minCRL != null) {
		if (crlNum.compareTo(minCRL) < 0) {
		    if (debug != null) {
			debug.println("X509CRLSelector.match: CRLNumber too small");
		    }
		    return false;
		}
	    }

	    /* match on maxCRLNumber */
	    if (maxCRL != null) {
		if (crlNum.compareTo(maxCRL) > 0) {
		    if (debug != null) {
			debug.println("X509CRLSelector.match: CRLNumber too large");
		    }
		    return false;
		}
	    }
	}


        /* match on dateAndTime */
        if (dateAndTime != null) {
	    Date crlThisUpdate = xcrl.getThisUpdate();
            Date nextUpdate = xcrl.getNextUpdate();
            if (nextUpdate == null) {
	        if (debug != null) {
		    debug.println("X509CRLSelector.match: nextUpdate null");
		}
	        return false;
            }
            if (crlThisUpdate.after(dateAndTime) 
	          || nextUpdate.before(dateAndTime)) {
	        if (debug != null) {
		    debug.println("X509CRLSelector.match: update out of range");
		}
	        return false;
            }
        }

        return true;
    
private static java.util.HashSetparseIssuerNames(java.util.Collection names)
Parse an argument of the form passed to setIssuerNames, returning a Collection of issuerX500Principals. Throw an IOException if the argument is malformed.

param
names a Collection of names. Each entry is a String or a byte array (the name, in string or ASN.1 DER encoded form, respectively). Null is not an acceptable value.
return
a HashSet of issuerX500Principals
throws
IOException if a parsing error occurs

        HashSet<X500Principal> x500Principals = new HashSet<X500Principal>();
	for (Iterator t = names.iterator(); t.hasNext(); ) {
	    Object nameObject = t.next();
	    if (nameObject instanceof String) {
		x500Principals.add(new X500Name((String)nameObject).asX500Principal());
	    } else {
		try {
		    x500Principals.add(new X500Principal((byte[])nameObject));
		} catch (IllegalArgumentException e) {
		    throw (IOException)new IOException("Invalid name").initCause(e);
		}
	    }
	}
        return x500Principals;
    
public voidsetCertificateChecking(java.security.cert.X509Certificate cert)
Sets the certificate being checked. This is not a criterion. Rather, it is optional information that may help a CertStore find CRLs that would be relevant when checking revocation for the specified certificate. If null is specified, then no such optional information is provided.

param
cert the X509Certificate being checked (or null)
see
#getCertificateChecking

        certChecking = cert;
    
public voidsetDateAndTime(java.util.Date dateAndTime)
Sets the dateAndTime criterion. The specified date must be equal to or later than the value of the thisUpdate component of the X509CRL and earlier than the value of the nextUpdate component. There is no match if the X509CRL does not contain a nextUpdate component. If null, no dateAndTime check will be done.

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

param
dateAndTime the Date to match against (or null)
see
#getDateAndTime

        if (dateAndTime == null)
            this.dateAndTime = null;
        else
            this.dateAndTime = (Date) dateAndTime.clone();
    
public voidsetIssuerNames(java.util.Collection names)
Note: use {@linkplain #setIssuers(Collection)} instead or only specify the byte array form of distinguished names when using this method. See {@link #addIssuerName(String)} for more information.

Sets the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names. If null, any issuer distinguished name will do.

This method allows the caller to specify, with a single method call, the complete set of issuer names which X509CRLs may contain. The specified value replaces the previous value for the issuerNames criterion.

The names parameter (if not null) is a Collection of names. Each name is a String or a byte array representing a distinguished name (in RFC 2253 or ASN.1 DER encoded form, respectively). If null is supplied as the value for this argument, no issuerNames check will be performed.

Note that the names parameter can contain duplicate distinguished names, but they may be removed from the Collection of names returned by the {@link #getIssuerNames getIssuerNames} method.

If a name is specified as a byte array, 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 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
#getIssuerNames

        if (names == null || names.size() == 0) {
            issuerNames = null;
            issuerX500Principals = null;
        } else {
            HashSet<Object> tempNames = cloneAndCheckIssuerNames(names);
            // Ensure that we either set both of these or neither
            issuerX500Principals = parseIssuerNames(tempNames);
            issuerNames = tempNames;
        }
    
public voidsetIssuers(java.util.Collection issuers)
Sets the issuerNames criterion. The issuer distinguished name in the X509CRL must match at least one of the specified distinguished names. If null, any issuer distinguished name will do.

This method allows the caller to specify, with a single method call, the complete set of issuer names which X509CRLs may contain. The specified value replaces the previous value for the issuerNames criterion.

The names parameter (if not null) is a Collection of X500Principals.

Note that the names parameter can contain duplicate distinguished names, but they may be removed from the Collection of names returned by the {@link #getIssuers getIssuers} method.

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

param
issuers a Collection of X500Principals (or null)
see
#getIssuers
since
1.5

        if ((issuers == null) || issuers.isEmpty()) {
            issuerNames = null;
            issuerX500Principals = null;
        } else {
	    // clone
	    issuerX500Principals = new HashSet(issuers);
	    issuerNames = new HashSet<Object>();
	    for (X500Principal p : issuerX500Principals) {
		issuerNames.add(p.getEncoded());
	    }
        }
    
public voidsetMaxCRLNumber(java.math.BigInteger maxCRL)
Sets the maxCRLNumber criterion. The X509CRL must have a CRL number extension whose value is less than or equal to the specified value. If null, no maxCRLNumber check will be done.

param
maxCRL the maximum CRL number accepted (or null)

        this.maxCRL = maxCRL;
    
public voidsetMinCRLNumber(java.math.BigInteger minCRL)
Sets the minCRLNumber criterion. The X509CRL must have a CRL number extension whose value is greater than or equal to the specified value. If null, no minCRLNumber check will be done.

param
minCRL the minimum CRL number accepted (or null)

        this.minCRL = minCRL;
    
public java.lang.StringtoString()
Returns a printable representation of the X509CRLSelector.

return
a String describing the contents of the X509CRLSelector.

        StringBuffer sb = new StringBuffer();
        sb.append("X509CRLSelector: [\n");
        if (issuerNames != null) {
            sb.append("  IssuerNames:\n");
            Iterator i = issuerNames.iterator();
            while (i.hasNext())
	        sb.append("    " + i.next() + "\n");
        }
        if (minCRL != null)
            sb.append("  minCRLNumber: " + minCRL + "\n");
        if (maxCRL != null)
            sb.append("  maxCRLNumber: " + maxCRL + "\n");
        if (dateAndTime != null)
            sb.append("  dateAndTime: " + dateAndTime + "\n");
        if (certChecking != null)
            sb.append("  Certificate being checked: " + certChecking + "\n");
        sb.append("]");
        return sb.toString();