You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

130 lines
4.5 KiB

using System;
using System.IO;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.EC;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/**
* EC domain class for generating key pairs and performing key agreement.
*/
public class BcTlsECDomain
: TlsECDomain
{
public static BcTlsSecret CalculateBasicAgreement(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey,
ECPublicKeyParameters publicKey)
{
ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement();
basicAgreement.Init(privateKey);
BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey);
/*
* RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by
* FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for
* any given field; leading zeros found in this octet string MUST NOT be truncated.
*/
byte[] secret = BigIntegers.AsUnsignedByteArray(basicAgreement.GetFieldSize(), agreementValue);
return crypto.AdoptLocalSecret(secret);
}
public static ECDomainParameters GetDomainParameters(TlsECConfig ecConfig)
{
return GetDomainParameters(ecConfig.NamedGroup);
}
public static ECDomainParameters GetDomainParameters(int namedGroup)
{
if (!NamedGroup.RefersToASpecificCurve(namedGroup))
return null;
// Parameters are lazily created the first time a particular curve is accessed
string curveName = NamedGroup.GetCurveName(namedGroup);
X9ECParameters ecP = CustomNamedCurves.GetByName(curveName);
if (ecP == null)
{
ecP = ECNamedCurveTable.GetByName(curveName);
if (ecP == null)
return null;
}
// It's a bit inefficient to do this conversion every time
#pragma warning disable CS0612 // 类型或成员已过时
return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
#pragma warning restore CS0612 // 类型或成员已过时
}
protected readonly BcTlsCrypto m_crypto;
protected readonly TlsECConfig m_ecConfig;
protected readonly ECDomainParameters m_ecDomainParameters;
public BcTlsECDomain(BcTlsCrypto crypto, TlsECConfig ecConfig)
{
this.m_crypto = crypto;
this.m_ecConfig = ecConfig;
this.m_ecDomainParameters = GetDomainParameters(ecConfig);
}
public virtual BcTlsSecret CalculateECDHAgreement(ECPrivateKeyParameters privateKey,
ECPublicKeyParameters publicKey)
{
return CalculateBasicAgreement(m_crypto, privateKey, publicKey);
}
public virtual TlsAgreement CreateECDH()
{
return new BcTlsECDH(this);
}
[Obsolete]
public virtual ECPoint DecodePoint(byte[] encoding)
{
return m_ecDomainParameters.Curve.DecodePoint(encoding);
}
public virtual ECPublicKeyParameters DecodePublicKey(byte[] encoding)
{
try
{
#pragma warning disable CS0612 // 类型或成员已过时
ECPoint point = DecodePoint(encoding);
#pragma warning restore CS0612 // 类型或成员已过时
return new ECPublicKeyParameters(point, m_ecDomainParameters);
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
}
public virtual byte[] EncodePoint(ECPoint point)
{
return point.GetEncoded(false);
}
public virtual byte[] EncodePublicKey(ECPublicKeyParameters publicKey)
{
return EncodePoint(publicKey.Q);
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
keyPairGenerator.Init(new ECKeyGenerationParameters(m_ecDomainParameters, m_crypto.SecureRandom));
return keyPairGenerator.GenerateKeyPair();
}
}
}