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 HostnameVerifier hostnameVerifier;
78 /**
79 * @deprecated To be removed.
80 */
81 @Deprecated
82 private Factory<SSLEngine, TlsDetails> tlsDetailsFactory;
83 private boolean systemProperties;
84
85 /**
86 * Assigns {@link SSLContext} instance.
87 */
88 public ClientTlsStrategyBuilder setSslContext(final SSLContext sslContext) {
89 this.sslContext = sslContext;
90 return this;
91 }
92
93 /**
94 * Assigns enabled {@code TLS} versions.
95 */
96 public final ClientTlsStrategyBuilder setTlsVersions(final String... tlslVersions) {
97 this.tlsVersions = tlslVersions;
98 return this;
99 }
100
101 /**
102 * Assigns enabled {@code TLS} versions.
103 */
104 public final ClientTlsStrategyBuilder setTlsVersions(final TLS... tlslVersions) {
105 this.tlsVersions = new String[tlslVersions.length];
106 for (int i = 0; i < tlslVersions.length; i++) {
107 this.tlsVersions[i] = tlslVersions[i].id;
108 }
109 return this;
110 }
111
112 /**
113 * Assigns enabled ciphers.
114 */
115 public final ClientTlsStrategyBuilder setCiphers(final String... ciphers) {
116 this.ciphers = ciphers;
117 return this;
118 }
119
120 /**
121 * Assigns {@link SSLBufferMode} value.
122 */
123 public ClientTlsStrategyBuilder setSslBufferMode(final SSLBufferMode sslBufferMode) {
124 this.sslBufferMode = sslBufferMode;
125 return this;
126 }
127
128 /**
129 * Assigns {@link HostnameVerifier} instance.
130 */
131 public ClientTlsStrategyBuilder setHostnameVerifier(final HostnameVerifier hostnameVerifier) {
132 this.hostnameVerifier = hostnameVerifier;
133 return this;
134 }
135
136 /**
137 * Assigns {@link TlsDetails} {@link Factory} instance.
138 *
139 * @deprecated Do not use.
140 */
141 @Deprecated
142 public ClientTlsStrategyBuilder setTlsDetailsFactory(final Factory<SSLEngine, TlsDetails> tlsDetailsFactory) {
143 this.tlsDetailsFactory = tlsDetailsFactory;
144 return this;
145 }
146
147 /**
148 * Use system properties when creating and configuring default
149 * implementations.
150 */
151 public final ClientTlsStrategyBuilder useSystemProperties() {
152 this.systemProperties = true;
153 return this;
154 }
155
156 @SuppressWarnings("deprecation")
157 public TlsStrategy build() {
158 final SSLContext sslContextCopy;
159 if (sslContext != null) {
160 sslContextCopy = sslContext;
161 } else {
162 sslContextCopy = systemProperties ? SSLContexts.createSystemDefault() : SSLContexts.createDefault();
163 }
164 final String[] tlsVersionsCopy;
165 if (tlsVersions != null) {
166 tlsVersionsCopy = tlsVersions;
167 } else {
168 tlsVersionsCopy = systemProperties ? HttpsSupport.getSystemProtocols() : null;
169 }
170 final String[] ciphersCopy;
171 if (ciphers != null) {
172 ciphersCopy = ciphers;
173 } else {
174 ciphersCopy = systemProperties ? HttpsSupport.getSystemCipherSuits() : null;
175 }
176 return new DefaultClientTlsStrategy(
177 sslContextCopy,
178 tlsVersionsCopy,
179 ciphersCopy,
180 sslBufferMode != null ? sslBufferMode : SSLBufferMode.STATIC,
181 hostnameVerifier != null ? hostnameVerifier : HttpsSupport.getDefaultHostnameVerifier(),
182 tlsDetailsFactory);
183 }
184
185 }