@@ -101,10 +101,14 @@ public abstract class SecurityHelper {
101101 private static String BC_PROVIDER_CLASS = "org.bouncycastle.jce.provider.BouncyCastleProvider" ;
102102 private static String BC_PROVIDER_NAME = "BC" ;
103103 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)
105105 private static volatile Boolean registerProvider = null ;
106106 static final Map <String , Class > implEngines = new ConcurrentHashMap <String , Class >(16 , 0.75f , 1 );
107107
108+ private static String BCJSSE_PROVIDER_CLASS = "org.bouncycastle.jsse.provider.BouncyCastleJsseProvider" ;
109+ static boolean setJsseBouncyCastleProvider = true ;
110+ static volatile Provider jsseProvider ;
111+
108112 /**
109113 * inject under a given name a cipher. also ensures that the registered
110114 * classes are getting used.
@@ -128,15 +132,32 @@ public static void addSignature(String name, Class<? extends SignatureSpi> clazz
128132 }
129133
130134 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 ) {
132152 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 ;
135157 }
136158 }
137159 }
138- doRegisterProvider ();
139- return securityProvider ;
160+ return provider ;
140161 }
141162
142163 static final boolean SPI_ACCESSIBLE ;
@@ -170,20 +191,22 @@ static Provider getSecurityProviderIfAccessible() {
170191 }
171192
172193 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 );
174195 securityProvider = provider ;
175196 }
176197
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 ;
179202 }
180203
181- private static Provider newBouncyCastleProvider () {
204+ private static Provider newBouncyCastleProvider (final String klass ) {
182205 try {
183- return (Provider ) Class .forName (BC_PROVIDER_CLASS ).newInstance ();
206+ return (Provider ) Class .forName (klass ).newInstance ();
184207 }
185208 catch (Throwable ignored ) {
186- OpenSSL .debug ("can not instantiate bouncy-castle provider: " , ignored );
209+ OpenSSL .debug ("can not instantiate bouncy-castle provider (" + klass + ") " , ignored );
187210 }
188211 return null ;
189212 }
@@ -203,7 +226,7 @@ public static boolean isProviderRegistered() {
203226 return Security .getProvider (securityProvider .getName ()) != null ;
204227 }
205228
206- private static void doRegisterProvider () {
229+ private static void doRegisterProvider (final Provider securityProvider ) {
207230 if ( registerProvider != null ) {
208231 synchronized (SecurityHelper .class ) {
209232 final Boolean register = registerProvider ;
@@ -640,20 +663,20 @@ static SecretKeyFactory getSecretKeyFactory(final String algorithm, final Provid
640663 );
641664 }
642665
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
644667
645668 public static SSLContext getSSLContext (final String protocol )
646669 throws NoSuchAlgorithmException {
647670 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 ();
650673 if ( provider != null ) {
651674 return getSSLContext (protocol , provider );
652675 }
653676 }
654677 }
655678 catch (NoSuchAlgorithmException e ) { }
656- return SSLContext .getInstance (protocol );
679+ return SSLContext .getInstance (protocol ); // built-in SunJSSE provider on HotSpot
657680 }
658681
659682 private static SSLContext getSSLContext (final String protocol , final Provider provider )
0 commit comments