1 module hunt.net.secure.conscrypt.AbstractConscryptSSLContextFactory; 2 3 // dfmt off 4 version(WITH_HUNT_SECURITY): 5 // dfmt on 6 7 import hunt.net.secure.ProtocolSelector; 8 import hunt.net.secure.conscrypt.ConscryptALPNSelector; 9 import hunt.net.secure.SSLContextFactory; 10 import hunt.net.ssl; 11 12 import hunt.Exceptions; 13 import hunt.stream.ByteArrayInputStream; 14 import hunt.stream.Common; 15 import hunt.logging; 16 import hunt.net.KeyCertOptions; 17 // import hunt.security.cert.X509Certificate; 18 import hunt.util.DateTime; 19 import hunt.util.TypeUtils; 20 21 import std.array; 22 import std.datetime : Clock; 23 import std.datetime.stopwatch; 24 import std.typecons; 25 26 27 /** 28 * 29 */ 30 abstract class AbstractConscryptSSLContextFactory : SSLContextFactory { 31 32 private enum string provideName = "Conscrypt"; 33 private string[] supportedProtocols; 34 35 // static this() { 36 // // Provider provider = Conscrypt.newProvider(); 37 // // provideName = provider.getName(); 38 // // Security.addProvider(provider); 39 // // provideName = "Conscrypt"; 40 // infof("add Conscrypt security provider"); 41 // } 42 43 // static string getProvideName() { 44 // return provideName; 45 // } 46 47 SSLContext getSSLContextWithManager() { // KeyManager[] km, TrustManager[] tm 48 version(HUNT_NET_DEBUG) long start = Clock.currStdTime; 49 50 SSLContext sslContext = SSLContext.getInstance(null, "TLSv1.2"); 51 // sslContext.init(km, tm); // TODO: 52 53 version(HUNT_NET_DEBUG) { 54 long end = Clock.currStdTime; 55 long d = convert!(TimeUnit.HectoNanosecond, TimeUnit.Millisecond)(end - start); 56 tracef("creating Conscrypt SSL context spends %d ms", d); 57 } 58 return sslContext; 59 } 60 61 // SSLContext getSSLContext(InputStream inputStream, string keystorePassword, string keyPassword) { 62 // return getSSLContext(inputStream, keystorePassword, keyPassword, null, null, null); 63 // } 64 65 // SSLContext getSSLContext(InputStream inputStream, string keystorePassword, string keyPassword, 66 // string keyManagerFactoryType, string trustManagerFactoryType, string sslProtocol) { 67 // version(HUNT_NET_DEBUG) StopWatch sw = StopWatch(AutoStart.yes); 68 // SSLContext sslContext; 69 70 // // KeyStore ks = KeyStore.getInstance("JKS"); 71 // // ks.load(inputStream, keystorePassword !is null ? keystorePassword.toCharArray() : null); 72 73 // // // PKIX,SunX509 74 // // KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyManagerFactoryType is null ? "SunX509" : keyManagerFactoryType); 75 // // kmf.init(ks, keyPassword !is null ? keyPassword.toCharArray() : null); 76 77 // // TrustManagerFactory tmf = TrustManagerFactory.getInstance(trustManagerFactoryType is null ? "SunX509" : trustManagerFactoryType); 78 // // tmf.init(ks); 79 80 // // TLSv1 TLSv1.2 81 // sslContext = SSLContext.getInstance(sslProtocol.empty ? "TLSv1.2" : sslProtocol, provideName); 82 // // sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 83 84 // version(HUNT_NET_DEBUG) { 85 // sw.stop(); 86 // infof("creating Conscrypt SSL context spends %s ms", sw.peek.total!"msecs"); 87 // } 88 89 // implementationMissing(false); 90 // return sslContext; 91 // } 92 93 void initializeSslContext() { 94 implementationMissing(false); 95 } 96 97 SSLContext getSSLContext(KeyCertOptions options, string sslProtocol) { 98 version(HUNT_NET_DEBUG) { 99 StopWatch sw = StopWatch(AutoStart.yes); 100 } 101 102 SSLContext sslContext; 103 104 // // PKIX,SunX509 105 // KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyManagerFactoryType is null ? "SunX509" : keyManagerFactoryType); 106 // kmf.init(ks, keyPassword !is null ? keyPassword.toCharArray() : null); 107 108 // TrustManagerFactory tmf = TrustManagerFactory.getInstance(trustManagerFactoryType is null ? "SunX509" : trustManagerFactoryType); 109 // tmf.init(ks); 110 111 // TLSv1 TLSv1.2 112 // sslContext = SSLContext.getInstance(options.getCertFile(), options.getKeyFile(), 113 // sslProtocol.empty ? "TLSv1.2" : sslProtocol, provideName); 114 sslContext = SSLContext.getInstance(options, sslProtocol.empty ? "TLSv1.2" : sslProtocol); 115 // sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 116 sslContext.initialize(options); 117 118 version(HUNT_NET_DEBUG) { 119 infof("creating Conscrypt SSL context spends %s ms", sw.peek.total!"msecs"); 120 sw.stop(); 121 } 122 return sslContext; 123 } 124 125 SSLContext getSSLContext() { 126 throw new NotImplementedException(); 127 } 128 129 130 Pair!(SSLEngine, ProtocolSelector) createSSLEngine(bool clientMode) { 131 SSLEngine sslEngine = getSSLContext().createSSLEngine(clientMode); 132 // sslEngine.setUseClientMode(clientMode); 133 return makePair(sslEngine, cast(ProtocolSelector)new ConscryptALPNSelector(sslEngine, supportedProtocols)); 134 } 135 136 Pair!(SSLEngine, ProtocolSelector) createSSLEngine(bool clientMode, string peerHost, int peerPort) { 137 SSLEngine sslEngine = getSSLContext().createSSLEngine(clientMode, peerHost, peerPort); 138 // sslEngine.setUseClientMode(clientMode); 139 return makePair(sslEngine, cast(ProtocolSelector)new ConscryptALPNSelector(sslEngine, supportedProtocols)); 140 } 141 142 string[] getSupportedProtocols() { 143 return supportedProtocols; 144 } 145 146 void setSupportedProtocols(string[] supportedProtocols) { 147 this.supportedProtocols = supportedProtocols; 148 } 149 } 150 151 /** 152 * 153 */ 154 class NoCheckConscryptSSLContextFactory : AbstractConscryptSSLContextFactory { 155 156 override SSLContext getSSLContext() { 157 try { 158 return getSSLContextWithManager(); 159 } catch (Exception e) { 160 errorf("get SSL context error: %s", e.msg); 161 version(HUNT_DEBUG) error(e); 162 return null; 163 } 164 } 165 166 alias getSSLContext = AbstractConscryptSSLContextFactory.getSSLContext; 167 } 168 169 /** 170 * 171 */ 172 class FileCredentialConscryptSSLContextFactory : AbstractConscryptSSLContextFactory { 173 174 private KeyCertOptions _options; 175 176 this(KeyCertOptions options) { 177 this._options = options; 178 } 179 180 override SSLContext getSSLContext() { 181 try { 182 return getSSLContext(_options, "TLSv1.2"); 183 } catch (Exception e) { 184 errorf("get SSL context error: %s", e.msg); 185 version(HUNT_DEBUG) error(e); 186 return null; 187 } 188 } 189 190 alias getSSLContext = AbstractConscryptSSLContextFactory.getSSLContext; 191 }