View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.client5.http.ssl;
29  
30  import javax.net.ssl.HostnameVerifier;
31  import javax.net.ssl.SSLContext;
32  import javax.net.ssl.SSLEngine;
33  
34  import org.apache.hc.core5.function.Factory;
35  import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
36  import org.apache.hc.core5.http.ssl.TLS;
37  import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
38  import org.apache.hc.core5.reactor.ssl.TlsDetails;
39  import org.apache.hc.core5.ssl.SSLContexts;
40  
41  /**
42   * Builder for client {@link TlsStrategy} instances.
43   * <p>
44   * When a particular component is not explicitly set this class will
45   * use its default implementation. System properties will be taken
46   * into account when configuring the default implementations when
47   * {@link #useSystemProperties()} method is called prior to calling
48   * {@link #build()}.
49   * </p>
50   * <ul>
51   *  <li>ssl.TrustManagerFactory.algorithm</li>
52   *  <li>javax.net.ssl.trustStoreType</li>
53   *  <li>javax.net.ssl.trustStore</li>
54   *  <li>javax.net.ssl.trustStoreProvider</li>
55   *  <li>javax.net.ssl.trustStorePassword</li>
56   *  <li>ssl.KeyManagerFactory.algorithm</li>
57   *  <li>javax.net.ssl.keyStoreType</li>
58   *  <li>javax.net.ssl.keyStore</li>
59   *  <li>javax.net.ssl.keyStoreProvider</li>
60   *  <li>javax.net.ssl.keyStorePassword</li>
61   *  <li>https.protocols</li>
62   *  <li>https.cipherSuites</li>
63   * </ul>
64   *
65   * @since 5.0
66   */
67  public class ClientTlsStrategyBuilder {
68  
69      public static ClientTlsStrategyBuilder create() {
70          return new ClientTlsStrategyBuilder();
71      }
72  
73      private SSLContext sslContext;
74      private String[] tlsVersions;
75      private String[] ciphers;
76      private SSLBufferMode sslBufferMode;
77      private HostnameVerificationPolicy hostnameVerificationPolicy;
78      private HostnameVerifier hostnameVerifier;
79      private boolean systemProperties;
80  
81      /**
82       * Assigns {@link SSLContext} instance.
83       */
84      public ClientTlsStrategyBuilder setSslContext(final SSLContext sslContext) {
85          this.sslContext = sslContext;
86          return this;
87      }
88  
89      /**
90       * Assigns enabled {@code TLS} versions.
91       */
92      public final ClientTlsStrategyBuilder setTlsVersions(final String... tlslVersions) {
93          this.tlsVersions = tlslVersions;
94          return this;
95      }
96  
97      /**
98       * Assigns enabled {@code TLS} versions.
99       */
100     public final ClientTlsStrategyBuilder setTlsVersions(final TLS... tlslVersions) {
101         this.tlsVersions = new String[tlslVersions.length];
102         for (int i = 0; i < tlslVersions.length; i++) {
103             this.tlsVersions[i] = tlslVersions[i].id;
104         }
105         return this;
106     }
107 
108     /**
109      * Assigns enabled ciphers.
110      */
111     public final ClientTlsStrategyBuilder setCiphers(final String... ciphers) {
112         this.ciphers = ciphers;
113         return this;
114     }
115 
116     /**
117      * Assigns {@link SSLBufferMode} value.
118      */
119     public ClientTlsStrategyBuilder setSslBufferMode(final SSLBufferMode sslBufferMode) {
120         this.sslBufferMode = sslBufferMode;
121         return this;
122     }
123 
124     /**
125      * Assigns {@link HostnameVerificationPolicy} value.
126      */
127     public void setHostnameVerificationPolicy(final HostnameVerificationPolicy hostnameVerificationPolicy) {
128         this.hostnameVerificationPolicy = hostnameVerificationPolicy;
129     }
130 
131     /**
132      * Assigns {@link HostnameVerifier} instance.
133      */
134     public ClientTlsStrategyBuilder setHostnameVerifier(final HostnameVerifier hostnameVerifier) {
135         this.hostnameVerifier = hostnameVerifier;
136         return this;
137     }
138 
139     /**
140      * Assigns {@link TlsDetails} {@link Factory} instance.
141      *
142      * @deprecated Do not use. This method has no effect.
143      */
144     @Deprecated
145     public ClientTlsStrategyBuilder setTlsDetailsFactory(final Factory<SSLEngine, TlsDetails> tlsDetailsFactory) {
146         return this;
147     }
148 
149     /**
150      * Use system properties when creating and configuring default
151      * implementations.
152      */
153     public final ClientTlsStrategyBuilder useSystemProperties() {
154         this.systemProperties = true;
155         return this;
156     }
157 
158     public TlsStrategy build() {
159         final SSLContext sslContextCopy;
160         if (sslContext != null) {
161             sslContextCopy = sslContext;
162         } else {
163             sslContextCopy = systemProperties ? SSLContexts.createSystemDefault() : SSLContexts.createDefault();
164         }
165         final String[] tlsVersionsCopy;
166         if (tlsVersions != null) {
167             tlsVersionsCopy = tlsVersions;
168         } else {
169             tlsVersionsCopy = systemProperties ? HttpsSupport.getSystemProtocols() : null;
170         }
171         final String[] ciphersCopy;
172         if (ciphers != null) {
173             ciphersCopy = ciphers;
174         } else {
175             ciphersCopy = systemProperties ? HttpsSupport.getSystemCipherSuits() : null;
176         }
177         final HostnameVerificationPolicy hostnameVerificationPolicyCopy = hostnameVerificationPolicy != null ? hostnameVerificationPolicy :
178                 (hostnameVerifier == null ? HostnameVerificationPolicy.BUILTIN : HostnameVerificationPolicy.BOTH);
179         final HostnameVerifier hostnameVerifierCopy = hostnameVerifier != null ? hostnameVerifier :
180                 (hostnameVerificationPolicyCopy == HostnameVerificationPolicy.CLIENT || hostnameVerificationPolicyCopy == HostnameVerificationPolicy.BOTH ?
181                         HttpsSupport.getDefaultHostnameVerifier() : NoopHostnameVerifier.INSTANCE);
182         return new DefaultClientTlsStrategy(
183                 sslContextCopy,
184                 tlsVersionsCopy,
185                 ciphersCopy,
186                 sslBufferMode != null ? sslBufferMode : SSLBufferMode.STATIC,
187                 hostnameVerificationPolicyCopy,
188                 hostnameVerifierCopy);
189     }
190 
191 }