org.bouncycastle.jsse.provider.CipherSuiteInfo Maven / Gradle / Ivy
The newest version!
package org.bouncycastle.jsse.provider;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.bouncycastle.tls.CipherSuite;
import org.bouncycastle.tls.CipherType;
import org.bouncycastle.tls.EncryptionAlgorithm;
import org.bouncycastle.tls.KeyExchangeAlgorithm;
import org.bouncycastle.tls.MACAlgorithm;
import org.bouncycastle.tls.TlsUtils;
import org.bouncycastle.tls.crypto.CryptoHashAlgorithm;
class CipherSuiteInfo
{
static CipherSuiteInfo forCipherSuite(int cipherSuite, String name)
{
if (!name.startsWith("TLS_"))
{
throw new IllegalArgumentException();
}
int encryptionAlgorithm = TlsUtils.getEncryptionAlgorithm(cipherSuite);
int encryptionAlgorithmType = TlsUtils.getEncryptionAlgorithmType(encryptionAlgorithm);
int cryptoHashAlgorithm = getCryptoHashAlgorithm(cipherSuite);
int keyExchangeAlgorithm = TlsUtils.getKeyExchangeAlgorithm(cipherSuite);
int macAlgorithm = TlsUtils.getMACAlgorithm(cipherSuite);
Set decompositionX509 = new HashSet();
decomposeKeyExchangeAlgorithm(decompositionX509, keyExchangeAlgorithm);
Set decompositionTLS = new HashSet(decompositionX509);
decomposeKeyExchangeAlgorithmTLS(decompositionTLS, keyExchangeAlgorithm);
decomposeEncryptionAlgorithm(decompositionTLS, encryptionAlgorithm);
decomposeHashAlgorithm(decompositionTLS, cryptoHashAlgorithm);
decomposeMACAlgorithm(decompositionTLS, encryptionAlgorithmType, macAlgorithm);
boolean isTLSv13 = (KeyExchangeAlgorithm.NULL == keyExchangeAlgorithm);
return new CipherSuiteInfo(cipherSuite, name, isTLSv13, Collections.unmodifiableSet(decompositionTLS),
Collections.unmodifiableSet(decompositionX509));
}
private final int cipherSuite;
private final String name;
private final boolean isTLSv13;
private final Set decompositionTLS, decompositionX509;
private CipherSuiteInfo(int cipherSuite, String name, boolean isTLSv13, Set decompositionTLS,
Set decompositionX509)
{
this.cipherSuite = cipherSuite;
this.name = name;
this.isTLSv13 = isTLSv13;
this.decompositionTLS = decompositionTLS;
this.decompositionX509 = decompositionX509;
}
public int getCipherSuite()
{
return cipherSuite;
}
public Set getDecompositionTLS()
{
return decompositionTLS;
}
public Set getDecompositionX509()
{
return decompositionX509;
}
public String getName()
{
return name;
}
boolean isTLSv13()
{
return isTLSv13;
}
private static void addAll(Set decomposition, String... entries)
{
for (String entry : entries)
{
decomposition.add(entry);
}
}
private static void decomposeEncryptionAlgorithm(Set decomposition, int encryptionAlgorithm)
{
String transformation = getTransformation(encryptionAlgorithm);
decomposition.addAll(JcaAlgorithmDecomposer.INSTANCE_JCA.decompose(transformation));
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm._3DES_EDE_CBC:
decomposition.add("3DES_EDE_CBC");
break;
case EncryptionAlgorithm.AES_128_CBC:
decomposition.add("AES_128_CBC");
break;
case EncryptionAlgorithm.AES_128_CCM:
decomposition.add("AES_128_CCM");
break;
case EncryptionAlgorithm.AES_128_CCM_8:
decomposition.add("AES_128_CCM_8");
break;
case EncryptionAlgorithm.AES_128_GCM:
decomposition.add("AES_128_GCM");
break;
case EncryptionAlgorithm.AES_256_CBC:
decomposition.add("AES_256_CBC");
break;
case EncryptionAlgorithm.AES_256_CCM:
decomposition.add("AES_256_CCM");
break;
case EncryptionAlgorithm.AES_256_CCM_8:
decomposition.add("AES_256_CCM_8");
break;
case EncryptionAlgorithm.AES_256_GCM:
decomposition.add("AES_256_GCM");
break;
case EncryptionAlgorithm.ARIA_128_CBC:
decomposition.add("ARIA_128_CBC");
break;
case EncryptionAlgorithm.ARIA_256_CBC:
decomposition.add("ARIA_256_CBC");
break;
case EncryptionAlgorithm.ARIA_128_GCM:
decomposition.add("ARIA_128_GCM");
break;
case EncryptionAlgorithm.ARIA_256_GCM:
decomposition.add("ARIA_256_GCM");
break;
case EncryptionAlgorithm.CAMELLIA_128_CBC:
decomposition.add("CAMELLIA_128_CBC");
break;
case EncryptionAlgorithm.CAMELLIA_256_CBC:
decomposition.add("CAMELLIA_256_CBC");
break;
case EncryptionAlgorithm.CAMELLIA_128_GCM:
decomposition.add("CAMELLIA_128_GCM");
break;
case EncryptionAlgorithm.CAMELLIA_256_GCM:
decomposition.add("CAMELLIA_256_GCM");
break;
case EncryptionAlgorithm.CHACHA20_POLY1305:
// NOTE: Following SunJSSE, nothing beyond the transformation added above (i.e "ChaCha20-Poly1305")
break;
case EncryptionAlgorithm.NULL:
decomposition.add("C_NULL");
break;
case EncryptionAlgorithm.SM4_CBC:
decomposition.add("SM4_CBC");
break;
case EncryptionAlgorithm.SM4_CCM:
decomposition.add("SM4_CCM");
break;
case EncryptionAlgorithm.SM4_GCM:
decomposition.add("SM4_GCM");
break;
default:
throw new IllegalArgumentException();
}
}
private static void decomposeHashAlgorithm(Set decomposition, int cryptoHashAlgorithm)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.sha256:
addAll(decomposition, "SHA256", "SHA-256", "HmacSHA256");
break;
case CryptoHashAlgorithm.sha384:
addAll(decomposition, "SHA384", "SHA-384", "HmacSHA384");
break;
// case CryptoHashAlgorithm.sha512:
// addAll(decomposition, "SHA512", "SHA-512", "HmacSHA512");
// break;
case CryptoHashAlgorithm.sm3:
addAll(decomposition, "SM3", "HmacSM3");
break;
default:
throw new IllegalArgumentException();
}
}
private static void decomposeKeyExchangeAlgorithm(Set decomposition, int keyExchangeAlgorithm)
{
switch (keyExchangeAlgorithm)
{
case KeyExchangeAlgorithm.DHE_DSS:
addAll(decomposition, "DSA", "DSS", "DH", "DHE", "DiffieHellman", "DHE_DSS");
break;
case KeyExchangeAlgorithm.DHE_RSA:
addAll(decomposition, "RSA", "DH", "DHE", "DiffieHellman", "DHE_RSA");
break;
case KeyExchangeAlgorithm.ECDHE_ECDSA:
addAll(decomposition, "ECDHE", "ECDSA", "ECDHE_ECDSA");
break;
case KeyExchangeAlgorithm.ECDHE_RSA:
addAll(decomposition, "ECDHE", "RSA", "ECDHE_RSA");
break;
case KeyExchangeAlgorithm.RSA:
addAll(decomposition, "RSA");
break;
case KeyExchangeAlgorithm.DH_anon:
case KeyExchangeAlgorithm.ECDH_anon:
case KeyExchangeAlgorithm.NULL:
break;
default:
throw new IllegalArgumentException();
}
}
private static void decomposeKeyExchangeAlgorithmTLS(Set decompositionTLS, int keyExchangeAlgorithm)
{
switch (keyExchangeAlgorithm)
{
case KeyExchangeAlgorithm.DH_anon:
addAll(decompositionTLS, "ANON", "DH", "DiffieHellman", "DH_ANON");
break;
case KeyExchangeAlgorithm.ECDH_anon:
addAll(decompositionTLS, "ANON", "ECDH", "ECDH_ANON");
break;
case KeyExchangeAlgorithm.NULL:
addAll(decompositionTLS, "K_NULL");
break;
case KeyExchangeAlgorithm.DHE_DSS:
case KeyExchangeAlgorithm.DHE_RSA:
case KeyExchangeAlgorithm.ECDHE_ECDSA:
case KeyExchangeAlgorithm.ECDHE_RSA:
case KeyExchangeAlgorithm.RSA:
break;
default:
throw new IllegalArgumentException();
}
}
private static void decomposeMACAlgorithm(Set decomposition, int cipherType, int macAlgorithm)
{
switch (macAlgorithm)
{
case MACAlgorithm._null:
if (CipherType.aead != cipherType)
{
addAll(decomposition, "M_NULL");
}
break;
case MACAlgorithm.hmac_md5:
addAll(decomposition, "MD5", "HmacMD5");
break;
case MACAlgorithm.hmac_sha1:
addAll(decomposition, "SHA1", "SHA-1", "HmacSHA1");
break;
case MACAlgorithm.hmac_sha256:
addAll(decomposition, "SHA256", "SHA-256", "HmacSHA256");
break;
case MACAlgorithm.hmac_sha384:
addAll(decomposition, "SHA384", "SHA-384", "HmacSHA384");
break;
// case MACAlgorithm.hmac_sha512:
// addAll(decomposition, "SHA512", "SHA-512", "HmacSHA512");
// break;
default:
throw new IllegalArgumentException();
}
}
private static int getCryptoHashAlgorithm(int cipherSuite)
{
switch (cipherSuite)
{
case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA:
case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
case CipherSuite.TLS_RSA_WITH_NULL_SHA:
/*
* TODO[jsse] We follow SunJSSE behaviour here, but it's not quite right; these cipher
* suites will actually use the legacy PRF based on MD5/SHA1 for TLS 1.1 or earlier.
*/
return CryptoHashAlgorithm.sha256;
case CipherSuite.TLS_AES_128_CCM_SHA256:
case CipherSuite.TLS_AES_128_CCM_8_SHA256:
case CipherSuite.TLS_AES_128_GCM_SHA256:
case CipherSuite.TLS_CHACHA20_POLY1305_SHA256:
case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256:
case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256:
case CipherSuite.TLS_DH_anon_WITH_ARIA_128_CBC_SHA256:
case CipherSuite.TLS_DH_anon_WITH_ARIA_128_GCM_SHA256:
case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256:
case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256:
case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
case CipherSuite.TLS_RSA_WITH_ARIA_128_CBC_SHA256:
case CipherSuite.TLS_RSA_WITH_ARIA_128_GCM_SHA256:
case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
return CryptoHashAlgorithm.sha256;
case CipherSuite.TLS_AES_256_GCM_SHA384:
case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384:
case CipherSuite.TLS_DH_anon_WITH_ARIA_256_CBC_SHA384:
case CipherSuite.TLS_DH_anon_WITH_ARIA_256_GCM_SHA384:
case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384:
case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384:
case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384:
case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384:
case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384:
case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384:
case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384:
case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
case CipherSuite.TLS_RSA_WITH_ARIA_256_CBC_SHA384:
case CipherSuite.TLS_RSA_WITH_ARIA_256_GCM_SHA384:
case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
return CryptoHashAlgorithm.sha384;
case CipherSuite.TLS_SM4_CCM_SM3:
case CipherSuite.TLS_SM4_GCM_SM3:
return CryptoHashAlgorithm.sm3;
default:
throw new IllegalArgumentException();
}
}
private static String getTransformation(int encryptionAlgorithm)
{
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm._3DES_EDE_CBC:
return "DESede/CBC/NoPadding";
case EncryptionAlgorithm.AES_128_CBC:
case EncryptionAlgorithm.AES_256_CBC:
return "AES/CBC/NoPadding";
case EncryptionAlgorithm.AES_128_CCM:
case EncryptionAlgorithm.AES_128_CCM_8:
case EncryptionAlgorithm.AES_256_CCM:
case EncryptionAlgorithm.AES_256_CCM_8:
return "AES/CCM/NoPadding";
case EncryptionAlgorithm.AES_128_GCM:
case EncryptionAlgorithm.AES_256_GCM:
return "AES/GCM/NoPadding";
case EncryptionAlgorithm.ARIA_128_CBC:
case EncryptionAlgorithm.ARIA_256_CBC:
return "ARIA/CBC/NoPadding";
case EncryptionAlgorithm.ARIA_128_GCM:
case EncryptionAlgorithm.ARIA_256_GCM:
return "ARIA/GCM/NoPadding";
case EncryptionAlgorithm.CAMELLIA_128_CBC:
case EncryptionAlgorithm.CAMELLIA_256_CBC:
return "Camellia/CBC/NoPadding";
case EncryptionAlgorithm.CAMELLIA_128_GCM:
case EncryptionAlgorithm.CAMELLIA_256_GCM:
return "Camellia/GCM/NoPadding";
case EncryptionAlgorithm.CHACHA20_POLY1305:
return "ChaCha20-Poly1305";
case EncryptionAlgorithm.NULL:
return "NULL";
case EncryptionAlgorithm.SM4_CBC:
return "SM4/CBC/NoPadding";
case EncryptionAlgorithm.SM4_CCM:
return "SM4/CCM/NoPadding";
case EncryptionAlgorithm.SM4_GCM:
return "SM4/GCM/NoPadding";
default:
throw new IllegalArgumentException();
}
}
}