1 /* 2 * Copyright (c) 2017, 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 java.util.ArrayList; 25 import java.util.List; 26 27 /* 28 * The TLS communication use case. 29 */ 30 public class UseCase { 31 32 private static final boolean FULL_CASES 33 = Utils.getBoolProperty("fullCases"); 34 35 public static final boolean FULL_CIPHER_SUITES 36 = Utils.getBoolProperty("fullCipherSuites"); 37 38 public static final Protocol[] PROTOCOLS = new Protocol[] { 39 Protocol.TLSV1, 40 Protocol.TLSV1_1, 41 Protocol.TLSV1_2, 42 Protocol.TLSV1_3 }; 43 44 public static final CipherSuite[] CIPHER_SUITES = new CipherSuite[] { 45 CipherSuite.TLS_AES_128_GCM_SHA256, 46 CipherSuite.TLS_AES_256_GCM_SHA384, 47 CipherSuite.TLS_CHACHA20_POLY1305_SHA256, 48 CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 49 CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 50 CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 51 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 52 CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 53 CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, 54 CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, 55 CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, 56 CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 57 CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 58 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 59 CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 60 CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, 61 CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, 62 CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, 63 CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 64 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 65 CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 66 CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, 67 CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, 68 CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, 69 CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 70 CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, 71 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 72 CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 73 CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, 74 CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, 75 CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 76 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 77 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 78 CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 79 CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, 80 CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, 81 CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, 82 CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 83 CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, 84 CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 85 CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, 86 CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, 87 CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, 88 CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 89 CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 }; 90 91 public static final CipherSuite[] MANDATORY_CIPHER_SUITES = new CipherSuite[] { 92 CipherSuite.TLS_AES_128_GCM_SHA256, 93 CipherSuite.TLS_CHACHA20_POLY1305_SHA256, 94 CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 95 CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, 96 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 97 CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 98 CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, 99 CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 100 CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 101 CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 }; 102 103 enum ServerName { 104 105 NONE(null), 106 EXAMPLE("EXAMPLE"); 107 108 final String name; 109 110 private ServerName(String name) { 111 this.name = name; 112 } 113 } 114 115 enum AppProtocol { 116 117 NONE(null, null), 118 EXAMPLE(new String[] { Utils.HTTP_2, Utils.HTTP_1_1 }, Utils.HTTP_2); 119 120 final String[] appProtocols; 121 122 // Expected negotiated application protocol 123 final String negoAppProtocol; 124 125 private AppProtocol(String[] appProtocols, String negoAppProtocol) { 126 this.appProtocols = appProtocols; 127 this.negoAppProtocol = negoAppProtocol; 128 } 129 } 130 131 private static final Object[][] PARAMS = new Object[][] { 132 FULL_CASES ? PROTOCOLS : PROTOCOLS, 133 FULL_CASES ? CIPHER_SUITES : MANDATORY_CIPHER_SUITES, 134 FULL_CASES ? new Boolean[] { false, true } : new Boolean[] { true }, 135 FULL_CASES 136 ? new ServerName[] { ServerName.NONE, ServerName.EXAMPLE } 137 : new ServerName[] { ServerName.EXAMPLE }, 138 FULL_CASES 139 ? new AppProtocol[] { 140 AppProtocol.NONE, 141 AppProtocol.EXAMPLE } 142 : new AppProtocol[] { 143 AppProtocol.EXAMPLE } }; 144 145 public final Protocol protocol; 146 public final CipherSuite cipherSuite; 147 public final Boolean clientAuth; 148 public final ServerName serverName; 149 public final AppProtocol appProtocol; 150 151 public final boolean negativeCase; 152 153 public UseCase( 154 Protocol protocol, 155 CipherSuite cipherSuite, 156 boolean clientAuth, 157 ServerName serverName, 158 AppProtocol appProtocol) { 159 this.protocol = protocol; 160 this.cipherSuite = cipherSuite; 161 this.clientAuth = clientAuth; 162 this.serverName = serverName; 163 this.appProtocol = appProtocol; 164 165 negativeCase = !cipherSuite.supportedByProtocol(protocol); 166 } 167 168 @Override 169 public String toString() { 170 return Utils.join(Utils.PARAM_DELIMITER, 171 "Protocol=" + protocol.name, 172 "CipherSuite=" + cipherSuite, 173 "ClientAuth=" + clientAuth, 174 "ServerName=" + serverName, 175 "AppProtocols=" + appProtocol); 176 } 177 178 public static List<UseCase> getAllUseCases() { 179 List<UseCase> useCases = new ArrayList<>(); 180 getUseCases(PARAMS, 0, new Object[PARAMS.length], useCases); 181 return useCases; 182 } 183 184 private static void getUseCases(Object[][] params, int index, 185 Object[] currentValues, List<UseCase> useCases) { 186 if (index == params.length) { 187 Protocol protocol = (Protocol) currentValues[0]; 188 CipherSuite cipherSuite = (CipherSuite) currentValues[1]; 189 190 UseCase useCase = new UseCase( 191 protocol, 192 cipherSuite, 193 (Boolean) currentValues[2], 194 (ServerName) currentValues[3], 195 (AppProtocol) currentValues[4]); 196 useCases.add(useCase); 197 } else { 198 Object[] values = params[index]; 199 for (int i = 0; i < values.length; i++) { 200 currentValues[index] = values[i]; 201 getUseCases(params, index + 1, currentValues, useCases); 202 } 203 } 204 } 205 }