View Javadoc
1   package org.sentrysoftware.http;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * HTTP Java Client
6    * ჻჻჻჻჻჻
7    * Copyright (C) 2023 - 2024 Sentry Software
8    * ჻჻჻჻჻჻
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   *
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
21   */
22  
23  import java.io.IOException;
24  import java.net.InetAddress;
25  import java.net.Socket;
26  
27  import javax.net.ssl.SSLSocket;
28  import javax.net.ssl.SSLSocketFactory;
29  
30  /**
31   * A {@link SSLSocketFactory} which uses an existing {@link SSLSocketFactory} to delegate its operations to and overrides the
32   * {@link javax.net.ssl.SSLSocket#getEnabledProtocols() enabled protocols} to the protocols that were passed to its
33   * {@link #ProtocolOverridingSSLSocketFactory(javax.net.ssl.SSLSocketFactory, String[]) constructor}
34   *
35   */
36  public class ProtocolOverridingSSLSocketFactory extends SSLSocketFactory {
37  
38  	private final SSLSocketFactory underlyingSSLSocketFactory;
39  	private final String[] enabledProtocols;
40  
41  	/**
42  	 * Constructs a {@code ProtocolOverridingSSLSocketFactory} with the given
43  	 * delegate {@link SSLSocketFactory} and array of enabled protocols.
44  	 *
45  	 * @param delegate         The underlying {@link SSLSocketFactory} to delegate operations to.
46  	 * @param enabledProtocols The array of protocols to be set as enabled protocols.
47  	 */
48  	public ProtocolOverridingSSLSocketFactory(final SSLSocketFactory delegate, final String[] enabledProtocols) {
49  		this.underlyingSSLSocketFactory = delegate;
50  		this.enabledProtocols = enabledProtocols;
51  	}
52  
53  	@Override
54  	public String[] getDefaultCipherSuites() {
55  		return underlyingSSLSocketFactory.getDefaultCipherSuites();
56  	}
57  
58  	@Override
59  	public String[] getSupportedCipherSuites() {
60  		return underlyingSSLSocketFactory.getSupportedCipherSuites();
61  	}
62  
63  	@Override
64  	public Socket createSocket(final Socket socket, final String host, final int port, final boolean autoClose) throws IOException {
65  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(socket, host, port, autoClose);
66  		return overrideProtocol(underlyingSocket);
67  	}
68  
69  	@Override
70  	public Socket createSocket(final String host, final int port) throws IOException {
71  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port);
72  		return overrideProtocol(underlyingSocket);
73  	}
74  
75  	@Override
76  	public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort) throws IOException {
77  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port, localAddress, localPort);
78  		return overrideProtocol(underlyingSocket);
79  	}
80  
81  	@Override
82  	public Socket createSocket(final InetAddress host, final int port) throws IOException {
83  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port);
84  		return overrideProtocol(underlyingSocket);
85  	}
86  
87  	@Override
88  	public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress, final int localPort) throws IOException {
89  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port, localAddress, localPort);
90  		return overrideProtocol(underlyingSocket);
91  	}
92  
93  	/**
94  	 * Set the {@link javax.net.ssl.SSLSocket#getEnabledProtocols() enabled protocols} to {@link #enabledProtocols} if the <code>socket</code> is a
95  	 * {@link SSLSocket}
96  	 *
97  	 * @param socket The Socket
98  	 * @return the amended socket
99  	 **/
100 	private Socket overrideProtocol(final Socket socket) {
101 		if (socket instanceof SSLSocket && enabledProtocols != null && enabledProtocols.length > 0) {
102 			((SSLSocket)socket).setEnabledProtocols(enabledProtocols);
103 		}
104 		return socket;
105 	}
106 }