Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Crypto/Tls/TlsSrpKeyExchange.cs
2025-10-09 09:57:24 +09:00

248 lines
7.7 KiB
C#

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;
}
}