1 /* 2 * Copyright (c) 2005, 2017, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.net.ssl; 27 28 import java.security.AlgorithmConstraints; 29 import java.util.Map; 30 import java.util.List; 31 import java.util.HashMap; 32 import java.util.ArrayList; 33 import java.util.Collection; 34 import java.util.Collections; 35 import java.util.LinkedHashMap; 36 37 /** 38 * Encapsulates parameters for an SSL/TLS/DTLS connection. The parameters 39 * are the list of ciphersuites to be accepted in an SSL/TLS/DTLS handshake, 40 * the list of protocols to be allowed, the endpoint identification 41 * algorithm during SSL/TLS/DTLS handshaking, the Server Name Indication (SNI), 42 * the maximum network packet size, the algorithm constraints and whether 43 * SSL/TLS/DTLS servers should request or require client authentication, etc. 44 * <p> 45 * SSLParameters can be created via the constructors in this class. 46 * Objects can also be obtained using the {@code getSSLParameters()} 47 * methods in 48 * {@link SSLSocket#getSSLParameters SSLSocket} and 49 * {@link SSLServerSocket#getSSLParameters SSLServerSocket} and 50 * {@link SSLEngine#getSSLParameters SSLEngine} or the 51 * {@link SSLContext#getDefaultSSLParameters getDefaultSSLParameters()} and 52 * {@link SSLContext#getSupportedSSLParameters getSupportedSSLParameters()} 53 * methods in {@code SSLContext}. 54 * <p> 55 * SSLParameters can be applied to a connection via the methods 56 * {@link SSLSocket#setSSLParameters SSLSocket.setSSLParameters()} and 57 * {@link SSLServerSocket#setSSLParameters SSLServerSocket.setSSLParameters()} 58 * and {@link SSLEngine#setSSLParameters SSLEngine.setSSLParameters()}. 59 * <p> 60 * For example: 61 * 62 * <blockquote><pre> 63 * SSLParameters p = sslSocket.getSSLParameters(); 64 * p.setProtocols(new String[] { "TLSv1.2" }); 65 * p.setCipherSuites( 66 * new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", ... }); 67 * p.setApplicationProtocols(new String[] {"h2", "http/1.1"}); 68 * sslSocket.setSSLParameters(p); 69 * </pre></blockquote> 70 * 71 * @see SSLSocket 72 * @see SSLEngine 73 * @see SSLContext 74 * 75 * @since 1.6 76 */ 77 public class SSLParameters { 78 79 private String[] cipherSuites; 80 private String[] protocols; 81 private boolean wantClientAuth; 82 private boolean needClientAuth; 83 private String identificationAlgorithm; 84 private AlgorithmConstraints algorithmConstraints; 85 private Map<Integer, SNIServerName> sniNames = null; 86 private Map<Integer, SNIMatcher> sniMatchers = null; 87 private boolean preferLocalCipherSuites; 88 private boolean enableRetransmissions = true; 89 private int maximumPacketSize = 0; 90 private String[] applicationProtocols = new String[0]; 91 92 /** 93 * Constructs SSLParameters. 94 * <p> 95 * The values of cipherSuites, protocols, cryptographic algorithm 96 * constraints, endpoint identification algorithm, server names and 97 * server name matchers are set to {@code null}; useCipherSuitesOrder, 98 * wantClientAuth and needClientAuth are set to {@code false}; 99 * enableRetransmissions is set to {@code true}; maximum network packet 100 * size is set to {@code 0}. 101 */ 102 public SSLParameters() { 103 // empty 104 } 105 106 /** 107 * Constructs SSLParameters from the specified array of ciphersuites. 108 * <p> 109 * Calling this constructor is equivalent to calling the no-args 110 * constructor followed by 111 * {@code setCipherSuites(cipherSuites);}. Note that the 112 * standard list of cipher suite names may be found in the <a href= 113 * "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names"> 114 * JSSE Cipher Suite Names</a> section of the Java Cryptography 115 * Architecture Standard Algorithm Name Documentation. Providers 116 * may support cipher suite names not found in this list. 117 * 118 * @param cipherSuites the array of ciphersuites (or null) 119 */ 120 public SSLParameters(String[] cipherSuites) { 121 setCipherSuites(cipherSuites); 122 } 123 124 /** 125 * Constructs SSLParameters from the specified array of ciphersuites 126 * and protocols. 127 * <p> 128 * Calling this constructor is equivalent to calling the no-args 129 * constructor followed by 130 * {@code setCipherSuites(cipherSuites); setProtocols(protocols);}. 131 * Note that the standard list of cipher suite names may be found in the 132 * <a href= 133 * "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names"> 134 * JSSE Cipher Suite Names</a> section of the Java Cryptography 135 * Architecture Standard Algorithm Name Documentation. Providers 136 * may support cipher suite names not found in this list. 137 * 138 * @param cipherSuites the array of ciphersuites (or null) 139 * @param protocols the array of protocols (or null) 140 */ 141 public SSLParameters(String[] cipherSuites, String[] protocols) { 142 setCipherSuites(cipherSuites); 143 setProtocols(protocols); 144 } 145 146 private static String[] clone(String[] s) { 147 return (s == null) ? null : s.clone(); 148 } 149 150 /** 151 * Returns a copy of the array of ciphersuites or null if none 152 * have been set. 153 * <P> 154 * The returned array includes cipher suites from the list of standard 155 * cipher suite names in the <a href= 156 * "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names"> 157 * JSSE Cipher Suite Names</a> section of the Java Cryptography 158 * Architecture Standard Algorithm Name Documentation, and may also 159 * include other cipher suites that the provider supports. 160 * 161 * @return a copy of the array of ciphersuites or null if none 162 * have been set. 163 */ 164 public String[] getCipherSuites() { 165 return clone(cipherSuites); 166 } 167 168 /** 169 * Sets the array of ciphersuites. 170 * 171 * @param cipherSuites the array of ciphersuites (or null). Note that the 172 * standard list of cipher suite names may be found in the <a href= 173 * "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names"> 174 * JSSE Cipher Suite Names</a> section of the Java Cryptography 175 * Architecture Standard Algorithm Name Documentation. Providers 176 * may support cipher suite names not found in this list or might not 177 * use the recommended name for a certain cipher suite. 178 */ 179 public void setCipherSuites(String[] cipherSuites) { 180 this.cipherSuites = clone(cipherSuites); 181 } 182 183 /** 184 * Returns a copy of the array of protocols or null if none 185 * have been set. 186 * 187 * @return a copy of the array of protocols or null if none 188 * have been set. 189 */ 190 public String[] getProtocols() { 191 return clone(protocols); 192 } 193 194 /** 195 * Sets the array of protocols. 196 * 197 * @param protocols the array of protocols (or null) 198 */ 199 public void setProtocols(String[] protocols) { 200 this.protocols = clone(protocols); 201 } 202 203 /** 204 * Returns whether client authentication should be requested. 205 * 206 * @return whether client authentication should be requested. 207 */ 208 public boolean getWantClientAuth() { 209 return wantClientAuth; 210 } 211 212 /** 213 * Sets whether client authentication should be requested. Calling 214 * this method clears the {@code needClientAuth} flag. 215 * 216 * @param wantClientAuth whether client authentication should be requested 217 */ 218 public void setWantClientAuth(boolean wantClientAuth) { 219 this.wantClientAuth = wantClientAuth; 220 this.needClientAuth = false; 221 } 222 223 /** 224 * Returns whether client authentication should be required. 225 * 226 * @return whether client authentication should be required. 227 */ 228 public boolean getNeedClientAuth() { 229 return needClientAuth; 230 } 231 232 /** 233 * Sets whether client authentication should be required. Calling 234 * this method clears the {@code wantClientAuth} flag. 235 * 236 * @param needClientAuth whether client authentication should be required 237 */ 238 public void setNeedClientAuth(boolean needClientAuth) { 239 this.wantClientAuth = false; 240 this.needClientAuth = needClientAuth; 241 } 242 243 /** 244 * Returns the cryptographic algorithm constraints. 245 * 246 * @return the cryptographic algorithm constraints, or null if the 247 * constraints have not been set 248 * 249 * @see #setAlgorithmConstraints(AlgorithmConstraints) 250 * 251 * @since 1.7 252 */ 253 public AlgorithmConstraints getAlgorithmConstraints() { 254 return algorithmConstraints; 255 } 256 257 /** 258 * Sets the cryptographic algorithm constraints, which will be used 259 * in addition to any configured by the runtime environment. 260 * <p> 261 * If the {@code constraints} parameter is non-null, every 262 * cryptographic algorithm, key and algorithm parameters used in the 263 * SSL/TLS/DTLS handshake must be permitted by the constraints. 264 * 265 * @param constraints the algorithm constraints (or null) 266 * 267 * @since 1.7 268 */ 269 public void setAlgorithmConstraints(AlgorithmConstraints constraints) { 270 // the constraints object is immutable 271 this.algorithmConstraints = constraints; 272 } 273 274 /** 275 * Gets the endpoint identification algorithm. 276 * 277 * @return the endpoint identification algorithm, or null if none 278 * has been set. 279 * 280 * @see X509ExtendedTrustManager 281 * @see #setEndpointIdentificationAlgorithm(String) 282 * 283 * @since 1.7 284 */ 285 public String getEndpointIdentificationAlgorithm() { 286 return identificationAlgorithm; 287 } 288 289 /** 290 * Sets the endpoint identification algorithm. 291 * <p> 292 * If the {@code algorithm} parameter is non-null or non-empty, the 293 * endpoint identification/verification procedures must be handled during 294 * SSL/TLS/DTLS handshaking. This is to prevent man-in-the-middle attacks. 295 * 296 * @param algorithm The standard string name of the endpoint 297 * identification algorithm (or null). 298 * See the <a href= 299 * "{@docRoot}/../specs/security/standard-names.html"> 300 * Java Security Standard Algorithm Names</a> document 301 * for information about standard algorithm names. 302 * 303 * @see X509ExtendedTrustManager 304 * 305 * @since 1.7 306 */ 307 public void setEndpointIdentificationAlgorithm(String algorithm) { 308 this.identificationAlgorithm = algorithm; 309 } 310 311 /** 312 * Sets the desired {@link SNIServerName}s of the Server Name 313 * Indication (SNI) parameter. 314 * <P> 315 * This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s 316 * operating in client mode. 317 * <P> 318 * Note that the {@code serverNames} list is cloned 319 * to protect against subsequent modification. 320 * 321 * @param serverNames 322 * the list of desired {@link SNIServerName}s (or null) 323 * 324 * @throws NullPointerException if the {@code serverNames} 325 * contains {@code null} element 326 * @throws IllegalArgumentException if the {@code serverNames} 327 * contains more than one name of the same name type 328 * 329 * @see SNIServerName 330 * @see #getServerNames() 331 * 332 * @since 1.8 333 */ 334 public final void setServerNames(List<SNIServerName> serverNames) { 335 if (serverNames != null) { 336 if (!serverNames.isEmpty()) { 337 sniNames = new LinkedHashMap<>(serverNames.size()); 338 for (SNIServerName serverName : serverNames) { 339 if (sniNames.put(serverName.getType(), 340 serverName) != null) { 341 throw new IllegalArgumentException( 342 "Duplicated server name of type " + 343 serverName.getType()); 344 } 345 } 346 } else { 347 sniNames = Collections.<Integer, SNIServerName>emptyMap(); 348 } 349 } else { 350 sniNames = null; 351 } 352 } 353 354 /** 355 * Returns a {@link List} containing all {@link SNIServerName}s of the 356 * Server Name Indication (SNI) parameter, or null if none has been set. 357 * <P> 358 * This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s 359 * operating in client mode. 360 * <P> 361 * For SSL/TLS/DTLS connections, the underlying SSL/TLS/DTLS provider 362 * may specify a default value for a certain server name type. In 363 * client mode, it is recommended that, by default, providers should 364 * include the server name indication whenever the server can be located 365 * by a supported server name type. 366 * <P> 367 * It is recommended that providers initialize default Server Name 368 * Indications when creating {@code SSLSocket}/{@code SSLEngine}s. 369 * In the following examples, the server name could be represented by an 370 * instance of {@link SNIHostName} which has been initialized with the 371 * hostname "www.example.com" and type 372 * {@link StandardConstants#SNI_HOST_NAME}. 373 * 374 * <pre> 375 * Socket socket = 376 * sslSocketFactory.createSocket("www.example.com", 443); 377 * </pre> 378 * or 379 * <pre> 380 * SSLEngine engine = 381 * sslContext.createSSLEngine("www.example.com", 443); 382 * </pre> 383 * 384 * @return null or an immutable list of non-null {@link SNIServerName}s 385 * 386 * @see List 387 * @see #setServerNames(List) 388 * 389 * @since 1.8 390 */ 391 public final List<SNIServerName> getServerNames() { 392 if (sniNames != null) { 393 if (!sniNames.isEmpty()) { 394 return Collections.<SNIServerName>unmodifiableList( 395 new ArrayList<>(sniNames.values())); 396 } else { 397 return Collections.<SNIServerName>emptyList(); 398 } 399 } 400 401 return null; 402 } 403 404 /** 405 * Sets the {@link SNIMatcher}s of the Server Name Indication (SNI) 406 * parameter. 407 * <P> 408 * This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s 409 * operating in server mode. 410 * <P> 411 * Note that the {@code matchers} collection is cloned to protect 412 * against subsequent modification. 413 * 414 * @param matchers 415 * the collection of {@link SNIMatcher}s (or null) 416 * 417 * @throws NullPointerException if the {@code matchers} 418 * contains {@code null} element 419 * @throws IllegalArgumentException if the {@code matchers} 420 * contains more than one name of the same name type 421 * 422 * @see Collection 423 * @see SNIMatcher 424 * @see #getSNIMatchers() 425 * 426 * @since 1.8 427 */ 428 public final void setSNIMatchers(Collection<SNIMatcher> matchers) { 429 if (matchers != null) { 430 if (!matchers.isEmpty()) { 431 sniMatchers = new HashMap<>(matchers.size()); 432 for (SNIMatcher matcher : matchers) { 433 if (sniMatchers.put(matcher.getType(), 434 matcher) != null) { 435 throw new IllegalArgumentException( 436 "Duplicated server name of type " + 437 matcher.getType()); 438 } 439 } 440 } else { 441 sniMatchers = Collections.<Integer, SNIMatcher>emptyMap(); 442 } 443 } else { 444 sniMatchers = null; 445 } 446 } 447 448 /** 449 * Returns a {@link Collection} containing all {@link SNIMatcher}s of the 450 * Server Name Indication (SNI) parameter, or null if none has been set. 451 * <P> 452 * This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s 453 * operating in server mode. 454 * <P> 455 * For better interoperability, providers generally will not define 456 * default matchers so that by default servers will ignore the SNI 457 * extension and continue the handshake. 458 * 459 * @return null or an immutable collection of non-null {@link SNIMatcher}s 460 * 461 * @see SNIMatcher 462 * @see #setSNIMatchers(Collection) 463 * 464 * @since 1.8 465 */ 466 public final Collection<SNIMatcher> getSNIMatchers() { 467 if (sniMatchers != null) { 468 if (!sniMatchers.isEmpty()) { 469 return Collections.<SNIMatcher>unmodifiableList( 470 new ArrayList<>(sniMatchers.values())); 471 } else { 472 return Collections.<SNIMatcher>emptyList(); 473 } 474 } 475 476 return null; 477 } 478 479 /** 480 * Sets whether the local cipher suites preference should be honored. 481 * 482 * @param honorOrder whether local cipher suites order in 483 * {@code #getCipherSuites} should be honored during 484 * SSL/TLS/DTLS handshaking. 485 * 486 * @see #getUseCipherSuitesOrder() 487 * 488 * @since 1.8 489 */ 490 public final void setUseCipherSuitesOrder(boolean honorOrder) { 491 this.preferLocalCipherSuites = honorOrder; 492 } 493 494 /** 495 * Returns whether the local cipher suites preference should be honored. 496 * 497 * @return whether local cipher suites order in {@code #getCipherSuites} 498 * should be honored during SSL/TLS/DTLS handshaking. 499 * 500 * @see #setUseCipherSuitesOrder(boolean) 501 * 502 * @since 1.8 503 */ 504 public final boolean getUseCipherSuitesOrder() { 505 return preferLocalCipherSuites; 506 } 507 508 /** 509 * Sets whether DTLS handshake retransmissions should be enabled. 510 * 511 * This method only applies to DTLS. 512 * 513 * @param enableRetransmissions 514 * {@code true} indicates that DTLS handshake retransmissions 515 * should be enabled; {@code false} indicates that DTLS handshake 516 * retransmissions should be disabled 517 * 518 * @see #getEnableRetransmissions() 519 * 520 * @since 9 521 */ 522 public void setEnableRetransmissions(boolean enableRetransmissions) { 523 this.enableRetransmissions = enableRetransmissions; 524 } 525 526 /** 527 * Returns whether DTLS handshake retransmissions should be enabled. 528 * 529 * This method only applies to DTLS. 530 * 531 * @return true, if DTLS handshake retransmissions should be enabled 532 * 533 * @see #setEnableRetransmissions(boolean) 534 * 535 * @since 9 536 */ 537 public boolean getEnableRetransmissions() { 538 return enableRetransmissions; 539 } 540 541 /** 542 * Sets the maximum expected network packet size in bytes for 543 * SSL/TLS/DTLS records. 544 * 545 * @apiNote It is recommended that if possible, the maximum packet size 546 * should not be less than 256 bytes so that small handshake 547 * messages, such as HelloVerifyRequests, are not fragmented. 548 * 549 * @implNote If the maximum packet size is too small to hold a minimal 550 * record, an implementation may attempt to generate as minimal 551 * records as possible. However, this may cause a generated 552 * packet to be larger than the maximum packet size. 553 * 554 * @param maximumPacketSize 555 * the maximum expected network packet size in bytes, or 556 * {@code 0} to use the implicit size that is automatically 557 * specified by the underlying implementation. 558 * @throws IllegalArgumentException 559 * if {@code maximumPacketSize} is negative. 560 * 561 * @see #getMaximumPacketSize() 562 * 563 * @since 9 564 */ 565 public void setMaximumPacketSize(int maximumPacketSize) { 566 if (maximumPacketSize < 0) { 567 throw new IllegalArgumentException( 568 "The maximum packet size cannot be negative"); 569 } 570 571 this.maximumPacketSize = maximumPacketSize; 572 } 573 574 /** 575 * Returns the maximum expected network packet size in bytes for 576 * SSL/TLS/DTLS records. 577 * 578 * @apiNote The implicit size may not be a fixed value, especially 579 * for a DTLS protocols implementation. 580 * 581 * @implNote For SSL/TLS/DTLS connections, the underlying provider 582 * should calculate and specify the implicit value of the 583 * maximum expected network packet size if it is not 584 * configured explicitly. For any connection populated 585 * object, this method should never return {@code 0} so 586 * that applications can retrieve the actual implicit size 587 * of the underlying implementation. 588 * <P> 589 * An implementation should attempt to comply with the maximum 590 * packet size configuration. However, if the maximum packet 591 * size is too small to hold a minimal record, an implementation 592 * may try to generate as minimal records as possible. This 593 * may cause a generated packet to be larger than the maximum 594 * packet size. 595 * 596 * @return the maximum expected network packet size, or {@code 0} if 597 * use the implicit size that is automatically specified by 598 * the underlying implementation and this object has not been 599 * populated by any connection. 600 * 601 * @see #setMaximumPacketSize(int) 602 * 603 * @since 9 604 */ 605 public int getMaximumPacketSize() { 606 return maximumPacketSize; 607 } 608 609 /** 610 * Returns a prioritized array of application-layer protocol names that 611 * can be negotiated over the SSL/TLS/DTLS protocols. 612 * <p> 613 * The array could be empty (zero-length), in which case protocol 614 * indications will not be used. 615 * <p> 616 * This method will return a new array each time it is invoked. 617 * 618 * @return a non-null, possibly zero-length array of application protocol 619 * {@code String}s. The array is ordered based on protocol 620 * preference, with {@code protocols[0]} being the most preferred. 621 * @see #setApplicationProtocols 622 * @since 9 623 */ 624 public String[] getApplicationProtocols() { 625 return applicationProtocols.clone(); 626 } 627 628 /** 629 * Sets the prioritized array of application-layer protocol names that 630 * can be negotiated over the SSL/TLS/DTLS protocols. 631 * <p> 632 * If application-layer protocols are supported by the underlying 633 * SSL/TLS implementation, this method configures which values can 634 * be negotiated by protocols such as <a 635 * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the 636 * Application Layer Protocol Negotiation (ALPN). 637 * <p> 638 * If this end of the connection is expected to offer application protocol 639 * values, all protocols configured by this method will be sent to the 640 * peer. 641 * <p> 642 * If this end of the connection is expected to select the application 643 * protocol value, the {@code protocols} configured by this method are 644 * compared with those sent by the peer. The first matched value becomes 645 * the negotiated value. If none of the {@code protocols} were actually 646 * requested by the peer, the underlying protocol will determine what 647 * action to take. (For example, ALPN will send a 648 * {@code "no_application_protocol"} alert and terminate the connection.) 649 * 650 * @implSpec 651 * This method will make a copy of the {@code protocols} array. 652 * 653 * @param protocols an ordered array of application protocols, 654 * with {@code protocols[0]} being the most preferred. 655 * If the array is empty (zero-length), protocol 656 * indications will not be used. 657 * @throws IllegalArgumentException if protocols is null, or if 658 * any element in a non-empty array is null or an 659 * empty (zero-length) string 660 * @see #getApplicationProtocols 661 * @since 9 662 */ 663 public void setApplicationProtocols(String[] protocols) { 664 if (protocols == null) { 665 throw new IllegalArgumentException("protocols was null"); 666 } 667 668 String[] tempProtocols = protocols.clone(); 669 670 for (String p : tempProtocols) { 671 if (p == null || p.equals("")) { 672 throw new IllegalArgumentException( 673 "An element of protocols was null/empty"); 674 } 675 } 676 applicationProtocols = tempProtocols; 677 } 678 }