Skip to content

Commit

Permalink
ssl: Various improvements
Browse files Browse the repository at this point in the history
Add support for BouncyCastle .
Fallback for missing "DEFAULT" SecureRandom (BouncyCastle).
Wrap SSLSocket instances to ignore "broken pipe" upon close (BouncyCastle).
Improve SNI handling.
Use BouncyCastle on Android if available.
Allow specifying Provider by classname, comma-separate list of dependent providers.
Improve tests.
Code cleanup.
  • Loading branch information
kohlschuetter committed Sep 23, 2023
1 parent 416f4aa commit e0f8825
Show file tree
Hide file tree
Showing 11 changed files with 1,375 additions and 255 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
package org.newsclub.net.unix.ssl;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.function.Function;

import javax.net.SocketFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLContextSpi;
Expand All @@ -38,9 +40,40 @@
*/
final class BuilderSSLContext extends SSLContext {
BuilderSSLContext(boolean clientMode, SSLContext context,
Function<SSLParameters, SSLParameters> parametersFunction) {
super(new ConfiguredSSLContextSpi(clientMode, context, parametersFunction), context
.getProvider(), context.getProtocol());
Function<SSLParameters, SSLParameters> parametersFunction, SocketFactory socketFactory) {
super(new ConfiguredSSLContextSpi(clientMode, context, parametersFunction, socketFactory),
context.getProvider(), context.getProtocol());
}

/**
* Calls {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)} with the given
* parameters. If there was a known problem with initializing the default {@link SecureRandom}
* (when {@code null} was specified), try {@link SecureRandom#getInstanceStrong()} instance.
*
* @param context The context to initialize.
* @param km The key managers, or {@code null}.
* @param tm The trust managers, or {@code null}.
* @param sr The secure random, or {@code null}.
* @throws KeyManagementException on error.
*/
static void initContext(SSLContext context, KeyManager[] km, TrustManager[] tm, SecureRandom sr)
throws KeyManagementException {
try {
context.init(km, tm, sr);
} catch (IllegalStateException e) {
// In certain configurations, BouncyCastle may fail to detect a SecureRandom named "DEFAULT"
if (sr == null && e.getMessage().contains("SecureRandom not available")) {
try {
// Use any strong SecureRandom instance as fallback
sr = SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e1) {
throw e;
}
context.init(km, tm, sr);
} else {
throw e;
}
}
}

private static final class ConfiguredSSLContextSpi extends SSLContextSpi {
Expand All @@ -52,7 +85,7 @@ private static final class ConfiguredSSLContextSpi extends SSLContextSpi {
private final boolean clientMode;

private ConfiguredSSLContextSpi(boolean clientMode, SSLContext context,
Function<SSLParameters, SSLParameters> parametersFunction) {
Function<SSLParameters, SSLParameters> parametersFunction, SocketFactory socketFactory) {
super();
this.clientMode = clientMode;
this.context = context;
Expand All @@ -63,15 +96,16 @@ private ConfiguredSSLContextSpi(boolean clientMode, SSLContext context,
}

this.params = p;
this.socketFactory = new BuilderSSLSocketFactory(clientMode, context.getSocketFactory(), p);
this.socketFactory = new BuilderSSLSocketFactory(clientMode, context, context
.getSocketFactory(), p, socketFactory);
this.serverSocketFactory = new BuilderSSLServerSocketFactory(context.getServerSocketFactory(),
p);
}

@Override
protected void engineInit(KeyManager[] km, TrustManager[] tm, SecureRandom sr)
throws KeyManagementException {
context.init(km, tm, sr);
initContext(context, km, tm, sr);
}

@Override
Expand Down
Loading

0 comments on commit e0f8825

Please sign in to comment.