org.bouncycastle.tls.crypto.impl.jcajce.JceTlsECDomain 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.tls.crypto.impl.jcajce;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPublicKeySpec;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.tls.AlertDescription;
import org.bouncycastle.tls.NamedGroup;
import org.bouncycastle.tls.TlsFatalAlert;
import org.bouncycastle.tls.crypto.TlsAgreement;
import org.bouncycastle.tls.crypto.TlsCryptoException;
import org.bouncycastle.tls.crypto.TlsECConfig;
import org.bouncycastle.tls.crypto.TlsECDomain;
/**
* EC domain class for generating key pairs and performing key agreement.
*/
public class JceTlsECDomain
implements TlsECDomain
{
protected final JcaTlsCrypto crypto;
protected final TlsECConfig ecConfig;
protected final ECParameterSpec ecSpec;
protected final ECCurve ecCurve;
public JceTlsECDomain(JcaTlsCrypto crypto, TlsECConfig ecConfig)
{
int namedGroup = ecConfig.getNamedGroup();
if (NamedGroup.refersToAnECDSACurve(namedGroup))
{
ECParameterSpec spec = ECUtil.getECParameterSpec(crypto, NamedGroup.getCurveName(namedGroup));
if (null != spec)
{
this.crypto = crypto;
this.ecConfig = ecConfig;
this.ecSpec = spec;
this.ecCurve = ECUtil.convertCurve(spec.getCurve(), spec.getOrder(), spec.getCofactor());
return;
}
}
throw new IllegalArgumentException("NamedGroup not supported: " + NamedGroup.getText(namedGroup));
}
public JceTlsSecret calculateECDHAgreement(PrivateKey privateKey, PublicKey publicKey)
throws IOException
{
try
{
/*
* RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by
* FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for
* any given field; leading zeros found in this octet string MUST NOT be truncated.
*
* We use the convention established by the JSSE to signal this by asking for "TlsPremasterSecret".
*/
byte[] secret = crypto.calculateKeyAgreement("ECDH", privateKey, publicKey, "TlsPremasterSecret");
return crypto.adoptLocalSecret(secret);
}
catch (GeneralSecurityException e)
{
throw new TlsCryptoException("cannot calculate secret", e);
}
}
public TlsAgreement createECDH()
{
return new JceTlsECDH(this);
}
public ECPoint decodePoint(byte[] encoding)
throws IOException
{
return ecCurve.decodePoint(encoding);
}
public PublicKey decodePublicKey(byte[] encoding)
throws IOException
{
try
{
ECPoint point = decodePoint(encoding).normalize();
BigInteger x = point.getAffineXCoord().toBigInteger();
BigInteger y = point.getAffineYCoord().toBigInteger();
ECPublicKeySpec keySpec = new ECPublicKeySpec(new java.security.spec.ECPoint(x, y), ecSpec);
KeyFactory keyFact = crypto.getHelper().createKeyFactory("EC");
return keyFact.generatePublic(keySpec);
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
}
public byte[] encodePoint(ECPoint point) throws IOException
{
return point.getEncoded(false);
}
public byte[] encodePublicKey(PublicKey publicKey) throws IOException
{
// TODO Add new org.bouncycastle.util.ECPointHolder with getEncodedPoint(boolean)
if (publicKey instanceof org.bouncycastle.jce.interfaces.ECPublicKey)
{
return encodePoint(((org.bouncycastle.jce.interfaces.ECPublicKey)publicKey).getQ());
}
if (publicKey instanceof java.security.interfaces.ECPublicKey)
{
java.security.spec.ECPoint w = ((java.security.interfaces.ECPublicKey)publicKey).getW();
return encodePoint(ecCurve.createPoint(w.getAffineX(), w.getAffineY()));
}
SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
return spki.getPublicKeyData().getOctets();
}
public KeyPair generateKeyPair()
{
try
{
KeyPairGenerator keyPairGenerator = crypto.getHelper().createKeyPairGenerator("EC");
keyPairGenerator.initialize(ecSpec, crypto.getSecureRandom());
return keyPairGenerator.generateKeyPair();
}
catch (GeneralSecurityException e)
{
throw Exceptions.illegalStateException("unable to create key pair: " + e.getMessage(), e);
}
}
}