1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.crypto.ssl;
21
22 import io.netty.channel.Channel;
23 import io.netty.channel.socket.SocketChannel;
24 import io.netty.handler.ssl.SslContext;
25 import io.netty.handler.ssl.SslHandler;
26 import org.waarp.common.logging.WaarpLogger;
27 import org.waarp.common.logging.WaarpLoggerFactory;
28
29 import java.net.InetSocketAddress;
30 import java.security.cert.X509Certificate;
31 import java.util.List;
32
33 import static org.waarp.common.digest.WaarpBC.*;
34
35
36
37
38 public class WaarpSslContextFactory {
39
40
41
42
43 private static final WaarpLogger logger = WaarpLoggerFactory.getLogger(WaarpSslContextFactory.class);
44
45 private static final long DEFAULT_HANDSHAKE_TIMEOUT = 10000;
46 public static final String HAS_TRUST_MANAGER_IS_SERVER_MODE = "Has TrustManager? {} Is ServerMode? {}";
47
48 static {
49 initializedTlsContext();
50 }
51
52
53
54
55 private final SslContext serverContext;
56 private final SslContext serverContextStartTls;
57
58
59
60
61 private final SslContext clientContext;
62
63 private boolean needClientAuthentication;
64
65
66
67
68
69
70 public WaarpSslContextFactory(final WaarpSecureKeyStore ggSecureKeyStore) {
71
72 serverContext = initSslContextFactory(ggSecureKeyStore, true, false, null);
73 serverContextStartTls = initSslContextFactory(ggSecureKeyStore, true, true, null);
74 clientContext = initSslContextFactory(ggSecureKeyStore, false, false, null);
75 }
76
77
78
79
80
81
82
83
84
85 public WaarpSslContextFactory(final WaarpSecureKeyStore ggSecureKeyStore, final List<String> ciphers,
86 final String... protocols) {
87
88 serverContext = initSslContextFactory(ggSecureKeyStore, true, false, ciphers, protocols);
89 serverContextStartTls = initSslContextFactory(ggSecureKeyStore, true, true, ciphers, protocols);
90 clientContext = initSslContextFactory(ggSecureKeyStore, false, false, ciphers, protocols);
91 }
92
93
94
95
96
97
98
99 public WaarpSslContextFactory(final WaarpSecureKeyStore ggSecureKeyStore, final boolean serverMode) {
100 if (serverMode) {
101 serverContext = initSslContextFactory(ggSecureKeyStore, true, false, null);
102 serverContextStartTls = initSslContextFactory(ggSecureKeyStore, true, true, null);
103 clientContext = null;
104 } else {
105 clientContext = initSslContextFactory(ggSecureKeyStore, false, false, null);
106 serverContext = null;
107 serverContextStartTls = null;
108 }
109 }
110
111
112
113
114
115
116
117
118
119 public WaarpSslContextFactory(final WaarpSecureKeyStore ggSecureKeyStore, final boolean serverMode,
120 final List<String> ciphers, final String... protocols) {
121 if (serverMode) {
122 serverContext = initSslContextFactory(ggSecureKeyStore, true, false, ciphers, protocols);
123 serverContextStartTls = initSslContextFactory(ggSecureKeyStore, true, true, ciphers, protocols);
124 clientContext = null;
125 } else {
126 clientContext = initSslContextFactory(ggSecureKeyStore, false, false, ciphers, protocols);
127 serverContext = null;
128 serverContextStartTls = null;
129 }
130 }
131
132
133
134
135
136
137
138 private SslContext initSslContextFactory(final WaarpSecureKeyStore ggSecureKeyStore,
139 final boolean serverMode, final boolean startTls,
140 final List<String> ciphers, final String... protocols) {
141
142 final WaarpSecureTrustManagerFactory secureTrustManagerFactory =
143 ggSecureKeyStore.getSecureTrustManagerFactory();
144 needClientAuthentication = secureTrustManagerFactory.needAuthentication();
145 X509Certificate[] certificates = null;
146 if (secureTrustManagerFactory.hasTrustStore()) {
147 logger.debug("Has TrustManager");
148 certificates = secureTrustManagerFactory.getX509Certificates();
149 } else {
150 logger.debug("No TrustManager");
151 }
152 if (serverMode) {
153 try {
154 return getInstanceForServer(ggSecureKeyStore.getKeyManagerFactory(), certificates,
155 needClientAuthentication, startTls, ciphers, protocols);
156 } catch (final Throwable e) {
157 logger.error("Failed to initialize the server-side SSLContext {}", e.getMessage());
158 throw new Error("Failed to initialize the server-side SSLContext", e);
159 }
160 } else {
161 try {
162 return getInstanceForClient(ggSecureKeyStore.getKeyManagerFactory(), certificates);
163 } catch (final Throwable e) {
164 logger.error("Failed to initialize the client-side SSLContext {}", e.getMessage());
165 throw new Error("Failed to initialize the client-side SSLContext", e);
166 }
167 }
168 }
169
170
171
172
173 public final SslContext getServerContext() {
174 return serverContext;
175 }
176
177
178
179
180 public final SslContext getClientContext() {
181 return clientContext;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195 public final SslHandler createHandlerServer(final boolean needClientAuth, final Channel channel) {
196 logger.debug(HAS_TRUST_MANAGER_IS_SERVER_MODE, needClientAuth, true);
197 channel.config().setAutoRead(true);
198 final SslHandler sslHandler = getServerContext().newHandler(channel.alloc());
199 sslHandler.setHandshakeTimeoutMillis(DEFAULT_HANDSHAKE_TIMEOUT);
200 return sslHandler;
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214 public final SslHandler createHandlerServer(final boolean needClientAuth, final boolean startTls,
215 final Channel channel) {
216 logger.debug(HAS_TRUST_MANAGER_IS_SERVER_MODE, needClientAuth, true);
217 channel.config().setAutoRead(true);
218 final SslHandler sslHandler;
219 if (startTls) {
220 sslHandler = serverContextStartTls.newHandler(channel.alloc());
221 } else {
222 sslHandler = getServerContext().newHandler(channel.alloc());
223 }
224 sslHandler.setHandshakeTimeoutMillis(DEFAULT_HANDSHAKE_TIMEOUT);
225 return sslHandler;
226 }
227
228
229
230
231
232
233
234
235
236 public final SslHandler createHandlerClient(final SocketChannel channel) {
237 logger.debug(HAS_TRUST_MANAGER_IS_SERVER_MODE, false, false);
238 channel.config().setAutoRead(true);
239 final InetSocketAddress socketAddress = channel.remoteAddress();
240 final SslHandler sslHandler;
241 if (socketAddress != null) {
242 logger.debug("socket {} {}", socketAddress.getHostName(), socketAddress.getPort());
243 sslHandler = getClientContext().newHandler(channel.alloc(), socketAddress.getHostName(),
244 socketAddress.getPort());
245 } else {
246 sslHandler = getClientContext().newHandler(channel.alloc());
247 }
248 sslHandler.setHandshakeTimeoutMillis(DEFAULT_HANDSHAKE_TIMEOUT);
249 return sslHandler;
250 }
251
252
253
254
255 public final boolean needClientAuthentication() {
256 return needClientAuthentication;
257 }
258 }