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