Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tls injection mechanism #1517

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
afe7f4e
Added multiples classes implementing the TLS injection mechanism in BC
sergejskozlovics Oct 25, 2023
33abb91
Added code that makes injected KEMs visible to TLS
sergejskozlovics Oct 25, 2023
006ee29
Re-implemented NamedGroupInfo to support injected KEMs
sergejskozlovics Oct 25, 2023
04d11e6
Re-implemented SignatureSchemeInfo to support injected Sig Algs
sergejskozlovics Oct 25, 2023
2c97329
added injected KEMs to the TLS supported groups extension
sergejskozlovics Oct 25, 2023
77b40de
adding injected KEMs and signature algorithms to the list of supporte…
sergejskozlovics Oct 25, 2023
d9c4416
using KEM as a TlsAgreement
sergejskozlovics Oct 25, 2023
fa0b30b
adding injected KEMs and signature algorithms to JcaTlsCrypto
sergejskozlovics Oct 25, 2023
c433374
Added code that makes signature algorithms (injected via InjectionPoi…
sergejskozlovics Oct 25, 2023
7450b06
Adding support for injected algorithms (via InjectionPoint) to the BC…
sergejskozlovics Oct 25, 2023
ece83e0
moved TLS injection mechanism from BC tls folder to core
sergejskozlovics Oct 27, 2023
e2d73dd
some changes in imports
sergejskozlovics Oct 27, 2023
4861e5e
changed arg ordering
sergejskozlovics Oct 27, 2023
8fdce66
More secure pop() method for InjectionPoint. Better logic for inserti…
sergejskozlovics Nov 23, 2023
8ab2aa2
Merge remote-tracking branch 'upstream/main' into tls-injection2
sergejskozlovics Apr 14, 2024
dc6a801
moved the main TLS Injection Mechanism out from the core package, lea…
sergejskozlovics Apr 19, 2024
48792c7
refactored TLS Injection Mechanism; moved it to the tls package
sergejskozlovics Apr 19, 2024
45dd268
fixed comments
sergejskozlovics Apr 19, 2024
ee644df
Removed UniversalKeyPairGenerator, since it is not used by the TLS In…
sergejskozlovics Apr 19, 2024
57af27a
renamed variables "*EncodedKey" to "*ByteKey"; add "RSASSA-PSS" as a …
sergejskozlovics Jun 3, 2024
9a2e253
added .clone() for the shared key, since BC may alter it
sergejskozlovics Jun 14, 2024
8449c71
added isEmpty() to InjectionPoint
sergejskozlovics Jun 14, 2024
afb1a44
fixed a bug when KEM keyGen() was unnecessarily invoked at the server…
sergejskozlovics Jun 14, 2024
ac2006b
adding the BC provider in InjectionPoint.push
sergejskozlovics Jun 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.bouncycastle.internal.asn1.oiw.ElGamalParameter;
import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers;
import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs;
import org.bouncycastle.util.Arrays;

/**
Expand All @@ -62,7 +63,7 @@ public class PrivateKeyFactory
* @throws IOException on an error decoding the key
*/
public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData)
throws IOException
throws IOException
{
if (privateKeyInfoData == null)
{
Expand All @@ -84,7 +85,7 @@ public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData)
* @throws IOException on an error decoding the key
*/
public static AsymmetricKeyParameter createKey(InputStream inStr)
throws IOException
throws IOException
{
return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject()));
}
Expand All @@ -97,7 +98,7 @@ public static AsymmetricKeyParameter createKey(InputStream inStr)
* @throws IOException on an error decoding the key
*/
public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo)
throws IOException
throws IOException
{
if (keyInfo == null)
{
Expand All @@ -107,23 +108,29 @@ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo)
AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
ASN1ObjectIdentifier algOID = algId.getAlgorithm();

// #tls-injection
if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedAlgorithm(algOID))
{
return Asn1BridgeForInjectedSigAlgs.theInstance().createPrivateKeyParameter(keyInfo);
}

if (algOID.equals(PKCSObjectIdentifiers.rsaEncryption)
|| algOID.equals(PKCSObjectIdentifiers.id_RSASSA_PSS)
|| algOID.equals(X509ObjectIdentifiers.id_ea_rsa))
|| algOID.equals(PKCSObjectIdentifiers.id_RSASSA_PSS)
|| algOID.equals(X509ObjectIdentifiers.id_ea_rsa))
{
RSAPrivateKey keyStructure = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey());

return new RSAPrivateCrtKeyParameters(keyStructure.getModulus(),
keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(),
keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(),
keyStructure.getExponent2(), keyStructure.getCoefficient());
keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(),
keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(),
keyStructure.getExponent2(), keyStructure.getCoefficient());
}
// TODO?
// else if (algOID.equals(X9ObjectIdentifiers.dhpublicnumber))
else if (algOID.equals(PKCSObjectIdentifiers.dhKeyAgreement))
{
DHParameter params = DHParameter.getInstance(algId.getParameters());
ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
ASN1Integer derX = (ASN1Integer) keyInfo.parsePrivateKey();

BigInteger lVal = params.getL();
int l = lVal == null ? 0 : lVal.intValue();
Expand All @@ -134,14 +141,14 @@ else if (algOID.equals(PKCSObjectIdentifiers.dhKeyAgreement))
else if (algOID.equals(OIWObjectIdentifiers.elGamalAlgorithm))
{
ElGamalParameter params = ElGamalParameter.getInstance(algId.getParameters());
ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
ASN1Integer derX = (ASN1Integer) keyInfo.parsePrivateKey();

return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters(
params.getP(), params.getG()));
params.getP(), params.getG()));
}
else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
{
ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
ASN1Integer derX = (ASN1Integer) keyInfo.parsePrivateKey();
ASN1Encodable algParameters = algId.getParameters();

DSAParameters parameters = null;
Expand All @@ -162,7 +169,7 @@ else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))

if (params.isNamedCurve())
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) params.getParameters();

x9 = CustomNamedCurves.getByOID(oid);
if (x9 == null)
Expand All @@ -175,7 +182,7 @@ else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))
{
x9 = X9ECParameters.getInstance(params.getParameters());
dParams = new ECDomainParameters(
x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
}

ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
Expand Down Expand Up @@ -212,9 +219,9 @@ else if (algOID.equals(EdECObjectIdentifiers.id_Ed448))
return new Ed448PrivateKeyParameters(getRawKey(keyInfo));
}
else if (
algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
{
ASN1Encodable algParameters = algId.getParameters();
GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algParameters);
Expand All @@ -226,11 +233,11 @@ else if (
X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet());

ecSpec = new ECGOST3410Parameters(
new ECNamedDomainParameters(
gostParams.getPublicKeyParamSet(), ecP),
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
new ECNamedDomainParameters(
gostParams.getPublicKeyParamSet(), ecP),
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());

int privateKeyLength = keyInfo.getPrivateKeyLength();

Expand Down Expand Up @@ -262,8 +269,8 @@ else if (
X9ECParameters ecP = ECNamedCurveTable.getByOID(oid);

ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(oid, ecP),
gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
}
else if (params.isImplicitlyCA())
{
Expand All @@ -273,8 +280,8 @@ else if (params.isImplicitlyCA())
{
X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(algOID, ecP),
gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
}

ASN1Encodable privKey = keyInfo.parsePrivateKey();
Expand All @@ -294,12 +301,12 @@ else if (params.isImplicitlyCA())
}

return new ECPrivateKeyParameters(
d,
new ECGOST3410Parameters(
ecSpec,
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet()));
d,
new ECGOST3410Parameters(
ecSpec,
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet()));

}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs;

/**
* Factory to create ASN.1 private key info objects from lightweight private keys.
Expand Down Expand Up @@ -71,7 +72,7 @@ private PrivateKeyInfoFactory()
* @throws java.io.IOException on an error encoding the key
*/
public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey)
throws IOException
throws IOException
{
return createPrivateKeyInfo(privateKey, null);
}
Expand All @@ -84,29 +85,37 @@ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter private
* @return the appropriate PrivateKeyInfo
* @throws java.io.IOException on an error encoding the key
*/
public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey, ASN1Set attributes)
throws IOException
public static PrivateKeyInfo createPrivateKeyInfo(
AsymmetricKeyParameter privateKey,
ASN1Set attributes)
throws IOException
{
// #tls-injection
if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedParameter(privateKey))
{
return Asn1BridgeForInjectedSigAlgs.theInstance().createPrivateKeyInfo(privateKey, attributes);
}

if (privateKey instanceof RSAKeyParameters)
{
RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters)privateKey;
RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters) privateKey;

return new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE),
new RSAPrivateKey(priv.getModulus(), priv.getPublicExponent(), priv.getExponent(), priv.getP(), priv.getQ(), priv.getDP(), priv.getDQ(), priv.getQInv()),
attributes);
new RSAPrivateKey(priv.getModulus(), priv.getPublicExponent(), priv.getExponent(), priv.getP(), priv.getQ(), priv.getDP(), priv.getDQ(), priv.getQInv()),
attributes);
}
else if (privateKey instanceof DSAPrivateKeyParameters)
{
DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)privateKey;
DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters) privateKey;
DSAParameters params = priv.getParameters();

return new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa,
new DSAParameter(params.getP(), params.getQ(), params.getG())), new ASN1Integer(priv.getX()),
attributes);
new DSAParameter(params.getP(), params.getQ(), params.getG())), new ASN1Integer(priv.getX()),
attributes);
}
else if (privateKey instanceof ECPrivateKeyParameters)
{
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)privateKey;
ECPrivateKeyParameters priv = (ECPrivateKeyParameters) privateKey;
ECDomainParameters domainParams = priv.getParameters();
ASN1Encodable params;
int orderBitLength;
Expand All @@ -119,9 +128,9 @@ else if (privateKey instanceof ECPrivateKeyParameters)
else if (domainParams instanceof ECGOST3410Parameters)
{
GOST3410PublicKeyAlgParameters gostParams = new GOST3410PublicKeyAlgParameters(
((ECGOST3410Parameters)domainParams).getPublicKeyParamSet(),
((ECGOST3410Parameters)domainParams).getDigestParamSet(),
((ECGOST3410Parameters)domainParams).getEncryptionParamSet());
((ECGOST3410Parameters) domainParams).getPublicKeyParamSet(),
((ECGOST3410Parameters) domainParams).getDigestParamSet(),
((ECGOST3410Parameters) domainParams).getEncryptionParamSet());


int size;
Expand All @@ -137,8 +146,8 @@ else if (domainParams instanceof ECGOST3410Parameters)

boolean is512 = priv.getD().bitLength() > 256;
identifier = (is512) ?
RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 :
RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 :
RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
size = (is512) ? 64 : 32;
}
byte[] encKey = new byte[size];
Expand All @@ -149,17 +158,17 @@ else if (domainParams instanceof ECGOST3410Parameters)
}
else if (domainParams instanceof ECNamedDomainParameters)
{
params = new X962Parameters(((ECNamedDomainParameters)domainParams).getName());
params = new X962Parameters(((ECNamedDomainParameters) domainParams).getName());
orderBitLength = domainParams.getN().bitLength();
}
else
{
X9ECParameters ecP = new X9ECParameters(
domainParams.getCurve(),
new X9ECPoint(domainParams.getG(), false),
domainParams.getN(),
domainParams.getH(),
domainParams.getSeed());
domainParams.getCurve(),
new X9ECPoint(domainParams.getG(), false),
domainParams.getN(),
domainParams.getH(),
domainParams.getSeed());

params = new X962Parameters(ecP);
orderBitLength = domainParams.getN().bitLength();
Expand All @@ -171,37 +180,37 @@ else if (domainParams instanceof ECNamedDomainParameters)
DERBitString publicKey = new DERBitString(q.getEncoded(false));

return new PrivateKeyInfo(
new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params),
new ECPrivateKey(orderBitLength, priv.getD(), publicKey, params),
attributes);
new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params),
new ECPrivateKey(orderBitLength, priv.getD(), publicKey, params),
attributes);
}
else if (privateKey instanceof X448PrivateKeyParameters)
{
X448PrivateKeyParameters key = (X448PrivateKeyParameters)privateKey;
X448PrivateKeyParameters key = (X448PrivateKeyParameters) privateKey;

return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448),
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
}
else if (privateKey instanceof X25519PrivateKeyParameters)
{
X25519PrivateKeyParameters key = (X25519PrivateKeyParameters)privateKey;
X25519PrivateKeyParameters key = (X25519PrivateKeyParameters) privateKey;

return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519),
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
}
else if (privateKey instanceof Ed448PrivateKeyParameters)
{
Ed448PrivateKeyParameters key = (Ed448PrivateKeyParameters)privateKey;
Ed448PrivateKeyParameters key = (Ed448PrivateKeyParameters) privateKey;

return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448),
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
}
else if (privateKey instanceof Ed25519PrivateKeyParameters)
{
Ed25519PrivateKeyParameters key = (Ed25519PrivateKeyParameters)privateKey;
Ed25519PrivateKeyParameters key = (Ed25519PrivateKeyParameters) privateKey;

return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519),
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded());
}
else
{
Expand All @@ -210,7 +219,11 @@ else if (privateKey instanceof Ed25519PrivateKeyParameters)
}


private static void extractBytes(byte[] encKey, int size, int offSet, BigInteger bI)
private static void extractBytes(
byte[] encKey,
int size,
int offSet,
BigInteger bI)
{
byte[] val = bI.toByteArray();
if (val.length < size)
Expand Down
Loading