diff options
4 files changed, 277 insertions, 137 deletions
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java index 1682df7..9317966 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java @@ -23,13 +23,18 @@ import java.security.KeyStoreException; import java.security.cert.CertPath; import java.security.cert.CertPathValidator; import java.security.cert.CertPathValidatorException; +import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateParsingException; import java.security.cert.CertificateFactory; +import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.List; @@ -179,12 +184,12 @@ public final class TrustManagerImpl implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - checkTrusted(chain, authType, null); + checkTrusted(chain, authType, null, true); } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - checkTrusted(chain, authType, null); + checkTrusted(chain, authType, null, false); } /** @@ -194,7 +199,7 @@ public final class TrustManagerImpl implements X509TrustManager { */ public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException { - return checkTrusted(chain, authType, host); + return checkTrusted(chain, authType, host, false); } public void handleTrustStorageUpdate() { @@ -202,10 +207,11 @@ public final class TrustManagerImpl implements X509TrustManager { trustedCertificateIndex.reset(); } else { trustedCertificateIndex.reset(trustAnchors(acceptedIssuers)); - } + } } - private List<X509Certificate> checkTrusted(X509Certificate[] chain, String authType, String host) + private List<X509Certificate> checkTrusted(X509Certificate[] chain, String authType, + String host, boolean clientAuth) throws CertificateException { if (chain == null || chain.length == 0 || authType == null || authType.length() == 0) { throw new IllegalArgumentException("null or zero-length parameter"); @@ -284,6 +290,8 @@ public final class TrustManagerImpl implements X509TrustManager { try { PKIXParameters params = new PKIXParameters(trustAnchor); params.setRevocationEnabled(false); + params.addCertPathChecker(new ExtendedKeyUsagePKIXCertPathChecker(clientAuth, + newChain[0])); validator.validate(certPath, params); // Add intermediate CAs to the index to tolerate sites // that assume that the browser will have cached these. @@ -382,28 +390,101 @@ public final class TrustManagerImpl implements X509TrustManager { } /** - * Check the trustedCertificateIndex for the cert to see if it is - * already trusted and failing that check the KeyStore if it is - * available. + * If an EKU extension is present in the end-entity certificate, + * it MUST contain an appropriate key usage. For servers, this + * includes anyExtendedKeyUsage, serverAuth, or the historical + * Server Gated Cryptography options of nsSGC or msSGC. For + * clients, this includes anyExtendedKeyUsage and clientAuth. */ - private TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) { - TrustAnchor trustAnchor = trustedCertificateIndex.findBySubjectAndPublicKey(cert); - if (trustAnchor != null) { - return trustAnchor; + private static class ExtendedKeyUsagePKIXCertPathChecker extends PKIXCertPathChecker { + + private static final String EKU_OID = "2.5.29.37"; + + private static final String EKU_anyExtendedKeyUsage = "2.5.29.37.0"; + private static final String EKU_clientAuth = "1.3.6.1.5.5.7.3.2"; + private static final String EKU_serverAuth = "1.3.6.1.5.5.7.3.1"; + private static final String EKU_nsSGC = "2.16.840.1.113730.4.1"; + private static final String EKU_msSGC = "1.3.6.1.4.1.311.10.3.3"; + + private static final Set<String> SUPPORTED_EXTENSIONS + = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(EKU_OID))); + + private final boolean clientAuth; + private final X509Certificate leaf; + + private ExtendedKeyUsagePKIXCertPathChecker(boolean clientAuth, X509Certificate leaf) { + this.clientAuth = clientAuth; + this.leaf = leaf; } - if (trustedCertificateStore == null) { - // not trusted and no TrustedCertificateStore to check - return null; + + @Override public void init(boolean forward) throws CertPathValidatorException { } - // probe KeyStore for a cert. AndroidCAStore stores its - // contents hashed by cert subject on the filesystem to make - // this faster than scanning all key store entries. - if (trustedCertificateStore.isTrustAnchor(cert)) { - // add new TrustAnchor to params index to avoid - // checking filesystem next time around. - return trustedCertificateIndex.index(cert); + + @Override public boolean isForwardCheckingSupported() { + return true; + } + + @Override public Set<String> getSupportedExtensions() { + return SUPPORTED_EXTENSIONS; + } + + @Override public void check(Certificate c, Collection<String> unresolvedCritExts) + throws CertPathValidatorException { + // We only want to validate the EKU on the leaf certificate. + if (c != leaf) { + return; + } + List<String> ekuOids; + try { + ekuOids = leaf.getExtendedKeyUsage(); + } catch (CertificateParsingException e) { + // A malformed EKU is bad news, consider it fatal. + throw new CertPathValidatorException(e); + } + // We are here to check EKU, but there is none. + if (ekuOids == null) { + return; + } + + boolean goodExtendedKeyUsage = false; + for (String ekuOid : ekuOids) { + // anyExtendedKeyUsage for clients and servers + if (ekuOid.equals(EKU_anyExtendedKeyUsage)) { + goodExtendedKeyUsage = true; + break; + } + + // clients + if (clientAuth) { + if (ekuOid.equals(EKU_clientAuth)) { + goodExtendedKeyUsage = true; + break; + } + continue; + } + + // servers + if (ekuOid.equals(EKU_serverAuth)) { + goodExtendedKeyUsage = true; + break; + } + if (ekuOid.equals(EKU_nsSGC)) { + goodExtendedKeyUsage = true; + break; + } + if (ekuOid.equals(EKU_msSGC)) { + goodExtendedKeyUsage = true; + break; + } + } + if (goodExtendedKeyUsage) { + // Mark extendedKeyUsage as resolved if present. + unresolvedCritExts.remove(EKU_OID); + } else { + throw new CertPathValidatorException("End-entity certificate does not have a valid " + + "extendedKeyUsage."); + } } - return null; } private TrustAnchor findTrustAnchorByIssuerAndSignature(X509Certificate lastCert) { @@ -424,6 +505,31 @@ public final class TrustManagerImpl implements X509TrustManager { return null; } + /** + * Check the trustedCertificateIndex for the cert to see if it is + * already trusted and failing that check the KeyStore if it is + * available. + */ + private TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) { + TrustAnchor trustAnchor = trustedCertificateIndex.findBySubjectAndPublicKey(cert); + if (trustAnchor != null) { + return trustAnchor; + } + if (trustedCertificateStore == null) { + // not trusted and no TrustedCertificateStore to check + return null; + } + // probe KeyStore for a cert. AndroidCAStore stores its + // contents hashed by cert subject on the filesystem to make + // this faster than scanning all key store entries. + if (trustedCertificateStore.isTrustAnchor(cert)) { + // add new TrustAnchor to params index to avoid + // checking filesystem next time around. + return trustedCertificateIndex.index(cert); + } + return null; + } + @Override public X509Certificate[] getAcceptedIssuers() { return (acceptedIssuers != null) ? acceptedIssuers.clone() : acceptedIssuers(rootKeyStore); } diff --git a/luni/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java index ad931af..37d0e07 100644 --- a/luni/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java +++ b/luni/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java @@ -16,9 +16,10 @@ package libcore.javax.net.ssl; +import com.android.org.bouncycastle.asn1.x509.KeyPurposeId; import java.security.InvalidAlgorithmParameterException; -import java.security.KeyStore; import java.security.KeyStore.PrivateKeyEntry; +import java.security.KeyStore; import java.security.Provider; import java.security.Security; import java.security.cert.CertificateException; @@ -257,4 +258,55 @@ public class TrustManagerFactoryTest extends TestCase { trustManager.checkServerTrusted((X509Certificate[]) pke.getCertificateChain(), "RSA"); } + public void test_TrustManagerFactory_extendedKeyUsage() throws Exception { + // anyExtendedKeyUsage should work for client or server + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage, false, true, true); + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage, true, true, true); + + // critical clientAuth should work for client + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_clientAuth, false, true, false); + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_clientAuth, true, true, false); + + // critical serverAuth should work for server + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_serverAuth, false, false, true); + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_serverAuth, true, false, true); + + // codeSigning should not work + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_codeSigning, false, false, false); + test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_codeSigning, true, false, false); + } + + private void test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId keyPurposeId, + boolean critical, + boolean client, + boolean server) + throws Exception { + String algorithm = "RSA"; + TestKeyStore intermediateCa = TestKeyStore.getIntermediateCa(); + TestKeyStore leaf = new TestKeyStore.Builder() + .keyAlgorithms(new String[] { algorithm }) + .aliasPrefix("criticalCodeSigning") + .signer(intermediateCa.getPrivateKey("RSA", "RSA")) + .rootCa(intermediateCa.getRootCertificate("RSA")) + .addExtendedKeyUsage(keyPurposeId, critical) + .build(); + // leaf.dump("test_TrustManagerFactory_criticalCodeSigning"); + PrivateKeyEntry privateKeyEntry = leaf.getPrivateKey(algorithm, algorithm); + X509Certificate[] chain = (X509Certificate[]) privateKeyEntry.getCertificateChain(); + + TestKeyStore rootCa = TestKeyStore.getRootCa(); + X509TrustManager trustManager = (X509TrustManager) rootCa.trustManagers[0]; + try { + trustManager.checkClientTrusted(chain, algorithm); + assertTrue(client); + } catch (Exception e) { + assertFalse(client); + } + try { + trustManager.checkServerTrusted(chain, algorithm); + assertTrue(server); + } catch (Exception e) { + assertFalse(server); + } + } } diff --git a/luni/src/test/java/tests/api/javax/net/ssl/X509TrustManagerTest.java b/luni/src/test/java/tests/api/javax/net/ssl/X509TrustManagerTest.java index ebe57de..ade0eca 100644 --- a/luni/src/test/java/tests/api/javax/net/ssl/X509TrustManagerTest.java +++ b/luni/src/test/java/tests/api/javax/net/ssl/X509TrustManagerTest.java @@ -1,210 +1,149 @@ package tests.api.javax.net.ssl; import java.io.ByteArrayInputStream; -import java.security.cert.CertificateFactory; import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; - import junit.framework.TestCase; - import org.apache.harmony.security.tests.support.cert.TestUtils; import org.apache.harmony.xnet.tests.support.X509TrustManagerImpl; -/** - * Tests for <code>X509TrustManager</code> class constructors and methods. - */ public class X509TrustManagerTest extends TestCase { - private X509Certificate[] setX509Certificate() { - try { - CertificateFactory certFact = CertificateFactory.getInstance("X.509"); - X509Certificate pemCert = (X509Certificate) certFact - .generateCertificate(new ByteArrayInputStream(TestUtils - .getX509Certificate_v3())); - X509Certificate[] xcert = {pemCert}; - return xcert; - } catch (Exception ex) { - fail("Unexpected exception " + ex); - } - return null; + private X509Certificate[] setX509Certificate() throws Exception { + CertificateFactory certFact = CertificateFactory.getInstance("X.509"); + X509Certificate pemCert = (X509Certificate) certFact.generateCertificate( + new ByteArrayInputStream(TestUtils.getX509Certificate_v3())); + X509Certificate[] xcert = { pemCert }; + return xcert; } - private X509Certificate[] setInvalid() { - try { - CertificateFactory certFact = CertificateFactory.getInstance("X.509"); - X509Certificate pemCert = (X509Certificate) certFact - .generateCertificate(new ByteArrayInputStream(TestUtils - .getX509Certificate_v1())); - X509Certificate[] xcert = {pemCert}; - return xcert; - } catch (Exception ex) { - fail("Unexpected exception " + ex); - } - return null; + private X509Certificate[] setInvalid() throws Exception { + CertificateFactory certFact = CertificateFactory.getInstance("X.509"); + X509Certificate pemCert = (X509Certificate) certFact.generateCertificate( + new ByteArrayInputStream(TestUtils.getX509Certificate_v1())); + X509Certificate[] xcert = { pemCert }; + return xcert; } - /** - * javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[] chain, String authType) - */ - public void test_checkClientTrusted_01() { + public void test_checkClientTrusted_01() throws Exception { X509TrustManagerImpl xtm = new X509TrustManagerImpl(); X509Certificate[] xcert = null; try { xtm.checkClientTrusted(xcert, "SSL"); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } xcert = new X509Certificate[0]; try { xtm.checkClientTrusted(xcert, "SSL"); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } xcert = setX509Certificate(); try { xtm.checkClientTrusted(xcert, null); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } try { xtm.checkClientTrusted(xcert, ""); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } } /** * javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[] chain, String authType) */ - public void test_checkClientTrusted_02() { + public void test_checkClientTrusted_02() throws Exception { X509TrustManagerImpl xtm = new X509TrustManagerImpl(); X509Certificate[] xcert = setInvalid(); try { xtm.checkClientTrusted(xcert, "SSL"); fail("CertificateException wasn't thrown"); - } catch (CertificateException ce) { - //expected + } catch (CertificateException expected) { } } /** * javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[] chain, String authType) */ - public void test_checkClientTrusted_03() { + public void test_checkClientTrusted_03() throws Exception { X509TrustManagerImpl xtm = new X509TrustManagerImpl(); X509Certificate[] xcert = setX509Certificate(); - - try { - xtm.checkClientTrusted(xcert, "SSL"); - } catch (Exception ex) { - fail("Unexpected exception " + ex); - } + xtm.checkClientTrusted(xcert, "SSL"); } /** * javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[] chain, String authType) */ - public void test_checkServerTrusted_01() { + public void test_checkServerTrusted_01() throws Exception { X509TrustManagerImpl xtm = new X509TrustManagerImpl(); X509Certificate[] xcert = null; try { xtm.checkServerTrusted(xcert, "SSL"); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } xcert = new X509Certificate[0]; try { xtm.checkServerTrusted(xcert, "SSL"); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } xcert = setX509Certificate(); try { xtm.checkServerTrusted(xcert, null); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } try { xtm.checkServerTrusted(xcert, ""); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } } /** * javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[] chain, String authType) */ - public void test_checkServerTrusted_02() { + public void test_checkServerTrusted_02() throws Exception { X509TrustManagerImpl xtm = new X509TrustManagerImpl(); X509Certificate[] xcert = setInvalid(); try { xtm.checkServerTrusted(xcert, "SSL"); fail("CertificateException wasn't thrown"); - } catch (CertificateException ce) { - //expected + } catch (CertificateException expected) { } } /** * javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[] chain, String authType) */ - public void test_checkServerTrusted_03() { + public void test_checkServerTrusted_03() throws Exception { X509TrustManagerImpl xtm = new X509TrustManagerImpl(); X509Certificate[] xcert = setX509Certificate(); - - try { - xtm.checkServerTrusted(xcert, "SSL"); - } catch (Exception ex) { - fail("Unexpected exception " + ex); - } + xtm.checkServerTrusted(xcert, "SSL"); } /** * javax.net.ssl.X509TrustManager#getAcceptedIssuers() */ - public void test_getAcceptedIssuers() { + public void test_getAcceptedIssuers() throws Exception { X509TrustManagerImpl xtm = new X509TrustManagerImpl(); - - try { - assertNotNull(xtm.getAcceptedIssuers()); - } catch (Exception ex) { - fail("Unexpected exception " + ex); - } + assertNotNull(xtm.getAcceptedIssuers()); } } diff --git a/support/src/test/java/libcore/java/security/TestKeyStore.java b/support/src/test/java/libcore/java/security/TestKeyStore.java index 74c2840..aee7f8a 100644 --- a/support/src/test/java/libcore/java/security/TestKeyStore.java +++ b/support/src/test/java/libcore/java/security/TestKeyStore.java @@ -18,9 +18,11 @@ package libcore.java.security; import com.android.org.bouncycastle.asn1.DEROctetString; import com.android.org.bouncycastle.asn1.x509.BasicConstraints; +import com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage; import com.android.org.bouncycastle.asn1.x509.GeneralName; import com.android.org.bouncycastle.asn1.x509.GeneralNames; import com.android.org.bouncycastle.asn1.x509.GeneralSubtree; +import com.android.org.bouncycastle.asn1.x509.KeyPurposeId; import com.android.org.bouncycastle.asn1.x509.KeyUsage; import com.android.org.bouncycastle.asn1.x509.NameConstraints; import com.android.org.bouncycastle.asn1.x509.X509Extensions; @@ -75,6 +77,7 @@ import libcore.javax.net.ssl.TestTrustManager; public final class TestKeyStore extends Assert { private static TestKeyStore ROOT_CA; + private static TestKeyStore INTERMEDIATE_CA; private static TestKeyStore SERVER; private static TestKeyStore CLIENT; @@ -145,7 +148,7 @@ public final class TestKeyStore extends Assert { .subject("CN=Test Root Certificate Authority") .ca(true) .build(); - TestKeyStore intermediateCa = new Builder() + INTERMEDIATE_CA = new Builder() .aliasPrefix("IntermediateCA") .subject("CN=Test Intermediate Certificate Authority") .ca(true) @@ -154,15 +157,15 @@ public final class TestKeyStore extends Assert { .build(); SERVER = new Builder() .aliasPrefix("server") - .signer(intermediateCa.getPrivateKey("RSA", "RSA")) - .rootCa(intermediateCa.getRootCertificate("RSA")) + .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA")) + .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA")) .build(); - CLIENT = new TestKeyStore(createClient(intermediateCa.keyStore), null, null); + CLIENT = new TestKeyStore(createClient(INTERMEDIATE_CA.keyStore), null, null); CLIENT_CERTIFICATE = new Builder() .aliasPrefix("client") .subject("emailAddress=test@user") - .signer(intermediateCa.getPrivateKey("RSA", "RSA")) - .rootCa(intermediateCa.getRootCertificate("RSA")) + .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA")) + .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA")) .build(); TestKeyStore rootCa2 = new Builder() .aliasPrefix("RootCA2") @@ -173,6 +176,22 @@ public final class TestKeyStore extends Assert { } /** + * Return an root CA that can be used to issue new certificates. + */ + public static TestKeyStore getRootCa() { + initCerts(); + return ROOT_CA; + } + + /** + * Return an intermediate CA that can be used to issue new certificates. + */ + public static TestKeyStore getIntermediateCa() { + initCerts(); + return INTERMEDIATE_CA; + } + + /** * Return a server keystore with a matched RSA certificate and * private key as well as a CA certificate. */ @@ -223,10 +242,13 @@ public final class TestKeyStore extends Assert { private boolean ca; private PrivateKeyEntry signer; private Certificate rootCa; + private final List<KeyPurposeId> extendedKeyUsages = new ArrayList<KeyPurposeId>(); + private final List<Boolean> criticalExtendedKeyUsages = new ArrayList<Boolean>(); private final List<GeneralName> subjectAltNames = new ArrayList<GeneralName>(); - private final Vector<GeneralSubtree> permittedNameConstraints - = new Vector<GeneralSubtree>(); - private final Vector<GeneralSubtree> excludedNameConstraints = new Vector<GeneralSubtree>(); + private final List<GeneralSubtree> permittedNameConstraints + = new ArrayList<GeneralSubtree>(); + private final List<GeneralSubtree> excludedNameConstraints + = new ArrayList<GeneralSubtree>(); public Builder() { subject = localhost(); @@ -284,7 +306,13 @@ public final class TestKeyStore extends Assert { return this; } - private Builder addSubjectAltName(GeneralName generalName) { + public Builder addExtendedKeyUsage(KeyPurposeId keyPurposeId, boolean critical) { + extendedKeyUsages.add(keyPurposeId); + criticalExtendedKeyUsages.add(critical); + return this; + } + + public Builder addSubjectAltName(GeneralName generalName) { subjectAltNames.add(generalName); return this; } @@ -413,6 +441,7 @@ public final class TestKeyStore extends Assert { : subject); PrivateKey signingKey = (caKey == null) ? privateKey : caKey; x509c = createCertificate(publicKey, signingKey, subject, issuer, keyUsage, ca, + extendedKeyUsages, criticalExtendedKeyUsages, subjectAltNames, permittedNameConstraints, excludedNameConstraints); } @@ -456,9 +485,11 @@ public final class TestKeyStore extends Assert { return createCertificate(publicKey, privateKey, principal, principal, 0, true, - new Vector<GeneralName>(), - new Vector<GeneralSubtree>(), - new Vector<GeneralSubtree>()); + new ArrayList<KeyPurposeId>(), + new ArrayList<Boolean>(), + new ArrayList<GeneralName>(), + new ArrayList<GeneralSubtree>(), + new ArrayList<GeneralSubtree>()); } catch (Exception e) { throw new RuntimeException(e); } @@ -471,9 +502,11 @@ public final class TestKeyStore extends Assert { X500Principal issuer, int keyUsage, boolean ca, + List<KeyPurposeId> extendedKeyUsages, + List<Boolean> criticalExtendedKeyUsages, List<GeneralName> subjectAltNames, - Vector<GeneralSubtree> permittedNameConstraints, - Vector<GeneralSubtree> excludedNameConstraints) throws Exception { + List<GeneralSubtree> permittedNameConstraints, + List<GeneralSubtree> excludedNameConstraints) throws Exception { // Note that there is no way to programmatically make a // Certificate using java.* or javax.* APIs. The // CertificateFactory interface assumes you want to read @@ -520,6 +553,13 @@ public final class TestKeyStore extends Assert { true, new BasicConstraints(true)); } + for (int i = 0; i < extendedKeyUsages.size(); i++) { + KeyPurposeId keyPurposeId = extendedKeyUsages.get(i); + boolean critical = criticalExtendedKeyUsages.get(i); + x509cg.addExtension(X509Extensions.ExtendedKeyUsage, + critical, + new ExtendedKeyUsage(keyPurposeId)); + } for (GeneralName subjectAltName : subjectAltNames) { x509cg.addExtension(X509Extensions.SubjectAlternativeName, false, @@ -592,10 +632,6 @@ public final class TestKeyStore extends Assert { /** * Create an empty KeyStore - * - * The KeyStore is optionally password protected by the - * keyStorePassword argument, which can be null if a password is - * not desired. */ public static KeyStore createKeyStore() { try { @@ -815,6 +851,13 @@ public final class TestKeyStore extends Assert { /** * Dump a key store for debugging. */ + public void dump(String context) throws KeyStoreException, NoSuchAlgorithmException { + dump(context, keyStore, keyPassword); + } + + /** + * Dump a key store for debugging. + */ public static void dump(String context, KeyStore keyStore, char[] keyPassword) throws KeyStoreException, NoSuchAlgorithmException { PrintStream out = System.out; |