Path: blob/master/test/jdk/sun/security/ssl/X509TrustManagerImpl/TooManyCAs.java
41152 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 820692526* @library /javax/net/ssl/templates27* @summary Support the certificate_authorities extension28* @run main/othervm TooManyCAs29* @run main/othervm -Djdk.tls.client.enableCAExtension=true TooManyCAs30*/31import javax.net.ssl.*;32import javax.security.auth.x500.X500Principal;33import java.io.*;34import java.net.InetAddress;35import java.net.Socket;36import java.security.cert.CertificateException;37import java.security.cert.X509Certificate;38import java.util.Arrays;3940/**41* Check if the connection can be established if the client or server trusts42* more CAs such that it exceeds the size limit of the certificate_authorities43* extension (2^16).44*/45public class TooManyCAs implements SSLContextTemplate {4647private static final String[][][] protocols = {48{{"TLSv1.3"}, {"TLSv1.3"}},49{{"TLSv1.3", "TLSv1.2"}, {"TLSv1.3"}},50{{"TLSv1.3"}, {"TLSv1.3", "TLSv1.2"}},51};5253private final String[] clientProtocols;54private final String[] serverProtocols;55private final boolean needClientAuth;5657TooManyCAs(int index, boolean needClientAuth) {58this.clientProtocols = protocols[index][0];59this.serverProtocols = protocols[index][1];60this.needClientAuth = needClientAuth;61}6263// Servers are configured before clients, increment test case after.64void configureClientSocket(SSLSocket clientSocket) {65System.err.print("Setting client protocol(s): ");66Arrays.stream(clientProtocols).forEachOrdered(System.err::print);67System.err.println();6869clientSocket.setEnabledProtocols(clientProtocols);70}7172void configureServerSocket(SSLServerSocket serverSocket) {73System.err.print("Setting server protocol(s): ");74Arrays.stream(serverProtocols).forEachOrdered(System.err::print);75System.err.println();7677serverSocket.setEnabledProtocols(serverProtocols);78if (needClientAuth) {79serverSocket.setNeedClientAuth(true);80}81}8283@Override84public TrustManager createClientTrustManager() throws Exception {85TrustManager trustManager =86SSLContextTemplate.super.createClientTrustManager();87return new BogusX509TrustManager(88(X509TrustManager)trustManager);89}9091@Override92public TrustManager createServerTrustManager() throws Exception {93TrustManager trustManager =94SSLContextTemplate.super.createServerTrustManager();95return new BogusX509TrustManager(96(X509TrustManager)trustManager);97}9899/*100* Run the test case.101*/102public static void main(String[] args) throws Exception {103for (int i = 0; i < protocols.length; i++) {104(new TooManyCAs(i, false)).run();105(new TooManyCAs(i, true)).run();106}107}108109private void run() throws Exception {110SSLServerSocket listenSocket = null;111SSLSocket serverSocket = null;112ClientSocket clientSocket = null;113try {114SSLServerSocketFactory serversocketfactory =115createServerSSLContext().getServerSocketFactory();116listenSocket =117(SSLServerSocket)serversocketfactory.createServerSocket(0);118listenSocket.setNeedClientAuth(false);119listenSocket.setEnableSessionCreation(true);120listenSocket.setUseClientMode(false);121configureServerSocket(listenSocket);122123System.err.println("Starting client");124clientSocket = new ClientSocket(listenSocket.getLocalPort());125clientSocket.start();126127System.err.println("Accepting client requests");128serverSocket = (SSLSocket)listenSocket.accept();129130if (!clientSocket.isDone) {131System.err.println("Waiting 3 seconds for client ");132Thread.sleep(3000);133}134135System.err.println("Sending data to client ...");136String serverData = "Hi, I am server";137BufferedWriter os = new BufferedWriter(138new OutputStreamWriter(serverSocket.getOutputStream()));139os.write(serverData, 0, serverData.length());140os.newLine();141os.flush();142} finally {143if (listenSocket != null) {144listenSocket.close();145}146147if (serverSocket != null) {148serverSocket.close();149}150}151152if (clientSocket != null && clientSocket.clientException != null) {153throw clientSocket.clientException;154}155}156157private class ClientSocket extends Thread{158boolean isDone = false;159int serverPort = 0;160Exception clientException;161162public ClientSocket(int serverPort) {163this.serverPort = serverPort;164}165166@Override167public void run() {168SSLSocket clientSocket = null;169String clientData = "Hi, I am client";170try {171System.err.println(172"Connecting to server at port " + serverPort);173SSLSocketFactory sslSocketFactory =174createClientSSLContext().getSocketFactory();175clientSocket = (SSLSocket)sslSocketFactory.createSocket(176InetAddress.getLocalHost(), serverPort);177configureClientSocket(clientSocket);178179System.err.println("Sending data to server ...");180181BufferedWriter os = new BufferedWriter(182new OutputStreamWriter(clientSocket.getOutputStream()));183os.write(clientData, 0, clientData.length());184os.newLine();185os.flush();186187System.err.println("Reading data from server");188BufferedReader is = new BufferedReader(189new InputStreamReader(clientSocket.getInputStream()));190String data = is.readLine();191System.err.println("Received Data from server: " + data);192} catch (Exception e) {193clientException = e;194System.err.println("unexpected client exception: " + e);195} finally {196if (clientSocket != null) {197try {198clientSocket.close();199System.err.println("client socket closed");200} catch (IOException ioe) {201clientException = ioe;202}203}204205isDone = true;206}207}208}209210// Construct a bogus trust manager which has more CAs such that exceed211// the size limit of the certificate_authorities extension (2^16).212private static final class BogusX509TrustManager213extends X509ExtendedTrustManager implements X509TrustManager {214private final X509ExtendedTrustManager tm;215216private BogusX509TrustManager(X509TrustManager trustManager) {217this.tm = (X509ExtendedTrustManager)trustManager;218}219220@Override221public void checkClientTrusted(X509Certificate[] chain,222String authType, Socket socket) throws CertificateException {223tm.checkClientTrusted(chain, authType, socket);224}225226@Override227public void checkServerTrusted(X509Certificate[] chain,228String authType, Socket socket) throws CertificateException {229tm.checkServerTrusted(chain, authType, socket);230}231232@Override233public void checkClientTrusted(X509Certificate[] chain,234String authType, SSLEngine sslEngine) throws CertificateException {235236tm.checkClientTrusted(chain, authType, sslEngine);237}238239@Override240public void checkServerTrusted(X509Certificate[] chain,241String authType, SSLEngine sslEngine) throws CertificateException {242243tm.checkServerTrusted(chain, authType, sslEngine);244}245246@Override247public void checkClientTrusted(X509Certificate[] chain,248String authType) throws CertificateException {249tm.checkServerTrusted(chain, authType);250}251252@Override253public void checkServerTrusted(X509Certificate[] chain,254String authType) throws CertificateException {255tm.checkServerTrusted(chain, authType);256}257258@Override259public X509Certificate[] getAcceptedIssuers() {260X509Certificate[] trustedCerts = tm.getAcceptedIssuers();261int sizeAccount = 0;262for (X509Certificate cert: trustedCerts) {263X500Principal x500Principal = cert.getSubjectX500Principal();264byte[] encodedPrincipal = x500Principal.getEncoded();265sizeAccount += encodedPrincipal.length;266}267268// 0xFFFF: the size limit of the certificate_authorities extension269int duplicated = (0xFFFF + sizeAccount) / sizeAccount;270X509Certificate[] returnedCAs =271new X509Certificate[trustedCerts.length * duplicated];272for (int i = 0; i < duplicated; i++) {273System.arraycopy(trustedCerts, 0,274returnedCAs,275i * trustedCerts.length + 0, trustedCerts.length);276}277278return returnedCAs;279}280}281}282283284