1 /*
2  * Copyright (c) 2019, 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 
24 import javax.net.ssl.SSLContext;
25 import javax.net.ssl.SSLServerSocket;
26 import javax.net.ssl.SSLSocket;
27 
28 /*
29   * @test
30   * @bug 8224650
31   * @library /javax/net/ssl/templates
32   *          /javax/net/ssl/TLSCommon
33   * @summary Test TLS ciphersuite with each individual supported group
34   * @run main/othervm NamedGroupsWithCipherSuite x25519
35   * @run main/othervm NamedGroupsWithCipherSuite x448
36   * @run main/othervm NamedGroupsWithCipherSuite secp256r1
37   * @run main/othervm NamedGroupsWithCipherSuite secp384r1
38   * @run main/othervm NamedGroupsWithCipherSuite secp521r1
39   * @run main/othervm NamedGroupsWithCipherSuite ffdhe2048
40   * @run main/othervm NamedGroupsWithCipherSuite ffdhe3072
41   * @run main/othervm NamedGroupsWithCipherSuite ffdhe4096
42   * @run main/othervm NamedGroupsWithCipherSuite ffdhe6144
43   * @run main/othervm NamedGroupsWithCipherSuite ffdhe8192
44  */
45 public class NamedGroupsWithCipherSuite extends SSLSocketTemplate {
46 
47     private static final Protocol[] PROTOCOLS = new Protocol[] {
48             Protocol.TLSV1_3,
49             Protocol.TLSV1_2,
50             Protocol.TLSV1_1,
51             Protocol.TLSV1
52     };
53 
54     private static final CipherSuite[] CIPHER_SUITES = new CipherSuite[] {
55             CipherSuite.TLS_AES_128_GCM_SHA256,
56             CipherSuite.TLS_AES_256_GCM_SHA384,
57             CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
58 
59             CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
60             CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
61             CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
62             CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
63 
64             CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
65             CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
66             CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
67             CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
68 
69             CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
70             CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
71 
72             CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
73             CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
74             CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
75     };
76 
77     private String protocol;
78     private String cipher;
79 
80     private SSLSocketTemplate.Cert[] trustedCerts = TRUSTED_CERTS;
81     private SSLSocketTemplate.Cert[] endEntityCerts = END_ENTITY_CERTS;
82 
NamedGroupsWithCipherSuite( String protocol, String cipher, String namedGroup)83     NamedGroupsWithCipherSuite(
84             String protocol,
85             String cipher,
86             String namedGroup) {
87         this.protocol = protocol;
88         this.cipher = cipher;
89 
90         if (cipher.startsWith("TLS_ECDHE_ECDSA")) {
91             switch (namedGroup) {
92             case "secp256r1":
93                 trustedCerts = new SSLSocketTemplate.Cert[] {
94                         SSLSocketTemplate.Cert.CA_ECDSA_SECP256R1 };
95                 endEntityCerts = new SSLSocketTemplate.Cert[] {
96                         SSLSocketTemplate.Cert.EE_ECDSA_SECP256R1 };
97                 break;
98             case "secp384r1":
99                 trustedCerts = new SSLSocketTemplate.Cert[] {
100                         SSLSocketTemplate.Cert.CA_ECDSA_SECP384R1 };
101                 endEntityCerts = new SSLSocketTemplate.Cert[] {
102                         SSLSocketTemplate.Cert.EE_ECDSA_SECP384R1 };
103                 break;
104             case "secp521r1":
105                 trustedCerts = new SSLSocketTemplate.Cert[] {
106                         SSLSocketTemplate.Cert.CA_ECDSA_SECP521R1 };
107                 endEntityCerts = new SSLSocketTemplate.Cert[] {
108                         SSLSocketTemplate.Cert.EE_ECDSA_SECP521R1 };
109             }
110         }
111     }
112 
createClientSSLContext()113     protected SSLContext createClientSSLContext() throws Exception {
114         return createSSLContext(trustedCerts, endEntityCerts,
115                 getClientContextParameters());
116     }
117 
createServerSSLContext()118     protected SSLContext createServerSSLContext() throws Exception {
119         return createSSLContext(trustedCerts, endEntityCerts,
120                 getServerContextParameters());
121     }
122 
123     // Servers are configured before clients, increment test case after.
124     @Override
configureClientSocket(SSLSocket socket)125     protected void configureClientSocket(SSLSocket socket) {
126         socket.setEnabledProtocols(new String[] { protocol });
127         socket.setEnabledCipherSuites(new String[] { cipher });
128     }
129 
130     @Override
configureServerSocket(SSLServerSocket serverSocket)131     protected void configureServerSocket(SSLServerSocket serverSocket) {
132         serverSocket.setEnabledProtocols(new String[] { protocol });
133         serverSocket.setEnabledCipherSuites(new String[] { cipher });
134     }
135 
main(String[] args)136     public static void main(String[] args) throws Exception {
137         String namedGroup = args[0];
138 
139         System.setProperty("jdk.tls.namedGroups", namedGroup);
140         System.out.println("NamedGroup: " + namedGroup);
141 
142         for (Protocol protocol : PROTOCOLS) {
143             for (CipherSuite cipherSuite : CIPHER_SUITES) {
144                 if (cipherSuite.supportedByProtocol(protocol)
145                         && groupSupportdByCipher(namedGroup, cipherSuite)) {
146                     System.out.printf("Protocol: %s, cipher suite: %s%n",
147                             protocol, cipherSuite);
148 
149                     new NamedGroupsWithCipherSuite(protocol.name,
150                             cipherSuite.name(), namedGroup).run();
151                 }
152             }
153         }
154     }
155 
groupSupportdByCipher(String group, CipherSuite cipherSuite)156     private static boolean groupSupportdByCipher(String group,
157             CipherSuite cipherSuite) {
158         return (group.startsWith("x")
159                         && xdhGroupSupportdByCipher(cipherSuite))
160                 || (group.startsWith("secp")
161                         && ecdhGroupSupportdByCipher(cipherSuite))
162                 || (group.startsWith("ffdhe")
163                         && ffdhGroupSupportdByCipher(cipherSuite));
164     }
165 
xdhGroupSupportdByCipher( CipherSuite cipherSuite)166     private static boolean xdhGroupSupportdByCipher(
167             CipherSuite cipherSuite) {
168         return cipherSuite.keyExAlgorithm == null
169                 || cipherSuite.keyExAlgorithm == KeyExAlgorithm.ECDHE_RSA;
170     }
171 
ecdhGroupSupportdByCipher( CipherSuite cipherSuite)172     private static boolean ecdhGroupSupportdByCipher(
173             CipherSuite cipherSuite) {
174         return cipherSuite.keyExAlgorithm == null
175                 || cipherSuite.keyExAlgorithm == KeyExAlgorithm.ECDHE_RSA
176                 || cipherSuite.keyExAlgorithm == KeyExAlgorithm.ECDHE_ECDSA;
177     }
178 
ffdhGroupSupportdByCipher( CipherSuite cipherSuite)179     private static boolean ffdhGroupSupportdByCipher(
180             CipherSuite cipherSuite) {
181         return cipherSuite.keyExAlgorithm == null
182                 || cipherSuite.keyExAlgorithm == KeyExAlgorithm.DHE_DSS
183                 || cipherSuite.keyExAlgorithm == KeyExAlgorithm.DHE_RSA;
184     }
185 }
186