136 lines
5.5 KiB
C#
136 lines
5.5 KiB
C#
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
|
#pragma warning disable
|
|
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
|
|
{
|
|
/// <summary>(D)TLS ECDHE key exchange (see RFC 4492).</summary>
|
|
public class TlsECDheKeyExchange
|
|
: TlsECDHKeyExchange
|
|
{
|
|
protected TlsSignerCredentials mServerCredentials = null;
|
|
|
|
public TlsECDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves,
|
|
byte[] clientECPointFormats, byte[] serverECPointFormats)
|
|
: base(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats)
|
|
{
|
|
}
|
|
|
|
public override void ProcessServerCredentials(TlsCredentials serverCredentials)
|
|
{
|
|
if (!(serverCredentials is TlsSignerCredentials))
|
|
throw new TlsFatalAlert(AlertDescription.internal_error);
|
|
|
|
ProcessServerCertificate(serverCredentials.Certificate);
|
|
|
|
this.mServerCredentials = (TlsSignerCredentials)serverCredentials;
|
|
}
|
|
|
|
public override byte[] GenerateServerKeyExchange()
|
|
{
|
|
DigestInputBuffer buf = new DigestInputBuffer();
|
|
|
|
this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves,
|
|
mClientECPointFormats, buf);
|
|
|
|
/*
|
|
* RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
|
|
*/
|
|
SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
|
|
mContext, mServerCredentials);
|
|
|
|
IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm);
|
|
|
|
SecurityParameters securityParameters = mContext.SecurityParameters;
|
|
d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
|
|
d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
|
|
buf.UpdateDigest(d);
|
|
|
|
byte[] hash = DigestUtilities.DoFinal(d);
|
|
|
|
byte[] signature = mServerCredentials.GenerateCertificateSignature(hash);
|
|
|
|
DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature);
|
|
signed_params.Encode(buf);
|
|
|
|
return buf.ToArray();
|
|
}
|
|
|
|
public override void ProcessServerKeyExchange(Stream input)
|
|
{
|
|
SecurityParameters securityParameters = mContext.SecurityParameters;
|
|
|
|
SignerInputBuffer buf = new SignerInputBuffer();
|
|
Stream teeIn = new TeeInputStream(input, buf);
|
|
|
|
ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, teeIn);
|
|
|
|
byte[] point = TlsUtilities.ReadOpaque8(teeIn);
|
|
|
|
DigitallySigned signed_params = ParseSignature(input);
|
|
|
|
ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
|
|
buf.UpdateSigner(signer);
|
|
if (!signer.VerifySignature(signed_params.Signature))
|
|
throw new TlsFatalAlert(AlertDescription.decrypt_error);
|
|
|
|
this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
|
|
mClientECPointFormats, curve_params, point));
|
|
}
|
|
|
|
public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
|
|
{
|
|
/*
|
|
* RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with
|
|
* ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because
|
|
* the use of a long-term ECDH client key would jeopardize the forward secrecy property of
|
|
* these algorithms.
|
|
*/
|
|
byte[] types = certificateRequest.CertificateTypes;
|
|
for (int i = 0; i < types.Length; ++i)
|
|
{
|
|
switch (types[i])
|
|
{
|
|
case ClientCertificateType.rsa_sign:
|
|
case ClientCertificateType.dss_sign:
|
|
case ClientCertificateType.ecdsa_sign:
|
|
break;
|
|
default:
|
|
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void ProcessClientCredentials(TlsCredentials clientCredentials)
|
|
{
|
|
if (clientCredentials is TlsSignerCredentials)
|
|
{
|
|
// OK
|
|
}
|
|
else
|
|
{
|
|
throw new TlsFatalAlert(AlertDescription.internal_error);
|
|
}
|
|
}
|
|
|
|
protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm,
|
|
SecurityParameters securityParameters)
|
|
{
|
|
ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey);
|
|
signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
|
|
signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
|
|
return signer;
|
|
}
|
|
}
|
|
}
|
|
#pragma warning restore
|
|
#endif
|