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

228 lines
5.2 KiB
C#

using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Tls;
public class TlsDHKeyExchange : AbstractTlsKeyExchange
{
protected TlsSigner mTlsSigner;
protected TlsDHVerifier mDHVerifier;
protected DHParameters mDHParameters;
protected AsymmetricKeyParameter mServerPublicKey;
protected TlsAgreementCredentials mAgreementCredentials;
protected DHPrivateKeyParameters mDHAgreePrivateKey;
protected DHPublicKeyParameters mDHAgreePublicKey;
public override bool RequiresServerKeyExchange
{
get
{
switch (mKeyExchange)
{
case 3:
case 5:
case 11:
return true;
default:
return false;
}
}
}
[Obsolete("Use constructor that takes a TlsDHVerifier")]
public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters)
: this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsDHVerifier(), dhParameters)
{
}
public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsDHVerifier dhVerifier, DHParameters dhParameters)
: base(keyExchange, supportedSignatureAlgorithms)
{
switch (keyExchange)
{
case 7:
case 9:
case 11:
mTlsSigner = null;
break;
case 5:
mTlsSigner = new TlsRsaSigner();
break;
case 3:
mTlsSigner = new TlsDssSigner();
break;
default:
throw new InvalidOperationException("unsupported key exchange algorithm");
}
mDHVerifier = dhVerifier;
mDHParameters = dhParameters;
}
public override void Init(TlsContext context)
{
base.Init(context);
if (mTlsSigner != null)
{
mTlsSigner.Init(context);
}
}
public override void SkipServerCredentials()
{
if (mKeyExchange != 11)
{
throw new TlsFatalAlert(10);
}
}
public override void ProcessServerCertificate(Certificate serverCertificate)
{
if (mKeyExchange == 11)
{
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 == null)
{
try
{
mDHAgreePublicKey = (DHPublicKeyParameters)mServerPublicKey;
mDHParameters = mDHAgreePublicKey.Parameters;
}
catch (InvalidCastException alertCause2)
{
throw new TlsFatalAlert(46, alertCause2);
}
TlsUtilities.ValidateKeyUsage(certificateAt, 8);
}
else
{
if (!mTlsSigner.IsValidPublicKey(mServerPublicKey))
{
throw new TlsFatalAlert(46);
}
TlsUtilities.ValidateKeyUsage(certificateAt, 128);
}
base.ProcessServerCertificate(serverCertificate);
}
public override byte[] GenerateServerKeyExchange()
{
if (!RequiresServerKeyExchange)
{
return null;
}
MemoryStream memoryStream = new MemoryStream();
mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mDHParameters, memoryStream);
return memoryStream.ToArray();
}
public override void ProcessServerKeyExchange(Stream input)
{
if (!RequiresServerKeyExchange)
{
throw new TlsFatalAlert(10);
}
mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, input);
mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters);
}
public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
if (mKeyExchange == 11)
{
throw new TlsFatalAlert(40);
}
byte[] certificateTypes = certificateRequest.CertificateTypes;
for (int i = 0; i < certificateTypes.Length; i++)
{
switch (certificateTypes[i])
{
case 1:
case 2:
case 3:
case 4:
case 64:
continue;
}
throw new TlsFatalAlert(47);
}
}
public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
if (mKeyExchange == 11)
{
throw new TlsFatalAlert(80);
}
if (clientCredentials is TlsAgreementCredentials)
{
mAgreementCredentials = (TlsAgreementCredentials)clientCredentials;
}
else if (!(clientCredentials is TlsSignerCredentials))
{
throw new TlsFatalAlert(80);
}
}
public override void GenerateClientKeyExchange(Stream output)
{
if (mAgreementCredentials == null)
{
mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, mDHParameters, output);
}
}
public override void ProcessClientCertificate(Certificate clientCertificate)
{
if (mKeyExchange == 11)
{
throw new TlsFatalAlert(10);
}
}
public override void ProcessClientKeyExchange(Stream input)
{
if (mDHAgreePublicKey == null)
{
mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters);
}
}
public override byte[] GeneratePremasterSecret()
{
if (mAgreementCredentials != null)
{
return mAgreementCredentials.GenerateAgreement(mDHAgreePublicKey);
}
if (mDHAgreePrivateKey != null)
{
return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey);
}
throw new TlsFatalAlert(80);
}
}