11864f965419c5b14ac9317c576c8a0f7169c067enmittler/* 21864f965419c5b14ac9317c576c8a0f7169c067enmittler * Copyright (C) 2010 The Android Open Source Project 31864f965419c5b14ac9317c576c8a0f7169c067enmittler * 41864f965419c5b14ac9317c576c8a0f7169c067enmittler * Licensed under the Apache License, Version 2.0 (the "License"); 51864f965419c5b14ac9317c576c8a0f7169c067enmittler * you may not use this file except in compliance with the License. 61864f965419c5b14ac9317c576c8a0f7169c067enmittler * You may obtain a copy of the License at 71864f965419c5b14ac9317c576c8a0f7169c067enmittler * 81864f965419c5b14ac9317c576c8a0f7169c067enmittler * http://www.apache.org/licenses/LICENSE-2.0 91864f965419c5b14ac9317c576c8a0f7169c067enmittler * 101864f965419c5b14ac9317c576c8a0f7169c067enmittler * Unless required by applicable law or agreed to in writing, software 111864f965419c5b14ac9317c576c8a0f7169c067enmittler * distributed under the License is distributed on an "AS IS" BASIS, 121864f965419c5b14ac9317c576c8a0f7169c067enmittler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131864f965419c5b14ac9317c576c8a0f7169c067enmittler * See the License for the specific language governing permissions and 141864f965419c5b14ac9317c576c8a0f7169c067enmittler * limitations under the License. 151864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 161864f965419c5b14ac9317c576c8a0f7169c067enmittler 171864f965419c5b14ac9317c576c8a0f7169c067enmittlerpackage libcore.java.security; 181864f965419c5b14ac9317c576c8a0f7169c067enmittler 19f65a3de1e35d7f734ae4bb2ca33ecfd776a92c4dKenny Rootimport static org.junit.Assert.assertEquals; 20f65a3de1e35d7f734ae4bb2ca33ecfd776a92c4dKenny Root 211864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.io.ByteArrayInputStream; 221864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.io.IOException; 231864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.io.PrintStream; 241864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.math.BigInteger; 251864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.KeyPair; 261864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.KeyPairGenerator; 271864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.KeyStore; 281864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.KeyStore.PasswordProtection; 291864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.KeyStore.PrivateKeyEntry; 301864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.KeyStore.TrustedCertificateEntry; 311864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.KeyStoreException; 321864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.NoSuchAlgorithmException; 331864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.Principal; 341864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.PrivateKey; 351864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.PublicKey; 361864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.SecureRandom; 371864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.Security; 381864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.UnrecoverableEntryException; 391864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.UnrecoverableKeyException; 401864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.cert.Certificate; 411864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.cert.CertificateException; 421864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.cert.CertificateFactory; 431864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.cert.X509Certificate; 441864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.security.spec.AlgorithmParameterSpec; 451864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.util.ArrayList; 461864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.util.Collections; 471864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.util.Date; 481864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport java.util.List; 491864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport javax.crypto.spec.DHParameterSpec; 501864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport javax.net.ssl.KeyManager; 511864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport javax.net.ssl.KeyManagerFactory; 521864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport javax.net.ssl.TrustManager; 531864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport javax.net.ssl.TrustManagerFactory; 541864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport javax.security.auth.x500.X500Principal; 551864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport libcore.javax.net.ssl.TestKeyManager; 561864f965419c5b14ac9317c576c8a0f7169c067enmittlerimport libcore.javax.net.ssl.TestTrustManager; 57027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.DEROctetString; 58027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x500.X500Name; 59027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.BasicConstraints; 60027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.CRLReason; 61027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.ExtendedKeyUsage; 62027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.Extension; 63027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.GeneralName; 64027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.GeneralNames; 65027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.GeneralSubtree; 66027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.KeyPurposeId; 67027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.KeyUsage; 68027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.NameConstraints; 69027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 70027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.X509CertificateHolder; 71027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.X509v3CertificateBuilder; 72027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; 73027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; 74027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.ocsp.BasicOCSPResp; 75027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; 76027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.ocsp.CertificateID; 77027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.ocsp.CertificateStatus; 78027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.ocsp.OCSPResp; 79027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.ocsp.OCSPRespBuilder; 80027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.cert.ocsp.RevokedStatus; 81027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.jce.provider.BouncyCastleProvider; 82027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.operator.DigestCalculatorProvider; 83027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.operator.bc.BcDigestCalculatorProvider; 84027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Rootimport org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; 851864f965419c5b14ac9317c576c8a0f7169c067enmittler 861864f965419c5b14ac9317c576c8a0f7169c067enmittler/** 871864f965419c5b14ac9317c576c8a0f7169c067enmittler * TestKeyStore is a convenience class for other tests that 881864f965419c5b14ac9317c576c8a0f7169c067enmittler * want a canned KeyStore with a variety of key pairs. 891864f965419c5b14ac9317c576c8a0f7169c067enmittler * 901864f965419c5b14ac9317c576c8a0f7169c067enmittler * Creating a key store is relatively slow, so a singleton instance is 911864f965419c5b14ac9317c576c8a0f7169c067enmittler * accessible via TestKeyStore.get(). 921864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 93f65a3de1e35d7f734ae4bb2ca33ecfd776a92c4dKenny Rootpublic final class TestKeyStore { 941864f965419c5b14ac9317c576c8a0f7169c067enmittler /** Size of DSA keys to generate for testing. */ 951864f965419c5b14ac9317c576c8a0f7169c067enmittler private static final int DSA_KEY_SIZE_BITS = 1024; 961864f965419c5b14ac9317c576c8a0f7169c067enmittler 971864f965419c5b14ac9317c576c8a0f7169c067enmittler /** Size of EC keys to generate for testing. */ 981864f965419c5b14ac9317c576c8a0f7169c067enmittler private static final int EC_KEY_SIZE_BITS = 256; 991864f965419c5b14ac9317c576c8a0f7169c067enmittler 1001864f965419c5b14ac9317c576c8a0f7169c067enmittler /** Size of RSA keys to generate for testing. */ 1011864f965419c5b14ac9317c576c8a0f7169c067enmittler private static final int RSA_KEY_SIZE_BITS = 1024; 1021864f965419c5b14ac9317c576c8a0f7169c067enmittler 1031864f965419c5b14ac9317c576c8a0f7169c067enmittler // Generated with: openssl dhparam -C 1024 104b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root private static final BigInteger DH_PARAMS_P = new BigInteger(1, 105b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root new byte[] { 106b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0xA2, (byte) 0x31, (byte) 0xB4, (byte) 0xB3, (byte) 0x6D, (byte) 0x9B, 107b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x7E, (byte) 0xF4, (byte) 0xE7, (byte) 0x21, (byte) 0x51, (byte) 0x40, 108b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0xEB, (byte) 0xC6, (byte) 0xB6, (byte) 0xD6, (byte) 0x54, (byte) 0x56, 109b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x72, (byte) 0xBE, (byte) 0x43, (byte) 0x18, (byte) 0x30, (byte) 0x5C, 110b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x15, (byte) 0x5A, (byte) 0xF9, (byte) 0x19, (byte) 0x62, (byte) 0xAD, 111b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0xF4, (byte) 0x29, (byte) 0xCB, (byte) 0xC6, (byte) 0xF6, (byte) 0x64, 112b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x0B, (byte) 0x9D, (byte) 0x23, (byte) 0x80, (byte) 0xF9, (byte) 0x5B, 113b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x1C, (byte) 0x1C, (byte) 0x6A, (byte) 0xB4, (byte) 0xEA, (byte) 0xB9, 114b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x80, (byte) 0x98, (byte) 0x8B, (byte) 0xAF, (byte) 0x15, (byte) 0xA8, 115b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x5C, (byte) 0xC4, (byte) 0xB0, (byte) 0x41, (byte) 0x29, (byte) 0x66, 116b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x9F, (byte) 0x9F, (byte) 0x1F, (byte) 0x88, (byte) 0x50, (byte) 0x97, 117b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x38, (byte) 0x0B, (byte) 0x01, (byte) 0x16, (byte) 0xD6, (byte) 0x84, 118b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x1D, (byte) 0x48, (byte) 0x6F, (byte) 0x7C, (byte) 0x06, (byte) 0x8C, 119b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x6E, (byte) 0x68, (byte) 0xCD, (byte) 0x38, (byte) 0xE6, (byte) 0x22, 120b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x30, (byte) 0x61, (byte) 0x37, (byte) 0x02, (byte) 0x3D, (byte) 0x47, 121b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x62, (byte) 0xCE, (byte) 0xB9, (byte) 0x1A, (byte) 0x69, (byte) 0x9D, 122b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0xA1, (byte) 0x9F, (byte) 0x10, (byte) 0xA1, (byte) 0xAA, (byte) 0x70, 123b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0xF7, (byte) 0x27, (byte) 0x9C, (byte) 0xD4, (byte) 0xA5, (byte) 0x15, 124b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0xE2, (byte) 0x15, (byte) 0x0C, (byte) 0x20, (byte) 0x90, (byte) 0x08, 125b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0xB6, (byte) 0xF5, (byte) 0xDF, (byte) 0x1C, (byte) 0xCB, (byte) 0x82, 126b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x6D, (byte) 0xC0, (byte) 0xE1, (byte) 0xBD, (byte) 0xCC, (byte) 0x4A, 127b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root (byte) 0x76, (byte) 0xE3, 128b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root }); 1291864f965419c5b14ac9317c576c8a0f7169c067enmittler 1301864f965419c5b14ac9317c576c8a0f7169c067enmittler // generator of 2 1311864f965419c5b14ac9317c576c8a0f7169c067enmittler private static final BigInteger DH_PARAMS_G = BigInteger.valueOf(2); 1321864f965419c5b14ac9317c576c8a0f7169c067enmittler 1331864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore ROOT_CA; 1341864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore INTERMEDIATE_CA; 1351864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore INTERMEDIATE_CA_2; 1361864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore INTERMEDIATE_CA_EC; 1371864f965419c5b14ac9317c576c8a0f7169c067enmittler 1381864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore SERVER; 1391864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore CLIENT; 1401864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore CLIENT_CERTIFICATE; 1411864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore CLIENT_EC_RSA_CERTIFICATE; 1421864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore CLIENT_EC_EC_CERTIFICATE; 1431864f965419c5b14ac9317c576c8a0f7169c067enmittler 1441864f965419c5b14ac9317c576c8a0f7169c067enmittler private static TestKeyStore CLIENT_2; 1451864f965419c5b14ac9317c576c8a0f7169c067enmittler 1461864f965419c5b14ac9317c576c8a0f7169c067enmittler static { 1471864f965419c5b14ac9317c576c8a0f7169c067enmittler if (StandardNames.IS_RI) { 1481864f965419c5b14ac9317c576c8a0f7169c067enmittler // Needed to create BKS keystore but add at end so most 1491864f965419c5b14ac9317c576c8a0f7169c067enmittler // algorithm come from the default providers 1501864f965419c5b14ac9317c576c8a0f7169c067enmittler Security.insertProviderAt( 1511864f965419c5b14ac9317c576c8a0f7169c067enmittler new BouncyCastleProvider(), Security.getProviders().length + 1); 1521864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (!BouncyCastleProvider.class.getName().startsWith("com.android")) { 1531864f965419c5b14ac9317c576c8a0f7169c067enmittler // If we run outside of the Android system, we need to make sure 1541864f965419c5b14ac9317c576c8a0f7169c067enmittler // that the BouncyCastleProvider's static field keyInfoConverters 1551864f965419c5b14ac9317c576c8a0f7169c067enmittler // is initialized. This happens in the default constructor only. 1561864f965419c5b14ac9317c576c8a0f7169c067enmittler new BouncyCastleProvider(); 1571864f965419c5b14ac9317c576c8a0f7169c067enmittler } 1581864f965419c5b14ac9317c576c8a0f7169c067enmittler } 1591864f965419c5b14ac9317c576c8a0f7169c067enmittler 1601864f965419c5b14ac9317c576c8a0f7169c067enmittler private static final byte[] LOCAL_HOST_ADDRESS = {127, 0, 0, 1}; 1611864f965419c5b14ac9317c576c8a0f7169c067enmittler private static final String LOCAL_HOST_NAME = "localhost"; 1621864f965419c5b14ac9317c576c8a0f7169c067enmittler 1631864f965419c5b14ac9317c576c8a0f7169c067enmittler public final KeyStore keyStore; 1641864f965419c5b14ac9317c576c8a0f7169c067enmittler public final char[] storePassword; 1651864f965419c5b14ac9317c576c8a0f7169c067enmittler public final char[] keyPassword; 1661864f965419c5b14ac9317c576c8a0f7169c067enmittler public final KeyManager[] keyManagers; 1671864f965419c5b14ac9317c576c8a0f7169c067enmittler public final TrustManager[] trustManagers; 1681864f965419c5b14ac9317c576c8a0f7169c067enmittler public final TestTrustManager trustManager; 1691864f965419c5b14ac9317c576c8a0f7169c067enmittler 1701864f965419c5b14ac9317c576c8a0f7169c067enmittler private TestKeyStore(KeyStore keyStore, char[] storePassword, char[] keyPassword) { 1711864f965419c5b14ac9317c576c8a0f7169c067enmittler this.keyStore = keyStore; 1721864f965419c5b14ac9317c576c8a0f7169c067enmittler this.storePassword = storePassword; 1731864f965419c5b14ac9317c576c8a0f7169c067enmittler this.keyPassword = keyPassword; 1741864f965419c5b14ac9317c576c8a0f7169c067enmittler this.keyManagers = createKeyManagers(keyStore, storePassword); 1751864f965419c5b14ac9317c576c8a0f7169c067enmittler this.trustManagers = createTrustManagers(keyStore); 1761864f965419c5b14ac9317c576c8a0f7169c067enmittler this.trustManager = (TestTrustManager) trustManagers[0]; 1771864f965419c5b14ac9317c576c8a0f7169c067enmittler } 1781864f965419c5b14ac9317c576c8a0f7169c067enmittler 1791864f965419c5b14ac9317c576c8a0f7169c067enmittler public static KeyManager[] createKeyManagers(KeyStore keyStore, char[] storePassword) { 1801864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 1811864f965419c5b14ac9317c576c8a0f7169c067enmittler String kmfa = KeyManagerFactory.getDefaultAlgorithm(); 1821864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfa); 1831864f965419c5b14ac9317c576c8a0f7169c067enmittler kmf.init(keyStore, storePassword); 1841864f965419c5b14ac9317c576c8a0f7169c067enmittler return TestKeyManager.wrap(kmf.getKeyManagers()); 1851864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 1861864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 1871864f965419c5b14ac9317c576c8a0f7169c067enmittler } 1881864f965419c5b14ac9317c576c8a0f7169c067enmittler } 1891864f965419c5b14ac9317c576c8a0f7169c067enmittler 1901864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TrustManager[] createTrustManagers(final KeyStore keyStore) { 1911864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 1921864f965419c5b14ac9317c576c8a0f7169c067enmittler String tmfa = TrustManagerFactory.getDefaultAlgorithm(); 1931864f965419c5b14ac9317c576c8a0f7169c067enmittler TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfa); 1941864f965419c5b14ac9317c576c8a0f7169c067enmittler tmf.init(keyStore); 1951864f965419c5b14ac9317c576c8a0f7169c067enmittler return TestTrustManager.wrap(tmf.getTrustManagers()); 1961864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 1971864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 1981864f965419c5b14ac9317c576c8a0f7169c067enmittler } 1991864f965419c5b14ac9317c576c8a0f7169c067enmittler } 2001864f965419c5b14ac9317c576c8a0f7169c067enmittler 2011864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 2021864f965419c5b14ac9317c576c8a0f7169c067enmittler * Lazily create shared test certificates. 2031864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 2041864f965419c5b14ac9317c576c8a0f7169c067enmittler private static synchronized void initCerts() { 2051864f965419c5b14ac9317c576c8a0f7169c067enmittler if (ROOT_CA != null) { 2061864f965419c5b14ac9317c576c8a0f7169c067enmittler return; 2071864f965419c5b14ac9317c576c8a0f7169c067enmittler } 2081864f965419c5b14ac9317c576c8a0f7169c067enmittler ROOT_CA = new Builder() 2091864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("RootCA") 2101864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("CN=Test Root Certificate Authority") 2111864f965419c5b14ac9317c576c8a0f7169c067enmittler .ca(true) 2121864f965419c5b14ac9317c576c8a0f7169c067enmittler .certificateSerialNumber(BigInteger.valueOf(1)) 2131864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2141864f965419c5b14ac9317c576c8a0f7169c067enmittler INTERMEDIATE_CA_EC = new Builder() 2151864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("IntermediateCA-EC") 2161864f965419c5b14ac9317c576c8a0f7169c067enmittler .keyAlgorithms("EC") 2171864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("CN=Test Intermediate Certificate Authority ECDSA") 2181864f965419c5b14ac9317c576c8a0f7169c067enmittler .ca(true) 2191864f965419c5b14ac9317c576c8a0f7169c067enmittler .signer(ROOT_CA.getPrivateKey("RSA", "RSA")) 2201864f965419c5b14ac9317c576c8a0f7169c067enmittler .rootCa(ROOT_CA.getRootCertificate("RSA")) 2211864f965419c5b14ac9317c576c8a0f7169c067enmittler .certificateSerialNumber(BigInteger.valueOf(2)) 2221864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2231864f965419c5b14ac9317c576c8a0f7169c067enmittler INTERMEDIATE_CA = new Builder() 2241864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("IntermediateCA") 2251864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("CN=Test Intermediate Certificate Authority") 2261864f965419c5b14ac9317c576c8a0f7169c067enmittler .ca(true) 2271864f965419c5b14ac9317c576c8a0f7169c067enmittler .signer(ROOT_CA.getPrivateKey("RSA", "RSA")) 2281864f965419c5b14ac9317c576c8a0f7169c067enmittler .rootCa(ROOT_CA.getRootCertificate("RSA")) 2291864f965419c5b14ac9317c576c8a0f7169c067enmittler .certificateSerialNumber(BigInteger.valueOf(2)) 2301864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2311864f965419c5b14ac9317c576c8a0f7169c067enmittler SERVER = new Builder() 2321864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("server") 2331864f965419c5b14ac9317c576c8a0f7169c067enmittler .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA")) 2341864f965419c5b14ac9317c576c8a0f7169c067enmittler .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA")) 2351864f965419c5b14ac9317c576c8a0f7169c067enmittler .addSubjectAltNameIpAddress(LOCAL_HOST_ADDRESS) 2361864f965419c5b14ac9317c576c8a0f7169c067enmittler .certificateSerialNumber(BigInteger.valueOf(3)) 2371864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2381864f965419c5b14ac9317c576c8a0f7169c067enmittler CLIENT = new TestKeyStore(createClient(INTERMEDIATE_CA.keyStore), null, null); 2391864f965419c5b14ac9317c576c8a0f7169c067enmittler CLIENT_EC_RSA_CERTIFICATE = new Builder() 2401864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("client-ec") 2411864f965419c5b14ac9317c576c8a0f7169c067enmittler .keyAlgorithms("EC") 2421864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("emailAddress=test-ec@user") 2431864f965419c5b14ac9317c576c8a0f7169c067enmittler .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA")) 2441864f965419c5b14ac9317c576c8a0f7169c067enmittler .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA")) 2451864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2461864f965419c5b14ac9317c576c8a0f7169c067enmittler CLIENT_EC_EC_CERTIFICATE = new Builder() 2471864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("client-ec") 2481864f965419c5b14ac9317c576c8a0f7169c067enmittler .keyAlgorithms("EC") 2491864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("emailAddress=test-ec@user") 2501864f965419c5b14ac9317c576c8a0f7169c067enmittler .signer(INTERMEDIATE_CA_EC.getPrivateKey("EC", "RSA")) 2511864f965419c5b14ac9317c576c8a0f7169c067enmittler .rootCa(INTERMEDIATE_CA_EC.getRootCertificate("RSA")) 2521864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2531864f965419c5b14ac9317c576c8a0f7169c067enmittler CLIENT_CERTIFICATE = new Builder() 2541864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("client") 2551864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("emailAddress=test@user") 2561864f965419c5b14ac9317c576c8a0f7169c067enmittler .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA")) 2571864f965419c5b14ac9317c576c8a0f7169c067enmittler .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA")) 2581864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2591864f965419c5b14ac9317c576c8a0f7169c067enmittler TestKeyStore rootCa2 = new Builder() 2601864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("RootCA2") 2611864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("CN=Test Root Certificate Authority 2") 2621864f965419c5b14ac9317c576c8a0f7169c067enmittler .ca(true) 2631864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2641864f965419c5b14ac9317c576c8a0f7169c067enmittler INTERMEDIATE_CA_2 = new Builder() 2651864f965419c5b14ac9317c576c8a0f7169c067enmittler .aliasPrefix("IntermediateCA") 2661864f965419c5b14ac9317c576c8a0f7169c067enmittler .subject("CN=Test Intermediate Certificate Authority") 2671864f965419c5b14ac9317c576c8a0f7169c067enmittler .ca(true) 2681864f965419c5b14ac9317c576c8a0f7169c067enmittler .signer(rootCa2.getPrivateKey("RSA", "RSA")) 2691864f965419c5b14ac9317c576c8a0f7169c067enmittler .rootCa(rootCa2.getRootCertificate("RSA")) 2701864f965419c5b14ac9317c576c8a0f7169c067enmittler .build(); 2711864f965419c5b14ac9317c576c8a0f7169c067enmittler CLIENT_2 = new TestKeyStore(createClient(rootCa2.keyStore), null, null); 2721864f965419c5b14ac9317c576c8a0f7169c067enmittler } 2731864f965419c5b14ac9317c576c8a0f7169c067enmittler 2741864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 2751864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return an root CA that can be used to issue new certificates. 2761864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 2771864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getRootCa() { 2781864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 2791864f965419c5b14ac9317c576c8a0f7169c067enmittler return ROOT_CA; 2801864f965419c5b14ac9317c576c8a0f7169c067enmittler } 2811864f965419c5b14ac9317c576c8a0f7169c067enmittler 2821864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 2831864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return an intermediate CA that can be used to issue new certificates. 2841864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 2851864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getIntermediateCa() { 2861864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 2871864f965419c5b14ac9317c576c8a0f7169c067enmittler return INTERMEDIATE_CA; 2881864f965419c5b14ac9317c576c8a0f7169c067enmittler } 2891864f965419c5b14ac9317c576c8a0f7169c067enmittler 2901864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 2911864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return an intermediate CA that can be used to issue new certificates. 2921864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 2931864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getIntermediateCa2() { 2941864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 2951864f965419c5b14ac9317c576c8a0f7169c067enmittler return INTERMEDIATE_CA_2; 2961864f965419c5b14ac9317c576c8a0f7169c067enmittler } 2971864f965419c5b14ac9317c576c8a0f7169c067enmittler 2981864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 2991864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return a server keystore with a matched RSA certificate and 3001864f965419c5b14ac9317c576c8a0f7169c067enmittler * private key as well as a CA certificate. 3011864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3021864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getServer() { 3031864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 3041864f965419c5b14ac9317c576c8a0f7169c067enmittler return SERVER; 3051864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3061864f965419c5b14ac9317c576c8a0f7169c067enmittler 3071864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3081864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return a keystore with a CA certificate 3091864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3101864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getClient() { 3111864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 3121864f965419c5b14ac9317c576c8a0f7169c067enmittler return CLIENT; 3131864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3141864f965419c5b14ac9317c576c8a0f7169c067enmittler 3151864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3161864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return a client keystore with a matched RSA certificate and 3171864f965419c5b14ac9317c576c8a0f7169c067enmittler * private key as well as a CA certificate. 3181864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3191864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getClientCertificate() { 3201864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 3211864f965419c5b14ac9317c576c8a0f7169c067enmittler return CLIENT_CERTIFICATE; 3221864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3231864f965419c5b14ac9317c576c8a0f7169c067enmittler 3241864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3251864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return a client keystore with a matched RSA certificate and 3261864f965419c5b14ac9317c576c8a0f7169c067enmittler * private key as well as a CA certificate. 3271864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3281864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getClientEcRsaCertificate() { 3291864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 3301864f965419c5b14ac9317c576c8a0f7169c067enmittler return CLIENT_EC_RSA_CERTIFICATE; 3311864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3321864f965419c5b14ac9317c576c8a0f7169c067enmittler 3331864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3341864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return a client keystore with a matched RSA certificate and 3351864f965419c5b14ac9317c576c8a0f7169c067enmittler * private key as well as a CA certificate. 3361864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3371864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getClientEcEcCertificate() { 3381864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 3391864f965419c5b14ac9317c576c8a0f7169c067enmittler return CLIENT_EC_EC_CERTIFICATE; 3401864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3411864f965419c5b14ac9317c576c8a0f7169c067enmittler 3421864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3431864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return a keystore with a second CA certificate that does not 3441864f965419c5b14ac9317c576c8a0f7169c067enmittler * trust the server certificate returned by getServer for negative 3451864f965419c5b14ac9317c576c8a0f7169c067enmittler * testing. 3461864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3471864f965419c5b14ac9317c576c8a0f7169c067enmittler public static TestKeyStore getClientCA2() { 3481864f965419c5b14ac9317c576c8a0f7169c067enmittler initCerts(); 3491864f965419c5b14ac9317c576c8a0f7169c067enmittler return CLIENT_2; 3501864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3511864f965419c5b14ac9317c576c8a0f7169c067enmittler 3521864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3531864f965419c5b14ac9317c576c8a0f7169c067enmittler * Creates KeyStores containing the requested key types. Since key 3541864f965419c5b14ac9317c576c8a0f7169c067enmittler * generation can be expensive, most tests should reuse the RSA-only 3551864f965419c5b14ac9317c576c8a0f7169c067enmittler * singleton instance returned by TestKeyStore.get. 3561864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3571864f965419c5b14ac9317c576c8a0f7169c067enmittler public static class Builder { 3581864f965419c5b14ac9317c576c8a0f7169c067enmittler private String[] keyAlgorithms = {"RSA"}; 3591864f965419c5b14ac9317c576c8a0f7169c067enmittler private char[] storePassword; 3601864f965419c5b14ac9317c576c8a0f7169c067enmittler private char[] keyPassword; 3611864f965419c5b14ac9317c576c8a0f7169c067enmittler private String aliasPrefix; 3621864f965419c5b14ac9317c576c8a0f7169c067enmittler private X500Principal subject; 3631864f965419c5b14ac9317c576c8a0f7169c067enmittler private int keyUsage; 3641864f965419c5b14ac9317c576c8a0f7169c067enmittler private boolean ca; 3651864f965419c5b14ac9317c576c8a0f7169c067enmittler private PrivateKeyEntry privateEntry; 3661864f965419c5b14ac9317c576c8a0f7169c067enmittler private PrivateKeyEntry signer; 3671864f965419c5b14ac9317c576c8a0f7169c067enmittler private Certificate rootCa; 3681864f965419c5b14ac9317c576c8a0f7169c067enmittler private final List<KeyPurposeId> extendedKeyUsages = new ArrayList<KeyPurposeId>(); 3691864f965419c5b14ac9317c576c8a0f7169c067enmittler private final List<Boolean> criticalExtendedKeyUsages = new ArrayList<Boolean>(); 3701864f965419c5b14ac9317c576c8a0f7169c067enmittler private final List<GeneralName> subjectAltNames = new ArrayList<GeneralName>(); 3711864f965419c5b14ac9317c576c8a0f7169c067enmittler private final List<GeneralSubtree> permittedNameConstraints = 3721864f965419c5b14ac9317c576c8a0f7169c067enmittler new ArrayList<GeneralSubtree>(); 3731864f965419c5b14ac9317c576c8a0f7169c067enmittler private final List<GeneralSubtree> excludedNameConstraints = 3741864f965419c5b14ac9317c576c8a0f7169c067enmittler new ArrayList<GeneralSubtree>(); 3751864f965419c5b14ac9317c576c8a0f7169c067enmittler // Generated randomly if not set 3761864f965419c5b14ac9317c576c8a0f7169c067enmittler private BigInteger certificateSerialNumber = null; 3771864f965419c5b14ac9317c576c8a0f7169c067enmittler 3781864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder() { 3791864f965419c5b14ac9317c576c8a0f7169c067enmittler subject = localhost(); 3801864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3811864f965419c5b14ac9317c576c8a0f7169c067enmittler 3821864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3831864f965419c5b14ac9317c576c8a0f7169c067enmittler * Sets the requested key types to generate and include. The default is 3841864f965419c5b14ac9317c576c8a0f7169c067enmittler * RSA only. 3851864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 3861864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder keyAlgorithms(String... keyAlgorithms) { 3871864f965419c5b14ac9317c576c8a0f7169c067enmittler this.keyAlgorithms = keyAlgorithms; 3881864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 3891864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3901864f965419c5b14ac9317c576c8a0f7169c067enmittler 3911864f965419c5b14ac9317c576c8a0f7169c067enmittler /** A unique prefix to identify the key aliases */ 3921864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder aliasPrefix(String aliasPrefix) { 3931864f965419c5b14ac9317c576c8a0f7169c067enmittler this.aliasPrefix = aliasPrefix; 3941864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 3951864f965419c5b14ac9317c576c8a0f7169c067enmittler } 3961864f965419c5b14ac9317c576c8a0f7169c067enmittler 3971864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 3981864f965419c5b14ac9317c576c8a0f7169c067enmittler * Sets the subject common name. The default is the local host's 3991864f965419c5b14ac9317c576c8a0f7169c067enmittler * canonical name. 4001864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 4011864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder subject(X500Principal subject) { 4021864f965419c5b14ac9317c576c8a0f7169c067enmittler this.subject = subject; 4031864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4041864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4051864f965419c5b14ac9317c576c8a0f7169c067enmittler 4061864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder subject(String commonName) { 4071864f965419c5b14ac9317c576c8a0f7169c067enmittler return subject(new X500Principal(commonName)); 4081864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4091864f965419c5b14ac9317c576c8a0f7169c067enmittler 4101864f965419c5b14ac9317c576c8a0f7169c067enmittler /** {@link KeyUsage} bit mask for 2.5.29.15 extension */ 4111864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder keyUsage(int keyUsage) { 4121864f965419c5b14ac9317c576c8a0f7169c067enmittler this.keyUsage = keyUsage; 4131864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4141864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4151864f965419c5b14ac9317c576c8a0f7169c067enmittler 4161864f965419c5b14ac9317c576c8a0f7169c067enmittler /** true If the keys being created are for a CA */ 4171864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder ca(boolean ca) { 4181864f965419c5b14ac9317c576c8a0f7169c067enmittler this.ca = ca; 4191864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4201864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4211864f965419c5b14ac9317c576c8a0f7169c067enmittler 4221864f965419c5b14ac9317c576c8a0f7169c067enmittler /** a private key entry to use for the generation of the certificate */ 4231864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder privateEntry(PrivateKeyEntry privateEntry) { 4241864f965419c5b14ac9317c576c8a0f7169c067enmittler this.privateEntry = privateEntry; 4251864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4261864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4271864f965419c5b14ac9317c576c8a0f7169c067enmittler 4281864f965419c5b14ac9317c576c8a0f7169c067enmittler /** a private key entry to be used for signing, otherwise self-sign */ 4291864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder signer(PrivateKeyEntry signer) { 4301864f965419c5b14ac9317c576c8a0f7169c067enmittler this.signer = signer; 4311864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4321864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4331864f965419c5b14ac9317c576c8a0f7169c067enmittler 4341864f965419c5b14ac9317c576c8a0f7169c067enmittler /** a root CA to include in the final store */ 4351864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder rootCa(Certificate rootCa) { 4361864f965419c5b14ac9317c576c8a0f7169c067enmittler this.rootCa = rootCa; 4371864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4381864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4391864f965419c5b14ac9317c576c8a0f7169c067enmittler 4401864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder addExtendedKeyUsage(KeyPurposeId keyPurposeId, boolean critical) { 4411864f965419c5b14ac9317c576c8a0f7169c067enmittler extendedKeyUsages.add(keyPurposeId); 4421864f965419c5b14ac9317c576c8a0f7169c067enmittler criticalExtendedKeyUsages.add(critical); 4431864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4441864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4451864f965419c5b14ac9317c576c8a0f7169c067enmittler 4461864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder addSubjectAltName(GeneralName generalName) { 4471864f965419c5b14ac9317c576c8a0f7169c067enmittler subjectAltNames.add(generalName); 4481864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4491864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4501864f965419c5b14ac9317c576c8a0f7169c067enmittler 4511864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder addSubjectAltNameIpAddress(byte[] ipAddress) { 4521864f965419c5b14ac9317c576c8a0f7169c067enmittler return addSubjectAltName( 4531864f965419c5b14ac9317c576c8a0f7169c067enmittler new GeneralName(GeneralName.iPAddress, new DEROctetString(ipAddress))); 4541864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4551864f965419c5b14ac9317c576c8a0f7169c067enmittler 4561864f965419c5b14ac9317c576c8a0f7169c067enmittler private Builder addNameConstraint(boolean permitted, GeneralName generalName) { 4571864f965419c5b14ac9317c576c8a0f7169c067enmittler if (permitted) { 4581864f965419c5b14ac9317c576c8a0f7169c067enmittler permittedNameConstraints.add(new GeneralSubtree(generalName)); 4591864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 4601864f965419c5b14ac9317c576c8a0f7169c067enmittler excludedNameConstraints.add(new GeneralSubtree(generalName)); 4611864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4621864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4631864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4641864f965419c5b14ac9317c576c8a0f7169c067enmittler 4651864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder addNameConstraint(boolean permitted, byte[] ipAddress) { 4661864f965419c5b14ac9317c576c8a0f7169c067enmittler return addNameConstraint(permitted, 4671864f965419c5b14ac9317c576c8a0f7169c067enmittler new GeneralName(GeneralName.iPAddress, new DEROctetString(ipAddress))); 4681864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4691864f965419c5b14ac9317c576c8a0f7169c067enmittler 4701864f965419c5b14ac9317c576c8a0f7169c067enmittler public Builder certificateSerialNumber(BigInteger certificateSerialNumber) { 4711864f965419c5b14ac9317c576c8a0f7169c067enmittler this.certificateSerialNumber = certificateSerialNumber; 4721864f965419c5b14ac9317c576c8a0f7169c067enmittler return this; 4731864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4741864f965419c5b14ac9317c576c8a0f7169c067enmittler 4751864f965419c5b14ac9317c576c8a0f7169c067enmittler public TestKeyStore build() { 4761864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 4771864f965419c5b14ac9317c576c8a0f7169c067enmittler if (StandardNames.IS_RI) { 4781864f965419c5b14ac9317c576c8a0f7169c067enmittler // JKS does not allow null password 4791864f965419c5b14ac9317c576c8a0f7169c067enmittler if (storePassword == null) { 4801864f965419c5b14ac9317c576c8a0f7169c067enmittler storePassword = "password".toCharArray(); 4811864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4821864f965419c5b14ac9317c576c8a0f7169c067enmittler if (keyPassword == null) { 4831864f965419c5b14ac9317c576c8a0f7169c067enmittler keyPassword = "password".toCharArray(); 4841864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4851864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4861864f965419c5b14ac9317c576c8a0f7169c067enmittler 4871864f965419c5b14ac9317c576c8a0f7169c067enmittler /* 4881864f965419c5b14ac9317c576c8a0f7169c067enmittler * This is not implemented for other key types because the logic 4891864f965419c5b14ac9317c576c8a0f7169c067enmittler * would be long to write and it's not needed currently. 4901864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 4911864f965419c5b14ac9317c576c8a0f7169c067enmittler if (privateEntry != null 4921864f965419c5b14ac9317c576c8a0f7169c067enmittler && (keyAlgorithms.length != 1 || !"RSA".equals(keyAlgorithms[0]))) { 4931864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException( 4941864f965419c5b14ac9317c576c8a0f7169c067enmittler "Only reusing an existing key is implemented for RSA"); 4951864f965419c5b14ac9317c576c8a0f7169c067enmittler } 4961864f965419c5b14ac9317c576c8a0f7169c067enmittler 4971864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyStore keyStore = createKeyStore(); 4981864f965419c5b14ac9317c576c8a0f7169c067enmittler for (String keyAlgorithm : keyAlgorithms) { 4991864f965419c5b14ac9317c576c8a0f7169c067enmittler String publicAlias = aliasPrefix + "-public-" + keyAlgorithm; 5001864f965419c5b14ac9317c576c8a0f7169c067enmittler String privateAlias = aliasPrefix + "-private-" + keyAlgorithm; 5011864f965419c5b14ac9317c576c8a0f7169c067enmittler if ((keyAlgorithm.equals("EC_RSA") || keyAlgorithm.equals("DH_RSA")) 5021864f965419c5b14ac9317c576c8a0f7169c067enmittler && signer == null && rootCa == null) { 5031864f965419c5b14ac9317c576c8a0f7169c067enmittler createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias, null, 5041864f965419c5b14ac9317c576c8a0f7169c067enmittler privateKey(keyStore, keyPassword, "RSA", "RSA")); 5051864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 5061864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("DH_DSA") && signer == null && rootCa == null) { 5071864f965419c5b14ac9317c576c8a0f7169c067enmittler createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias, null, 5081864f965419c5b14ac9317c576c8a0f7169c067enmittler privateKey(keyStore, keyPassword, "DSA", "DSA")); 5091864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 5101864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5111864f965419c5b14ac9317c576c8a0f7169c067enmittler createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias, privateEntry, 5121864f965419c5b14ac9317c576c8a0f7169c067enmittler signer); 5131864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5141864f965419c5b14ac9317c576c8a0f7169c067enmittler if (rootCa != null) { 5151864f965419c5b14ac9317c576c8a0f7169c067enmittler keyStore.setCertificateEntry( 5161864f965419c5b14ac9317c576c8a0f7169c067enmittler aliasPrefix + "-root-ca-" + rootCa.getPublicKey().getAlgorithm(), 5171864f965419c5b14ac9317c576c8a0f7169c067enmittler rootCa); 5181864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5191864f965419c5b14ac9317c576c8a0f7169c067enmittler return new TestKeyStore(keyStore, storePassword, keyPassword); 5201864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 5211864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 5221864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5231864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5241864f965419c5b14ac9317c576c8a0f7169c067enmittler 5251864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 5261864f965419c5b14ac9317c576c8a0f7169c067enmittler * Add newly generated keys of a given key type to an existing 5271864f965419c5b14ac9317c576c8a0f7169c067enmittler * KeyStore. The PrivateKey will be stored under the specified 5281864f965419c5b14ac9317c576c8a0f7169c067enmittler * private alias name. The X509Certificate will be stored on the 5291864f965419c5b14ac9317c576c8a0f7169c067enmittler * public alias name and have the given subject distinguished 5301864f965419c5b14ac9317c576c8a0f7169c067enmittler * name. 5311864f965419c5b14ac9317c576c8a0f7169c067enmittler * 5321864f965419c5b14ac9317c576c8a0f7169c067enmittler * If a CA is provided, it will be used to sign the generated 5331864f965419c5b14ac9317c576c8a0f7169c067enmittler * certificate and OCSP responses. Otherwise, the certificate 5341864f965419c5b14ac9317c576c8a0f7169c067enmittler * will be self signed. The certificate will be valid for one 5351864f965419c5b14ac9317c576c8a0f7169c067enmittler * day before and one day after the time of creation. 5361864f965419c5b14ac9317c576c8a0f7169c067enmittler * 5371864f965419c5b14ac9317c576c8a0f7169c067enmittler * Based on: 5381864f965419c5b14ac9317c576c8a0f7169c067enmittler * org.bouncycastle.jce.provider.test.SigTest 5391864f965419c5b14ac9317c576c8a0f7169c067enmittler * org.bouncycastle.jce.provider.test.CertTest 5401864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 5411864f965419c5b14ac9317c576c8a0f7169c067enmittler private KeyStore createKeys(KeyStore keyStore, String keyAlgorithm, String publicAlias, 5421864f965419c5b14ac9317c576c8a0f7169c067enmittler String privateAlias, PrivateKeyEntry privateEntry, PrivateKeyEntry signer) 5431864f965419c5b14ac9317c576c8a0f7169c067enmittler throws Exception { 5441864f965419c5b14ac9317c576c8a0f7169c067enmittler PrivateKey caKey; 5451864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate caCert; 5461864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate[] caCertChain; 5471864f965419c5b14ac9317c576c8a0f7169c067enmittler if (signer == null) { 5481864f965419c5b14ac9317c576c8a0f7169c067enmittler caKey = null; 5491864f965419c5b14ac9317c576c8a0f7169c067enmittler caCert = null; 5501864f965419c5b14ac9317c576c8a0f7169c067enmittler caCertChain = null; 5511864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 5521864f965419c5b14ac9317c576c8a0f7169c067enmittler caKey = signer.getPrivateKey(); 5531864f965419c5b14ac9317c576c8a0f7169c067enmittler caCert = (X509Certificate) signer.getCertificate(); 5541864f965419c5b14ac9317c576c8a0f7169c067enmittler caCertChain = (X509Certificate[]) signer.getCertificateChain(); 5551864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5561864f965419c5b14ac9317c576c8a0f7169c067enmittler 5571864f965419c5b14ac9317c576c8a0f7169c067enmittler final PrivateKey privateKey; 5581864f965419c5b14ac9317c576c8a0f7169c067enmittler final PublicKey publicKey; 5591864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate x509c; 5601864f965419c5b14ac9317c576c8a0f7169c067enmittler if (publicAlias == null && privateAlias == null) { 5611864f965419c5b14ac9317c576c8a0f7169c067enmittler // don't want anything apparently 5621864f965419c5b14ac9317c576c8a0f7169c067enmittler privateKey = null; 5631864f965419c5b14ac9317c576c8a0f7169c067enmittler publicKey = null; 5641864f965419c5b14ac9317c576c8a0f7169c067enmittler x509c = null; 5651864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 5661864f965419c5b14ac9317c576c8a0f7169c067enmittler if (privateEntry == null) { 5671864f965419c5b14ac9317c576c8a0f7169c067enmittler // 1a.) we make the keys 5681864f965419c5b14ac9317c576c8a0f7169c067enmittler int keySize = -1; 5691864f965419c5b14ac9317c576c8a0f7169c067enmittler AlgorithmParameterSpec spec = null; 5701864f965419c5b14ac9317c576c8a0f7169c067enmittler if (keyAlgorithm.equals("RSA")) { 5711864f965419c5b14ac9317c576c8a0f7169c067enmittler keySize = RSA_KEY_SIZE_BITS; 5721864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("DH_RSA")) { 5731864f965419c5b14ac9317c576c8a0f7169c067enmittler spec = new DHParameterSpec(DH_PARAMS_P, DH_PARAMS_G); 5741864f965419c5b14ac9317c576c8a0f7169c067enmittler keyAlgorithm = "DH"; 5751864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("DSA")) { 5761864f965419c5b14ac9317c576c8a0f7169c067enmittler keySize = DSA_KEY_SIZE_BITS; 5771864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("DH_DSA")) { 5781864f965419c5b14ac9317c576c8a0f7169c067enmittler spec = new DHParameterSpec(DH_PARAMS_P, DH_PARAMS_G); 5791864f965419c5b14ac9317c576c8a0f7169c067enmittler keyAlgorithm = "DH"; 5801864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("EC")) { 5811864f965419c5b14ac9317c576c8a0f7169c067enmittler keySize = EC_KEY_SIZE_BITS; 5821864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("EC_RSA")) { 5831864f965419c5b14ac9317c576c8a0f7169c067enmittler keySize = EC_KEY_SIZE_BITS; 5841864f965419c5b14ac9317c576c8a0f7169c067enmittler keyAlgorithm = "EC"; 5851864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 5861864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalArgumentException("Unknown key algorithm " + keyAlgorithm); 5871864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5881864f965419c5b14ac9317c576c8a0f7169c067enmittler 5891864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgorithm); 5901864f965419c5b14ac9317c576c8a0f7169c067enmittler if (spec != null) { 5911864f965419c5b14ac9317c576c8a0f7169c067enmittler kpg.initialize(spec); 5921864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keySize != -1) { 5931864f965419c5b14ac9317c576c8a0f7169c067enmittler kpg.initialize(keySize); 5941864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 5951864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new AssertionError( 5961864f965419c5b14ac9317c576c8a0f7169c067enmittler "Must either have set algorithm parameters or key size!"); 5971864f965419c5b14ac9317c576c8a0f7169c067enmittler } 5981864f965419c5b14ac9317c576c8a0f7169c067enmittler 5991864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyPair kp = kpg.generateKeyPair(); 6001864f965419c5b14ac9317c576c8a0f7169c067enmittler privateKey = kp.getPrivate(); 6011864f965419c5b14ac9317c576c8a0f7169c067enmittler publicKey = kp.getPublic(); 6021864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 6031864f965419c5b14ac9317c576c8a0f7169c067enmittler // 1b.) we use the previous keys 6041864f965419c5b14ac9317c576c8a0f7169c067enmittler privateKey = privateEntry.getPrivateKey(); 6051864f965419c5b14ac9317c576c8a0f7169c067enmittler publicKey = privateEntry.getCertificate().getPublicKey(); 6061864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6071864f965419c5b14ac9317c576c8a0f7169c067enmittler 6081864f965419c5b14ac9317c576c8a0f7169c067enmittler // 2.) use keys to make certificate 6091864f965419c5b14ac9317c576c8a0f7169c067enmittler X500Principal issuer = 6101864f965419c5b14ac9317c576c8a0f7169c067enmittler ((caCert != null) ? caCert.getSubjectX500Principal() : subject); 6111864f965419c5b14ac9317c576c8a0f7169c067enmittler PrivateKey signingKey = (caKey == null) ? privateKey : caKey; 6121864f965419c5b14ac9317c576c8a0f7169c067enmittler x509c = createCertificate(publicKey, signingKey, subject, issuer, keyUsage, ca, 6131864f965419c5b14ac9317c576c8a0f7169c067enmittler extendedKeyUsages, criticalExtendedKeyUsages, subjectAltNames, 6141864f965419c5b14ac9317c576c8a0f7169c067enmittler permittedNameConstraints, excludedNameConstraints, certificateSerialNumber); 6151864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6161864f965419c5b14ac9317c576c8a0f7169c067enmittler 6171864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate[] x509cc; 6181864f965419c5b14ac9317c576c8a0f7169c067enmittler if (privateAlias == null) { 6191864f965419c5b14ac9317c576c8a0f7169c067enmittler // don't need certificate chain 6201864f965419c5b14ac9317c576c8a0f7169c067enmittler x509cc = null; 6211864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (caCertChain == null) { 6221864f965419c5b14ac9317c576c8a0f7169c067enmittler x509cc = new X509Certificate[] {x509c}; 6231864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 6241864f965419c5b14ac9317c576c8a0f7169c067enmittler x509cc = new X509Certificate[caCertChain.length + 1]; 6251864f965419c5b14ac9317c576c8a0f7169c067enmittler x509cc[0] = x509c; 6261864f965419c5b14ac9317c576c8a0f7169c067enmittler System.arraycopy(caCertChain, 0, x509cc, 1, caCertChain.length); 6271864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6281864f965419c5b14ac9317c576c8a0f7169c067enmittler 6291864f965419c5b14ac9317c576c8a0f7169c067enmittler // 3.) put certificate and private key into the key store 6301864f965419c5b14ac9317c576c8a0f7169c067enmittler if (privateAlias != null) { 6311864f965419c5b14ac9317c576c8a0f7169c067enmittler keyStore.setKeyEntry(privateAlias, privateKey, keyPassword, x509cc); 6321864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6331864f965419c5b14ac9317c576c8a0f7169c067enmittler if (publicAlias != null) { 6341864f965419c5b14ac9317c576c8a0f7169c067enmittler keyStore.setCertificateEntry(publicAlias, x509c); 6351864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6361864f965419c5b14ac9317c576c8a0f7169c067enmittler return keyStore; 6371864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6381864f965419c5b14ac9317c576c8a0f7169c067enmittler 6391864f965419c5b14ac9317c576c8a0f7169c067enmittler private X500Principal localhost() { 6401864f965419c5b14ac9317c576c8a0f7169c067enmittler return new X500Principal("CN=" + LOCAL_HOST_NAME); 6411864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6421864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6431864f965419c5b14ac9317c576c8a0f7169c067enmittler 6441864f965419c5b14ac9317c576c8a0f7169c067enmittler public static X509Certificate createCa( 6451864f965419c5b14ac9317c576c8a0f7169c067enmittler PublicKey publicKey, PrivateKey privateKey, String subject) { 6461864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 6471864f965419c5b14ac9317c576c8a0f7169c067enmittler X500Principal principal = new X500Principal(subject); 6481864f965419c5b14ac9317c576c8a0f7169c067enmittler return createCertificate(publicKey, privateKey, principal, principal, 0, true, 6491864f965419c5b14ac9317c576c8a0f7169c067enmittler new ArrayList<KeyPurposeId>(), new ArrayList<Boolean>(), 6501864f965419c5b14ac9317c576c8a0f7169c067enmittler new ArrayList<GeneralName>(), new ArrayList<GeneralSubtree>(), 6511864f965419c5b14ac9317c576c8a0f7169c067enmittler new ArrayList<GeneralSubtree>(), null /* serialNumber, generated randomly */); 6521864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 6531864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 6541864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6551864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6561864f965419c5b14ac9317c576c8a0f7169c067enmittler 6571864f965419c5b14ac9317c576c8a0f7169c067enmittler private static X509Certificate createCertificate(PublicKey publicKey, PrivateKey privateKey, 6581864f965419c5b14ac9317c576c8a0f7169c067enmittler X500Principal subject, X500Principal issuer, int keyUsage, boolean ca, 6591864f965419c5b14ac9317c576c8a0f7169c067enmittler List<KeyPurposeId> extendedKeyUsages, List<Boolean> criticalExtendedKeyUsages, 6601864f965419c5b14ac9317c576c8a0f7169c067enmittler List<GeneralName> subjectAltNames, List<GeneralSubtree> permittedNameConstraints, 6611864f965419c5b14ac9317c576c8a0f7169c067enmittler List<GeneralSubtree> excludedNameConstraints, BigInteger serialNumber) 6621864f965419c5b14ac9317c576c8a0f7169c067enmittler throws Exception { 6631864f965419c5b14ac9317c576c8a0f7169c067enmittler // Note that there is no way to programmatically make a 6641864f965419c5b14ac9317c576c8a0f7169c067enmittler // Certificate using java.* or javax.* APIs. The 6651864f965419c5b14ac9317c576c8a0f7169c067enmittler // CertificateFactory interface assumes you want to read 6661864f965419c5b14ac9317c576c8a0f7169c067enmittler // in a stream of bytes, typically the X.509 factory would 6671864f965419c5b14ac9317c576c8a0f7169c067enmittler // allow ASN.1 DER encoded bytes and optionally some PEM 6681864f965419c5b14ac9317c576c8a0f7169c067enmittler // formats. Here we use Bouncy Castle's 6691864f965419c5b14ac9317c576c8a0f7169c067enmittler // X509V3CertificateGenerator and related classes. 6701864f965419c5b14ac9317c576c8a0f7169c067enmittler 6711864f965419c5b14ac9317c576c8a0f7169c067enmittler long millisPerDay = 24 * 60 * 60 * 1000; 6721864f965419c5b14ac9317c576c8a0f7169c067enmittler long now = System.currentTimeMillis(); 6731864f965419c5b14ac9317c576c8a0f7169c067enmittler Date start = new Date(now - millisPerDay); 6741864f965419c5b14ac9317c576c8a0f7169c067enmittler Date end = new Date(now + millisPerDay); 6751864f965419c5b14ac9317c576c8a0f7169c067enmittler 6761864f965419c5b14ac9317c576c8a0f7169c067enmittler String keyAlgorithm = privateKey.getAlgorithm(); 6771864f965419c5b14ac9317c576c8a0f7169c067enmittler String signatureAlgorithm; 6781864f965419c5b14ac9317c576c8a0f7169c067enmittler if (keyAlgorithm.equals("RSA")) { 6791864f965419c5b14ac9317c576c8a0f7169c067enmittler signatureAlgorithm = "sha1WithRSA"; 6801864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("DSA")) { 6811864f965419c5b14ac9317c576c8a0f7169c067enmittler signatureAlgorithm = "sha1WithDSA"; 6821864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("EC")) { 6831864f965419c5b14ac9317c576c8a0f7169c067enmittler signatureAlgorithm = "sha1WithECDSA"; 6841864f965419c5b14ac9317c576c8a0f7169c067enmittler } else if (keyAlgorithm.equals("EC_RSA")) { 6851864f965419c5b14ac9317c576c8a0f7169c067enmittler signatureAlgorithm = "sha1WithRSA"; 6861864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 6871864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalArgumentException("Unknown key algorithm " + keyAlgorithm); 6881864f965419c5b14ac9317c576c8a0f7169c067enmittler } 6891864f965419c5b14ac9317c576c8a0f7169c067enmittler 6901864f965419c5b14ac9317c576c8a0f7169c067enmittler if (serialNumber == null) { 6911864f965419c5b14ac9317c576c8a0f7169c067enmittler byte[] serialBytes = new byte[16]; 6921864f965419c5b14ac9317c576c8a0f7169c067enmittler new SecureRandom().nextBytes(serialBytes); 6931864f965419c5b14ac9317c576c8a0f7169c067enmittler serialNumber = new BigInteger(1, serialBytes); 6941864f965419c5b14ac9317c576c8a0f7169c067enmittler } 695027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root 696027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root X509v3CertificateBuilder x509cg = 697027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root new X509v3CertificateBuilder(X500Name.getInstance(issuer.getEncoded()), 698027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root serialNumber, start, end, X500Name.getInstance(subject.getEncoded()), 699027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); 7001864f965419c5b14ac9317c576c8a0f7169c067enmittler if (keyUsage != 0) { 701027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root x509cg.addExtension(Extension.keyUsage, true, new KeyUsage(keyUsage)); 7021864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7031864f965419c5b14ac9317c576c8a0f7169c067enmittler if (ca) { 704027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root x509cg.addExtension(Extension.basicConstraints, true, new BasicConstraints(true)); 7051864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7061864f965419c5b14ac9317c576c8a0f7169c067enmittler for (int i = 0; i < extendedKeyUsages.size(); i++) { 7071864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyPurposeId keyPurposeId = extendedKeyUsages.get(i); 7081864f965419c5b14ac9317c576c8a0f7169c067enmittler boolean critical = criticalExtendedKeyUsages.get(i); 7091864f965419c5b14ac9317c576c8a0f7169c067enmittler x509cg.addExtension( 710027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root Extension.extendedKeyUsage, critical, new ExtendedKeyUsage(keyPurposeId)); 7111864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7121864f965419c5b14ac9317c576c8a0f7169c067enmittler for (GeneralName subjectAltName : subjectAltNames) { 713027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root x509cg.addExtension(Extension.subjectAlternativeName, false, 7141864f965419c5b14ac9317c576c8a0f7169c067enmittler new GeneralNames(subjectAltName).getEncoded()); 7151864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7161864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!permittedNameConstraints.isEmpty() || !excludedNameConstraints.isEmpty()) { 717027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root x509cg.addExtension(Extension.nameConstraints, true, 7181864f965419c5b14ac9317c576c8a0f7169c067enmittler new NameConstraints( 7191864f965419c5b14ac9317c576c8a0f7169c067enmittler permittedNameConstraints.toArray( 7201864f965419c5b14ac9317c576c8a0f7169c067enmittler new GeneralSubtree[permittedNameConstraints.size()]), 7211864f965419c5b14ac9317c576c8a0f7169c067enmittler excludedNameConstraints.toArray( 7221864f965419c5b14ac9317c576c8a0f7169c067enmittler new GeneralSubtree[excludedNameConstraints.size()]))); 7231864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7241864f965419c5b14ac9317c576c8a0f7169c067enmittler 725027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root X509CertificateHolder x509holder = 726027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root x509cg.build(new JcaContentSignerBuilder(signatureAlgorithm).build(privateKey)); 727027eb2c41cadcf47472d5c9a2e46eafa4a3440b9Kenny Root X509Certificate x509c = new JcaX509CertificateConverter().getCertificate(x509holder); 7281864f965419c5b14ac9317c576c8a0f7169c067enmittler if (StandardNames.IS_RI) { 7291864f965419c5b14ac9317c576c8a0f7169c067enmittler /* 7301864f965419c5b14ac9317c576c8a0f7169c067enmittler * The RI can't handle the BC EC signature algorithm 7311864f965419c5b14ac9317c576c8a0f7169c067enmittler * string of "ECDSA", since it expects "...WITHEC...", 7321864f965419c5b14ac9317c576c8a0f7169c067enmittler * so convert from BC to RI X509Certificate 7331864f965419c5b14ac9317c576c8a0f7169c067enmittler * implementation via bytes. 7341864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 7351864f965419c5b14ac9317c576c8a0f7169c067enmittler CertificateFactory cf = CertificateFactory.getInstance("X.509"); 7361864f965419c5b14ac9317c576c8a0f7169c067enmittler ByteArrayInputStream bais = new ByteArrayInputStream(x509c.getEncoded()); 7371864f965419c5b14ac9317c576c8a0f7169c067enmittler Certificate c = cf.generateCertificate(bais); 7381864f965419c5b14ac9317c576c8a0f7169c067enmittler x509c = (X509Certificate) c; 7391864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7401864f965419c5b14ac9317c576c8a0f7169c067enmittler return x509c; 7411864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7421864f965419c5b14ac9317c576c8a0f7169c067enmittler 7431864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 7441864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the key algorithm for a possible compound algorithm 7451864f965419c5b14ac9317c576c8a0f7169c067enmittler * identifier containing an underscore. If not underscore is 7461864f965419c5b14ac9317c576c8a0f7169c067enmittler * present, the argument is returned unmodified. However for an 7471864f965419c5b14ac9317c576c8a0f7169c067enmittler * algorithm such as EC_RSA, return EC. 7481864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 7491864f965419c5b14ac9317c576c8a0f7169c067enmittler public static String keyAlgorithm(String algorithm) { 7501864f965419c5b14ac9317c576c8a0f7169c067enmittler int index = algorithm.indexOf('_'); 7511864f965419c5b14ac9317c576c8a0f7169c067enmittler if (index == -1) { 7521864f965419c5b14ac9317c576c8a0f7169c067enmittler return algorithm; 7531864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7541864f965419c5b14ac9317c576c8a0f7169c067enmittler return algorithm.substring(0, index); 7551864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7561864f965419c5b14ac9317c576c8a0f7169c067enmittler 7571864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 7581864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the signature algorithm for a possible compound 7591864f965419c5b14ac9317c576c8a0f7169c067enmittler * algorithm identifier containing an underscore. If not 7601864f965419c5b14ac9317c576c8a0f7169c067enmittler * underscore is present, the argument is returned 7611864f965419c5b14ac9317c576c8a0f7169c067enmittler * unmodified. However for an algorithm such as EC_RSA, return 7621864f965419c5b14ac9317c576c8a0f7169c067enmittler * RSA. 7631864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 7641864f965419c5b14ac9317c576c8a0f7169c067enmittler public static String signatureAlgorithm(String algorithm) { 7651864f965419c5b14ac9317c576c8a0f7169c067enmittler int index = algorithm.indexOf('_'); 7661864f965419c5b14ac9317c576c8a0f7169c067enmittler if (index == -1) { 7671864f965419c5b14ac9317c576c8a0f7169c067enmittler return algorithm; 7681864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7691864f965419c5b14ac9317c576c8a0f7169c067enmittler return algorithm.substring(index + 1, algorithm.length()); 7701864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7711864f965419c5b14ac9317c576c8a0f7169c067enmittler 7721864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 7731864f965419c5b14ac9317c576c8a0f7169c067enmittler * Create an empty KeyStore 7741864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 7751864f965419c5b14ac9317c576c8a0f7169c067enmittler public static KeyStore createKeyStore() { 7761864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 7771864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyStore keyStore = KeyStore.getInstance(StandardNames.KEY_STORE_ALGORITHM); 7781864f965419c5b14ac9317c576c8a0f7169c067enmittler keyStore.load(null, null); 7791864f965419c5b14ac9317c576c8a0f7169c067enmittler return keyStore; 7801864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 7811864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 7821864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7831864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7841864f965419c5b14ac9317c576c8a0f7169c067enmittler 7851864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 7861864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the only private key in a TestKeyStore for the given 7871864f965419c5b14ac9317c576c8a0f7169c067enmittler * algorithms. Throws IllegalStateException if there are are more 7881864f965419c5b14ac9317c576c8a0f7169c067enmittler * or less than one. 7891864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 7901864f965419c5b14ac9317c576c8a0f7169c067enmittler public PrivateKeyEntry getPrivateKey(String keyAlgorithm, String signatureAlgorithm) { 7911864f965419c5b14ac9317c576c8a0f7169c067enmittler return privateKey(keyStore, keyPassword, keyAlgorithm, signatureAlgorithm); 7921864f965419c5b14ac9317c576c8a0f7169c067enmittler } 7931864f965419c5b14ac9317c576c8a0f7169c067enmittler 7941864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 7951864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the only private key in a keystore for the given 7961864f965419c5b14ac9317c576c8a0f7169c067enmittler * algorithms. Throws IllegalStateException if there are are more 7971864f965419c5b14ac9317c576c8a0f7169c067enmittler * or less than one. 7981864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 7991864f965419c5b14ac9317c576c8a0f7169c067enmittler public static PrivateKeyEntry privateKey( 8001864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyStore keyStore, char[] keyPassword, String keyAlgorithm, String signatureAlgorithm) { 8011864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 8021864f965419c5b14ac9317c576c8a0f7169c067enmittler PrivateKeyEntry found = null; 8031864f965419c5b14ac9317c576c8a0f7169c067enmittler PasswordProtection password = new PasswordProtection(keyPassword); 8041864f965419c5b14ac9317c576c8a0f7169c067enmittler for (String alias : Collections.list(keyStore.aliases())) { 8051864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!keyStore.entryInstanceOf(alias, PrivateKeyEntry.class)) { 8061864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 8071864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8081864f965419c5b14ac9317c576c8a0f7169c067enmittler PrivateKeyEntry privateKey = (PrivateKeyEntry) keyStore.getEntry(alias, password); 8091864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!privateKey.getPrivateKey().getAlgorithm().equals(keyAlgorithm)) { 8101864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 8111864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8121864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate certificate = (X509Certificate) privateKey.getCertificate(); 8131864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!certificate.getSigAlgName().contains(signatureAlgorithm)) { 8141864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 8151864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8161864f965419c5b14ac9317c576c8a0f7169c067enmittler if (found != null) { 8171864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException("KeyStore has more than one private key for" 8181864f965419c5b14ac9317c576c8a0f7169c067enmittler + " keyAlgorithm: " + keyAlgorithm + " signatureAlgorithm: " 8191864f965419c5b14ac9317c576c8a0f7169c067enmittler + signatureAlgorithm + "\nfirst: " + found.getPrivateKey() 8201864f965419c5b14ac9317c576c8a0f7169c067enmittler + "\nsecond: " + privateKey.getPrivateKey()); 8211864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8221864f965419c5b14ac9317c576c8a0f7169c067enmittler found = privateKey; 8231864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8241864f965419c5b14ac9317c576c8a0f7169c067enmittler if (found == null) { 8251864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException("KeyStore contained no private key for" 826b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root + " keyAlgorithm: " + keyAlgorithm 827b6aab0c31d784c009ff2e576cf1db38fbcf2b691Kenny Root + " signatureAlgorithm: " + signatureAlgorithm); 8281864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8291864f965419c5b14ac9317c576c8a0f7169c067enmittler return found; 8301864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 8311864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException("Problem getting key for " + keyAlgorithm + " and signature " 8321864f965419c5b14ac9317c576c8a0f7169c067enmittler + signatureAlgorithm, 8331864f965419c5b14ac9317c576c8a0f7169c067enmittler e); 8341864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8351864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8361864f965419c5b14ac9317c576c8a0f7169c067enmittler 8371864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 8381864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the issuing CA certificate of the given 8391864f965419c5b14ac9317c576c8a0f7169c067enmittler * certificate. Throws IllegalStateException if there are are more 8401864f965419c5b14ac9317c576c8a0f7169c067enmittler * or less than one. 8411864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 8421864f965419c5b14ac9317c576c8a0f7169c067enmittler public Certificate getIssuer(Certificate cert) throws Exception { 8431864f965419c5b14ac9317c576c8a0f7169c067enmittler return issuer(keyStore, cert); 8441864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8451864f965419c5b14ac9317c576c8a0f7169c067enmittler 8461864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 8471864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the issuing CA certificate of the given 8481864f965419c5b14ac9317c576c8a0f7169c067enmittler * certificate. Throws IllegalStateException if there are are more 8491864f965419c5b14ac9317c576c8a0f7169c067enmittler * or less than one. 8501864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 8511864f965419c5b14ac9317c576c8a0f7169c067enmittler public static Certificate issuer(KeyStore keyStore, Certificate c) throws Exception { 8521864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!(c instanceof X509Certificate)) { 8531864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException("issuer requires an X509Certificate, found " + c); 8541864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8551864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate cert = (X509Certificate) c; 8561864f965419c5b14ac9317c576c8a0f7169c067enmittler 8571864f965419c5b14ac9317c576c8a0f7169c067enmittler Certificate found = null; 8581864f965419c5b14ac9317c576c8a0f7169c067enmittler for (String alias : Collections.list(keyStore.aliases())) { 8591864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!keyStore.entryInstanceOf(alias, TrustedCertificateEntry.class)) { 8601864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 8611864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8621864f965419c5b14ac9317c576c8a0f7169c067enmittler TrustedCertificateEntry certificateEntry = 8631864f965419c5b14ac9317c576c8a0f7169c067enmittler (TrustedCertificateEntry) keyStore.getEntry(alias, null); 8641864f965419c5b14ac9317c576c8a0f7169c067enmittler Certificate certificate = certificateEntry.getTrustedCertificate(); 8651864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!(certificate instanceof X509Certificate)) { 8661864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 8671864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8681864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate x = (X509Certificate) certificate; 8691864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!cert.getIssuerDN().equals(x.getSubjectDN())) { 8701864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 8711864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8721864f965419c5b14ac9317c576c8a0f7169c067enmittler if (found != null) { 8731864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException("KeyStore has more than one issuing CA for " + cert 8741864f965419c5b14ac9317c576c8a0f7169c067enmittler + "\nfirst: " + found + "\nsecond: " + certificate); 8751864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8761864f965419c5b14ac9317c576c8a0f7169c067enmittler found = certificate; 8771864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8781864f965419c5b14ac9317c576c8a0f7169c067enmittler if (found == null) { 8791864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException("KeyStore contained no issuing CA for " + cert); 8801864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8811864f965419c5b14ac9317c576c8a0f7169c067enmittler return found; 8821864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8831864f965419c5b14ac9317c576c8a0f7169c067enmittler 8841864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 8851864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the only self-signed root certificate in a TestKeyStore 8861864f965419c5b14ac9317c576c8a0f7169c067enmittler * for the given algorithm. Throws IllegalStateException if there 8871864f965419c5b14ac9317c576c8a0f7169c067enmittler * are are more or less than one. 8881864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 8891864f965419c5b14ac9317c576c8a0f7169c067enmittler public X509Certificate getRootCertificate(String algorithm) { 8901864f965419c5b14ac9317c576c8a0f7169c067enmittler return rootCertificate(keyStore, algorithm); 8911864f965419c5b14ac9317c576c8a0f7169c067enmittler } 8921864f965419c5b14ac9317c576c8a0f7169c067enmittler 8931864f965419c5b14ac9317c576c8a0f7169c067enmittler private static OCSPResp generateOCSPResponse(PrivateKeyEntry server, PrivateKeyEntry issuer, 8941864f965419c5b14ac9317c576c8a0f7169c067enmittler CertificateStatus status) throws CertificateException { 8951864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 8961864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate serverCertJca = (X509Certificate) server.getCertificate(); 8971864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate caCertJca = (X509Certificate) issuer.getCertificate(); 8981864f965419c5b14ac9317c576c8a0f7169c067enmittler 8991864f965419c5b14ac9317c576c8a0f7169c067enmittler X509CertificateHolder caCert = new JcaX509CertificateHolder(caCertJca); 9001864f965419c5b14ac9317c576c8a0f7169c067enmittler 9011864f965419c5b14ac9317c576c8a0f7169c067enmittler DigestCalculatorProvider digCalcProv = new BcDigestCalculatorProvider(); 9021864f965419c5b14ac9317c576c8a0f7169c067enmittler BasicOCSPRespBuilder basicBuilder = new BasicOCSPRespBuilder( 9031864f965419c5b14ac9317c576c8a0f7169c067enmittler SubjectPublicKeyInfo.getInstance(caCertJca.getPublicKey().getEncoded()), 9041864f965419c5b14ac9317c576c8a0f7169c067enmittler digCalcProv.get(CertificateID.HASH_SHA1)); 9051864f965419c5b14ac9317c576c8a0f7169c067enmittler 9061864f965419c5b14ac9317c576c8a0f7169c067enmittler CertificateID certId = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), 9071864f965419c5b14ac9317c576c8a0f7169c067enmittler caCert, serverCertJca.getSerialNumber()); 9081864f965419c5b14ac9317c576c8a0f7169c067enmittler 9091864f965419c5b14ac9317c576c8a0f7169c067enmittler basicBuilder.addResponse(certId, status); 9101864f965419c5b14ac9317c576c8a0f7169c067enmittler 9111864f965419c5b14ac9317c576c8a0f7169c067enmittler BasicOCSPResp resp = basicBuilder.build( 9121864f965419c5b14ac9317c576c8a0f7169c067enmittler new JcaContentSignerBuilder("SHA256withRSA").build(issuer.getPrivateKey()), 9131864f965419c5b14ac9317c576c8a0f7169c067enmittler null, new Date()); 9141864f965419c5b14ac9317c576c8a0f7169c067enmittler 9151864f965419c5b14ac9317c576c8a0f7169c067enmittler OCSPRespBuilder builder = new OCSPRespBuilder(); 9161864f965419c5b14ac9317c576c8a0f7169c067enmittler return builder.build(OCSPRespBuilder.SUCCESSFUL, resp); 9171864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 9181864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new CertificateException("cannot generate OCSP response", e); 9191864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9201864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9211864f965419c5b14ac9317c576c8a0f7169c067enmittler 9221864f965419c5b14ac9317c576c8a0f7169c067enmittler public static byte[] getOCSPResponseForGood(PrivateKeyEntry server, PrivateKeyEntry issuer) 9231864f965419c5b14ac9317c576c8a0f7169c067enmittler throws CertificateException { 9241864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 9251864f965419c5b14ac9317c576c8a0f7169c067enmittler return generateOCSPResponse(server, issuer, CertificateStatus.GOOD).getEncoded(); 9261864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (IOException e) { 9271864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new CertificateException(e); 9281864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9291864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9301864f965419c5b14ac9317c576c8a0f7169c067enmittler 9311864f965419c5b14ac9317c576c8a0f7169c067enmittler public static byte[] getOCSPResponseForRevoked(PrivateKeyEntry server, PrivateKeyEntry issuer) 9321864f965419c5b14ac9317c576c8a0f7169c067enmittler throws CertificateException { 9331864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 9341864f965419c5b14ac9317c576c8a0f7169c067enmittler return generateOCSPResponse( 9351864f965419c5b14ac9317c576c8a0f7169c067enmittler server, issuer, new RevokedStatus(new Date(), CRLReason.keyCompromise)) 9361864f965419c5b14ac9317c576c8a0f7169c067enmittler .getEncoded(); 9371864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (IOException e) { 9381864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new CertificateException(e); 9391864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9401864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9411864f965419c5b14ac9317c576c8a0f7169c067enmittler 9421864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 9431864f965419c5b14ac9317c576c8a0f7169c067enmittler * Return the only self-signed root certificate in a keystore for 9441864f965419c5b14ac9317c576c8a0f7169c067enmittler * the given algorithm. Throws IllegalStateException if there are 9451864f965419c5b14ac9317c576c8a0f7169c067enmittler * are more or less than one. 9461864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 9471864f965419c5b14ac9317c576c8a0f7169c067enmittler public static X509Certificate rootCertificate(KeyStore keyStore, String algorithm) { 9481864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 9491864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate found = null; 9501864f965419c5b14ac9317c576c8a0f7169c067enmittler for (String alias : Collections.list(keyStore.aliases())) { 9511864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!keyStore.entryInstanceOf(alias, TrustedCertificateEntry.class)) { 9521864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 9531864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9541864f965419c5b14ac9317c576c8a0f7169c067enmittler TrustedCertificateEntry certificateEntry = 9551864f965419c5b14ac9317c576c8a0f7169c067enmittler (TrustedCertificateEntry) keyStore.getEntry(alias, null); 9561864f965419c5b14ac9317c576c8a0f7169c067enmittler Certificate certificate = certificateEntry.getTrustedCertificate(); 9571864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!certificate.getPublicKey().getAlgorithm().equals(algorithm)) { 9581864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 9591864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9601864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!(certificate instanceof X509Certificate)) { 9611864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 9621864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9631864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate x = (X509Certificate) certificate; 9641864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!x.getIssuerDN().equals(x.getSubjectDN())) { 9651864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 9661864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9671864f965419c5b14ac9317c576c8a0f7169c067enmittler if (found != null) { 9681864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException("KeyStore has more than one root CA for " 9691864f965419c5b14ac9317c576c8a0f7169c067enmittler + algorithm + "\nfirst: " + found + "\nsecond: " + certificate); 9701864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9711864f965419c5b14ac9317c576c8a0f7169c067enmittler found = x; 9721864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9731864f965419c5b14ac9317c576c8a0f7169c067enmittler if (found == null) { 9741864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new IllegalStateException("KeyStore contained no root CA for " + algorithm); 9751864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9761864f965419c5b14ac9317c576c8a0f7169c067enmittler return found; 9771864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 9781864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 9791864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9801864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9811864f965419c5b14ac9317c576c8a0f7169c067enmittler 9821864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 983ae6e905323df3356e110c15808c7d4102da554c8Nathan Mittler * Return an {@code X509Certificate} that matches the given {@code alias}. 9841864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 9851864f965419c5b14ac9317c576c8a0f7169c067enmittler public KeyStore.Entry getEntryByAlias(String alias) { 9861864f965419c5b14ac9317c576c8a0f7169c067enmittler return entryByAlias(keyStore, alias); 9871864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9881864f965419c5b14ac9317c576c8a0f7169c067enmittler 9891864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 9901864f965419c5b14ac9317c576c8a0f7169c067enmittler * Finds an entry in the keystore by the given alias. 9911864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 9921864f965419c5b14ac9317c576c8a0f7169c067enmittler public static KeyStore.Entry entryByAlias(KeyStore keyStore, String alias) { 9931864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 9941864f965419c5b14ac9317c576c8a0f7169c067enmittler return keyStore.getEntry(alias, null); 9951864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (NoSuchAlgorithmException | UnrecoverableEntryException | KeyStoreException e) { 9961864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 9971864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9981864f965419c5b14ac9317c576c8a0f7169c067enmittler } 9991864f965419c5b14ac9317c576c8a0f7169c067enmittler 10001864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 10011864f965419c5b14ac9317c576c8a0f7169c067enmittler * Create a client key store that only contains self-signed certificates but no private keys 10021864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 10031864f965419c5b14ac9317c576c8a0f7169c067enmittler public static KeyStore createClient(KeyStore caKeyStore) { 10041864f965419c5b14ac9317c576c8a0f7169c067enmittler KeyStore clientKeyStore = createKeyStore(); 10051864f965419c5b14ac9317c576c8a0f7169c067enmittler copySelfSignedCertificates(clientKeyStore, caKeyStore); 10061864f965419c5b14ac9317c576c8a0f7169c067enmittler return clientKeyStore; 10071864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10081864f965419c5b14ac9317c576c8a0f7169c067enmittler 10091864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 10101864f965419c5b14ac9317c576c8a0f7169c067enmittler * Copy self-signed certificates from one key store to another. 10111864f965419c5b14ac9317c576c8a0f7169c067enmittler * Returns true if successful, false if no match found. 10121864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 10131864f965419c5b14ac9317c576c8a0f7169c067enmittler public static boolean copySelfSignedCertificates(KeyStore dst, KeyStore src) { 10141864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 10151864f965419c5b14ac9317c576c8a0f7169c067enmittler boolean copied = false; 10161864f965419c5b14ac9317c576c8a0f7169c067enmittler for (String alias : Collections.list(src.aliases())) { 10171864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!src.isCertificateEntry(alias)) { 10181864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 10191864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10201864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate cert = (X509Certificate) src.getCertificate(alias); 10211864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!cert.getSubjectDN().equals(cert.getIssuerDN())) { 10221864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 10231864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10241864f965419c5b14ac9317c576c8a0f7169c067enmittler dst.setCertificateEntry(alias, cert); 10251864f965419c5b14ac9317c576c8a0f7169c067enmittler copied = true; 10261864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10271864f965419c5b14ac9317c576c8a0f7169c067enmittler return copied; 10281864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (Exception e) { 10291864f965419c5b14ac9317c576c8a0f7169c067enmittler throw new RuntimeException(e); 10301864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10311864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10321864f965419c5b14ac9317c576c8a0f7169c067enmittler 10331864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 10341864f965419c5b14ac9317c576c8a0f7169c067enmittler * Copy named certificates from one key store to another. 10351864f965419c5b14ac9317c576c8a0f7169c067enmittler * Returns true if successful, false if no match found. 10361864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 10371864f965419c5b14ac9317c576c8a0f7169c067enmittler public static boolean copyCertificate(Principal subject, KeyStore dst, KeyStore src) 10381864f965419c5b14ac9317c576c8a0f7169c067enmittler throws Exception { 10391864f965419c5b14ac9317c576c8a0f7169c067enmittler for (String alias : Collections.list(src.aliases())) { 10401864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!src.isCertificateEntry(alias)) { 10411864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 10421864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10431864f965419c5b14ac9317c576c8a0f7169c067enmittler X509Certificate cert = (X509Certificate) src.getCertificate(alias); 10441864f965419c5b14ac9317c576c8a0f7169c067enmittler if (!cert.getSubjectDN().equals(subject)) { 10451864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 10461864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10471864f965419c5b14ac9317c576c8a0f7169c067enmittler dst.setCertificateEntry(alias, cert); 10481864f965419c5b14ac9317c576c8a0f7169c067enmittler return true; 10491864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10501864f965419c5b14ac9317c576c8a0f7169c067enmittler return false; 10511864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10521864f965419c5b14ac9317c576c8a0f7169c067enmittler 10531864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 10541864f965419c5b14ac9317c576c8a0f7169c067enmittler * Dump a key store for debugging. 10551864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 10561864f965419c5b14ac9317c576c8a0f7169c067enmittler public void dump(String context) throws KeyStoreException, NoSuchAlgorithmException { 10571864f965419c5b14ac9317c576c8a0f7169c067enmittler dump(context, keyStore, keyPassword); 10581864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10591864f965419c5b14ac9317c576c8a0f7169c067enmittler 10601864f965419c5b14ac9317c576c8a0f7169c067enmittler /** 10611864f965419c5b14ac9317c576c8a0f7169c067enmittler * Dump a key store for debugging. 10621864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 10631864f965419c5b14ac9317c576c8a0f7169c067enmittler public static void dump(String context, KeyStore keyStore, char[] keyPassword) 10641864f965419c5b14ac9317c576c8a0f7169c067enmittler throws KeyStoreException, NoSuchAlgorithmException { 10651864f965419c5b14ac9317c576c8a0f7169c067enmittler PrintStream out = System.out; 10661864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("context=" + context); 10671864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tkeyStore=" + keyStore); 10681864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tkeyStore.type=" + keyStore.getType()); 10691864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tkeyStore.provider=" + keyStore.getProvider()); 10701864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tkeyPassword=" + ((keyPassword == null) ? null : new String(keyPassword))); 10711864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tsize=" + keyStore.size()); 10721864f965419c5b14ac9317c576c8a0f7169c067enmittler for (String alias : Collections.list(keyStore.aliases())) { 10731864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("alias=" + alias); 10741864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tcreationDate=" + keyStore.getCreationDate(alias)); 10751864f965419c5b14ac9317c576c8a0f7169c067enmittler if (keyStore.isCertificateEntry(alias)) { 10761864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tcertificate:"); 10771864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("=========================================="); 10781864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println(keyStore.getCertificate(alias)); 10791864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("=========================================="); 10801864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 10811864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10821864f965419c5b14ac9317c576c8a0f7169c067enmittler if (keyStore.isKeyEntry(alias)) { 10831864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tkey:"); 10841864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("=========================================="); 10851864f965419c5b14ac9317c576c8a0f7169c067enmittler String key; 10861864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 10871864f965419c5b14ac9317c576c8a0f7169c067enmittler key = ("Key retrieved using password\n" + keyStore.getKey(alias, keyPassword)); 10881864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (UnrecoverableKeyException e1) { 10891864f965419c5b14ac9317c576c8a0f7169c067enmittler try { 10901864f965419c5b14ac9317c576c8a0f7169c067enmittler key = ("Key retrieved without password\n" + keyStore.getKey(alias, null)); 10911864f965419c5b14ac9317c576c8a0f7169c067enmittler } catch (UnrecoverableKeyException e2) { 10921864f965419c5b14ac9317c576c8a0f7169c067enmittler key = "Key could not be retrieved"; 10931864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10941864f965419c5b14ac9317c576c8a0f7169c067enmittler } 10951864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println(key); 10961864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("=========================================="); 10971864f965419c5b14ac9317c576c8a0f7169c067enmittler Certificate[] chain = keyStore.getCertificateChain(alias); 10981864f965419c5b14ac9317c576c8a0f7169c067enmittler if (chain == null) { 10991864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("No certificate chain associated with key"); 11001864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("=========================================="); 11011864f965419c5b14ac9317c576c8a0f7169c067enmittler } else { 11021864f965419c5b14ac9317c576c8a0f7169c067enmittler for (int i = 0; i < chain.length; i++) { 11031864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("Certificate chain element #" + i); 11041864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println(chain[i]); 11051864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("=========================================="); 11061864f965419c5b14ac9317c576c8a0f7169c067enmittler } 11071864f965419c5b14ac9317c576c8a0f7169c067enmittler } 11081864f965419c5b14ac9317c576c8a0f7169c067enmittler continue; 11091864f965419c5b14ac9317c576c8a0f7169c067enmittler } 11101864f965419c5b14ac9317c576c8a0f7169c067enmittler out.println("\tunknown entry type"); 11111864f965419c5b14ac9317c576c8a0f7169c067enmittler } 11121864f965419c5b14ac9317c576c8a0f7169c067enmittler } 11131864f965419c5b14ac9317c576c8a0f7169c067enmittler 11141864f965419c5b14ac9317c576c8a0f7169c067enmittler public static void assertChainLength(Object[] chain) { 11151864f965419c5b14ac9317c576c8a0f7169c067enmittler /* 11161864f965419c5b14ac9317c576c8a0f7169c067enmittler * Note chain is Object[] to support both 11171864f965419c5b14ac9317c576c8a0f7169c067enmittler * java.security.cert.X509Certificate and 11181864f965419c5b14ac9317c576c8a0f7169c067enmittler * javax.security.cert.X509Certificate 11191864f965419c5b14ac9317c576c8a0f7169c067enmittler */ 11201864f965419c5b14ac9317c576c8a0f7169c067enmittler assertEquals(3, chain.length); 11211864f965419c5b14ac9317c576c8a0f7169c067enmittler } 11221864f965419c5b14ac9317c576c8a0f7169c067enmittler} 1123