|
23 | 23 | */
|
24 | 24 | package org.jruby.ext.openssl;
|
25 | 25 |
|
| 26 | +import static org.jruby.ext.openssl.OpenSSL.debug; |
26 | 27 | import static org.jruby.ext.openssl.OpenSSL.debugStackTrace;
|
27 | 28 |
|
28 | 29 | import java.io.IOException;
|
@@ -103,10 +104,10 @@ public abstract class SecurityHelper {
|
103 | 104 | static boolean setBouncyCastleProvider = true; // (package access for tests)
|
104 | 105 | static volatile Provider securityProvider; // 'BC' provider (package access for tests)
|
105 | 106 | private static volatile Boolean registerProvider = null;
|
106 |
| - static final Map<String, Class> implEngines = new ConcurrentHashMap<String, Class>(16, 0.75f, 1); |
| 107 | + static final Map<String, Class> implEngines = new ConcurrentHashMap<>(16, 0.75f, 1); |
107 | 108 |
|
108 | 109 | private static String BCJSSE_PROVIDER_CLASS = "org.bouncycastle.jsse.provider.BouncyCastleJsseProvider";
|
109 |
| - static boolean setJsseBouncyCastleProvider = true; |
| 110 | + static boolean setJsseProvider = true; |
110 | 111 | static volatile Provider jsseProvider;
|
111 | 112 |
|
112 | 113 | /**
|
@@ -146,14 +147,22 @@ public static Provider getSecurityProvider() {
|
146 | 147 | return provider;
|
147 | 148 | }
|
148 | 149 |
|
149 |
| - static Provider getJsseProvider() { |
| 150 | + private static Provider getJsseProvider(final String name) { |
150 | 151 | Provider provider = jsseProvider;
|
151 |
| - if ( setJsseBouncyCastleProvider && provider == null ) { |
| 152 | + if ( setJsseProvider && provider == null ) { |
152 | 153 | synchronized(SecurityHelper.class) {
|
153 | 154 | provider = jsseProvider;
|
154 |
| - if ( setJsseBouncyCastleProvider && provider == null ) { |
155 |
| - provider = jsseProvider = newBouncyCastleProvider(BCJSSE_PROVIDER_CLASS); |
156 |
| - setJsseBouncyCastleProvider = false; |
| 155 | + if ( setJsseProvider && provider == null ) { |
| 156 | + try { |
| 157 | + provider = Security.getProvider(name); |
| 158 | + } |
| 159 | + catch (Exception ex) { |
| 160 | + debug("failed to get provider: " + name, ex); |
| 161 | + } |
| 162 | + if (provider == null && "BCJSSE".equals(name)) { |
| 163 | + provider = newBouncyCastleProvider(BCJSSE_PROVIDER_CLASS); |
| 164 | + } |
| 165 | + jsseProvider = provider; setJsseProvider = false; |
157 | 166 | }
|
158 | 167 | }
|
159 | 168 | }
|
@@ -649,16 +658,23 @@ static SecretKeyFactory getSecretKeyFactory(final String algorithm, final Provid
|
649 | 658 | );
|
650 | 659 | }
|
651 | 660 |
|
652 |
| - private static final boolean providerSSLContext; // NOTE: experimental support for using BCJSSE |
| 661 | + private static final String providerSSLContext; // NOTE: experimental support for using BCJSSE |
653 | 662 | static {
|
654 |
| - providerSSLContext = SafePropertyAccessor.getBoolean("jruby.openssl.ssl.provider"); |
| 663 | + String providerSSL = SafePropertyAccessor.getProperty("jruby.openssl.ssl.provider", ""); |
| 664 | + switch (providerSSL.trim()) { |
| 665 | + case "BC": case "true": |
| 666 | + providerSSL = "BCJSSE"; break; |
| 667 | + case "": case "false": |
| 668 | + providerSSL = null; break; |
| 669 | + } |
| 670 | + providerSSLContext = providerSSL; |
655 | 671 | }
|
656 | 672 |
|
657 | 673 | public static SSLContext getSSLContext(final String protocol)
|
658 | 674 | throws NoSuchAlgorithmException {
|
659 | 675 | try {
|
660 |
| - if ( providerSSLContext && ! "SSL".equals(protocol) ) { // only TLS supported in BCJSSE |
661 |
| - final Provider provider = getJsseProvider(); |
| 676 | + if ( providerSSLContext != null && ! "SSL".equals(protocol) ) { // only TLS supported in BCJSSE |
| 677 | + final Provider provider = getJsseProvider(providerSSLContext); |
662 | 678 | if ( provider != null ) {
|
663 | 679 | return getSSLContext(protocol, provider);
|
664 | 680 | }
|
|
0 commit comments