diff --git a/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java index 119548f4c4b..7855dc22a65 100644 --- a/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java @@ -25,12 +25,10 @@ import java.io.Closeable; import java.io.IOException; -import java.io.InputStream; import java.net.InetAddress; import java.net.URI; import java.security.AccessController; import java.security.KeyStore; -import java.security.KeyStoreException; import java.security.PrivilegedAction; import java.security.Security; import java.util.Locale; @@ -38,17 +36,11 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509ExtendedKeyManager; -import javax.net.ssl.X509TrustManager; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -63,6 +55,8 @@ import org.wildfly.security.ssl.SSLUtils; import org.wildfly.security.ssl.test.util.CAGenerationTool; import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; +import org.wildfly.security.ssl.test.util.DefinedCAIdentity; +import org.wildfly.security.ssl.test.util.DefinedIdentity; import org.wildfly.security.x500.principal.X500AttributePrincipalDecoder; /** @@ -72,64 +66,13 @@ */ public class MaskedPasswordSSLAuthenticationTest { - private static final char[] PASSWORD = "Elytron".toCharArray(); + private static final String JKS_LOCATION = "./target/test-classes/jks"; private static CAGenerationTool caGenerationTool; - /** - * Get the key manager backed by the specified key store. - * - * @param keystorePath the path to the keystore with X509 private key - * @return the initialised key manager. - */ - private static X509ExtendedKeyManager getKeyManager(final String keystorePath) throws Exception { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); - keyManagerFactory.init(createKeyStore(keystorePath), PASSWORD); - - for (KeyManager current : keyManagerFactory.getKeyManagers()) { - if (current instanceof X509ExtendedKeyManager) { - return (X509ExtendedKeyManager) current; - } - } - - throw new IllegalStateException("Unable to obtain X509ExtendedKeyManager."); - } - - private static TrustManagerFactory getTrustManagerFactory() throws Exception { - return TrustManagerFactory.getInstance("PKIX"); - } - - /** - * Get the trust manager that trusts all certificates signed by the certificate authority. - * - * @return the trust manager that trusts all certificates signed by the certificate authority. - * @throws KeyStoreException - */ - private static X509TrustManager getCATrustManager() throws Exception { - TrustManagerFactory trustManagerFactory = getTrustManagerFactory(); - trustManagerFactory.init(createKeyStore("/jks/ca.truststore")); - - for (TrustManager current : trustManagerFactory.getTrustManagers()) { - if (current instanceof X509TrustManager) { - return (X509TrustManager) current; - } - } - - throw new IllegalStateException("Unable to obtain X509TrustManager."); - } - - private static KeyStore createKeyStore(final String path) throws Exception { - KeyStore keyStore = KeyStore.getInstance("jks"); - try (InputStream caTrustStoreFile = MaskedPasswordSSLAuthenticationTest.class.getResourceAsStream(path)) { - keyStore.load(caTrustStoreFile, PASSWORD); - } - - return keyStore; - } - - private static SecurityDomain getKeyStoreBackedSecurityDomain(String keyStorePath) throws Exception { - SecurityRealm securityRealm = new KeyStoreBackedSecurityRealm(createKeyStore(keyStorePath)); + private static SecurityDomain getKeyStoreBackedSecurityDomain(KeyStore keyStore) throws Exception { + SecurityRealm securityRealm = new KeyStoreBackedSecurityRealm(keyStore); return SecurityDomain.builder() .addRealm("KeystoreRealm", securityRealm) @@ -156,10 +99,13 @@ public static void afterTest() throws IOException { @Test public void testTwoWay() throws Exception { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); + SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java index 8666bf529f6..7555998138f 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java @@ -17,12 +17,12 @@ */ package org.wildfly.security.ssl; -import static org.junit.Assert.fail; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import static org.wildfly.security.ssl.test.util.CAGenerationTool.SIGNATURE_ALGORTHM; import static org.wildfly.security.x500.X500.OID_AD_OCSP; import static org.wildfly.security.x500.X500.OID_KP_OCSP_SIGNING; @@ -37,10 +37,9 @@ import java.net.ServerSocket; import java.net.SocketException; import java.net.URI; -import java.security.Principal; -import java.security.KeyStore; -import java.security.KeyStoreException; import java.security.AccessController; +import java.security.KeyStore; +import java.security.Principal; import java.security.PrivilegedAction; import java.security.Security; import java.security.cert.X509Certificate; @@ -55,17 +54,12 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509ExtendedKeyManager; -import javax.net.ssl.X509TrustManager; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x500.X500Name; @@ -79,21 +73,24 @@ import org.junit.BeforeClass; import org.junit.Test; import org.wildfly.common.Assert; -import org.wildfly.security.auth.server.SecurityIdentity; -import org.wildfly.security.password.WildFlyElytronPasswordProvider; import org.wildfly.security.auth.client.AuthenticationContext; import org.wildfly.security.auth.client.AuthenticationContextConfigurationClient; import org.wildfly.security.auth.realm.KeyStoreBackedSecurityRealm; import org.wildfly.security.auth.server.SecurityDomain; +import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.auth.server.SecurityRealm; +import org.wildfly.security.password.WildFlyElytronPasswordProvider; import org.wildfly.security.permission.PermissionVerifier; import org.wildfly.security.ssl.test.util.CAGenerationTool; import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; +import org.wildfly.security.ssl.test.util.CustomIdentity; +import org.wildfly.security.ssl.test.util.DefinedCAIdentity; +import org.wildfly.security.ssl.test.util.DefinedIdentity; import org.wildfly.security.x500.GeneralName; -import org.wildfly.security.x500.principal.X500AttributePrincipalDecoder; import org.wildfly.security.x500.cert.AccessDescription; import org.wildfly.security.x500.cert.AuthorityInformationAccessExtension; import org.wildfly.security.x500.cert.ExtendedKeyUsageExtension; +import org.wildfly.security.x500.principal.X500AttributePrincipalDecoder; /** * Simple test case to test authentication occurring during the establishment of an {@link SSLSession}. @@ -123,64 +120,20 @@ public class SSLAuthenticationTest { private static final File LADYBUG_REVOKED_PEM_CRL = new File(WORKING_DIR_CACRL, "ladybug-revoked.pem"); private static TestingOcspServer ocspServer = null; private static X509Certificate ocspResponderCertificate; - - /** - * Get the key manager backed by the specified key store. - * - * @param keystorePath the path to the keystore with X509 private key - * @return the initialised key manager. - */ - private static X509ExtendedKeyManager getKeyManager(final String keystorePath) throws Exception { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); - keyManagerFactory.init(createKeyStore(keystorePath), PASSWORD); - - for (KeyManager current : keyManagerFactory.getKeyManagers()) { - if (current instanceof X509ExtendedKeyManager) { - return (X509ExtendedKeyManager) current; - } - } - - throw new IllegalStateException("Unable to obtain X509ExtendedKeyManager."); - } + private static KeyStore shortWingedKeyStore; + private static CustomIdentity goodIdentity; + private static CustomIdentity revokedIdentity; private static TrustManagerFactory getTrustManagerFactory() throws Exception { return TrustManagerFactory.getInstance("PKIX"); } - /** - * Get the trust manager that trusts all certificates signed by the certificate authority. - * - * @return the trust manager that trusts all certificates signed by the certificate authority. - * @throws KeyStoreException - */ - private static X509TrustManager getCATrustManager() throws Exception { - TrustManagerFactory trustManagerFactory = getTrustManagerFactory(); - trustManagerFactory.init(createKeyStore("/jks/ca.truststore")); - - for (TrustManager current : trustManagerFactory.getTrustManagers()) { - if (current instanceof X509TrustManager) { - return (X509TrustManager) current; - } - } - - throw new IllegalStateException("Unable to obtain X509TrustManager."); - } - private static KeyStore createKeyStore() throws Exception { KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(null,null); + ks.load(null, null); return ks; } - private static KeyStore createKeyStore(final String path) throws Exception { - KeyStore keyStore = KeyStore.getInstance("jks"); - try (InputStream caTrustStoreFile = SSLAuthenticationTest.class.getResourceAsStream(path)) { - keyStore.load(caTrustStoreFile, PASSWORD); - } - - return keyStore; - } - private static void createTemporaryKeyStoreFile(KeyStore keyStore, File outputFile, char[] password) throws Exception { if (!outputFile.exists()) { outputFile.createNewFile(); @@ -190,12 +143,12 @@ private static void createTemporaryKeyStoreFile(KeyStore keyStore, File outputFi } } - private static SecurityDomain getKeyStoreBackedSecurityDomain(String keyStorePath) throws Exception { - return getKeyStoreBackedSecurityDomain(keyStorePath, true); + private static SecurityDomain getKeyStoreBackedSecurityDomain(KeyStore keyStore) throws Exception { + return getKeyStoreBackedSecurityDomain(keyStore, true); } - private static SecurityDomain getKeyStoreBackedSecurityDomain(String keyStorePath, boolean decoder) throws Exception { - SecurityRealm securityRealm = new KeyStoreBackedSecurityRealm(createKeyStore(keyStorePath)); + private static SecurityDomain getKeyStoreBackedSecurityDomain(KeyStore keyStore, boolean decoder) throws Exception { + SecurityRealm securityRealm = new KeyStoreBackedSecurityRealm(keyStore); SecurityDomain.Builder builder = SecurityDomain.builder() .addRealm("KeystoreRealm", securityRealm) @@ -222,34 +175,42 @@ public static void beforeTest() throws Exception { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // Generates certificate and keystore for OCSP responder - ocspResponderCertificate = caGenerationTool.createIdentity("ocspResponder", - new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=OcspResponder"), - "ocsp-responder.keystore", Identity.CA, new ExtendedKeyUsageExtension(false, Collections.singletonList(OID_KP_OCSP_SIGNING))); + DefinedCAIdentity caIdentity = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedCAIdentity intermediateCAIdentity = caGenerationTool.getDefinedCAIdentity(Identity.INTERMEDIATE); + CustomIdentity responderIdentity = caIdentity.createIdentity("ocspResponder", + new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=OcspResponder"), + "ocsp-responder.keystore", new ExtendedKeyUsageExtension(false, Collections.singletonList(OID_KP_OCSP_SIGNING))); + ocspResponderCertificate = responderIdentity.getCertificate(); // Generates GOOD certificate referencing the OCSP responder - X509Certificate ocspCheckedGoodCertificate = caGenerationTool.createIdentity("checked", - new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=ocspCheckedGood"), - "ocsp-checked-good.keystore", Identity.INTERMEDIATE, new AuthorityInformationAccessExtension(Collections.singletonList( - new AccessDescription(OID_AD_OCSP, new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp")) - ))); + goodIdentity = intermediateCAIdentity.createIdentity("checked", + new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=ocspCheckedGood"), + "ocsp-checked-good.keystore", new AuthorityInformationAccessExtension(Collections.singletonList( + new AccessDescription(OID_AD_OCSP, new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp")) + ))); + X509Certificate ocspCheckedGoodCertificate = goodIdentity.getCertificate(); // Generates REVOKED certificate referencing the OCSP responder - X509Certificate ocspCheckedRevokedCertificate = caGenerationTool.createIdentity("checked", - new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=ocspCheckedRevoked"), - "ocsp-checked-revoked.keystore", Identity.CA, (new AuthorityInformationAccessExtension(Collections.singletonList( - new AccessDescription(OID_AD_OCSP, new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp")) - )))); + revokedIdentity = caIdentity.createIdentity("checked", + new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=ocspCheckedRevoked"), + "ocsp-checked-revoked.keystore", (new AuthorityInformationAccessExtension(Collections.singletonList( + new AccessDescription(OID_AD_OCSP, new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp")) + )))); + X509Certificate ocspCheckedRevokedCertificate = revokedIdentity.getCertificate(); // Generates UNKNOWN certificate referencing the OCSP responder - X509Certificate ocspCheckedUnknownCertificate = caGenerationTool.createIdentity("checked", - new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=ocspCheckedUnknown"), - "ocsp-checked-unknown.keystore", Identity.CA, new AuthorityInformationAccessExtension(Collections.singletonList( - new AccessDescription(OID_AD_OCSP, new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp")) - ))); - - X509Certificate greenJuneCertificate = caGenerationTool.getCertificate(Identity.GREENJUNE); - - KeyStore beetlesKeyStore = createKeyStore("/jks/beetles.keystore"); + CustomIdentity unknownIdentity = caIdentity.createIdentity("checked", + new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=ocspCheckedUnknown"), + "ocsp-checked-unknown.keystore", new AuthorityInformationAccessExtension(Collections.singletonList( + new AccessDescription(OID_AD_OCSP, new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp")) + ))); + X509Certificate ocspCheckedUnknownCertificate = unknownIdentity.getCertificate(); + + X509Certificate greenJuneCertificate = caGenerationTool + .getDefinedIdentity(Identity.GREENJUNE) + .getCertificate(); + + KeyStore beetlesKeyStore = caGenerationTool.getBeetlesKeyStore(); beetlesKeyStore.setCertificateEntry("ocspResponder", ocspResponderCertificate); beetlesKeyStore.setCertificateEntry("ocspCheckedGood", ocspCheckedGoodCertificate); beetlesKeyStore.setCertificateEntry("ocspCheckedRevoked", ocspCheckedRevokedCertificate); @@ -258,9 +219,9 @@ public static void beforeTest() throws Exception { createTemporaryKeyStoreFile(beetlesKeyStore, new File(JKS_LOCATION, "beetles.keystore"), PASSWORD); // Adds trusted cert for shortwinged - KeyStore shortwingedKeyStore = createKeyStore(); - shortwingedKeyStore.setCertificateEntry("rove", caGenerationTool.getCertificate(Identity.ROVE)); - createTemporaryKeyStoreFile(shortwingedKeyStore, SHORTWINGED_FILE, PASSWORD); + shortWingedKeyStore = createKeyStore(); + shortWingedKeyStore.setCertificateEntry("rove", caGenerationTool.getDefinedIdentity(Identity.ROVE).getCertificate()); + //createTemporaryKeyStoreFile(shortwingedKeyStore, SHORTWINGED_FILE, PASSWORD); // Used for all CRLs Calendar calendar = Calendar.getInstance(); @@ -273,52 +234,53 @@ public static void beforeTest() throws Exception { // Creates the CRL for ca/crl/blank.pem X509v2CRLBuilder caBlankCrlBuilder = new X509v2CRLBuilder( - convertSunStyleToBCStyle(caGenerationTool.getCertificate(Identity.CA).getSubjectDN()), + convertSunStyleToBCStyle(caIdentity.getCertificate().getSubjectDN()), currentDate ); X509CRLHolder caBlankCrlHolder = caBlankCrlBuilder.setNextUpdate(nextYear).build( new JcaContentSignerBuilder(SIGNATURE_ALGORTHM) .setProvider("BC") - .build(caGenerationTool.getPrivateKey(Identity.CA)) + .build(caIdentity.getPrivateKey()) ); // Creates the CRL for ica/crl/blank.pem X509v2CRLBuilder icaBlankCrlBuilder = new X509v2CRLBuilder( - convertSunStyleToBCStyle(caGenerationTool.getCertificate(Identity.INTERMEDIATE).getSubjectDN()), + convertSunStyleToBCStyle(intermediateCAIdentity.getCertificate().getSubjectDN()), currentDate ); X509CRLHolder icaBlankCrlHolder = icaBlankCrlBuilder.setNextUpdate(nextYear).build( new JcaContentSignerBuilder(SIGNATURE_ALGORTHM) .setProvider("BC") - .build(caGenerationTool.getPrivateKey(Identity.INTERMEDIATE)) + .build(intermediateCAIdentity.getPrivateKey()) ); // Creates the CRL for firefly-revoked.pem X509v2CRLBuilder fireflyRevokedCrlBuilder = new X509v2CRLBuilder( - convertSunStyleToBCStyle(caGenerationTool.getCertificate(Identity.CA).getSubjectDN()), + convertSunStyleToBCStyle(caIdentity.getCertificate().getSubjectDN()), currentDate ); fireflyRevokedCrlBuilder.addCRLEntry( - caGenerationTool.getCertificate(Identity.FIREFLY).getSerialNumber(), + caGenerationTool.getDefinedIdentity(Identity.FIREFLY).getCertificate().getSerialNumber(), revokeDate, CRLReason.unspecified ); X509CRLHolder fireflyRevokedCrlHolder = fireflyRevokedCrlBuilder.setNextUpdate(nextYear).build( new JcaContentSignerBuilder(SIGNATURE_ALGORTHM) .setProvider("BC") - .build(caGenerationTool.getPrivateKey(Identity.CA)) + .build(caIdentity.getPrivateKey()) ); + DefinedCAIdentity secondCAIdentity = caGenerationTool.getDefinedCAIdentity(Identity.SECOND_CA); // Creates the CRL for ladybug-revoked.pem X509v2CRLBuilder ladybugRevokedCrlBuilder = new X509v2CRLBuilder( - convertSunStyleToBCStyle(caGenerationTool.getCertificate(Identity.SECOND_CA).getSubjectDN()), + convertSunStyleToBCStyle(secondCAIdentity.getCertificate().getSubjectDN()), currentDate ); // revokes the certificate with serial number #2 ladybugRevokedCrlBuilder.addCRLEntry( - caGenerationTool.getCertificate(Identity.LADYBUG).getSerialNumber(), + caGenerationTool.getDefinedIdentity(Identity.LADYBUG).getCertificate().getSerialNumber(), revokeDate, CRLReason.unspecified ); @@ -326,35 +288,35 @@ public static void beforeTest() throws Exception { X509CRLHolder ladybugRevokedCrlHolder = ladybugRevokedCrlBuilder.setNextUpdate(nextYear).build( new JcaContentSignerBuilder(SIGNATURE_ALGORTHM) .setProvider("BC") - .build(caGenerationTool.getPrivateKey(Identity.SECOND_CA)) + .build(secondCAIdentity.getPrivateKey()) ); // Creates the CRL for ica-revoked.pem X509v2CRLBuilder icaRevokedCrlBuilder = new X509v2CRLBuilder( - convertSunStyleToBCStyle(caGenerationTool.getCertificate(Identity.CA).getSubjectDN()), + convertSunStyleToBCStyle(caIdentity.getCertificate().getSubjectDN()), currentDate ); icaRevokedCrlBuilder.addCRLEntry( - caGenerationTool.getCertificate(Identity.INTERMEDIATE).getSerialNumber(), + intermediateCAIdentity.getCertificate().getSerialNumber(), revokeDate, CRLReason.unspecified ); X509CRLHolder icaRevokedCrlHolder = icaRevokedCrlBuilder.setNextUpdate(nextYear).build( new JcaContentSignerBuilder(SIGNATURE_ALGORTHM) .setProvider("BC") - .build(caGenerationTool.getPrivateKey(Identity.CA)) + .build(caIdentity.getPrivateKey()) ); // Creates the CRL for rove-revoked.pem X509v2CRLBuilder roveRevokedCrlBuilder = new X509v2CRLBuilder( - convertSunStyleToBCStyle(caGenerationTool.getCertificate(Identity.INTERMEDIATE).getSubjectDN()), + convertSunStyleToBCStyle(intermediateCAIdentity.getCertificate().getSubjectDN()), currentDate ); X509CRLHolder roveRevokedCrlHolder = roveRevokedCrlBuilder.setNextUpdate(nextYear).build( new JcaContentSignerBuilder(SIGNATURE_ALGORTHM) .setProvider("BC") - .build(caGenerationTool.getPrivateKey(Identity.INTERMEDIATE)) + .build(intermediateCAIdentity.getPrivateKey()) ); PemWriter caBlankCrlOutput = new PemWriter(new OutputStreamWriter(new FileOutputStream(CA_BLANK_PEM_CRL))); @@ -385,9 +347,9 @@ public static void beforeTest() throws Exception { roveRevokedCrlOutput.close(); ocspServer = new TestingOcspServer(OCSP_PORT); - ocspServer.createIssuer(1, caGenerationTool.getCertificate(Identity.CA)); - ocspServer.createIssuer(2, caGenerationTool.getCertificate(Identity.INTERMEDIATE)); - ocspServer.createCertificate(1, 1, caGenerationTool.getCertificate(Identity.INTERMEDIATE)); + ocspServer.createIssuer(1, caIdentity.getCertificate()); + ocspServer.createIssuer(2, intermediateCAIdentity.getCertificate()); + ocspServer.createCertificate(1, 1, intermediateCAIdentity.getCertificate()); ocspServer.createCertificate(2, 2, ocspCheckedGoodCertificate); ocspServer.createCertificate(3, 1, ocspCheckedRevokedCertificate); ocspServer.revokeCertificate(3, 4); @@ -433,8 +395,9 @@ public static void afterTest() throws Exception { @Test public void testOneWay() throws Throwable { + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setKeyManager(firefly.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way.org", true, "OU=Elytron,O=Elytron,C=UK,ST=Elytron,CN=Firefly", null, true); @@ -442,8 +405,9 @@ public void testOneWay() throws Throwable { @Test public void testCrlBlank() throws Throwable { + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setKeyManager(firefly.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-crl.org", true, "OU=Elytron,O=Elytron,C=UK,ST=Elytron,CN=Firefly", null, true); @@ -451,8 +415,9 @@ public void testCrlBlank() throws Throwable { @Test public void testServerRevoked() throws Throwable { + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setKeyManager(firefly.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-firefly-revoked.org", false, null, null, true); @@ -460,8 +425,9 @@ public void testServerRevoked() throws Throwable { @Test public void testServerIcaRevoked() throws Throwable { + DefinedIdentity rove = caGenerationTool.getDefinedIdentity(Identity.ROVE); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/rove.keystore")) + .setKeyManager(rove.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-ica-revoked.org", false, null, null, true); @@ -474,8 +440,9 @@ public void testServerIcaRevoked() throws Throwable { */ @Test public void testOneWayServerRejectedWithSingleCRL() throws Throwable { + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setKeyManager(firefly.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-one-crl.org", false, null, null, true); @@ -488,8 +455,9 @@ public void testOneWayServerRejectedWithSingleCRL() throws Throwable { */ @Test public void testOneWayServerRejectedWithMultipleCRL() throws Throwable { + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setKeyManager(firefly.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-multiple-crls-failure.org", false, @@ -503,8 +471,9 @@ public void testOneWayServerRejectedWithMultipleCRL() throws Throwable { */ @Test public void testOneWayServerAcceptedWithMultipleCRL() throws Throwable { + DefinedIdentity greenJune = caGenerationTool.getDefinedIdentity(Identity.GREENJUNE); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/greenjune.keystore")) + .setKeyManager(greenJune.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-multiple-crls-success.org", true, @@ -517,8 +486,9 @@ public void testOneWayServerAcceptedWithMultipleCRL() throws Throwable { */ @Test public void testCRLMaxCertPathSucceeds() throws Throwable { + DefinedIdentity rove = caGenerationTool.getDefinedIdentity(Identity.ROVE); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/rove.keystore")) + .setKeyManager(rove.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-max-cert-path.org", true, "OU=Elytron,O=Elytron,C=UK,ST=Elytron,CN=Rove", null, true); @@ -531,8 +501,9 @@ public void testCRLMaxCertPathSucceeds() throws Throwable { */ @Test public void testCRLMaxCertPathFails() throws Throwable { + DefinedIdentity rove = caGenerationTool.getDefinedIdentity(Identity.ROVE); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/rove.keystore")) + .setKeyManager(rove.createKeyManager()) .build().create(); performConnectionTest(serverContext, "protocol://test-one-way-max-cert-path-failure.org", false, null, null, true); @@ -540,10 +511,12 @@ public void testCRLMaxCertPathFails() throws Throwable { @Test public void testTwoWay() throws Throwable { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); @@ -553,10 +526,12 @@ public void testTwoWay() throws Throwable { @Test public void testTwoWayNoDecoder() throws Throwable { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore", false)) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore(), false)) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); @@ -566,10 +541,12 @@ public void testTwoWayNoDecoder() throws Throwable { @Test public void testTwoWayIca() throws Throwable { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/shortwinged.keystore")) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(shortWingedKeyStore)) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); @@ -585,9 +562,10 @@ public void testTwoWayIca() throws Throwable { public void testAcceptedIssuersConfiguredWithCRL() throws Throwable { InputStream crl = new FileInputStream("./target/test-classes/ica/crl/blank-blank.pem"); + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); X509RevocationTrustManager trustManager = X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore")) + .setTrustStore(ca.loadKeyStore()) .setCrlStream(crl) .setPreferCrls(true) .setNoFallback(true) @@ -608,11 +586,13 @@ public void testTwoWayClientRejectedWithSingleCRL() throws Throwable { // this CRL contains the certificate with the alias "ladybug" which is being sent by the client crlStreams.add(new FileInputStream("target/test-classes/ca/crl/ladybug-revoked.pem")); + DefinedCAIdentity secondCA = caGenerationTool.getDefinedCAIdentity(Identity.SECOND_CA); + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setKeyManager(firefly.createKeyManager()) .setTrustManager(X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore2")) + .setTrustStore(secondCA.loadKeyStore()) .setCrlStreams(crlStreams) .setPreferCrls(true) .setNoFallback(true) @@ -635,12 +615,14 @@ public void testTwoWayClientAcceptedWithSingleCRL() throws Throwable { // CRL contains "ladybug" certificate but client sends "green june" certificate crlStreams.add(new FileInputStream("target/test-classes/ca/crl/ladybug-revoked.pem")); + DefinedCAIdentity secondCA = caGenerationTool.getDefinedCAIdentity(Identity.SECOND_CA); + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(firefly.createKeyManager()) .setTrustManager(X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore2")) + .setTrustStore(secondCA.loadKeyStore()) .setCrlStreams(crlStreams) .setPreferCrls(true) .setNoFallback(true) @@ -666,11 +648,13 @@ public void testTwoWayClientRejectedWithMultipleCRL() throws Throwable { crlStreams.add(new FileInputStream("target/test-classes/ca/crl/ladybug-revoked.pem")); crlStreams.add(new FileInputStream("target/test-classes/ca/crl/firefly-revoked.pem")); + DefinedCAIdentity secondCA = caGenerationTool.getDefinedCAIdentity(Identity.SECOND_CA); + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setKeyManager(firefly.createKeyManager()) .setTrustManager(X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore2")) + .setTrustStore(secondCA.loadKeyStore()) .setCrlStreams(crlStreams) .setPreferCrls(true) .setNoFallback(true) @@ -694,12 +678,14 @@ public void testTwoWayClientAcceptedWithMultipleCRL() throws Throwable { crlStreams.add(new FileInputStream("target/test-classes/ca/crl/ladybug-revoked.pem")); crlStreams.add(new FileInputStream("target/test-classes/ca/crl/firefly-revoked.pem")); + DefinedCAIdentity secondCA = caGenerationTool.getDefinedCAIdentity(Identity.SECOND_CA); + DefinedIdentity firefly = caGenerationTool.getDefinedIdentity(Identity.FIREFLY); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/firefly.keystore")) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(firefly.createKeyManager()) .setTrustManager(X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore2")) + .setTrustStore(secondCA.loadKeyStore()) .setCrlStreams(crlStreams) .setPreferCrls(true) .setNoFallback(true) @@ -714,12 +700,14 @@ public void testTwoWayClientAcceptedWithMultipleCRL() throws Throwable { @Test public void testOcspGood() throws Throwable { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(scarab.createKeyManager()) .setTrustManager(X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore")) + .setTrustStore(ca.loadKeyStore()) .setOcspResponderCert(ocspResponderCertificate) .build()) .setNeedClientAuth(true) @@ -750,12 +738,14 @@ public void testOcspMaxCertPathOkay() throws Throwable { } private void ocspMaxCertPathCommon(int maxCertPath, boolean expectValid) throws Throwable { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(scarab.createKeyManager()) .setTrustManager(X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore")) + .setTrustStore(ca.loadKeyStore()) .setOcspResponderCert(ocspResponderCertificate) .setMaxCertPath(maxCertPath) .build()) @@ -768,17 +758,18 @@ private void ocspMaxCertPathCommon(int maxCertPath, boolean expectValid) throws @Test public void testClientSideOcsp() throws Throwable { SSLContext serverContextGood = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/ocsp-checked-good.keystore")) + .setKeyManager(goodIdentity.createKeyManager()) .build().create(); SSLContext serverContextRevoked = new SSLContextBuilder() - .setKeyManager(getKeyManager("/jks/ocsp-checked-revoked.keystore")) + .setKeyManager(revokedIdentity.createKeyManager()) .build().create(); + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); SSLContext clientContext = new SSLContextBuilder() .setTrustManager(X509RevocationTrustManager.builder() .setTrustManagerFactory(getTrustManagerFactory()) - .setTrustStore(createKeyStore("/jks/ca.truststore")) + .setTrustStore(ca.loadKeyStore()) .setOcspResponderCert(ocspResponderCertificate) .build()) .setClientMode(true) @@ -796,10 +787,12 @@ public void testClientSideOcsp() throws Throwable { @Test public void testWantClientAuthWithCorrectCertificate() throws Throwable { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setWantClientAuth(true) .build().create(); @@ -809,10 +802,12 @@ public void testWantClientAuthWithCorrectCertificate() throws Throwable { @Test public void testWantClientAuthWithIncorrectCertificate() throws Throwable { + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); SSLContext serverContext = new SSLContextBuilder() - .setSecurityDomain(getKeyStoreBackedSecurityDomain("/jks/beetles.keystore")) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setSecurityDomain(getKeyStoreBackedSecurityDomain(caGenerationTool.getBeetlesKeyStore())) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setWantClientAuth(true) .build().create(); diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java index 2b2addb635e..88ca0cd3e11 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java @@ -23,12 +23,9 @@ import java.io.Closeable; import java.io.IOException; -import java.io.InputStream; import java.net.InetAddress; import java.net.URI; import java.security.AccessController; -import java.security.KeyStore; -import java.security.KeyStoreException; import java.security.PrivilegedAction; import java.security.Security; import java.util.Locale; @@ -36,17 +33,11 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509ExtendedKeyManager; -import javax.net.ssl.X509TrustManager; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -61,6 +52,8 @@ import org.wildfly.security.permission.PermissionVerifier; import org.wildfly.security.ssl.test.util.CAGenerationTool; import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; +import org.wildfly.security.ssl.test.util.DefinedCAIdentity; +import org.wildfly.security.ssl.test.util.DefinedIdentity; import org.wildfly.security.x500.principal.X500AttributePrincipalDecoder; /** @@ -70,7 +63,6 @@ */ public class TLS13AuthenticationTest { - private static final char[] PASSWORD = "Elytron".toCharArray(); private static final String CA_JKS_LOCATION = "./target/test-classes/jks"; private static CAGenerationTool caGenerationTool = null; @@ -84,7 +76,7 @@ public static void setUp() throws Exception{ .setRequestIdentities(Identity.LADYBIRD, Identity.SCARAB) .build(); - SecurityRealm securityRealm = new KeyStoreBackedSecurityRealm(loadKeyStore("/jks/beetles.keystore")); + SecurityRealm securityRealm = new KeyStoreBackedSecurityRealm(caGenerationTool.getBeetlesKeyStore()); securityDomain = SecurityDomain.builder() .addRealm("KeystoreRealm", securityRealm) .build() @@ -105,11 +97,14 @@ public static void cleanUp() throws IOException { public void testTwoWayTLS13() throws Exception { final String CIPHER_SUITE = "TLS_AES_128_GCM_SHA256"; + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); + SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) .setCipherSuiteSelector(CipherSuiteSelector.fromNamesString(CIPHER_SUITE)) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); @@ -124,11 +119,14 @@ public void testDifferentPreferredTLS13Suites() throws Exception { final String PREFERRED_CIPHER_SUITE = "TLS_AES_256_GCM_SHA384"; final String SERVER_CIPHER_SUITE = String.format("%s:%s", PREFERRED_CIPHER_SUITE, REQUIRED_CIPHER_SUITE); + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); + SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) .setCipherSuiteSelector(CipherSuiteSelector.fromNamesString(SERVER_CIPHER_SUITE)) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); @@ -142,14 +140,17 @@ public void testClientTLS12Only() throws Exception { final String TLS13_CIPHER_SUITE = "TLS_AES_128_GCM_SHA256"; final String TLS12_CIPHER_SUITE = "TLS_RSA_WITH_AES_128_CBC_SHA256"; // TLS v1.2 + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); + SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) .setCipherSuiteSelector(CipherSuiteSelector.aggregate( CipherSuiteSelector.fromNamesString(TLS13_CIPHER_SUITE), CipherSuiteSelector.fromString(TLS12_CIPHER_SUITE) )) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); @@ -162,11 +163,14 @@ public void testClientTLS12Only() throws Exception { public void testServerTLS12Only() throws Exception { final String SERVER_CIPHER_SUITE = "TLS_RSA_WITH_AES_128_CBC_SHA256"; // TLS v1.2 + DefinedCAIdentity ca = caGenerationTool.getDefinedCAIdentity(Identity.CA); + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); + SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) .setCipherSuiteSelector(CipherSuiteSelector.fromString(SERVER_CIPHER_SUITE)) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) - .setTrustManager(getCATrustManager()) + .setKeyManager(scarab.createKeyManager()) + .setTrustManager(ca.createTrustManager()) .setNeedClientAuth(true) .build().create(); @@ -179,9 +183,11 @@ public void testServerTLS12Only() throws Exception { public void testOneWayTLS13() throws Exception { final String CIPHER_SUITE = "TLS_AES_128_GCM_SHA256"; + DefinedIdentity scarab = caGenerationTool.getDefinedIdentity(Identity.SCARAB); + SSLContext serverContext = new SSLContextBuilder() .setCipherSuiteSelector(CipherSuiteSelector.fromNamesString(CIPHER_SUITE)) - .setKeyManager(getKeyManager("/jks/scarab.keystore")) + .setKeyManager(scarab.createKeyManager()) .build().create(); SecurityIdentity identity = performConnectionTest(serverContext, "protocol://test-one-way-tls13.org", "wildfly-ssl-test-config-v1_5.xml", CIPHER_SUITE, true); @@ -241,53 +247,6 @@ private SecurityIdentity performConnectionTest(SSLContext serverContext, String } } - /** - * Get the key manager backed by the specified key store. - * - * @param keystorePath the path to the keystore with X509 private key - * @return the initialised key manager. - */ - private static X509ExtendedKeyManager getKeyManager(final String keystorePath) throws Exception { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); - keyManagerFactory.init(loadKeyStore(keystorePath), PASSWORD); - - for (KeyManager current : keyManagerFactory.getKeyManagers()) { - if (current instanceof X509ExtendedKeyManager) { - return (X509ExtendedKeyManager) current; - } - } - - throw new IllegalStateException("Unable to obtain X509ExtendedKeyManager."); - } - - /** - * Get the trust manager that trusts all certificates signed by the certificate authority. - * - * @return the trust manager that trusts all certificates signed by the certificate authority. - * @throws KeyStoreException - */ - private static X509TrustManager getCATrustManager() throws Exception { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); - trustManagerFactory.init(loadKeyStore("/jks/ca.truststore")); - - for (TrustManager current : trustManagerFactory.getTrustManagers()) { - if (current instanceof X509TrustManager) { - return (X509TrustManager) current; - } - } - - throw new IllegalStateException("Unable to obtain X509TrustManager."); - } - - private static KeyStore loadKeyStore(final String path) throws Exception { - KeyStore keyStore = KeyStore.getInstance("jks"); - try (InputStream caTrustStoreFile = SSLAuthenticationTest.class.getResourceAsStream(path)) { - keyStore.load(caTrustStoreFile, PASSWORD); - } - - return keyStore; - } - private void safeClose(Closeable closeable) { try { closeable.close(); diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java index 86526400a81..4481352b8f8 100644 --- a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java @@ -55,7 +55,8 @@ import org.wildfly.security.x500.cert.X509CertificateExtension; /** - * A tool for generating a complete set of certificates backed by a generated certificate authority. + * A tool for generating a complete set of certificates backed by a generated + * certificate authority. * * @author Darran Lofthouse */ @@ -67,10 +68,11 @@ public class CAGenerationTool implements Closeable { private static final String KEY_ALGORITHM = "RSA"; private static final String KEYSTORE_TYPE = "JKS"; // TODO Switch to PKCS#12 private static final int OCSP_PORT = 4854; - private static final char[] PASSWORD = "Elytron".toCharArray(); + static final char[] PASSWORD = "Elytron".toCharArray(); private static final Set BEETLES = Collections - .unmodifiableSet(new HashSet<>(Arrays.asList(Identity.LADYBIRD, Identity.SCARAB, Identity.DUNG, Identity.FIREFLY))); + .unmodifiableSet( + new HashSet<>(Arrays.asList(Identity.LADYBIRD, Identity.SCARAB, Identity.DUNG, Identity.FIREFLY))); private static final Predicate INCLUDE_IN_BEETLES = BEETLES::contains; private final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); @@ -79,6 +81,8 @@ public class CAGenerationTool implements Closeable { private final File workingDir; + private volatile boolean closed = false; + protected CAGenerationTool(Builder builder) throws Exception { // Ensure we have the directory created to hold the resulting KeyStores workingDir = new File(builder.baseDir); @@ -108,13 +112,54 @@ protected CAGenerationTool(Builder builder) throws Exception { } } + public DefinedIdentity getDefinedIdentity(final Identity identity) { + if (identity.isCertificateAuthority()) { + return getDefinedCAIdentity(identity); + } + + if (!certificateMap.containsKey(identity)) { + throw new IllegalStateException(String.format("Identity %s has not been created.", identity.toString())); + } + + X509Certificate certificate = certificateMap.get(identity); + + return new DefinedIdentity(this, identity, certificate); + } + + public DefinedCAIdentity getDefinedCAIdentity(final Identity identity) { + if (!identity.isCertificateAuthority()) { + throw new IllegalStateException( + String.format("Identity %s is not a CertificateAuthority", identity.toString())); + } + + if (!caMap.containsKey(identity)) { + throw new IllegalStateException(String.format("Identity %s has not been created.", identity.toString())); + } + + CAState caState = caMap.get(identity); + return new DefinedCAIdentity(this, identity, caState.issuerCertificate, caState.signingKey); + } + + public KeyStore getBeetlesKeyStore() { + return loadKeyStore(new File(workingDir, BEETLES_STORE)); + } + + /** + * @deprecated Use {@link CommonIdentity#getCertificate()} instead. + */ + @Deprecated() public X509Certificate getCertificate(final Identity identity) { return certificateMap.get(identity); } + /** + * @deprecated Use {@link DefinedCAIdentity#getPrivateKey()} instead. + */ + @Deprecated() public PrivateKey getPrivateKey(final Identity identity) { if (!identity.isCertificateAuthority()) { - throw new IllegalStateException(String.format("Identity %s if not a CertificateAuthority", identity.toString())); + throw new IllegalStateException( + String.format("Identity %s if not a CertificateAuthority", identity.toString())); } return caMap.computeIfAbsent(identity, this::createCA).signingKey; @@ -126,7 +171,8 @@ private CAState createCA(final Identity identity) { Identity signedBy = identity.getSignedBy(); if (signedBy == null) { // As a root CA it will require a self signed certificate. - SelfSignedX509CertificateAndSigningKey issuerSelfSignedX509CertificateAndSigningKey = SelfSignedX509CertificateAndSigningKey.builder() + SelfSignedX509CertificateAndSigningKey issuerSelfSignedX509CertificateAndSigningKey = SelfSignedX509CertificateAndSigningKey + .builder() .setDn(identity.getPrincipal()) .setKeyAlgorithmName(KEY_ALGORITHM) .setSignatureAlgorithmName(SIGNATURE_ALGORTHM) @@ -147,8 +193,8 @@ private CAState createCA(final Identity identity) { .setSerialNumber(BigInteger.valueOf(signerState.serialNumber++)) .addExtension(new BasicConstraintsExtension(false, true, -1)) .addExtension(new AuthorityInformationAccessExtension(Collections.singletonList( - new AccessDescription(OID_AD_OCSP, new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp")) - ))) + new AccessDescription(OID_AD_OCSP, + new GeneralName.URIName("http://localhost:" + OCSP_PORT + "/ocsp"))))) .build(); caState.issuerCertificate = intermediateIssuerCertificate; @@ -175,24 +221,72 @@ private CAState createCA(final Identity identity) { return caState; } - public X509Certificate createIdentity(final String alias, final X500Principal principal, final String keyStoreName, - final Identity ca, final X509CertificateExtension... extensions) { - KeyPair keyPair = keyPairGenerator.generateKeyPair(); + private X509Certificate createCustomCertificate(final Identity ca, final X500Principal principal, + final KeyPair keyPair, final X509CertificateExtension... extensions) throws CertificateException{ + CAState caState = caMap.computeIfAbsent(ca, this::createCA); + X509CertificateBuilder certificateBuilder = new X509CertificateBuilder() + .setIssuerDn(ca.getPrincipal()) + .setSubjectDn(principal) + .setSignatureAlgorithmName(SIGNATURE_ALGORTHM) + .setSigningKey(caState.signingKey) + .setPublicKey(keyPair.getPublic()) + .setSerialNumber(BigInteger.valueOf(caState.serialNumber++)) + .addExtension(new BasicConstraintsExtension(false, false, -1)); + for (X509CertificateExtension currentExtension : extensions) { + certificateBuilder.addExtension(currentExtension); + } + + return certificateBuilder.build(); + } + + CustomIdentity createCustomIdentity(final String alias, final X500Principal principal, final String keyStoreName, + final Identity ca, final X509CertificateExtension... extensions) { try { - X509CertificateBuilder certificateBuilder = new X509CertificateBuilder() - .setIssuerDn(ca.getPrincipal()) - .setSubjectDn(principal) - .setSignatureAlgorithmName(SIGNATURE_ALGORTHM) - .setSigningKey(caState.signingKey) - .setPublicKey(keyPair.getPublic()) - .setSerialNumber(BigInteger.valueOf(caState.serialNumber++)) - .addExtension(new BasicConstraintsExtension(false, false, -1)); - for (X509CertificateExtension currentExtension : extensions) { - certificateBuilder.addExtension(currentExtension); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + X509Certificate builtCertificate = createCustomCertificate(ca, principal, keyPair, extensions); + + File keyStoreFile = new File(workingDir, keyStoreName); + KeyStore keyStore = createEmptyKeyStore(); + + List certificates = new ArrayList<>(); + certificates.add(builtCertificate); + + Identity caIdentity = ca; + CAState caState; + + do { + caState = caMap.get(caIdentity); // We just created a signed cert above, the complete chain must be + // present. + certificates.add(caState.issuerCertificate); + caIdentity = caIdentity.getSignedBy(); + } while (caIdentity != null); + + keyStore.setKeyEntry(alias, keyPair.getPrivate(), PASSWORD, + certificates.toArray(new X509Certificate[certificates.size()])); + try (OutputStream out = new FileOutputStream(keyStoreFile)) { + keyStore.store(out, PASSWORD); } - X509Certificate builtCertificate = certificateBuilder.build(); + + return new CustomIdentity(this, builtCertificate, keyStoreFile); + + } catch (IOException | KeyStoreException | CertificateException | NoSuchAlgorithmException e) { + throw new RuntimeException("Umnable to create identity", e); + } + } + + /** + * @deprecated Use + * {@link #createIdentity(String, X500Principal, String, X509CertificateExtension...)} + * instead. + */ + @Deprecated + public X509Certificate createIdentity(final String alias, final X500Principal principal, final String keyStoreName, + final Identity ca, final X509CertificateExtension... extensions) { + try { + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + X509Certificate builtCertificate = createCustomCertificate(ca, principal, keyPair, extensions); File keyStoreFile = new File(workingDir, keyStoreName); KeyStore keyStore = createEmptyKeyStore(); @@ -201,9 +295,14 @@ public X509Certificate createIdentity(final String alias, final X500Principal pr certificates.add(builtCertificate); Identity caIdentity = ca; + CAState caState; + do { - caState = caMap.get(caIdentity); // We just created a signed cert above, the complete chain must be present. - keyStore.setCertificateEntry(caIdentity.toString(), caState.issuerCertificate); // This could be removed as the cert chain is added to the Entry. + caState = caMap.get(caIdentity); // We just created a signed cert above, the complete chain must be + // present. + keyStore.setCertificateEntry(caIdentity.toString(), caState.issuerCertificate); // This could be removed + // as the cert chain is + // added to the Entry. certificates.add(caState.issuerCertificate); caIdentity = caIdentity.getSignedBy(); } while (caIdentity != null); @@ -220,7 +319,8 @@ public X509Certificate createIdentity(final String alias, final X500Principal pr } } - public X509Certificate createSelfSignedIdentity(final String alias, final X500Principal principal, final String keyStoreName) { + private X509Certificate createSelfSignedIdentity(final String alias, final X500Principal principal, + final String keyStoreName) { SelfSignedX509CertificateAndSigningKey selfSignedIdentity = SelfSignedX509CertificateAndSigningKey.builder() .setDn(principal) .setKeyAlgorithmName(KEY_ALGORITHM) @@ -256,7 +356,7 @@ private X509Certificate createIdentity(final Identity identity) { private static KeyStore createEmptyKeyStore() { try { KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE); - ks.load(null,null); + ks.load(null, null); return ks; } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { @@ -264,7 +364,11 @@ private static KeyStore createEmptyKeyStore() { } } - private static KeyStore loadKeyStore(final File location) { + KeyStore loadKeyStore(final Identity identity) { + return loadKeyStore(new File(workingDir, identity.getKeyStoreName())); + } + + static KeyStore loadKeyStore(final File location) { try (InputStream caTrustStoreFile = new FileInputStream(location)) { KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); keyStore.load(caTrustStoreFile, PASSWORD); @@ -275,8 +379,15 @@ private static KeyStore loadKeyStore(final File location) { } } + void assertNotClosed() { + if (closed) { + throw new IllegalStateException("The CAGenerationTool is closed."); + } + } + @Override public void close() throws IOException { + closed = true; workingDir.delete(); } @@ -306,7 +417,8 @@ public enum Identity { CA, true, null), ROVE("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=Rove", INTERMEDIATE, false, "rove.keystore"), - SECOND_CA("CN=Wildfly CA, ST=Wildfly, C=CA, EMAILADDRESS=admin@wildfly.org O=Another Root Certificate Authority", + SECOND_CA( + "CN=Wildfly CA, ST=Wildfly, C=CA, EMAILADDRESS=admin@wildfly.org O=Another Root Certificate Authority", null, true, "ca.truststore2"), LADYBUG("OU=Wildfly, O=Wildfly, C=CA, ST=Wildfly, CN=Ladybug", SECOND_CA, false, "ladybug.keystore"), @@ -318,8 +430,9 @@ public enum Identity { private final boolean ca; private final String keyStoreName; - private Identity(final String distinguishedName, final Identity signedBy, final boolean ca, final String keyStoreName) { - this.principal = new X500Principal(distinguishedName); + private Identity(final String distinguishedName, final Identity signedBy, final boolean ca, + final String keyStoreName) { + this.principal = new X500Principal(distinguishedName); this.signedBy = signedBy; this.ca = ca; this.keyStoreName = keyStoreName; diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CommonIdentity.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CommonIdentity.java new file mode 100644 index 00000000000..2d8f3664015 --- /dev/null +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CommonIdentity.java @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.security.ssl.test.util; + +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.X509ExtendedKeyManager; + +public abstract class CommonIdentity { + + protected final CAGenerationTool caGenerationTool; + private final X509Certificate certificate; + + CommonIdentity(CAGenerationTool caGenerationTool, X509Certificate certificate) { + this.caGenerationTool = caGenerationTool; + this.certificate = certificate; + } + + public X509Certificate getCertificate() { + caGenerationTool.assertNotClosed(); + + return certificate; + } + + public abstract KeyStore loadKeyStore(); + + public X509ExtendedKeyManager createKeyManager() { + caGenerationTool.assertNotClosed(); + + try { + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); + keyManagerFactory.init(loadKeyStore(), CAGenerationTool.PASSWORD); + + for (KeyManager current : keyManagerFactory.getKeyManagers()) { + if (current instanceof X509ExtendedKeyManager) { + return (X509ExtendedKeyManager) current; + } + } + } catch (NoSuchAlgorithmException | KeyStoreException | UnrecoverableKeyException e) { + throw new IllegalStateException("Unable to obtain X509ExtendedKeyManager.", e); + } + + throw new IllegalStateException("Unable to obtain X509ExtendedKeyManager."); + } + +} diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CustomIdentity.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CustomIdentity.java new file mode 100644 index 00000000000..a1ce69a2b5e --- /dev/null +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CustomIdentity.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.security.ssl.test.util; + +import java.io.File; +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +public class CustomIdentity extends CommonIdentity { + + private final File keyStoreFile; + + CustomIdentity(CAGenerationTool caGenerationTool, X509Certificate certificate, File keyStoreFile) { + super(caGenerationTool, certificate); + this.keyStoreFile = keyStoreFile; + } + + @Override + public KeyStore loadKeyStore() { + return CAGenerationTool.loadKeyStore(keyStoreFile); + } + +} diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedCAIdentity.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedCAIdentity.java new file mode 100644 index 00000000000..4b01b4af6c8 --- /dev/null +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedCAIdentity.java @@ -0,0 +1,74 @@ +/* + * Copyright 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.security.ssl.test.util; + +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; +import javax.security.auth.x500.X500Principal; + +import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; +import org.wildfly.security.x500.cert.X509CertificateExtension; + +public class DefinedCAIdentity extends DefinedIdentity { + + private final PrivateKey privateKey; + + DefinedCAIdentity(CAGenerationTool caGenerationTool, Identity identity, + X509Certificate certificate, PrivateKey privateKey) { + super(caGenerationTool, identity, certificate); + this.privateKey = privateKey; + } + + public CustomIdentity createIdentity(final String alias, final X500Principal principal, + final String keyStoreName, final X509CertificateExtension... extensions) { + caGenerationTool.assertNotClosed(); + + return caGenerationTool.createCustomIdentity(alias, principal, keyStoreName, identity, extensions); + } + + + public PrivateKey getPrivateKey() { + caGenerationTool.assertNotClosed(); + + return privateKey; + } + + public X509TrustManager createTrustManager() { + caGenerationTool.assertNotClosed(); + + try { + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); + trustManagerFactory.init(caGenerationTool.loadKeyStore(identity)); + + for (TrustManager current : trustManagerFactory.getTrustManagers()) { + if (current instanceof X509TrustManager) { + return (X509TrustManager) current; + } + } + } catch (NoSuchAlgorithmException | KeyStoreException e) { + throw new IllegalStateException("Unable to obtain X509TrustManager.", e); + } + + throw new IllegalStateException("Unable to obtain X509TrustManager."); + } +} diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedIdentity.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedIdentity.java new file mode 100644 index 00000000000..28595b8e112 --- /dev/null +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedIdentity.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.security.ssl.test.util; + +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; + +public class DefinedIdentity extends CommonIdentity { + + protected final Identity identity; + + DefinedIdentity(CAGenerationTool caGenerationTool, + Identity identity, + X509Certificate certificate) { + super(caGenerationTool, certificate); + this.identity = identity; + } + + public KeyStore loadKeyStore() { + caGenerationTool.assertNotClosed(); + + return caGenerationTool.loadKeyStore(identity); + } + +}