blob: b602aee12c57ac5913c5649e970a39953fa4921f [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.security.cert;
27
28import java.io.IOException;
29import java.math.BigInteger;
30import java.util.*;
31
32import javax.security.auth.x500.X500Principal;
33
34import sun.security.util.Debug;
35import sun.security.util.DerInputStream;
36import sun.security.x509.CRLNumberExtension;
37import sun.security.x509.X500Name;
38
39/**
40 * A <code>CRLSelector</code> that selects <code>X509CRLs</code> that
41 * match all specified criteria. This class is particularly useful when
42 * selecting CRLs from a <code>CertStore</code> to check revocation status
43 * of a particular certificate.
44 * <p>
45 * When first constructed, an <code>X509CRLSelector</code> has no criteria
46 * enabled and each of the <code>get</code> methods return a default
47 * value (<code>null</code>). Therefore, the {@link #match match} method
48 * would return <code>true</code> for any <code>X509CRL</code>. Typically,
49 * several criteria are enabled (by calling {@link #setIssuers setIssuers}
50 * or {@link #setDateAndTime setDateAndTime}, for instance) and then the
51 * <code>X509CRLSelector</code> is passed to
52 * {@link CertStore#getCRLs CertStore.getCRLs} or some similar
53 * method.
54 * <p>
55 * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
56 * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>
57 * for definitions of the X.509 CRL fields and extensions mentioned below.
58 * <p>
59 * <b>Concurrent Access</b>
60 * <p>
61 * Unless otherwise specified, the methods defined in this class are not
62 * thread-safe. Multiple threads that need to access a single
63 * object concurrently should synchronize amongst themselves and
64 * provide the necessary locking. Multiple threads each manipulating
65 * separate objects need not synchronize.
66 *
67 * @see CRLSelector
68 * @see X509CRL
69 *
70 * @since 1.4
71 * @author Steve Hanna
72 */
73public class X509CRLSelector implements CRLSelector {
74
75 private static final Debug debug = Debug.getInstance("certpath");
76 private HashSet<Object> issuerNames;
77 private HashSet<X500Principal> issuerX500Principals;
78 private BigInteger minCRL;
79 private BigInteger maxCRL;
80 private Date dateAndTime;
81 private X509Certificate certChecking;
82
83 /**
84 * Creates an <code>X509CRLSelector</code>. Initially, no criteria are set
85 * so any <code>X509CRL</code> will match.
86 */
87 public X509CRLSelector() {}
88
89 /**
90 * Sets the issuerNames criterion. The issuer distinguished name in the
91 * <code>X509CRL</code> must match at least one of the specified
92 * distinguished names. If <code>null</code>, any issuer distinguished name
93 * will do.
94 * <p>
95 * This method allows the caller to specify, with a single method call,
96 * the complete set of issuer names which <code>X509CRLs</code> may contain.
97 * The specified value replaces the previous value for the issuerNames
98 * criterion.
99 * <p>
100 * The <code>names</code> parameter (if not <code>null</code>) is a
101 * <code>Collection</code> of <code>X500Principal</code>s.
102 * <p>
103 * Note that the <code>names</code> parameter can contain duplicate
104 * distinguished names, but they may be removed from the
105 * <code>Collection</code> of names returned by the
106 * {@link #getIssuers getIssuers} method.
107 * <p>
108 * Note that a copy is performed on the <code>Collection</code> to
109 * protect against subsequent modifications.
110 *
111 * @param issuers a <code>Collection</code> of X500Principals
112 * (or <code>null</code>)
113 * @see #getIssuers
114 * @since 1.5
115 */
116 public void setIssuers(Collection<X500Principal> issuers) {
117 if ((issuers == null) || issuers.isEmpty()) {
118 issuerNames = null;
119 issuerX500Principals = null;
120 } else {
121 // clone
122 issuerX500Principals = new HashSet<X500Principal>(issuers);
123 issuerNames = new HashSet<Object>();
124 for (X500Principal p : issuerX500Principals) {
125 issuerNames.add(p.getEncoded());
126 }
127 }
128 }
129
130 /**
131 * <strong>Note:</strong> use {@linkplain #setIssuers(Collection)} instead
132 * or only specify the byte array form of distinguished names when using
133 * this method. See {@link #addIssuerName(String)} for more information.
134 * <p>
135 * Sets the issuerNames criterion. The issuer distinguished name in the
136 * <code>X509CRL</code> must match at least one of the specified
137 * distinguished names. If <code>null</code>, any issuer distinguished name
138 * will do.
139 * <p>
140 * This method allows the caller to specify, with a single method call,
141 * the complete set of issuer names which <code>X509CRLs</code> may contain.
142 * The specified value replaces the previous value for the issuerNames
143 * criterion.
144 * <p>
145 * The <code>names</code> parameter (if not <code>null</code>) is a
146 * <code>Collection</code> of names. Each name is a <code>String</code>
147 * or a byte array representing a distinguished name (in
148 * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> or
149 * ASN.1 DER encoded form, respectively). If <code>null</code> is supplied
150 * as the value for this argument, no issuerNames check will be performed.
151 * <p>
152 * Note that the <code>names</code> parameter can contain duplicate
153 * distinguished names, but they may be removed from the
154 * <code>Collection</code> of names returned by the
155 * {@link #getIssuerNames getIssuerNames} method.
156 * <p>
157 * If a name is specified as a byte array, it should contain a single DER
158 * encoded distinguished name, as defined in X.501. The ASN.1 notation for
159 * this structure is as follows.
160 * <pre><code>
161 * Name ::= CHOICE {
162 * RDNSequence }
163 *
164 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
165 *
166 * RelativeDistinguishedName ::=
167 * SET SIZE (1 .. MAX) OF AttributeTypeAndValue
168 *
169 * AttributeTypeAndValue ::= SEQUENCE {
170 * type AttributeType,
171 * value AttributeValue }
172 *
173 * AttributeType ::= OBJECT IDENTIFIER
174 *
175 * AttributeValue ::= ANY DEFINED BY AttributeType
176 * ....
177 * DirectoryString ::= CHOICE {
178 * teletexString TeletexString (SIZE (1..MAX)),
179 * printableString PrintableString (SIZE (1..MAX)),
180 * universalString UniversalString (SIZE (1..MAX)),
181 * utf8String UTF8String (SIZE (1.. MAX)),
182 * bmpString BMPString (SIZE (1..MAX)) }
183 * </code></pre>
184 * <p>
185 * Note that a deep copy is performed on the <code>Collection</code> to
186 * protect against subsequent modifications.
187 *
188 * @param names a <code>Collection</code> of names (or <code>null</code>)
189 * @throws IOException if a parsing error occurs
190 * @see #getIssuerNames
191 */
192 public void setIssuerNames(Collection<?> names) throws IOException {
193 if (names == null || names.size() == 0) {
194 issuerNames = null;
195 issuerX500Principals = null;
196 } else {
197 HashSet<Object> tempNames = cloneAndCheckIssuerNames(names);
198 // Ensure that we either set both of these or neither
199 issuerX500Principals = parseIssuerNames(tempNames);
200 issuerNames = tempNames;
201 }
202 }
203
204 /**
205 * Adds a name to the issuerNames criterion. The issuer distinguished
206 * name in the <code>X509CRL</code> must match at least one of the specified
207 * distinguished names.
208 * <p>
209 * This method allows the caller to add a name to the set of issuer names
210 * which <code>X509CRLs</code> may contain. The specified name is added to
211 * any previous value for the issuerNames criterion.
212 * If the specified name is a duplicate, it may be ignored.
213 *
214 * @param issuer the issuer as X500Principal
215 * @since 1.5
216 */
217 public void addIssuer(X500Principal issuer) {
218 addIssuerNameInternal(issuer.getEncoded(), issuer);
219 }
220
221 /**
222 * <strong>Denigrated</strong>, use
223 * {@linkplain #addIssuer(X500Principal)} or
224 * {@linkplain #addIssuerName(byte[])} instead. This method should not be
225 * relied on as it can fail to match some CRLs because of a loss of
226 * encoding information in the RFC 2253 String form of some distinguished
227 * names.
228 * <p>
229 * Adds a name to the issuerNames criterion. The issuer distinguished
230 * name in the <code>X509CRL</code> must match at least one of the specified
231 * distinguished names.
232 * <p>
233 * This method allows the caller to add a name to the set of issuer names
234 * which <code>X509CRLs</code> may contain. The specified name is added to
235 * any previous value for the issuerNames criterion.
236 * If the specified name is a duplicate, it may be ignored.
237 *
238 * @param name the name in RFC 2253 form
239 * @throws IOException if a parsing error occurs
240 */
241 public void addIssuerName(String name) throws IOException {
242 addIssuerNameInternal(name, new X500Name(name).asX500Principal());
243 }
244
245 /**
246 * Adds a name to the issuerNames criterion. The issuer distinguished
247 * name in the <code>X509CRL</code> must match at least one of the specified
248 * distinguished names.
249 * <p>
250 * This method allows the caller to add a name to the set of issuer names
251 * which <code>X509CRLs</code> may contain. The specified name is added to
252 * any previous value for the issuerNames criterion. If the specified name
253 * is a duplicate, it may be ignored.
254 * If a name is specified as a byte array, it should contain a single DER
255 * encoded distinguished name, as defined in X.501. The ASN.1 notation for
256 * this structure is as follows.
257 * <p>
258 * The name is provided as a byte array. This byte array should contain
259 * a single DER encoded distinguished name, as defined in X.501. The ASN.1
260 * notation for this structure appears in the documentation for
261 * {@link #setIssuerNames setIssuerNames(Collection names)}.
262 * <p>
263 * Note that the byte array supplied here is cloned to protect against
264 * subsequent modifications.
265 *
266 * @param name a byte array containing the name in ASN.1 DER encoded form
267 * @throws IOException if a parsing error occurs
268 */
269 public void addIssuerName(byte[] name) throws IOException {
270 // clone because byte arrays are modifiable
271 addIssuerNameInternal(name.clone(), new X500Name(name).asX500Principal());
272 }
273
274 /**
275 * A private method that adds a name (String or byte array) to the
276 * issuerNames criterion. The issuer distinguished
277 * name in the <code>X509CRL</code> must match at least one of the specified
278 * distinguished names.
279 *
280 * @param name the name in string or byte array form
281 * @param principal the name in X500Principal form
282 * @throws IOException if a parsing error occurs
283 */
284 private void addIssuerNameInternal(Object name, X500Principal principal) {
285 if (issuerNames == null) {
286 issuerNames = new HashSet<Object>();
287 }
288 if (issuerX500Principals == null) {
289 issuerX500Principals = new HashSet<X500Principal>();
290 }
291 issuerNames.add(name);
292 issuerX500Principals.add(principal);
293 }
294
295 /**
296 * Clone and check an argument of the form passed to
297 * setIssuerNames. Throw an IOException if the argument is malformed.
298 *
299 * @param names a <code>Collection</code> of names. Each entry is a
300 * String or a byte array (the name, in string or ASN.1
301 * DER encoded form, respectively). <code>null</code> is
302 * not an acceptable value.
303 * @return a deep copy of the specified <code>Collection</code>
304 * @throws IOException if a parsing error occurs
305 */
306 private static HashSet<Object> cloneAndCheckIssuerNames(Collection<?> names)
307 throws IOException
308 {
309 HashSet<Object> namesCopy = new HashSet<Object>();
310 Iterator<?> i = names.iterator();
311 while (i.hasNext()) {
312 Object nameObject = i.next();
313 if (!(nameObject instanceof byte []) &&
314 !(nameObject instanceof String))
315 throw new IOException("name not byte array or String");
316 if (nameObject instanceof byte [])
317 namesCopy.add(((byte []) nameObject).clone());
318 else
319 namesCopy.add(nameObject);
320 }
321 return(namesCopy);
322 }
323
324 /**
325 * Clone an argument of the form passed to setIssuerNames.
326 * Throw a RuntimeException if the argument is malformed.
327 * <p>
328 * This method wraps cloneAndCheckIssuerNames, changing any IOException
329 * into a RuntimeException. This method should be used when the object being
330 * cloned has already been checked, so there should never be any exceptions.
331 *
332 * @param names a <code>Collection</code> of names. Each entry is a
333 * String or a byte array (the name, in string or ASN.1
334 * DER encoded form, respectively). <code>null</code> is
335 * not an acceptable value.
336 * @return a deep copy of the specified <code>Collection</code>
337 * @throws RuntimeException if a parsing error occurs
338 */
339 private static HashSet<Object> cloneIssuerNames(Collection<Object> names) {
340 try {
341 return cloneAndCheckIssuerNames(names);
342 } catch (IOException ioe) {
343 throw new RuntimeException(ioe);
344 }
345 }
346
347 /**
348 * Parse an argument of the form passed to setIssuerNames,
349 * returning a Collection of issuerX500Principals.
350 * Throw an IOException if the argument is malformed.
351 *
352 * @param names a <code>Collection</code> of names. Each entry is a
353 * String or a byte array (the name, in string or ASN.1
354 * DER encoded form, respectively). <Code>Null</Code> is
355 * not an acceptable value.
356 * @return a HashSet of issuerX500Principals
357 * @throws IOException if a parsing error occurs
358 */
359 private static HashSet<X500Principal> parseIssuerNames(Collection<Object> names)
360 throws IOException {
361 HashSet<X500Principal> x500Principals = new HashSet<X500Principal>();
362 for (Iterator<Object> t = names.iterator(); t.hasNext(); ) {
363 Object nameObject = t.next();
364 if (nameObject instanceof String) {
365 x500Principals.add(new X500Name((String)nameObject).asX500Principal());
366 } else {
367 try {
368 x500Principals.add(new X500Principal((byte[])nameObject));
369 } catch (IllegalArgumentException e) {
370 throw (IOException)new IOException("Invalid name").initCause(e);
371 }
372 }
373 }
374 return x500Principals;
375 }
376
377 /**
378 * Sets the minCRLNumber criterion. The <code>X509CRL</code> must have a
379 * CRL number extension whose value is greater than or equal to the
380 * specified value. If <code>null</code>, no minCRLNumber check will be
381 * done.
382 *
383 * @param minCRL the minimum CRL number accepted (or <code>null</code>)
384 */
385 public void setMinCRLNumber(BigInteger minCRL) {
386 this.minCRL = minCRL;
387 }
388
389 /**
390 * Sets the maxCRLNumber criterion. The <code>X509CRL</code> must have a
391 * CRL number extension whose value is less than or equal to the
392 * specified value. If <code>null</code>, no maxCRLNumber check will be
393 * done.
394 *
395 * @param maxCRL the maximum CRL number accepted (or <code>null</code>)
396 */
397 public void setMaxCRLNumber(BigInteger maxCRL) {
398 this.maxCRL = maxCRL;
399 }
400
401 /**
402 * Sets the dateAndTime criterion. The specified date must be
403 * equal to or later than the value of the thisUpdate component
404 * of the <code>X509CRL</code> and earlier than the value of the
405 * nextUpdate component. There is no match if the <code>X509CRL</code>
406 * does not contain a nextUpdate component.
407 * If <code>null</code>, no dateAndTime check will be done.
408 * <p>
409 * Note that the <code>Date</code> supplied here is cloned to protect
410 * against subsequent modifications.
411 *
412 * @param dateAndTime the <code>Date</code> to match against
413 * (or <code>null</code>)
414 * @see #getDateAndTime
415 */
416 public void setDateAndTime(Date dateAndTime) {
417 if (dateAndTime == null)
418 this.dateAndTime = null;
419 else
420 this.dateAndTime = (Date) dateAndTime.clone();
421 }
422
423 /**
424 * Sets the certificate being checked. This is not a criterion. Rather,
425 * it is optional information that may help a <code>CertStore</code>
426 * find CRLs that would be relevant when checking revocation for the
427 * specified certificate. If <code>null</code> is specified, then no
428 * such optional information is provided.
429 *
430 * @param cert the <code>X509Certificate</code> being checked
431 * (or <code>null</code>)
432 * @see #getCertificateChecking
433 */
434 public void setCertificateChecking(X509Certificate cert) {
435 certChecking = cert;
436 }
437
438 /**
439 * Returns the issuerNames criterion. The issuer distinguished
440 * name in the <code>X509CRL</code> must match at least one of the specified
441 * distinguished names. If the value returned is <code>null</code>, any
442 * issuer distinguished name will do.
443 * <p>
444 * If the value returned is not <code>null</code>, it is a
445 * unmodifiable <code>Collection</code> of <code>X500Principal</code>s.
446 *
447 * @return an unmodifiable <code>Collection</code> of names
448 * (or <code>null</code>)
449 * @see #setIssuers
450 * @since 1.5
451 */
452 public Collection<X500Principal> getIssuers() {
453 if (issuerX500Principals == null) {
454 return null;
455 }
456 return Collections.unmodifiableCollection(issuerX500Principals);
457 }
458
459 /**
460 * Returns a copy of the issuerNames criterion. The issuer distinguished
461 * name in the <code>X509CRL</code> must match at least one of the specified
462 * distinguished names. If the value returned is <code>null</code>, any
463 * issuer distinguished name will do.
464 * <p>
465 * If the value returned is not <code>null</code>, it is a
466 * <code>Collection</code> of names. Each name is a <code>String</code>
467 * or a byte array representing a distinguished name (in RFC 2253 or
468 * ASN.1 DER encoded form, respectively). Note that the
469 * <code>Collection</code> returned may contain duplicate names.
470 * <p>
471 * If a name is specified as a byte array, it should contain a single DER
472 * encoded distinguished name, as defined in X.501. The ASN.1 notation for
473 * this structure is given in the documentation for
474 * {@link #setIssuerNames setIssuerNames(Collection names)}.
475 * <p>
476 * Note that a deep copy is performed on the <code>Collection</code> to
477 * protect against subsequent modifications.
478 *
479 * @return a <code>Collection</code> of names (or <code>null</code>)
480 * @see #setIssuerNames
481 */
482 public Collection<Object> getIssuerNames() {
483 if (issuerNames == null) {
484 return null;
485 }
486 return cloneIssuerNames(issuerNames);
487 }
488
489 /**
490 * Returns the minCRLNumber criterion. The <code>X509CRL</code> must have a
491 * CRL number extension whose value is greater than or equal to the
492 * specified value. If <code>null</code>, no minCRLNumber check will be done.
493 *
494 * @return the minimum CRL number accepted (or <code>null</code>)
495 */
496 public BigInteger getMinCRL() {
497 return minCRL;
498 }
499
500 /**
501 * Returns the maxCRLNumber criterion. The <code>X509CRL</code> must have a
502 * CRL number extension whose value is less than or equal to the
503 * specified value. If <code>null</code>, no maxCRLNumber check will be
504 * done.
505 *
506 * @return the maximum CRL number accepted (or <code>null</code>)
507 */
508 public BigInteger getMaxCRL() {
509 return maxCRL;
510 }
511
512 /**
513 * Returns the dateAndTime criterion. The specified date must be
514 * equal to or later than the value of the thisUpdate component
515 * of the <code>X509CRL</code> and earlier than the value of the
516 * nextUpdate component. There is no match if the
517 * <code>X509CRL</code> does not contain a nextUpdate component.
518 * If <code>null</code>, no dateAndTime check will be done.
519 * <p>
520 * Note that the <code>Date</code> returned is cloned to protect against
521 * subsequent modifications.
522 *
523 * @return the <code>Date</code> to match against (or <code>null</code>)
524 * @see #setDateAndTime
525 */
526 public Date getDateAndTime() {
527 if (dateAndTime == null)
528 return null;
529 return (Date) dateAndTime.clone();
530 }
531
532 /**
533 * Returns the certificate being checked. This is not a criterion. Rather,
534 * it is optional information that may help a <code>CertStore</code>
535 * find CRLs that would be relevant when checking revocation for the
536 * specified certificate. If the value returned is <code>null</code>, then
537 * no such optional information is provided.
538 *
539 * @return the certificate being checked (or <code>null</code>)
540 * @see #setCertificateChecking
541 */
542 public X509Certificate getCertificateChecking() {
543 return certChecking;
544 }
545
546 /**
547 * Returns a printable representation of the <code>X509CRLSelector</code>.
548 *
549 * @return a <code>String</code> describing the contents of the
550 * <code>X509CRLSelector</code>.
551 */
552 public String toString() {
553 StringBuffer sb = new StringBuffer();
554 sb.append("X509CRLSelector: [\n");
555 if (issuerNames != null) {
556 sb.append(" IssuerNames:\n");
557 Iterator<Object> i = issuerNames.iterator();
558 while (i.hasNext())
559 sb.append(" " + i.next() + "\n");
560 }
561 if (minCRL != null)
562 sb.append(" minCRLNumber: " + minCRL + "\n");
563 if (maxCRL != null)
564 sb.append(" maxCRLNumber: " + maxCRL + "\n");
565 if (dateAndTime != null)
566 sb.append(" dateAndTime: " + dateAndTime + "\n");
567 if (certChecking != null)
568 sb.append(" Certificate being checked: " + certChecking + "\n");
569 sb.append("]");
570 return sb.toString();
571 }
572
573 /**
574 * Decides whether a <code>CRL</code> should be selected.
575 *
576 * @param crl the <code>CRL</code> to be checked
577 * @return <code>true</code> if the <code>CRL</code> should be selected,
578 * <code>false</code> otherwise
579 */
580 public boolean match(CRL crl) {
581 if (!(crl instanceof X509CRL)) {
582 return false;
583 }
584 X509CRL xcrl = (X509CRL)crl;
585
586 /* match on issuer name */
587 if (issuerNames != null) {
588 X500Principal issuer = xcrl.getIssuerX500Principal();
589 Iterator<X500Principal> i = issuerX500Principals.iterator();
590 boolean found = false;
591 while (!found && i.hasNext()) {
592 if (i.next().equals(issuer)) {
593 found = true;
594 }
595 }
596 if (!found) {
597 if (debug != null) {
598 debug.println("X509CRLSelector.match: issuer DNs "
599 + "don't match");
600 }
601 return false;
602 }
603 }
604
605 if ((minCRL != null) || (maxCRL != null)) {
606 /* Get CRL number extension from CRL */
607 byte[] crlNumExtVal = xcrl.getExtensionValue("2.5.29.20");
608 if (crlNumExtVal == null) {
609 if (debug != null) {
610 debug.println("X509CRLSelector.match: no CRLNumber");
611 }
612 }
613 BigInteger crlNum;
614 try {
615 DerInputStream in = new DerInputStream(crlNumExtVal);
616 byte[] encoded = in.getOctetString();
617 CRLNumberExtension crlNumExt =
618 new CRLNumberExtension(Boolean.FALSE, encoded);
619 crlNum = (BigInteger)crlNumExt.get(CRLNumberExtension.NUMBER);
620 } catch (IOException ex) {
621 if (debug != null) {
622 debug.println("X509CRLSelector.match: exception in "
623 + "decoding CRL number");
624 }
625 return false;
626 }
627
628 /* match on minCRLNumber */
629 if (minCRL != null) {
630 if (crlNum.compareTo(minCRL) < 0) {
631 if (debug != null) {
632 debug.println("X509CRLSelector.match: CRLNumber too small");
633 }
634 return false;
635 }
636 }
637
638 /* match on maxCRLNumber */
639 if (maxCRL != null) {
640 if (crlNum.compareTo(maxCRL) > 0) {
641 if (debug != null) {
642 debug.println("X509CRLSelector.match: CRLNumber too large");
643 }
644 return false;
645 }
646 }
647 }
648
649
650 /* match on dateAndTime */
651 if (dateAndTime != null) {
652 Date crlThisUpdate = xcrl.getThisUpdate();
653 Date nextUpdate = xcrl.getNextUpdate();
654 if (nextUpdate == null) {
655 if (debug != null) {
656 debug.println("X509CRLSelector.match: nextUpdate null");
657 }
658 return false;
659 }
660 if (crlThisUpdate.after(dateAndTime)
661 || nextUpdate.before(dateAndTime)) {
662 if (debug != null) {
663 debug.println("X509CRLSelector.match: update out of range");
664 }
665 return false;
666 }
667 }
668
669 return true;
670 }
671
672 /**
673 * Returns a copy of this object.
674 *
675 * @return the copy
676 */
677 public Object clone() {
678 try {
679 X509CRLSelector copy = (X509CRLSelector)super.clone();
680 if (issuerNames != null) {
681 copy.issuerNames =
682 new HashSet<Object>(issuerNames);
683 copy.issuerX500Principals =
684 new HashSet<X500Principal>(issuerX500Principals);
685 }
686 return copy;
687 } catch (CloneNotSupportedException e) {
688 /* Cannot happen */
689 throw new InternalError(e.toString());
690 }
691 }
692}