1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.common.digest;
22
23 import io.netty.handler.ssl.ClientAuth;
24 import io.netty.handler.ssl.OpenSsl;
25 import io.netty.handler.ssl.SslContext;
26 import io.netty.handler.ssl.SslContextBuilder;
27
28 import javax.net.ssl.KeyManagerFactory;
29 import javax.net.ssl.SSLContext;
30 import javax.net.ssl.SSLException;
31 import java.security.NoSuchAlgorithmException;
32 import java.security.NoSuchProviderException;
33 import java.security.Provider;
34 import java.security.SecureRandom;
35 import java.security.Security;
36 import java.security.cert.X509Certificate;
37 import java.util.List;
38
39 public class WaarpBC {
40 public static final String PROTOCOL = "TLS";
41 public static final long DEFAULT_SESSIONCACHE_TIMEOUTSEC = 60;
42 public static final long DEFAULT_SESSIONCACHE_SIZE = 20480;
43 private static volatile boolean initialized = false;
44 private static boolean specialSecureRandom = false;
45
46 static {
47 initializedTlsContext();
48 }
49
50 public static void initializedTlsContext() {
51 try {
52 if (!initialized) {
53 addBcProvider();
54 registerRandomSecure();
55 initialized = true;
56 }
57 } catch (final Throwable throwable) {
58 throwable.printStackTrace();
59 System.err
60 .println("Error occurs at startup: " +
61 throwable.getMessage());
62 }
63 }
64
65
66
67
68 private static void addBcProvider() {
69 OpenSsl.isAvailable();
70 }
71
72
73
74
75
76
77 private static void registerRandomSecure() {
78 if (System.getProperty("os.name").contains("Windows")) {
79 final Provider provider = Security.getProvider("SunMSCAPI");
80 if (provider != null) {
81 Security.removeProvider(provider.getName());
82 Security.insertProviderAt(provider, 1);
83 specialSecureRandom = true;
84 }
85 } else {
86 System.setProperty("java.security.egd", "file:/dev/./urandom");
87 final Provider provider = Security.getProvider("SUN");
88 final String type = "SecureRandom";
89 final String alg = "NativePRNGNonBlocking";
90 if (provider != null) {
91 final String name = String.format("%s.%s", type, alg);
92 final Provider.Service service = provider.getService(type, alg);
93 if (service != null) {
94 Security.insertProviderAt(
95 new Provider(name, provider.getVersion(), "Waarp quick fix for SecureRandom using urandom") {
96 private static final long serialVersionUID = 1001L;
97
98 {
99 System.setProperty(name, service.getClassName());
100 }
101
102 }, 1);
103 specialSecureRandom = true;
104 }
105 }
106 }
107 }
108
109 public static SecureRandom getSecureRandom() {
110 if (!specialSecureRandom) {
111 return new SecureRandom();
112 }
113 if (System.getProperty("os.name").contains("Windows")) {
114 try {
115 return SecureRandom.getInstance("Windows-PRNG", "SunMSCAPI");
116 } catch (final NoSuchAlgorithmException e) {
117 return new SecureRandom();
118 } catch (final NoSuchProviderException e) {
119 return new SecureRandom();
120 }
121 } else {
122 try {
123 return SecureRandom.getInstance("NativePRNGNonBlocking", "SUN");
124 } catch (final NoSuchAlgorithmException e) {
125 return new SecureRandom();
126 } catch (final NoSuchProviderException e) {
127 return new SecureRandom();
128 }
129 }
130 }
131
132 public static SslContext getInstanceForServer(final KeyManagerFactory keyManagerFactory,
133 final X509Certificate[] x509Certificates,
134 final boolean clientNeedAuthentication,
135 final boolean startTls, final List<String> ciphers,
136 final String... protocols) throws SSLException {
137 final SslContextBuilder builder =
138 SslContextBuilder.forServer(keyManagerFactory).sslProvider(SslContext.defaultServerProvider());
139 if (x509Certificates != null) {
140 builder.trustManager(x509Certificates);
141 }
142 builder.clientAuth(clientNeedAuthentication? ClientAuth.REQUIRE : ClientAuth.NONE);
143 if (ciphers != null && !ciphers.isEmpty()) {
144 builder.ciphers(ciphers);
145 }
146 if (protocols != null && protocols.length > 0) {
147 builder.protocols(protocols);
148 }
149 builder.sessionCacheSize(DEFAULT_SESSIONCACHE_SIZE).sessionTimeout(DEFAULT_SESSIONCACHE_TIMEOUTSEC)
150 .startTls(startTls);
151 return builder.build();
152 }
153
154 public static SslContext getInstanceForClient(final KeyManagerFactory keyManagerFactory,
155 final X509Certificate[] x509Certificates)
156 throws NoSuchAlgorithmException, NoSuchProviderException, SSLException {
157 final SslContextBuilder builder =
158 SslContextBuilder.forClient().sslProvider(SslContext.defaultClientProvider())
159 .keyManager(keyManagerFactory);
160 if (x509Certificates != null) {
161 builder.trustManager(x509Certificates);
162 }
163 builder.sessionCacheSize(DEFAULT_SESSIONCACHE_SIZE).sessionTimeout(DEFAULT_SESSIONCACHE_TIMEOUTSEC);
164 return builder.build();
165 }
166
167 public static SSLContext getInstanceJDK() throws NoSuchAlgorithmException {
168 return SSLContext.getInstance(PROTOCOL);
169 }
170
171 private WaarpBC() {
172
173 }
174 }