1 package org.bouncycastle.jce.provider; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.math.BigInteger; 6 import java.net.URL; 7 import java.security.GeneralSecurityException; 8 import java.security.KeyFactory; 9 import java.security.PublicKey; 10 import java.security.cert.CRLException; 11 import java.security.cert.CertPath; 12 import java.security.cert.CertPathBuilderException; 13 import java.security.cert.CertPathValidatorException; 14 import java.security.cert.CertStore; 15 import java.security.cert.CertStoreException; 16 import java.security.cert.Certificate; 17 import java.security.cert.CertificateFactory; 18 import java.security.cert.CertificateParsingException; 19 import org.bouncycastle.jce.cert.PolicyQualifierInfo; 20 import org.bouncycastle.jce.cert.TrustAnchor; 21 import java.security.cert.X509CRL; 22 import java.security.cert.X509CRLEntry; 23 import java.security.cert.X509CRLSelector; 24 import java.security.cert.X509CertSelector; 25 import java.security.cert.X509Certificate; 26 import java.security.interfaces.DSAParams; 27 import java.security.interfaces.DSAPublicKey; 28 import java.security.spec.DSAPublicKeySpec; 29 import java.text.ParseException; 30 import java.util.ArrayList; 31 import java.util.Collection; 32 import java.util.Collections; 33 import java.util.Date; 34 import java.util.Enumeration; 35 import java.util.HashSet; 36 import java.util.Iterator; 37 import java.util.HashSet; 38 import java.util.List; 39 import java.util.Map; 40 import java.util.Set; 41 42 import org.bouncycastle.jce.X509Principal; 43 import org.bouncycastle.jce.PrincipalUtil; 44 45 import org.bouncycastle.asn1.ASN1Encodable; 46 import org.bouncycastle.asn1.ASN1Enumerated; 47 import org.bouncycastle.asn1.ASN1GeneralizedTime; 48 import org.bouncycastle.asn1.ASN1Integer; 49 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 50 import org.bouncycastle.asn1.ASN1OctetString; 51 import org.bouncycastle.asn1.ASN1OutputStream; 52 import org.bouncycastle.asn1.ASN1Primitive; 53 import org.bouncycastle.asn1.ASN1Sequence; 54 import org.bouncycastle.asn1.ASN1String; 55 import org.bouncycastle.asn1.DEROctetString; 56 import org.bouncycastle.asn1.DERSequence; 57 import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers; 58 import org.bouncycastle.asn1.x500.X500Name; 59 import org.bouncycastle.asn1.x500.style.RFC4519Style; 60 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 61 import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; 62 import org.bouncycastle.asn1.x509.CRLDistPoint; 63 import org.bouncycastle.asn1.x509.CRLReason; 64 import org.bouncycastle.asn1.x509.DistributionPoint; 65 import org.bouncycastle.asn1.x509.DistributionPointName; 66 import org.bouncycastle.asn1.x509.Extension; 67 import org.bouncycastle.asn1.x509.GeneralName; 68 import org.bouncycastle.asn1.x509.GeneralNames; 69 import org.bouncycastle.asn1.x509.PolicyInformation; 70 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 71 import org.bouncycastle.jcajce.PKIXCRLStore; 72 import org.bouncycastle.jcajce.PKIXCRLStoreSelector; 73 import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters; 74 import org.bouncycastle.jcajce.PKIXCertStore; 75 import org.bouncycastle.jcajce.PKIXCertStoreSelector; 76 import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; 77 import org.bouncycastle.jcajce.PKIXExtendedParameters; 78 import org.bouncycastle.jcajce.util.JcaJceHelper; 79 import org.bouncycastle.jce.exception.ExtCertPathBuilderException; 80 import org.bouncycastle.jce.exception.ExtCertPathValidatorException; 81 import org.bouncycastle.util.Properties; 82 import org.bouncycastle.util.Selector; 83 import org.bouncycastle.util.Store; 84 import org.bouncycastle.util.StoreException; 85 import org.bouncycastle.x509.X509AttributeCertificate; 86 87 class CertPathValidatorUtilities 88 { 89 protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId(); 90 protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId(); 91 protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId(); 92 protected static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId(); 93 protected static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId(); 94 protected static final String KEY_USAGE = Extension.keyUsage.getId(); 95 protected static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId(); 96 protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId(); 97 protected static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId(); 98 protected static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId(); 99 protected static final String FRESHEST_CRL = Extension.freshestCRL.getId(); 100 protected static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId(); 101 protected static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId(); 102 103 protected static final String ANY_POLICY = "2.5.29.32.0"; 104 105 protected static final String CRL_NUMBER = Extension.cRLNumber.getId(); 106 107 /* 108 * key usage bits 109 */ 110 protected static final int KEY_CERT_SIGN = 5; 111 protected static final int CRL_SIGN = 6; 112 113 protected static final String[] crlReasons = new String[]{ 114 "unspecified", 115 "keyCompromise", 116 "cACompromise", 117 "affiliationChanged", 118 "superseded", 119 "cessationOfOperation", 120 "certificateHold", 121 "unknown", 122 "removeFromCRL", 123 "privilegeWithdrawn", 124 "aACompromise"}; 125 findTargets(PKIXExtendedBuilderParameters paramsPKIX)126 static Collection findTargets(PKIXExtendedBuilderParameters paramsPKIX) throws CertPathBuilderException 127 { 128 PKIXExtendedParameters baseParams = paramsPKIX.getBaseParameters(); 129 PKIXCertStoreSelector certSelect = baseParams.getTargetConstraints(); 130 HashSet targets = new HashSet(); 131 132 try 133 { 134 CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertificateStores()); 135 CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertStores()); 136 } 137 catch (AnnotatedException e) 138 { 139 throw new ExtCertPathBuilderException("Error finding target certificate.", e); 140 } 141 142 if (!targets.isEmpty()) 143 { 144 return targets; 145 } 146 147 Certificate target = certSelect.getCertificate(); 148 if (null == target) 149 { 150 throw new CertPathBuilderException("No certificate found matching targetConstraints."); 151 } 152 153 return Collections.singleton(target); 154 } 155 156 /** 157 * Search the given Set of TrustAnchor's for one that is the 158 * issuer of the given X509 certificate. Uses the default provider 159 * for signature verification. 160 * 161 * @param cert the X509 certificate 162 * @param trustAnchors a Set of TrustAnchor's 163 * @return the <code>TrustAnchor</code> object if found or 164 * <code>null</code> if not. 165 * @throws AnnotatedException if a TrustAnchor was found but the signature verification 166 * on the given certificate has thrown an exception. 167 */ findTrustAnchor( X509Certificate cert, Set trustAnchors)168 protected static TrustAnchor findTrustAnchor( 169 X509Certificate cert, 170 Set trustAnchors) 171 throws AnnotatedException 172 { 173 return findTrustAnchor(cert, trustAnchors, null); 174 } 175 176 /** 177 * Search the given Set of TrustAnchor's for one that is the 178 * issuer of the given X509 certificate. Uses the specified 179 * provider for signature verification, or the default provider 180 * if null. 181 * 182 * @param cert the X509 certificate 183 * @param trustAnchors a Set of TrustAnchor's 184 * @param sigProvider the provider to use for signature verification 185 * @return the <code>TrustAnchor</code> object if found or 186 * <code>null</code> if not. 187 * @throws AnnotatedException if a TrustAnchor was found but the signature verification 188 * on the given certificate has thrown an exception. 189 */ findTrustAnchor( X509Certificate cert, Set trustAnchors, String sigProvider)190 protected static TrustAnchor findTrustAnchor( 191 X509Certificate cert, 192 Set trustAnchors, 193 String sigProvider) 194 throws AnnotatedException 195 { 196 TrustAnchor trust = null; 197 PublicKey trustPublicKey = null; 198 Exception invalidKeyEx = null; 199 200 X509CertSelector certSelectX509 = new X509CertSelector(); 201 X509Principal certIssuerPrincipal; 202 try 203 { 204 205 certIssuerPrincipal = PrincipalUtil.getIssuerX509Principal(cert); 206 } 207 catch (Exception e) 208 { 209 throw new AnnotatedException(e.getMessage(), e); 210 } 211 try 212 { 213 certSelectX509.setSubject(certIssuerPrincipal.getEncoded()); 214 } 215 catch (Exception e) 216 { 217 throw new AnnotatedException(e.getMessage(), e); 218 } 219 220 X500Name certIssuerName = null; 221 222 Iterator iter = trustAnchors.iterator(); 223 while (iter.hasNext() && trust == null) 224 { 225 trust = (TrustAnchor)iter.next(); 226 if (trust.getTrustedCert() != null) 227 { 228 if (certSelectX509.match(trust.getTrustedCert())) 229 { 230 trustPublicKey = trust.getTrustedCert().getPublicKey(); 231 } 232 else 233 { 234 trust = null; 235 } 236 } 237 else if (trust.getCAName() != null 238 && trust.getCAPublicKey() != null) 239 { 240 if (certIssuerName == null) 241 { 242 certIssuerName = X500Name.getInstance(certIssuerPrincipal.getEncoded()); 243 } 244 245 try 246 { 247 X500Name caName = X500Name.getInstance(new X509Principal(trust.getCAName()).getEncoded()); 248 249 if (certIssuerName.equals(caName)) 250 { 251 trustPublicKey = trust.getCAPublicKey(); 252 } 253 else 254 { 255 trust = null; 256 } 257 } 258 catch (IllegalArgumentException ex) 259 { 260 trust = null; 261 } 262 } 263 else 264 { 265 trust = null; 266 } 267 268 if (trustPublicKey != null) 269 { 270 try 271 { 272 verifyX509Certificate(cert, trustPublicKey, sigProvider); 273 } 274 catch (Exception ex) 275 { 276 invalidKeyEx = ex; 277 trust = null; 278 trustPublicKey = null; 279 } 280 } 281 } 282 283 if (trust == null && invalidKeyEx != null) 284 { 285 throw new AnnotatedException("TrustAnchor found but certificate validation failed.", invalidKeyEx); 286 } 287 288 return trust; 289 } 290 isIssuerTrustAnchor( X509Certificate cert, Set trustAnchors, String sigProvider)291 static boolean isIssuerTrustAnchor( 292 X509Certificate cert, 293 Set trustAnchors, 294 String sigProvider) 295 throws AnnotatedException 296 { 297 try 298 { 299 return findTrustAnchor(cert, trustAnchors, sigProvider) != null; 300 } 301 catch (Exception e) 302 { 303 return false; 304 } 305 } 306 getAdditionalStoresFromAltNames( byte[] issuerAlternativeName, Map<GeneralName, PKIXCertStore> altNameCertStoreMap)307 static List<PKIXCertStore> getAdditionalStoresFromAltNames( 308 byte[] issuerAlternativeName, 309 Map<GeneralName, PKIXCertStore> altNameCertStoreMap) 310 throws CertificateParsingException 311 { 312 // if in the IssuerAltName extension an URL 313 // is given, add an additional X.509 store 314 if (issuerAlternativeName == null) 315 { 316 return Collections.EMPTY_LIST; 317 } 318 319 GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets()); 320 321 GeneralName[] names = issuerAltName.getNames(); 322 List stores = new ArrayList(); 323 324 for (int i = 0; i != names.length; i++) 325 { 326 GeneralName altName = names[i]; 327 328 PKIXCertStore altStore = (PKIXCertStore)altNameCertStoreMap.get(altName); 329 if (altStore != null) 330 { 331 stores.add(altStore); 332 } 333 } 334 335 return stores; 336 } 337 getValidityDate(PKIXExtendedParameters paramsPKIX, Date currentDate)338 protected static Date getValidityDate(PKIXExtendedParameters paramsPKIX, Date currentDate) 339 { 340 Date validityDate = paramsPKIX.getValidityDate(); 341 342 return null == validityDate ? currentDate : validityDate; 343 } 344 isSelfIssued(X509Certificate cert)345 protected static boolean isSelfIssued(X509Certificate cert) 346 { 347 return cert.getSubjectDN().equals(cert.getIssuerDN()); 348 } 349 350 /** 351 * Extract the value of the given extension, if it exists. 352 * 353 * @param ext The extension object. 354 * @param oid The object identifier to obtain. 355 * @throws AnnotatedException if the extension cannot be read. 356 */ getExtensionValue(java.security.cert.X509Extension ext, String oid)357 protected static ASN1Primitive getExtensionValue(java.security.cert.X509Extension ext, String oid) 358 throws AnnotatedException 359 { 360 byte[] bytes = ext.getExtensionValue(oid); 361 362 return null == bytes ? null : getObject(oid, bytes); 363 } 364 getObject(String oid, byte[] ext)365 private static ASN1Primitive getObject(String oid, byte[] ext) throws AnnotatedException 366 { 367 try 368 { 369 ASN1OctetString octs = ASN1OctetString.getInstance(ext); 370 371 return ASN1Primitive.fromByteArray(octs.getOctets()); 372 } 373 catch (Exception e) 374 { 375 throw new AnnotatedException("exception processing extension " + oid, e); 376 } 377 } 378 getAlgorithmIdentifier(PublicKey key)379 protected static AlgorithmIdentifier getAlgorithmIdentifier(PublicKey key) throws CertPathValidatorException 380 { 381 try 382 { 383 return SubjectPublicKeyInfo.getInstance(key.getEncoded()).getAlgorithm(); 384 } 385 catch (Exception e) 386 { 387 throw new ExtCertPathValidatorException("Subject public key cannot be decoded.", e); 388 } 389 } 390 391 // crl checking 392 393 394 // 395 // policy checking 396 // 397 getQualifierSet(ASN1Sequence qualifiers)398 protected static final Set getQualifierSet(ASN1Sequence qualifiers) 399 throws CertPathValidatorException 400 { 401 Set pq = new HashSet(); 402 403 if (qualifiers == null) 404 { 405 return pq; 406 } 407 408 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 409 ASN1OutputStream aOut = ASN1OutputStream.create(bOut); 410 411 Enumeration e = qualifiers.getObjects(); 412 while (e.hasMoreElements()) 413 { 414 try 415 { 416 aOut.writeObject((ASN1Encodable)e.nextElement()); 417 418 pq.add(new PolicyQualifierInfo(bOut.toByteArray())); 419 } 420 catch (IOException ex) 421 { 422 throw new ExtCertPathValidatorException("Policy qualifier info cannot be decoded.", ex); 423 } 424 425 bOut.reset(); 426 } 427 428 return pq; 429 } 430 removePolicyNode( PKIXPolicyNode validPolicyTree, List[] policyNodes, PKIXPolicyNode _node)431 protected static PKIXPolicyNode removePolicyNode( 432 PKIXPolicyNode validPolicyTree, 433 List[] policyNodes, 434 PKIXPolicyNode _node) 435 { 436 PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent(); 437 438 if (validPolicyTree == null) 439 { 440 return null; 441 } 442 443 if (_parent == null) 444 { 445 for (int j = 0; j < policyNodes.length; j++) 446 { 447 policyNodes[j] = new ArrayList(); 448 } 449 450 return null; 451 } 452 else 453 { 454 _parent.removeChild(_node); 455 removePolicyNodeRecurse(policyNodes, _node); 456 457 return validPolicyTree; 458 } 459 } 460 removePolicyNodeRecurse( List[] policyNodes, PKIXPolicyNode _node)461 private static void removePolicyNodeRecurse( 462 List[] policyNodes, 463 PKIXPolicyNode _node) 464 { 465 policyNodes[_node.getDepth()].remove(_node); 466 467 if (_node.hasChildren()) 468 { 469 Iterator _iter = _node.getChildren(); 470 while (_iter.hasNext()) 471 { 472 PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next(); 473 removePolicyNodeRecurse(policyNodes, _child); 474 } 475 } 476 } 477 478 processCertD1i( int index, List[] policyNodes, ASN1ObjectIdentifier pOid, Set pq)479 protected static boolean processCertD1i( 480 int index, 481 List[] policyNodes, 482 ASN1ObjectIdentifier pOid, 483 Set pq) 484 { 485 List policyNodeVec = policyNodes[index - 1]; 486 487 for (int j = 0; j < policyNodeVec.size(); j++) 488 { 489 PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j); 490 Set expectedPolicies = node.getExpectedPolicies(); 491 492 if (expectedPolicies.contains(pOid.getId())) 493 { 494 Set childExpectedPolicies = new HashSet(); 495 childExpectedPolicies.add(pOid.getId()); 496 497 PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(), 498 index, 499 childExpectedPolicies, 500 node, 501 pq, 502 pOid.getId(), 503 false); 504 node.addChild(child); 505 policyNodes[index].add(child); 506 507 return true; 508 } 509 } 510 511 return false; 512 } 513 processCertD1ii( int index, List[] policyNodes, ASN1ObjectIdentifier _poid, Set _pq)514 protected static void processCertD1ii( 515 int index, 516 List[] policyNodes, 517 ASN1ObjectIdentifier _poid, 518 Set _pq) 519 { 520 List policyNodeVec = policyNodes[index - 1]; 521 522 for (int j = 0; j < policyNodeVec.size(); j++) 523 { 524 PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j); 525 526 if (ANY_POLICY.equals(_node.getValidPolicy())) 527 { 528 Set _childExpectedPolicies = new HashSet(); 529 _childExpectedPolicies.add(_poid.getId()); 530 531 PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(), 532 index, 533 _childExpectedPolicies, 534 _node, 535 _pq, 536 _poid.getId(), 537 false); 538 _node.addChild(_child); 539 policyNodes[index].add(_child); 540 return; 541 } 542 } 543 } 544 prepareNextCertB1( int i, List[] policyNodes, String id_p, Map m_idp, X509Certificate cert )545 protected static void prepareNextCertB1( 546 int i, 547 List[] policyNodes, 548 String id_p, 549 Map m_idp, 550 X509Certificate cert 551 ) 552 throws AnnotatedException, CertPathValidatorException 553 { 554 boolean idp_found = false; 555 Iterator nodes_i = policyNodes[i].iterator(); 556 while (nodes_i.hasNext()) 557 { 558 PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); 559 if (node.getValidPolicy().equals(id_p)) 560 { 561 idp_found = true; 562 node.expectedPolicies = (Set)m_idp.get(id_p); 563 break; 564 } 565 } 566 567 if (!idp_found) 568 { 569 nodes_i = policyNodes[i].iterator(); 570 while (nodes_i.hasNext()) 571 { 572 PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); 573 if (ANY_POLICY.equals(node.getValidPolicy())) 574 { 575 Set pq = null; 576 ASN1Sequence policies = null; 577 try 578 { 579 policies = DERSequence.getInstance(getExtensionValue(cert, CERTIFICATE_POLICIES)); 580 } 581 catch (Exception e) 582 { 583 throw new AnnotatedException("Certificate policies cannot be decoded.", e); 584 } 585 Enumeration e = policies.getObjects(); 586 while (e.hasMoreElements()) 587 { 588 PolicyInformation pinfo = null; 589 590 try 591 { 592 pinfo = PolicyInformation.getInstance(e.nextElement()); 593 } 594 catch (Exception ex) 595 { 596 throw new AnnotatedException("Policy information cannot be decoded.", ex); 597 } 598 if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) 599 { 600 try 601 { 602 pq = getQualifierSet(pinfo.getPolicyQualifiers()); 603 } 604 catch (CertPathValidatorException ex) 605 { 606 throw new ExtCertPathValidatorException( 607 "Policy qualifier info set could not be built.", ex); 608 } 609 break; 610 } 611 } 612 boolean ci = false; 613 if (cert.getCriticalExtensionOIDs() != null) 614 { 615 ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES); 616 } 617 618 PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); 619 if (ANY_POLICY.equals(p_node.getValidPolicy())) 620 { 621 PKIXPolicyNode c_node = new PKIXPolicyNode( 622 new ArrayList(), i, 623 (Set)m_idp.get(id_p), 624 p_node, pq, id_p, ci); 625 p_node.addChild(c_node); 626 policyNodes[i].add(c_node); 627 } 628 break; 629 } 630 } 631 } 632 } 633 prepareNextCertB2( int i, List[] policyNodes, String id_p, PKIXPolicyNode validPolicyTree)634 protected static PKIXPolicyNode prepareNextCertB2( 635 int i, 636 List[] policyNodes, 637 String id_p, 638 PKIXPolicyNode validPolicyTree) 639 { 640 Iterator nodes_i = policyNodes[i].iterator(); 641 while (nodes_i.hasNext()) 642 { 643 PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); 644 if (node.getValidPolicy().equals(id_p)) 645 { 646 PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); 647 p_node.removeChild(node); 648 nodes_i.remove(); 649 for (int k = (i - 1); k >= 0; k--) 650 { 651 List nodes = policyNodes[k]; 652 for (int l = 0; l < nodes.size(); l++) 653 { 654 PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); 655 if (!node2.hasChildren()) 656 { 657 validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2); 658 if (validPolicyTree == null) 659 { 660 break; 661 } 662 } 663 } 664 } 665 } 666 } 667 return validPolicyTree; 668 } 669 isAnyPolicy( Set policySet)670 protected static boolean isAnyPolicy( 671 Set policySet) 672 { 673 return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); 674 } 675 676 /** 677 * Return a Collection of all certificates or attribute certificates found in the X509Store's 678 * that are matching the certSelect criteriums. 679 * 680 * @param certs 681 * a {@link HashSet} to which the certificates will be added. 682 * @param certSelect 683 * a {@link Selector} object that will be used to select the certificates 684 * @param certStores 685 * a List containing only {@link Store} objects. These are used to search for 686 * certificates. 687 * @return a Collection of all found {@link X509Certificate} May be empty but never 688 * <code>null</code>. 689 */ findCertificates(HashSet certs, PKIXCertStoreSelector certSelect, List certStores)690 protected static void findCertificates(HashSet certs, PKIXCertStoreSelector certSelect, List certStores) 691 throws AnnotatedException 692 { 693 Iterator iter = certStores.iterator(); 694 while (iter.hasNext()) 695 { 696 Object obj = iter.next(); 697 if (obj instanceof Store) 698 { 699 Store certStore = (Store)obj; 700 try 701 { 702 certs.addAll(certStore.getMatches(certSelect)); 703 } 704 catch (StoreException e) 705 { 706 throw new AnnotatedException("Problem while picking certificates from X.509 store.", e); 707 } 708 } 709 else 710 { 711 CertStore certStore = (CertStore)obj; 712 try 713 { 714 certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore)); 715 } 716 catch (CertStoreException e) 717 { 718 throw new AnnotatedException("Problem while picking certificates from certificate store.", e); 719 } 720 } 721 } 722 } 723 getAdditionalStoresFromCRLDistributionPoint( CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap, Date validDate, JcaJceHelper helper)724 static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint( 725 CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap, Date validDate, JcaJceHelper helper) 726 throws AnnotatedException 727 { 728 if (null == crldp) 729 { 730 return Collections.EMPTY_LIST; 731 } 732 733 DistributionPoint dps[]; 734 try 735 { 736 dps = crldp.getDistributionPoints(); 737 } 738 catch (Exception e) 739 { 740 throw new AnnotatedException("Distribution points could not be read.", e); 741 } 742 743 List stores = new ArrayList(); 744 745 for (int i = 0; i < dps.length; i++) 746 { 747 DistributionPointName dpn = dps[i].getDistributionPoint(); 748 // look for URLs in fullName 749 if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME) 750 { 751 GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames(); 752 753 for (int j = 0; j < genNames.length; j++) 754 { 755 PKIXCRLStore store = (PKIXCRLStore)namedCRLStoreMap.get(genNames[j]); 756 if (store != null) 757 { 758 stores.add(store); 759 } 760 } 761 } 762 } 763 764 // if the named CRL store is empty, and we're told to check with CRLDP 765 if (stores.isEmpty() && Properties.isOverrideSet("org.bouncycastle.x509.enableCRLDP")) 766 { 767 CertificateFactory certFact; 768 try 769 { 770 certFact = helper.createCertificateFactory("X.509"); 771 } 772 catch (Exception e) 773 { 774 throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e); 775 } 776 777 for (int i = 0; i < dps.length; i++) 778 { 779 DistributionPointName dpn = dps[i].getDistributionPoint(); 780 // look for URLs in fullName 781 if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME) 782 { 783 GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames(); 784 785 for (int j = 0; j < genNames.length; j++) 786 { 787 GeneralName name = genNames[i]; 788 if (name.getTagNo() == GeneralName.uniformResourceIdentifier) 789 { 790 try 791 { 792 URL distributionPoint = new URL(((ASN1String)name.getName()).getString()); 793 PKIXCRLStore store = CrlCache.getCrl(certFact, validDate, distributionPoint); 794 if (store != null) 795 { 796 stores.add(store); 797 } 798 break; 799 } 800 catch (Exception e) 801 { 802 // ignore... TODO: maybe log 803 } 804 } 805 } 806 } 807 } 808 } 809 810 return stores; 811 } 812 813 /** 814 * Add the CRL issuers from the cRLIssuer field of the distribution point or 815 * from the certificate if not given to the issuer criterion of the 816 * <code>selector</code>. 817 * <p> 818 * The <code>issuerPrincipals</code> are a collection with a single 819 * <code>X500Name</code> for <code>X509Certificate</code>s. 820 * </p> 821 * @param dp The distribution point. 822 * @param issuerPrincipals The issuers of the certificate or attribute 823 * certificate which contains the distribution point. 824 * @param selector The CRL selector. 825 * @throws AnnotatedException if an exception occurs while processing. 826 * @throws ClassCastException if <code>issuerPrincipals</code> does not 827 * contain only <code>X500Name</code>s. 828 */ getCRLIssuersFromDistributionPoint( DistributionPoint dp, Collection issuerPrincipals, X509CRLSelector selector)829 protected static void getCRLIssuersFromDistributionPoint( 830 DistributionPoint dp, 831 Collection issuerPrincipals, 832 X509CRLSelector selector) 833 throws AnnotatedException 834 { 835 List issuers = new ArrayList(); 836 // indirect CRL 837 if (dp.getCRLIssuer() != null) 838 { 839 GeneralName genNames[] = dp.getCRLIssuer().getNames(); 840 // look for a DN 841 for (int j = 0; j < genNames.length; j++) 842 { 843 if (genNames[j].getTagNo() == GeneralName.directoryName) 844 { 845 try 846 { 847 issuers.add(X500Name.getInstance(genNames[j].getName().toASN1Primitive().getEncoded())); 848 } 849 catch (IOException e) 850 { 851 throw new AnnotatedException( 852 "CRL issuer information from distribution point cannot be decoded.", e); 853 } 854 } 855 } 856 } 857 else 858 { 859 /* 860 * certificate issuer is CRL issuer, distributionPoint field MUST be 861 * present. 862 */ 863 if (dp.getDistributionPoint() == null) 864 { 865 throw new AnnotatedException( 866 "CRL issuer is omitted from distribution point but no distributionPoint field present."); 867 } 868 // add and check issuer principals 869 for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); ) 870 { 871 issuers.add(it.next()); 872 } 873 } 874 // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid 875 // distributionPoint 876 // if (dp.getDistributionPoint() != null) 877 // { 878 // // look for nameRelativeToCRLIssuer 879 // if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) 880 // { 881 // // append fragment to issuer, only one 882 // // issuer can be there, if this is given 883 // if (issuers.size() != 1) 884 // { 885 // throw new AnnotatedException( 886 // "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given."); 887 // } 888 // ASN1Encodable relName = dp.getDistributionPoint().getName(); 889 // Iterator it = issuers.iterator(); 890 // List issuersTemp = new ArrayList(issuers.size()); 891 // while (it.hasNext()) 892 // { 893 // Enumeration e = null; 894 // try 895 // { 896 // e = ASN1Sequence.getInstance( 897 // new ASN1InputStream(((X509Principal) it.next()) 898 // .getEncoded()).readObject()).getObjects(); 899 // } 900 // catch (IOException ex) 901 // { 902 // throw new AnnotatedException( 903 // "Cannot decode CRL issuer information.", ex); 904 // } 905 // ASN1EncodableVector v = new ASN1EncodableVector(); 906 // while (e.hasMoreElements()) 907 // { 908 // v.add((ASN1Encodable) e.nextElement()); 909 // } 910 // v.add(relName); 911 // issuersTemp.add(new X509Principal(new DERSequence(v) 912 // .getDEREncoded())); 913 // } 914 // issuers.clear(); 915 // issuers.addAll(issuersTemp); 916 // } 917 // } 918 Iterator it = issuers.iterator(); 919 while (it.hasNext()) 920 { 921 try 922 { 923 selector.addIssuerName(((X500Name)it.next()).getEncoded()); 924 } 925 catch (IOException ex) 926 { 927 throw new AnnotatedException( 928 "Cannot decode CRL issuer information.", ex); 929 } 930 } 931 } 932 getSerialNumber(Object cert)933 private static BigInteger getSerialNumber(Object cert) 934 { 935 return ((X509Certificate)cert).getSerialNumber(); 936 } 937 getCertStatus( Date validDate, X509CRL crl, Object cert, CertStatus certStatus)938 protected static void getCertStatus( 939 Date validDate, 940 X509CRL crl, 941 Object cert, 942 CertStatus certStatus) 943 throws AnnotatedException 944 { 945 boolean isIndirect; 946 try 947 { 948 isIndirect = X509CRLObject.isIndirectCRL(crl); 949 } 950 catch (CRLException exception) 951 { 952 throw new AnnotatedException("Failed check for indirect CRL.", exception); 953 } 954 955 X509CRLEntry crl_entry; 956 if (isIndirect) 957 { 958 crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); 959 960 if (crl_entry == null) 961 { 962 return; 963 } 964 965 X509Principal certificateIssuer = ((X509CRLEntryObject)crl_entry).getCertificateIssuer(); 966 967 X500Name certIssuer; 968 if (certificateIssuer == null) 969 { 970 certIssuer = PrincipalUtils.getIssuerPrincipal(crl); 971 } 972 else 973 { 974 try 975 { 976 certIssuer = X500Name.getInstance(certificateIssuer.getEncoded()); 977 } 978 catch (Exception e) 979 { 980 throw new AnnotatedException(e.toString(), e); 981 } 982 } 983 984 if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer)) 985 { 986 return; 987 } 988 } 989 else if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl))) 990 { 991 return; // not for our issuer, ignore 992 } 993 else 994 { 995 crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); 996 997 if (crl_entry == null) 998 { 999 return; 1000 } 1001 } 1002 1003 ASN1Enumerated reasonCode = null; 1004 if (crl_entry.hasExtensions()) 1005 { 1006 if (crl_entry.hasUnsupportedCriticalExtension()) 1007 { 1008 throw new AnnotatedException("CRL entry has unsupported critical extensions."); 1009 } 1010 1011 try 1012 { 1013 reasonCode = ASN1Enumerated 1014 .getInstance(CertPathValidatorUtilities.getExtensionValue(crl_entry, Extension.reasonCode.getId())); 1015 } 1016 catch (Exception e) 1017 { 1018 throw new AnnotatedException("Reason code CRL entry extension could not be decoded.", e); 1019 } 1020 } 1021 1022 int reasonCodeValue = (null == reasonCode) 1023 ? CRLReason.unspecified 1024 : reasonCode.intValueExact(); 1025 1026 // for reason keyCompromise, caCompromise, aACompromise or unspecified 1027 if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime()) 1028 || reasonCodeValue == CRLReason.unspecified 1029 || reasonCodeValue == CRLReason.keyCompromise 1030 || reasonCodeValue == CRLReason.cACompromise 1031 || reasonCodeValue == CRLReason.aACompromise) 1032 { 1033 // (i) or (j) 1034 certStatus.setCertStatus(reasonCodeValue); 1035 certStatus.setRevocationDate(crl_entry.getRevocationDate()); 1036 } 1037 } 1038 1039 /** 1040 * Fetches delta CRLs according to RFC 3280 section 5.2.4. 1041 * 1042 * @param validityDate The date for which the delta CRLs must be valid. 1043 * @param completeCRL The complete CRL the delta CRL is for. 1044 * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs. 1045 * @throws AnnotatedException if an exception occurs while picking the delta 1046 * CRLs. 1047 */ getDeltaCRLs(Date validityDate, X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores, JcaJceHelper helper)1048 protected static Set getDeltaCRLs(Date validityDate, 1049 X509CRL completeCRL, 1050 List<CertStore> certStores, 1051 List<PKIXCRLStore> pkixCrlStores, 1052 JcaJceHelper helper) 1053 throws AnnotatedException 1054 { 1055 X509CRLSelector baseDeltaSelect = new X509CRLSelector(); 1056 // 5.2.4 (a) 1057 try 1058 { 1059 baseDeltaSelect.addIssuerName(PrincipalUtils.getIssuerPrincipal(completeCRL).getEncoded()); 1060 } 1061 catch (IOException e) 1062 { 1063 throw new AnnotatedException("Cannot extract issuer from CRL.", e); 1064 } 1065 1066 BigInteger completeCRLNumber = null; 1067 try 1068 { 1069 ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL, CRL_NUMBER); 1070 if (derObject != null) 1071 { 1072 completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue(); 1073 } 1074 } 1075 catch (Exception e) 1076 { 1077 throw new AnnotatedException( 1078 "CRL number extension could not be extracted from CRL.", e); 1079 } 1080 1081 // 5.2.4 (b) 1082 byte[] idp; 1083 try 1084 { 1085 idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT); 1086 } 1087 catch (Exception e) 1088 { 1089 throw new AnnotatedException("Issuing distribution point extension value could not be read.", e); 1090 } 1091 1092 // 5.2.4 (d) 1093 1094 baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber.add(BigInteger.valueOf(1))); 1095 1096 PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect); 1097 1098 selBuilder.setIssuingDistributionPoint(idp); 1099 selBuilder.setIssuingDistributionPointEnabled(true); 1100 1101 // 5.2.4 (c) 1102 selBuilder.setMaxBaseCRLNumber(completeCRLNumber); 1103 1104 PKIXCRLStoreSelector deltaSelect = selBuilder.build(); 1105 1106 // find delta CRLs 1107 Set temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores); 1108 1109 // if the named CRL store is empty, and we're told to check with CRLDP 1110 if (temp.isEmpty() && Properties.isOverrideSet("org.bouncycastle.x509.enableCRLDP")) 1111 { 1112 CertificateFactory certFact; 1113 try 1114 { 1115 certFact = helper.createCertificateFactory("X.509"); 1116 } 1117 catch (Exception e) 1118 { 1119 throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e); 1120 } 1121 1122 CRLDistPoint id = CRLDistPoint.getInstance(idp); 1123 DistributionPoint[] dps = id.getDistributionPoints(); 1124 for (int i = 0; i < dps.length; i++) 1125 { 1126 DistributionPointName dpn = dps[i].getDistributionPoint(); 1127 // look for URLs in fullName 1128 if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME) 1129 { 1130 GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames(); 1131 1132 for (int j = 0; j < genNames.length; j++) 1133 { 1134 GeneralName name = genNames[i]; 1135 if (name.getTagNo() == GeneralName.uniformResourceIdentifier) 1136 { 1137 try 1138 { 1139 PKIXCRLStore store = CrlCache.getCrl(certFact, validityDate, 1140 new URL(((ASN1String)name.getName()).getString())); 1141 if (store != null) 1142 { 1143 ArrayList ls = new ArrayList(); 1144 ls.add(store); 1145 temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, Collections.EMPTY_LIST, 1146 ls); 1147 } 1148 break; 1149 } 1150 catch (Exception e) 1151 { 1152 // ignore... TODO: maybe log 1153 } 1154 } 1155 } 1156 } 1157 } 1158 } 1159 1160 Set result = new HashSet(); 1161 1162 for (Iterator it = temp.iterator(); it.hasNext(); ) 1163 { 1164 X509CRL crl = (X509CRL)it.next(); 1165 1166 if (isDeltaCRL(crl)) 1167 { 1168 result.add(crl); 1169 } 1170 } 1171 1172 return result; 1173 } 1174 isDeltaCRL(X509CRL crl)1175 private static boolean isDeltaCRL(X509CRL crl) 1176 { 1177 Set critical = crl.getCriticalExtensionOIDs(); 1178 1179 if (critical == null) 1180 { 1181 return false; 1182 } 1183 1184 return critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); 1185 } 1186 1187 /** 1188 * Fetches complete CRLs according to RFC 3280. 1189 * 1190 * @param dp The distribution point for which the complete CRL 1191 * @param cert The <code>X509Certificate</code> for 1192 * which the CRL should be searched. 1193 * @param currentDate The date for which the delta CRLs must be valid. 1194 * @param paramsPKIX The extended PKIX parameters. 1195 * @return A <code>Set</code> of <code>X509CRL</code>s with complete 1196 * CRLs. 1197 * @throws AnnotatedException if an exception occurs while picking the CRLs 1198 * or no CRLs are found. 1199 */ getCompleteCRLs(PKIXCertRevocationCheckerParameters params, DistributionPoint dp, Object cert, PKIXExtendedParameters paramsPKIX, Date validityDate)1200 protected static Set getCompleteCRLs(PKIXCertRevocationCheckerParameters params, DistributionPoint dp, Object cert, 1201 PKIXExtendedParameters paramsPKIX, Date validityDate) 1202 throws AnnotatedException, RecoverableCertPathValidatorException 1203 { 1204 X509CRLSelector baseCrlSelect = new X509CRLSelector(); 1205 1206 try 1207 { 1208 Set issuers = new HashSet(); 1209 issuers.add(PrincipalUtils.getEncodedIssuerPrincipal(cert)); 1210 1211 CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect); 1212 } 1213 catch (AnnotatedException e) 1214 { 1215 throw new AnnotatedException("Could not get issuer information from distribution point.", e); 1216 } 1217 1218 if (cert instanceof X509Certificate) 1219 { 1220 baseCrlSelect.setCertificateChecking((X509Certificate)cert); 1221 } 1222 1223 PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true) 1224 .build(); 1225 1226 Set crls = PKIXCRLUtil.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()); 1227 1228 checkCRLsNotEmpty(params, crls, cert); 1229 1230 return crls; 1231 } 1232 getValidCertDateFromValidityModel(Date validityDate, int validityModel, CertPath certPath, int index)1233 protected static Date getValidCertDateFromValidityModel(Date validityDate, int validityModel, CertPath certPath, 1234 int index) throws AnnotatedException 1235 { 1236 if (PKIXExtendedParameters.CHAIN_VALIDITY_MODEL != validityModel || index <= 0) 1237 { 1238 // use given signing/encryption/... time (or current date) 1239 return validityDate; 1240 } 1241 1242 X509Certificate issuedCert = (X509Certificate)certPath.getCertificates().get(index - 1); 1243 1244 if (index - 1 == 0) 1245 { 1246 // use time when cert was issued, if available 1247 ASN1GeneralizedTime dateOfCertgen = null; 1248 try 1249 { 1250 byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)) 1251 .getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId()); 1252 if (extBytes != null) 1253 { 1254 dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes)); 1255 } 1256 } 1257 catch (IOException e) 1258 { 1259 throw new AnnotatedException("Date of cert gen extension could not be read."); 1260 } 1261 catch (IllegalArgumentException e) 1262 { 1263 throw new AnnotatedException("Date of cert gen extension could not be read."); 1264 } 1265 if (dateOfCertgen != null) 1266 { 1267 try 1268 { 1269 return dateOfCertgen.getDate(); 1270 } 1271 catch (ParseException e) 1272 { 1273 throw new AnnotatedException("Date from date of cert gen extension could not be parsed.", e); 1274 } 1275 } 1276 } 1277 1278 return issuedCert.getNotBefore(); 1279 } 1280 1281 /** 1282 * Return the next working key inheriting DSA parameters if necessary. 1283 * <p> 1284 * This methods inherits DSA parameters from the indexed certificate or 1285 * previous certificates in the certificate chain to the returned 1286 * <code>PublicKey</code>. The list is searched upwards, meaning the end 1287 * certificate is at position 0 and previous certificates are following. 1288 * </p> 1289 * <p> 1290 * If the indexed certificate does not contain a DSA key this method simply 1291 * returns the public key. If the DSA key already contains DSA parameters 1292 * the key is also only returned. 1293 * </p> 1294 * 1295 * @param certs The certification path. 1296 * @param index The index of the certificate which contains the public key 1297 * which should be extended with DSA parameters. 1298 * @return The public key of the certificate in list position 1299 * <code>index</code> extended with DSA parameters if applicable. 1300 * @throws AnnotatedException if DSA parameters cannot be inherited. 1301 */ getNextWorkingKey(List certs, int index, JcaJceHelper helper)1302 protected static PublicKey getNextWorkingKey(List certs, int index, JcaJceHelper helper) 1303 throws CertPathValidatorException 1304 { 1305 Certificate cert = (Certificate)certs.get(index); 1306 PublicKey pubKey = cert.getPublicKey(); 1307 if (!(pubKey instanceof DSAPublicKey)) 1308 { 1309 return pubKey; 1310 } 1311 DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey; 1312 if (dsaPubKey.getParams() != null) 1313 { 1314 return dsaPubKey; 1315 } 1316 for (int i = index + 1; i < certs.size(); i++) 1317 { 1318 X509Certificate parentCert = (X509Certificate)certs.get(i); 1319 pubKey = parentCert.getPublicKey(); 1320 if (!(pubKey instanceof DSAPublicKey)) 1321 { 1322 throw new CertPathValidatorException( 1323 "DSA parameters cannot be inherited from previous certificate."); 1324 } 1325 DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey; 1326 if (prevDSAPubKey.getParams() == null) 1327 { 1328 continue; 1329 } 1330 DSAParams dsaParams = prevDSAPubKey.getParams(); 1331 DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec( 1332 dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); 1333 try 1334 { 1335 KeyFactory keyFactory = helper.createKeyFactory("DSA"); 1336 return keyFactory.generatePublic(dsaPubKeySpec); 1337 } 1338 catch (Exception exception) 1339 { 1340 throw new RuntimeException(exception.getMessage()); 1341 } 1342 } 1343 throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate."); 1344 } 1345 1346 /** 1347 * Find the issuer certificates of a given certificate. 1348 * 1349 * @param cert The certificate for which an issuer should be found. 1350 * @return A <code>Collection</code> object containing the issuer 1351 * <code>X509Certificate</code>s. Never <code>null</code>. 1352 * @throws AnnotatedException if an error occurs. 1353 */ findIssuerCerts( X509Certificate cert, List<CertStore> certStores, List<PKIXCertStore> pkixCertStores)1354 static Collection findIssuerCerts( 1355 X509Certificate cert, 1356 List<CertStore> certStores, 1357 List<PKIXCertStore> pkixCertStores) 1358 throws AnnotatedException 1359 { 1360 X509CertSelector selector = new X509CertSelector(); 1361 1362 try 1363 { 1364 selector.setSubject(PrincipalUtils.getIssuerPrincipal(cert).getEncoded()); 1365 } 1366 catch (Exception e) 1367 { 1368 throw new AnnotatedException( 1369 "Subject criteria for certificate selector to find issuer certificate could not be set.", e); 1370 } 1371 1372 try 1373 { 1374 byte[] akiExtensionValue = cert.getExtensionValue(AUTHORITY_KEY_IDENTIFIER); 1375 if (akiExtensionValue != null) 1376 { 1377 ASN1OctetString aki = ASN1OctetString.getInstance(akiExtensionValue); 1378 byte[] authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(aki.getOctets()).getKeyIdentifier(); 1379 if (authorityKeyIdentifier != null) 1380 { 1381 selector.setSubjectKeyIdentifier(new DEROctetString(authorityKeyIdentifier).getEncoded()); 1382 } 1383 } 1384 } 1385 catch (Exception e) 1386 { 1387 // authority key identifier could not be retrieved from target cert, just search without it 1388 } 1389 1390 PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build(); 1391 HashSet certs = new HashSet(); 1392 1393 try 1394 { 1395 CertPathValidatorUtilities.findCertificates(certs, certSelect, certStores); 1396 CertPathValidatorUtilities.findCertificates(certs, certSelect, pkixCertStores); 1397 } 1398 catch (AnnotatedException e) 1399 { 1400 throw new AnnotatedException("Issuer certificate cannot be searched.", e); 1401 } 1402 1403 // issuers cannot be verified because possible DSA inheritance parameters are missing 1404 1405 return certs; 1406 } 1407 verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider)1408 protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider) 1409 throws Exception 1410 { 1411 if (sigProvider == null) 1412 { 1413 cert.verify(publicKey); 1414 } 1415 else 1416 { 1417 cert.verify(publicKey, sigProvider); 1418 } 1419 } 1420 checkCRLsNotEmpty(PKIXCertRevocationCheckerParameters params, Set crls, Object cert)1421 static void checkCRLsNotEmpty(PKIXCertRevocationCheckerParameters params, Set crls, Object cert) 1422 throws RecoverableCertPathValidatorException 1423 { 1424 if (crls.isEmpty()) 1425 { 1426 if (cert instanceof X509AttributeCertificate) 1427 { 1428 X509AttributeCertificate aCert = (X509AttributeCertificate)cert; 1429 1430 throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"", null, 1431 params.getCertPath(), params.getIndex()); 1432 } 1433 else 1434 { 1435 X509Certificate xCert = (X509Certificate)cert; 1436 1437 throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\"", null, 1438 params.getCertPath(), params.getIndex()); 1439 } 1440 } 1441 } 1442 } 1443