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