8228967: Trust/Key store and SSL context utilities for tests
authorjjiang
Thu, 05 Sep 2019 14:55:21 +0800
changeset 58013 d80e4bce4588
parent 58012 70cb43a67409
child 58014 aba258cd7df8
8228967: Trust/Key store and SSL context utilities for tests Reviewed-by: xuelei
test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
test/jdk/java/security/cert/X509CRL/VerifyDefault.java
test/jdk/java/security/cert/X509Certificate/VerifyDefault.java
test/jdk/java/security/testlibrary/CertUtils.java
test/jdk/javax/net/ssl/DTLS/CipherSuite.java
test/jdk/javax/net/ssl/DTLS/ClientAuth.java
test/jdk/javax/net/ssl/DTLS/DTLSOverDatagram.java
test/jdk/javax/net/ssl/DTLS/InvalidCookie.java
test/jdk/javax/net/ssl/DTLS/InvalidRecords.java
test/jdk/javax/net/ssl/DTLS/NoMacInitialClientHello.java
test/jdk/javax/net/ssl/DTLS/PacketLossRetransmission.java
test/jdk/javax/net/ssl/DTLS/Reordered.java
test/jdk/javax/net/ssl/DTLS/RespondToRetransmit.java
test/jdk/javax/net/ssl/DTLS/Retransmission.java
test/jdk/javax/net/ssl/DTLS/WeakCipherSuite.java
test/jdk/sun/security/mscapi/KeytoolChangeAlias.java
test/jdk/sun/security/util/HostnameMatcher/NullHostnameCheck.java
test/jdk/sun/security/util/HostnameMatcher/TestHostnameChecker.java
test/lib/jdk/test/lib/security/CertUtils.java
test/lib/jdk/test/lib/security/KeyEntry.java
test/lib/jdk/test/lib/security/KeyStoreUtils.java
test/lib/jdk/test/lib/security/SSLContextBuilder.java
--- a/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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 {
 
--- a/test/jdk/java/security/cert/X509CRL/VerifyDefault.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/java/security/cert/X509CRL/VerifyDefault.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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 =
--- a/test/jdk/java/security/cert/X509Certificate/VerifyDefault.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/java/security/cert/X509Certificate/VerifyDefault.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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 =
--- a/test/jdk/java/security/testlibrary/CertUtils.java	Thu Sep 05 02:13:59 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <code>String</code>s 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 <code>String</code>s that are file names
-     * @throws Exception on error
-     */
-    public static CertPath buildPath(String relPath, String [] fileNames)
-        throws Exception {
-        List<X509Certificate> list = new ArrayList<X509Certificate>();
-        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 <code>String</code>s that are file names
-     * @return the <code>CertStore</code> 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 <code>String</code>s that are file names
-     * @return the <code>CertStore</code> created
-     * @throws Exception on error
-     */
-    public static CertStore createStore(String relPath, String [] fileNames)
-        throws Exception {
-        Set<X509Certificate> certs = new HashSet<X509Certificate>();
-        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 <code>String</code>s that are file names
-     * @return the <code>CertStore</code> 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 <code>String</code>s that are file names
-     * @return the <code>CertStore</code> created
-     * @throws Exception on error
-     */
-    public static CertStore createCRLStore(String relPath, String [] fileNames)
-        throws Exception {
-        Set<X509CRL> crls = new HashSet<X509CRL>();
-        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();
-    }
-}
--- a/test/jdk/javax/net/ssl/DTLS/CipherSuite.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/CipherSuite.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
--- a/test/jdk/javax/net/ssl/DTLS/ClientAuth.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/ClientAuth.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
  */
--- a/test/jdk/javax/net/ssl/DTLS/DTLSOverDatagram.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/DTLSOverDatagram.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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();
     }
 
 
--- a/test/jdk/javax/net/ssl/DTLS/InvalidCookie.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/InvalidCookie.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
  */
--- a/test/jdk/javax/net/ssl/DTLS/InvalidRecords.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/InvalidRecords.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
  */
--- a/test/jdk/javax/net/ssl/DTLS/NoMacInitialClientHello.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/NoMacInitialClientHello.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
--- a/test/jdk/javax/net/ssl/DTLS/PacketLossRetransmission.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/PacketLossRetransmission.java	Thu Sep 05 14:55:21 2019 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2019 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
--- a/test/jdk/javax/net/ssl/DTLS/Reordered.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/Reordered.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
  */
--- a/test/jdk/javax/net/ssl/DTLS/RespondToRetransmit.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/RespondToRetransmit.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
--- a/test/jdk/javax/net/ssl/DTLS/Retransmission.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/Retransmission.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
  */
--- a/test/jdk/javax/net/ssl/DTLS/WeakCipherSuite.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/javax/net/ssl/DTLS/WeakCipherSuite.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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
--- a/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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 {
--- a/test/jdk/sun/security/util/HostnameMatcher/NullHostnameCheck.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/sun/security/util/HostnameMatcher/NullHostnameCheck.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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,35 +33,29 @@
 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
  * @summary Verify hostname returns an exception instead of null pointer when
  * creating a new engine
+ * @library /test/lib
  * @run main NullHostnameCheck
  */
 
-
 public final class NullHostnameCheck {
 
     public static void main(String[] args) throws Exception {
-        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("TLSv1.2");
-        serverCtx.init(kmf.getKeyManagers(), null, null);
+        String password = "123456";
+        SSLContext serverCtx = SSLContextBuilder.builder()
+                .keyStore(KeyStoreUtils.loadKeyStoreBase64(
+                        keystoreB64, password))
+                .kmfPassphrase(password)
+                .protocol("TLSv1.2")
+                .build();
         SSLEngine serverEngine = serverCtx.createSSLEngine("localhost", -1);
         serverEngine.setUseClientMode(false);
 
@@ -67,12 +64,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
--- a/test/jdk/sun/security/util/HostnameMatcher/TestHostnameChecker.java	Thu Sep 05 02:13:59 2019 +0200
+++ b/test/jdk/sun/security/util/HostnameMatcher/TestHostnameChecker.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/security/CertUtils.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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 <code>String</code>s 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 <code>String</code>s that are file names
+     * @throws Exception on error
+     */
+    public static CertPath buildPath(String relPath, String [] fileNames)
+            throws Exception {
+        List<X509Certificate> list = new ArrayList<X509Certificate>();
+        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 <code>String</code>s that are file names
+     * @return the <code>CertStore</code> 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 <code>String</code>s that are file names
+     * @return the <code>CertStore</code> created
+     * @throws Exception on error
+     */
+    public static CertStore createStore(String relPath, String [] fileNames)
+            throws Exception {
+        Set<X509Certificate> certs = new HashSet<X509Certificate>();
+        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 <code>String</code>s that are file names
+     * @return the <code>CertStore</code> 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 <code>String</code>s that are file names
+     * @return the <code>CertStore</code> created
+     * @throws Exception on error
+     */
+    public static CertStore createCRLStore(String relPath, String [] fileNames)
+        throws Exception {
+        Set<X509CRL> crls = new HashSet<X509CRL>();
+        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<String> predicate) {
+        Path filePath = Paths.get(TEST_SRC, relativeFilePath);
+        try (Stream<String> lines = Files.lines(filePath)) {
+            Stream<String> 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	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/security/KeyEntry.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/security/KeyStoreUtils.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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<KeyEntry> 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	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/security/SSLContextBuilder.java	Thu Sep 05 14:55:21 2019 +0800
@@ -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;
+    }
+}