org.bouncycastle.jsse.provider.CipherSuiteInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of impersonator Show documentation
Show all versions of impersonator Show documentation
Spoof TLS/JA3/JA4 and HTTP/2 fingerprints in Java
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();
}
}
}