--- old/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java 2020-06-09 18:21:04.139482000 +0200 +++ new/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java 2020-06-09 18:21:03.202481000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,7 @@ /** * @test * @bug 6714842 - * @library ../../../testlibrary - * @build CertUtils + * @library /test/lib * @run main/othervm BuildEEBasicConstraints * @summary make sure a PKIX CertPathBuilder builds a path to an * end entity certificate when the setBasicConstraints method of the @@ -49,6 +48,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import jdk.test.lib.security.CertUtils; public final class BuildEEBasicConstraints { --- old/test/jdk/java/security/cert/X509CRL/VerifyDefault.java 2020-06-09 18:21:07.667533000 +0200 +++ new/test/jdk/java/security/cert/X509CRL/VerifyDefault.java 2020-06-09 18:21:06.623530000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test * @bug 8175029 - * @library ../../testlibrary + * @library /test/lib * @summary check that default implementation of * X509CRL.verify(PublicKey, Provider) works on custom X509CRL impl. */ @@ -44,6 +44,7 @@ import java.security.cert.X509CRLEntry; import java.util.Date; import java.util.Set; +import jdk.test.lib.security.CertUtils; public class VerifyDefault { private static final String TEST_CRL = --- old/test/jdk/java/security/cert/X509Certificate/VerifyDefault.java 2020-06-09 18:21:11.274356000 +0200 +++ new/test/jdk/java/security/cert/X509Certificate/VerifyDefault.java 2020-06-09 18:21:10.365350000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test * @bug 8175029 - * @library ../../testlibrary + * @library /test/lib * @summary check that default implementation of * X509Certificate.verify(PublicKey, Provider) works on custom * X509Certificate impl. @@ -47,6 +47,7 @@ import java.util.Date; import java.util.List; import java.util.Set; +import jdk.test.lib.security.CertUtils; public class VerifyDefault { private static final String TEST_CERT = --- old/test/jdk/javax/net/ssl/DTLS/CipherSuite.java 2020-06-09 18:21:14.808412000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/CipherSuite.java 2020-06-09 18:21:13.844386000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util * jdk.crypto.ec + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA * @run main/othervm CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 --- old/test/jdk/javax/net/ssl/DTLS/ClientAuth.java 2020-06-09 18:21:18.719326000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/ClientAuth.java 2020-06-09 18:21:17.766308000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm ClientAuth */ --- old/test/jdk/javax/net/ssl/DTLS/DTLSOverDatagram.java 2020-06-09 18:21:22.094302000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/DTLSOverDatagram.java 2020-06-09 18:21:21.189320000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,16 +29,18 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @run main/othervm DTLSOverDatagram */ -import java.io.*; import java.nio.*; import java.net.*; import java.util.*; -import java.security.*; -import java.security.cert.*; import javax.net.ssl.*; + +import jdk.test.lib.security.KeyStoreUtils; +import jdk.test.lib.security.SSLContextBuilder; + import java.util.concurrent.*; import sun.security.util.HexDumpEncoder; @@ -60,7 +62,6 @@ private static String pathToStores = "../etc"; private static String keyStoreFile = "keystore"; private static String trustStoreFile = "truststore"; - private static String passwd = "passphrase"; private static String keyFilename = System.getProperty("test.src", ".") + "/" + pathToStores + @@ -537,30 +538,13 @@ // get DTSL context SSLContext getDTLSContext() throws Exception { - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); - - char[] passphrase = "passphrase".toCharArray(); - - try (FileInputStream fis = new FileInputStream(keyFilename)) { - ks.load(fis, passphrase); - } - - try (FileInputStream fis = new FileInputStream(trustFilename)) { - ts.load(fis, passphrase); - } - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, passphrase); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ts); - - SSLContext sslCtx = SSLContext.getInstance("DTLS"); - - sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - - return sslCtx; + String passphrase = "passphrase"; + return SSLContextBuilder.builder() + .trustStore(KeyStoreUtils.loadKeyStore(trustFilename, passphrase)) + .keyStore(KeyStoreUtils.loadKeyStore(keyFilename, passphrase)) + .kmfPassphrase(passphrase) + .protocol("DTLS") + .build(); } --- old/test/jdk/javax/net/ssl/DTLS/InvalidCookie.java 2020-06-09 18:21:25.317314000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/InvalidCookie.java 2020-06-09 18:21:24.343320000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm InvalidCookie */ --- old/test/jdk/javax/net/ssl/DTLS/InvalidRecords.java 2020-06-09 18:21:28.659364000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/InvalidRecords.java 2020-06-09 18:21:27.722388000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm InvalidRecords */ --- old/test/jdk/javax/net/ssl/DTLS/NoMacInitialClientHello.java 2020-06-09 18:21:32.159461000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/NoMacInitialClientHello.java 2020-06-09 18:21:31.132449000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm -Djdk.tls.client.enableStatusRequestExtension=false * NoMacInitialClientHello --- old/test/jdk/javax/net/ssl/DTLS/PacketLossRetransmission.java 2020-06-09 18:21:35.547481000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/PacketLossRetransmission.java 2020-06-09 18:21:34.604478000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8161086 * @summary DTLS handshaking fails if some messages were lost * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * * @run main/othervm PacketLossRetransmission client 0 hello_request --- old/test/jdk/javax/net/ssl/DTLS/Reordered.java 2020-06-09 18:21:39.364564000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/Reordered.java 2020-06-09 18:21:37.927559000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm Reordered */ --- old/test/jdk/javax/net/ssl/DTLS/RespondToRetransmit.java 2020-06-09 18:21:42.943321000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/RespondToRetransmit.java 2020-06-09 18:21:41.977338000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8161086 * @summary DTLS handshaking fails if some messages were lost * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * * @run main/othervm RespondToRetransmit client 0 hello_request --- old/test/jdk/javax/net/ssl/DTLS/Retransmission.java 2020-06-09 18:21:46.342304000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/Retransmission.java 2020-06-09 18:21:45.393384000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm Retransmission */ --- old/test/jdk/javax/net/ssl/DTLS/WeakCipherSuite.java 2020-06-09 18:21:49.973311000 +0200 +++ new/test/jdk/javax/net/ssl/DTLS/WeakCipherSuite.java 2020-06-09 18:21:48.875312000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @bug 8043758 * @summary Datagram Transport Layer Security (DTLS) * @modules java.base/sun.security.util + * @library /test/lib * @build DTLSOverDatagram * @run main/othervm WeakCipherSuite TLS_DH_anon_WITH_AES_128_GCM_SHA256 * @run main/othervm WeakCipherSuite SSL_DH_anon_WITH_DES_CBC_SHA --- old/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java 2020-06-09 18:21:53.745320000 +0200 +++ new/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java 2020-06-09 18:21:52.711325000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ import jdk.test.lib.SecurityTools; +import jdk.test.lib.security.CertUtils; import java.security.KeyStore; @@ -30,7 +31,6 @@ * @bug 6415696 6931562 8180570 * @requires os.family == "windows" * @library /test/lib - * @library /test/jdk/java/security/testlibrary * @summary Test "keytool -changealias" using the Microsoft CryptoAPI provider. */ public class KeytoolChangeAlias { --- old/test/jdk/sun/security/util/HostnameMatcher/NullHostnameCheck.java 2020-06-09 18:21:57.301357000 +0200 +++ new/test/jdk/sun/security/util/HostnameMatcher/NullHostnameCheck.java 2020-06-09 18:21:56.393315000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,10 @@ * questions. */ -import javax.net.ssl.KeyManagerFactory; +import java.nio.ByteBuffer; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; @@ -30,18 +33,16 @@ import javax.net.ssl.SSLParameters; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import java.io.ByteArrayInputStream; -import java.nio.ByteBuffer; -import java.security.KeyStore; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Base64; + +import jdk.test.lib.security.KeyStoreUtils; +import jdk.test.lib.security.SSLContextBuilder; /* * @test * @bug 8211339 8234728 * @summary Verify hostname returns an exception instead of null pointer when * creating a new engine + * @library /test/lib * @run main NullHostnameCheck TLSv1 * @run main NullHostnameCheck TLSv1.1 * @run main NullHostnameCheck TLSv1.2 @@ -53,16 +54,13 @@ public static void main(String[] args) throws Exception { String protocol = args[0]; - KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - keyStore.load( - new ByteArrayInputStream(Base64.getDecoder(). - decode(keystoreB64)), - "123456".toCharArray()); - KeyManagerFactory kmf = KeyManagerFactory.getInstance( - KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(keyStore, "123456".toCharArray()); - SSLContext serverCtx = SSLContext.getInstance(protocol); - serverCtx.init(kmf.getKeyManagers(), null, null); + String password = "123456"; + SSLContext serverCtx = SSLContextBuilder.builder() + .keyStore(KeyStoreUtils.loadKeyStoreBase64( + keystoreB64, password)) + .kmfPassphrase(password) + .protocol(protocol) + .build(); SSLEngine serverEngine = serverCtx.createSSLEngine("localhost", -1); serverEngine.setUseClientMode(false); @@ -71,12 +69,12 @@ new X509TrustManager() { @Override public void checkClientTrusted( - X509Certificate[] x509Certificates, String s) { + X509Certificate[] x509Certificates, String s) { } @Override public void checkServerTrusted( - X509Certificate[] x509Certificates, String s) { + X509Certificate[] x509Certificates, String s) { } @Override --- old/test/jdk/sun/security/util/HostnameMatcher/TestHostnameChecker.java 2020-06-09 18:22:00.572377000 +0200 +++ new/test/jdk/sun/security/util/HostnameMatcher/TestHostnameChecker.java 2020-06-09 18:21:59.620377000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,13 @@ * @test * @bug 4514108 * @summary Verify host name matching behaves as defined in RFC2818. + * @library /test/lib * @modules java.base/sun.security.util */ -import java.io.*; import java.security.cert.*; +import jdk.test.lib.security.CertUtils; import sun.security.util.*; /** @@ -172,28 +173,15 @@ public class TestHostnameChecker { - private final static String PATH = System.getProperty("test.src", "."); - public static void main(String[] args) throws Exception { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - InputStream in = new FileInputStream(new File(PATH, "cert1.crt")); - X509Certificate cert1 = (X509Certificate)cf.generateCertificate(in); - in.close(); - in = new FileInputStream(new File(PATH, "cert2.crt")); - X509Certificate cert2 = (X509Certificate)cf.generateCertificate(in); - in.close(); - in = new FileInputStream(new File(PATH, "cert3.crt")); - X509Certificate cert3 = (X509Certificate)cf.generateCertificate(in); - in.close(); - in = new FileInputStream(new File(PATH, "cert4.crt")); - X509Certificate cert4 = (X509Certificate)cf.generateCertificate(in); - in.close(); - in = new FileInputStream(new File(PATH, "cert5.crt")); - X509Certificate cert5 = (X509Certificate)cf.generateCertificate(in); - in.close(); + X509Certificate cert1 = CertUtils.getCertFromFile("cert1.crt"); + X509Certificate cert2 = CertUtils.getCertFromFile("cert2.crt"); + X509Certificate cert3 = CertUtils.getCertFromFile("cert3.crt"); + X509Certificate cert4 = CertUtils.getCertFromFile("cert4.crt"); + X509Certificate cert5 = CertUtils.getCertFromFile("cert5.crt"); HostnameChecker checker = HostnameChecker.getInstance( - HostnameChecker.TYPE_TLS); + HostnameChecker.TYPE_TLS); System.out.println("TLS tests........."); System.out.println("=================="); check(checker, "foo1.com", cert1, true); --- /dev/null 2020-02-29 14:22:47.584405148 +0100 +++ new/test/lib/jdk/test/lib/security/CertUtils.java 2020-06-09 18:22:03.179409000 +0200 @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * + * @author Sean Mullan + * @author Steve Hanna + * + */ + +package jdk.test.lib.security; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CRLException; +import java.security.cert.CertPath; +import java.security.cert.CertPathBuilder; +import java.security.cert.CertPathValidator; +import java.security.cert.CertStore; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.CollectionCertStoreParameters; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.PKIXCertPathBuilderResult; +import java.security.cert.PKIXCertPathValidatorResult; +import java.security.cert.PKIXParameters; +import java.security.cert.X509CRL; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Static utility methods useful for testing certificate/certpath APIs. + */ +public class CertUtils { + + private CertUtils() {} + + /* + * Version: 3 (0x2) + * Serial Number: + * 7b:bb:a0:55:00:9d:69:16:1e:cb:e2:ad:25:d1:32:ff:fa:52:1b:05 + * Signature Algorithm: sha256WithRSAEncryption + * Issuer: CN = localhost + * Validity + * Not Before: Aug 1 11:58:25 2019 GMT + * Not After : Jul 29 11:58:25 2029 GMT + * Subject: CN = localhost + */ + public static final String RSA_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDCTCCAfGgAwIBAgIUe7ugVQCdaRYey+KtJdEy//pSGwUwDQYJKoZIhvcNAQEL\n" + + "BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MDgwMTExNTgyNVoXDTI5MDcy\n" + + "OTExNTgyNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\n" + + "AAOCAQ8AMIIBCgKCAQEAxDGfn+GQEErnE1ErBaYpH8+rFgUS/nhFuaKLMNsYMtAY\n" + + "GI7XvnwzSMeYou6tDobi0WMxlnQRSlVEmmT6OPOOC9RLnt2qdU2klXVR5DCzVTrp\n" + + "wX5TILkP+KzePRQFrpi4z6Fx15cIVhP4OdPUd4rwAffD+nYaijQezLuKwdBKBHlt\n" + + "GBGxn978Ppcmx/6qAfFZjhtxJXBM7LzUPkDs6jHy10FK9KkqjmmB6zXM0Rvv8nN3\n" + + "9o55H3LnbO4XSIoRUGwSISSiHEBHbOZyBblDc0yoRAnjqxSDIj5oxessfDt5gG6C\n" + + "LqrUyfLDo7pbmQrdBoH2NEX9yScYVE1MnlRA6LusCQIDAQABo1MwUTAdBgNVHQ4E\n" + + "FgQUbZzwnSvM67UCB3ng5fTGcL24uqUwHwYDVR0jBBgwFoAUbZzwnSvM67UCB3ng\n" + + "5fTGcL24uqUwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAgAtI\n" + + "feN7JySd5HdEqA0/vvCCoBJ/Z9//3OxQyW8NnkmVW3F1eMIWII/vOdYj1WJgq1uK\n" + + "a4GKiUVgEYTVSJxwj3mBmvd9o93Im9BSI0RkGOQOTnCLJNTksAD+2qO4F984xucS\n" + + "/R2BChlbik7+7uPZ7qnhfDmxyMJqtUuze/JkA4IrVssbFM30j70gGjNNd/waBsR2\n" + + "upI29x7LSCdPkXmwUuzUR5/zBHaR4pZ2nQvsfxoP384BvpM1SCNrBUGvxGzDDiGA\n" + + "pOJwIJoTEU7gGaHF8BeEUtC1YbSDWr+dN4IM7uzL6sdVs8xPVxkeptlVU7cDIyiN\n" + + "DPm3K0U4oj/KoFfMHg==\n" + + "-----END CERTIFICATE-----"; + public static final String RSA_KEY = + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEMZ+f4ZAQSucT\n" + + "USsFpikfz6sWBRL+eEW5oosw2xgy0BgYjte+fDNIx5ii7q0OhuLRYzGWdBFKVUSa\n" + + "ZPo4844L1Eue3ap1TaSVdVHkMLNVOunBflMguQ/4rN49FAWumLjPoXHXlwhWE/g5\n" + + "09R3ivAB98P6dhqKNB7Mu4rB0EoEeW0YEbGf3vw+lybH/qoB8VmOG3ElcEzsvNQ+\n" + + "QOzqMfLXQUr0qSqOaYHrNczRG+/yc3f2jnkfcuds7hdIihFQbBIhJKIcQEds5nIF\n" + + "uUNzTKhECeOrFIMiPmjF6yx8O3mAboIuqtTJ8sOjuluZCt0GgfY0Rf3JJxhUTUye\n" + + "VEDou6wJAgMBAAECggEAFwYn0HB9IpxXr9mnrdsJGnWZg1UHHJvqutVLdmlP1q67\n" + + "FS62POGAdzsNO5m872Z++cmlSR3H5axKB8Bv6P0UH2lDkpo65dc9yFhjSt84PHlU\n" + + "c2Oqx71QFYPb9NkDrbC4h41Pudg8nzVqvQaR+ZFxhxmXgy4XAT8KmkYsC4CxHwMY\n" + + "FYCHsNc8kpyXc7P5bbjpdQHMwpBP3dyo42h8cim8P2c5pKM0ipSm4vD9r8NIbvG7\n" + + "+bzLBC0aJCfL0wY2c8qRD2k5Xl/NRKovya8v6IUCyigyJV5DZMOfRqCMDeMuiaxl\n" + + "cvKqIPO5wxE3Wt36cEPZGO6GI6H+tzXZT0+y0+OfXQKBgQD5kR2GscpFhc+/A9Qn\n" + + "QQxeMHjDqXUjP11Czg+/K2vKjC+RHNIzOh+4jGWNb9nlMSu22IRltRzyDOrPRytB\n" + + "RT2o5rUGSv/oZ/lEMMyHz+xPaBfegYSCkZ3h01iL1fdAUALHtzG5c6S8JXhtWzHk\n" + + "q/dk6iXPfTtSREBkwv7c43vXTwKBgQDJQE0ZvgTSnscA+GkM1R7tH0hqKyk/xeus\n" + + "/xu23EraiIg4qoJ7Lk2IRvOkgotuK/SK+qoWlBr3OwBRzByxBXSdjdciZ5jbOc1g\n" + + "TA4Qwma6R9ukYdW+W95nYmsgyOi0+7tX9oVJatBJGyq3atayUANy8Lun4kSRdurn\n" + + "WibRxuxxJwKBgQCq62vhV9pECwTguWqPB8nEqEXNGz2SSk9A9YdrUf2c1q2tIKQF\n" + + "WYVoCx9x4mzEvwxFSbxDO+r7C0W1d/Rz20wDZR4NlUf2j170CMfLK+eX6p6OUP3D\n" + + "vp72jpxSCNQxQ5rj1N9FN6JXCQKVQqPFDNF+V65VkFsUWJIRcErEVTf3mQKBgAiW\n" + + "AbQTc0k5FOxprLGrdgJPz1sYNE5QN1nOGHSYuWjRYl5oh+CRfSVPQZ3HJAOzRF+Z\n" + + "iiAkeXIKxly3BJJY1TzTjFYfbVoNAUIWfJMieBeCcVB2DBRu/vISNNfVOnheNQPv\n" + + "tIgJUpGL4yqoGDjLSRpiQt9Ku/ooxKTSJ83TWssJAoGAflsMfkS9hdoAcWMUWkPU\n" + + "VMTP/yHshZKJK66uAtLJYvSLXMJAN4uCIobiPM0EsdLxTh1nrL36NmWsTZlMhMsS\n" + + "rPaBIT6f6m2M2+8ixiJoZ1ut2iyKxkkvWcECbXqjWw6ndGyAoL1/7OR5guJliePy\n" + + "axFzqDc4QQBTtrjLYuHGi9k="; + + /* + * Version: 3 (0x2) + * Serial Number: + * 3c:09:6b:31:d7:7c:00:93:b2:79:54:f9:c2:3c:d2:dd:76:56:f0:50 + * Signature Algorithm: ecdsa-with-SHA256 + * Issuer: CN = localhost + * Validity + * Not Before: Aug 1 11:58:34 2019 GMT + * Not After : Jul 29 11:58:34 2029 GMT + * Subject: CN = localhost + */ + public static final String ECDSA_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBfjCCASOgAwIBAgIUPAlrMdd8AJOyeVT5wjzS3XZW8FAwCgYIKoZIzj0EAwIw\n" + + "FDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MDgwMTExNTgzNFoXDTI5MDcyOTEx\n" + + "NTgzNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" + + "AQcDQgAEs8ThmP8Xi9aBkB3WPfHRflpk6u44/9NIH4IiRSmbB7jmgCH3rP50izNR\n" + + "va4fKIZUJ0vPCS9zBr4rKVco9Z6qV6NTMFEwHQYDVR0OBBYEFFgf2AXMfO1OpBul\n" + + "ArF1gqmVA04YMB8GA1UdIwQYMBaAFFgf2AXMfO1OpBulArF1gqmVA04YMA8GA1Ud\n" + + "EwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAKWR1yXjBedp6hOoxvZ8n9e8\n" + + "k2ZPdboTfyIRvCw9O4BUAiEAuHsWWs34c3xPCxsyoxbpgkBLwdZ1pZASbCMbgZ59\n" + + "RYo=\n" + + "-----END CERTIFICATE-----"; + public static final String ECDSA_KEY = + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgajTO2cTGJdOUawrQ\n" + + "XqGfGuX6AEevTXQY0hlVHAVx516hRANCAASzxOGY/xeL1oGQHdY98dF+WmTq7jj/\n" + + "00gfgiJFKZsHuOaAIfes/nSLM1G9rh8ohlQnS88JL3MGvispVyj1nqpX"; + + /* + * Version: 3 (0x2) + Serial Number: + 76:07:da:cb:0f:8a:89:26:72:cb:db:20:ec:df:b2:52:50:01:6a:56 + Signature Algorithm: rsassaPss + Hash Algorithm: sha256 + Mask Algorithm: mgf1 with sha256 + Salt Length: 0xDE + Trailer Field: 0xBC (default) + Issuer: CN = localhost + Validity + Not Before: Aug 1 11:58:40 2019 GMT + Not After : Jul 29 11:58:40 2029 GMT + Subject: CN = localhost + */ + public static final String RSASSAPSS_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDaTCCAiCgAwIBAgIUdgfayw+KiSZyy9sg7N+yUlABalYwPgYJKoZIhvcNAQEK\n" + + "MDGgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQC\n" + + "AgDeMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xOTA4MDExMTU4NDBaFw0yOTA3\n" + + "MjkxMTU4NDBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASAwCwYJKoZIhvcNAQEK\n" + + "A4IBDwAwggEKAoIBAQC5igqwiTdawCKIDmGVXAnYSIj5QIiMW4VzeWj87+bWqMec\n" + + "9uiOkFBI9c1y3CMoAPu9SEBbycAMadExB0pRq93Kz7pO30nyOFwDhvnArqg0e+mn\n" + + "6yaJeYWkQFX0HNS/vBwlVPLSkyuE80Tt1bND7ur4z31hT6H16nDBfx14b9aXW9j0\n" + + "L2zqZbyq4jhbELeBK0DtD1tpmJsYHxXjL174fDQ0dArNjIq529veS9z+FjdpuZTm\n" + + "e3XxOyWofA0EV4t3wN7x5RvI0pTo7Na+15TjTlhwHTuaiUPsOvMg73sI+3OxXGHI\n" + + "GDoOgqliYqHH0SkTYWpZF9Be3Th/R90Qg7Pvzo4HAgMBAAGjUzBRMB0GA1UdDgQW\n" + + "BBRQAfLTSK6mt9aKxrWbHUKsKwrBfDAfBgNVHSMEGDAWgBRQAfLTSK6mt9aKxrWb\n" + + "HUKsKwrBfDAPBgNVHRMBAf8EBTADAQH/MD4GCSqGSIb3DQEBCjAxoA0wCwYJYIZI\n" + + "AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIEAgIA3gOCAQEAQPJz\n" + + "TGugNS+wmxe6BGHmWLLsRJAQn/lr+3dJIfkfBlmkc43tSdL5R+5LfkNjE7sCUW4s\n" + + "FFKVlQH8XzHbJH0USNp+yxJBjBv5XpXW+mrhGhCBiIoEXce78irNJLy6dJPIFo/m\n" + + "z4Lt2YS5VassInrBvb9KyNlinpqJ5sjptLM2Nc77Rv/uFOkgTNwyuAi+LYuP1lEm\n" + + "4AZcywjfxBv/mmuZ8oAgPj50cN0gsgQmi/bofiZsK4GrZpSncjMYZvG/C4WF2Zem\n" + + "cd7KZtQoPrv3bSE3gyotN04wE2nFLsaR2gheuv0URitDPAzpv8QV3WjEUt6uaFZi\n" + + "K6deQ/N/JiwhoqjM+Q==\n" + + "-----END CERTIFICATE-----"; + public static final String RSASSAPSS_KEY = + "MIIEuwIBADALBgkqhkiG9w0BAQoEggSnMIIEowIBAAKCAQEAuYoKsIk3WsAiiA5h\n" + + "lVwJ2EiI+UCIjFuFc3lo/O/m1qjHnPbojpBQSPXNctwjKAD7vUhAW8nADGnRMQdK\n" + + "Uavdys+6Tt9J8jhcA4b5wK6oNHvpp+smiXmFpEBV9BzUv7wcJVTy0pMrhPNE7dWz\n" + + "Q+7q+M99YU+h9epwwX8deG/Wl1vY9C9s6mW8quI4WxC3gStA7Q9baZibGB8V4y9e\n" + + "+Hw0NHQKzYyKudvb3kvc/hY3abmU5nt18TslqHwNBFeLd8De8eUbyNKU6OzWvteU\n" + + "405YcB07molD7DrzIO97CPtzsVxhyBg6DoKpYmKhx9EpE2FqWRfQXt04f0fdEIOz\n" + + "786OBwIDAQABAoIBAH4eO03st9fUKqTZQbPJMFf4VkM3fpoJzBjGOntUh1D6wVUM\n" + + "8N+XcTtm+hRNVwhmQrhTWIwMA6NsemodToNdlBG8SiQ624Tukn1DTpmPH38ti5I8\n" + + "4aEpHZKcuNCKmIMMVwV5TOWebEKfKgeQ754J1Wbzg4KWIr2KcsLUqS+otfGDsOMK\n" + + "nuIhFQhamtNFzuWSRIYJl5jfNcnXmeTivVNywE0Q/PGD3lLn8xB3Bk6uNTAUFBdc\n" + + "nbK7efViSfuNY+kZbHne+mcSGiBJPSzTfd25+/JhYaKFjPiQsIqPAwnZK80LBdeb\n" + + "lxf3zSzpgbx9Jai+kULZJsrVoReZlS6fxeqzZAECgYEA4jRcR6tEQGImsIT7zBTS\n" + + "FYTsqr0wzuUl2m3mNNQX9ZIKEVJxv9Vevyd4eQIwQRwgPM2U2JLsXPjVFc/fCAJO\n" + + "KuLY5sXog4b0c8cHjA8nbJbmjKHkXfgCnKFGoXvUV13LgFg9DX6hzkCKMJxDO9R+\n" + + "pE9k6HXq58yyDvRBvFOCuYECgYEA0fpxa0gwCmyMKQeFnBPd53rnPOBoW2YKnIzR\n" + + "/X1q6YRFdeRgvcBXScPknU1nvoxAtRqHYDSI3d/sHMzZ+qb0BBoD7i2qjKsSH32u\n" + + "jP5m5+psPebJ0UEH/bTUbETWEu9rt8sapag6Mp1QL6uYZW5OOULCpGYa9KcfX93A\n" + + "hwgeO4cCgYBy+mptg4CNuVYxI2dZtLuUdJxXrRLCF3fGL1Z0Q9pp2HGFnIJ1H9+p\n" + + "CkcSOyqL7d/1CApAi23ZVCH7lE2ppIJXCjd2FeK5+D8JGoGbj5haedl2YlPR795j\n" + + "/xYHvwmP3v0xn6ho05UrYWLckpEaOEim/DQudMGSUVmwgDdpookwAQKBgQCv6RhL\n" + + "wFY+5WEmnl6YuywUWSqQHZBPwdTyAieKLh/7MgzfD0zcqt51td84yTg4slcjYe43\n" + + "8ssW1hmApz2Wd3fGV+UjDK7s2gR8zVYGWLrtX77+vPImlEyVh4DOk3yksF+Vwlm4\n" + + "no7jCFe9GAy8LQTrg7p87+11OO1X6vb4KRzq0QKBgCZD8lN/qHpscBQucx60vToU\n" + + "247vlb9LmzsMFVUeyJhg/v1+1kswIImuYC+X0nO8yF++mD8OyWIZaXZAkmEsU9qF\n" + + "ZCdo4KHSmFTKm6mCPW+5tro3GCsavRZqFHeQF8iVRsN3V86q6wRlMvyYmKMLd0Ko\n" + + "0CyaEnQ+kBtL6IaeVNQV"; + + /* + * Version: 3 (0x2) + * Serial Number: + * 49:33:8a:a8:cd:d9:14:f8:09:a1:0c:2f:67:a3:27:a6:fc:df:25:f8 + * Signature Algorithm: dsa_with_SHA256 + * Issuer: CN = localhost + * Validity + * Not Before: Aug 1 12:01:30 2019 GMT + * Not After : Jul 27 12:01:30 2039 GMT + * Subject: CN = localhost + */ + public static final String DSA_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "MIIEbzCCBBSgAwIBAgIUSTOKqM3ZFPgJoQwvZ6MnpvzfJfgwCwYJYIZIAWUDBAMC\n" + + "MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xOTA4MDExMjAxMzBaFw0zOTA3Mjcx\n" + + "MjAxMzBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCA0cwggI5BgcqhkjOOAQBMIIC\n" + + "LAKCAQEAsFMaoryk333Vm0JY8QEu1y0HmQkvp5dlM/4ozMj8l6hx8HYo+LYTQD4e\n" + + "t7b7xUf5sYc4mjxpwbV4uf8Q4G1BHfJCGdGKxKigObsbDqpRRBlubHppOX6F6mRz\n" + + "wgaNRfWqlZbcSa+X82SfagtjMVKrH75eIs74U7EBQRun7XilrDFKuG6c98cY1JFI\n" + + "BpAp/Sw+kEk0LYYgdGIVWhNCunECcqWtdz1AEBzHOiqEthKTzF+o1qxBFCYjOnZo\n" + + "wkgG5fqXDc4Rb0iNyxSQXK/lTi/4r6IABY3u7f5NOhj0GmRbbCA/Ef0i6GQKJqzk\n" + + "hfzTQDwRsvX17xLFTOeNQb26dvm23wIhAL6RNExpfF++/0Ph4mkPqxuDLHWACa/y\n" + + "3VeNr8NjO7ovAoIBABndio/73FVBpnpbFdT1DnqY3IWUbpr40zudROuGWvSd66Ia\n" + + "pNtRb/fcgMm3UjAq92SjbF+Rn+gf1ylm1LCtE4xeN02gxCJnR9/HKmuSTDnVOH5F\n" + + "62yjQaEPZ7rG2cr7fP67YiW1b3nTQSL11y62MVvp+JH1BMVd4gYMop7wG8eRajFr\n" + + "hW3AY6dz5J2w6fywvZTIXzv1cZS7be1adcdYSvkFs9V6bT+lQHKNpqM8aab61Kp9\n" + + "aB3+p39nKYm6KPpc/wuSHs5Ez5C89mLrHB4l6xZAMAWqwkDnUmiRScwfyOIKG8VY\n" + + "2c9GtfZOCB21dupwXGruFH1tcg5IP7wHJddOWCADggEGAAKCAQEAkrNcrwgXKVWc\n" + + "gwv4CAJhRAH0svQChcLI1I5+6FB8KomN4xVW+obJcNag3qbTCd3V3mHu6gITxxkq\n" + + "EoA2zCBQFMAIGW2G1PkqOlBK8K3hOut/IEbWmiMlC51P0AUHBd1NDCY6q96Y+mot\n" + + "ogGc3lMQZK5mWseUirP6Qt43N7Ev57PXypKC5MnQKA2+NEhhiHvDruSBloj9zu+w\n" + + "oNhXZP+0dPBb96eeHwcRj25MSuhY+Jpg2OoU+FzDvx7QDEqkq801EBdr9WOiY9hx\n" + + "DpbUZH3mLYo9tzBwDK8RngPlcwlMpuR/A3pu6qLAGJHnVWb1c9mhNHv+8p5to74k\n" + + "2RqOaSU26aNTMFEwHQYDVR0OBBYEFJ8MbprhtUOkVraW76QALKQnZ6yNMB8GA1Ud\n" + + "IwQYMBaAFJ8MbprhtUOkVraW76QALKQnZ6yNMA8GA1UdEwEB/wQFMAMBAf8wCwYJ\n" + + "YIZIAWUDBAMCA0gAMEUCIHaOTmgo0rK4EWGLruxLiTcHZs1KanLrf9FlKbmur9Ee\n" + + "AiEAnE+fxuTBexuPj2elmnxViUj/UYo/NlC4OarhIO1SCzk=\n" + + "-----END CERTIFICATE-----"; + public static final String DSA_KEY = + "MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQCwUxqivKTffdWbQljxAS7XLQeZ\n" + + "CS+nl2Uz/ijMyPyXqHHwdij4thNAPh63tvvFR/mxhziaPGnBtXi5/xDgbUEd8kIZ\n" + + "0YrEqKA5uxsOqlFEGW5semk5foXqZHPCBo1F9aqVltxJr5fzZJ9qC2MxUqsfvl4i\n" + + "zvhTsQFBG6fteKWsMUq4bpz3xxjUkUgGkCn9LD6QSTQthiB0YhVaE0K6cQJypa13\n" + + "PUAQHMc6KoS2EpPMX6jWrEEUJiM6dmjCSAbl+pcNzhFvSI3LFJBcr+VOL/ivogAF\n" + + "je7t/k06GPQaZFtsID8R/SLoZAomrOSF/NNAPBGy9fXvEsVM541Bvbp2+bbfAiEA\n" + + "vpE0TGl8X77/Q+HiaQ+rG4MsdYAJr/LdV42vw2M7ui8CggEAGd2Kj/vcVUGmelsV\n" + + "1PUOepjchZRumvjTO51E64Za9J3rohqk21Fv99yAybdSMCr3ZKNsX5Gf6B/XKWbU\n" + + "sK0TjF43TaDEImdH38cqa5JMOdU4fkXrbKNBoQ9nusbZyvt8/rtiJbVvedNBIvXX\n" + + "LrYxW+n4kfUExV3iBgyinvAbx5FqMWuFbcBjp3PknbDp/LC9lMhfO/VxlLtt7Vp1\n" + + "x1hK+QWz1XptP6VAco2mozxppvrUqn1oHf6nf2cpiboo+lz/C5IezkTPkLz2Yusc\n" + + "HiXrFkAwBarCQOdSaJFJzB/I4gobxVjZz0a19k4IHbV26nBcau4UfW1yDkg/vAcl\n" + + "105YIAQjAiEAvP+ZQ7yzUk8rNgk65U/SF++Eyt+i+WR1UBvGxAEEKIQ="; + + private static final String TEST_SRC = System.getProperty("test.src", "."); + + /** + * Get a PEM-encoded PKCS8 private key from a string. + * + * @param keyAlgo the key algorithm + * @param keyStr string containing the PEM-encoded PKCS8 private key + * @return the private key + * @throws NoSuchAlgorithmException if no Provider supports a KeyFactorySpi + * implementation for the specified algorithm + * @throws InvalidKeySpecException if the given key specification is + * inappropriate for this key factory to produce a private key. + */ + public static PrivateKey getKeyFromString(String keyAlgo, String keyStr) + throws NoSuchAlgorithmException, InvalidKeySpecException { + KeyFactory keyFactory = KeyFactory.getInstance(keyAlgo); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder().decode(keyStr)); + PrivateKey key = keyFactory.generatePrivate(keySpec); + return key; + } + + /** + * Get a PEM-encoded PKCS8 private key from a file. + * + * @param keyAlgo the key algorithm + * @param keyPath path to file containing the PEM-encoded PKCS8 private key + * @return the private key + * @throws NoSuchAlgorithmException if no Provider supports a KeyFactorySpi + * implementation for the specified algorithm + * @throws InvalidKeySpecException if the given key specification is + * inappropriate for this key factory to produce a private key. + */ + public static PrivateKey getKeyFromFile(String keyAlgo, String keyPath) + throws NoSuchAlgorithmException, InvalidKeySpecException { + return getKeyFromString( + keyAlgo, + + // Filter the below lines if any + // -----BEGIN PRIVATE KEY----- + // -----END PRIVATE KEY----- + readFile(keyPath, line -> !line.startsWith("-----"))); + } + + /** + * Get an X.509 certificate from an input stream. + * + * @param input an input stream with the certificate data. + * @return the X509Certificate + * @throws CertificateException on parsing errors. + * @throws IOException on input stream errors. + */ + public static X509Certificate getCertFromStream(InputStream input) + throws CertificateException, IOException { + try { + CertificateFactory certFactory + = CertificateFactory.getInstance("X.509"); + return (X509Certificate) certFactory.generateCertificate(input); + } finally { + if (input != null) { + input.close(); + } + } + } + + /** + * Get a PEM-encoded X.509 certificate from a string. + * + * @param cert string containing the PEM-encoded certificate + * @return the X509Certificate + * @throws CertificateException if the certificate type is not supported + * or cannot be parsed + * @throws IOException + */ + public static X509Certificate getCertFromString(String certStr) + throws CertificateException, IOException { + return getCertFromStream(new ByteArrayInputStream(certStr.getBytes())); + } + + /** + * Get a X.509 certificate from a file. + * + * @param certFilePath path to file containing certificate + * @return the X509Certificate + * @throws CertificateException if the certificate type is not supported + * or cannot be parsed + * @throws IOException if the file cannot be opened + */ + public static X509Certificate getCertFromFile(String certFilePath) + throws CertificateException, IOException { + return getCertFromStream( + Files.newInputStream(Paths.get(TEST_SRC, certFilePath))); + } + + /** + * Get a DER-encoded X.509 CRL from a file. + * + * @param crlFilePath path to file containing DER-encoded CRL + * @return the X509CRL + * @throws CertificateException if the crl type is not supported + * @throws CRLException if the crl cannot be parsed + * @throws IOException if the file cannot be opened + */ + public static X509CRL getCRLFromFile(String crlFilePath) + throws CertificateException, CRLException, IOException { + File crlFile = new File(TEST_SRC, crlFilePath); + try (FileInputStream fis = new FileInputStream(crlFile)) { + return (X509CRL) + CertificateFactory.getInstance("X.509").generateCRL(fis); + } + } + + /** + * Get a PEM-encoded X.509 crl from a string. + * + * @param crl string containing the PEM-encoded crl + * @return the X509CRL + * @throws CertificateException if the crl type is not supported + * @throws CRLException if the crl cannot be parsed + */ + public static X509CRL getCRLFromString(String crl) + throws CertificateException, CRLException { + byte[] crlBytes = crl.getBytes(); + ByteArrayInputStream bais = new ByteArrayInputStream(crlBytes); + return (X509CRL) + CertificateFactory.getInstance("X.509").generateCRL(bais); + } + + /** + * Read a bunch of certs from files and create a CertPath from them. + * + * @param fileNames an array of Strings that are file names + * @throws Exception on error + */ + public static CertPath buildPath(String [] fileNames) throws Exception { + return buildPath("", fileNames); + } + + /** + * Read a bunch of certs from files and create a CertPath from them. + * + * @param relPath relative path containing certs (must end in + * file.separator) + * @param fileNames an array of Strings that are file names + * @throws Exception on error + */ + public static CertPath buildPath(String relPath, String [] fileNames) + throws Exception { + List list = new ArrayList(); + for (int i = 0; i < fileNames.length; i++) { + list.add(0, getCertFromFile(relPath + fileNames[i])); + } + CertificateFactory cf = CertificateFactory.getInstance("X509"); + return(cf.generateCertPath(list)); + } + + + /** + * Read a bunch of certs from files and create a CertStore from them. + * + * @param fileNames an array of Strings that are file names + * @return the CertStore created + * @throws Exception on error + */ + public static CertStore createStore(String [] fileNames) throws Exception { + return createStore("", fileNames); + } + + /** + * Read a bunch of certs from files and create a CertStore from them. + * + * @param relPath relative path containing certs (must end in + * file.separator) + * @param fileNames an array of Strings that are file names + * @return the CertStore created + * @throws Exception on error + */ + public static CertStore createStore(String relPath, String [] fileNames) + throws Exception { + Set certs = new HashSet(); + for (int i = 0; i < fileNames.length; i++) { + certs.add(getCertFromFile(relPath + fileNames[i])); + } + return CertStore.getInstance("Collection", + new CollectionCertStoreParameters(certs)); + } + + /** + * Read a bunch of CRLs from files and create a CertStore from them. + * + * @param fileNames an array of Strings that are file names + * @return the CertStore created + * @throws Exception on error + */ + public static CertStore createCRLStore(String [] fileNames) + throws Exception { + return createCRLStore("", fileNames); + } + + /** + * Read a bunch of CRLs from files and create a CertStore from them. + * + * @param relPath relative path containing CRLs (must end in file.separator) + * @param fileNames an array of Strings that are file names + * @return the CertStore created + * @throws Exception on error + */ + public static CertStore createCRLStore(String relPath, String [] fileNames) + throws Exception { + Set crls = new HashSet(); + for (int i = 0; i < fileNames.length; i++) { + crls.add(getCRLFromFile(relPath + fileNames[i])); + } + return CertStore.getInstance("Collection", + new CollectionCertStoreParameters(crls)); + } + + /** + * Perform a PKIX path build. On failure, throw an exception. + * + * @param params PKIXBuilderParameters to use in validation + * @throws Exception on error + */ + public static PKIXCertPathBuilderResult build(PKIXBuilderParameters params) + throws Exception { + CertPathBuilder builder = + CertPathBuilder.getInstance("PKIX"); + return (PKIXCertPathBuilderResult) builder.build(params); + } + + /** + * Perform a PKIX validation. On failure, throw an exception. + * + * @param path CertPath to validate + * @param params PKIXParameters to use in validation + * @throws Exception on error + */ + public static PKIXCertPathValidatorResult validate + (CertPath path, PKIXParameters params) throws Exception { + CertPathValidator validator = + CertPathValidator.getInstance("PKIX"); + return (PKIXCertPathValidatorResult) validator.validate(path, params); + } + + /** + * Get the content of a file with given filter condition. + * + * @param relativeFilePath path to file that relative to test.src directory. + * @param predicate The condition for filtering file content + * @return the file content + */ + private static String readFile(String relativeFilePath, + Predicate predicate) { + Path filePath = Paths.get(TEST_SRC, relativeFilePath); + try (Stream lines = Files.lines(filePath)) { + Stream interStream = null; + if (predicate != null) { + interStream = lines.filter(predicate); + } + return interStream != null + ? interStream.collect(Collectors.joining("\n")) + : lines.collect(Collectors.joining("\n")); + } catch (IOException e) { + throw new RuntimeException("Cannot read file", e); + } + } +} --- /dev/null 2020-02-29 14:22:47.584405148 +0100 +++ new/test/lib/jdk/test/lib/security/KeyEntry.java 2020-06-09 18:22:06.682537000 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test.lib.security; + +/* + * An entry in key store. + */ +public class KeyEntry { + + // The key algorithm + public final String keyAlgo; + + // The PEM-encoded PKCS8 key string + public final String keyStr; + + // The password to protect the key + public final String password; + + // The certificate chain + // Every certificate is a PEM-encoded string + public final String[] certStrs; + + public KeyEntry(String keyAlgo, String keyStr, String password, + String[] certStrs) { + this.keyAlgo = keyAlgo; + this.keyStr = keyStr; + this.password = password; + this.certStrs = certStrs; + } + + public KeyEntry(String keyAlgo, String keyStr, String[] certStrs) { + this(keyAlgo, keyStr, null, certStrs); + } +} --- /dev/null 2020-02-29 14:22:47.584405148 +0100 +++ new/test/lib/jdk/test/lib/security/KeyStoreUtils.java 2020-06-09 18:22:10.065553000 +0200 @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test.lib.security; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +/* + * Utilities for creating key store. + */ +public class KeyStoreUtils { + + private static final String DEFAULT_TYPE = KeyStore.getDefaultType(); + + /** + * Create key store with a given input stream. + * + * @param type the key store type + * @param input the input stream containing a key store + * @param password the password used to check the integrity of the key store + * @return the key store + * @throws Exception on errors + */ + public static KeyStore loadKeyStore(String type, InputStream input, + String password) throws Exception { + KeyStore keyStore = KeyStore.getInstance(type); + try { + keyStore.load(input, + password == null ? null : password.toCharArray()); + return keyStore; + } finally { + if (input != null) { + input.close(); + } + } + } + + /** + * Create key store with a given input stream. + * + * @param input the input stream containing a key store + * @param password the password used to check the integrity of the key store + * @return the key store + * @throws Exception on errors + */ + public static KeyStore loadKeyStore(InputStream input, String password) + throws Exception { + return loadKeyStore(DEFAULT_TYPE, input, password); + } + + /** + * Create key store with given Base64-encoded string. + * + * @param keyStoreBase64 the Base64-encoded string containing a key store + * @param password the password used to check the integrity of the key store + * @return the key store + * @throws Exception on errors + */ + public static KeyStore loadKeyStoreBase64(String keyStoreBase64, + String password) throws Exception { + return loadKeyStore(DEFAULT_TYPE, new ByteArrayInputStream( + Base64.getDecoder().decode(keyStoreBase64)), password); + } + + /** + * Create key store with a given file. + * + * @param type the key store type + * @param path the path to file containing a key store + * @param password the password used to check the integrity of the key store + * @return the key store + * @throws Exception on errors + */ + public static KeyStore loadKeyStore(String type, String path, + String password) throws Exception { + return loadKeyStore(type, new FileInputStream(path), password); + } + + /** + * Create key store with a given file. + * + * @param path the path to file containing a key store + * @param password the password used to check the integrity of the key store + * @return the key store + * @throws Exception on errors + */ + public static KeyStore loadKeyStore(String path, String password) + throws Exception { + return loadKeyStore(DEFAULT_TYPE, path, password); + } + + /** + * Create trust store with given certificates. + * + * @param type the key store type + * @param certStrs the certificates added to the trust store + * @return the trust store + * @throws Exception on errors + */ + public static KeyStore createTrustStore(String type, String[] certStrs) + throws Exception { + KeyStore trustStore = initKeyStore(type); + + for (int i = 0; i < certStrs.length; i++) { + trustStore.setCertificateEntry("trust-" + i, + CertUtils.getCertFromString(certStrs[i])); + } + + return trustStore; + } + + /** + * Create trust store with given certificates. + * + * @param certStrs the certificates added to the trust store + * @return the trust store + * @throws Exception on errors + */ + public static KeyStore createTrustStore(String[] certStrs) + throws Exception { + return createTrustStore(DEFAULT_TYPE, certStrs); + } + + /** + * Create key store with given entries. + * + * @param type the key store type + * @param entries the key entries added to the key store + * @return the key store + * @throws Exception on errors + */ + public static KeyStore createKeyStore(String type, KeyEntry[] entries) + throws Exception { + KeyStore keyStore = initKeyStore(type); + + for (int i = 0; i < entries.length; i++) { + KeyEntry entry = entries[i]; + PrivateKey key = CertUtils.getKeyFromString( + entry.keyAlgo, entry.keyStr); + char[] password = entry.password == null + ? null + : entry.password.toCharArray(); + Certificate[] chain = new Certificate[entry.certStrs.length]; + for (int j = 0; j < chain.length; j++) { + chain[j] = CertUtils.getCertFromString(entry.certStrs[j]); + } + + keyStore.setKeyEntry("cert-" + i, key, password, chain); + } + + return keyStore; + } + + /** + * Create key store with given entries. + * + * @param entries the key entries added to the key store + * @return the key store + * @throws Exception on errors + */ + public static KeyStore createKeyStore(KeyEntry[] entries) + throws Exception { + return createKeyStore(DEFAULT_TYPE, entries); + } + + /** + * Create key store with given private keys and associated certificate chains. + * Note that here one chain contains only one certificate. If a chain needs + * to contain multiple certificates, please use the following methods: + * createKeyStore(String type, KeyEntry[] entries); + * createKeyStore(KeyEntry[] entries) + * + * @param type the key store type + * @param keyAlgos the key algorithm array + * @param keyStrs the PEM-encoded PKCS8 key string array + * @param passwords the key-associated password array + * @param certStrs the key-associated certificate array + * @return the key store + * @throws Exception on errors + */ + public static KeyStore createKeyStore(String type, String[] keyAlgos, + String[] keyStrs, String[] passwords, String[] certStrs) + throws Exception { + KeyEntry[] entries = new KeyEntry[keyStrs.length]; + for (int i = 0; i < entries.length; i++) { + entries[i] = new KeyEntry( + keyAlgos[i], + keyStrs[i], + passwords == null ? null : passwords[i], + new String[] { certStrs[i] }); + } + return createKeyStore(type, entries); + } + + /** + * Create key store with given private keys and associated certificate chains. + * Note that here one chain contains only one certificate. If a chain needs + * to contain multiple certificates, please use the following methods: + * createKeyStore(String type, KeyEntry[] entries); + * createKeyStore(KeyEntry[] entries) + * + * @param keyAlgos the key algorithm array + * @param keyStrs the PEM-encoded PKCS8 key string array + * @param passwords the key-associated password array + * @param certStrs the key-associated certificate array + * @return the key store + * @throws Exception on errors + */ + public static KeyStore createKeyStore(String[] keyAlgos, String[] keyStrs, + String[] passwords, String[] certStrs) throws Exception { + return createKeyStore(DEFAULT_TYPE, keyAlgos, keyStrs, passwords, + certStrs); + } + + private static KeyStore initKeyStore(String type) throws Exception { + KeyStore keyStore = KeyStore.getInstance(type); + keyStore.load(null, null); + return keyStore; + } + + /** + * The default trust store that contains RSA, ECDSA, RSASSA-PSS and DSA + * certificates. + */ + public static KeyStore defaultTrustStore() throws Exception { + return createTrustStore( + new String[] { CertUtils.RSA_CERT, CertUtils.ECDSA_CERT, + CertUtils.RSASSAPSS_CERT, CertUtils.DSA_CERT }); + } + + /** + * The default key store that contains RSA, ECDSA, RSASSA-PSS and DSA + * certificates. + */ + public static KeyStore defaultKeyStore() throws Exception { + List entries = new ArrayList<>(); + entries.add(new KeyEntry("RSA", CertUtils.RSA_KEY, + new String[] { CertUtils.RSA_CERT })); + entries.add(new KeyEntry("EC", CertUtils.ECDSA_KEY, + new String[] { CertUtils.ECDSA_CERT })); + entries.add(new KeyEntry("RSASSA-PSS", CertUtils.RSASSAPSS_KEY, + new String[] { CertUtils.RSASSAPSS_CERT })); + entries.add(new KeyEntry("DSA", CertUtils.DSA_KEY, + new String[] { CertUtils.DSA_CERT })); + return createKeyStore(entries.toArray(new KeyEntry[entries.size()])); + } +} --- /dev/null 2020-02-29 14:22:47.584405148 +0100 +++ new/test/lib/jdk/test/lib/security/SSLContextBuilder.java 2020-06-09 18:22:13.613293000 +0200 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test.lib.security; + +import java.security.KeyStore; +import java.security.SecureRandom; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + +/* + * SSL context builder. + */ +public class SSLContextBuilder { + + // Trust store + private KeyStore trustStore = null; + + // Key store + private KeyStore keyStore = null; + + // Trust manager factory algorithm + private String tmfAlgo = TrustManagerFactory.getDefaultAlgorithm(); + + // Key manager factory algorithm + private String kmfAlgo = KeyManagerFactory.getDefaultAlgorithm(); + + // Key manager factory passphrase + private String kmfPassphrase = null; + + // Context protocol + private String protocol = "TLS"; + + private SecureRandom random = null; + + public SSLContextBuilder trustStore(KeyStore trustStore) { + this.trustStore = trustStore; + return this; + } + + public SSLContextBuilder keyStore(KeyStore keyStore) { + this.keyStore = keyStore; + return this; + } + + public SSLContextBuilder tmfAlgo(String tmfAlgo) { + this.tmfAlgo = tmfAlgo; + return this; + } + + public SSLContextBuilder kmfAlgo(String kmfAlgo) { + this.kmfAlgo = kmfAlgo; + return this; + } + + public SSLContextBuilder kmfPassphrase(String kmfPassphrase) { + this.kmfPassphrase = kmfPassphrase; + return this; + } + + public SSLContextBuilder protocol(String protocol) { + this.protocol = protocol; + return this; + } + + public SSLContextBuilder random(SecureRandom random) { + this.random = random; + return this; + } + + public SSLContext build() throws Exception { + return buildSSLContext( + trustStore, keyStore, + tmfAlgo, kmfAlgo, kmfPassphrase, + protocol, random); + } + + public static SSLContextBuilder builder() { + return new SSLContextBuilder(); + } + + /** + * The default TLS context. + */ + public static SSLContext defaultTLSContext() throws Exception { + return builder() + .trustStore(KeyStoreUtils.defaultTrustStore()) + .keyStore(KeyStoreUtils.defaultKeyStore()) + .build(); + } + + /** + * The default DTLS context. + */ + public static SSLContext defaultDTLSContext() throws Exception { + return builder() + .trustStore(KeyStoreUtils.defaultTrustStore()) + .keyStore(KeyStoreUtils.defaultKeyStore()) + .protocol("DTLS") + .build(); + } + + private static SSLContext buildSSLContext( + KeyStore trustStore, KeyStore keyStore, + String tmfAlgo, String kmfAlgo, String kmfPassphrase, + String protocol, SecureRandom random) throws Exception { + TrustManagerFactory tmf = null; + if (trustStore != null) { + tmf = TrustManagerFactory.getInstance(tmfAlgo); + tmf.init(trustStore); + } + + KeyManagerFactory kmf = null; + if (keyStore != null) { + kmf = KeyManagerFactory.getInstance(kmfAlgo); + kmf.init(keyStore, + kmfPassphrase == null ? null : kmfPassphrase.toCharArray()); + } + + SSLContext context = SSLContext.getInstance(protocol); + context.init( + kmf == null ? null : kmf.getKeyManagers(), + tmf == null ? null : tmf.getTrustManagers(), + random); + return context; + } +} --- old/test/jdk/java/security/testlibrary/CertUtils.java 2020-06-09 18:22:18.165346000 +0200 +++ /dev/null 2020-02-29 14:22:47.584405148 +0100 @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * - * @author Sean Mullan - * @author Steve Hanna - * - */ -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.CertPath; -import java.security.cert.CertPathBuilder; -import java.security.cert.CertPathValidator; -import java.security.cert.CertStore; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.CRLException; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.PKIXCertPathBuilderResult; -import java.security.cert.PKIXCertPathValidatorResult; -import java.security.cert.PKIXParameters; -import java.security.cert.X509Certificate; -import java.security.cert.X509CRL; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Static utility methods useful for testing certificate/certpath APIs. - */ -public class CertUtils { - - private CertUtils() {} - - /** - * Get a DER-encoded X.509 certificate from a file. - * - * @param certFilePath path to file containing DER-encoded certificate - * @return the X509Certificate - * @throws CertificateException if the certificate type is not supported - * or cannot be parsed - * @throws IOException if the file cannot be opened - */ - public static X509Certificate getCertFromFile(String certFilePath) - throws CertificateException, IOException { - File certFile = new File(System.getProperty("test.src", "."), - certFilePath); - try (FileInputStream fis = new FileInputStream(certFile)) { - return (X509Certificate) - CertificateFactory.getInstance("X.509") - .generateCertificate(fis); - } - } - - /** - * Get a PEM-encoded X.509 certificate from a string. - * - * @param cert string containing the PEM-encoded certificate - * @return the X509Certificate - * @throws CertificateException if the certificate type is not supported - * or cannot be parsed - */ - public static X509Certificate getCertFromString(String cert) - throws CertificateException { - byte[] certBytes = cert.getBytes(); - ByteArrayInputStream bais = new ByteArrayInputStream(certBytes); - return (X509Certificate) - CertificateFactory.getInstance("X.509").generateCertificate(bais); - } - - /** - * Get a DER-encoded X.509 CRL from a file. - * - * @param crlFilePath path to file containing DER-encoded CRL - * @return the X509CRL - * @throws CertificateException if the crl type is not supported - * @throws CRLException if the crl cannot be parsed - * @throws IOException if the file cannot be opened - */ - public static X509CRL getCRLFromFile(String crlFilePath) - throws CertificateException, CRLException, IOException { - File crlFile = new File(System.getProperty("test.src", "."), - crlFilePath); - try (FileInputStream fis = new FileInputStream(crlFile)) { - return (X509CRL) - CertificateFactory.getInstance("X.509").generateCRL(fis); - } - } - - /** - * Get a PEM-encoded X.509 crl from a string. - * - * @param crl string containing the PEM-encoded crl - * @return the X509CRL - * @throws CertificateException if the crl type is not supported - * @throws CRLException if the crl cannot be parsed - */ - public static X509CRL getCRLFromString(String crl) - throws CertificateException, CRLException { - byte[] crlBytes = crl.getBytes(); - ByteArrayInputStream bais = new ByteArrayInputStream(crlBytes); - return (X509CRL) - CertificateFactory.getInstance("X.509").generateCRL(bais); - } - - /** - * Read a bunch of certs from files and create a CertPath from them. - * - * @param fileNames an array of Strings that are file names - * @throws Exception on error - */ - public static CertPath buildPath(String [] fileNames) throws Exception { - return buildPath("", fileNames); - } - - /** - * Read a bunch of certs from files and create a CertPath from them. - * - * @param relPath relative path containing certs (must end in - * file.separator) - * @param fileNames an array of Strings that are file names - * @throws Exception on error - */ - public static CertPath buildPath(String relPath, String [] fileNames) - throws Exception { - List list = new ArrayList(); - for (int i = 0; i < fileNames.length; i++) { - list.add(0, getCertFromFile(relPath + fileNames[i])); - } - CertificateFactory cf = CertificateFactory.getInstance("X509"); - return(cf.generateCertPath(list)); - } - - - /** - * Read a bunch of certs from files and create a CertStore from them. - * - * @param fileNames an array of Strings that are file names - * @return the CertStore created - * @throws Exception on error - */ - public static CertStore createStore(String [] fileNames) throws Exception { - return createStore("", fileNames); - } - - /** - * Read a bunch of certs from files and create a CertStore from them. - * - * @param relPath relative path containing certs (must end in - * file.separator) - * @param fileNames an array of Strings that are file names - * @return the CertStore created - * @throws Exception on error - */ - public static CertStore createStore(String relPath, String [] fileNames) - throws Exception { - Set certs = new HashSet(); - for (int i = 0; i < fileNames.length; i++) { - certs.add(getCertFromFile(relPath + fileNames[i])); - } - return CertStore.getInstance("Collection", - new CollectionCertStoreParameters(certs)); - } - - /** - * Read a bunch of CRLs from files and create a CertStore from them. - * - * @param fileNames an array of Strings that are file names - * @return the CertStore created - * @throws Exception on error - */ - public static CertStore createCRLStore(String [] fileNames) - throws Exception { - return createCRLStore("", fileNames); - } - - /** - * Read a bunch of CRLs from files and create a CertStore from them. - * - * @param relPath relative path containing CRLs (must end in file.separator) - * @param fileNames an array of Strings that are file names - * @return the CertStore created - * @throws Exception on error - */ - public static CertStore createCRLStore(String relPath, String [] fileNames) - throws Exception { - Set crls = new HashSet(); - for (int i = 0; i < fileNames.length; i++) { - crls.add(getCRLFromFile(relPath + fileNames[i])); - } - return CertStore.getInstance("Collection", - new CollectionCertStoreParameters(crls)); - } - - /** - * Perform a PKIX path build. On failure, throw an exception. - * - * @param params PKIXBuilderParameters to use in validation - * @throws Exception on error - */ - public static PKIXCertPathBuilderResult build(PKIXBuilderParameters params) - throws Exception { - CertPathBuilder builder = - CertPathBuilder.getInstance("PKIX"); - return (PKIXCertPathBuilderResult) builder.build(params); - } - - /** - * Perform a PKIX validation. On failure, throw an exception. - * - * @param path CertPath to validate - * @param params PKIXParameters to use in validation - * @throws Exception on error - */ - public static PKIXCertPathValidatorResult validate - (CertPath path, PKIXParameters params) throws Exception { - CertPathValidator validator = - CertPathValidator.getInstance("PKIX"); - return (PKIXCertPathValidatorResult) validator.validate(path, params); - } - - /* - * Reads the entire input stream into a byte array. - */ - private static byte[] getTotalBytes(InputStream is) throws IOException { - byte[] buffer = new byte[8192]; - ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); - int n; - baos.reset(); - while ((n = is.read(buffer, 0, buffer.length)) != -1) { - baos.write(buffer, 0, n); - } - return baos.toByteArray(); - } -}