
org.bouncycastle.jsse.provider.ContextData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bctls-debug-jdk15to18 Show documentation
Show all versions of bctls-debug-jdk15to18 Show documentation
The Bouncy Castle Java APIs for TLS and DTLS, including a provider for the JSSE.
The newest version!
package org.bouncycastle.jsse.provider;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Vector;
import org.bouncycastle.jsse.BCX509ExtendedKeyManager;
import org.bouncycastle.jsse.BCX509ExtendedTrustManager;
import org.bouncycastle.jsse.java.security.BCAlgorithmConstraints;
import org.bouncycastle.jsse.java.security.BCCryptoPrimitive;
import org.bouncycastle.tls.ProtocolVersion;
import org.bouncycastle.tls.SignatureAndHashAlgorithm;
import org.bouncycastle.tls.TlsUtils;
import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto;
final class ContextData
{
private static final Set TLS_CRYPTO_PRIMITIVES_BC = JsseUtils.KEY_AGREEMENT_CRYPTO_PRIMITIVES_BC;
private final boolean fipsMode;
private final JcaTlsCrypto crypto;
private final BCX509ExtendedKeyManager x509KeyManager;
private final BCX509ExtendedTrustManager x509TrustManager;
private final Map supportedCipherSuites;
private final Map supportedProtocols;
private final String[] defaultCipherSuitesClient;
private final String[] defaultCipherSuitesServer;
private final String[] defaultProtocolsClient;
private final String[] defaultProtocolsServer;
private final ProvSSLSessionContext clientSessionContext;
private final ProvSSLSessionContext serverSessionContext;
private final NamedGroupInfo.PerContext namedGroups;
private final SignatureSchemeInfo.PerContext signatureSchemes;
ContextData(boolean fipsMode, JcaTlsCrypto crypto, BCX509ExtendedKeyManager x509KeyManager,
BCX509ExtendedTrustManager x509TrustManager, Map supportedCipherSuites,
Map supportedProtocols, String[] defaultCipherSuitesClient,
String[] defaultCipherSuitesServer, String[] defaultProtocolsClient, String[] defaultProtocolsServer)
{
this.fipsMode = fipsMode;
this.crypto = crypto;
this.x509KeyManager = x509KeyManager;
this.x509TrustManager = x509TrustManager;
this.supportedCipherSuites = supportedCipherSuites;
this.supportedProtocols = supportedProtocols;
this.defaultCipherSuitesClient = defaultCipherSuitesClient;
this.defaultCipherSuitesServer = defaultCipherSuitesServer;
this.defaultProtocolsClient = defaultProtocolsClient;
this.defaultProtocolsServer = defaultProtocolsServer;
this.clientSessionContext = new ProvSSLSessionContext(this);
this.serverSessionContext = new ProvSSLSessionContext(this);
this.namedGroups = NamedGroupInfo.createPerContext(fipsMode, crypto);
this.signatureSchemes = SignatureSchemeInfo.createPerContext(fipsMode, crypto, namedGroups);
}
int[] getActiveCipherSuites(JcaTlsCrypto crypto, ProvSSLParameters sslParameters,
ProtocolVersion[] activeProtocolVersions)
{
String[] enabledCipherSuites = sslParameters.getCipherSuitesArray();
BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints();
ProtocolVersion latest = ProtocolVersion.getLatestTLS(activeProtocolVersions);
ProtocolVersion earliest = ProtocolVersion.getEarliestTLS(activeProtocolVersions);
boolean post13Active = TlsUtils.isTLSv13(latest);
boolean pre13Active = !TlsUtils.isTLSv13(earliest);
int[] candidates = new int[enabledCipherSuites.length];
int count = 0;
for (String enabledCipherSuite : enabledCipherSuites)
{
CipherSuiteInfo candidate = supportedCipherSuites.get(enabledCipherSuite);
if (null == candidate)
{
continue;
}
if (candidate.isTLSv13())
{
if (!post13Active)
{
continue;
}
}
else
{
if (!pre13Active)
{
continue;
}
}
if (!algorithmConstraints.permits(TLS_CRYPTO_PRIMITIVES_BC, enabledCipherSuite, null))
{
continue;
}
/*
* TODO[jsse] SunJSSE also checks that the cipher suite is usable for at least one of
* the active protocol versions. Also, if the cipher suite involves a key exchange,
* there must be at least one suitable NamedGroup available.
*/
candidates[count++] = candidate.getCipherSuite();
}
/*
* TODO Move cipher suite management into CipherSuiteInfo (PerConnection/PerContext pattern
* like NamedGroupInfo) to avoid unnecessary repetition of these sorts of checks.
*/
int[] result = TlsUtils.getSupportedCipherSuites(crypto, candidates, 0, count);
if (result.length < 1)
{
// TODO[jsse] Refactor so that this can be an SSLHandshakeException?
throw new IllegalStateException("No usable cipher suites enabled");
}
return result;
}
ProtocolVersion[] getActiveProtocolVersions(ProvSSLParameters sslParameters)
{
// String[] enabledCipherSuites = sslParameters.getCipherSuitesArray();
String[] enabledProtocols = sslParameters.getProtocolsArray();
BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints();
SortedSet result = new TreeSet(new Comparator()
{
public int compare(ProtocolVersion o1, ProtocolVersion o2)
{
return o1.isLaterVersionOf(o2) ? -1 : o2.isLaterVersionOf(o1) ? 1 : 0;
}
});
for (String enabledProtocol : enabledProtocols)
{
ProtocolVersion candidate = supportedProtocols.get(enabledProtocol);
if (null == candidate)
{
continue;
}
if (!algorithmConstraints.permits(TLS_CRYPTO_PRIMITIVES_BC, enabledProtocol, null))
{
continue;
}
/*
* TODO[jsse] SunJSSE also checks that there is at least one "activatable" cipher suite
* that could be used for this protocol version.
*/
result.add(candidate);
}
if (result.isEmpty())
{
// TODO[jsse] Refactor so that this can be an SSLHandshakeException?
throw new IllegalStateException("No usable protocols enabled");
}
return result.toArray(new ProtocolVersion[result.size()]);
}
ProvSSLSessionContext getClientSessionContext()
{
return clientSessionContext;
}
JcaTlsCrypto getCrypto()
{
return crypto;
}
String[] getDefaultCipherSuites(boolean isClient)
{
return implGetDefaultCipherSuites(isClient).clone();
}
String[] getDefaultProtocols(boolean isClient)
{
return implGetDefaultProtocols(isClient).clone();
}
ProvSSLParameters getDefaultSSLParameters(boolean isClient)
{
return new ProvSSLParameters(this, implGetDefaultCipherSuites(isClient), implGetDefaultProtocols(isClient));
}
ProvSSLParameters getSupportedSSLParameters(boolean isClient)
{
return new ProvSSLParameters(this, getSupportedCipherSuites(), getSupportedProtocols());
}
NamedGroupInfo.PerConnection getNamedGroupsClient(ProvSSLParameters sslParameters,
ProtocolVersion[] activeProtocolVersions)
{
return NamedGroupInfo.createPerConnectionClient(namedGroups, sslParameters, activeProtocolVersions);
}
NamedGroupInfo.PerConnection getNamedGroupsServer(ProvSSLParameters sslParameters,
ProtocolVersion negotiatedVersion)
{
return NamedGroupInfo.createPerConnectionServer(namedGroups, sslParameters, negotiatedVersion);
}
ProvSSLSessionContext getServerSessionContext()
{
return serverSessionContext;
}
SignatureSchemeInfo.PerConnection getSignatureSchemesClient(ProvSSLParameters sslParameters,
ProtocolVersion[] activeProtocolVersions, NamedGroupInfo.PerConnection namedGroups)
{
return SignatureSchemeInfo.createPerConnectionClient(signatureSchemes, sslParameters, activeProtocolVersions,
namedGroups);
}
SignatureSchemeInfo.PerConnection getSignatureSchemesServer(ProvSSLParameters sslParameters,
ProtocolVersion negotiatedVersion, NamedGroupInfo.PerConnection namedGroups)
{
return SignatureSchemeInfo.createPerConnectionServer(signatureSchemes, sslParameters, negotiatedVersion,
namedGroups);
}
List getSignatureSchemes(Vector sigAndHashAlgs)
{
return SignatureSchemeInfo.getSignatureSchemes(signatureSchemes, sigAndHashAlgs);
}
String[] getSupportedCipherSuites()
{
return JsseUtils.getKeysArray(supportedCipherSuites);
}
String[] getSupportedCipherSuites(String[] cipherSuites)
{
if (null == cipherSuites)
{
throw new NullPointerException("'cipherSuites' cannot be null");
}
ArrayList result = new ArrayList(cipherSuites.length);
for (String cipherSuite : cipherSuites)
{
if (TlsUtils.isNullOrEmpty(cipherSuite))
{
throw new IllegalArgumentException("'cipherSuites' cannot contain null or empty string elements");
}
if (supportedCipherSuites.containsKey(cipherSuite))
{
result.add(cipherSuite);
}
}
// NOTE: This method must always return a copy, so no fast path when all supported
return JsseUtils.getArray(result);
}
String[] getSupportedProtocols()
{
return JsseUtils.getKeysArray(supportedProtocols);
}
BCX509ExtendedKeyManager getX509KeyManager()
{
return x509KeyManager;
}
BCX509ExtendedTrustManager getX509TrustManager()
{
return x509TrustManager;
}
boolean isFipsMode()
{
return fipsMode;
}
boolean isSupportedProtocols(String[] protocols)
{
if (protocols == null)
{
return false;
}
for (String protocol : protocols)
{
if (protocol == null || !supportedProtocols.containsKey(protocol))
{
return false;
}
}
return true;
}
void updateDefaultSSLParameters(ProvSSLParameters sslParameters, boolean isClient)
{
if (sslParameters.getCipherSuitesArray() == implGetDefaultCipherSuites(!isClient))
{
sslParameters.setCipherSuitesArray(implGetDefaultCipherSuites(isClient));
}
if (sslParameters.getProtocolsArray() == implGetDefaultProtocols(!isClient))
{
sslParameters.setProtocolsArray(implGetDefaultProtocols(isClient));
}
}
String validateNegotiatedCipherSuite(ProvSSLParameters sslParameters, int cipherSuite)
{
// NOTE: The redundancy among these various checks is intentional
String name = ProvSSLContextSpi.getCipherSuiteName(cipherSuite);
if (null == name
|| !JsseUtils.contains(sslParameters.getCipherSuitesArray(), name)
|| !sslParameters.getAlgorithmConstraints().permits(TLS_CRYPTO_PRIMITIVES_BC, name, null)
|| !supportedCipherSuites.containsKey(name))
{
throw new IllegalStateException("SSL connection negotiated unsupported ciphersuite: " + cipherSuite);
}
return name;
}
String validateNegotiatedProtocol(ProvSSLParameters sslParameters, ProtocolVersion protocol)
{
// NOTE: The redundancy among these various checks is intentional
String name = ProvSSLContextSpi.getProtocolVersionName(protocol);
if (null == name
|| !JsseUtils.contains(sslParameters.getProtocolsArray(), name)
|| !sslParameters.getAlgorithmConstraints().permits(TLS_CRYPTO_PRIMITIVES_BC, name, null)
|| !supportedProtocols.containsKey(name))
{
throw new IllegalStateException("SSL connection negotiated unsupported protocol: " + protocol);
}
return name;
}
private String[] implGetDefaultCipherSuites(boolean isClient)
{
return isClient ? defaultCipherSuitesClient : defaultCipherSuitesServer;
}
private String[] implGetDefaultProtocols(boolean isClient)
{
return isClient ? defaultProtocolsClient : defaultProtocolsServer;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy