diff options
author | Sergio Giro <sgiro@google.com> | 2015-04-09 14:10:16 +0100 |
---|---|---|
committer | Sergio Giro <sgiro@google.com> | 2015-04-20 15:41:23 +0100 |
commit | 028ab6e01e3b911024b9b9243e9a0f4ac377c0fa (patch) | |
tree | 35d98bf60cbe7a6487bd0014728eb263e89004bb /bcprov/src/main/java/org/bouncycastle/jce | |
parent | b44aff7a3b88138f0070630d467c7527cd90c2f3 (diff) | |
download | android_external_bouncycastle-028ab6e01e3b911024b9b9243e9a0f4ac377c0fa.tar.gz android_external_bouncycastle-028ab6e01e3b911024b9b9243e9a0f4ac377c0fa.tar.bz2 android_external_bouncycastle-028ab6e01e3b911024b9b9243e9a0f4ac377c0fa.zip |
bouncycastle: upgrade to version 1.52
Change-Id: I227db8e458e67af46ccb1c07bfca77a733f25979
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jce')
12 files changed, 506 insertions, 1052 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java index c9ac46e..e8a8abe 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java @@ -8,14 +8,14 @@ public class AnnotatedException { private Throwable _underlyingException; - AnnotatedException(String string, Throwable e) + public AnnotatedException(String string, Throwable e) { super(string); _underlyingException = e; } - AnnotatedException(String string) + public AnnotatedException(String string) { this(string, null); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java index 145186a..82c6a5a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -44,7 +44,7 @@ import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { - private static String info = "BouncyCastle Security Provider v1.51"; + private static String info = "BouncyCastle Security Provider v1.52"; public static final String PROVIDER_NAME = "BC"; @@ -139,7 +139,7 @@ public final class BouncyCastleProvider extends Provider */ public BouncyCastleProvider() { - super(PROVIDER_NAME, 1.51, info); + super(PROVIDER_NAME, 1.52, info); AccessController.doPrivileged(new PrivilegedAction() { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java index b4338f6..f53f3ac 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java @@ -13,7 +13,6 @@ import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; -import java.security.cert.PKIXParameters; import java.security.cert.PolicyQualifierInfo; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; @@ -27,14 +26,15 @@ import java.security.spec.DSAPublicKeySpec; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; - import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; @@ -47,10 +47,13 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERIA5String; +import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; @@ -60,27 +63,22 @@ import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509Extension; -// BEGIN android-removed -// import org.bouncycastle.jce.X509LDAPCertStoreParameters; -// END android-removed +import org.bouncycastle.jcajce.PKIXCRLStore; +import org.bouncycastle.jcajce.PKIXCRLStoreSelector; +import org.bouncycastle.jcajce.PKIXCertStore; +import org.bouncycastle.jcajce.PKIXCertStoreSelector; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; -import org.bouncycastle.util.Integers; import org.bouncycastle.util.Selector; +import org.bouncycastle.util.Store; import org.bouncycastle.util.StoreException; -import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; -import org.bouncycastle.x509.ExtendedPKIXParameters; -// BEGIN android-removed -// import org.bouncycastle.x509.X509AttributeCertStoreSelector; -// END android-removed import org.bouncycastle.x509.X509AttributeCertificate; -import org.bouncycastle.x509.X509CRLStoreSelector; -import org.bouncycastle.x509.X509CertStoreSelector; // BEGIN android-removed -// import org.bouncycastle.x509.X509Store; +// import org.bouncycastle.x509.extension.X509ExtensionUtil; // END android-removed -public class CertPathValidatorUtilities +class CertPathValidatorUtilities { protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); @@ -166,7 +164,7 @@ public class CertPathValidatorUtilities Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); - X500Principal certIssuer = getEncodedIssuerPrincipal(cert); + X500Name certIssuer = PrincipalUtils.getEncodedIssuerPrincipal(cert); try { @@ -197,7 +195,7 @@ public class CertPathValidatorUtilities { try { - X500Principal caName = new X500Principal(trust.getCAName()); + X500Name caName = PrincipalUtils.getCA(trust); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); @@ -240,50 +238,41 @@ public class CertPathValidatorUtilities return trust; } - protected static void addAdditionalStoresFromAltNames( - X509Certificate cert, - ExtendedPKIXParameters pkixParams) + static List<PKIXCertStore> getAdditionalStoresFromAltNames( + byte[] issuerAlternativeName, + Map<GeneralName, PKIXCertStore> altNameCertStoreMap) throws CertificateParsingException { // if in the IssuerAltName extension an URI - // is given, add an additinal X.509 store - if (cert.getIssuerAlternativeNames() != null) + // is given, add an additional X.509 store + if (issuerAlternativeName != null) { - Iterator it = cert.getIssuerAlternativeNames().iterator(); - while (it.hasNext()) + GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets()); + + GeneralName[] names = issuerAltName.getNames(); + List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>(); + + for (int i = 0; i != names.length; i++) { - // look for URI - List list = (List)it.next(); - if (list.get(0).equals(Integers.valueOf(GeneralName.uniformResourceIdentifier))) + GeneralName altName = names[i]; + + PKIXCertStore altStore = altNameCertStoreMap.get(altName); + + if (altStore != null) { - // found - String temp = (String)list.get(1); - CertPathValidatorUtilities.addAdditionalStoreFromLocation(temp, pkixParams); + stores.add(altStore); } } - } - } - /** - * Returns the issuer of an attribute certificate or certificate. - * - * @param cert The attribute certificate or certificate. - * @return The issuer as <code>X500Principal</code>. - */ - protected static X500Principal getEncodedIssuerPrincipal( - Object cert) - { - if (cert instanceof X509Certificate) - { - return ((X509Certificate)cert).getIssuerX500Principal(); + return stores; } else { - return (X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]; + return Collections.EMPTY_LIST; } } - protected static Date getValidDate(PKIXParameters paramsPKIX) + protected static Date getValidDate(PKIXExtendedParameters paramsPKIX) { Date validDate = paramsPKIX.getDate(); @@ -295,11 +284,6 @@ public class CertPathValidatorUtilities return validDate; } - protected static X500Principal getSubjectPrincipal(X509Certificate cert) - { - return cert.getSubjectX500Principal(); - } - protected static boolean isSelfIssued(X509Certificate cert) { return cert.getSubjectDN().equals(cert.getIssuerDN()); @@ -346,11 +330,6 @@ public class CertPathValidatorUtilities } } - protected static X500Principal getIssuerPrincipal(X509CRL crl) - { - return crl.getIssuerX500Principal(); - } - protected static AlgorithmIdentifier getAlgorithmIdentifier( PublicKey key) throws CertPathValidatorException @@ -361,7 +340,7 @@ public class CertPathValidatorUtilities SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); - return info.getAlgorithmId(); + return info.getAlgorithm(); } catch (Exception e) { @@ -655,73 +634,22 @@ public class CertPathValidatorUtilities return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); } - protected static void addAdditionalStoreFromLocation(String location, - ExtendedPKIXParameters pkixParams) - { - if (pkixParams.isAdditionalLocationsEnabled()) - { - try - { - // BEGIN android-removed - // if (location.startsWith("ldap://")) - // { - // // ldap://directory.d-trust.net/CN=D-TRUST - // // Qualified CA 2003 1:PN,O=D-Trust GmbH,C=DE - // // skip "ldap://" - // location = location.substring(7); - // // after first / baseDN starts - // String base = null; - // String url = null; - // if (location.indexOf("/") != -1) - // { - // base = location.substring(location.indexOf("/")); - // // URL - // url = "ldap://" - // + location.substring(0, location.indexOf("/")); - // } - // else - // { - // url = "ldap://" + location; - // } - // // use all purpose parameters - // X509LDAPCertStoreParameters params = new X509LDAPCertStoreParameters.Builder( - // url, base).build(); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "CERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "CRL/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "ATTRIBUTECERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "CERTIFICATEPAIR/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // } - // END android-removed - } - catch (Exception e) - { - // cannot happen - throw new RuntimeException("Exception adding X.509 stores."); - } - } - } - /** * Return a Collection of all certificates or attribute certificates found * in the X509Store's that are matching the certSelect criteriums. * * @param certSelect a {@link Selector} object that will be used to select * the certificates - * @param certStores a List containing only {@link X509Store} objects. These + * @param certStores a List containing only {@link Store} objects. These * are used to search for certificates. - * @return a Collection of all found {@link X509Certificate} or - * {@link org.bouncycastle.x509.X509AttributeCertificate} objects. + * @return a Collection of all found {@link X509Certificate} * May be empty but never <code>null</code>. */ - protected static Collection findCertificates(X509CertStoreSelector certSelect, + protected static Collection findCertificates(PKIXCertStoreSelector certSelect, List certStores) throws AnnotatedException { - Set certs = new HashSet(); + Set certs = new LinkedHashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) @@ -749,7 +677,7 @@ public class CertPathValidatorUtilities try { - certs.addAll(certStore.getCertificates(certSelect)); + certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore)); } catch (CertStoreException e) { @@ -762,38 +690,7 @@ public class CertPathValidatorUtilities return certs; } - // BEGIN android-removed - // protected static Collection findCertificates(X509AttributeCertStoreSelector certSelect, - // List certStores) - // throws AnnotatedException - // { - // Set certs = new HashSet(); - // Iterator iter = certStores.iterator(); - // - // while (iter.hasNext()) - // { - // Object obj = iter.next(); - // - // if (obj instanceof X509Store) - // { - // X509Store certStore = (X509Store)obj; - // try - // { - // certs.addAll(certStore.getMatches(certSelect)); - // } - // catch (StoreException e) - // { - // throw new AnnotatedException( - // "Problem while picking certificates from X.509 store.", e); - // } - // } - // } - // return certs; - // } - // END android-removed - - protected static void addAdditionalStoresFromCRLDistributionPoint( - CRLDistPoint crldp, ExtendedPKIXParameters pkixParams) + static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap) throws AnnotatedException { if (crldp != null) @@ -808,6 +705,8 @@ public class CertPathValidatorUtilities throw new AnnotatedException( "Distribution points could not be read.", e); } + List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>(); + for (int i = 0; i < dps.length; i++) { DistributionPointName dpn = dps[i].getDistributionPoint(); @@ -818,21 +717,31 @@ public class CertPathValidatorUtilities { GeneralName[] genNames = GeneralNames.getInstance( dpn.getName()).getNames(); - // look for an URI + for (int j = 0; j < genNames.length; j++) { - if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) + // BEGIN android-removed + // PKIXCRLStore store = namedCRLStoreMap.get(genNames[i]); + // END android-removed + // BEGIN android-added + // Seems like a bug, unless there should be a guarantee that j < i, + // However, it's breaking the tests. + PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]); + // END android-added + if (store != null) { - String location = DERIA5String.getInstance( - genNames[j].getName()).getString(); - CertPathValidatorUtilities - .addAdditionalStoreFromLocation(location, - pkixParams); + stores.add(store); } } } } } + + return stores; + } + else + { + return Collections.EMPTY_LIST; } } @@ -840,26 +749,22 @@ public class CertPathValidatorUtilities * Add the CRL issuers from the cRLIssuer field of the distribution point or * from the certificate if not given to the issuer criterion of the * <code>selector</code>. - * <p/> + * <p> * The <code>issuerPrincipals</code> are a collection with a single - * <code>X500Principal</code> for <code>X509Certificate</code>s. For - * {@link X509AttributeCertificate}s the issuer may contain more than one - * <code>X500Principal</code>. - * + * <code>X500Name</code> for <code>X509Certificate</code>s. + * </p> * @param dp The distribution point. * @param issuerPrincipals The issuers of the certificate or attribute * certificate which contains the distribution point. * @param selector The CRL selector. - * @param pkixParams The PKIX parameters containing the cert stores. * @throws AnnotatedException if an exception occurs while processing. * @throws ClassCastException if <code>issuerPrincipals</code> does not - * contain only <code>X500Principal</code>s. + * contain only <code>X500Name</code>s. */ protected static void getCRLIssuersFromDistributionPoint( DistributionPoint dp, Collection issuerPrincipals, - X509CRLSelector selector, - ExtendedPKIXParameters pkixParams) + X509CRLSelector selector) throws AnnotatedException { List issuers = new ArrayList(); @@ -874,7 +779,7 @@ public class CertPathValidatorUtilities { try { - issuers.add(new X500Principal(genNames[j].getName() + issuers.add(X500Name.getInstance(genNames[j].getName() .toASN1Primitive().getEncoded())); } catch (IOException e) @@ -900,7 +805,7 @@ public class CertPathValidatorUtilities // add and check issuer principals for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); ) { - issuers.add((X500Principal)it.next()); + issuers.add(it.next()); } } // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid @@ -952,7 +857,7 @@ public class CertPathValidatorUtilities { try { - selector.addIssuerName(((X500Principal)it.next()).getEncoded()); + selector.addIssuerName(((X500Name)it.next()).getEncoded()); } catch (IOException ex) { @@ -965,14 +870,7 @@ public class CertPathValidatorUtilities private static BigInteger getSerialNumber( Object cert) { - if (cert instanceof X509Certificate) - { - return ((X509Certificate)cert).getSerialNumber(); - } - else - { - return ((X509AttributeCertificate)cert).getSerialNumber(); - } + return ((X509Certificate)cert).getSerialNumber(); } protected static void getCertStatus( @@ -1002,20 +900,32 @@ public class CertPathValidatorUtilities { return; } - - X500Principal certIssuer = crl_entry.getCertificateIssuer(); + // BEGIN android-removed + // X500Name certIssuer = X500Name.getInstance(crl_entry.getCertificateIssuer().getEncoded()); + // END android-removed + // BEGIN android-added + // The original code throws null pointer exception for OpenSSLX509CRL, + // which uses the implementation for getCertificateIssuer() in X509CRL, method + // whose reference implementation has the following JavaDoc: "If the certificate + // issuer is also the CRL issuer, this method returns null." + X500Name certIssuer = null; + X500Principal certificateIssuerPrincipal = crl_entry.getCertificateIssuer(); + if (certificateIssuerPrincipal != null) { + certIssuer = X500Name.getInstance(certificateIssuerPrincipal.getEncoded()); + } + // END android-added if (certIssuer == null) { - certIssuer = getIssuerPrincipal(crl); + certIssuer = PrincipalUtils.getIssuerPrincipal(crl); } - if (!getEncodedIssuerPrincipal(cert).equals(certIssuer)) + if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer)) { return; } } - else if (!getEncodedIssuerPrincipal(cert).equals(getIssuerPrincipal(crl))) + else if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl))) { return; // not for our issuer, ignore } @@ -1037,7 +947,7 @@ public class CertPathValidatorUtilities reasonCode = ASN1Enumerated .getInstance(CertPathValidatorUtilities .getExtensionValue(crl_entry, - X509Extension.reasonCode.getId())); + Extension.reasonCode.getId())); } catch (Exception e) { @@ -1074,31 +984,29 @@ public class CertPathValidatorUtilities /** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * - * @param currentDate The date for which the delta CRLs must be valid. - * @param paramsPKIX The extended PKIX parameters. + * @param validityDate The date for which the delta CRLs must be valid. * @param completeCRL The complete CRL the delta CRL is for. * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs. * @throws AnnotatedException if an exception occurs while picking the delta * CRLs. */ - protected static Set getDeltaCRLs(Date currentDate, - ExtendedPKIXParameters paramsPKIX, X509CRL completeCRL) + protected static Set getDeltaCRLs(Date validityDate, + X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores) throws AnnotatedException { - - X509CRLStoreSelector deltaSelect = new X509CRLStoreSelector(); - + X509CRLSelector baseDeltaSelect = new X509CRLSelector(); // 5.2.4 (a) try { - deltaSelect.addIssuerName(CertPathValidatorUtilities - .getIssuerPrincipal(completeCRL).getEncoded()); + baseDeltaSelect.addIssuerName(PrincipalUtils.getIssuerPrincipal(completeCRL).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL.", e); } + + BigInteger completeCRLNumber = null; try { @@ -1130,17 +1038,21 @@ public class CertPathValidatorUtilities // 5.2.4 (d) - deltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber + baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber .add(BigInteger.valueOf(1))); - deltaSelect.setIssuingDistributionPoint(idp); - deltaSelect.setIssuingDistributionPointEnabled(true); + PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect); + + selBuilder.setIssuingDistributionPoint(idp); + selBuilder.setIssuingDistributionPointEnabled(true); // 5.2.4 (c) - deltaSelect.setMaxBaseCRLNumber(completeCRLNumber); + selBuilder.setMaxBaseCRLNumber(completeCRLNumber); + + PKIXCRLStoreSelector deltaSelect = selBuilder.build(); // find delta CRLs - Set temp = CRL_UTIL.findCRLs(deltaSelect, paramsPKIX, currentDate); + Set temp = CRL_UTIL.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores); Set result = new HashSet(); @@ -1173,8 +1085,7 @@ public class CertPathValidatorUtilities * Fetches complete CRLs according to RFC 3280. * * @param dp The distribution point for which the complete CRL - * @param cert The <code>X509Certificate</code> or - * {@link org.bouncycastle.x509.X509AttributeCertificate} for + * @param cert The <code>X509Certificate</code> for * which the CRL should be searched. * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. @@ -1184,66 +1095,51 @@ public class CertPathValidatorUtilities * or no CRLs are found. */ protected static Set getCompleteCRLs(DistributionPoint dp, Object cert, - Date currentDate, ExtendedPKIXParameters paramsPKIX) + Date currentDate, PKIXExtendedParameters paramsPKIX) throws AnnotatedException { - X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); + X509CRLSelector baseCrlSelect = new X509CRLSelector(); + try { Set issuers = new HashSet(); - if (cert instanceof X509AttributeCertificate) - { - issuers.add(((X509AttributeCertificate)cert) - .getIssuer().getPrincipals()[0]); - } - else - { - issuers.add(getEncodedIssuerPrincipal(cert)); - } - CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); + + issuers.add(PrincipalUtils.getEncodedIssuerPrincipal(cert)); + + CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect); } catch (AnnotatedException e) { throw new AnnotatedException( "Could not get issuer information from distribution point.", e); } + if (cert instanceof X509Certificate) { - crlselect.setCertificateChecking((X509Certificate)cert); - } - else if (cert instanceof X509AttributeCertificate) - { - crlselect.setAttrCertificateChecking((X509AttributeCertificate)cert); + baseCrlSelect.setCertificateChecking((X509Certificate)cert); } + PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true).build(); - crlselect.setCompleteCRLEnabled(true); - - Set crls = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); + Date validityDate = currentDate; - if (crls.isEmpty()) + if (paramsPKIX.getDate() != null) { - if (cert instanceof X509AttributeCertificate) - { - X509AttributeCertificate aCert = (X509AttributeCertificate)cert; + validityDate = paramsPKIX.getDate(); + } - throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\""); - } - else - { - X509Certificate xCert = (X509Certificate)cert; + Set crls = CRL_UTIL.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()); + + checkCRLsNotEmpty(crls, cert); - throw new AnnotatedException("No CRLs found for issuer \"" + xCert.getIssuerX500Principal() + "\""); - } - } return crls; } protected static Date getValidCertDateFromValidityModel( - ExtendedPKIXParameters paramsPKIX, CertPath certPath, int index) + PKIXExtendedParameters paramsPKIX, CertPath certPath, int index) throws AnnotatedException { - if (paramsPKIX.getValidityModel() == ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) + if (paramsPKIX.getValidityModel() == PKIXExtendedParameters.CHAIN_VALIDITY_MODEL) { // if end cert use given signing/encryption/... time if (index <= 0) @@ -1324,7 +1220,7 @@ public class CertPathValidatorUtilities * <code>index</code> extended with DSA parameters if applicable. * @throws AnnotatedException if DSA parameters cannot be inherited. */ - protected static PublicKey getNextWorkingKey(List certs, int index) + protected static PublicKey getNextWorkingKey(List certs, int index, JcaJceHelper helper) throws CertPathValidatorException { Certificate cert = (Certificate)certs.get(index); @@ -1357,7 +1253,7 @@ public class CertPathValidatorUtilities dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); try { - KeyFactory keyFactory = KeyFactory.getInstance("DSA", BouncyCastleProvider.PROVIDER_NAME); + KeyFactory keyFactory = helper.createKeyFactory("DSA"); return keyFactory.generatePublic(dsaPubKeySpec); } catch (Exception exception) @@ -1372,37 +1268,57 @@ public class CertPathValidatorUtilities * Find the issuer certificates of a given certificate. * * @param cert The certificate for which an issuer should be found. - * @param pkixParams * @return A <code>Collection</code> object containing the issuer * <code>X509Certificate</code>s. Never <code>null</code>. * @throws AnnotatedException if an error occurs. */ - protected static Collection findIssuerCerts( + static Collection findIssuerCerts( X509Certificate cert, - ExtendedPKIXBuilderParameters pkixParams) + List<CertStore> certStores, + List<PKIXCertStore> pkixCertStores) throws AnnotatedException { - X509CertStoreSelector certSelect = new X509CertStoreSelector(); - Set certs = new HashSet(); + X509CertSelector selector = new X509CertSelector(); + try { - certSelect.setSubject(cert.getIssuerX500Principal().getEncoded()); + selector.setSubject(PrincipalUtils.getIssuerPrincipal(cert).getEncoded()); } - catch (IOException ex) + catch (IOException e) { throw new AnnotatedException( - "Subject criteria for certificate selector to find issuer certificate could not be set.", ex); + "Subject criteria for certificate selector to find issuer certificate could not be set.", e); + } + + try + { + byte[] akiExtensionValue = cert.getExtensionValue(AUTHORITY_KEY_IDENTIFIER); + if (akiExtensionValue != null) + { + ASN1OctetString aki = ASN1OctetString.getInstance(akiExtensionValue); + byte[] authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(aki.getOctets()).getKeyIdentifier(); + if (authorityKeyIdentifier != null) + { + selector.setSubjectKeyIdentifier(new DEROctetString(authorityKeyIdentifier).getEncoded()); + } + } + } + catch (Exception e) + { + // authority key identifier could not be retrieved from target cert, just search without it } + PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build(); + Set certs = new LinkedHashSet(); + Iterator iter; try { List matches = new ArrayList(); - matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getCertStores())); - matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getStores())); - matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getAdditionalStores())); + matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, certStores)); + matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixCertStores)); iter = matches.iterator(); } @@ -1435,4 +1351,24 @@ public class CertPathValidatorUtilities cert.verify(publicKey, sigProvider); } } + + static void checkCRLsNotEmpty(Set crls, Object cert) + throws AnnotatedException + { + if (crls.isEmpty()) + { + if (cert instanceof X509AttributeCertificate) + { + X509AttributeCertificate aCert = (X509AttributeCertificate)cert; + + throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\""); + } + else + { + X509Certificate xCert = (X509Certificate)cert; + + throw new AnnotatedException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\""); + } + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java deleted file mode 100644 index c5b6292..0000000 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java +++ /dev/null @@ -1,609 +0,0 @@ -package org.bouncycastle.jce.provider; - -import java.security.AlgorithmParameters; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.SecureRandom; -import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherSpi; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.ShortBufferException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.PBEParameterSpec; -// BEGIN android-removed -// import javax.crypto.spec.RC2ParameterSpec; -// import javax.crypto.spec.RC5ParameterSpec; -// END android-removed -import javax.crypto.spec.SecretKeySpec; - -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.StreamCipher; -// BEGIN android-removed -// import org.bouncycastle.crypto.engines.BlowfishEngine; -// import org.bouncycastle.crypto.engines.DESEngine; -// import org.bouncycastle.crypto.engines.DESedeEngine; -// import org.bouncycastle.crypto.engines.SkipjackEngine; -// import org.bouncycastle.crypto.engines.TwofishEngine; -// END android-removed -import org.bouncycastle.crypto.modes.CFBBlockCipher; -import org.bouncycastle.crypto.modes.OFBBlockCipher; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; -import org.bouncycastle.jcajce.provider.symmetric.util.PBE; - -public class JCEStreamCipher - extends CipherSpi - implements PBE -{ - // - // specs we can handle. - // - private Class[] availableSpecs = - { - // BEGIN android-removed - // RC2ParameterSpec.class, - // RC5ParameterSpec.class, - // END android-removed - IvParameterSpec.class, - PBEParameterSpec.class - }; - - private StreamCipher cipher; - private ParametersWithIV ivParam; - - private int ivLength = 0; - - private PBEParameterSpec pbeSpec = null; - private String pbeAlgorithm = null; - - private AlgorithmParameters engineParams; - - protected JCEStreamCipher( - StreamCipher engine, - int ivLength) - { - cipher = engine; - this.ivLength = ivLength; - } - - protected int engineGetBlockSize() - { - return 0; - } - - protected byte[] engineGetIV() - { - return (ivParam != null) ? ivParam.getIV() : null; - } - - protected int engineGetKeySize( - Key key) - { - return key.getEncoded().length * 8; - } - - protected int engineGetOutputSize( - int inputLen) - { - return inputLen; - } - - protected AlgorithmParameters engineGetParameters() - { - if (engineParams == null) - { - if (pbeSpec != null) - { - try - { - AlgorithmParameters engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); - engineParams.init(pbeSpec); - - return engineParams; - } - catch (Exception e) - { - return null; - } - } - } - - return engineParams; - } - - /** - * should never be called. - */ - protected void engineSetMode( - String mode) - { - if (!mode.equalsIgnoreCase("ECB")) - { - throw new IllegalArgumentException("can't support mode " + mode); - } - } - - /** - * should never be called. - */ - protected void engineSetPadding( - String padding) - throws NoSuchPaddingException - { - if (!padding.equalsIgnoreCase("NoPadding")) - { - throw new NoSuchPaddingException("Padding " + padding + " unknown."); - } - } - - protected void engineInit( - int opmode, - Key key, - AlgorithmParameterSpec params, - SecureRandom random) - throws InvalidKeyException, InvalidAlgorithmParameterException - { - CipherParameters param; - - this.pbeSpec = null; - this.pbeAlgorithm = null; - - this.engineParams = null; - - // - // basic key check - // - if (!(key instanceof SecretKey)) - { - throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption."); - } - - if (key instanceof BCPBEKey) - { - BCPBEKey k = (BCPBEKey)key; - - if (k.getOID() != null) - { - pbeAlgorithm = k.getOID().getId(); - } - else - { - pbeAlgorithm = k.getAlgorithm(); - } - - if (k.getParam() != null) - { - param = k.getParam(); - pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount()); - } - else if (params instanceof PBEParameterSpec) - { - param = PBE.Util.makePBEParameters(k, params, cipher.getAlgorithmName()); - pbeSpec = (PBEParameterSpec)params; - } - else - { - throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); - } - - if (k.getIvSize() != 0) - { - ivParam = (ParametersWithIV)param; - } - } - else if (params == null) - { - param = new KeyParameter(key.getEncoded()); - } - else if (params instanceof IvParameterSpec) - { - param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV()); - ivParam = (ParametersWithIV)param; - } - else - { - throw new IllegalArgumentException("unknown parameter type."); - } - - if ((ivLength != 0) && !(param instanceof ParametersWithIV)) - { - SecureRandom ivRandom = random; - - if (ivRandom == null) - { - ivRandom = new SecureRandom(); - } - - if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) - { - byte[] iv = new byte[ivLength]; - - ivRandom.nextBytes(iv); - param = new ParametersWithIV(param, iv); - ivParam = (ParametersWithIV)param; - } - else - { - throw new InvalidAlgorithmParameterException("no IV set when one expected"); - } - } - - switch (opmode) - { - case Cipher.ENCRYPT_MODE: - case Cipher.WRAP_MODE: - cipher.init(true, param); - break; - case Cipher.DECRYPT_MODE: - case Cipher.UNWRAP_MODE: - cipher.init(false, param); - break; - default: - System.out.println("eeek!"); - } - } - - protected void engineInit( - int opmode, - Key key, - AlgorithmParameters params, - SecureRandom random) - throws InvalidKeyException, InvalidAlgorithmParameterException - { - AlgorithmParameterSpec paramSpec = null; - - if (params != null) - { - for (int i = 0; i != availableSpecs.length; i++) - { - try - { - paramSpec = params.getParameterSpec(availableSpecs[i]); - break; - } - catch (Exception e) - { - continue; - } - } - - if (paramSpec == null) - { - throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); - } - } - - engineInit(opmode, key, paramSpec, random); - engineParams = params; - } - - protected void engineInit( - int opmode, - Key key, - SecureRandom random) - throws InvalidKeyException - { - try - { - engineInit(opmode, key, (AlgorithmParameterSpec)null, random); - } - catch (InvalidAlgorithmParameterException e) - { - throw new InvalidKeyException(e.getMessage()); - } - } - - protected byte[] engineUpdate( - byte[] input, - int inputOffset, - int inputLen) - { - byte[] out = new byte[inputLen]; - - cipher.processBytes(input, inputOffset, inputLen, out, 0); - - return out; - } - - protected int engineUpdate( - byte[] input, - int inputOffset, - int inputLen, - byte[] output, - int outputOffset) - throws ShortBufferException - { - try - { - cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); - - return inputLen; - } - catch (DataLengthException e) - { - throw new ShortBufferException(e.getMessage()); - } - } - - protected byte[] engineDoFinal( - byte[] input, - int inputOffset, - int inputLen) - throws BadPaddingException, IllegalBlockSizeException - { - if (inputLen != 0) - { - byte[] out = engineUpdate(input, inputOffset, inputLen); - - cipher.reset(); - - return out; - } - - cipher.reset(); - - return new byte[0]; - } - - protected int engineDoFinal( - byte[] input, - int inputOffset, - int inputLen, - byte[] output, - int outputOffset) - throws BadPaddingException - { - if (inputLen != 0) - { - cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); - } - - cipher.reset(); - - return inputLen; - } - - protected byte[] engineWrap( - Key key) - throws IllegalBlockSizeException, InvalidKeyException - { - byte[] encoded = key.getEncoded(); - if (encoded == null) - { - throw new InvalidKeyException("Cannot wrap key, null encoding."); - } - - try - { - return engineDoFinal(encoded, 0, encoded.length); - } - catch (BadPaddingException e) - { - throw new IllegalBlockSizeException(e.getMessage()); - } - } - - protected Key engineUnwrap( - byte[] wrappedKey, - String wrappedKeyAlgorithm, - int wrappedKeyType) - throws InvalidKeyException - { - byte[] encoded; - try - { - encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); - } - catch (BadPaddingException e) - { - throw new InvalidKeyException(e.getMessage()); - } - catch (IllegalBlockSizeException e2) - { - throw new InvalidKeyException(e2.getMessage()); - } - - if (wrappedKeyType == Cipher.SECRET_KEY) - { - return new SecretKeySpec(encoded, wrappedKeyAlgorithm); - } - else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) - { - /* - * The caller doesn't know the algorithm as it is part of - * the encrypted data. - */ - try - { - PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); - - PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); - - if (privKey != null) - { - return privKey; - } - else - { - throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); - } - } - catch (Exception e) - { - throw new InvalidKeyException("Invalid key encoding."); - } - } - else - { - try - { - KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); - - if (wrappedKeyType == Cipher.PUBLIC_KEY) - { - return kf.generatePublic(new X509EncodedKeySpec(encoded)); - } - else if (wrappedKeyType == Cipher.PRIVATE_KEY) - { - return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); - } - } - catch (NoSuchProviderException e) - { - throw new InvalidKeyException("Unknown key type " + e.getMessage()); - } - catch (NoSuchAlgorithmException e) - { - throw new InvalidKeyException("Unknown key type " + e.getMessage()); - } - catch (InvalidKeySpecException e2) - { - throw new InvalidKeyException("Unknown key type " + e2.getMessage()); - } - - throw new InvalidKeyException("Unknown key type " + wrappedKeyType); - } - } - - /* - * The ciphers that inherit from us. - */ - - // BEGIN android-removed - // /** - // * DES - // */ - // static public class DES_CFB8 - // extends JCEStreamCipher - // { - // public DES_CFB8() - // { - // super(new CFBBlockCipher(new DESEngine(), 8), 64); - // } - // } - // - // /** - // * DESede - // */ - // static public class DESede_CFB8 - // extends JCEStreamCipher - // { - // public DESede_CFB8() - // { - // super(new CFBBlockCipher(new DESedeEngine(), 8), 64); - // } - // } - // - // /** - // * SKIPJACK - // */ - // static public class Skipjack_CFB8 - // extends JCEStreamCipher - // { - // public Skipjack_CFB8() - // { - // super(new CFBBlockCipher(new SkipjackEngine(), 8), 64); - // } - // } - // - // /** - // * Blowfish - // */ - // static public class Blowfish_CFB8 - // extends JCEStreamCipher - // { - // public Blowfish_CFB8() - // { - // super(new CFBBlockCipher(new BlowfishEngine(), 8), 64); - // } - // } - // - // /** - // * Twofish - // */ - // static public class Twofish_CFB8 - // extends JCEStreamCipher - // { - // public Twofish_CFB8() - // { - // super(new CFBBlockCipher(new TwofishEngine(), 8), 128); - // } - // } - // - // /** - // * DES - // */ - // static public class DES_OFB8 - // extends JCEStreamCipher - // { - // public DES_OFB8() - // { - // super(new OFBBlockCipher(new DESEngine(), 8), 64); - // } - // } - // - // /** - // * DESede - // */ - // static public class DESede_OFB8 - // extends JCEStreamCipher - // { - // public DESede_OFB8() - // { - // super(new OFBBlockCipher(new DESedeEngine(), 8), 64); - // } - // } - // - // /** - // * SKIPJACK - // */ - // static public class Skipjack_OFB8 - // extends JCEStreamCipher - // { - // public Skipjack_OFB8() - // { - // super(new OFBBlockCipher(new SkipjackEngine(), 8), 64); - // } - // } - // - // /** - // * Blowfish - // */ - // static public class Blowfish_OFB8 - // extends JCEStreamCipher - // { - // public Blowfish_OFB8() - // { - // super(new OFBBlockCipher(new BlowfishEngine(), 8), 64); - // } - // } - // - // /** - // * Twofish - // */ - // static public class Twofish_OFB8 - // extends JCEStreamCipher - // { - // public Twofish_OFB8() - // { - // super(new OFBBlockCipher(new TwofishEngine(), 8), 128); - // } - // } - // END android-removed -} diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java index ebd2f2a..b53b7aa 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java @@ -2,7 +2,6 @@ package org.bouncycastle.jce.provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; -import java.security.cert.PKIXParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; @@ -12,16 +11,14 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import org.bouncycastle.jcajce.PKIXCRLStore; +import org.bouncycastle.jcajce.PKIXCRLStoreSelector; +import org.bouncycastle.util.Store; import org.bouncycastle.util.StoreException; -import org.bouncycastle.x509.ExtendedPKIXParameters; -import org.bouncycastle.x509.X509CRLStoreSelector; -// BEGIN android-removed -// import org.bouncycastle.x509.X509Store; -// END android-removed -public class PKIXCRLUtil +class PKIXCRLUtil { - public Set findCRLs(X509CRLStoreSelector crlselect, ExtendedPKIXParameters paramsPKIX, Date currentDate) + public Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores) throws AnnotatedException { Set initialSet = new HashSet(); @@ -29,9 +26,8 @@ public class PKIXCRLUtil // get complete CRL(s) try { - initialSet.addAll(findCRLs(crlselect, paramsPKIX.getAdditionalStores())); - initialSet.addAll(findCRLs(crlselect, paramsPKIX.getStores())); - initialSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); + initialSet.addAll(findCRLs(crlselect, pkixCrlStores)); + initialSet.addAll(findCRLs(crlselect, certStores)); } catch (AnnotatedException e) { @@ -39,12 +35,6 @@ public class PKIXCRLUtil } Set finalSet = new HashSet(); - Date validityDate = currentDate; - - if (paramsPKIX.getDate() != null) - { - validityDate = paramsPKIX.getDate(); - } // based on RFC 5280 6.3.3 for (Iterator it = initialSet.iterator(); it.hasNext();) @@ -72,38 +62,20 @@ public class PKIXCRLUtil return finalSet; } - public Set findCRLs(X509CRLStoreSelector crlselect, PKIXParameters paramsPKIX) - throws AnnotatedException - { - Set completeSet = new HashSet(); - - // get complete CRL(s) - try - { - completeSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); - } - catch (AnnotatedException e) - { - throw new AnnotatedException("Exception obtaining complete CRLs.", e); - } - - return completeSet; - } - -/** + /** * Return a Collection of all CRLs found in the X509Store's that are * matching the crlSelect criteriums. * - * @param crlSelect a {@link X509CRLStoreSelector} object that will be used + * @param crlSelect a {@link org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used * to select the CRLs * @param crlStores a List containing only - * {@link org.bouncycastle.x509.X509Store X509Store} objects. + * {@link Store} objects. * These are used to search for CRLs * * @return a Collection of all found {@link java.security.cert.X509CRL X509CRL} objects. May be * empty but never <code>null</code>. */ - private final Collection findCRLs(X509CRLStoreSelector crlSelect, + private final Collection findCRLs(PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException { Set crls = new HashSet(); @@ -117,10 +89,10 @@ public class PKIXCRLUtil Object obj = iter.next(); // BEGIN android-removed - // if (obj instanceof X509Store) + // if (obj instanceof Store) // { - // X509Store store = (X509Store)obj; - // + // Store store = (Store)obj; + // try // { // crls.addAll(store.getMatches(crlSelect)); @@ -139,7 +111,7 @@ public class PKIXCRLUtil try { - crls.addAll(store.getCRLs(crlSelect)); + crls.addAll(PKIXCRLStoreSelector.getCRLs(crlSelect, store)); foundValidStore = true; } catch (CertStoreException e) diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java index 384eb86..b713395 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java @@ -6,8 +6,6 @@ import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertPathBuilderSpi; import java.security.cert.CertPathParameters; -import java.security.cert.CertPathValidator; -import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathBuilderResult; @@ -19,10 +17,15 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.jcajce.PKIXCertStore; +import org.bouncycastle.jcajce.PKIXCertStoreSelector; +import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory; import org.bouncycastle.jce.exception.ExtCertPathBuilderException; -import org.bouncycastle.util.Selector; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; -import org.bouncycastle.x509.X509CertStoreSelector; +import org.bouncycastle.x509.ExtendedPKIXParameters; /** * Implements the PKIX CertPathBuilding algorithm for BouncyCastle. @@ -42,23 +45,45 @@ public class PKIXCertPathBuilderSpi throws CertPathBuilderException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXBuilderParameters) - && !(params instanceof ExtendedPKIXBuilderParameters)) + && !(params instanceof ExtendedPKIXBuilderParameters) + && !(params instanceof PKIXExtendedBuilderParameters)) { throw new InvalidAlgorithmParameterException( "Parameters must be an instance of " + PKIXBuilderParameters.class.getName() + " or " - + ExtendedPKIXBuilderParameters.class.getName() + "."); + + PKIXExtendedBuilderParameters.class.getName() + "."); } - ExtendedPKIXBuilderParameters pkixParams = null; - if (params instanceof ExtendedPKIXBuilderParameters) + PKIXExtendedBuilderParameters paramsPKIX; + if (params instanceof PKIXBuilderParameters) { - pkixParams = (ExtendedPKIXBuilderParameters) params; + PKIXExtendedParameters.Builder paramsPKIXBldr = new PKIXExtendedParameters.Builder((PKIXBuilderParameters)params); + PKIXExtendedBuilderParameters.Builder paramsBldrPKIXBldr; + + if (params instanceof ExtendedPKIXParameters) + { + ExtendedPKIXBuilderParameters extPKIX = (ExtendedPKIXBuilderParameters)params; + + ; + for (Iterator it = extPKIX.getAdditionalStores().iterator(); it.hasNext();) + { + paramsPKIXBldr.addCertificateStore((PKIXCertStore)it.next()); + } + paramsBldrPKIXBldr = new PKIXExtendedBuilderParameters.Builder(paramsPKIXBldr.build()); + + paramsBldrPKIXBldr.addExcludedCerts(extPKIX.getExcludedCerts()); + paramsBldrPKIXBldr.setMaxPathLength(extPKIX.getMaxPathLength()); + } + else + { + paramsBldrPKIXBldr = new PKIXExtendedBuilderParameters.Builder((PKIXBuilderParameters)params); + } + + paramsPKIX = paramsBldrPKIXBldr.build(); } else { - pkixParams = (ExtendedPKIXBuilderParameters) ExtendedPKIXBuilderParameters - .getInstance((PKIXBuilderParameters) params); + paramsPKIX = (PKIXExtendedBuilderParameters)params; } Collection targets; @@ -68,19 +93,12 @@ public class PKIXCertPathBuilderSpi // search target certificates - Selector certSelect = pkixParams.getTargetConstraints(); - if (!(certSelect instanceof X509CertStoreSelector)) - { - throw new CertPathBuilderException( - "TargetConstraints must be an instance of " - + X509CertStoreSelector.class.getName() + " for " - + this.getClass().getName() + " class."); - } + PKIXCertStoreSelector certSelect = paramsPKIX.getBaseParameters().getTargetConstraints(); try { - targets = CertPathValidatorUtilities.findCertificates((X509CertStoreSelector)certSelect, pkixParams.getStores()); - targets.addAll(CertPathValidatorUtilities.findCertificates((X509CertStoreSelector)certSelect, pkixParams.getCertStores())); + targets = CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertificateStores()); + targets.addAll(CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertStores())); } catch (AnnotatedException e) { @@ -102,7 +120,7 @@ public class PKIXCertPathBuilderSpi while (targetIter.hasNext() && result == null) { cert = (X509Certificate) targetIter.next(); - result = build(cert, pkixParams, certPathList); + result = build(cert, paramsPKIX, certPathList); } if (result == null && certPathException != null) @@ -128,7 +146,7 @@ public class PKIXCertPathBuilderSpi private Exception certPathException; protected CertPathBuilderResult build(X509Certificate tbvCert, - ExtendedPKIXBuilderParameters pkixParams, List tbvPath) + PKIXExtendedBuilderParameters pkixParams, List tbvPath) { // If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the @@ -155,13 +173,13 @@ public class PKIXCertPathBuilderSpi tbvPath.add(tbvCert); CertificateFactory cFact; - CertPathValidator validator; + PKIXCertPathValidatorSpi validator; CertPathBuilderResult builderResult = null; try { - cFact = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); - validator = CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); + cFact = new CertificateFactory(); + validator = new PKIXCertPathValidatorSpi(); } catch (Exception e) { @@ -172,8 +190,8 @@ public class PKIXCertPathBuilderSpi try { // check whether the issuer of <tbvCert> is a TrustAnchor - if (CertPathValidatorUtilities.findTrustAnchor(tbvCert, pkixParams.getTrustAnchors(), - pkixParams.getSigProvider()) != null) + if (CertPathValidatorUtilities.findTrustAnchor(tbvCert, pkixParams.getBaseParameters().getTrustAnchors(), + pkixParams.getBaseParameters().getSigProvider()) != null) { // exception message from possibly later tried certification // chains @@ -181,7 +199,7 @@ public class PKIXCertPathBuilderSpi PKIXCertPathValidatorResult result = null; try { - certPath = cFact.generateCertPath(tbvPath); + certPath = cFact.engineGenerateCertPath(tbvPath); } catch (Exception e) { @@ -192,7 +210,7 @@ public class PKIXCertPathBuilderSpi try { - result = (PKIXCertPathValidatorResult) validator.validate( + result = (PKIXCertPathValidatorResult) validator.engineValidate( certPath, pkixParams); } catch (Exception e) @@ -208,16 +226,21 @@ public class PKIXCertPathBuilderSpi } else { + List stores = new ArrayList(); + + + stores.addAll(pkixParams.getBaseParameters().getCertificateStores()); + // add additional X.509 stores from locations in certificate try { - CertPathValidatorUtilities.addAdditionalStoresFromAltNames( - tbvCert, pkixParams); + stores.addAll(CertPathValidatorUtilities.getAdditionalStoresFromAltNames( + tbvCert.getExtensionValue(Extension.issuerAlternativeName.getId()), pkixParams.getBaseParameters().getNamedCertificateStoreMap())); } catch (CertificateParsingException e) { throw new AnnotatedException( - "No additiontal X.509 stores can be added from certificate locations.", + "No additional X.509 stores can be added from certificate locations.", e); } Collection issuers = new HashSet(); @@ -225,7 +248,7 @@ public class PKIXCertPathBuilderSpi // of the stores try { - issuers.addAll(CertPathValidatorUtilities.findIssuerCerts(tbvCert, pkixParams)); + issuers.addAll(CertPathValidatorUtilities.findIssuerCerts(tbvCert, pkixParams.getBaseParameters().getCertStores(), stores)); } catch (AnnotatedException e) { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java index 19dc768..d902812 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java @@ -21,11 +21,14 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import javax.security.auth.x500.X500Principal; - import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.x509.ExtendedPKIXParameters; @@ -36,6 +39,11 @@ import org.bouncycastle.x509.ExtendedPKIXParameters; public class PKIXCertPathValidatorSpi extends CertPathValidatorSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + + public PKIXCertPathValidatorSpi() + { + } // BEGIN android-added private static class NoPreloadHolder { private final static CertBlacklist blacklist = new CertBlacklist(); @@ -48,21 +56,36 @@ public class PKIXCertPathValidatorSpi throws CertPathValidatorException, InvalidAlgorithmParameterException { - if (!(params instanceof PKIXParameters)) + if (!(params instanceof CertPathParameters)) { throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() + " instance."); } - ExtendedPKIXParameters paramsPKIX; - if (params instanceof ExtendedPKIXParameters) + PKIXExtendedParameters paramsPKIX; + if (params instanceof PKIXParameters) { - paramsPKIX = (ExtendedPKIXParameters)params; + PKIXExtendedParameters.Builder paramsPKIXBldr = new PKIXExtendedParameters.Builder((PKIXParameters)params); + + if (params instanceof ExtendedPKIXParameters) + { + ExtendedPKIXParameters extPKIX = (ExtendedPKIXParameters)params; + + paramsPKIXBldr.setUseDeltasEnabled(extPKIX.isUseDeltasEnabled()); + paramsPKIXBldr.setValidityModel(extPKIX.getValidityModel()); + } + + paramsPKIX = paramsPKIXBldr.build(); + } + else if (params instanceof PKIXExtendedBuilderParameters) + { + paramsPKIX = ((PKIXExtendedBuilderParameters)params).getBaseParameters(); } else { - paramsPKIX = ExtendedPKIXParameters.getInstance((PKIXParameters)params); + paramsPKIX = (PKIXExtendedParameters)params; } + if (paramsPKIX.getTrustAnchors() == null) { throw new InvalidAlgorithmParameterException( @@ -129,6 +152,9 @@ public class PKIXCertPathValidatorSpi throw new CertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1); } + // RFC 5280 - CRLs must originate from the same trust anchor as the target certificate. + paramsPKIX = new PKIXExtendedParameters.Builder(paramsPKIX).setTrustAnchor(trust).build(); + // // (e), (f), (g) are part of the paramsPKIX object. // @@ -210,19 +236,19 @@ public class PKIXCertPathValidatorSpi // (g), (h), (i), (j) // PublicKey workingPublicKey; - X500Principal workingIssuerName; + X500Name workingIssuerName; X509Certificate sign = trust.getTrustedCert(); try { if (sign != null) { - workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); + workingIssuerName = PrincipalUtils.getSubjectPrincipal(sign); workingPublicKey = sign.getPublicKey(); } else { - workingIssuerName = new X500Principal(trust.getCAName()); + workingIssuerName = PrincipalUtils.getCA(trust); workingPublicKey = trust.getCAPublicKey(); } } @@ -305,7 +331,7 @@ public class PKIXCertPathValidatorSpi // RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, index, workingPublicKey, - verificationAlreadyPerformed, workingIssuerName, sign); + verificationAlreadyPerformed, workingIssuerName, sign, helper); RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator); @@ -390,12 +416,12 @@ public class PKIXCertPathValidatorSpi sign = cert; // (c) - workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); + workingIssuerName = PrincipalUtils.getSubjectPrincipal(sign); // (d) try { - workingPublicKey = CertPathValidatorUtilities.getNextWorkingKey(certPath.getCertificates(), index); + workingPublicKey = CertPathValidatorUtilities.getNextWorkingKey(certPath.getCertificates(), index, helper); } catch (CertPathValidatorException e) { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java index 7ecc486..0742712 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java @@ -635,13 +635,17 @@ public class PKIXNameConstraintValidator private boolean emailIsConstrained(String email, String constraint) { String sub = email.substring(email.indexOf('@') + 1); - // a particular mailbox + // a particular mailbox or @domain if (constraint.indexOf('@') != -1) { if (email.equalsIgnoreCase(constraint)) { return true; } + if (sub.equalsIgnoreCase(constraint.substring(1))) + { + return true; + } } // on particular host else if (!(constraint.charAt(0) == '.')) diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java index 3437605..d89e920 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java @@ -165,4 +165,9 @@ public class PKIXPolicyNode return _node; } + + public void setExpectedPolicies(Set expectedPolicies) + { + this.expectedPolicies = expectedPolicies; + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java new file mode 100644 index 0000000..9059079 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java @@ -0,0 +1,53 @@ +package org.bouncycastle.jce.provider; + +import java.security.cert.TrustAnchor; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLEntry; +import java.security.cert.X509Certificate; + +import javax.security.auth.x500.X500Principal; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.x509.X509AttributeCertificate; + +class PrincipalUtils +{ + static X500Name getSubjectPrincipal(X509Certificate cert) + { + return X500Name.getInstance(cert.getSubjectX500Principal().getEncoded()); + } + + static X500Name getIssuerPrincipal(X509CRL crl) + { + return X500Name.getInstance(crl.getIssuerX500Principal().getEncoded()); + } + + static X500Name getIssuerPrincipal(X509Certificate cert) + { + return X500Name.getInstance(cert.getIssuerX500Principal().getEncoded()); + } + + static X500Name getCA(TrustAnchor trustAnchor) + { + return X500Name.getInstance(trustAnchor.getCA().getEncoded()); + } + + /** + * Returns the issuer of an attribute certificate or certificate. + * + * @param cert The attribute certificate or certificate. + * @return The issuer as <code>X500Principal</code>. + */ + static X500Name getEncodedIssuerPrincipal( + Object cert) + { + if (cert instanceof X509Certificate) + { + return getIssuerPrincipal((X509Certificate)cert); + } + else + { + return X500Name.getInstance(((X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]).getEncoded()); + } + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java index 881ceeb..d67a77e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java @@ -5,13 +5,14 @@ import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.cert.CertPath; -import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathValidatorException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.PKIXCertPathChecker; import java.security.cert.X509CRL; +import java.security.cert.X509CRLSelector; +import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.cert.X509Extension; import java.text.SimpleDateFormat; @@ -26,9 +27,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; -import java.util.Vector; - -import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; @@ -37,36 +35,42 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x500.RDN; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; -import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.asn1.x509.X509Name; +import org.bouncycastle.jcajce.PKIXCRLStore; +import org.bouncycastle.jcajce.PKIXCRLStoreSelector; +import org.bouncycastle.jcajce.PKIXCertStoreSelector; +import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.util.JcaJceHelper; +import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.util.Arrays; -import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; -import org.bouncycastle.x509.ExtendedPKIXParameters; -import org.bouncycastle.x509.X509CRLStoreSelector; -import org.bouncycastle.x509.X509CertStoreSelector; -public class RFC3280CertPathUtilities +class RFC3280CertPathUtilities { private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); /** * If the complete CRL includes an issuing distribution point (IDP) CRL * extension check the following: - * <p/> + * <p> * (i) If the distribution point name is present in the IDP CRL extension * and the distribution field is present in the DP, then verify that one of * the names in the IDP matches one of the names in the DP. If the @@ -75,17 +79,17 @@ public class RFC3280CertPathUtilities * names in the IDP matches one of the names in the cRLIssuer field of the * DP. * </p> - * <p/> + * <p> * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL * extension, verify that the certificate does not include the basic * constraints extension with the cA boolean asserted. * </p> - * <p/> + * <p> * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL * extension, verify that the certificate includes the basic constraints * extension with the cA boolean asserted. * </p> - * <p/> + * <p> * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted. * </p> * @@ -133,20 +137,18 @@ public class RFC3280CertPathUtilities ASN1EncodableVector vec = new ASN1EncodableVector(); try { - Enumeration e = ASN1Sequence.getInstance( - ASN1Sequence.fromByteArray(CertPathValidatorUtilities.getIssuerPrincipal(crl) - .getEncoded())).getObjects(); + Enumeration e = ASN1Sequence.getInstance(PrincipalUtils.getIssuerPrincipal(crl)).getObjects(); while (e.hasMoreElements()) { vec.add((ASN1Encodable)e.nextElement()); } } - catch (IOException e) + catch (Exception e) { throw new AnnotatedException("Could not read CRL issuer.", e); } vec.add(dpName.getName()); - names.add(new GeneralName(X509Name.getInstance(new DERSequence(vec)))); + names.add(new GeneralName(X500Name.getInstance(new DERSequence(vec)))); } boolean matches = false; // verify that one of the names in the IDP matches one @@ -170,11 +172,10 @@ public class RFC3280CertPathUtilities genNames = new GeneralName[1]; try { - genNames[0] = new GeneralName(new X509Name( - (ASN1Sequence)ASN1Sequence.fromByteArray(CertPathValidatorUtilities - .getEncodedIssuerPrincipal(cert).getEncoded()))); + genNames[0] = new GeneralName(X500Name.getInstance(PrincipalUtils + .getEncodedIssuerPrincipal(cert).getEncoded())); } - catch (IOException e) + catch (Exception e) { throw new AnnotatedException("Could not read certificate issuer.", e); } @@ -188,7 +189,7 @@ public class RFC3280CertPathUtilities vec.add((ASN1Encodable)e.nextElement()); } vec.add(dpName.getName()); - genNames[j] = new GeneralName(new X509Name(new DERSequence(vec))); + genNames[j] = new GeneralName(X500Name.getInstance(new DERSequence(vec))); } } if (genNames != null) @@ -296,7 +297,16 @@ public class RFC3280CertPathUtilities isIndirect = true; } } - byte[] issuerBytes = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); + byte[] issuerBytes; + + try + { + issuerBytes = PrincipalUtils.getIssuerPrincipal(crl).getEncoded(); + } + catch (IOException e) + { + throw new AnnotatedException("Exception encoding CRL issuer: " + e.getMessage(), e); + } boolean matchIssuer = false; if (dp.getCRLIssuer() != null) @@ -331,8 +341,8 @@ public class RFC3280CertPathUtilities } else { - if (CertPathValidatorUtilities.getIssuerPrincipal(crl).equals( - CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert))) + if (PrincipalUtils.getIssuerPrincipal(crl).equals( + PrincipalUtils.getEncodedIssuerPrincipal(cert))) { matchIssuer = true; } @@ -377,33 +387,33 @@ public class RFC3280CertPathUtilities } - public static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); + public static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId(); - public static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); + public static final String POLICY_MAPPINGS = Extension.policyMappings.getId(); - public static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); + public static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId(); - public static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); + public static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId(); - public static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); + public static final String FRESHEST_CRL = Extension.freshestCRL.getId(); - public static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); + public static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId(); - public static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); + public static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId(); - public static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); + public static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId(); - public static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); + public static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId(); - public static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); + public static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId(); - public static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); + public static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId(); - public static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); + public static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId(); - public static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); + public static final String KEY_USAGE = Extension.keyUsage.getId(); - public static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); + public static final String CRL_NUMBER = Extension.cRLNumber.getId(); public static final String ANY_POLICY = "2.5.29.32.0"; @@ -438,18 +448,19 @@ public class RFC3280CertPathUtilities Object cert, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, - ExtendedPKIXParameters paramsPKIX, - List certPathCerts) + PKIXExtendedParameters paramsPKIX, + List certPathCerts, + JcaJceHelper helper) throws AnnotatedException { // (f) // get issuer from CRL - X509CertStoreSelector selector = new X509CertStoreSelector(); + X509CertSelector certSelector = new X509CertSelector(); try { - byte[] issuerPrincipal = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); - selector.setSubject(issuerPrincipal); + byte[] issuerPrincipal = PrincipalUtils.getIssuerPrincipal(crl).getEncoded(); + certSelector.setSubject(issuerPrincipal); } catch (IOException e) { @@ -457,12 +468,13 @@ public class RFC3280CertPathUtilities "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e); } + PKIXCertStoreSelector selector = new PKIXCertStoreSelector.Builder(certSelector).build(); + // get CRL signing certs Collection coll; try { - coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getStores()); - coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getAdditionalStores())); + coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertificateStores()); coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores())); } catch (AnnotatedException e) @@ -493,13 +505,13 @@ public class RFC3280CertPathUtilities } try { - CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); - selector = new X509CertStoreSelector(); - selector.setCertificate(signingCert); - ExtendedPKIXParameters temp = (ExtendedPKIXParameters)paramsPKIX.clone(); - temp.setTargetCertConstraints(selector); - ExtendedPKIXBuilderParameters params = (ExtendedPKIXBuilderParameters)ExtendedPKIXBuilderParameters - .getInstance(temp); + PKIXCertPathBuilderSpi builder = new PKIXCertPathBuilderSpi(); + X509CertSelector tmpCertSelector = new X509CertSelector(); + tmpCertSelector.setCertificate(signingCert); + + PKIXExtendedParameters.Builder paramsBuilder = new PKIXExtendedParameters.Builder(paramsPKIX) + .setTargetConstraints(new PKIXCertStoreSelector.Builder(tmpCertSelector).build()); + /* * if signingCert is placed not higher on the cert path a * dependency loop results. CRL for cert is checked, but @@ -511,19 +523,22 @@ public class RFC3280CertPathUtilities */ if (certPathCerts.contains(signingCert)) { - params.setRevocationEnabled(false); + paramsBuilder.setRevocationEnabled(false); } else { - params.setRevocationEnabled(true); + paramsBuilder.setRevocationEnabled(true); } - List certs = builder.build(params).getCertPath().getCertificates(); + + PKIXExtendedBuilderParameters extParams = new PKIXExtendedBuilderParameters.Builder(paramsBuilder.build()).build(); + + List certs = builder.engineBuild(extParams).getCertPath().getCertificates(); validCerts.add(signingCert); - validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0)); + validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0, helper)); } catch (CertPathBuilderException e) { - throw new AnnotatedException("Internal error.", e); + throw new AnnotatedException("CertPath for CRL signer failed to validate.", e); } catch (CertPathValidatorException e) { @@ -531,7 +546,7 @@ public class RFC3280CertPathUtilities } catch (Exception e) { - throw new RuntimeException(e.getMessage()); + throw new AnnotatedException(e.getMessage()); } } @@ -618,7 +633,7 @@ public class RFC3280CertPathUtilities protected static Set processCRLA1i( Date currentDate, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException @@ -650,19 +665,24 @@ public class RFC3280CertPathUtilities } if (freshestCRL != null) { + List crlStores = new ArrayList(); + + crlStores.addAll(paramsPKIX.getCRLStores()); + try { - CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX); + crlStores.addAll(CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX.getNamedCRLStoreMap())); } catch (AnnotatedException e) { throw new AnnotatedException( "No new delta CRL locations could be added from Freshest CRL extension.", e); } + // get delta CRL(s) try { - set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); + set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, crl, paramsPKIX.getCertStores(), crlStores)); } catch (AnnotatedException e) { @@ -675,33 +695,41 @@ public class RFC3280CertPathUtilities protected static Set[] processCRLA1ii( Date currentDate, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException { Set deltaSet = new HashSet(); - X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); + X509CRLSelector crlselect = new X509CRLSelector(); crlselect.setCertificateChecking(cert); try { - crlselect.addIssuerName(crl.getIssuerX500Principal().getEncoded()); + crlselect.addIssuerName(PrincipalUtils.getIssuerPrincipal(crl).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL." + e, e); } - crlselect.setCompleteCRLEnabled(true); - Set completeSet = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); + PKIXCRLStoreSelector extSelect = new PKIXCRLStoreSelector.Builder(crlselect).setCompleteCRLEnabled(true).build(); + + Date validityDate = currentDate; + + if (paramsPKIX.getDate() != null) + { + validityDate = paramsPKIX.getDate(); + } + + Set completeSet = CRL_UTIL.findCRLs(extSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()); if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRL(s) try { - deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); + deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores())); } catch (AnnotatedException e) { @@ -727,7 +755,7 @@ public class RFC3280CertPathUtilities protected static void processCRLC( X509CRL deltaCRL, X509CRL completeCRL, - ExtendedPKIXParameters pkixParams) + PKIXExtendedParameters pkixParams) throws AnnotatedException { if (deltaCRL == null) @@ -748,7 +776,7 @@ public class RFC3280CertPathUtilities if (pkixParams.isUseDeltasEnabled()) { // (c) (1) - if (!deltaCRL.getIssuerX500Principal().equals(completeCRL.getIssuerX500Principal())) + if (!PrincipalUtils.getIssuerPrincipal(deltaCRL).equals(PrincipalUtils.getIssuerPrincipal(completeCRL))) { throw new AnnotatedException("Complete CRL issuer does not match delta CRL issuer."); } @@ -835,7 +863,7 @@ public class RFC3280CertPathUtilities X509CRL deltacrl, Object cert, CertStatus certStatus, - ExtendedPKIXParameters pkixParams) + PKIXExtendedParameters pkixParams) throws AnnotatedException { if (pkixParams.isUseDeltasEnabled() && deltacrl != null) @@ -1164,13 +1192,12 @@ public class RFC3280CertPathUtilities // if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n))) { - X500Principal principal = CertPathValidatorUtilities.getSubjectPrincipal(cert); - ASN1InputStream aIn = new ASN1InputStream(principal.getEncoded()); + X500Name principal = PrincipalUtils.getSubjectPrincipal(cert); ASN1Sequence dns; try { - dns = DERSequence.getInstance(aIn.readObject()); + dns = DERSequence.getInstance(principal.getEncoded()); } catch (Exception e) { @@ -1200,10 +1227,11 @@ public class RFC3280CertPathUtilities throw new CertPathValidatorException("Subject alternative name extension could not be decoded.", e, certPath, index); } - Vector emails = new X509Name(dns).getValues(X509Name.EmailAddress); - for (Enumeration e = emails.elements(); e.hasMoreElements();) + RDN[] emails = X500Name.getInstance(dns).getRDNs(BCStyle.EmailAddress); + for (int eI = 0; eI != emails.length; eI++) { - String email = (String)e.nextElement(); + // TODO: this should take into account multi-valued RDNs + String email = ((ASN1String)emails[eI].getFirst().getValue()).getString(); GeneralName emailAsGeneralName = new GeneralName(GeneralName.rfc822Name, email); try { @@ -1450,12 +1478,13 @@ public class RFC3280CertPathUtilities protected static void processCertA( CertPath certPath, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, int index, PublicKey workingPublicKey, boolean verificationAlreadyPerformed, - X500Principal workingIssuerName, - X509Certificate sign) + X500Name workingIssuerName, + X509Certificate sign, + JcaJceHelper helper) throws ExtCertPathValidatorException { List certs = certPath.getCertificates(); @@ -1506,7 +1535,7 @@ public class RFC3280CertPathUtilities try { checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX, - certPath, index), sign, workingPublicKey, certs); + certPath, index), sign, workingPublicKey, certs, helper); } catch (AnnotatedException e) { @@ -1522,9 +1551,9 @@ public class RFC3280CertPathUtilities // // (a) (4) name chaining // - if (!CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).equals(workingIssuerName)) + if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(workingIssuerName)) { - throw new ExtCertPathValidatorException("IssuerName(" + CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert) + throw new ExtCertPathValidatorException("IssuerName(" + PrincipalUtils.getEncodedIssuerPrincipal(cert) + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null, certPath, index); } @@ -1725,14 +1754,15 @@ public class RFC3280CertPathUtilities */ private static void checkCRL( DistributionPoint dp, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, CertStatus certStatus, ReasonsMask reasonMask, - List certPathCerts) + List certPathCerts, + JcaJceHelper helper) throws AnnotatedException { Date currentDate = new Date(System.currentTimeMillis()); @@ -1776,16 +1806,23 @@ public class RFC3280CertPathUtilities // (f) Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey, - paramsPKIX, certPathCerts); + paramsPKIX, certPathCerts, helper); // (g) PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys); X509CRL deltaCRL = null; + Date validityDate = currentDate; + + if (paramsPKIX.getDate() != null) + { + validityDate = paramsPKIX.getDate(); + } + if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRLs - Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl); + Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()); // we only want one valid delta CRL // (h) deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key); @@ -1804,7 +1841,7 @@ public class RFC3280CertPathUtilities * the CRL validity time */ - if (paramsPKIX.getValidityModel() != ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) + if (paramsPKIX.getValidityModel() != PKIXExtendedParameters.CHAIN_VALIDITY_MODEL) { /* * if a certificate has expired, but was revoked, it is not @@ -1844,8 +1881,8 @@ public class RFC3280CertPathUtilities if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); - criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); - criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); + criticalExtensions.remove(Extension.issuingDistributionPoint.getId()); + criticalExtensions.remove(Extension.deltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { @@ -1859,8 +1896,8 @@ public class RFC3280CertPathUtilities if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); - criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); - criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); + criticalExtensions.remove(Extension.issuingDistributionPoint.getId()); + criticalExtensions.remove(Extension.deltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { throw new AnnotatedException("Delta CRL contains unsupported critical extension."); @@ -1895,12 +1932,13 @@ public class RFC3280CertPathUtilities * or some error occurs. */ protected static void checkCRLs( - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate sign, PublicKey workingPublicKey, - List certPathCerts) + List certPathCerts, + JcaJceHelper helper) throws AnnotatedException { AnnotatedException lastException = null; @@ -1914,9 +1952,15 @@ public class RFC3280CertPathUtilities { throw new AnnotatedException("CRL distribution point extension could not be read.", e); } + + PKIXExtendedParameters.Builder paramsBldr = new PKIXExtendedParameters.Builder(paramsPKIX); try { - CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX); + List extras = CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX.getNamedCRLStoreMap()); + for (Iterator it = extras.iterator(); it.hasNext();) + { + paramsBldr.addCRLStore((PKIXCRLStore)it.next()); + } } catch (AnnotatedException e) { @@ -1925,6 +1969,7 @@ public class RFC3280CertPathUtilities } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); + PKIXExtendedParameters finalParams = paramsBldr.build(); boolean validCrlFound = false; // for each distribution point @@ -1943,10 +1988,9 @@ public class RFC3280CertPathUtilities { for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++) { - ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); try { - checkCRL(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); + checkCRL(dps[i], finalParams, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts, helper); validCrlFound = true; } catch (AnnotatedException e) @@ -1975,7 +2019,7 @@ public class RFC3280CertPathUtilities ASN1Primitive issuer = null; try { - issuer = new ASN1InputStream(CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).getEncoded()) + issuer = new ASN1InputStream(PrincipalUtils.getEncodedIssuerPrincipal(cert).getEncoded()) .readObject(); } catch (Exception e) @@ -1984,9 +2028,9 @@ public class RFC3280CertPathUtilities } DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.directoryName, issuer))), null, null); - ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); + PKIXExtendedParameters paramsPKIXClone = (PKIXExtendedParameters)paramsPKIX.clone(); checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, - certPathCerts); + certPathCerts, helper); validCrlFound = true; } catch (AnnotatedException e) @@ -2391,7 +2435,7 @@ public class RFC3280CertPathUtilities protected static PKIXPolicyNode wrapupCertG( CertPath certPath, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, Set userInitialPolicySet, int index, List[] policyNodes, diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java index b5b4f13..c9ee77c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java @@ -62,7 +62,7 @@ public class X509CRLObject private boolean isHashCodeSet = false; private int hashCodeValue; - static boolean isIndirectCRL(X509CRL crl) + public static boolean isIndirectCRL(X509CRL crl) throws CRLException { try |