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 final String[] preferredProtocols = {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};
247 String[] availableProtocols = null;
248
249 SSLSocket socket = null;
250
251 try {
252 final SSLSocketFactory factory = sslCtxt.getSocketFactory();
253 socket = (SSLSocket) factory.createSocket();
254
255 availableProtocols = socket.getSupportedProtocols();
256 Arrays.sort(availableProtocols);
257 } catch (Exception ex) {
258 LOGGER.debug("Error getting protocol list, using TLSv1", ex);
259 return new String[]{"TLSv1"};
260 } finally {
261 if (socket != null) {
262 try {
263 socket.close();
264 } catch (IOException ex) {
265 LOGGER.trace("Error closing socket", ex);
266 }
267 }
268 }
269
270 final List<String> aa = new ArrayList<String>();
271 for (String preferredProtocol : preferredProtocols) {
272 final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
273 if (idx >= 0) {
274 aa.add(preferredProtocol);
275 }
276 }
277
278 return aa.toArray(new String[0]);
279 }
280
281
282
283
284 private SSLContext sslCtxt;
285
286
287
288 private String[] protocols;
289 }