1 module hunt.net.secure.conscrypt.OpenSSLContextImpl;
2 
3 
4 // dfmt off
5 version(WITH_HUNT_SECURITY):
6 // dfmt on
7 
8 import hunt.net.secure.conscrypt.ClientSessionContext;
9 import hunt.net.secure.conscrypt.ConscryptEngine;
10 import hunt.net.secure.conscrypt.NativeCrypto;
11 import hunt.net.secure.conscrypt.SSLParametersImpl;
12 import hunt.net.secure.conscrypt.ServerSessionContext;
13 
14 // import hunt.net.ssl.KeyManager;
15 import hunt.net.ssl.SSLContextSpi;
16 import hunt.net.ssl.SSLEngine;
17 
18 import hunt.net.KeyCertOptions;
19 
20 import hunt.Exceptions;
21 import hunt.logging;
22 // import hunt.security.Key;
23 
24 import std.array;
25 
26 
27 /**
28  * OpenSSL-backed SSLContext service provider interface.
29  *
30  * <p>Public to allow contruction via the provider framework.
31  *
32  */
33 abstract class OpenSSLContextImpl : SSLContextSpi {
34     /**
35      * The default SSLContextImpl for use with
36      * SSLContext.getInstance("Default"). Protected by the
37      * DefaultSSLContextImpl.class monitor.
38      */
39     private __gshared DefaultSSLContextImpl defaultSslContextImpl;
40 
41     /** TLS algorithm to initialize all sockets. */
42     private string[] algorithms;
43 
44     /** Client session cache. */
45     private ClientSessionContext clientSessionContext;
46 
47     /** Server session cache. */
48     private ServerSessionContext serverSessionContext;
49 
50     SSLParametersImpl sslParameters;
51 
52     /** Allows outside callers to get the preferred SSLContext. */
53     // static OpenSSLContextImpl getPreferred() {
54     //     return new TLSv12();
55     // }
56 
57     this(KeyCertOptions options) {
58         this.algorithms = null;
59         if (defaultSslContextImpl is null) {
60             // TODO: Tasks pending completion -@zhangxueping at 2019-12-17T22:17:15+08:00
61             // Create different sessionContext for client and server
62             clientSessionContext = new ClientSessionContext();
63             serverSessionContext = new ServerSessionContext();
64 
65             version(HUNT_NET_DEBUG) warning("Initializing OpenSSL Context...");
66 
67             if(options !is null) {
68                 string caFile = options.getCaFile();
69                 if(!caFile.empty()) {
70                     // serverSessionContext.setVerify();
71                     serverSessionContext.useCaCertificate(caFile, options.getCaPassword());
72                 }
73 
74                 serverSessionContext.useCertificate(options.getCertFile(), options.getKeyFile(),
75                     options.getCertPassword(), options.getKeyPassword());
76             }
77             
78             defaultSslContextImpl = cast(DefaultSSLContextImpl) this;
79         } else {
80             version(HUNT_NET_DEBUG) warning("Using existed defaultSslContextImpl");
81             clientSessionContext = defaultSslContextImpl.engineGetClientSessionContext();
82             serverSessionContext = defaultSslContextImpl.engineGetServerSessionContext();
83         }
84         sslParameters = new SSLParametersImpl(options, clientSessionContext,
85                 serverSessionContext, algorithms);
86     }
87 
88     // this(string[] algorithms, string certificate, string privatekey) {
89     //     this.algorithms = algorithms;
90     //     // clientSessionContext = new ClientSessionContext();
91     //     serverSessionContext = new ServerSessionContext(certificate, privatekey);
92     // }
93 
94     /**
95      * Constuctor for the DefaultSSLContextImpl.
96      */
97     // this(string certificate, string privatekey) {
98     //     // synchronized {
99     //         this.algorithms = null;
100     //         if (defaultSslContextImpl is null) {
101     //             clientSessionContext = new ClientSessionContext();
102     //             serverSessionContext = new ServerSessionContext(certificate, privatekey);
103     //             defaultSslContextImpl = cast(DefaultSSLContextImpl) this;
104     //         } else {
105     //             clientSessionContext = defaultSslContextImpl.engineGetClientSessionContext();
106     //             serverSessionContext = defaultSslContextImpl.engineGetServerSessionContext();
107     //         }
108     //         sslParameters = new SSLParametersImpl(defaultSslContextImpl.getKeyManagers(),
109     //                 defaultSslContextImpl.getTrustManagers(), clientSessionContext,
110     //                 serverSessionContext, algorithms);
111     //     // }
112     // }
113 
114     /**
115      * Initializes this {@code SSLContext} instance. All of the arguments are
116      * optional, and the security providers will be searched for the required
117      * implementations of the needed algorithms.
118      *
119      * @param kms the key sources or {@code null}
120      * @param tms the trust decision sources or {@code null}
121      * @param sr the randomness source or {@code null}
122      * @throws KeyManagementException if initializing this instance fails
123      */
124     override
125     // void engineInit(KeyManager[] kms, TrustManager[] tms) {
126     //     sslParameters = new SSLParametersImpl(
127     //             kms, tms, clientSessionContext, serverSessionContext, algorithms);
128     // }
129 
130     void engineInit(KeyCertOptions options) {
131         sslParameters = new SSLParametersImpl(options, clientSessionContext, serverSessionContext, algorithms);
132     }    
133 
134     // override
135     // SSLSocketFactory engineGetSocketFactory() {
136     //     if (sslParameters is null) {
137     //         throw new IllegalStateException("SSLContext is not initialized.");
138     //     }
139     //     // return Platform.wrapSocketFactoryIfNeeded(new OpenSSLSocketFactoryImpl(sslParameters));
140 
141     //     implementationMissing();
142     //     return null;
143     // }
144 
145     // override
146     // SSLServerSocketFactory engineGetServerSocketFactory() {
147     //     if (sslParameters is null) {
148     //         throw new IllegalStateException("SSLContext is not initialized.");
149     //     }
150     //     return new OpenSSLServerSocketFactoryImpl(sslParameters);
151     // }
152 
153     override
154     SSLEngine engineCreateSSLEngine(bool clientMode, string host, int port) {
155         if (sslParameters is null) {
156             throw new IllegalStateException("SSLContext is not initialized.");
157         }
158         SSLParametersImpl p = cast(SSLParametersImpl) sslParameters.clone();
159         p.setUseClientMode(clientMode);
160         return new ConscryptEngine(host, port, p);
161     }
162 
163     override
164     SSLEngine engineCreateSSLEngine(bool clientMode) {
165         if (sslParameters is null) {
166             throw new IllegalStateException("SSLContext is not initialized.");
167         }
168 
169         SSLParametersImpl p = cast(SSLParametersImpl) sslParameters.clone();
170         p.setUseClientMode(clientMode);
171 
172         return new ConscryptEngine(p);
173     }
174 
175     override
176     ServerSessionContext engineGetServerSessionContext() {
177         return serverSessionContext;
178     }
179 
180     override
181     ClientSessionContext engineGetClientSessionContext() {
182         return clientSessionContext;
183     }
184 
185     // /**
186     //  * Public to allow construction via the provider framework.
187     //  */
188     // static final class TLSv12 : OpenSSLContextImpl {
189     //     this() {
190     //         super(NativeCrypto.TLSV12_PROTOCOLS);
191     //     }
192     // }
193 
194     // /**
195     //  * Public to allow construction via the provider framework.
196     //  */
197     // static final class TLSv11 : OpenSSLContextImpl {
198     //     this() {
199     //         super(NativeCrypto.TLSV11_PROTOCOLS);
200     //     }
201     // }
202 
203     // /**
204     //  * Public to allow construction via the provider framework.
205     //  */
206     // static final class TLSv1 : OpenSSLContextImpl {
207     //     this() {
208     //         super(NativeCrypto.TLSV1_PROTOCOLS);
209     //     }
210     // }
211 }
212 
213 
214 
215 /**
216  * Support class for this package.
217  *
218  */
219 
220 final class DefaultSSLContextImpl : OpenSSLContextImpl {
221 
222     /**
223      * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
224      * DefaultSSLContextImpl.class monitor
225      */
226     // private static KeyManager[] KEY_MANAGERS;
227 
228     /**
229      * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
230      * DefaultSSLContextImpl.class monitor
231      */
232     // private static TrustManager[] TRUST_MANAGERS;
233 
234     /**
235      * DefaultSSLContextImpl delegates the work to the super class since there
236      * is no way to put a synchronized around both the call to super and the
237      * rest of this constructor to guarantee that we don't have races in
238      * creating the state shared between all default SSLContexts.
239      */
240     this(KeyCertOptions options) {
241         // warning("No certificates provided!");
242         super(options);
243     }
244 
245     // this(string certificate, string privatekey) {
246     //     super(certificate, privatekey);
247     // }
248 
249     // TODO javax.net.ssl.keyStoreProvider system property
250     // KeyManager[] getKeyManagers () {
251     //     if (KEY_MANAGERS !is null) {
252     //         return KEY_MANAGERS;
253     //     }
254     //     // find KeyStore, KeyManagers
255     //     // string keystore = System.getProperty("javax.net.ssl.keyStore");
256     //     // if (keystore is null) {
257     //     //     return null;
258     //     // }
259     //     // string keystorepwd = System.getProperty("javax.net.ssl.keyStorePassword");
260     //     // char[] pwd = (keystorepwd is null) ? null : keystorepwd.toCharArray();
261 
262     //     // KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
263     //     // InputStream is = null;
264     //     // try {
265     //     //     is = new BufferedInputStream(new FileInputStream(keystore));
266     //     //     ks.load(is, pwd);
267     //     // } finally {
268     //     //     if (is !is null) {
269     //     //         is.close();
270     //     //     }
271     //     // }
272 
273     //     // string kmfAlg = KeyManagerFactory.getDefaultAlgorithm();
274     //     // KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlg);
275     //     // kmf.init(ks, pwd);
276     //     // KEY_MANAGERS = kmf.getKeyManagers();
277     //     // implementationMissing();
278     //     return KEY_MANAGERS;
279     // }
280 
281     // TODO javax.net.ssl.trustStoreProvider system property
282     // TrustManager[] getTrustManagers() {
283     //     if (TRUST_MANAGERS !is null) {
284     //         return TRUST_MANAGERS;
285     //     }
286 
287     //     // find TrustStore, TrustManagers
288     //     // string keystore = System.getProperty("javax.net.ssl.trustStore");
289     //     // if (keystore is null) {
290     //     //     return null;
291     //     // }
292     //     // string keystorepwd = System.getProperty("javax.net.ssl.trustStorePassword");
293     //     // char[] pwd = (keystorepwd is null) ? null : keystorepwd.toCharArray();
294 
295     //     // // TODO Defaults: jssecacerts; cacerts
296     //     // KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
297     //     // InputStream is = null;
298     //     // try {
299     //     //     is = new BufferedInputStream(new FileInputStream(keystore));
300     //     //     ks.load(is, pwd);
301     //     // } finally {
302     //     //     if (is !is null) {
303     //     //         is.close();
304     //     //     }
305     //     // }
306     //     // string tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
307     //     // TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
308     //     // tmf.init(ks);
309     //     // TRUST_MANAGERS = tmf.getTrustManagers();
310 
311     //     // implementationMissing();
312     //     return TRUST_MANAGERS;
313     // }
314 
315     // override
316     // void engineInit(KeyManager[] kms, TrustManager[] tms) {
317     //     throw new KeyManagementException("Do not init() the default SSLContext ");
318     // }
319 }
320