1/*
2 * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24import java.io.InputStream;
25import java.io.OutputStream;
26import java.security.cert.Certificate;
27import javax.net.ssl.KeyManager;
28import javax.net.ssl.SSLContext;
29import javax.net.ssl.SSLSession;
30import javax.net.ssl.SSLSocket;
31import javax.net.ssl.SSLSocketFactory;
32import javax.net.ssl.TrustManager;
33
34class JSSEClient extends CipherTestUtils.Client {
35
36    private static final String DEFAULT = "DEFAULT";
37    private static final String TLS = "TLS";
38
39    private final SSLContext context;
40    private final MyX509KeyManager keyManager;
41    private final int port;
42    private final String host;
43    private final String protocol;
44
45    JSSEClient(CipherTestUtils cipherTest, String host, int port,
46            String protocols, String ciphersuite) throws Exception {
47        super(cipherTest, ciphersuite);
48        this.host = host;
49        this.port = port;
50        this.protocol = protocols;
51        this.keyManager = new MyX509KeyManager(
52                                    cipherTest.getClientKeyManager());
53        context = SSLContext.getInstance(TLS);
54    }
55
56    @Override
57    void runTest(CipherTestUtils.TestParameters params) throws Exception {
58        keyManager.setAuthType(params.clientAuth);
59        context.init(
60                new KeyManager[]{ keyManager },
61                new TrustManager[]{ cipherTest.getClientTrustManager() },
62                CipherTestUtils.secureRandom);
63        SSLSocketFactory factory = (SSLSocketFactory)context.getSocketFactory();
64
65        System.out.println("Connecting to server...");
66        try (SSLSocket socket = (SSLSocket) factory.createSocket(host, port)) {
67            socket.setSoTimeout(CipherTestUtils.TIMEOUT);
68            socket.setEnabledCipherSuites(params.cipherSuite.split(","));
69            if (params.protocol != null && !params.protocol.trim().isEmpty()
70                    && !params.protocol.trim().equals(DEFAULT)) {
71                socket.setEnabledProtocols(params.protocol.split(","));
72            }
73            CipherTestUtils.printInfo(socket);
74            InputStream in = socket.getInputStream();
75            OutputStream out = socket.getOutputStream();
76            sendRequest(in, out);
77            SSLSession session = socket.getSession();
78            session.invalidate();
79            String cipherSuite = session.getCipherSuite();
80            if (params.cipherSuite.equals(cipherSuite) == false) {
81                throw new RuntimeException("Negotiated ciphersuite mismatch: "
82                        + cipherSuite + " != " + params.cipherSuite);
83            }
84            String protocol = session.getProtocol();
85            if (!DEFAULT.equals(params.protocol)
86                    && !params.protocol.contains(protocol)) {
87                throw new RuntimeException("Negotiated protocol mismatch: "
88                        + protocol + " != " + params.protocol);
89            }
90            if (!cipherSuite.contains("DH_anon")) {
91                session.getPeerCertificates();
92            }
93            Certificate[] certificates = session.getLocalCertificates();
94            if (params.clientAuth == null) {
95                if (certificates != null) {
96                    throw new RuntimeException("Local certificates "
97                            + "should be null");
98                }
99            } else {
100                if ((certificates == null) || (certificates.length == 0)) {
101                    throw new RuntimeException("Certificates missing");
102                }
103                String keyAlg = certificates[0].getPublicKey().getAlgorithm();
104                if ("EC".equals(keyAlg)) {
105                    keyAlg = "ECDSA";
106                }
107                if (!params.clientAuth.equals(keyAlg)) {
108                    throw new RuntimeException("Certificate type mismatch: "
109                            + keyAlg + " != " + params.clientAuth);
110                }
111            }
112        }
113    }
114}
115