/* * Copyright (c) 2016, 2018, 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.
*/
/** * Template to help speed up your client/server tests. * * Two examples that use this template: * test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java * test/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java
*/ publicabstractclass SSLSocketTest {
/* * Run the test case.
*/ publicvoid run() throws Exception {
bootup();
}
/* * Define the server side application of the test for the specified socket.
*/ protectedabstractvoid runServerApplication(SSLSocket socket) throws Exception;
/* * Define the client side application of the test for the specified socket. * This method is used if the returned value of * isCustomizedClientConnection() is false. * * @param socket may be null is no client socket is generated. * * @see #isCustomizedClientConnection()
*/ protectedabstractvoid runClientApplication(SSLSocket socket) throws Exception;
/* * Define the client side application of the test for the specified * server port. This method is used if the returned value of * isCustomizedClientConnection() is true. * * Note that the client need to connect to the server port by itself * for the actual message exchange. * * @see #isCustomizedClientConnection()
*/ protectedvoid runClientApplication(int serverPort) throws Exception { // blank
}
/* * Create an instance of SSLContext for client use.
*/ protected SSLContext createClientSSLContext() throws Exception { return createSSLContext(trustedCertStrs,
endEntityCertStrs, endEntityPrivateKeys,
endEntityPrivateKeyAlgs,
endEntityPrivateKeyNames,
getClientContextParameters());
}
/* * Create an instance of SSLContext for server use.
*/ protected SSLContext createServerSSLContext() throws Exception { return createSSLContext(trustedCertStrs,
endEntityCertStrs, endEntityPrivateKeys,
endEntityPrivateKeyAlgs,
endEntityPrivateKeyNames,
getServerContextParameters());
}
/* * The parameters used to configure SSLContext.
*/ protectedstaticfinalclass ContextParameters { final String contextProtocol; final String tmAlgorithm; final String kmAlgorithm;
/* * Get the client side parameters of SSLContext.
*/ protected ContextParameters getClientContextParameters() { returnnew ContextParameters("TLS", "PKIX", "NewSunX509");
}
/* * Get the server side parameters of SSLContext.
*/ protected ContextParameters getServerContextParameters() { returnnew ContextParameters("TLS", "PKIX", "NewSunX509");
}
/* * Does the client side use customized connection other than * explicit Socket.connect(), for example, URL.openConnection()?
*/ protectedboolean isCustomizedClientConnection() { returnfalse;
}
/* * Configure the server side socket.
*/ protectedvoid configureServerSocket(SSLServerSocket socket) {
}
/* * ============================================= * Define the client and server side operations. * * If the client or server is doing some kind of object creation * that the other side depends on, and that thread prematurely * exits, you may experience a hang. The test harness will * terminate all hung threads after its timeout has expired, * currently 3 minutes by default, but you might try to be * smart about it....
*/
/* * Is the server ready to serve?
*/ privatefinal CountDownLatch serverCondition = new CountDownLatch(1);
/* * Is the client ready to handshake?
*/ privatefinal CountDownLatch clientCondition = new CountDownLatch(1);
/* * What's the server port? Use any free port by default
*/ privatevolatileint serverPort = 0;
/* * Define the server side of the test.
*/ privatevoid doServerSide() throws Exception { // kick start the server side service
SSLContext context = createServerSSLContext();
SSLServerSocketFactory sslssf = context.getServerSocketFactory();
SSLServerSocket sslServerSocket =
(SSLServerSocket)sslssf.createServerSocket(serverPort);
configureServerSocket(sslServerSocket);
serverPort = sslServerSocket.getLocalPort();
// Signal the client, the server is ready to accept connection.
serverCondition.countDown();
// Try to accept a connection in 30 seconds.
SSLSocket sslSocket; try {
sslServerSocket.setSoTimeout(30000);
sslSocket = (SSLSocket)sslServerSocket.accept();
} catch (SocketTimeoutException ste) { // Ignore the test case if no connection within 30 seconds.
System.out.println( "No incoming client connection in 30 seconds. " + "Ignore in server side."); return;
} finally {
sslServerSocket.close();
}
// handle the connection try { // Is it the expected client connection? // // Naughty test cases or third party routines may try to // connection to this server port unintentionally. In // order to mitigate the impact of unexpected client // connections and avoid intermittent failure, it should // be checked that the accepted connection is really linked // to the expected client. boolean clientIsReady =
clientCondition.await(30L, TimeUnit.SECONDS);
if (clientIsReady) { // Run the application in server side.
runServerApplication(sslSocket);
} else { // Otherwise, ignore // We don't actually care about plain socket connections // for TLS communication testing generally. Just ignore // the test if the accepted connection is not linked to // the expected client or the client connection timeout // in 30 seconds.
System.out.println( "The client is not the expected one or timeout. " + "Ignore in server side.");
}
} finally {
sslSocket.close();
}
}
/* * Define the client side of the test.
*/ privatevoid doClientSide() throws Exception {
// Wait for server to get started. // // The server side takes care of the issue if the server cannot // get started in 90 seconds. The client side would just ignore // the test case if the serer is not ready. boolean serverIsReady =
serverCondition.await(90L, TimeUnit.SECONDS); if (!serverIsReady) {
System.out.println( "The server is not ready yet in 90 seconds. " + "Ignore in client side."); return;
}
if (isCustomizedClientConnection()) { // Signal the server, the client is ready to communicate.
clientCondition.countDown();
// Run the application in client side.
runClientApplication(serverPort);
try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) { try {
sslSocket.connect( new InetSocketAddress("localhost", serverPort), 15000);
} catch (IOException ioe) { // The server side may be impacted by naughty test cases or // third party routines, and cannot accept connections. // // Just ignore the test if the connection cannot be // established.
System.out.println( "Cannot make a connection in 15 seconds. " + "Ignore in client side."); return;
}
// OK, here the client and server get connected.
// Signal the server, the client is ready to communicate.
clientCondition.countDown();
// There is still a chance in theory that the server thread may // wait client-ready timeout and then quit. The chance should // be really rare so we don't consider it until it becomes a // real problem.
// Run the application in client side.
runClientApplication(sslSocket);
}
}
/* * ============================================= * Stuffs to customize the SSLContext instances.
*/
/* * ======================================= * Certificates and keys used in the test.
*/ // Trusted certificates. privatefinalstatic String[] trustedCertStrs = { // SHA256withECDSA, curve prime256v1 // Validity // Not Before: May 22 07:18:16 2018 GMT // Not After : May 17 07:18:16 2038 GMT // Subject Key Identifier: // 60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86 "-----BEGIN CERTIFICATE-----\n" + "MIIBvjCCAWOgAwIBAgIJAIvFG6GbTroCMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" + "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYTAlVT\n" + "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n" + "MBMGByqGSM49AgEGCCqGSM49AwEHA0IABBz1WeVb6gM2mh85z3QlvaB/l11b5h0v\n" + "LIzmkC3DKlVukZT+ltH2Eq1oEkpXuf7QmbM0ibrUgtjsWH3mULfmcWmjUDBOMB0G\n" + "A1UdDgQWBBRgz71z//oaMNKk7NNJcUbvGjWghjAfBgNVHSMEGDAWgBRgz71z//oa\n" + "MNKk7NNJcUbvGjWghjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCG\n" + "6wluh1r2/T6L31mZXRKf9JxeSf9pIzoLj+8xQeUChQIhAJ09wAi1kV8yePLh2FD9\n" + "2YEHlSQUAbwwqCDEVB5KxaqP\n" + "-----END CERTIFICATE-----", // -----BEGIN PRIVATE KEY----- // MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/HcHdoLJCdq3haVd // XZTSKP00YzM3xX97l98vGL/RI1KhRANCAAQc9VnlW+oDNpofOc90Jb2gf5ddW+Yd // LyyM5pAtwypVbpGU/pbR9hKtaBJKV7n+0JmzNIm61ILY7Fh95lC35nFp // -----END PRIVATE KEY-----
// Private key in the format of PKCS#8. privatefinalstatic String[] endEntityPrivateKeys = { // // EC private key related to cert endEntityCertStrs[0]. // "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgn5K03bpTLjEtFQRa\n" + "JUtx22gtmGEvvSUSQdimhGthdtihRANCAARv72fTmp9ed8dRvTG1Ak1Lgl5KLoiM\n" + "59bk2pyG8qd8l7L1WQnNHtAcu44RJ1/GVHurxghaCKHeJYsZ8H7DEeI6",
Certificate[] trustedCert = new Certificate[trustedMaterials.length]; for (int i = 0; i < trustedMaterials.length; i++) {
String trustedCertStr = trustedMaterials[i];
is = new ByteArrayInputStream(trustedCertStr.getBytes()); try {
trustedCert[i] = cf.generateCertificate(is);
} finally {
is.close();
}
ts.setCertificateEntry("trusted-cert-" + i, trustedCert[i]);
}
}
// Import the key materials. // // Note that certification pathes bigger than one are not supported yet. boolean hasKeyMaterials =
(keyMaterialCerts != null) && (keyMaterialCerts.length != 0) &&
(keyMaterialKeys != null) && (keyMaterialKeys.length != 0) &&
(keyMaterialKeyAlgs != null) && (keyMaterialKeyAlgs.length != 0) &&
(keyMaterialCerts.length == keyMaterialKeys.length) &&
(keyMaterialCerts.length == keyMaterialKeyAlgs.length); if (hasKeyMaterials) {
ks = KeyStore.getInstance("JKS");
ks.load(null, null);
for (int i = 0; i < keyMaterialCerts.length; i++) {
String keyCertStr = keyMaterialCerts[i];
// generate the private key.
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
Base64.getMimeDecoder().decode(keyMaterialKeys[i]));
KeyFactory kf =
KeyFactory.getInstance(keyMaterialKeyAlgs[i]);
PrivateKey priKey = kf.generatePrivate(priKeySpec);
/* * Should we run the client or server in a separate thread? * Both sides can throw exceptions, but do you have a preference * as to which side should be the main thread.
*/ privatestaticfinalboolean separateServerThread = false;
/* * Boot up the testing, used to drive remainder of the test.
*/ privatevoid bootup() throws Exception {
Exception startException = null; try { if (separateServerThread) {
startServer(true);
startClient(false);
} else {
startClient(true);
startServer(false);
}
} catch (Exception e) {
startException = e;
}
/* * Wait for other side to close down.
*/ if (separateServerThread) { if (serverThread != null) {
serverThread.join();
}
} else { if (clientThread != null) {
clientThread.join();
}
}
/* * When we get here, the test is pretty much over. * Which side threw the error?
*/
Exception local;
Exception remote;
if (separateServerThread) {
remote = serverException;
local = clientException;
} else {
remote = clientException;
local = serverException;
}
/* * If there was an exception *AND* a startException, * output it.
*/ if (exception != null) { if (exception != startException && startException != null) {
exception.addSuppressed(startException);
} throw exception;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.