@@ -101,10 +101,14 @@ public abstract class SecurityHelper {
101
101
private static String BC_PROVIDER_CLASS = "org.bouncycastle.jce.provider.BouncyCastleProvider" ;
102
102
private static String BC_PROVIDER_NAME = "BC" ;
103
103
static boolean setBouncyCastleProvider = true ; // (package access for tests)
104
- static Provider securityProvider ; // 'BC' provider (package access for tests)
104
+ static volatile Provider securityProvider ; // 'BC' provider (package access for tests)
105
105
private static volatile Boolean registerProvider = null ;
106
106
static final Map <String , Class > implEngines = new ConcurrentHashMap <String , Class >(16 , 0.75f , 1 );
107
107
108
+ private static String BCJSSE_PROVIDER_CLASS = "org.bouncycastle.jsse.provider.BouncyCastleJsseProvider" ;
109
+ static boolean setJsseBouncyCastleProvider = true ;
110
+ static volatile Provider jsseProvider ;
111
+
108
112
/**
109
113
* inject under a given name a cipher. also ensures that the registered
110
114
* classes are getting used.
@@ -128,15 +132,32 @@ public static void addSignature(String name, Class<? extends SignatureSpi> clazz
128
132
}
129
133
130
134
public static Provider getSecurityProvider () {
131
- if ( setBouncyCastleProvider && securityProvider == null ) {
135
+ Provider provider = securityProvider ;
136
+ if ( setBouncyCastleProvider && provider == null ) {
137
+ synchronized (SecurityHelper .class ) {
138
+ provider = securityProvider ;
139
+ if ( setBouncyCastleProvider && provider == null ) {
140
+ provider = setBouncyCastleProvider ();
141
+ setBouncyCastleProvider = false ;
142
+ }
143
+ }
144
+ }
145
+ doRegisterProvider (provider );
146
+ return provider ;
147
+ }
148
+
149
+ static Provider getJsseProvider () {
150
+ Provider provider = jsseProvider ;
151
+ if ( setJsseBouncyCastleProvider && provider == null ) {
132
152
synchronized (SecurityHelper .class ) {
133
- if ( setBouncyCastleProvider && securityProvider == null ) {
134
- setBouncyCastleProvider (); setBouncyCastleProvider = false ;
153
+ provider = jsseProvider ;
154
+ if ( setJsseBouncyCastleProvider && provider == null ) {
155
+ provider = jsseProvider = newBouncyCastleProvider (BCJSSE_PROVIDER_CLASS );
156
+ setJsseBouncyCastleProvider = false ;
135
157
}
136
158
}
137
159
}
138
- doRegisterProvider ();
139
- return securityProvider ;
160
+ return provider ;
140
161
}
141
162
142
163
static final boolean SPI_ACCESSIBLE ;
@@ -170,20 +191,22 @@ static Provider getSecurityProviderIfAccessible() {
170
191
}
171
192
172
193
public static synchronized void setSecurityProvider (final Provider provider ) {
173
- if ( provider != null ) OpenSSL .debug ("using provider: " + provider );
194
+ if ( provider != null ) OpenSSL .debug ("using (security) provider: " + provider );
174
195
securityProvider = provider ;
175
196
}
176
197
177
- static synchronized void setBouncyCastleProvider () {
178
- setSecurityProvider ( newBouncyCastleProvider () );
198
+ static synchronized Provider setBouncyCastleProvider () {
199
+ Provider provider = newBouncyCastleProvider (BC_PROVIDER_CLASS );
200
+ setSecurityProvider (provider );
201
+ return provider ;
179
202
}
180
203
181
- private static Provider newBouncyCastleProvider () {
204
+ private static Provider newBouncyCastleProvider (final String klass ) {
182
205
try {
183
- return (Provider ) Class .forName (BC_PROVIDER_CLASS ).newInstance ();
206
+ return (Provider ) Class .forName (klass ).newInstance ();
184
207
}
185
208
catch (Throwable ignored ) {
186
- OpenSSL .debug ("can not instantiate bouncy-castle provider: " , ignored );
209
+ OpenSSL .debug ("can not instantiate bouncy-castle provider (" + klass + ") " , ignored );
187
210
}
188
211
return null ;
189
212
}
@@ -203,7 +226,7 @@ public static boolean isProviderRegistered() {
203
226
return Security .getProvider (securityProvider .getName ()) != null ;
204
227
}
205
228
206
- private static void doRegisterProvider () {
229
+ private static void doRegisterProvider (final Provider securityProvider ) {
207
230
if ( registerProvider != null ) {
208
231
synchronized (SecurityHelper .class ) {
209
232
final Boolean register = registerProvider ;
@@ -640,20 +663,20 @@ static SecretKeyFactory getSecretKeyFactory(final String algorithm, final Provid
640
663
);
641
664
}
642
665
643
- private static boolean providerSSLContext = false ; // BC does not implement + JDK default is fine
666
+ private static boolean providerSSLContext = false ; // NOTE: disabled for now due issues
644
667
645
668
public static SSLContext getSSLContext (final String protocol )
646
669
throws NoSuchAlgorithmException {
647
670
try {
648
- if ( providerSSLContext ) {
649
- final Provider provider = getSecurityProviderIfAccessible ();
671
+ if ( providerSSLContext && ! "SSL" . equals ( protocol ) ) { // only TLS versions with BC JSSE
672
+ final Provider provider = getJsseProvider ();
650
673
if ( provider != null ) {
651
674
return getSSLContext (protocol , provider );
652
675
}
653
676
}
654
677
}
655
678
catch (NoSuchAlgorithmException e ) { }
656
- return SSLContext .getInstance (protocol );
679
+ return SSLContext .getInstance (protocol ); // built-in SunJSSE provider on HotSpot
657
680
}
658
681
659
682
private static SSLContext getSSLContext (final String protocol , final Provider provider )
0 commit comments