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