init commit
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto.Agreement.Srp;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Tls;
|
||||
|
||||
public class TlsSrpKeyExchange : AbstractTlsKeyExchange
|
||||
{
|
||||
protected TlsSigner mTlsSigner;
|
||||
|
||||
protected TlsSrpGroupVerifier mGroupVerifier;
|
||||
|
||||
protected byte[] mIdentity;
|
||||
|
||||
protected byte[] mPassword;
|
||||
|
||||
protected AsymmetricKeyParameter mServerPublicKey = null;
|
||||
|
||||
protected Srp6GroupParameters mSrpGroup = null;
|
||||
|
||||
protected Srp6Client mSrpClient = null;
|
||||
|
||||
protected Srp6Server mSrpServer = null;
|
||||
|
||||
protected BigInteger mSrpPeerCredentials = null;
|
||||
|
||||
protected BigInteger mSrpVerifier = null;
|
||||
|
||||
protected byte[] mSrpSalt = null;
|
||||
|
||||
protected TlsSignerCredentials mServerCredentials = null;
|
||||
|
||||
public override bool RequiresServerKeyExchange => true;
|
||||
|
||||
protected static TlsSigner CreateSigner(int keyExchange)
|
||||
{
|
||||
return keyExchange switch
|
||||
{
|
||||
21 => null,
|
||||
23 => new TlsRsaSigner(),
|
||||
22 => new TlsDssSigner(),
|
||||
_ => throw new ArgumentException("unsupported key exchange algorithm"),
|
||||
};
|
||||
}
|
||||
|
||||
[Obsolete("Use constructor taking an explicit 'groupVerifier' argument")]
|
||||
public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, byte[] identity, byte[] password)
|
||||
: this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsSrpGroupVerifier(), identity, password)
|
||||
{
|
||||
}
|
||||
|
||||
public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsSrpGroupVerifier groupVerifier, byte[] identity, byte[] password)
|
||||
: base(keyExchange, supportedSignatureAlgorithms)
|
||||
{
|
||||
mTlsSigner = CreateSigner(keyExchange);
|
||||
mGroupVerifier = groupVerifier;
|
||||
mIdentity = identity;
|
||||
mPassword = password;
|
||||
mSrpClient = new Srp6Client();
|
||||
}
|
||||
|
||||
public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, byte[] identity, TlsSrpLoginParameters loginParameters)
|
||||
: base(keyExchange, supportedSignatureAlgorithms)
|
||||
{
|
||||
mTlsSigner = CreateSigner(keyExchange);
|
||||
mIdentity = identity;
|
||||
mSrpServer = new Srp6Server();
|
||||
mSrpGroup = loginParameters.Group;
|
||||
mSrpVerifier = loginParameters.Verifier;
|
||||
mSrpSalt = loginParameters.Salt;
|
||||
}
|
||||
|
||||
public override void Init(TlsContext context)
|
||||
{
|
||||
base.Init(context);
|
||||
if (mTlsSigner != null)
|
||||
{
|
||||
mTlsSigner.Init(context);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SkipServerCredentials()
|
||||
{
|
||||
if (mTlsSigner != null)
|
||||
{
|
||||
throw new TlsFatalAlert(10);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ProcessServerCertificate(Certificate serverCertificate)
|
||||
{
|
||||
if (mTlsSigner == null)
|
||||
{
|
||||
throw new TlsFatalAlert(10);
|
||||
}
|
||||
if (serverCertificate.IsEmpty)
|
||||
{
|
||||
throw new TlsFatalAlert(42);
|
||||
}
|
||||
X509CertificateStructure certificateAt = serverCertificate.GetCertificateAt(0);
|
||||
SubjectPublicKeyInfo subjectPublicKeyInfo = certificateAt.SubjectPublicKeyInfo;
|
||||
try
|
||||
{
|
||||
mServerPublicKey = PublicKeyFactory.CreateKey(subjectPublicKeyInfo);
|
||||
}
|
||||
catch (Exception alertCause)
|
||||
{
|
||||
throw new TlsFatalAlert(43, alertCause);
|
||||
}
|
||||
if (!mTlsSigner.IsValidPublicKey(mServerPublicKey))
|
||||
{
|
||||
throw new TlsFatalAlert(46);
|
||||
}
|
||||
TlsUtilities.ValidateKeyUsage(certificateAt, 128);
|
||||
base.ProcessServerCertificate(serverCertificate);
|
||||
}
|
||||
|
||||
public override void ProcessServerCredentials(TlsCredentials serverCredentials)
|
||||
{
|
||||
if (mKeyExchange == 21 || !(serverCredentials is TlsSignerCredentials))
|
||||
{
|
||||
throw new TlsFatalAlert(80);
|
||||
}
|
||||
ProcessServerCertificate(serverCredentials.Certificate);
|
||||
mServerCredentials = (TlsSignerCredentials)serverCredentials;
|
||||
}
|
||||
|
||||
public override byte[] GenerateServerKeyExchange()
|
||||
{
|
||||
mSrpServer.Init(mSrpGroup, mSrpVerifier, TlsUtilities.CreateHash(2), mContext.SecureRandom);
|
||||
BigInteger b = mSrpServer.GenerateServerCredentials();
|
||||
ServerSrpParams serverSrpParams = new ServerSrpParams(mSrpGroup.N, mSrpGroup.G, mSrpSalt, b);
|
||||
DigestInputBuffer digestInputBuffer = new DigestInputBuffer();
|
||||
serverSrpParams.Encode(digestInputBuffer);
|
||||
if (mServerCredentials != null)
|
||||
{
|
||||
SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(mContext, mServerCredentials);
|
||||
IDigest digest = TlsUtilities.CreateHash(signatureAndHashAlgorithm);
|
||||
SecurityParameters securityParameters = mContext.SecurityParameters;
|
||||
digest.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
|
||||
digest.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
|
||||
digestInputBuffer.UpdateDigest(digest);
|
||||
byte[] array = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(array, 0);
|
||||
byte[] signature = mServerCredentials.GenerateCertificateSignature(array);
|
||||
DigitallySigned digitallySigned = new DigitallySigned(signatureAndHashAlgorithm, signature);
|
||||
digitallySigned.Encode(digestInputBuffer);
|
||||
}
|
||||
return digestInputBuffer.ToArray();
|
||||
}
|
||||
|
||||
public override void ProcessServerKeyExchange(Stream input)
|
||||
{
|
||||
SecurityParameters securityParameters = mContext.SecurityParameters;
|
||||
SignerInputBuffer signerInputBuffer = null;
|
||||
Stream input2 = input;
|
||||
if (mTlsSigner != null)
|
||||
{
|
||||
signerInputBuffer = new SignerInputBuffer();
|
||||
input2 = new TeeInputStream(input, signerInputBuffer);
|
||||
}
|
||||
ServerSrpParams serverSrpParams = ServerSrpParams.Parse(input2);
|
||||
if (signerInputBuffer != null)
|
||||
{
|
||||
DigitallySigned digitallySigned = ParseSignature(input);
|
||||
ISigner signer = InitVerifyer(mTlsSigner, digitallySigned.Algorithm, securityParameters);
|
||||
signerInputBuffer.UpdateSigner(signer);
|
||||
if (!signer.VerifySignature(digitallySigned.Signature))
|
||||
{
|
||||
throw new TlsFatalAlert(51);
|
||||
}
|
||||
}
|
||||
mSrpGroup = new Srp6GroupParameters(serverSrpParams.N, serverSrpParams.G);
|
||||
if (!mGroupVerifier.Accept(mSrpGroup))
|
||||
{
|
||||
throw new TlsFatalAlert(71);
|
||||
}
|
||||
mSrpSalt = serverSrpParams.S;
|
||||
try
|
||||
{
|
||||
mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, serverSrpParams.B);
|
||||
}
|
||||
catch (CryptoException alertCause)
|
||||
{
|
||||
throw new TlsFatalAlert(47, alertCause);
|
||||
}
|
||||
mSrpClient.Init(mSrpGroup, TlsUtilities.CreateHash(2), mContext.SecureRandom);
|
||||
}
|
||||
|
||||
public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
|
||||
{
|
||||
throw new TlsFatalAlert(10);
|
||||
}
|
||||
|
||||
public override void ProcessClientCredentials(TlsCredentials clientCredentials)
|
||||
{
|
||||
throw new TlsFatalAlert(80);
|
||||
}
|
||||
|
||||
public override void GenerateClientKeyExchange(Stream output)
|
||||
{
|
||||
BigInteger x = mSrpClient.GenerateClientCredentials(mSrpSalt, mIdentity, mPassword);
|
||||
TlsSrpUtilities.WriteSrpParameter(x, output);
|
||||
mContext.SecurityParameters.srpIdentity = Arrays.Clone(mIdentity);
|
||||
}
|
||||
|
||||
public override void ProcessClientKeyExchange(Stream input)
|
||||
{
|
||||
try
|
||||
{
|
||||
mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, TlsSrpUtilities.ReadSrpParameter(input));
|
||||
}
|
||||
catch (CryptoException alertCause)
|
||||
{
|
||||
throw new TlsFatalAlert(47, alertCause);
|
||||
}
|
||||
mContext.SecurityParameters.srpIdentity = Arrays.Clone(mIdentity);
|
||||
}
|
||||
|
||||
public override byte[] GeneratePremasterSecret()
|
||||
{
|
||||
try
|
||||
{
|
||||
BigInteger n = ((mSrpServer != null) ? mSrpServer.CalculateSecret(mSrpPeerCredentials) : mSrpClient.CalculateSecret(mSrpPeerCredentials));
|
||||
return BigIntegers.AsUnsignedByteArray(n);
|
||||
}
|
||||
catch (CryptoException alertCause)
|
||||
{
|
||||
throw new TlsFatalAlert(47, alertCause);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, SecurityParameters securityParameters)
|
||||
{
|
||||
ISigner signer = tlsSigner.CreateVerifyer(algorithm, mServerPublicKey);
|
||||
signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
|
||||
signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
|
||||
return signer;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user