Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/net/ssl/SSLParameters.java
38918 views
/*1* Copyright (c) 2005, 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. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.net.ssl;2627import java.security.AlgorithmConstraints;28import java.util.Map;29import java.util.List;30import java.util.HashMap;31import java.util.ArrayList;32import java.util.Collection;33import java.util.Collections;34import java.util.LinkedHashMap;3536/**37* Encapsulates parameters for an SSL/TLS connection. The parameters38* are the list of ciphersuites to be accepted in an SSL/TLS handshake,39* the list of protocols to be allowed, the endpoint identification40* algorithm during SSL/TLS handshaking, the Server Name Indication (SNI),41* the algorithm constraints and whether SSL/TLS servers should request42* or require client authentication, etc.43* <p>44* SSLParameters can be created via the constructors in this class.45* Objects can also be obtained using the <code>getSSLParameters()</code>46* methods in47* {@link SSLSocket#getSSLParameters SSLSocket} and48* {@link SSLServerSocket#getSSLParameters SSLServerSocket} and49* {@link SSLEngine#getSSLParameters SSLEngine} or the50* {@link SSLContext#getDefaultSSLParameters getDefaultSSLParameters()} and51* {@link SSLContext#getSupportedSSLParameters getSupportedSSLParameters()}52* methods in <code>SSLContext</code>.53* <p>54* SSLParameters can be applied to a connection via the methods55* {@link SSLSocket#setSSLParameters SSLSocket.setSSLParameters()} and56* {@link SSLServerSocket#setSSLParameters SSLServerSocket.setSSLParameters()}57* and {@link SSLEngine#setSSLParameters SSLEngine.setSSLParameters()}.58* <p>59* For example:60*61* <blockquote><pre>62* SSLParameters p = sslSocket.getSSLParameters();63* p.setProtocols(new String[] { "TLSv1.2" });64* p.setCipherSuites(65* new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", ... });66* p.setApplicationProtocols(new String[] {"h2", "http/1.1"});67* sslSocket.setSSLParameters(p);68* </pre></blockquote>*69*70* @see SSLSocket71* @see SSLEngine72* @see SSLContext73*74* @since 1.675*/76public class SSLParameters {7778private String[] cipherSuites;79private String[] protocols;80private boolean wantClientAuth;81private boolean needClientAuth;82private String identificationAlgorithm;83private AlgorithmConstraints algorithmConstraints;84private Map<Integer, SNIServerName> sniNames = null;85private Map<Integer, SNIMatcher> sniMatchers = null;86private boolean preferLocalCipherSuites;87private String[] applicationProtocols = new String[0];8889/**90* Constructs SSLParameters.91* <p>92* The values of cipherSuites, protocols, cryptographic algorithm93* constraints, endpoint identification algorithm, server names and94* server name matchers are set to <code>null</code>, useCipherSuitesOrder,95* wantClientAuth and needClientAuth are set to <code>false</code>.96*/97public SSLParameters() {98// empty99}100101/**102* Constructs SSLParameters from the specified array of ciphersuites.103* <p>104* Calling this constructor is equivalent to calling the no-args105* constructor followed by106* <code>setCipherSuites(cipherSuites);</code>.107*108* @param cipherSuites the array of ciphersuites (or null)109*/110public SSLParameters(String[] cipherSuites) {111setCipherSuites(cipherSuites);112}113114/**115* Constructs SSLParameters from the specified array of ciphersuites116* and protocols.117* <p>118* Calling this constructor is equivalent to calling the no-args119* constructor followed by120* <code>setCipherSuites(cipherSuites); setProtocols(protocols);</code>.121*122* @param cipherSuites the array of ciphersuites (or null)123* @param protocols the array of protocols (or null)124*/125public SSLParameters(String[] cipherSuites, String[] protocols) {126setCipherSuites(cipherSuites);127setProtocols(protocols);128}129130private static String[] clone(String[] s) {131return (s == null) ? null : s.clone();132}133134/**135* Returns a copy of the array of ciphersuites or null if none136* have been set.137*138* @return a copy of the array of ciphersuites or null if none139* have been set.140*/141public String[] getCipherSuites() {142return clone(cipherSuites);143}144145/**146* Sets the array of ciphersuites.147*148* @param cipherSuites the array of ciphersuites (or null)149*/150public void setCipherSuites(String[] cipherSuites) {151this.cipherSuites = clone(cipherSuites);152}153154/**155* Returns a copy of the array of protocols or null if none156* have been set.157*158* @return a copy of the array of protocols or null if none159* have been set.160*/161public String[] getProtocols() {162return clone(protocols);163}164165/**166* Sets the array of protocols.167*168* @param protocols the array of protocols (or null)169*/170public void setProtocols(String[] protocols) {171this.protocols = clone(protocols);172}173174/**175* Returns whether client authentication should be requested.176*177* @return whether client authentication should be requested.178*/179public boolean getWantClientAuth() {180return wantClientAuth;181}182183/**184* Sets whether client authentication should be requested. Calling185* this method clears the <code>needClientAuth</code> flag.186*187* @param wantClientAuth whether client authentication should be requested188*/189public void setWantClientAuth(boolean wantClientAuth) {190this.wantClientAuth = wantClientAuth;191this.needClientAuth = false;192}193194/**195* Returns whether client authentication should be required.196*197* @return whether client authentication should be required.198*/199public boolean getNeedClientAuth() {200return needClientAuth;201}202203/**204* Sets whether client authentication should be required. Calling205* this method clears the <code>wantClientAuth</code> flag.206*207* @param needClientAuth whether client authentication should be required208*/209public void setNeedClientAuth(boolean needClientAuth) {210this.wantClientAuth = false;211this.needClientAuth = needClientAuth;212}213214/**215* Returns the cryptographic algorithm constraints.216*217* @return the cryptographic algorithm constraints, or null if the218* constraints have not been set219*220* @see #setAlgorithmConstraints(AlgorithmConstraints)221*222* @since 1.7223*/224public AlgorithmConstraints getAlgorithmConstraints() {225return algorithmConstraints;226}227228/**229* Sets the cryptographic algorithm constraints, which will be used230* in addition to any configured by the runtime environment.231* <p>232* If the <code>constraints</code> parameter is non-null, every233* cryptographic algorithm, key and algorithm parameters used in the234* SSL/TLS handshake must be permitted by the constraints.235*236* @param constraints the algorithm constraints (or null)237*238* @since 1.7239*/240public void setAlgorithmConstraints(AlgorithmConstraints constraints) {241// the constraints object is immutable242this.algorithmConstraints = constraints;243}244245/**246* Gets the endpoint identification algorithm.247*248* @return the endpoint identification algorithm, or null if none249* has been set.250*251* @see X509ExtendedTrustManager252* @see #setEndpointIdentificationAlgorithm(String)253*254* @since 1.7255*/256public String getEndpointIdentificationAlgorithm() {257return identificationAlgorithm;258}259260/**261* Sets the endpoint identification algorithm.262* <p>263* If the <code>algorithm</code> parameter is non-null or non-empty, the264* endpoint identification/verification procedures must be handled during265* SSL/TLS handshaking. This is to prevent man-in-the-middle attacks.266*267* @param algorithm The standard string name of the endpoint268* identification algorithm (or null). See Appendix A in the <a href=269* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">270* Java Cryptography Architecture API Specification & Reference </a>271* for information about standard algorithm names.272*273* @see X509ExtendedTrustManager274*275* @since 1.7276*/277public void setEndpointIdentificationAlgorithm(String algorithm) {278this.identificationAlgorithm = algorithm;279}280281/**282* Sets the desired {@link SNIServerName}s of the Server Name283* Indication (SNI) parameter.284* <P>285* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s286* operating in client mode.287* <P>288* Note that the {@code serverNames} list is cloned289* to protect against subsequent modification.290*291* @param serverNames292* the list of desired {@link SNIServerName}s (or null)293*294* @throws NullPointerException if the {@code serverNames}295* contains {@code null} element296* @throws IllegalArgumentException if the {@code serverNames}297* contains more than one name of the same name type298*299* @see SNIServerName300* @see #getServerNames()301*302* @since 1.8303*/304public final void setServerNames(List<SNIServerName> serverNames) {305if (serverNames != null) {306if (!serverNames.isEmpty()) {307sniNames = new LinkedHashMap<>(serverNames.size());308for (SNIServerName serverName : serverNames) {309if (sniNames.put(serverName.getType(),310serverName) != null) {311throw new IllegalArgumentException(312"Duplicated server name of type " +313serverName.getType());314}315}316} else {317sniNames = Collections.<Integer, SNIServerName>emptyMap();318}319} else {320sniNames = null;321}322}323324/**325* Returns a {@link List} containing all {@link SNIServerName}s of the326* Server Name Indication (SNI) parameter, or null if none has been set.327* <P>328* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s329* operating in client mode.330* <P>331* For SSL/TLS connections, the underlying SSL/TLS provider332* may specify a default value for a certain server name type. In333* client mode, it is recommended that, by default, providers should334* include the server name indication whenever the server can be located335* by a supported server name type.336* <P>337* It is recommended that providers initialize default Server Name338* Indications when creating {@code SSLSocket}/{@code SSLEngine}s.339* In the following examples, the server name could be represented by an340* instance of {@link SNIHostName} which has been initialized with the341* hostname "www.example.com" and type342* {@link StandardConstants#SNI_HOST_NAME}.343*344* <pre>345* Socket socket =346* sslSocketFactory.createSocket("www.example.com", 443);347* </pre>348* or349* <pre>350* SSLEngine engine =351* sslContext.createSSLEngine("www.example.com", 443);352* </pre>353* <P>354*355* @return null or an immutable list of non-null {@link SNIServerName}s356*357* @see List358* @see #setServerNames(List)359*360* @since 1.8361*/362public final List<SNIServerName> getServerNames() {363if (sniNames != null) {364if (!sniNames.isEmpty()) {365return Collections.<SNIServerName>unmodifiableList(366new ArrayList<>(sniNames.values()));367} else {368return Collections.<SNIServerName>emptyList();369}370}371372return null;373}374375/**376* Sets the {@link SNIMatcher}s of the Server Name Indication (SNI)377* parameter.378* <P>379* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s380* operating in server mode.381* <P>382* Note that the {@code matchers} collection is cloned to protect383* against subsequent modification.384*385* @param matchers386* the collection of {@link SNIMatcher}s (or null)387*388* @throws NullPointerException if the {@code matchers}389* contains {@code null} element390* @throws IllegalArgumentException if the {@code matchers}391* contains more than one name of the same name type392*393* @see Collection394* @see SNIMatcher395* @see #getSNIMatchers()396*397* @since 1.8398*/399public final void setSNIMatchers(Collection<SNIMatcher> matchers) {400if (matchers != null) {401if (!matchers.isEmpty()) {402sniMatchers = new HashMap<>(matchers.size());403for (SNIMatcher matcher : matchers) {404if (sniMatchers.put(matcher.getType(),405matcher) != null) {406throw new IllegalArgumentException(407"Duplicated server name of type " +408matcher.getType());409}410}411} else {412sniMatchers = Collections.<Integer, SNIMatcher>emptyMap();413}414} else {415sniMatchers = null;416}417}418419/**420* Returns a {@link Collection} containing all {@link SNIMatcher}s of the421* Server Name Indication (SNI) parameter, or null if none has been set.422* <P>423* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s424* operating in server mode.425* <P>426* For better interoperability, providers generally will not define427* default matchers so that by default servers will ignore the SNI428* extension and continue the handshake.429*430* @return null or an immutable collection of non-null {@link SNIMatcher}s431*432* @see SNIMatcher433* @see #setSNIMatchers(Collection)434*435* @since 1.8436*/437public final Collection<SNIMatcher> getSNIMatchers() {438if (sniMatchers != null) {439if (!sniMatchers.isEmpty()) {440return Collections.<SNIMatcher>unmodifiableList(441new ArrayList<>(sniMatchers.values()));442} else {443return Collections.<SNIMatcher>emptyList();444}445}446447return null;448}449450/**451* Sets whether the local cipher suites preference should be honored.452*453* @param honorOrder whether local cipher suites order in454* {@code #getCipherSuites} should be honored during455* SSL/TLS handshaking.456*457* @see #getUseCipherSuitesOrder()458*459* @since 1.8460*/461public final void setUseCipherSuitesOrder(boolean honorOrder) {462this.preferLocalCipherSuites = honorOrder;463}464465/**466* Returns whether the local cipher suites preference should be honored.467*468* @return whether local cipher suites order in {@code #getCipherSuites}469* should be honored during SSL/TLS handshaking.470*471* @see #setUseCipherSuitesOrder(boolean)472*473* @since 1.8474*/475public final boolean getUseCipherSuitesOrder() {476return preferLocalCipherSuites;477}478479/**480* Returns a prioritized array of application-layer protocol names that481* can be negotiated over the SSL/TLS/DTLS protocols.482* <p>483* The array could be empty (zero-length), in which case protocol484* indications will not be used.485* <p>486* This method will return a new array each time it is invoked.487*488* @return a non-null, possibly zero-length array of application protocol489* {@code String}s. The array is ordered based on protocol490* preference, with {@code protocols[0]} being the most preferred.491* @see #setApplicationProtocols492* @since 8493*/494public String[] getApplicationProtocols() {495return applicationProtocols.clone();496}497498/**499* Sets the prioritized array of application-layer protocol names that500* can be negotiated over the SSL/TLS/DTLS protocols.501* <p>502* If application-layer protocols are supported by the underlying503* SSL/TLS implementation, this method configures which values can504* be negotiated by protocols such as <a505* href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the506* Application Layer Protocol Negotiation (ALPN).507* <p>508* If this end of the connection is expected to offer application protocol509* values, all protocols configured by this method will be sent to the510* peer.511* <p>512* If this end of the connection is expected to select the application513* protocol value, the {@code protocols} configured by this method are514* compared with those sent by the peer. The first matched value becomes515* the negotiated value. If none of the {@code protocols} were actually516* requested by the peer, the underlying protocol will determine what517* action to take. (For example, ALPN will send a518* {@code "no_application_protocol"} alert and terminate the connection.)519*520* @implSpec521* This method will make a copy of the {@code protocols} array.522*523* @param protocols an ordered array of application protocols,524* with {@code protocols[0]} being the most preferred.525* If the array is empty (zero-length), protocol526* indications will not be used.527* @throws IllegalArgumentException if protocols is null, or if528* any element in a non-empty array is null or an529* empty (zero-length) string530* @see #getApplicationProtocols531* @since 8532*/533public void setApplicationProtocols(String[] protocols) {534if (protocols == null) {535throw new IllegalArgumentException("protocols was null");536}537538String[] tempProtocols = protocols.clone();539540for (String p : tempProtocols) {541if (p == null || p.equals("")) {542throw new IllegalArgumentException(543"An element of protocols was null/empty");544}545}546applicationProtocols = tempProtocols;547}548}549550551