1 package org.owasp.dependencycheck.utils;
2
3 import java.io.IOException;
4 import java.net.InetAddress;
5 import java.net.Socket;
6 import java.security.KeyManagementException;
7 import java.security.NoSuchAlgorithmException;
8 import java.security.SecureRandom;
9 import java.util.ArrayList;
10 import java.util.Arrays;
11 import java.util.List;
12 import javax.net.ssl.KeyManager;
13 import javax.net.ssl.SSLContext;
14 import javax.net.ssl.SSLSocket;
15 import javax.net.ssl.SSLSocketFactory;
16 import javax.net.ssl.TrustManager;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20
21
22
23
24
25
26
27
28
29
30 public class SSLSocketFactoryEx extends SSLSocketFactory {
31
32
33
34
35 private static final Logger LOGGER = LoggerFactory.getLogger(SSLSocketFactoryEx.class);
36
37
38
39
40
41
42
43
44 public SSLSocketFactoryEx() throws NoSuchAlgorithmException, KeyManagementException {
45 initSSLSocketFactoryEx(null, null, null);
46 }
47
48
49
50
51
52
53
54
55
56
57
58 public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
59 initSSLSocketFactoryEx(km, tm, random);
60 }
61
62
63
64
65
66
67
68
69
70 public SSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException {
71 initSSLSocketFactoryEx(ctx);
72 }
73
74
75
76
77
78
79 @Override
80 public String[] getDefaultCipherSuites() {
81 return sslCtxt.getSocketFactory().getDefaultCipherSuites();
82 }
83
84
85
86
87
88
89 @Override
90 public String[] getSupportedCipherSuites() {
91 return sslCtxt.getSocketFactory().getSupportedCipherSuites();
92 }
93
94
95
96
97
98
99 public String[] getDefaultProtocols() {
100 return Arrays.copyOf(protocols, protocols.length);
101 }
102
103
104
105
106
107
108 public String[] getSupportedProtocols() {
109 return Arrays.copyOf(protocols, protocols.length);
110 }
111
112
113
114
115
116
117
118
119
120
121
122 @Override
123 public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
124 final SSLSocketFactory factory = sslCtxt.getSocketFactory();
125 final SSLSocket ss = (SSLSocket) factory.createSocket(s, host, port, autoClose);
126
127 ss.setEnabledProtocols(protocols);
128
129 return ss;
130 }
131
132
133
134
135
136
137
138
139
140
141
142 @Override
143 public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
144 final SSLSocketFactory factory = sslCtxt.getSocketFactory();
145 final SSLSocket ss = (SSLSocket) factory.createSocket(address, port, localAddress, localPort);
146
147 ss.setEnabledProtocols(protocols);
148
149 return ss;
150 }
151
152
153
154
155
156
157
158
159
160
161
162 @Override
163 public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
164 final SSLSocketFactory factory = sslCtxt.getSocketFactory();
165 final SSLSocket ss = (SSLSocket) factory.createSocket(host, port, localHost, localPort);
166
167 ss.setEnabledProtocols(protocols);
168
169 return ss;
170 }
171
172
173
174
175
176
177
178
179
180 @Override
181 public Socket createSocket(InetAddress host, int port) throws IOException {
182 final SSLSocketFactory factory = sslCtxt.getSocketFactory();
183 final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
184
185 ss.setEnabledProtocols(protocols);
186
187 return ss;
188 }
189
190
191
192
193
194
195
196
197
198 @Override
199 public Socket createSocket(String host, int port) throws IOException {
200 final SSLSocketFactory factory = sslCtxt.getSocketFactory();
201 final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
202
203 ss.setEnabledProtocols(protocols);
204
205 return ss;
206 }
207
208
209
210
211
212
213
214
215
216
217
218 private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)
219 throws NoSuchAlgorithmException, KeyManagementException {
220 sslCtxt = SSLContext.getInstance("TLS");
221 sslCtxt.init(km, tm, random);
222
223 protocols = getProtocolList();
224 }
225
226
227
228
229
230
231
232
233
234 private void initSSLSocketFactoryEx(SSLContext ctx)
235 throws NoSuchAlgorithmException, KeyManagementException {
236 sslCtxt = ctx;
237 protocols = getProtocolList();
238 }
239
240
241
242
243
244
245 protected String[] getProtocolList() {
246 SSLSocket socket = null;
247 String[] availableProtocols = null;
248 final String[] preferredProtocols = Settings.getString(
249 Settings.KEYS.DOWNLOADER_TLS_PROTOCOL_LIST,
250 "TLSv1,TLSv1.1,TLSv1.2,TLSv1.3")
251 .split(",");
252 try {
253 final SSLSocketFactory factory = sslCtxt.getSocketFactory();
254 socket = (SSLSocket) factory.createSocket();
255
256 availableProtocols = socket.getSupportedProtocols();
257 Arrays.sort(availableProtocols);
258 if (LOGGER.isDebugEnabled()) {
259 LOGGER.debug("Available Protocols:");
260 for (String p : availableProtocols) {
261 LOGGER.debug(p);
262 }
263 }
264 } catch (Exception ex) {
265 LOGGER.debug("Error getting protocol list, using TLSv1", ex);
266 return new String[]{"TLSv1"};
267 } finally {
268 if (socket != null) {
269 try {
270 socket.close();
271 } catch (IOException ex) {
272 LOGGER.trace("Error closing socket", ex);
273 }
274 }
275 }
276
277 final List<String> aa = new ArrayList<String>();
278 for (String preferredProtocol : preferredProtocols) {
279 final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
280 if (idx >= 0) {
281 aa.add(preferredProtocol);
282 }
283 }
284
285 return aa.toArray(new String[0]);
286 }
287
288
289
290
291 private SSLContext sslCtxt;
292
293
294
295 private String[] protocols;
296 }