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

227 lines
5.4 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 TlsECDHKeyExchange : AbstractTlsKeyExchange
{
protected TlsSigner mTlsSigner;
protected int[] mNamedCurves;
protected byte[] mClientECPointFormats;
protected byte[] mServerECPointFormats;
protected AsymmetricKeyParameter mServerPublicKey;
protected TlsAgreementCredentials mAgreementCredentials;
protected ECPrivateKeyParameters mECAgreePrivateKey;
protected ECPublicKeyParameters mECAgreePublicKey;
public override bool RequiresServerKeyExchange
{
get
{
switch (mKeyExchange)
{
case 17:
case 19:
case 20:
return true;
default:
return false;
}
}
}
public TlsECDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves, byte[] clientECPointFormats, byte[] serverECPointFormats)
: base(keyExchange, supportedSignatureAlgorithms)
{
switch (keyExchange)
{
case 19:
mTlsSigner = new TlsRsaSigner();
break;
case 17:
mTlsSigner = new TlsECDsaSigner();
break;
case 16:
case 18:
case 20:
mTlsSigner = null;
break;
default:
throw new InvalidOperationException("unsupported key exchange algorithm");
}
mNamedCurves = namedCurves;
mClientECPointFormats = clientECPointFormats;
mServerECPointFormats = serverECPointFormats;
}
public override void Init(TlsContext context)
{
base.Init(context);
if (mTlsSigner != null)
{
mTlsSigner.Init(context);
}
}
public override void SkipServerCredentials()
{
if (mKeyExchange != 20)
{
throw new TlsFatalAlert(10);
}
}
public override void ProcessServerCertificate(Certificate serverCertificate)
{
if (mKeyExchange == 20)
{
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
{
mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey((ECPublicKeyParameters)mServerPublicKey);
}
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();
mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, mClientECPointFormats, memoryStream);
return memoryStream.ToArray();
}
public override void ProcessServerKeyExchange(Stream input)
{
if (!RequiresServerKeyExchange)
{
throw new TlsFatalAlert(10);
}
ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input);
byte[] encoding = TlsUtilities.ReadOpaque8(input);
mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(mClientECPointFormats, curve_params, encoding));
}
public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
if (mKeyExchange == 20)
{
throw new TlsFatalAlert(40);
}
byte[] certificateTypes = certificateRequest.CertificateTypes;
for (int i = 0; i < certificateTypes.Length; i++)
{
switch (certificateTypes[i])
{
case 1:
case 2:
case 64:
case 65:
case 66:
continue;
}
throw new TlsFatalAlert(47);
}
}
public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
if (mKeyExchange == 20)
{
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)
{
mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, mServerECPointFormats, mECAgreePublicKey.Parameters, output);
}
}
public override void ProcessClientCertificate(Certificate clientCertificate)
{
if (mKeyExchange == 20)
{
throw new TlsFatalAlert(10);
}
}
public override void ProcessClientKeyExchange(Stream input)
{
if (mECAgreePublicKey == null)
{
byte[] encoding = TlsUtilities.ReadOpaque8(input);
ECDomainParameters parameters = mECAgreePrivateKey.Parameters;
mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(mServerECPointFormats, parameters, encoding));
}
}
public override byte[] GeneratePremasterSecret()
{
if (mAgreementCredentials != null)
{
return mAgreementCredentials.GenerateAgreement(mECAgreePublicKey);
}
if (mECAgreePrivateKey != null)
{
return TlsEccUtilities.CalculateECDHBasicAgreement(mECAgreePublicKey, mECAgreePrivateKey);
}
throw new TlsFatalAlert(80);
}
}