Skip to content

Commit b15706e

Browse files
committed
prepare for using BC's JSSE implementation as an SSL support backend
1 parent f8dc59e commit b15706e

File tree

2 files changed

+43
-19
lines changed

2 files changed

+43
-19
lines changed

src/main/java/org/jruby/ext/openssl/Cipher.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,9 @@ private static String[] providerCipherModes(final String alg) {
186186
}
187187

188188
private static Provider.Service providerCipherService(final String alg) {
189-
if ( SecurityHelper.securityProvider != null ) {
190-
return SecurityHelper.securityProvider.getService("Cipher", alg);
189+
Provider securityProvider = SecurityHelper.securityProvider;
190+
if ( securityProvider != null ) {
191+
return securityProvider.getService("Cipher", alg);
191192
}
192193
return null;
193194
}

src/main/java/org/jruby/ext/openssl/SecurityHelper.java

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)