This commit is contained in:
2026-06-15 18:18:16 +08:00
parent 97c9fba14e
commit 2b9f134e5f
4164 changed files with 386922 additions and 79 deletions

View File

@@ -0,0 +1,101 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections.Generic;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>Base class for a TlsCrypto implementation that provides some needed methods from elsewhere in the impl
/// package.</summary>
public abstract class AbstractTlsCrypto
: TlsCrypto
{
public abstract bool HasAnyStreamVerifiers(IList<SignatureAndHashAlgorithm> signatureAndHashAlgorithms);
public abstract bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes);
public abstract bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm);
public abstract bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm);
public abstract bool HasDHAgreement();
public abstract bool HasECDHAgreement();
public abstract bool HasEncryptionAlgorithm(int encryptionAlgorithm);
public abstract bool HasHkdfAlgorithm(int cryptoHashAlgorithm);
public abstract bool HasMacAlgorithm(int macAlgorithm);
public abstract bool HasNamedGroup(int namedGroup);
public abstract bool HasRsaEncryption();
public abstract bool HasSignatureAlgorithm(short signatureAlgorithm);
public abstract bool HasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm);
public abstract bool HasSignatureScheme(int signatureScheme);
public abstract bool HasSrpAuthentication();
public abstract TlsSecret CreateSecret(byte[] data);
public abstract TlsSecret GenerateRsaPreMasterSecret(ProtocolVersion clientVersion);
public abstract SecureRandom SecureRandom { get; }
public virtual TlsCertificate CreateCertificate(byte[] encoding)
{
return CreateCertificate(CertificateType.X509, encoding);
}
public abstract TlsCertificate CreateCertificate(short type, byte[] encoding);
public abstract TlsCipher CreateCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm, int macAlgorithm);
public abstract TlsDHDomain CreateDHDomain(TlsDHConfig dhConfig);
public abstract TlsECDomain CreateECDomain(TlsECConfig ecConfig);
public virtual TlsSecret AdoptSecret(TlsSecret secret)
{
// TODO[tls] Need an alternative that doesn't require AbstractTlsSecret (which holds literal data)
if (secret is AbstractTlsSecret)
{
AbstractTlsSecret sec = (AbstractTlsSecret)secret;
return CreateSecret(sec.CopyData());
}
throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(secret));
}
public abstract TlsHash CreateHash(int cryptoHashAlgorithm);
public abstract TlsHmac CreateHmac(int macAlgorithm);
public abstract TlsHmac CreateHmacForHash(int cryptoHashAlgorithm);
public abstract TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public abstract TlsNonceGenerator CreateNonceGenerator(ReadOnlySpan<byte> additionalSeedMaterial);
#endif
public abstract TlsSrp6Client CreateSrp6Client(TlsSrpConfig srpConfig);
public abstract TlsSrp6Server CreateSrp6Server(TlsSrpConfig srpConfig, BigInteger srpVerifier);
public abstract TlsSrp6VerifierGenerator CreateSrp6VerifierGenerator(TlsSrpConfig srpConfig);
public abstract TlsSecret HkdfInit(int cryptoHashAlgorithm);
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d1a4a126833da2e40844fa8069bfeb86
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,144 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>Base class for a TlsSecret implementation which captures common code and fields.</summary>
public abstract class AbstractTlsSecret
: TlsSecret
{
protected static byte[] CopyData(AbstractTlsSecret other)
{
return other.CopyData();
}
protected byte[] m_data;
/// <summary>Base constructor.</summary>
/// <param name="data">the byte[] making up the secret value.</param>
protected AbstractTlsSecret(byte[] data)
{
m_data = data;
}
protected virtual void CheckAlive()
{
if (m_data == null)
throw new InvalidOperationException("Secret has already been extracted or destroyed");
}
protected abstract AbstractTlsCrypto Crypto { get; }
public virtual byte[] CalculateHmac(int cryptoHashAlgorithm, byte[] buf, int off, int len)
{
lock (this)
{
CheckAlive();
TlsHmac hmac = Crypto.CreateHmacForHash(cryptoHashAlgorithm);
hmac.SetKey(m_data, 0, m_data.Length);
hmac.Update(buf, off, len);
return hmac.CalculateMac();
}
}
public abstract TlsSecret DeriveUsingPrf(int prfAlgorithm, string label, byte[] seed, int length);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public abstract TlsSecret DeriveUsingPrf(int prfAlgorithm, ReadOnlySpan<char> label, ReadOnlySpan<byte> seed,
int length);
#endif
public virtual void Destroy()
{
lock (this)
{
if (m_data != null)
{
// TODO Is there a way to ensure the data is really overwritten?
Array.Clear(m_data, 0, m_data.Length);
m_data = null;
}
}
}
/// <exception cref="IOException"/>
public virtual byte[] Encrypt(TlsEncryptor encryptor)
{
lock (this)
{
CheckAlive();
return encryptor.Encrypt(m_data, 0, m_data.Length);
}
}
public virtual byte[] Extract()
{
lock (this)
{
CheckAlive();
byte[] result = m_data;
m_data = null;
return result;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void ExtractTo(Span<byte> output)
{
lock (this)
{
CheckAlive();
m_data.CopyTo(output);
m_data = null;
}
}
#endif
public abstract TlsSecret HkdfExpand(int cryptoHashAlgorithm, byte[] info, int length);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public abstract TlsSecret HkdfExpand(int cryptoHashAlgorithm, ReadOnlySpan<byte> info, int length);
#endif
public abstract TlsSecret HkdfExtract(int cryptoHashAlgorithm, TlsSecret ikm);
public virtual bool IsAlive()
{
lock (this)
{
return null != m_data;
}
}
public virtual int Length
{
get
{
lock (this)
{
CheckAlive();
return m_data.Length;
}
}
}
internal virtual byte[] CopyData()
{
lock (this)
{
return Arrays.Clone(m_data);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef94305ee072ddf41a9532746428c761
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
public sealed class LegacyTls13Verifier
: TlsVerifier
{
private readonly int m_signatureScheme;
private readonly Tls13Verifier m_tls13Verifier;
public LegacyTls13Verifier(int signatureScheme, Tls13Verifier tls13Verifier)
{
if (!TlsUtilities.IsValidUint16(signatureScheme))
throw new ArgumentException("signatureScheme");
if (tls13Verifier == null)
throw new ArgumentNullException("tls13Verifier");
this.m_signatureScheme = signatureScheme;
this.m_tls13Verifier = tls13Verifier;
}
public TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned)
{
SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
return new TlsStreamVerifierImpl(m_tls13Verifier, digitallySigned.Signature);
}
public bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash)
{
throw new NotSupportedException();
}
private class TlsStreamVerifierImpl
: TlsStreamVerifier
{
private readonly Tls13Verifier m_tls13Verifier;
private readonly byte[] m_signature;
internal TlsStreamVerifierImpl(Tls13Verifier tls13Verifier, byte[] signature)
{
this.m_tls13Verifier = tls13Verifier;
this.m_signature = signature;
}
public Stream Stream
{
get { return m_tls13Verifier.Stream; }
}
public bool IsVerified()
{
return m_tls13Verifier.VerifySignature(m_signature);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8723fad84fcafb34b816778c033680f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,140 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
public abstract class RsaUtilities
{
private static readonly byte[] RSAPSSParams_256_A, RSAPSSParams_384_A, RSAPSSParams_512_A;
private static readonly byte[] RSAPSSParams_256_B, RSAPSSParams_384_B, RSAPSSParams_512_B;
static RsaUtilities()
{
/*
* RFC 4055
*/
AlgorithmIdentifier sha256Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256);
AlgorithmIdentifier sha384Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384);
AlgorithmIdentifier sha512Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512);
AlgorithmIdentifier sha256Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
AlgorithmIdentifier sha384Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
AlgorithmIdentifier sha512Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
AlgorithmIdentifier mgf1SHA256Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha256Identifier_A);
AlgorithmIdentifier mgf1SHA384Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha384Identifier_A);
AlgorithmIdentifier mgf1SHA512Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha512Identifier_A);
AlgorithmIdentifier mgf1SHA256Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha256Identifier_B);
AlgorithmIdentifier mgf1SHA384Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha384Identifier_B);
AlgorithmIdentifier mgf1SHA512Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha512Identifier_B);
DerInteger sha256Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha256));
DerInteger sha384Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha384));
DerInteger sha512Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha512));
DerInteger trailerField = new DerInteger(1);
try
{
RSAPSSParams_256_A = new RsassaPssParameters(sha256Identifier_A, mgf1SHA256Identifier_A, sha256Size, trailerField)
.GetEncoded(Asn1Encodable.Der);
RSAPSSParams_384_A = new RsassaPssParameters(sha384Identifier_A, mgf1SHA384Identifier_A, sha384Size, trailerField)
.GetEncoded(Asn1Encodable.Der);
RSAPSSParams_512_A = new RsassaPssParameters(sha512Identifier_A, mgf1SHA512Identifier_A, sha512Size, trailerField)
.GetEncoded(Asn1Encodable.Der);
RSAPSSParams_256_B = new RsassaPssParameters(sha256Identifier_B, mgf1SHA256Identifier_B, sha256Size, trailerField)
.GetEncoded(Asn1Encodable.Der);
RSAPSSParams_384_B = new RsassaPssParameters(sha384Identifier_B, mgf1SHA384Identifier_B, sha384Size, trailerField)
.GetEncoded(Asn1Encodable.Der);
RSAPSSParams_512_B = new RsassaPssParameters(sha512Identifier_B, mgf1SHA512Identifier_B, sha512Size, trailerField)
.GetEncoded(Asn1Encodable.Der);
}
catch (IOException e)
{
throw new InvalidOperationException(e.Message);
}
}
public static bool SupportsPkcs1(AlgorithmIdentifier pubKeyAlgID)
{
DerObjectIdentifier oid = pubKeyAlgID.Algorithm;
return PkcsObjectIdentifiers.RsaEncryption.Equals(oid)
|| X509ObjectIdentifiers.IdEARsa.Equals(oid);
}
public static bool SupportsPss_Pss(short signatureAlgorithm, AlgorithmIdentifier pubKeyAlgID)
{
DerObjectIdentifier oid = pubKeyAlgID.Algorithm;
if (!PkcsObjectIdentifiers.IdRsassaPss.Equals(oid))
return false;
/*
* TODO ASN.1 NULL shouldn't really be allowed here; it's a workaround for e.g. Oracle JDK
* 1.8.0_241, where the X.509 certificate implementation adds the NULL when re-encoding the
* original parameters. It appears it was fixed at some later date (OpenJDK 12.0.2 does not
* have the issue), but not sure exactly when.
*/
Asn1Encodable pssParams = pubKeyAlgID.Parameters;
if (null == pssParams || pssParams is DerNull)
{
switch (signatureAlgorithm)
{
case SignatureAlgorithm.rsa_pss_pss_sha256:
case SignatureAlgorithm.rsa_pss_pss_sha384:
case SignatureAlgorithm.rsa_pss_pss_sha512:
return true;
default:
return false;
}
}
byte[] encoded;
try
{
encoded = pssParams.ToAsn1Object().GetEncoded(Asn1Encodable.Der);
}
catch (Exception)
{
return false;
}
byte[] expected_A, expected_B;
switch (signatureAlgorithm)
{
case SignatureAlgorithm.rsa_pss_pss_sha256:
expected_A = RSAPSSParams_256_A;
expected_B = RSAPSSParams_256_B;
break;
case SignatureAlgorithm.rsa_pss_pss_sha384:
expected_A = RSAPSSParams_384_A;
expected_B = RSAPSSParams_384_B;
break;
case SignatureAlgorithm.rsa_pss_pss_sha512:
expected_A = RSAPSSParams_512_A;
expected_B = RSAPSSParams_512_B;
break;
default:
return false;
}
return Arrays.AreEqual(expected_A, encoded)
|| Arrays.AreEqual(expected_B, encoded);
}
public static bool SupportsPss_Rsae(AlgorithmIdentifier pubKeyAlgID)
{
DerObjectIdentifier oid = pubKeyAlgID.Algorithm;
return PkcsObjectIdentifiers.RsaEncryption.Equals(oid);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f935fb480e2cd004491dcdde3d7ff10c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,497 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>A generic TLS 1.2 AEAD cipher.</summary>
public class TlsAeadCipher
: TlsCipher
{
public const int AEAD_CCM = 1;
public const int AEAD_CHACHA20_POLY1305 = 2;
public const int AEAD_GCM = 3;
private const int NONCE_RFC5288 = 1;
private const int NONCE_RFC7905 = 2;
protected readonly TlsCryptoParameters m_cryptoParams;
protected readonly int m_keySize;
protected readonly int m_macSize;
protected readonly int m_fixed_iv_length;
protected readonly int m_record_iv_length;
protected readonly TlsAeadCipherImpl m_decryptCipher, m_encryptCipher;
protected readonly byte[] m_decryptNonce, m_encryptNonce;
protected readonly bool m_isTlsV13;
protected readonly int m_nonceMode;
/// <exception cref="IOException"/>
public TlsAeadCipher(TlsCryptoParameters cryptoParams, TlsAeadCipherImpl encryptCipher,
TlsAeadCipherImpl decryptCipher, int keySize, int macSize, int aeadType)
{
SecurityParameters securityParameters = cryptoParams.SecurityParameters;
ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion;
if (!TlsImplUtilities.IsTlsV12(negotiatedVersion))
throw new TlsFatalAlert(AlertDescription.internal_error);
this.m_isTlsV13 = TlsImplUtilities.IsTlsV13(negotiatedVersion);
this.m_nonceMode = GetNonceMode(m_isTlsV13, aeadType);
switch (m_nonceMode)
{
case NONCE_RFC5288:
this.m_fixed_iv_length = 4;
this.m_record_iv_length = 8;
break;
case NONCE_RFC7905:
this.m_fixed_iv_length = 12;
this.m_record_iv_length = 0;
break;
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
this.m_cryptoParams = cryptoParams;
this.m_keySize = keySize;
this.m_macSize = macSize;
this.m_decryptCipher = decryptCipher;
this.m_encryptCipher = encryptCipher;
this.m_decryptNonce = new byte[m_fixed_iv_length];
this.m_encryptNonce = new byte[m_fixed_iv_length];
bool isServer = cryptoParams.IsServer;
if (m_isTlsV13)
{
RekeyCipher(securityParameters, decryptCipher, m_decryptNonce, !isServer);
RekeyCipher(securityParameters, encryptCipher, m_encryptNonce, isServer);
return;
}
int keyBlockSize = (2 * keySize) + (2 * m_fixed_iv_length);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> keyBlock = keyBlockSize <= 512
? stackalloc byte[keyBlockSize]
: new byte[keyBlockSize];
TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlock);
if (isServer)
{
decryptCipher.SetKey(keyBlock[..keySize]); keyBlock = keyBlock[keySize..];
encryptCipher.SetKey(keyBlock[..keySize]); keyBlock = keyBlock[keySize..];
keyBlock[..m_fixed_iv_length].CopyTo(m_decryptNonce); keyBlock = keyBlock[m_fixed_iv_length..];
keyBlock[..m_fixed_iv_length].CopyTo(m_encryptNonce); keyBlock = keyBlock[m_fixed_iv_length..];
}
else
{
encryptCipher.SetKey(keyBlock[..keySize]); keyBlock = keyBlock[keySize..];
decryptCipher.SetKey(keyBlock[..keySize]); keyBlock = keyBlock[keySize..];
keyBlock[..m_fixed_iv_length].CopyTo(m_encryptNonce); keyBlock = keyBlock[m_fixed_iv_length..];
keyBlock[..m_fixed_iv_length].CopyTo(m_decryptNonce); keyBlock = keyBlock[m_fixed_iv_length..];
}
if (!keyBlock.IsEmpty)
throw new TlsFatalAlert(AlertDescription.internal_error);
#else
byte[] keyBlock = TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlockSize);
int pos = 0;
if (isServer)
{
decryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize;
encryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize;
Array.Copy(keyBlock, pos, m_decryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length;
Array.Copy(keyBlock, pos, m_encryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length;
}
else
{
encryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize;
decryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize;
Array.Copy(keyBlock, pos, m_encryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length;
Array.Copy(keyBlock, pos, m_decryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length;
}
if (pos != keyBlockSize)
throw new TlsFatalAlert(AlertDescription.internal_error);
#endif
int nonceLength = m_fixed_iv_length + m_record_iv_length;
// NOTE: Ensure dummy nonce is not part of the generated sequence(s)
byte[] dummyNonce = new byte[nonceLength];
dummyNonce[0] = (byte)~m_encryptNonce[0];
dummyNonce[1] = (byte)~m_decryptNonce[1];
encryptCipher.Init(dummyNonce, macSize, null);
decryptCipher.Init(dummyNonce, macSize, null);
}
public virtual int GetCiphertextDecodeLimit(int plaintextLimit)
{
return plaintextLimit + m_macSize + m_record_iv_length + (m_isTlsV13 ? 1 : 0);
}
public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit)
{
int innerPlaintextLimit = plaintextLength;
if (m_isTlsV13)
{
// TODO[tls13] Add support for padding
int maxPadding = 0;
innerPlaintextLimit = 1 + System.Math.Min(plaintextLimit, plaintextLength + maxPadding);
}
return innerPlaintextLimit + m_macSize + m_record_iv_length;
}
public virtual int GetPlaintextLimit(int ciphertextLimit)
{
return ciphertextLimit - m_macSize - m_record_iv_length - (m_isTlsV13 ? 1 : 0);
}
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion,
int headerAllocation, byte[] plaintext, int plaintextOffset, int plaintextLength)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return EncodePlaintext(seqNo, contentType, recordVersion, headerAllocation,
plaintext.AsSpan(plaintextOffset, plaintextLength));
#else
byte[] nonce = new byte[m_encryptNonce.Length + m_record_iv_length];
switch (m_nonceMode)
{
case NONCE_RFC5288:
Array.Copy(m_encryptNonce, 0, nonce, 0, m_encryptNonce.Length);
// RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number.
TlsUtilities.WriteUint64(seqNo, nonce, m_encryptNonce.Length);
break;
case NONCE_RFC7905:
TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8);
for (int i = 0; i < m_encryptNonce.Length; ++i)
{
nonce[i] ^= m_encryptNonce[i];
}
break;
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
int extraLength = m_isTlsV13 ? 1 : 0;
// TODO[tls13] If we support adding padding to TLSInnerPlaintext, this will need review
int encryptionLength = m_encryptCipher.GetOutputSize(plaintextLength + extraLength);
int ciphertextLength = m_record_iv_length + encryptionLength;
byte[] output = new byte[headerAllocation + ciphertextLength];
int outputPos = headerAllocation;
if (m_record_iv_length != 0)
{
Array.Copy(nonce, nonce.Length - m_record_iv_length, output, outputPos, m_record_iv_length);
outputPos += m_record_iv_length;
}
short recordType = m_isTlsV13 ? ContentType.application_data : contentType;
byte[] additionalData = GetAdditionalData(seqNo, recordType, recordVersion, ciphertextLength,
plaintextLength);
try
{
Array.Copy(plaintext, plaintextOffset, output, outputPos, plaintextLength);
if (m_isTlsV13)
{
output[outputPos + plaintextLength] = (byte)contentType;
}
m_encryptCipher.Init(nonce, m_macSize, additionalData);
outputPos += m_encryptCipher.DoFinal(output, outputPos, plaintextLength + extraLength, output,
outputPos);
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
if (outputPos != output.Length)
{
// NOTE: The additional data mechanism for AEAD ciphers requires exact output size prediction.
throw new TlsFatalAlert(AlertDescription.internal_error);
}
return new TlsEncodeResult(output, 0, output.Length, recordType);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion,
int headerAllocation, ReadOnlySpan<byte> plaintext)
{
byte[] nonce = new byte[m_encryptNonce.Length + m_record_iv_length];
switch (m_nonceMode)
{
case NONCE_RFC5288:
Array.Copy(m_encryptNonce, 0, nonce, 0, m_encryptNonce.Length);
// RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number.
TlsUtilities.WriteUint64(seqNo, nonce, m_encryptNonce.Length);
break;
case NONCE_RFC7905:
TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8);
for (int i = 0; i < m_encryptNonce.Length; ++i)
{
nonce[i] ^= m_encryptNonce[i];
}
break;
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
int extraLength = m_isTlsV13 ? 1 : 0;
// TODO[tls13] If we support adding padding to TLSInnerPlaintext, this will need review
int encryptionLength = m_encryptCipher.GetOutputSize(plaintext.Length + extraLength);
int ciphertextLength = m_record_iv_length + encryptionLength;
byte[] output = new byte[headerAllocation + ciphertextLength];
int outputPos = headerAllocation;
if (m_record_iv_length != 0)
{
Array.Copy(nonce, nonce.Length - m_record_iv_length, output, outputPos, m_record_iv_length);
outputPos += m_record_iv_length;
}
short recordType = m_isTlsV13 ? ContentType.application_data : contentType;
byte[] additionalData = GetAdditionalData(seqNo, recordType, recordVersion, ciphertextLength,
plaintext.Length);
try
{
plaintext.CopyTo(output.AsSpan(outputPos));
if (m_isTlsV13)
{
output[outputPos + plaintext.Length] = (byte)contentType;
}
m_encryptCipher.Init(nonce, m_macSize, additionalData);
outputPos += m_encryptCipher.DoFinal(output, outputPos, plaintext.Length + extraLength, output,
outputPos);
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
if (outputPos != output.Length)
{
// NOTE: The additional data mechanism for AEAD ciphers requires exact output size prediction.
throw new TlsFatalAlert(AlertDescription.internal_error);
}
return new TlsEncodeResult(output, 0, output.Length, recordType);
}
#endif
public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion,
byte[] ciphertext, int ciphertextOffset, int ciphertextLength)
{
if (GetPlaintextLimit(ciphertextLength) < 0)
throw new TlsFatalAlert(AlertDescription.decode_error);
byte[] nonce = new byte[m_decryptNonce.Length + m_record_iv_length];
switch (m_nonceMode)
{
case NONCE_RFC5288:
Array.Copy(m_decryptNonce, 0, nonce, 0, m_decryptNonce.Length);
Array.Copy(ciphertext, ciphertextOffset, nonce, nonce.Length - m_record_iv_length,
m_record_iv_length);
break;
case NONCE_RFC7905:
TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8);
for (int i = 0; i < m_decryptNonce.Length; ++i)
{
nonce[i] ^= m_decryptNonce[i];
}
break;
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
int encryptionOffset = ciphertextOffset + m_record_iv_length;
int encryptionLength = ciphertextLength - m_record_iv_length;
int plaintextLength = m_decryptCipher.GetOutputSize(encryptionLength);
byte[] additionalData = GetAdditionalData(seqNo, recordType, recordVersion, ciphertextLength,
plaintextLength);
int outputPos;
try
{
m_decryptCipher.Init(nonce, m_macSize, additionalData);
outputPos = m_decryptCipher.DoFinal(ciphertext, encryptionOffset, encryptionLength, ciphertext,
encryptionOffset);
}
catch (TlsFatalAlert fatalAlert)
{
if (AlertDescription.bad_record_mac == fatalAlert.AlertDescription)
{
m_decryptCipher.Reset();
}
throw fatalAlert;
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
m_decryptCipher.Reset();
throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
}
if (outputPos != plaintextLength)
{
// NOTE: The additional data mechanism for AEAD ciphers requires exact output size prediction.
throw new TlsFatalAlert(AlertDescription.internal_error);
}
short contentType = recordType;
if (m_isTlsV13)
{
// Strip padding and read true content type from TLSInnerPlaintext
int pos = plaintextLength;
for (;;)
{
if (--pos < 0)
throw new TlsFatalAlert(AlertDescription.unexpected_message);
byte octet = ciphertext[encryptionOffset + pos];
if (0 != octet)
{
contentType = (short)(octet & 0xFF);
plaintextLength = pos;
break;
}
}
}
return new TlsDecodeResult(ciphertext, encryptionOffset, plaintextLength, contentType);
}
public virtual void RekeyDecoder()
{
RekeyCipher(m_cryptoParams.SecurityParameters, m_decryptCipher, m_decryptNonce, !m_cryptoParams.IsServer);
}
public virtual void RekeyEncoder()
{
RekeyCipher(m_cryptoParams.SecurityParameters, m_encryptCipher, m_encryptNonce, m_cryptoParams.IsServer);
}
public virtual bool UsesOpaqueRecordType
{
get { return m_isTlsV13; }
}
protected virtual byte[] GetAdditionalData(long seqNo, short recordType, ProtocolVersion recordVersion,
int ciphertextLength, int plaintextLength)
{
if (m_isTlsV13)
{
/*
* TLSCiphertext.opaque_type || TLSCiphertext.legacy_record_version || TLSCiphertext.length
*/
byte[] additional_data = new byte[5];
TlsUtilities.WriteUint8(recordType, additional_data, 0);
TlsUtilities.WriteVersion(recordVersion, additional_data, 1);
TlsUtilities.WriteUint16(ciphertextLength, additional_data, 3);
return additional_data;
}
else
{
/*
* seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length
*/
byte[] additional_data = new byte[13];
TlsUtilities.WriteUint64(seqNo, additional_data, 0);
TlsUtilities.WriteUint8(recordType, additional_data, 8);
TlsUtilities.WriteVersion(recordVersion, additional_data, 9);
TlsUtilities.WriteUint16(plaintextLength, additional_data, 11);
return additional_data;
}
}
protected virtual void RekeyCipher(SecurityParameters securityParameters, TlsAeadCipherImpl cipher,
byte[] nonce, bool serverSecret)
{
if (!m_isTlsV13)
throw new TlsFatalAlert(AlertDescription.internal_error);
TlsSecret secret = serverSecret
? securityParameters.TrafficSecretServer
: securityParameters.TrafficSecretClient;
// TODO[tls13] For early data, have to disable server->client
if (null == secret)
throw new TlsFatalAlert(AlertDescription.internal_error);
Setup13Cipher(cipher, nonce, secret, securityParameters.PrfCryptoHashAlgorithm);
}
protected virtual void Setup13Cipher(TlsAeadCipherImpl cipher, byte[] nonce, TlsSecret secret,
int cryptoHashAlgorithm)
{
byte[] key = TlsCryptoUtilities.HkdfExpandLabel(secret, cryptoHashAlgorithm, "key",
TlsUtilities.EmptyBytes, m_keySize).Extract();
byte[] iv = TlsCryptoUtilities.HkdfExpandLabel(secret, cryptoHashAlgorithm, "iv", TlsUtilities.EmptyBytes,
m_fixed_iv_length).Extract();
cipher.SetKey(key, 0, m_keySize);
Array.Copy(iv, 0, nonce, 0, m_fixed_iv_length);
// NOTE: Ensure dummy nonce is not part of the generated sequence(s)
iv [0] ^= 0x80;
cipher.Init(iv, m_macSize, null);
}
private static int GetNonceMode(bool isTLSv13, int aeadType)
{
switch (aeadType)
{
case AEAD_CCM:
case AEAD_GCM:
return isTLSv13 ? NONCE_RFC7905 : NONCE_RFC5288;
case AEAD_CHACHA20_POLY1305:
return NONCE_RFC7905;
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5fdf671c05679fb4a9235bb34a12cec0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>Base interface for services supporting AEAD encryption/decryption.</summary>
public interface TlsAeadCipherImpl
{
/// <summary>Set the key to be used by the AEAD cipher implementation supporting this service.</summary>
/// <param name="key">array holding the AEAD cipher key.</param>
/// <param name="keyOff">offset into the array the key starts at.</param>
/// <param name="keyLen">length of the key in the array.</param>
/// <exception cref="IOException"/>
void SetKey(byte[] key, int keyOff, int keyLen);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
void SetKey(ReadOnlySpan<byte> key);
#endif
/// <summary>Initialise the parameters for the AEAD operator.</summary>
/// <param name="nonce">the nonce.</param>
/// <param name="macSize">MAC size in bytes.</param>
/// <param name="additionalData">any additional data to be included in the MAC calculation.</param>
/// <exception cref="IOException">if the parameters are inappropriate.</exception>
void Init(byte[] nonce, int macSize, byte[] additionalData);
/// <summary>Return the maximum size of the output for input of inputLength bytes.</summary>
/// <param name="inputLength">the length (in bytes) of the proposed input.</param>
/// <returns>the maximum size of the output.</returns>
int GetOutputSize(int inputLength);
/// <summary>Perform the cipher encryption/decryption returning the output in output.</summary>
/// <remarks>
/// Note: we have to use DoFinal() here as it is the only way to guarantee output from the underlying cipher.
/// </remarks>
/// <param name="input">array holding input data to the cipher.</param>
/// <param name="inputOffset">offset into input array data starts at.</param>
/// <param name="inputLength">length of the input data in the array.</param>
/// <param name="output">array to hold the cipher output.</param>
/// <param name="outputOffset">offset into output array to start saving output.</param>
/// <returns>the amount of data written to output.</returns>
/// <exception cref="IOException">in case of failure.</exception>
int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset);
void Reset();
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9f52f1077f381fd4285eaf40e6ac99f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,532 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>A generic TLS 1.0-1.2 block cipher. This can be used for AES or 3DES for example.</summary>
public class TlsBlockCipher
: TlsCipher
{
protected readonly TlsCryptoParameters m_cryptoParams;
protected readonly byte[] m_randomData;
protected readonly bool m_encryptThenMac;
protected readonly bool m_useExplicitIV;
protected readonly bool m_acceptExtraPadding;
protected readonly bool m_useExtraPadding;
protected readonly TlsBlockCipherImpl m_decryptCipher, m_encryptCipher;
protected readonly TlsSuiteMac m_readMac, m_writeMac;
/// <exception cref="IOException"/>
public TlsBlockCipher(TlsCryptoParameters cryptoParams, TlsBlockCipherImpl encryptCipher,
TlsBlockCipherImpl decryptCipher, TlsHmac clientMac, TlsHmac serverMac, int cipherKeySize)
{
SecurityParameters securityParameters = cryptoParams.SecurityParameters;
ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion;
if (TlsImplUtilities.IsTlsV13(negotiatedVersion))
throw new TlsFatalAlert(AlertDescription.internal_error);
this.m_cryptoParams = cryptoParams;
this.m_randomData = cryptoParams.NonceGenerator.GenerateNonce(256);
this.m_encryptThenMac = securityParameters.IsEncryptThenMac;
this.m_useExplicitIV = TlsImplUtilities.IsTlsV11(negotiatedVersion);
this.m_acceptExtraPadding = !negotiatedVersion.IsSsl;
/*
* Don't use variable-length padding with truncated MACs.
*
* See "Tag Size Does Matter: Attacks and Proofs for the TLS Record Protocol", Paterson,
* Ristenpart, Shrimpton.
*
* TODO[DTLS] Consider supporting in DTLS (without exceeding send limit though)
*/
this.m_useExtraPadding = securityParameters.IsExtendedPadding
&& ProtocolVersion.TLSv10.IsEqualOrEarlierVersionOf(negotiatedVersion)
&& (m_encryptThenMac || !securityParameters.IsTruncatedHmac);
this.m_encryptCipher = encryptCipher;
this.m_decryptCipher = decryptCipher;
TlsBlockCipherImpl clientCipher, serverCipher;
if (cryptoParams.IsServer)
{
clientCipher = decryptCipher;
serverCipher = encryptCipher;
}
else
{
clientCipher = encryptCipher;
serverCipher = decryptCipher;
}
int keyBlockSize = (2 * cipherKeySize) + clientMac.MacLength + serverMac.MacLength;
// From TLS 1.1 onwards, block ciphers don't need IVs from the key_block
if (!m_useExplicitIV)
{
keyBlockSize += clientCipher.GetBlockSize() + serverCipher.GetBlockSize();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> keyBlock = keyBlockSize <= 512
? stackalloc byte[keyBlockSize]
: new byte[keyBlockSize];
TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlock);
clientMac.SetKey(keyBlock[..clientMac.MacLength]); keyBlock = keyBlock[clientMac.MacLength..];
serverMac.SetKey(keyBlock[..serverMac.MacLength]); keyBlock = keyBlock[serverMac.MacLength..];
clientCipher.SetKey(keyBlock[..cipherKeySize]); keyBlock = keyBlock[cipherKeySize..];
serverCipher.SetKey(keyBlock[..cipherKeySize]); keyBlock = keyBlock[cipherKeySize..];
int clientIVLength = clientCipher.GetBlockSize();
int serverIVLength = serverCipher.GetBlockSize();
if (m_useExplicitIV)
{
clientCipher.Init(clientIVLength <= 64 ? stackalloc byte[clientIVLength] : new byte[clientIVLength]);
serverCipher.Init(serverIVLength <= 64 ? stackalloc byte[serverIVLength] : new byte[serverIVLength]);
}
else
{
clientCipher.Init(keyBlock[..clientIVLength]); keyBlock = keyBlock[clientIVLength..];
serverCipher.Init(keyBlock[..serverIVLength]); keyBlock = keyBlock[serverIVLength..];
}
if (!keyBlock.IsEmpty)
throw new TlsFatalAlert(AlertDescription.internal_error);
#else
byte[] keyBlock = TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlockSize);
int pos = 0;
clientMac.SetKey(keyBlock, pos, clientMac.MacLength);
pos += clientMac.MacLength;
serverMac.SetKey(keyBlock, pos, serverMac.MacLength);
pos += serverMac.MacLength;
clientCipher.SetKey(keyBlock, pos, cipherKeySize);
pos += cipherKeySize;
serverCipher.SetKey(keyBlock, pos, cipherKeySize);
pos += cipherKeySize;
int clientIVLength = clientCipher.GetBlockSize();
int serverIVLength = serverCipher.GetBlockSize();
if (m_useExplicitIV)
{
clientCipher.Init(new byte[clientIVLength], 0, clientIVLength);
serverCipher.Init(new byte[serverIVLength], 0, serverIVLength);
}
else
{
clientCipher.Init(keyBlock, pos, clientIVLength);
pos += clientIVLength;
serverCipher.Init(keyBlock, pos, serverIVLength);
pos += serverIVLength;
}
if (pos != keyBlockSize)
throw new TlsFatalAlert(AlertDescription.internal_error);
#endif
if (cryptoParams.IsServer)
{
this.m_writeMac = new TlsSuiteHmac(cryptoParams, serverMac);
this.m_readMac = new TlsSuiteHmac(cryptoParams, clientMac);
}
else
{
this.m_writeMac = new TlsSuiteHmac(cryptoParams, clientMac);
this.m_readMac = new TlsSuiteHmac(cryptoParams, serverMac);
}
}
public virtual int GetCiphertextDecodeLimit(int plaintextLimit)
{
int blockSize = m_decryptCipher.GetBlockSize();
int macSize = m_readMac.Size;
int maxPadding = 256;
return GetCiphertextLength(blockSize, macSize, maxPadding, plaintextLimit);
}
public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit)
{
int blockSize = m_encryptCipher.GetBlockSize();
int macSize = m_writeMac.Size;
int maxPadding = m_useExtraPadding ? 256 : blockSize;
return GetCiphertextLength(blockSize, macSize, maxPadding, plaintextLength);
}
public virtual int GetPlaintextLimit(int ciphertextLimit)
{
int blockSize = m_encryptCipher.GetBlockSize();
int macSize = m_writeMac.Size;
int plaintextLimit = ciphertextLimit;
// Leave room for the MAC, and require block-alignment
if (m_encryptThenMac)
{
plaintextLimit -= macSize;
plaintextLimit -= plaintextLimit % blockSize;
}
else
{
plaintextLimit -= plaintextLimit % blockSize;
plaintextLimit -= macSize;
}
// Minimum 1 byte of padding
--plaintextLimit;
// An explicit IV consumes 1 block
if (m_useExplicitIV)
{
plaintextLimit -= blockSize;
}
return plaintextLimit;
}
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion,
int headerAllocation, byte[] plaintext, int offset, int len)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return EncodePlaintext(seqNo, contentType, recordVersion, headerAllocation, plaintext.AsSpan(offset, len));
#else
int blockSize = m_encryptCipher.GetBlockSize();
int macSize = m_writeMac.Size;
int enc_input_length = len;
if (!m_encryptThenMac)
{
enc_input_length += macSize;
}
int padding_length = blockSize - (enc_input_length % blockSize);
if (m_useExtraPadding)
{
// Add a random number of extra blocks worth of padding
int maxExtraPadBlocks = (256 - padding_length) / blockSize;
int actualExtraPadBlocks = ChooseExtraPadBlocks(maxExtraPadBlocks);
padding_length += actualExtraPadBlocks * blockSize;
}
int totalSize = len + macSize + padding_length;
if (m_useExplicitIV)
{
totalSize += blockSize;
}
byte[] outBuf = new byte[headerAllocation + totalSize];
int outOff = headerAllocation;
if (m_useExplicitIV)
{
// Technically the explicit IV will be the encryption of this nonce
byte[] explicitIV = m_cryptoParams.NonceGenerator.GenerateNonce(blockSize);
Array.Copy(explicitIV, 0, outBuf, outOff, blockSize);
outOff += blockSize;
}
Array.Copy(plaintext, offset, outBuf, outOff, len);
outOff += len;
if (!m_encryptThenMac)
{
byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, plaintext, offset, len);
Array.Copy(mac, 0, outBuf, outOff, mac.Length);
outOff += mac.Length;
}
byte padByte = (byte)(padding_length - 1);
for (int i = 0; i < padding_length; ++i)
{
outBuf[outOff++] = padByte;
}
m_encryptCipher.DoFinal(outBuf, headerAllocation, outOff - headerAllocation, outBuf, headerAllocation);
if (m_encryptThenMac)
{
byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, outBuf, headerAllocation,
outOff - headerAllocation);
Array.Copy(mac, 0, outBuf, outOff, mac.Length);
outOff += mac.Length;
}
if (outOff != outBuf.Length)
throw new TlsFatalAlert(AlertDescription.internal_error);
return new TlsEncodeResult(outBuf, 0, outBuf.Length, contentType);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion,
int headerAllocation, ReadOnlySpan<byte> plaintext)
{
int blockSize = m_encryptCipher.GetBlockSize();
int macSize = m_writeMac.Size;
int enc_input_length = plaintext.Length;
if (!m_encryptThenMac)
{
enc_input_length += macSize;
}
int padding_length = blockSize - (enc_input_length % blockSize);
if (m_useExtraPadding)
{
// Add a random number of extra blocks worth of padding
int maxExtraPadBlocks = (256 - padding_length) / blockSize;
int actualExtraPadBlocks = ChooseExtraPadBlocks(maxExtraPadBlocks);
padding_length += actualExtraPadBlocks * blockSize;
}
int totalSize = plaintext.Length + macSize + padding_length;
if (m_useExplicitIV)
{
totalSize += blockSize;
}
byte[] outBuf = new byte[headerAllocation + totalSize];
int outOff = headerAllocation;
if (m_useExplicitIV)
{
// Technically the explicit IV will be the encryption of this nonce
byte[] explicitIV = m_cryptoParams.NonceGenerator.GenerateNonce(blockSize);
Array.Copy(explicitIV, 0, outBuf, outOff, blockSize);
outOff += blockSize;
}
plaintext.CopyTo(outBuf.AsSpan(outOff));
outOff += plaintext.Length;
if (!m_encryptThenMac)
{
byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, plaintext);
mac.CopyTo(outBuf.AsSpan(outOff));
outOff += mac.Length;
}
byte padByte = (byte)(padding_length - 1);
for (int i = 0; i < padding_length; ++i)
{
outBuf[outOff++] = padByte;
}
m_encryptCipher.DoFinal(outBuf, headerAllocation, outOff - headerAllocation, outBuf, headerAllocation);
if (m_encryptThenMac)
{
byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, outBuf, headerAllocation,
outOff - headerAllocation);
Array.Copy(mac, 0, outBuf, outOff, mac.Length);
outOff += mac.Length;
}
if (outOff != outBuf.Length)
throw new TlsFatalAlert(AlertDescription.internal_error);
return new TlsEncodeResult(outBuf, 0, outBuf.Length, contentType);
}
#endif
public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion,
byte[] ciphertext, int offset, int len)
{
int blockSize = m_decryptCipher.GetBlockSize();
int macSize = m_readMac.Size;
int minLen = blockSize;
if (m_encryptThenMac)
{
minLen += macSize;
}
else
{
minLen = System.Math.Max(minLen, macSize + 1);
}
if (m_useExplicitIV)
{
minLen += blockSize;
}
if (len < minLen)
throw new TlsFatalAlert(AlertDescription.decode_error);
int blocks_length = len;
if (m_encryptThenMac)
{
blocks_length -= macSize;
}
if (blocks_length % blockSize != 0)
throw new TlsFatalAlert(AlertDescription.decryption_failed);
if (m_encryptThenMac)
{
byte[] expectedMac = m_readMac.CalculateMac(seqNo, recordType, ciphertext, offset, len - macSize);
bool checkMac = TlsUtilities.ConstantTimeAreEqual(macSize, expectedMac, 0, ciphertext,
offset + len - macSize);
if (!checkMac)
{
/*
* RFC 7366 3. The MAC SHALL be evaluated before any further processing such as
* decryption is performed, and if the MAC verification fails, then processing SHALL
* terminate immediately. For TLS, a fatal bad_record_mac MUST be generated [2]. For
* DTLS, the record MUST be discarded, and a fatal bad_record_mac MAY be generated
* [4]. This immediate response to a bad MAC eliminates any timing channels that may
* be available through the use of manipulated packet data.
*/
throw new TlsFatalAlert(AlertDescription.bad_record_mac);
}
}
m_decryptCipher.DoFinal(ciphertext, offset, blocks_length, ciphertext, offset);
if (m_useExplicitIV)
{
offset += blockSize;
blocks_length -= blockSize;
}
// If there's anything wrong with the padding, this will return zero
int totalPad = CheckPaddingConstantTime(ciphertext, offset, blocks_length, blockSize,
m_encryptThenMac ? 0 : macSize);
bool badMac = (totalPad == 0);
int dec_output_length = blocks_length - totalPad;
if (!m_encryptThenMac)
{
dec_output_length -= macSize;
byte[] expectedMac = m_readMac.CalculateMacConstantTime(seqNo, recordType, ciphertext, offset,
dec_output_length, blocks_length - macSize, m_randomData);
badMac |= !TlsUtilities.ConstantTimeAreEqual(macSize, expectedMac, 0, ciphertext,
offset + dec_output_length);
}
if (badMac)
throw new TlsFatalAlert(AlertDescription.bad_record_mac);
return new TlsDecodeResult(ciphertext, offset, dec_output_length, recordType);
}
public virtual void RekeyDecoder()
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
public virtual void RekeyEncoder()
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
public virtual bool UsesOpaqueRecordType
{
get { return false; }
}
protected virtual int CheckPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize)
{
int end = off + len;
byte lastByte = buf[end - 1];
int padlen = lastByte & 0xff;
int totalPad = padlen + 1;
int dummyIndex = 0;
byte padDiff = 0;
int totalPadLimit = System.Math.Min(m_acceptExtraPadding ? 256 : blockSize, len - macSize);
if (totalPad > totalPadLimit)
{
totalPad = 0;
}
else
{
int padPos = end - totalPad;
do
{
padDiff |= (byte)(buf[padPos++] ^ lastByte);
}
while (padPos < end);
dummyIndex = totalPad;
if (padDiff != 0)
{
totalPad = 0;
}
}
// Run some extra dummy checks so the number of checks is always constant
{
byte[] dummyPad = m_randomData;
while (dummyIndex < 256)
{
padDiff |= (byte)(dummyPad[dummyIndex++] ^ lastByte);
}
// Ensure the above loop is not eliminated
dummyPad[0] ^= padDiff;
}
return totalPad;
}
protected virtual int ChooseExtraPadBlocks(int max)
{
byte[] random = m_cryptoParams.NonceGenerator.GenerateNonce(4);
int x = (int)Pack.LE_To_UInt32(random, 0);
int n = Integers.NumberOfTrailingZeros(x);
return System.Math.Min(n, max);
}
protected virtual int GetCiphertextLength(int blockSize, int macSize, int maxPadding, int plaintextLength)
{
int ciphertextLength = plaintextLength;
// An explicit IV consumes 1 block
if (m_useExplicitIV)
{
ciphertextLength += blockSize;
}
// Leave room for the MAC and (block-aligning) padding
ciphertextLength += maxPadding;
if (m_encryptThenMac)
{
ciphertextLength -= (ciphertextLength % blockSize);
ciphertextLength += macSize;
}
else
{
ciphertextLength += macSize;
ciphertextLength -= (ciphertextLength % blockSize);
}
return ciphertextLength;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a85161e5ba712cb4883536de2b0fce4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>Interface for block cipher services.</summary>
public interface TlsBlockCipherImpl
{
/// <summary>Set the key to be used by the block cipher implementation supporting this service.</summary>
/// <param name="key">array holding the block cipher key.</param>
/// <param name="keyOff">offset into the array the key starts at.</param>
/// <param name="keyLen">length of the key in the array.</param>
/// <exception cref="IOException"/>
void SetKey(byte[] key, int keyOff, int keyLen);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
void SetKey(ReadOnlySpan<byte> key);
#endif
/// <summary>Initialise the parameters for operator.</summary>
/// <param name="iv">array holding the initialization vector (IV).</param>
/// <param name="ivOff">offset into the array the IV starts at.</param>
/// <param name="ivLen">length of the IV in the array.</param>
/// <exception cref="IOException">if the parameters are inappropriate.</exception>
void Init(byte[] iv, int ivOff, int ivLen);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
void Init(ReadOnlySpan<byte> iv);
#endif
/// <summary>Perform the cipher encryption/decryption returning the output in output.</summary>
/// <remarks>
/// Note: we have to use DoFinal() here as it is the only way to guarantee output from the underlying cipher.
/// </remarks>
/// <param name="input">array holding input data to the cipher.</param>
/// <param name="inputOffset">offset into input array data starts at.</param>
/// <param name="inputLength">length of the input data in the array.</param>
/// <param name="output">array to hold the cipher output.</param>
/// <param name="outputOffset">offset into output array to start saving output.</param>
/// <returns>the amount of data written to output.</returns>
/// <exception cref="IOException">in case of failure.</exception>
int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset);
/// <summary>Return the blocksize (in bytes) of the underlying block cipher.</summary>
/// <returns>the cipher's blocksize.</returns>
int GetBlockSize();
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c9525369b45ed6042817ffbc5e90e0cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>Useful utility methods.</summary>
public abstract class TlsImplUtilities
{
public static bool IsSsl(TlsCryptoParameters cryptoParams)
{
return cryptoParams.ServerVersion.IsSsl;
}
public static bool IsTlsV10(ProtocolVersion version)
{
return ProtocolVersion.TLSv10.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion());
}
public static bool IsTlsV10(TlsCryptoParameters cryptoParams)
{
return IsTlsV10(cryptoParams.ServerVersion);
}
public static bool IsTlsV11(ProtocolVersion version)
{
return ProtocolVersion.TLSv11.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion());
}
public static bool IsTlsV11(TlsCryptoParameters cryptoParams)
{
return IsTlsV11(cryptoParams.ServerVersion);
}
public static bool IsTlsV12(ProtocolVersion version)
{
return ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion());
}
public static bool IsTlsV12(TlsCryptoParameters cryptoParams)
{
return IsTlsV12(cryptoParams.ServerVersion);
}
public static bool IsTlsV13(ProtocolVersion version)
{
return ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion());
}
public static bool IsTlsV13(TlsCryptoParameters cryptoParams)
{
return IsTlsV13(cryptoParams.ServerVersion);
}
public static byte[] CalculateKeyBlock(TlsCryptoParameters cryptoParams, int length)
{
SecurityParameters securityParameters = cryptoParams.SecurityParameters;
TlsSecret master_secret = securityParameters.MasterSecret;
int prfAlgorithm = securityParameters.PrfAlgorithm;
byte[] seed = Arrays.Concatenate(securityParameters.ServerRandom, securityParameters.ClientRandom);
return master_secret.DeriveUsingPrf(prfAlgorithm, ExporterLabel.key_expansion, seed, length).Extract();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public static void CalculateKeyBlock(TlsCryptoParameters cryptoParams, Span<byte> keyBlock)
{
SecurityParameters securityParameters = cryptoParams.SecurityParameters;
TlsSecret master_secret = securityParameters.MasterSecret;
int prfAlgorithm = securityParameters.PrfAlgorithm;
Span<byte> cr = securityParameters.ClientRandom, sr = securityParameters.ServerRandom;
Span<byte> seed = stackalloc byte[sr.Length + cr.Length];
sr.CopyTo(seed);
cr.CopyTo(seed[sr.Length..]);
TlsSecret derived = master_secret.DeriveUsingPrf(prfAlgorithm, ExporterLabel.key_expansion, seed,
keyBlock.Length);
derived.ExtractTo(keyBlock);
}
#endif
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 87bfbb1614880a14989169d07561dd32
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,133 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>The NULL cipher.</summary>
public class TlsNullCipher
: TlsCipher
{
protected readonly TlsCryptoParameters m_cryptoParams;
protected readonly TlsSuiteHmac m_readMac, m_writeMac;
/// <exception cref="IOException"/>
public TlsNullCipher(TlsCryptoParameters cryptoParams, TlsHmac clientMac, TlsHmac serverMac)
{
if (TlsImplUtilities.IsTlsV13(cryptoParams))
throw new TlsFatalAlert(AlertDescription.internal_error);
m_cryptoParams = cryptoParams;
int keyBlockSize = clientMac.MacLength + serverMac.MacLength;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> keyBlock = keyBlockSize <= 512
? stackalloc byte[keyBlockSize]
: new byte[keyBlockSize];
TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlock);
clientMac.SetKey(keyBlock[..clientMac.MacLength]); keyBlock = keyBlock[clientMac.MacLength..];
serverMac.SetKey(keyBlock[..serverMac.MacLength]); keyBlock = keyBlock[serverMac.MacLength..];
if (!keyBlock.IsEmpty)
throw new TlsFatalAlert(AlertDescription.internal_error);
#else
byte[] keyBlock = TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlockSize);
int pos = 0;
clientMac.SetKey(keyBlock, pos, clientMac.MacLength);
pos += clientMac.MacLength;
serverMac.SetKey(keyBlock, pos, serverMac.MacLength);
pos += serverMac.MacLength;
if (pos != keyBlockSize)
throw new TlsFatalAlert(AlertDescription.internal_error);
#endif
if (cryptoParams.IsServer)
{
this.m_writeMac = new TlsSuiteHmac(cryptoParams, serverMac);
this.m_readMac = new TlsSuiteHmac(cryptoParams, clientMac);
}
else
{
this.m_writeMac = new TlsSuiteHmac(cryptoParams, clientMac);
this.m_readMac = new TlsSuiteHmac(cryptoParams, serverMac);
}
}
public virtual int GetCiphertextDecodeLimit(int plaintextLimit)
{
return plaintextLimit + m_writeMac.Size;
}
public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit)
{
return plaintextLength + m_writeMac.Size;
}
public virtual int GetPlaintextLimit(int ciphertextLimit)
{
return ciphertextLimit - m_writeMac.Size;
}
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion,
int headerAllocation, byte[] plaintext, int offset, int len)
{
byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, plaintext, offset, len);
byte[] ciphertext = new byte[headerAllocation + len + mac.Length];
Array.Copy(plaintext, offset, ciphertext, headerAllocation, len);
Array.Copy(mac, 0, ciphertext, headerAllocation + len, mac.Length);
return new TlsEncodeResult(ciphertext, 0, ciphertext.Length, contentType);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion,
int headerAllocation, ReadOnlySpan<byte> plaintext)
{
byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, plaintext);
byte[] ciphertext = new byte[headerAllocation + plaintext.Length + mac.Length];
plaintext.CopyTo(ciphertext.AsSpan(headerAllocation));
mac.CopyTo(ciphertext.AsSpan(headerAllocation + plaintext.Length));
return new TlsEncodeResult(ciphertext, 0, ciphertext.Length, contentType);
}
#endif
public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion,
byte[] ciphertext, int offset, int len)
{
int macSize = m_readMac.Size;
if (len < macSize)
throw new TlsFatalAlert(AlertDescription.decode_error);
int macInputLen = len - macSize;
byte[] expectedMac = m_readMac.CalculateMac(seqNo, recordType, ciphertext, offset, macInputLen);
bool badMac = !TlsUtilities.ConstantTimeAreEqual(macSize, expectedMac, 0, ciphertext, offset + macInputLen);
if (badMac)
throw new TlsFatalAlert(AlertDescription.bad_record_mac);
return new TlsDecodeResult(ciphertext, offset, macInputLen, recordType);
}
public virtual void RekeyDecoder()
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
public virtual void RekeyEncoder()
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
public virtual bool UsesOpaqueRecordType
{
get { return false; }
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4997ddc18edf0d749b1c186f7fc1bbf8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest.</summary>
public class TlsSuiteHmac
: TlsSuiteMac
{
protected static int GetMacSize(TlsCryptoParameters cryptoParams, TlsMac mac)
{
int macSize = mac.MacLength;
if (cryptoParams.SecurityParameters.IsTruncatedHmac)
{
macSize = System.Math.Min(macSize, 10);
}
return macSize;
}
protected readonly TlsCryptoParameters m_cryptoParams;
protected readonly TlsHmac m_mac;
protected readonly int m_digestBlockSize;
protected readonly int m_digestOverhead;
protected readonly int m_macSize;
/// <summary>Generate a new instance of a TlsMac.</summary>
/// <param name="cryptoParams">the TLS client context specific crypto parameters.</param>
/// <param name="mac">The MAC to use.</param>
public TlsSuiteHmac(TlsCryptoParameters cryptoParams, TlsHmac mac)
{
this.m_cryptoParams = cryptoParams;
this.m_mac = mac;
this.m_macSize = GetMacSize(cryptoParams, mac);
this.m_digestBlockSize = mac.InternalBlockSize;
// TODO This should check the actual algorithm, not assume based on the digest size
if (TlsImplUtilities.IsSsl(cryptoParams) && mac.MacLength == 20)
{
/*
* NOTE: For the SSL 3.0 MAC with SHA-1, the secret + input pad is not block-aligned.
*/
this.m_digestOverhead = 4;
}
else
{
this.m_digestOverhead = m_digestBlockSize / 8;
}
}
public virtual int Size
{
get { return m_macSize; }
}
public virtual byte[] CalculateMac(long seqNo, short type, byte[] msg, int msgOff, int msgLen)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return CalculateMac(seqNo, type, msg.AsSpan(msgOff, msgLen));
#else
ProtocolVersion serverVersion = m_cryptoParams.ServerVersion;
bool isSsl = serverVersion.IsSsl;
byte[] macHeader = new byte[isSsl ? 11 : 13];
TlsUtilities.WriteUint64(seqNo, macHeader, 0);
TlsUtilities.WriteUint8(type, macHeader, 8);
if (!isSsl)
{
TlsUtilities.WriteVersion(serverVersion, macHeader, 9);
}
TlsUtilities.WriteUint16(msgLen, macHeader, macHeader.Length - 2);
m_mac.Update(macHeader, 0, macHeader.Length);
m_mac.Update(msg, msgOff, msgLen);
return Truncate(m_mac.CalculateMac());
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual byte[] CalculateMac(long seqNo, short type, ReadOnlySpan<byte> message)
{
ProtocolVersion serverVersion = m_cryptoParams.ServerVersion;
bool isSsl = serverVersion.IsSsl;
byte[] macHeader = new byte[isSsl ? 11 : 13];
TlsUtilities.WriteUint64(seqNo, macHeader, 0);
TlsUtilities.WriteUint8(type, macHeader, 8);
if (!isSsl)
{
TlsUtilities.WriteVersion(serverVersion, macHeader, 9);
}
TlsUtilities.WriteUint16(message.Length, macHeader, macHeader.Length - 2);
m_mac.Update(macHeader);
m_mac.Update(message);
return Truncate(m_mac.CalculateMac());
}
#endif
public virtual byte[] CalculateMacConstantTime(long seqNo, short type, byte[] msg, int msgOff, int msgLen,
int fullLength, byte[] dummyData)
{
/*
* Actual MAC only calculated on 'length' bytes...
*/
byte[] result = CalculateMac(seqNo, type, msg, msgOff, msgLen);
/*
* ...but ensure a constant number of complete digest blocks are processed (as many as would
* be needed for 'fullLength' bytes of input).
*/
int headerLength = TlsImplUtilities.IsSsl(m_cryptoParams) ? 11 : 13;
// How many extra full blocks do we need to calculate?
int extra = GetDigestBlockCount(headerLength + fullLength) - GetDigestBlockCount(headerLength + msgLen);
while (--extra >= 0)
{
m_mac.Update(dummyData, 0, m_digestBlockSize);
}
// One more byte in case the implementation is "lazy" about processing blocks
m_mac.Update(dummyData, 0, 1);
m_mac.Reset();
return result;
}
protected virtual int GetDigestBlockCount(int inputLength)
{
// NOTE: The input pad for HMAC is always a full digest block
// NOTE: This calculation assumes a minimum of 1 pad byte
return (inputLength + m_digestOverhead) / m_digestBlockSize;
}
protected virtual byte[] Truncate(byte[] bs)
{
if (bs.Length <= m_macSize)
return bs;
return Arrays.CopyOf(bs, m_macSize);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 842fbe759a5c520499b0ae24cc9a7b8d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
{
/// <summary>Base interface for a generic TLS MAC implementation for use with a bulk cipher.</summary>
public interface TlsSuiteMac
{
/// <summary>Return the output length (in bytes) of this MAC.</summary>
/// <returns>The output length of this MAC.</returns>
int Size { get; }
/// <summary>Calculate the MAC for some given data.</summary>
/// <param name="seqNo">The sequence number of the record.</param>
/// <param name="type">The content type of the message.</param>
/// <param name="message">A byte array containing the message.</param>
/// <param name="offset">The number of bytes to skip, before the message starts.</param>
/// <param name="length">The length of the message.</param>
/// <returns>A new byte array containing the MAC value.</returns>
byte[] CalculateMac(long seqNo, short type, byte[] message, int offset, int length);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
byte[] CalculateMac(long seqNo, short type, ReadOnlySpan<byte> message);
#endif
/// <summary>Constant time calculation of the MAC for some given data with a given expected length.</summary>
/// <param name="seqNo">The sequence number of the record.</param>
/// <param name="type">The content type of the message.</param>
/// <param name="message">A byte array containing the message.</param>
/// <param name="offset">The number of bytes to skip, before the message starts.</param>
/// <param name="length">The length of the message.</param>
/// <param name="expectedLength">The expected length of the full message.</param>
/// <param name="randomData">Random data for padding out the MAC calculation if required.</param>
/// <returns>A new byte array containing the MAC value.</returns>
byte[] CalculateMacConstantTime(long seqNo, short type, byte[] message, int offset, int length,
int expectedLength, byte[] randomData);
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be9f7fb1fa73d6c499fe6eed529ccca3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9337994829923a8419cb2808e470fcbc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,149 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
public sealed class BcChaCha20Poly1305
: TlsAeadCipherImpl
{
private static readonly byte[] Zeroes = new byte[15];
private readonly ChaCha7539Engine m_cipher = new ChaCha7539Engine();
private readonly Poly1305 m_mac = new Poly1305();
private readonly bool m_isEncrypting;
private int m_additionalDataLength;
public BcChaCha20Poly1305(bool isEncrypting)
{
this.m_isEncrypting = isEncrypting;
}
public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)
{
if (m_isEncrypting)
{
int ciphertextLength = inputLength;
m_cipher.DoFinal(input, inputOffset, inputLength, output, outputOffset);
int outputLength = inputLength;
if (ciphertextLength != outputLength)
throw new InvalidOperationException();
UpdateMac(output, outputOffset, ciphertextLength);
byte[] lengths = new byte[16];
Pack.UInt64_To_LE((ulong)m_additionalDataLength, lengths, 0);
Pack.UInt64_To_LE((ulong)ciphertextLength, lengths, 8);
m_mac.BlockUpdate(lengths, 0, 16);
m_mac.DoFinal(output, outputOffset + ciphertextLength);
return ciphertextLength + 16;
}
else
{
int ciphertextLength = inputLength - 16;
UpdateMac(input, inputOffset, ciphertextLength);
byte[] expectedMac = new byte[16];
Pack.UInt64_To_LE((ulong)m_additionalDataLength, expectedMac, 0);
Pack.UInt64_To_LE((ulong)ciphertextLength, expectedMac, 8);
m_mac.BlockUpdate(expectedMac, 0, 16);
m_mac.DoFinal(expectedMac, 0);
bool badMac = !TlsUtilities.ConstantTimeAreEqual(16, expectedMac, 0, input, inputOffset + ciphertextLength);
if (badMac)
throw new TlsFatalAlert(AlertDescription.bad_record_mac);
m_cipher.DoFinal(input, inputOffset, ciphertextLength, output, outputOffset);
int outputLength = ciphertextLength;
if (ciphertextLength != outputLength)
throw new InvalidOperationException();
return ciphertextLength;
}
}
public int GetOutputSize(int inputLength)
{
return m_isEncrypting ? inputLength + 16 : inputLength - 16;
}
public void Init(byte[] nonce, int macSize, byte[] additionalData)
{
if (nonce == null || nonce.Length != 12 || macSize != 16)
throw new TlsFatalAlert(AlertDescription.internal_error);
m_cipher.Init(m_isEncrypting, new ParametersWithIV(null, nonce));
InitMac();
if (additionalData == null)
{
this.m_additionalDataLength = 0;
}
else
{
this.m_additionalDataLength = additionalData.Length;
UpdateMac(additionalData, 0, additionalData.Length);
}
}
public void Reset()
{
m_cipher.Reset();
m_mac.Reset();
}
public void SetKey(byte[] key, int keyOff, int keyLen)
{
KeyParameter cipherKey = new KeyParameter(key, keyOff, keyLen);
m_cipher.Init(m_isEncrypting, new ParametersWithIV(cipherKey, Zeroes, 0, 12));
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void SetKey(ReadOnlySpan<byte> key)
{
KeyParameter cipherKey = new KeyParameter(key);
m_cipher.Init(m_isEncrypting, new ParametersWithIV(cipherKey, Zeroes.AsSpan(0, 12)));
}
#endif
private void InitMac()
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> firstBlock = stackalloc byte[64];
m_cipher.ProcessBytes(firstBlock, firstBlock);
m_mac.Init(new KeyParameter(firstBlock[..32]));
firstBlock.Fill(0x00);
#else
byte[] firstBlock = new byte[64];
m_cipher.ProcessBytes(firstBlock, 0, 64, firstBlock, 0);
m_mac.Init(new KeyParameter(firstBlock, 0, 32));
Array.Clear(firstBlock, 0, firstBlock.Length);
#endif
}
private void UpdateMac(byte[] buf, int off, int len)
{
m_mac.BlockUpdate(buf, off, len);
int partial = len % 16;
if (partial != 0)
{
m_mac.BlockUpdate(Zeroes, 0, 16 - partial);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a547c44455703b94e8a66138181bac45
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,116 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summay>Credentialed class generating agreed secrets from a peer's public key for our end of the TLS connection
/// using the BC light-weight API.</summay>
public class BcDefaultTlsCredentialedAgreement
: TlsCredentialedAgreement
{
protected readonly TlsCredentialedAgreement m_agreementCredentials;
public BcDefaultTlsCredentialedAgreement(BcTlsCrypto crypto, Certificate certificate,
AsymmetricKeyParameter privateKey)
{
if (crypto == null)
throw new ArgumentNullException("crypto");
if (certificate == null)
throw new ArgumentNullException("certificate");
if (certificate.IsEmpty)
throw new ArgumentException("cannot be empty", "certificate");
if (privateKey == null)
throw new ArgumentNullException("privateKey");
if (!privateKey.IsPrivate)
throw new ArgumentException("must be private", "privateKey");
if (privateKey is DHPrivateKeyParameters)
{
this.m_agreementCredentials = new DHCredentialedAgreement(crypto, certificate,
(DHPrivateKeyParameters)privateKey);
}
else if (privateKey is ECPrivateKeyParameters)
{
this.m_agreementCredentials = new ECCredentialedAgreement(crypto, certificate,
(ECPrivateKeyParameters)privateKey);
}
else
{
throw new ArgumentException("'privateKey' type not supported: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(privateKey));
}
}
public virtual Certificate Certificate
{
get { return m_agreementCredentials.Certificate; }
}
public virtual TlsSecret GenerateAgreement(TlsCertificate peerCertificate)
{
return m_agreementCredentials.GenerateAgreement(peerCertificate);
}
private sealed class DHCredentialedAgreement
: TlsCredentialedAgreement
{
private readonly BcTlsCrypto m_crypto;
private readonly Certificate m_certificate;
private readonly DHPrivateKeyParameters m_privateKey;
internal DHCredentialedAgreement(BcTlsCrypto crypto, Certificate certificate,
DHPrivateKeyParameters privateKey)
{
this.m_crypto = crypto;
this.m_certificate = certificate;
this.m_privateKey = privateKey;
}
public TlsSecret GenerateAgreement(TlsCertificate peerCertificate)
{
BcTlsCertificate bcCert = BcTlsCertificate.Convert(m_crypto, peerCertificate);
DHPublicKeyParameters peerPublicKey = bcCert.GetPubKeyDH();
return BcTlsDHDomain.CalculateDHAgreement(m_crypto, m_privateKey, peerPublicKey, false);
}
public Certificate Certificate
{
get { return m_certificate; }
}
}
private sealed class ECCredentialedAgreement
: TlsCredentialedAgreement
{
private readonly BcTlsCrypto m_crypto;
private readonly Certificate m_certificate;
private readonly ECPrivateKeyParameters m_privateKey;
internal ECCredentialedAgreement(BcTlsCrypto crypto, Certificate certificate,
ECPrivateKeyParameters privateKey)
{
this.m_crypto = crypto;
this.m_certificate = certificate;
this.m_privateKey = privateKey;
}
public TlsSecret GenerateAgreement(TlsCertificate peerCertificate)
{
BcTlsCertificate bcCert = BcTlsCertificate.Convert(m_crypto, peerCertificate);
ECPublicKeyParameters peerPublicKey = bcCert.GetPubKeyEC();
return BcTlsECDomain.CalculateECDHAgreement(m_crypto, m_privateKey, peerPublicKey);
}
public Certificate Certificate
{
get { return m_certificate; }
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 84303c0f198bc434b870377ae76edfec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,143 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Encodings;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Credentialed class decrypting RSA encrypted secrets sent from a peer for our end of the TLS connection
/// using the BC light-weight API.</summary>
public class BcDefaultTlsCredentialedDecryptor
: TlsCredentialedDecryptor
{
protected readonly BcTlsCrypto m_crypto;
protected readonly Certificate m_certificate;
protected readonly AsymmetricKeyParameter m_privateKey;
public BcDefaultTlsCredentialedDecryptor(BcTlsCrypto crypto, Certificate certificate,
AsymmetricKeyParameter privateKey)
{
if (crypto == null)
throw new ArgumentNullException("crypto");
if (certificate == null)
throw new ArgumentNullException("certificate");
if (certificate.IsEmpty)
throw new ArgumentException("cannot be empty", "certificate");
if (privateKey == null)
throw new ArgumentNullException("privateKey");
if (!privateKey.IsPrivate)
throw new ArgumentException("must be private", "privateKey");
if (privateKey is RsaKeyParameters)
{
}
else
{
throw new ArgumentException("'privateKey' type not supported: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(privateKey));
}
this.m_crypto = crypto;
this.m_certificate = certificate;
this.m_privateKey = privateKey;
}
public virtual Certificate Certificate
{
get { return m_certificate; }
}
public virtual TlsSecret Decrypt(TlsCryptoParameters cryptoParams, byte[] ciphertext)
{
// TODO Keep only the decryption itself here - move error handling outside
return SafeDecryptPreMasterSecret(cryptoParams, (RsaKeyParameters)m_privateKey, ciphertext);
}
/*
* TODO[tls-ops] Probably need to make RSA encryption/decryption into TlsCrypto functions so
* that users can implement "generic" encryption credentials externally
*/
protected virtual TlsSecret SafeDecryptPreMasterSecret(TlsCryptoParameters cryptoParams,
RsaKeyParameters rsaServerPrivateKey, byte[] encryptedPreMasterSecret)
{
SecureRandom secureRandom = m_crypto.SecureRandom;
/*
* RFC 5246 7.4.7.1.
*/
ProtocolVersion expectedVersion = cryptoParams.RsaPreMasterSecretVersion;
// TODO Provide as configuration option?
bool versionNumberCheckDisabled = false;
/*
* Generate 48 random bytes we can use as a Pre-Master-Secret, if the
* PKCS1 padding check should fail.
*/
byte[] fallback = new byte[48];
secureRandom.NextBytes(fallback);
byte[] M = Arrays.Clone(fallback);
try
{
Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine(), fallback);
encoding.Init(false, new ParametersWithRandom(rsaServerPrivateKey, secureRandom));
M = encoding.ProcessBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.Length);
}
catch (Exception)
{
/*
* This should never happen since the decryption should never throw an exception
* and return a random value instead.
*
* In any case, a TLS server MUST NOT generate an alert if processing an
* RSA-encrypted premaster secret message fails, or the version number is not as
* expected. Instead, it MUST continue the handshake with a randomly generated
* premaster secret.
*/
}
/*
* If ClientHello.legacy_version is TLS 1.1 or higher, server implementations MUST check the
* version number [..].
*/
if (versionNumberCheckDisabled && !TlsImplUtilities.IsTlsV11(expectedVersion))
{
/*
* If the version number is TLS 1.0 or earlier, server implementations SHOULD check the
* version number, but MAY have a configuration option to disable the check.
*/
}
else
{
/*
* Compare the version number in the decrypted Pre-Master-Secret with the legacy_version
* field from the ClientHello. If they don't match, continue the handshake with the
* randomly generated 'fallback' value.
*
* NOTE: The comparison and replacement must be constant-time.
*/
int mask = (expectedVersion.MajorVersion ^ (M[0] & 0xFF))
| (expectedVersion.MinorVersion ^ (M[1] & 0xFF));
// 'mask' will be all 1s if the versions matched, or else all 0s.
mask = (mask - 1) >> 31;
for (int i = 0; i < 48; i++)
{
M[i] = (byte)((M[i] & mask) | (fallback[i] & ~mask));
}
}
return m_crypto.CreateSecret(M);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8e593abd1a2506c4d9e25120fce65765
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,89 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Credentialed class for generating signatures based on the use of primitives from the BC light-weight API.</summary>
public class BcDefaultTlsCredentialedSigner
: DefaultTlsCredentialedSigner
{
private static BcTlsCertificate GetEndEntity(BcTlsCrypto crypto, Certificate certificate)
{
if (certificate == null || certificate.IsEmpty)
throw new ArgumentException("No certificate");
return BcTlsCertificate.Convert(crypto, certificate.GetCertificateAt(0));
}
private static TlsSigner MakeSigner(BcTlsCrypto crypto, AsymmetricKeyParameter privateKey,
Certificate certificate, SignatureAndHashAlgorithm signatureAndHashAlgorithm)
{
TlsSigner signer;
if (privateKey is RsaKeyParameters)
{
RsaKeyParameters privKeyRsa = (RsaKeyParameters)privateKey;
if (signatureAndHashAlgorithm != null)
{
int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm);
if (SignatureScheme.IsRsaPss(signatureScheme))
{
return new BcTlsRsaPssSigner(crypto, privKeyRsa, signatureScheme);
}
}
RsaKeyParameters pubKeyRsa = GetEndEntity(crypto, certificate).GetPubKeyRsa();
signer = new BcTlsRsaSigner(crypto, privKeyRsa, pubKeyRsa);
}
else if (privateKey is DsaPrivateKeyParameters)
{
signer = new BcTlsDsaSigner(crypto, (DsaPrivateKeyParameters)privateKey);
}
else if (privateKey is ECPrivateKeyParameters)
{
ECPrivateKeyParameters privKeyEC = (ECPrivateKeyParameters)privateKey;
if (signatureAndHashAlgorithm != null)
{
int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm);
if (SignatureScheme.IsECDsa(signatureScheme))
{
return new BcTlsECDsa13Signer(crypto, privKeyEC, signatureScheme);
}
}
signer = new BcTlsECDsaSigner(crypto, privKeyEC);
}
else if (privateKey is Ed25519PrivateKeyParameters)
{
signer = new BcTlsEd25519Signer(crypto, (Ed25519PrivateKeyParameters)privateKey);
}
else if (privateKey is Ed448PrivateKeyParameters)
{
signer = new BcTlsEd448Signer(crypto, (Ed448PrivateKeyParameters)privateKey);
}
else
{
throw new ArgumentException("'privateKey' type not supported: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(privateKey));
}
return signer;
}
public BcDefaultTlsCredentialedSigner(TlsCryptoParameters cryptoParams, BcTlsCrypto crypto,
AsymmetricKeyParameter privateKey, Certificate certificate,
SignatureAndHashAlgorithm signatureAndHashAlgorithm)
: base(cryptoParams, MakeSigner(crypto, privateKey, certificate, signatureAndHashAlgorithm), certificate,
signatureAndHashAlgorithm)
{
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e58111d54937dc94f843131c59731115
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,133 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>HMAC implementation based on original internet draft for HMAC (RFC 2104).</summary>
/// <remarks>
/// The difference is that padding is concatenated versus XORed with the key, e.g:
/// <code>H(K + opad, H(K + ipad, text))</code>
/// </remarks>
internal class BcSsl3Hmac
: TlsHmac
{
private const byte IPAD_BYTE = (byte)0x36;
private const byte OPAD_BYTE = (byte)0x5C;
private static readonly byte[] IPAD = GenPad(IPAD_BYTE, 48);
private static readonly byte[] OPAD = GenPad(OPAD_BYTE, 48);
private readonly IDigest m_digest;
private readonly int m_padLength;
private byte[] m_secret;
/// <summary>Base constructor for one of the standard digest algorithms for which the byteLength is known.
/// </summary>
/// <remarks>
/// Behaviour is undefined for digests other than MD5 or SHA1.
/// </remarks>
/// <param name="digest">the digest.</param>
internal BcSsl3Hmac(IDigest digest)
{
this.m_digest = digest;
if (digest.GetDigestSize() == 20)
{
this.m_padLength = 40;
}
else
{
this.m_padLength = 48;
}
}
public virtual void SetKey(byte[] key, int keyOff, int keyLen)
{
this.m_secret = TlsUtilities.CopyOfRangeExact(key, keyOff, keyOff + keyLen);
Reset();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void SetKey(ReadOnlySpan<byte> key)
{
this.m_secret = key.ToArray();
Reset();
}
#endif
public virtual void Update(byte[] input, int inOff, int len)
{
m_digest.BlockUpdate(input, inOff, len);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void Update(ReadOnlySpan<byte> input)
{
m_digest.BlockUpdate(input);
}
#endif
public virtual byte[] CalculateMac()
{
byte[] result = new byte[m_digest.GetDigestSize()];
DoFinal(result, 0);
return result;
}
public virtual void CalculateMac(byte[] output, int outOff)
{
DoFinal(output, outOff);
}
public virtual int InternalBlockSize
{
get { return m_digest.GetByteLength(); }
}
public virtual int MacLength
{
get { return m_digest.GetDigestSize(); }
}
/**
* Reset the mac generator.
*/
public virtual void Reset()
{
m_digest.Reset();
m_digest.BlockUpdate(m_secret, 0, m_secret.Length);
m_digest.BlockUpdate(IPAD, 0, m_padLength);
}
private void DoFinal(byte[] output, int outOff)
{
byte[] tmp = new byte[m_digest.GetDigestSize()];
m_digest.DoFinal(tmp, 0);
m_digest.BlockUpdate(m_secret, 0, m_secret.Length);
m_digest.BlockUpdate(OPAD, 0, m_padLength);
m_digest.BlockUpdate(tmp, 0, tmp.Length);
m_digest.DoFinal(output, outOff);
Reset();
}
private static byte[] GenPad(byte b, int count)
{
byte[] padding = new byte[count];
Arrays.Fill(padding, b);
return padding;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1cf89108ae984c499e7cf5dba3cbde6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTls13Verifier
: Tls13Verifier
{
private readonly SignerSink m_output;
internal BcTls13Verifier(ISigner verifier)
{
if (verifier == null)
throw new ArgumentNullException("verifier");
this.m_output = new SignerSink(verifier);
}
public Stream Stream
{
get { return m_output; }
}
public bool VerifySignature(byte[] signature)
{
return m_output.Signer.VerifySignature(signature);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4aa938c0bce81eb4dba1f37cc3bb491d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsAeadCipherImpl
: TlsAeadCipherImpl
{
private readonly bool m_isEncrypting;
private readonly IAeadCipher m_cipher;
private KeyParameter key;
internal BcTlsAeadCipherImpl(IAeadCipher cipher, bool isEncrypting)
{
this.m_cipher = cipher;
this.m_isEncrypting = isEncrypting;
}
public void SetKey(byte[] key, int keyOff, int keyLen)
{
this.key = new KeyParameter(key, keyOff, keyLen);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void SetKey(ReadOnlySpan<byte> key)
{
this.key = new KeyParameter(key);
}
#endif
public void Init(byte[] nonce, int macSize, byte[] additionalData)
{
m_cipher.Init(m_isEncrypting, new AeadParameters(key, macSize * 8, nonce, additionalData));
}
public int GetOutputSize(int inputLength)
{
return m_cipher.GetOutputSize(inputLength);
}
public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)
{
int len = m_cipher.ProcessBytes(input, inputOffset, inputLength, output, outputOffset);
try
{
len += m_cipher.DoFinal(output, outputOffset + len);
}
catch (InvalidCipherTextException e)
{
throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
}
return len;
}
public void Reset()
{
m_cipher.Reset();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 445248e82182d894baa56e1df879c8cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsBlockCipherImpl
: TlsBlockCipherImpl
{
private readonly bool m_isEncrypting;
private readonly IBlockCipher m_cipher;
private KeyParameter key;
internal BcTlsBlockCipherImpl(IBlockCipher cipher, bool isEncrypting)
{
this.m_cipher = cipher;
this.m_isEncrypting = isEncrypting;
}
public void SetKey(byte[] key, int keyOff, int keyLen)
{
this.key = new KeyParameter(key, keyOff, keyLen);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void SetKey(ReadOnlySpan<byte> key)
{
this.key = new KeyParameter(key);
}
#endif
public void Init(byte[] iv, int ivOff, int ivLen)
{
m_cipher.Init(m_isEncrypting, new ParametersWithIV(key, iv, ivOff, ivLen));
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void Init(ReadOnlySpan<byte> iv)
{
m_cipher.Init(m_isEncrypting, new ParametersWithIV(key, iv));
}
#endif
public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)
{
int blockSize = m_cipher.GetBlockSize();
for (int i = 0; i < inputLength; i += blockSize)
{
m_cipher.ProcessBlock(input, inputOffset + i, output, outputOffset + i);
}
return inputLength;
}
public int GetBlockSize()
{
return m_cipher.GetBlockSize();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a239f59225989d442bc5c8187707e487
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,101 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Implementation class for a single X.509 certificate based on the BC light-weight API.</summary>
public class BcTlsCertificate
: BcTlsRawKeyCertificate
{
/// <exception cref="IOException"/>
public static BcTlsCertificate Convert(BcTlsCrypto crypto, TlsCertificate certificate)
{
if (certificate is BcTlsCertificate)
return (BcTlsCertificate)certificate;
return new BcTlsCertificate(crypto, certificate.GetEncoded());
}
/// <exception cref="IOException"/>
public static X509CertificateStructure ParseCertificate(byte[] encoding)
{
try
{
Asn1Object asn1 = TlsUtilities.ReadAsn1Object(encoding);
return X509CertificateStructure.GetInstance(asn1);
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.bad_certificate, e);
}
}
protected readonly X509CertificateStructure m_certificate;
/// <exception cref="IOException"/>
public BcTlsCertificate(BcTlsCrypto crypto, byte[] encoding)
: this(crypto, ParseCertificate(encoding))
{
}
public BcTlsCertificate(BcTlsCrypto crypto, X509CertificateStructure certificate)
: base(crypto, certificate.SubjectPublicKeyInfo)
{
m_certificate = certificate;
}
public virtual X509CertificateStructure X509CertificateStructure => m_certificate;
/// <exception cref="IOException"/>
public override byte[] GetEncoded()
{
return m_certificate.GetEncoded(Asn1Encodable.Der);
}
/// <exception cref="IOException"/>
public override byte[] GetExtension(DerObjectIdentifier extensionOid)
{
X509Extensions extensions = m_certificate.TbsCertificate.Extensions;
if (extensions != null)
{
X509Extension extension = extensions.GetExtension(extensionOid);
if (extension != null)
{
return Arrays.Clone(extension.Value.GetOctets());
}
}
return null;
}
public override BigInteger SerialNumber => m_certificate.SerialNumber.Value;
public override string SigAlgOid => m_certificate.SignatureAlgorithm.Algorithm.Id;
public override Asn1Encodable GetSigAlgParams() => m_certificate.SignatureAlgorithm.Parameters;
protected override bool SupportsKeyUsage(int keyUsageBits)
{
X509Extensions exts = m_certificate.TbsCertificate.Extensions;
if (exts != null)
{
KeyUsage ku = KeyUsage.FromExtensions(exts);
if (ku != null)
{
int bits = ku.GetBytes()[0] & 0xff;
if ((bits & keyUsageBits) != keyUsageBits)
return false;
}
}
return true;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f90dea4e64a35bc4cb84ba6c806af5c1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,774 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections.Generic;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/**
* Class for providing cryptographic services for TLS based on implementations in the BC light-weight API.
* <p>
* This class provides default implementations for everything. If you need to customise it, extend the class
* and override the appropriate methods.
* </p>
*/
public class BcTlsCrypto
: AbstractTlsCrypto
{
private readonly SecureRandom m_entropySource;
public BcTlsCrypto()
: this(CryptoServicesRegistrar.GetSecureRandom())
{
}
public BcTlsCrypto(SecureRandom entropySource)
{
if (entropySource == null)
throw new ArgumentNullException(nameof(entropySource));
this.m_entropySource = entropySource;
}
internal virtual BcTlsSecret AdoptLocalSecret(byte[] data)
{
return new BcTlsSecret(this, data);
}
public override SecureRandom SecureRandom
{
get { return m_entropySource; }
}
public override TlsCertificate CreateCertificate(short type, byte[] encoding)
{
switch (type)
{
case CertificateType.X509:
return new BcTlsCertificate(this, encoding);
case CertificateType.RawPublicKey:
return new BcTlsRawKeyCertificate(this, encoding);
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
public override TlsCipher CreateCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm,
int macAlgorithm)
{
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm.AES_128_CBC:
case EncryptionAlgorithm.ARIA_128_CBC:
case EncryptionAlgorithm.CAMELLIA_128_CBC:
case EncryptionAlgorithm.SEED_CBC:
case EncryptionAlgorithm.SM4_CBC:
return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 16, macAlgorithm);
case EncryptionAlgorithm.cls_3DES_EDE_CBC:
return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 24, macAlgorithm);
case EncryptionAlgorithm.AES_256_CBC:
case EncryptionAlgorithm.ARIA_256_CBC:
case EncryptionAlgorithm.CAMELLIA_256_CBC:
return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 32, macAlgorithm);
case EncryptionAlgorithm.AES_128_CCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 16, 16);
case EncryptionAlgorithm.AES_128_CCM_8:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 16, 8);
case EncryptionAlgorithm.AES_128_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Gcm(cryptoParams, 16, 16);
case EncryptionAlgorithm.AES_256_CCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 32, 16);
case EncryptionAlgorithm.AES_256_CCM_8:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 32, 8);
case EncryptionAlgorithm.AES_256_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Gcm(cryptoParams, 32, 16);
case EncryptionAlgorithm.ARIA_128_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aria_Gcm(cryptoParams, 16, 16);
case EncryptionAlgorithm.ARIA_256_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aria_Gcm(cryptoParams, 32, 16);
case EncryptionAlgorithm.CAMELLIA_128_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Camellia_Gcm(cryptoParams, 16, 16);
case EncryptionAlgorithm.CAMELLIA_256_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Camellia_Gcm(cryptoParams, 32, 16);
case EncryptionAlgorithm.CHACHA20_POLY1305:
// NOTE: Ignores macAlgorithm
return CreateChaCha20Poly1305(cryptoParams);
case EncryptionAlgorithm.NULL:
return CreateNullCipher(cryptoParams, macAlgorithm);
case EncryptionAlgorithm.SM4_CCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_SM4_Ccm(cryptoParams);
case EncryptionAlgorithm.SM4_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_SM4_Gcm(cryptoParams);
case EncryptionAlgorithm.DES40_CBC:
case EncryptionAlgorithm.DES_CBC:
case EncryptionAlgorithm.IDEA_CBC:
case EncryptionAlgorithm.RC2_CBC_40:
case EncryptionAlgorithm.RC4_128:
case EncryptionAlgorithm.RC4_40:
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
public override TlsDHDomain CreateDHDomain(TlsDHConfig dhConfig)
{
return new BcTlsDHDomain(this, dhConfig);
}
public override TlsECDomain CreateECDomain(TlsECConfig ecConfig)
{
switch (ecConfig.NamedGroup)
{
case NamedGroup.x25519:
return new BcX25519Domain(this);
case NamedGroup.x448:
return new BcX448Domain(this);
default:
return new BcTlsECDomain(this, ecConfig);
}
}
public override TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return CreateNonceGenerator(Spans.FromNullableReadOnly(additionalSeedMaterial));
#else
int cryptoHashAlgorithm = CryptoHashAlgorithm.sha256;
IDigest digest = CreateDigest(cryptoHashAlgorithm);
int seedLength = TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm);
byte[] seed = new byte[seedLength];
SecureRandom.NextBytes(seed);
DigestRandomGenerator randomGenerator = new DigestRandomGenerator(digest);
randomGenerator.AddSeedMaterial(additionalSeedMaterial);
randomGenerator.AddSeedMaterial(seed);
return new BcTlsNonceGenerator(randomGenerator);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override TlsNonceGenerator CreateNonceGenerator(ReadOnlySpan<byte> additionalSeedMaterial)
{
int cryptoHashAlgorithm = CryptoHashAlgorithm.sha256;
IDigest digest = CreateDigest(cryptoHashAlgorithm);
int seedLength = TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm);
Span<byte> seed = seedLength <= 128
? stackalloc byte[seedLength]
: new byte[seedLength];
SecureRandom.NextBytes(seed);
DigestRandomGenerator randomGenerator = new DigestRandomGenerator(digest);
randomGenerator.AddSeedMaterial(additionalSeedMaterial);
randomGenerator.AddSeedMaterial(seed);
return new BcTlsNonceGenerator(randomGenerator);
}
#endif
public override bool HasAnyStreamVerifiers(IList<SignatureAndHashAlgorithm> signatureAndHashAlgorithms)
{
foreach (SignatureAndHashAlgorithm algorithm in signatureAndHashAlgorithms)
{
switch (SignatureScheme.From(algorithm))
{
case SignatureScheme.ed25519:
case SignatureScheme.ed448:
return true;
}
}
return false;
}
public override bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes)
{
return false;
}
public override bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.md5:
case CryptoHashAlgorithm.sha1:
case CryptoHashAlgorithm.sha224:
case CryptoHashAlgorithm.sha256:
case CryptoHashAlgorithm.sha384:
case CryptoHashAlgorithm.sha512:
case CryptoHashAlgorithm.sm3:
return true;
default:
return false;
}
}
public override bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm)
{
switch (cryptoSignatureAlgorithm)
{
case CryptoSignatureAlgorithm.rsa:
case CryptoSignatureAlgorithm.dsa:
case CryptoSignatureAlgorithm.ecdsa:
case CryptoSignatureAlgorithm.rsa_pss_rsae_sha256:
case CryptoSignatureAlgorithm.rsa_pss_rsae_sha384:
case CryptoSignatureAlgorithm.rsa_pss_rsae_sha512:
case CryptoSignatureAlgorithm.ed25519:
case CryptoSignatureAlgorithm.ed448:
case CryptoSignatureAlgorithm.rsa_pss_pss_sha256:
case CryptoSignatureAlgorithm.rsa_pss_pss_sha384:
case CryptoSignatureAlgorithm.rsa_pss_pss_sha512:
return true;
// TODO[draft-smyshlyaev-tls12-gost-suites-10]
case CryptoSignatureAlgorithm.gostr34102012_256:
case CryptoSignatureAlgorithm.gostr34102012_512:
// TODO[RFC 8998]
case CryptoSignatureAlgorithm.sm2:
default:
return false;
}
}
public override bool HasDHAgreement()
{
return true;
}
public override bool HasECDHAgreement()
{
return true;
}
public override bool HasEncryptionAlgorithm(int encryptionAlgorithm)
{
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm.AES_128_CBC:
case EncryptionAlgorithm.AES_128_CCM:
case EncryptionAlgorithm.AES_128_CCM_8:
case EncryptionAlgorithm.AES_128_GCM:
case EncryptionAlgorithm.AES_256_CBC:
case EncryptionAlgorithm.AES_256_CCM:
case EncryptionAlgorithm.AES_256_CCM_8:
case EncryptionAlgorithm.AES_256_GCM:
case EncryptionAlgorithm.ARIA_128_CBC:
case EncryptionAlgorithm.ARIA_128_GCM:
case EncryptionAlgorithm.ARIA_256_CBC:
case EncryptionAlgorithm.ARIA_256_GCM:
case EncryptionAlgorithm.CAMELLIA_128_CBC:
case EncryptionAlgorithm.CAMELLIA_128_GCM:
case EncryptionAlgorithm.CAMELLIA_256_CBC:
case EncryptionAlgorithm.CAMELLIA_256_GCM:
case EncryptionAlgorithm.CHACHA20_POLY1305:
case EncryptionAlgorithm.cls_3DES_EDE_CBC:
case EncryptionAlgorithm.NULL:
case EncryptionAlgorithm.SEED_CBC:
case EncryptionAlgorithm.SM4_CBC:
case EncryptionAlgorithm.SM4_CCM:
case EncryptionAlgorithm.SM4_GCM:
return true;
case EncryptionAlgorithm.DES_CBC:
case EncryptionAlgorithm.DES40_CBC:
case EncryptionAlgorithm.IDEA_CBC:
case EncryptionAlgorithm.RC2_CBC_40:
case EncryptionAlgorithm.RC4_128:
case EncryptionAlgorithm.RC4_40:
default:
return false;
}
}
public override bool HasHkdfAlgorithm(int cryptoHashAlgorithm)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.sha256:
case CryptoHashAlgorithm.sha384:
case CryptoHashAlgorithm.sha512:
case CryptoHashAlgorithm.sm3:
return true;
default:
return false;
}
}
public override bool HasMacAlgorithm(int macAlgorithm)
{
switch (macAlgorithm)
{
case MacAlgorithm.hmac_md5:
case MacAlgorithm.hmac_sha1:
case MacAlgorithm.hmac_sha256:
case MacAlgorithm.hmac_sha384:
case MacAlgorithm.hmac_sha512:
return true;
default:
return false;
}
}
public override bool HasNamedGroup(int namedGroup)
{
return NamedGroup.RefersToASpecificGroup(namedGroup);
}
public override bool HasRsaEncryption()
{
return true;
}
public override bool HasSignatureAlgorithm(short signatureAlgorithm)
{
switch (signatureAlgorithm)
{
case SignatureAlgorithm.rsa:
case SignatureAlgorithm.dsa:
case SignatureAlgorithm.ecdsa:
case SignatureAlgorithm.ed25519:
case SignatureAlgorithm.ed448:
case SignatureAlgorithm.rsa_pss_rsae_sha256:
case SignatureAlgorithm.rsa_pss_rsae_sha384:
case SignatureAlgorithm.rsa_pss_rsae_sha512:
case SignatureAlgorithm.rsa_pss_pss_sha256:
case SignatureAlgorithm.rsa_pss_pss_sha384:
case SignatureAlgorithm.rsa_pss_pss_sha512:
case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256:
case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384:
case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512:
return true;
// TODO[draft-smyshlyaev-tls12-gost-suites-10]
case SignatureAlgorithm.gostr34102012_256:
case SignatureAlgorithm.gostr34102012_512:
// TODO[RFC 8998]
//case SignatureAlgorithm.sm2:
default:
return false;
}
}
public override bool HasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm)
{
short signature = sigAndHashAlgorithm.Signature;
switch (sigAndHashAlgorithm.Hash)
{
case HashAlgorithm.md5:
return SignatureAlgorithm.rsa == signature && HasSignatureAlgorithm(signature);
default:
return HasSignatureAlgorithm(signature);
}
}
public override bool HasSignatureScheme(int signatureScheme)
{
switch (signatureScheme)
{
case SignatureScheme.sm2sig_sm3:
return false;
default:
{
short signature = SignatureScheme.GetSignatureAlgorithm(signatureScheme);
switch(SignatureScheme.GetCryptoHashAlgorithm(signatureScheme))
{
case CryptoHashAlgorithm.md5:
return SignatureAlgorithm.rsa == signature && HasSignatureAlgorithm(signature);
default:
return HasSignatureAlgorithm(signature);
}
}
}
}
public override bool HasSrpAuthentication()
{
return true;
}
public override TlsSecret CreateSecret(byte[] data)
{
try
{
return AdoptLocalSecret(Arrays.Clone(data));
}
finally
{
// TODO[tls-ops] Add this after checking all callers
//if (data != null)
//{
// Array.Clear(data, 0, data.Length);
//}
}
}
public override TlsSecret GenerateRsaPreMasterSecret(ProtocolVersion version)
{
byte[] data = new byte[48];
SecureRandom.NextBytes(data);
TlsUtilities.WriteVersion(version, data, 0);
return AdoptLocalSecret(data);
}
public virtual IDigest CloneDigest(int cryptoHashAlgorithm, IDigest digest)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.md5:
return new MD5Digest((MD5Digest)digest);
case CryptoHashAlgorithm.sha1:
return new Sha1Digest((Sha1Digest)digest);
case CryptoHashAlgorithm.sha224:
return new Sha224Digest((Sha224Digest)digest);
case CryptoHashAlgorithm.sha256:
return new Sha256Digest((Sha256Digest)digest);
case CryptoHashAlgorithm.sha384:
return new Sha384Digest((Sha384Digest)digest);
case CryptoHashAlgorithm.sha512:
return new Sha512Digest((Sha512Digest)digest);
case CryptoHashAlgorithm.sm3:
return new SM3Digest((SM3Digest)digest);
default:
throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm);
}
}
public virtual IDigest CreateDigest(int cryptoHashAlgorithm)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.md5:
return new MD5Digest();
case CryptoHashAlgorithm.sha1:
return new Sha1Digest();
case CryptoHashAlgorithm.sha224:
return new Sha224Digest();
case CryptoHashAlgorithm.sha256:
return new Sha256Digest();
case CryptoHashAlgorithm.sha384:
return new Sha384Digest();
case CryptoHashAlgorithm.sha512:
return new Sha512Digest();
case CryptoHashAlgorithm.sm3:
return new SM3Digest();
default:
throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm);
}
}
public override TlsHash CreateHash(int cryptoHashAlgorithm)
{
return new BcTlsHash(this, cryptoHashAlgorithm);
}
protected virtual IBlockCipher CreateBlockCipher(int encryptionAlgorithm)
{
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm.cls_3DES_EDE_CBC:
return CreateDesEdeEngine();
case EncryptionAlgorithm.AES_128_CBC:
case EncryptionAlgorithm.AES_256_CBC:
return CreateAesEngine();
case EncryptionAlgorithm.ARIA_128_CBC:
case EncryptionAlgorithm.ARIA_256_CBC:
return CreateAriaEngine();
case EncryptionAlgorithm.CAMELLIA_128_CBC:
case EncryptionAlgorithm.CAMELLIA_256_CBC:
return CreateCamelliaEngine();
case EncryptionAlgorithm.SEED_CBC:
return CreateSeedEngine();
case EncryptionAlgorithm.SM4_CBC:
return CreateSM4Engine();
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
protected virtual IBlockCipher CreateCbcBlockCipher(IBlockCipher blockCipher)
{
return new CbcBlockCipher(blockCipher);
}
protected virtual IBlockCipher CreateCbcBlockCipher(int encryptionAlgorithm)
{
return CreateCbcBlockCipher(CreateBlockCipher(encryptionAlgorithm));
}
protected virtual TlsCipher CreateChaCha20Poly1305(TlsCryptoParameters cryptoParams)
{
BcChaCha20Poly1305 encrypt = new BcChaCha20Poly1305(true);
BcChaCha20Poly1305 decrypt = new BcChaCha20Poly1305(false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 32, 16, TlsAeadCipher.AEAD_CHACHA20_POLY1305);
}
protected virtual TlsAeadCipher CreateCipher_Aes_Ccm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Ccm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Ccm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_CCM);
}
protected virtual TlsAeadCipher CreateCipher_Aes_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsAeadCipher CreateCipher_Aria_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aria_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aria_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsAeadCipher CreateCipher_Camellia_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Camellia_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Camellia_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsCipher CreateCipher_Cbc(TlsCryptoParameters cryptoParams, int encryptionAlgorithm,
int cipherKeySize, int macAlgorithm)
{
BcTlsBlockCipherImpl encrypt = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), true);
BcTlsBlockCipherImpl decrypt = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), false);
TlsHmac clientMac = CreateMac(cryptoParams, macAlgorithm);
TlsHmac serverMac = CreateMac(cryptoParams, macAlgorithm);
return new TlsBlockCipher(cryptoParams, encrypt, decrypt, clientMac, serverMac, cipherKeySize);
}
protected virtual TlsAeadCipher CreateCipher_SM4_Ccm(TlsCryptoParameters cryptoParams)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Ccm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Ccm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 16, 16, TlsAeadCipher.AEAD_CCM);
}
protected virtual TlsAeadCipher CreateCipher_SM4_Gcm(TlsCryptoParameters cryptoParams)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 16, 16, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsNullCipher CreateNullCipher(TlsCryptoParameters cryptoParams, int macAlgorithm)
{
return new TlsNullCipher(cryptoParams, CreateMac(cryptoParams, macAlgorithm),
CreateMac(cryptoParams, macAlgorithm));
}
protected virtual IBlockCipher CreateAesEngine()
{
return AesUtilities.CreateEngine();
}
protected virtual IBlockCipher CreateAriaEngine()
{
return new AriaEngine();
}
protected virtual IBlockCipher CreateCamelliaEngine()
{
return new CamelliaEngine();
}
protected virtual IBlockCipher CreateDesEdeEngine()
{
return new DesEdeEngine();
}
protected virtual IBlockCipher CreateSeedEngine()
{
return new SeedEngine();
}
protected virtual IBlockCipher CreateSM4Engine()
{
return new SM4Engine();
}
protected virtual IAeadCipher CreateCcmMode(IBlockCipher engine)
{
return new CcmBlockCipher(engine);
}
protected virtual IAeadCipher CreateGcmMode(IBlockCipher engine)
{
// TODO Consider allowing custom configuration of multiplier
return new GcmBlockCipher(engine);
}
protected virtual IAeadCipher CreateAeadCipher_Aes_Ccm()
{
return CreateCcmMode(CreateAesEngine());
}
protected virtual IAeadCipher CreateAeadCipher_Aes_Gcm()
{
return CreateGcmMode(CreateAesEngine());
}
protected virtual IAeadCipher CreateAeadCipher_Aria_Gcm()
{
return CreateGcmMode(CreateAriaEngine());
}
protected virtual IAeadCipher CreateAeadCipher_Camellia_Gcm()
{
return CreateGcmMode(CreateCamelliaEngine());
}
protected virtual IAeadCipher CreateAeadCipher_SM4_Ccm()
{
return CreateCcmMode(CreateSM4Engine());
}
protected virtual IAeadCipher CreateAeadCipher_SM4_Gcm()
{
return CreateGcmMode(CreateSM4Engine());
}
public override TlsHmac CreateHmac(int macAlgorithm)
{
switch (macAlgorithm)
{
case MacAlgorithm.hmac_md5:
case MacAlgorithm.hmac_sha1:
case MacAlgorithm.hmac_sha256:
case MacAlgorithm.hmac_sha384:
case MacAlgorithm.hmac_sha512:
return CreateHmacForHash(TlsCryptoUtilities.GetHashForHmac(macAlgorithm));
default:
throw new ArgumentException("invalid MacAlgorithm: " + macAlgorithm);
}
}
public override TlsHmac CreateHmacForHash(int cryptoHashAlgorithm)
{
return new BcTlsHmac(new HMac(CreateDigest(cryptoHashAlgorithm)));
}
protected virtual TlsHmac CreateHmac_Ssl(int macAlgorithm)
{
switch (macAlgorithm)
{
case MacAlgorithm.hmac_md5:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.md5));
case MacAlgorithm.hmac_sha1:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha1));
case MacAlgorithm.hmac_sha256:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha256));
case MacAlgorithm.hmac_sha384:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha384));
case MacAlgorithm.hmac_sha512:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha512));
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
protected virtual TlsHmac CreateMac(TlsCryptoParameters cryptoParams, int macAlgorithm)
{
if (TlsImplUtilities.IsSsl(cryptoParams))
{
return CreateHmac_Ssl(macAlgorithm);
}
else
{
return CreateHmac(macAlgorithm);
}
}
public override TlsSrp6Client CreateSrp6Client(TlsSrpConfig srpConfig)
{
BigInteger[] ng = srpConfig.GetExplicitNG();
Srp6GroupParameters srpGroup = new Srp6GroupParameters(ng[0], ng[1]);
Srp6Client srp6Client = new Srp6Client();
srp6Client.Init(srpGroup, CreateDigest(CryptoHashAlgorithm.sha1), SecureRandom);
return new BcTlsSrp6Client(srp6Client);
}
public override TlsSrp6Server CreateSrp6Server(TlsSrpConfig srpConfig, BigInteger srpVerifier)
{
BigInteger[] ng = srpConfig.GetExplicitNG();
Srp6GroupParameters srpGroup = new Srp6GroupParameters(ng[0], ng[1]);
Srp6Server srp6Server = new Srp6Server();
srp6Server.Init(srpGroup, srpVerifier, CreateDigest(CryptoHashAlgorithm.sha1), SecureRandom);
return new BcTlsSrp6Server(srp6Server);
}
public override TlsSrp6VerifierGenerator CreateSrp6VerifierGenerator(TlsSrpConfig srpConfig)
{
BigInteger[] ng = srpConfig.GetExplicitNG();
Srp6VerifierGenerator srp6VerifierGenerator = new Srp6VerifierGenerator();
srp6VerifierGenerator.Init(ng[0], ng[1], CreateDigest(CryptoHashAlgorithm.sha1));
return new BcTlsSrp6VerifierGenerator(srp6VerifierGenerator);
}
public override TlsSecret HkdfInit(int cryptoHashAlgorithm)
{
return AdoptLocalSecret(new byte[TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm)]);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 36e6d3f8becfe7d46a9fe2a9c8a37c3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Support class for ephemeral Diffie-Hellman using the BC light-weight library.</summary>
public class BcTlsDH
: TlsAgreement
{
protected readonly BcTlsDHDomain m_domain;
protected AsymmetricCipherKeyPair m_localKeyPair;
protected DHPublicKeyParameters m_peerPublicKey;
public BcTlsDH(BcTlsDHDomain domain)
{
this.m_domain = domain;
}
public virtual byte[] GenerateEphemeral()
{
this.m_localKeyPair = m_domain.GenerateKeyPair();
return m_domain.EncodePublicKey((DHPublicKeyParameters)m_localKeyPair.Public);
}
public virtual void ReceivePeerValue(byte[] peerValue)
{
this.m_peerPublicKey = m_domain.DecodePublicKey(peerValue);
}
public virtual TlsSecret CalculateSecret()
{
return m_domain.CalculateDHAgreement((DHPrivateKeyParameters)m_localKeyPair.Private, m_peerPublicKey);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9191048a1d0bd014090167375a36ec73
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>BC light-weight support class for Diffie-Hellman key pair generation and key agreement over a
/// specified Diffie-Hellman configuration.</summary>
public class BcTlsDHDomain
: TlsDHDomain
{
private static byte[] EncodeValue(DHParameters dh, bool padded, BigInteger x)
{
return padded
? BigIntegers.AsUnsignedByteArray(GetValueLength(dh), x)
: BigIntegers.AsUnsignedByteArray(x);
}
private static int GetValueLength(DHParameters dh)
{
return BigIntegers.GetUnsignedByteLength(dh.P);
}
public static BcTlsSecret CalculateDHAgreement(BcTlsCrypto crypto, DHPrivateKeyParameters privateKey,
DHPublicKeyParameters publicKey, bool padded)
{
DHBasicAgreement basicAgreement = new DHBasicAgreement();
basicAgreement.Init(privateKey);
BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey);
byte[] secret = EncodeValue(privateKey.Parameters, padded, agreementValue);
return crypto.AdoptLocalSecret(secret);
}
public static DHParameters GetDomainParameters(TlsDHConfig dhConfig)
{
DHGroup dhGroup = TlsDHUtilities.GetDHGroup(dhConfig);
if (dhGroup == null)
throw new ArgumentException("No DH configuration provided");
return new DHParameters(dhGroup.P, dhGroup.G, dhGroup.Q, dhGroup.L);
}
protected readonly BcTlsCrypto m_crypto;
protected readonly TlsDHConfig m_config;
protected readonly DHParameters m_domainParameters;
public BcTlsDHDomain(BcTlsCrypto crypto, TlsDHConfig dhConfig)
{
this.m_crypto = crypto;
this.m_config = dhConfig;
this.m_domainParameters = GetDomainParameters(dhConfig);
}
public virtual BcTlsSecret CalculateDHAgreement(DHPrivateKeyParameters privateKey,
DHPublicKeyParameters publicKey)
{
return CalculateDHAgreement(m_crypto, privateKey, publicKey, m_config.IsPadded);
}
public virtual TlsAgreement CreateDH()
{
return new BcTlsDH(this);
}
/// <exception cref="IOException"/>
public virtual BigInteger DecodeParameter(byte[] encoding)
{
if (m_config.IsPadded && GetValueLength(m_domainParameters) != encoding.Length)
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
return new BigInteger(1, encoding);
}
/// <exception cref="IOException"/>
public virtual DHPublicKeyParameters DecodePublicKey(byte[] encoding)
{
/*
* RFC 7919 3. [..] the client MUST verify that dh_Ys is in the range 1 < dh_Ys < dh_p - 1.
* If dh_Ys is not in this range, the client MUST terminate the connection with a fatal
* handshake_failure(40) alert.
*/
try
{
BigInteger y = DecodeParameter(encoding);
return new DHPublicKeyParameters(y, m_domainParameters);
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.handshake_failure, e);
}
}
public virtual byte[] EncodeParameter(BigInteger x)
{
return EncodeValue(m_domainParameters, m_config.IsPadded, x);
}
public virtual byte[] EncodePublicKey(DHPublicKeyParameters publicKey)
{
return EncodeValue(m_domainParameters, true, publicKey.Y);
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
DHBasicKeyPairGenerator keyPairGenerator = new DHBasicKeyPairGenerator();
keyPairGenerator.Init(new DHKeyGenerationParameters(m_crypto.SecureRandom, m_domainParameters));
return keyPairGenerator.GenerateKeyPair();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30ef06c298d99664b9cf05c5a42e22ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Implementation class for generation of the raw DSA signature type using the BC light-weight API.
/// </summary>
public class BcTlsDsaSigner
: BcTlsDssSigner
{
public BcTlsDsaSigner(BcTlsCrypto crypto, DsaPrivateKeyParameters privateKey)
: base(crypto, privateKey)
{
}
protected override IDsa CreateDsaImpl(int cryptoHashAlgorithm)
{
return new DsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm)));
}
protected override short SignatureAlgorithm
{
get { return Tls.SignatureAlgorithm.dsa; }
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0baf4b33ad021e44bab408cea5773ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Implementation class for the verification of the raw DSA signature type using the BC light-weight API.
/// </summary>
public class BcTlsDsaVerifier
: BcTlsDssVerifier
{
public BcTlsDsaVerifier(BcTlsCrypto crypto, DsaPublicKeyParameters publicKey)
: base(crypto, publicKey)
{
}
protected override IDsa CreateDsaImpl()
{
return new DsaSigner();
}
protected override short SignatureAlgorithm
{
get { return Tls.SignatureAlgorithm.dsa; }
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1dd8d1f47f4d96d4c83c665b309cc52d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>BC light-weight base class for the signers implementing the two DSA style algorithms from FIPS PUB
/// 186-4: DSA and ECDSA.</summary>
public abstract class BcTlsDssSigner
: BcTlsSigner
{
protected BcTlsDssSigner(BcTlsCrypto crypto, AsymmetricKeyParameter privateKey)
: base(crypto, privateKey)
{
}
protected abstract IDsa CreateDsaImpl(int cryptoHashAlgorithm);
protected abstract short SignatureAlgorithm { get; }
public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash)
{
if (algorithm != null && algorithm.Signature != SignatureAlgorithm)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
int cryptoHashAlgorithm = (null == algorithm)
? CryptoHashAlgorithm.sha1
: TlsCryptoUtilities.GetHash(algorithm.Hash);
ISigner signer = new DsaDigestSigner(CreateDsaImpl(cryptoHashAlgorithm), new NullDigest());
signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom));
if (algorithm == null)
{
// Note: Only use the SHA1 part of the (MD5/SHA1) hash
signer.BlockUpdate(hash, 16, 20);
}
else
{
signer.BlockUpdate(hash, 0, hash.Length);
}
try
{
return signer.GenerateSignature();
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c2ca5e7e6ad55c489e5936b0beccc9c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>BC light-weight base class for the verifiers supporting the two DSA style algorithms from FIPS PUB
/// 186-4: DSA and ECDSA.</summary>
public abstract class BcTlsDssVerifier
: BcTlsVerifier
{
protected BcTlsDssVerifier(BcTlsCrypto crypto, AsymmetricKeyParameter publicKey)
: base(crypto, publicKey)
{
}
protected abstract IDsa CreateDsaImpl();
protected abstract short SignatureAlgorithm { get; }
public override bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash)
{
SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
if (algorithm != null && algorithm.Signature != SignatureAlgorithm)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
ISigner signer = new DsaDigestSigner(CreateDsaImpl(), new NullDigest());
signer.Init(false, m_publicKey);
if (algorithm == null)
{
// Note: Only use the SHA1 part of the (MD5/SHA1) hash
signer.BlockUpdate(hash, 16, 20);
}
else
{
signer.BlockUpdate(hash, 0, hash.Length);
}
return signer.VerifySignature(digitallySigned.Signature);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82bc57525eb1d6847bd0f677aa9ffc1e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Support class for ephemeral Elliptic Curve Diffie-Hellman using the BC light-weight library.</summary>
public class BcTlsECDH
: TlsAgreement
{
protected readonly BcTlsECDomain m_domain;
protected AsymmetricCipherKeyPair m_localKeyPair;
protected ECPublicKeyParameters m_peerPublicKey;
public BcTlsECDH(BcTlsECDomain domain)
{
this.m_domain = domain;
}
public virtual byte[] GenerateEphemeral()
{
this.m_localKeyPair = m_domain.GenerateKeyPair();
return m_domain.EncodePublicKey((ECPublicKeyParameters)m_localKeyPair.Public);
}
public virtual void ReceivePeerValue(byte[] peerValue)
{
this.m_peerPublicKey = m_domain.DecodePublicKey(peerValue);
}
public virtual TlsSecret CalculateSecret()
{
return m_domain.CalculateECDHAgreement((ECPrivateKeyParameters)m_localKeyPair.Private, m_peerPublicKey);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6aa1f94604e5f1944b98d536face36a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,125 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X9;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/**
* EC domain class for generating key pairs and performing key agreement.
*/
public class BcTlsECDomain
: TlsECDomain
{
public static BcTlsSecret CalculateECDHAgreement(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 = ECKeyPairGenerator.FindECCurveByName(curveName);
if (ecP == null)
return null;
// It's a bit inefficient to do this conversion every time
return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
}
protected readonly BcTlsCrypto m_crypto;
protected readonly TlsECConfig m_config;
protected readonly ECDomainParameters m_domainParameters;
public BcTlsECDomain(BcTlsCrypto crypto, TlsECConfig ecConfig)
{
this.m_crypto = crypto;
this.m_config = ecConfig;
this.m_domainParameters = GetDomainParameters(ecConfig);
}
public virtual BcTlsSecret CalculateECDHAgreement(ECPrivateKeyParameters privateKey,
ECPublicKeyParameters publicKey)
{
return CalculateECDHAgreement(m_crypto, privateKey, publicKey);
}
public virtual TlsAgreement CreateECDH()
{
return new BcTlsECDH(this);
}
public virtual ECPoint DecodePoint(byte[] encoding)
{
return m_domainParameters.Curve.DecodePoint(encoding);
}
/// <exception cref="IOException"/>
public virtual ECPublicKeyParameters DecodePublicKey(byte[] encoding)
{
try
{
ECPoint point = DecodePoint(encoding);
return new ECPublicKeyParameters(point, m_domainParameters);
}
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_domainParameters, m_crypto.SecureRandom));
return keyPairGenerator.GenerateKeyPair();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2fd27ec13a575ea4c8600311dcb18f69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Implementation class for generation of ECDSA signatures in TLS 1.3+ using the BC light-weight API.
/// </summary>
public class BcTlsECDsa13Signer
: BcTlsSigner
{
private readonly int m_signatureScheme;
public BcTlsECDsa13Signer(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey, int signatureScheme)
: base(crypto, privateKey)
{
if (!SignatureScheme.IsECDsa(signatureScheme))
throw new ArgumentException("signatureScheme");
this.m_signatureScheme = signatureScheme;
}
public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash)
{
if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme);
IDsa dsa = new ECDsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm)));
ISigner signer = new DsaDigestSigner(dsa, new NullDigest());
signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom));
signer.BlockUpdate(hash, 0, hash.Length);
try
{
return signer.GenerateSignature();
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42b7da95e44910341b4de9117adf94bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Implementation class for generation of the raw ECDSA signature type using the BC light-weight API.
/// </summary>
public class BcTlsECDsaSigner
: BcTlsDssSigner
{
public BcTlsECDsaSigner(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey)
: base(crypto, privateKey)
{
}
protected override IDsa CreateDsaImpl(int cryptoHashAlgorithm)
{
return new ECDsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm)));
}
protected override short SignatureAlgorithm
{
get { return Tls.SignatureAlgorithm.ecdsa; }
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc174da35b6a95c43b4f9fd3ff8f9601
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Implementation class for the verification of the raw ECDSA signature type using the BC light-weight
/// API.</summary>
public class BcTlsECDsaVerifier
: BcTlsDssVerifier
{
public BcTlsECDsaVerifier(BcTlsCrypto crypto, ECPublicKeyParameters publicKey)
: base(crypto, publicKey)
{
}
protected override IDsa CreateDsaImpl()
{
return new ECDsaSigner();
}
protected override short SignatureAlgorithm
{
get { return Tls.SignatureAlgorithm.ecdsa; }
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 92d29c21e5ab5ce409a87a091497c11b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
public class BcTlsEd25519Signer
: BcTlsSigner
{
public BcTlsEd25519Signer(BcTlsCrypto crypto, Ed25519PrivateKeyParameters privateKey)
: base(crypto, privateKey)
{
}
public override TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm)
{
if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed25519)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
Ed25519Signer signer = new Ed25519Signer();
signer.Init(true, m_privateKey);
return new BcTlsStreamSigner(signer);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 815dee36ad3d2184fa77798c223a4b38
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
public class BcTlsEd448Signer
: BcTlsSigner
{
public BcTlsEd448Signer(BcTlsCrypto crypto, Ed448PrivateKeyParameters privateKey)
: base(crypto, privateKey)
{
}
public override TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm)
{
if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed448)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
Ed448Signer signer = new Ed448Signer(TlsUtilities.EmptyBytes);
signer.Init(true, m_privateKey);
return new BcTlsStreamSigner(signer);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a5ec0d7e05eb7cc43bc8fd211f9ba4c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsHash
: TlsHash
{
private readonly BcTlsCrypto m_crypto;
private readonly int m_cryptoHashAlgorithm;
private readonly IDigest m_digest;
internal BcTlsHash(BcTlsCrypto crypto, int cryptoHashAlgorithm)
: this(crypto, cryptoHashAlgorithm, crypto.CreateDigest(cryptoHashAlgorithm))
{
}
private BcTlsHash(BcTlsCrypto crypto, int cryptoHashAlgorithm, IDigest digest)
{
this.m_crypto = crypto;
this.m_cryptoHashAlgorithm = cryptoHashAlgorithm;
this.m_digest = digest;
}
public void Update(byte[] data, int offSet, int length)
{
m_digest.BlockUpdate(data, offSet, length);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void Update(ReadOnlySpan<byte> input)
{
m_digest.BlockUpdate(input);
}
#endif
public byte[] CalculateHash()
{
byte[] rv = new byte[m_digest.GetDigestSize()];
m_digest.DoFinal(rv, 0);
return rv;
}
public TlsHash CloneHash()
{
IDigest clone = m_crypto.CloneDigest(m_cryptoHashAlgorithm, m_digest);
return new BcTlsHash(m_crypto, m_cryptoHashAlgorithm, clone);
}
public void Reset()
{
m_digest.Reset();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a4db1fa62387dd4bbae89d4aeca62fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,73 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsHmac
: TlsHmac
{
private readonly HMac m_hmac;
internal BcTlsHmac(HMac hmac)
{
this.m_hmac = hmac;
}
public void SetKey(byte[] key, int keyOff, int keyLen)
{
m_hmac.Init(new KeyParameter(key, keyOff, keyLen));
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void SetKey(ReadOnlySpan<byte> key)
{
m_hmac.Init(new KeyParameter(key));
}
#endif
public void Update(byte[] input, int inOff, int length)
{
m_hmac.BlockUpdate(input, inOff, length);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void Update(ReadOnlySpan<byte> input)
{
m_hmac.BlockUpdate(input);
}
#endif
public byte[] CalculateMac()
{
byte[] rv = new byte[m_hmac.GetMacSize()];
m_hmac.DoFinal(rv, 0);
return rv;
}
public void CalculateMac(byte[] output, int outOff)
{
m_hmac.DoFinal(output, outOff);
}
public int InternalBlockSize
{
get { return m_hmac.GetUnderlyingDigest().GetByteLength(); }
}
public int MacLength
{
get { return m_hmac.GetMacSize(); }
}
public void Reset()
{
m_hmac.Reset();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bef25266360b4f04db436903e852505d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsNonceGenerator
: TlsNonceGenerator
{
private readonly IRandomGenerator m_randomGenerator;
internal BcTlsNonceGenerator(IRandomGenerator randomGenerator)
{
this.m_randomGenerator = randomGenerator;
}
public byte[] GenerateNonce(int size)
{
byte[] nonce = new byte[size];
m_randomGenerator.NextBytes(nonce);
return nonce;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9bd9a1921160b7d4d982cb9241e1f81f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,511 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Implementation class for a single X.509 certificate based on the BC light-weight API.</summary>
public class BcTlsRawKeyCertificate
: TlsCertificate
{
protected readonly BcTlsCrypto m_crypto;
protected readonly SubjectPublicKeyInfo m_keyInfo;
protected DHPublicKeyParameters m_pubKeyDH = null;
protected ECPublicKeyParameters m_pubKeyEC = null;
protected Ed25519PublicKeyParameters m_pubKeyEd25519 = null;
protected Ed448PublicKeyParameters m_pubKeyEd448 = null;
protected RsaKeyParameters m_pubKeyRsa = null;
/// <exception cref="IOException"/>
public BcTlsRawKeyCertificate(BcTlsCrypto crypto, byte[] encoding)
: this(crypto, SubjectPublicKeyInfo.GetInstance(encoding))
{
}
public BcTlsRawKeyCertificate(BcTlsCrypto crypto, SubjectPublicKeyInfo keyInfo)
{
m_crypto = crypto;
m_keyInfo = keyInfo;
}
public virtual SubjectPublicKeyInfo SubjectPublicKeyInfo => m_keyInfo;
/// <exception cref="IOException"/>
public virtual TlsEncryptor CreateEncryptor(int tlsCertificateRole)
{
ValidateKeyUsage(KeyUsage.KeyEncipherment);
switch (tlsCertificateRole)
{
case TlsCertificateRole.RsaEncryption:
{
this.m_pubKeyRsa = GetPubKeyRsa();
return new BcTlsRsaEncryptor(m_crypto, m_pubKeyRsa);
}
// TODO[gmssl]
//case TlsCertificateRole.Sm2Encryption:
//{
// this.m_pubKeyEC = GetPubKeyEC();
// return new BcTlsSM2Encryptor(m_crypto, m_pubKeyEC);
//}
}
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
/// <exception cref="IOException"/>
public virtual TlsVerifier CreateVerifier(short signatureAlgorithm)
{
switch (signatureAlgorithm)
{
case SignatureAlgorithm.ed25519:
case SignatureAlgorithm.ed448:
{
int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm);
Tls13Verifier tls13Verifier = CreateVerifier(signatureScheme);
return new LegacyTls13Verifier(signatureScheme, tls13Verifier);
}
}
ValidateKeyUsage(KeyUsage.DigitalSignature);
switch (signatureAlgorithm)
{
case SignatureAlgorithm.dsa:
return new BcTlsDsaVerifier(m_crypto, GetPubKeyDss());
case SignatureAlgorithm.ecdsa:
return new BcTlsECDsaVerifier(m_crypto, GetPubKeyEC());
case SignatureAlgorithm.rsa:
{
ValidateRsa_Pkcs1();
return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa());
}
case SignatureAlgorithm.rsa_pss_pss_sha256:
case SignatureAlgorithm.rsa_pss_pss_sha384:
case SignatureAlgorithm.rsa_pss_pss_sha512:
{
ValidateRsa_Pss_Pss(signatureAlgorithm);
int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm);
return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
}
case SignatureAlgorithm.rsa_pss_rsae_sha256:
case SignatureAlgorithm.rsa_pss_rsae_sha384:
case SignatureAlgorithm.rsa_pss_rsae_sha512:
{
ValidateRsa_Pss_Rsae();
int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm);
return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
}
default:
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
}
/// <exception cref="IOException"/>
public virtual Tls13Verifier CreateVerifier(int signatureScheme)
{
ValidateKeyUsage(KeyUsage.DigitalSignature);
switch (signatureScheme)
{
case SignatureScheme.ecdsa_brainpoolP256r1tls13_sha256:
case SignatureScheme.ecdsa_brainpoolP384r1tls13_sha384:
case SignatureScheme.ecdsa_brainpoolP512r1tls13_sha512:
case SignatureScheme.ecdsa_secp256r1_sha256:
case SignatureScheme.ecdsa_secp384r1_sha384:
case SignatureScheme.ecdsa_secp521r1_sha512:
case SignatureScheme.ecdsa_sha1:
{
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
ISigner verifier = new DsaDigestSigner(new ECDsaSigner(), digest);
verifier.Init(false, GetPubKeyEC());
return new BcTls13Verifier(verifier);
}
case SignatureScheme.ed25519:
{
Ed25519Signer verifier = new Ed25519Signer();
verifier.Init(false, GetPubKeyEd25519());
return new BcTls13Verifier(verifier);
}
case SignatureScheme.ed448:
{
Ed448Signer verifier = new Ed448Signer(TlsUtilities.EmptyBytes);
verifier.Init(false, GetPubKeyEd448());
return new BcTls13Verifier(verifier);
}
case SignatureScheme.rsa_pkcs1_sha1:
case SignatureScheme.rsa_pkcs1_sha256:
case SignatureScheme.rsa_pkcs1_sha384:
case SignatureScheme.rsa_pkcs1_sha512:
{
ValidateRsa_Pkcs1();
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
RsaDigestSigner verifier = new RsaDigestSigner(digest,
TlsCryptoUtilities.GetOidForHash(cryptoHashAlgorithm));
verifier.Init(false, GetPubKeyRsa());
return new BcTls13Verifier(verifier);
}
case SignatureScheme.rsa_pss_pss_sha256:
case SignatureScheme.rsa_pss_pss_sha384:
case SignatureScheme.rsa_pss_pss_sha512:
{
ValidateRsa_Pss_Pss(SignatureScheme.GetSignatureAlgorithm(signatureScheme));
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize());
verifier.Init(false, GetPubKeyRsa());
return new BcTls13Verifier(verifier);
}
case SignatureScheme.rsa_pss_rsae_sha256:
case SignatureScheme.rsa_pss_rsae_sha384:
case SignatureScheme.rsa_pss_rsae_sha512:
{
ValidateRsa_Pss_Rsae();
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize());
verifier.Init(false, GetPubKeyRsa());
return new BcTls13Verifier(verifier);
}
// TODO[RFC 8998]
//case SignatureScheme.sm2sig_sm3:
//{
// ParametersWithID parametersWithID = new ParametersWithID(GetPubKeyEC(),
// Strings.ToByteArray("TLSv1.3+GM+Cipher+Suite"));
// SM2Signer verifier = new SM2Signer();
// verifier.Init(false, parametersWithID);
// return new BcTls13Verifier(verifier);
//}
default:
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
}
/// <exception cref="IOException"/>
public virtual byte[] GetEncoded()
{
return m_keyInfo.GetEncoded(Asn1Encodable.Der);
}
/// <exception cref="IOException"/>
public virtual byte[] GetExtension(DerObjectIdentifier extensionOid)
{
return null;
}
public virtual BigInteger SerialNumber => null;
public virtual string SigAlgOid => null;
public virtual Asn1Encodable GetSigAlgParams() => null;
/// <exception cref="IOException"/>
public virtual short GetLegacySignatureAlgorithm()
{
AsymmetricKeyParameter publicKey = GetPublicKey();
if (publicKey.IsPrivate)
throw new TlsFatalAlert(AlertDescription.internal_error);
if (!SupportsKeyUsage(KeyUsage.DigitalSignature))
return -1;
/*
* RFC 5246 7.4.6. Client Certificate
*/
/*
* RSA public key; the certificate MUST allow the key to be used for signing with the
* signature scheme and hash algorithm that will be employed in the certificate verify
* message.
*/
if (publicKey is RsaKeyParameters)
return SignatureAlgorithm.rsa;
/*
* DSA public key; the certificate MUST allow the key to be used for signing with the
* hash algorithm that will be employed in the certificate verify message.
*/
if (publicKey is DsaPublicKeyParameters)
return SignatureAlgorithm.dsa;
/*
* ECDSA-capable public key; the certificate MUST allow the key to be used for signing
* with the hash algorithm that will be employed in the certificate verify message; the
* public key MUST use a curve and point format supported by the server.
*/
if (publicKey is ECPublicKeyParameters)
{
// TODO Check the curve and point format
return SignatureAlgorithm.ecdsa;
}
return -1;
}
/// <exception cref="IOException"/>
public virtual DHPublicKeyParameters GetPubKeyDH()
{
try
{
return (DHPublicKeyParameters)GetPublicKey();
}
catch (InvalidCastException e)
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
}
}
/// <exception cref="IOException"/>
public virtual DsaPublicKeyParameters GetPubKeyDss()
{
try
{
return (DsaPublicKeyParameters)GetPublicKey();
}
catch (InvalidCastException e)
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
}
}
/// <exception cref="IOException"/>
public virtual ECPublicKeyParameters GetPubKeyEC()
{
try
{
return (ECPublicKeyParameters)GetPublicKey();
}
catch (InvalidCastException e)
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
}
}
/// <exception cref="IOException"/>
public virtual Ed25519PublicKeyParameters GetPubKeyEd25519()
{
try
{
return (Ed25519PublicKeyParameters)GetPublicKey();
}
catch (InvalidCastException e)
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
}
}
/// <exception cref="IOException"/>
public virtual Ed448PublicKeyParameters GetPubKeyEd448()
{
try
{
return (Ed448PublicKeyParameters)GetPublicKey();
}
catch (InvalidCastException e)
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
}
}
/// <exception cref="IOException"/>
public virtual RsaKeyParameters GetPubKeyRsa()
{
try
{
return (RsaKeyParameters)GetPublicKey();
}
catch (InvalidCastException e)
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
}
}
/// <exception cref="IOException"/>
public virtual bool SupportsSignatureAlgorithm(short signatureAlgorithm)
{
return SupportsSignatureAlgorithm(signatureAlgorithm, KeyUsage.DigitalSignature);
}
/// <exception cref="IOException"/>
public virtual bool SupportsSignatureAlgorithmCA(short signatureAlgorithm)
{
return SupportsSignatureAlgorithm(signatureAlgorithm, KeyUsage.KeyCertSign);
}
/// <exception cref="IOException"/>
public virtual TlsCertificate CheckUsageInRole(int tlsCertificateRole)
{
switch (tlsCertificateRole)
{
case TlsCertificateRole.DH:
{
ValidateKeyUsage(KeyUsage.KeyAgreement);
this.m_pubKeyDH = GetPubKeyDH();
return this;
}
case TlsCertificateRole.ECDH:
{
ValidateKeyUsage(KeyUsage.KeyAgreement);
this.m_pubKeyEC = GetPubKeyEC();
return this;
}
}
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
/// <exception cref="IOException"/>
protected virtual AsymmetricKeyParameter GetPublicKey()
{
try
{
return PublicKeyFactory.CreateKey(m_keyInfo);
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
}
}
protected virtual bool SupportsKeyUsage(int keyUsageBits)
{
return true;
}
protected virtual bool SupportsRsa_Pkcs1()
{
AlgorithmIdentifier pubKeyAlgID = m_keyInfo.AlgorithmID;
return RsaUtilities.SupportsPkcs1(pubKeyAlgID);
}
protected virtual bool SupportsRsa_Pss_Pss(short signatureAlgorithm)
{
AlgorithmIdentifier pubKeyAlgID = m_keyInfo.AlgorithmID;
return RsaUtilities.SupportsPss_Pss(signatureAlgorithm, pubKeyAlgID);
}
protected virtual bool SupportsRsa_Pss_Rsae()
{
AlgorithmIdentifier pubKeyAlgID = m_keyInfo.AlgorithmID;
return RsaUtilities.SupportsPss_Rsae(pubKeyAlgID);
}
/// <exception cref="IOException"/>
protected virtual bool SupportsSignatureAlgorithm(short signatureAlgorithm, int keyUsage)
{
if (!SupportsKeyUsage(keyUsage))
return false;
AsymmetricKeyParameter publicKey = GetPublicKey();
switch (signatureAlgorithm)
{
case SignatureAlgorithm.rsa:
return SupportsRsa_Pkcs1()
&& publicKey is RsaKeyParameters;
case SignatureAlgorithm.dsa:
return publicKey is DsaPublicKeyParameters;
case SignatureAlgorithm.ecdsa:
case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256:
case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384:
case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512:
return publicKey is ECPublicKeyParameters;
case SignatureAlgorithm.ed25519:
return publicKey is Ed25519PublicKeyParameters;
case SignatureAlgorithm.ed448:
return publicKey is Ed448PublicKeyParameters;
case SignatureAlgorithm.rsa_pss_rsae_sha256:
case SignatureAlgorithm.rsa_pss_rsae_sha384:
case SignatureAlgorithm.rsa_pss_rsae_sha512:
return SupportsRsa_Pss_Rsae()
&& publicKey is RsaKeyParameters;
case SignatureAlgorithm.rsa_pss_pss_sha256:
case SignatureAlgorithm.rsa_pss_pss_sha384:
case SignatureAlgorithm.rsa_pss_pss_sha512:
return SupportsRsa_Pss_Pss(signatureAlgorithm)
&& publicKey is RsaKeyParameters;
default:
return false;
}
}
/// <exception cref="IOException"/>
public virtual void ValidateKeyUsage(int keyUsageBits)
{
if (!SupportsKeyUsage(keyUsageBits))
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
/// <exception cref="IOException"/>
protected virtual void ValidateRsa_Pkcs1()
{
if (!SupportsRsa_Pkcs1())
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
/// <exception cref="IOException"/>
protected virtual void ValidateRsa_Pss_Pss(short signatureAlgorithm)
{
if (!SupportsRsa_Pss_Pss(signatureAlgorithm))
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
/// <exception cref="IOException"/>
protected virtual void ValidateRsa_Pss_Rsae()
{
if (!SupportsRsa_Pss_Rsae())
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f956740c47d73ee42b06809b11ca0fd1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Encodings;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsRsaEncryptor
: TlsEncryptor
{
private static RsaKeyParameters CheckPublicKey(RsaKeyParameters pubKeyRsa)
{
if (null == pubKeyRsa || pubKeyRsa.IsPrivate)
throw new ArgumentException("No public RSA key provided", "pubKeyRsa");
return pubKeyRsa;
}
private readonly BcTlsCrypto m_crypto;
private readonly RsaKeyParameters m_pubKeyRsa;
internal BcTlsRsaEncryptor(BcTlsCrypto crypto, RsaKeyParameters pubKeyRsa)
{
this.m_crypto = crypto;
this.m_pubKeyRsa = CheckPublicKey(pubKeyRsa);
}
public byte[] Encrypt(byte[] input, int inOff, int length)
{
try
{
Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine());
encoding.Init(true, new ParametersWithRandom(m_pubKeyRsa, m_crypto.SecureRandom));
return encoding.ProcessBlock(input, inOff, length);
}
catch (InvalidCipherTextException e)
{
/*
* This should never happen, only during decryption.
*/
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e2fbf26ff4db16e4ab6d7a66dc1b2734
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Operator supporting the generation of RSASSA-PSS signatures using the BC light-weight API.</summary>
public class BcTlsRsaPssSigner
: BcTlsSigner
{
private readonly int m_signatureScheme;
public BcTlsRsaPssSigner(BcTlsCrypto crypto, RsaKeyParameters privateKey, int signatureScheme)
: base(crypto, privateKey)
{
if (!SignatureScheme.IsRsaPss(signatureScheme))
throw new ArgumentException("signatureScheme");
this.m_signatureScheme = signatureScheme;
}
public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash)
{
if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
PssSigner signer = PssSigner.CreateRawSigner(new RsaBlindedEngine(), digest, digest, digest.GetDigestSize(),
PssSigner.TrailerImplicit);
signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom));
signer.BlockUpdate(hash, 0, hash.Length);
try
{
return signer.GenerateSignature();
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 32c0adc0dc01c7048b8ef04bb6a0ab9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Operator supporting the verification of RSASSA-PSS signatures using the BC light-weight API.</summary>
public class BcTlsRsaPssVerifier
: BcTlsVerifier
{
private readonly int m_signatureScheme;
public BcTlsRsaPssVerifier(BcTlsCrypto crypto, RsaKeyParameters publicKey, int signatureScheme)
: base(crypto, publicKey)
{
if (!SignatureScheme.IsRsaPss(signatureScheme))
throw new ArgumentException("signatureScheme");
this.m_signatureScheme = signatureScheme;
}
public override bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash)
{
SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
PssSigner verifier = PssSigner.CreateRawSigner(new RsaEngine(), digest, digest, digest.GetDigestSize(),
PssSigner.TrailerImplicit);
verifier.Init(false, m_publicKey);
verifier.BlockUpdate(hash, 0, hash.Length);
return verifier.VerifySignature(digitallySigned.Signature);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 394d3707553c52046b3e608d23561d65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Encodings;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Operator supporting the generation of RSASSA-PKCS1-v1_5 signatures using the BC light-weight API.
/// </summary>
public class BcTlsRsaSigner
: BcTlsSigner
{
private readonly RsaKeyParameters m_publicKey;
public BcTlsRsaSigner(BcTlsCrypto crypto, RsaKeyParameters privateKey, RsaKeyParameters publicKey)
: base(crypto, privateKey)
{
this.m_publicKey = publicKey;
}
public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash)
{
IDigest nullDigest = new NullDigest();
ISigner signer;
if (algorithm != null)
{
if (algorithm.Signature != SignatureAlgorithm.rsa)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
/*
* RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated
* using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1].
*/
signer = new RsaDigestSigner(nullDigest, TlsUtilities.GetOidForHashAlgorithm(algorithm.Hash));
}
else
{
/*
* RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme
* that did not include a DigestInfo encoding.
*/
signer = new GenericSigner(new Pkcs1Encoding(new RsaBlindedEngine()), nullDigest);
}
signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom));
signer.BlockUpdate(hash, 0, hash.Length);
try
{
byte[] signature = signer.GenerateSignature();
signer.Init(false, m_publicKey);
signer.BlockUpdate(hash, 0, hash.Length);
if (signer.VerifySignature(signature))
{
return signature;
}
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 493cafec07827344580a19f8e73a15fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Encodings;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>Operator supporting the verification of RSASSA-PKCS1-v1_5 signatures using the BC light-weight API.
/// </summary>
public class BcTlsRsaVerifier
: BcTlsVerifier
{
public BcTlsRsaVerifier(BcTlsCrypto crypto, RsaKeyParameters publicKey)
: base(crypto, publicKey)
{
}
public override bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash)
{
IDigest nullDigest = new NullDigest();
SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
ISigner signer;
if (algorithm != null)
{
if (algorithm.Signature != SignatureAlgorithm.rsa)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
/*
* RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated
* using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1].
*/
signer = new RsaDigestSigner(nullDigest, TlsUtilities.GetOidForHashAlgorithm(algorithm.Hash));
}
else
{
/*
* RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme
* that did not include a DigestInfo encoding.
*/
signer = new GenericSigner(new Pkcs1Encoding(new RsaBlindedEngine()), nullDigest);
}
signer.Init(false, m_publicKey);
signer.BlockUpdate(hash, 0, hash.Length);
return signer.VerifySignature(digitallySigned.Signature);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 262b99bbd5b956c45a02f2057583f956
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,416 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/// <summary>BC light-weight support class for handling TLS secrets and deriving key material and other secrets
/// from them.</summary>
public class BcTlsSecret
: AbstractTlsSecret
{
public static BcTlsSecret Convert(BcTlsCrypto crypto, TlsSecret secret)
{
if (secret is BcTlsSecret)
return (BcTlsSecret)secret;
if (secret is AbstractTlsSecret)
{
AbstractTlsSecret abstractTlsSecret = (AbstractTlsSecret)secret;
return crypto.AdoptLocalSecret(CopyData(abstractTlsSecret));
}
throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(secret));
}
// SSL3 magic mix constants ("A", "BB", "CCC", ...)
private static readonly byte[] Ssl3Const = GenerateSsl3Constants();
private static byte[] GenerateSsl3Constants()
{
int n = 15;
byte[] result = new byte[n * (n + 1) / 2];
int pos = 0;
for (int i = 0; i < n; ++i)
{
byte b = (byte)('A' + i);
for (int j = 0; j <= i; ++j)
{
result[pos++] = b;
}
}
return result;
}
protected readonly BcTlsCrypto m_crypto;
public BcTlsSecret(BcTlsCrypto crypto, byte[] data)
: base(data)
{
this.m_crypto = crypto;
}
public override TlsSecret DeriveUsingPrf(int prfAlgorithm, string label, byte[] seed, int length)
{
lock (this)
{
CheckAlive();
switch (prfAlgorithm)
{
case PrfAlgorithm.tls13_hkdf_sha256:
return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sha256, label, seed, length);
case PrfAlgorithm.tls13_hkdf_sha384:
return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sha384, label, seed, length);
case PrfAlgorithm.tls13_hkdf_sm3:
return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sm3, label, seed, length);
default:
return m_crypto.AdoptLocalSecret(Prf(prfAlgorithm, label, seed, length));
}
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override TlsSecret DeriveUsingPrf(int prfAlgorithm, ReadOnlySpan<char> label, ReadOnlySpan<byte> seed,
int length)
{
lock (this)
{
CheckAlive();
switch (prfAlgorithm)
{
case PrfAlgorithm.tls13_hkdf_sha256:
return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sha256, label, seed, length);
case PrfAlgorithm.tls13_hkdf_sha384:
return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sha384, label, seed, length);
case PrfAlgorithm.tls13_hkdf_sm3:
return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sm3, label, seed, length);
default:
return m_crypto.AdoptLocalSecret(Prf(prfAlgorithm, label, seed, length));
}
}
}
#endif
public override TlsSecret HkdfExpand(int cryptoHashAlgorithm, byte[] info, int length)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return HkdfExpand(cryptoHashAlgorithm, info.AsSpan(), length);
#else
lock (this)
{
if (length < 1)
return m_crypto.AdoptLocalSecret(TlsUtilities.EmptyBytes);
int hashLen = TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm);
if (length > (255 * hashLen))
throw new ArgumentException("must be <= 255 * (output size of 'hashAlgorithm')", "length");
CheckAlive();
byte[] prk = m_data;
HMac hmac = new HMac(m_crypto.CreateDigest(cryptoHashAlgorithm));
hmac.Init(new KeyParameter(prk));
byte[] okm = new byte[length];
byte[] t = new byte[hashLen];
byte counter = 0x00;
int pos = 0;
for (;;)
{
hmac.BlockUpdate(info, 0, info.Length);
hmac.Update(++counter);
hmac.DoFinal(t, 0);
int remaining = length - pos;
if (remaining <= hashLen)
{
Array.Copy(t, 0, okm, pos, remaining);
break;
}
Array.Copy(t, 0, okm, pos, hashLen);
pos += hashLen;
hmac.BlockUpdate(t, 0, t.Length);
}
return m_crypto.AdoptLocalSecret(okm);
}
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override TlsSecret HkdfExpand(int cryptoHashAlgorithm, ReadOnlySpan<byte> info, int length)
{
lock (this)
{
if (length < 1)
return m_crypto.AdoptLocalSecret(TlsUtilities.EmptyBytes);
int hashLen = TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm);
if (length > (255 * hashLen))
throw new ArgumentException("must be <= 255 * (output size of 'hashAlgorithm')", "length");
CheckAlive();
ReadOnlySpan<byte> prk = m_data;
HMac hmac = new HMac(m_crypto.CreateDigest(cryptoHashAlgorithm));
hmac.Init(new KeyParameter(prk));
byte[] okm = new byte[length];
Span<byte> t = hashLen <= 128
? stackalloc byte[hashLen]
: new byte[hashLen];
byte counter = 0x00;
int pos = 0;
for (;;)
{
hmac.BlockUpdate(info);
hmac.Update(++counter);
hmac.DoFinal(t);
int remaining = length - pos;
if (remaining <= hashLen)
{
t[..remaining].CopyTo(okm.AsSpan(pos));
break;
}
t.CopyTo(okm.AsSpan(pos));
pos += hashLen;
hmac.BlockUpdate(t);
}
return m_crypto.AdoptLocalSecret(okm);
}
}
#endif
public override TlsSecret HkdfExtract(int cryptoHashAlgorithm, TlsSecret ikm)
{
lock (this)
{
CheckAlive();
byte[] salt = m_data;
this.m_data = null;
HMac hmac = new HMac(m_crypto.CreateDigest(cryptoHashAlgorithm));
hmac.Init(new KeyParameter(salt));
Convert(m_crypto, ikm).UpdateMac(hmac);
byte[] prk = new byte[hmac.GetMacSize()];
hmac.DoFinal(prk, 0);
return m_crypto.AdoptLocalSecret(prk);
}
}
protected override AbstractTlsCrypto Crypto
{
get { return m_crypto; }
}
protected virtual void HmacHash(int cryptoHashAlgorithm, byte[] secret, int secretOff, int secretLen,
byte[] seed, byte[] output)
{
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
HMac hmac = new HMac(digest);
hmac.Init(new KeyParameter(secret, secretOff, secretLen));
byte[] a = seed;
int macSize = hmac.GetMacSize();
byte[] b1 = new byte[macSize];
byte[] b2 = new byte[macSize];
int pos = 0;
while (pos < output.Length)
{
hmac.BlockUpdate(a, 0, a.Length);
hmac.DoFinal(b1, 0);
a = b1;
hmac.BlockUpdate(a, 0, a.Length);
hmac.BlockUpdate(seed, 0, seed.Length);
hmac.DoFinal(b2, 0);
Array.Copy(b2, 0, output, pos, System.Math.Min(macSize, output.Length - pos));
pos += macSize;
}
}
protected virtual byte[] Prf(int prfAlgorithm, string label, byte[] seed, int length)
{
if (PrfAlgorithm.ssl_prf_legacy == prfAlgorithm)
return Prf_Ssl(seed, length);
byte[] labelSeed = Arrays.Concatenate(Strings.ToByteArray(label), seed);
if (PrfAlgorithm.tls_prf_legacy == prfAlgorithm)
return Prf_1_0(labelSeed, length);
return Prf_1_2(prfAlgorithm, labelSeed, length);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
protected virtual byte[] Prf(int prfAlgorithm, ReadOnlySpan<char> label, ReadOnlySpan<byte> seed, int length)
{
if (PrfAlgorithm.ssl_prf_legacy == prfAlgorithm)
return Prf_Ssl(seed, length);
byte[] labelSeed = new byte[label.Length + seed.Length];
for (int i = 0; i < label.Length; ++i)
{
labelSeed[i] = (byte)label[i];
}
seed.CopyTo(labelSeed.AsSpan(label.Length));
if (PrfAlgorithm.tls_prf_legacy == prfAlgorithm)
return Prf_1_0(labelSeed, length);
return Prf_1_2(prfAlgorithm, labelSeed, length);
}
#endif
protected virtual byte[] Prf_Ssl(byte[] seed, int length)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return Prf_Ssl(seed.AsSpan(), length);
#else
IDigest md5 = m_crypto.CreateDigest(CryptoHashAlgorithm.md5);
IDigest sha1 = m_crypto.CreateDigest(CryptoHashAlgorithm.sha1);
int md5Size = md5.GetDigestSize();
int sha1Size = sha1.GetDigestSize();
byte[] tmp = new byte[System.Math.Max(md5Size, sha1Size)];
byte[] result = new byte[length];
int constLen = 1, constPos = 0, resultPos = 0;
while (resultPos < length)
{
sha1.BlockUpdate(Ssl3Const, constPos, constLen);
constPos += constLen++;
sha1.BlockUpdate(m_data, 0, m_data.Length);
sha1.BlockUpdate(seed, 0, seed.Length);
sha1.DoFinal(tmp, 0);
md5.BlockUpdate(m_data, 0, m_data.Length);
md5.BlockUpdate(tmp, 0, sha1Size);
int remaining = length - resultPos;
if (remaining < md5Size)
{
md5.DoFinal(tmp, 0);
Array.Copy(tmp, 0, result, resultPos, remaining);
resultPos += remaining;
}
else
{
md5.DoFinal(result, resultPos);
resultPos += md5Size;
}
}
return result;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
protected virtual byte[] Prf_Ssl(ReadOnlySpan<byte> seed, int length)
{
IDigest md5 = m_crypto.CreateDigest(CryptoHashAlgorithm.md5);
IDigest sha1 = m_crypto.CreateDigest(CryptoHashAlgorithm.sha1);
int md5Size = md5.GetDigestSize();
int sha1Size = sha1.GetDigestSize();
Span<byte> tmp = stackalloc byte[System.Math.Max(md5Size, sha1Size)];
byte[] result = new byte[length];
int constLen = 1, constPos = 0, resultPos = 0;
while (resultPos < length)
{
sha1.BlockUpdate(Ssl3Const.AsSpan(constPos, constLen));
constPos += constLen++;
sha1.BlockUpdate(m_data);
sha1.BlockUpdate(seed);
sha1.DoFinal(tmp);
md5.BlockUpdate(m_data);
md5.BlockUpdate(tmp[..sha1Size]);
int remaining = length - resultPos;
if (remaining < md5Size)
{
md5.DoFinal(tmp);
tmp[..remaining].CopyTo(result.AsSpan(resultPos));
resultPos += remaining;
}
else
{
md5.DoFinal(result.AsSpan(resultPos));
resultPos += md5Size;
}
}
return result;
}
#endif
protected virtual byte[] Prf_1_0(byte[] labelSeed, int length)
{
int s_half = (m_data.Length + 1) / 2;
byte[] b1 = new byte[length];
HmacHash(CryptoHashAlgorithm.md5, m_data, 0, s_half, labelSeed, b1);
byte[] b2 = new byte[length];
HmacHash(CryptoHashAlgorithm.sha1, m_data, m_data.Length - s_half, s_half, labelSeed, b2);
for (int i = 0; i < length; i++)
{
b1[i] ^= b2[i];
}
return b1;
}
protected virtual byte[] Prf_1_2(int prfAlgorithm, byte[] labelSeed, int length)
{
int cryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(prfAlgorithm);
byte[] result = new byte[length];
HmacHash(cryptoHashAlgorithm, m_data, 0, m_data.Length, labelSeed, result);
return result;
}
protected virtual void UpdateMac(IMac mac)
{
lock (this)
{
CheckAlive();
mac.BlockUpdate(m_data, 0, m_data.Length);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85a721fd49f4902428c3caa39ac83b40
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
public abstract class BcTlsSigner
: TlsSigner
{
protected readonly BcTlsCrypto m_crypto;
protected readonly AsymmetricKeyParameter m_privateKey;
protected BcTlsSigner(BcTlsCrypto crypto, AsymmetricKeyParameter privateKey)
{
if (crypto == null)
throw new ArgumentNullException("crypto");
if (privateKey == null)
throw new ArgumentNullException("privateKey");
if (!privateKey.IsPrivate)
throw new ArgumentException("must be private", "privateKey");
this.m_crypto = crypto;
this.m_privateKey = privateKey;
}
public virtual byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash)
{
throw new NotSupportedException();
}
public virtual TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm)
{
return null;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 305b37d61fbd1214a8eea941cb9d1f8e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsSrp6Client
: TlsSrp6Client
{
private readonly Srp6Client m_srp6Client;
internal BcTlsSrp6Client(Srp6Client srpClient)
{
this.m_srp6Client = srpClient;
}
public BigInteger CalculateSecret(BigInteger serverB)
{
try
{
return m_srp6Client.CalculateSecret(serverB);
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
}
public BigInteger GenerateClientCredentials(byte[] srpSalt, byte[] identity, byte[] password)
{
return m_srp6Client.GenerateClientCredentials(srpSalt, identity, password);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05a4b14ea34033a45b780e27139d8afb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsSrp6Server
: TlsSrp6Server
{
private readonly Srp6Server m_srp6Server;
internal BcTlsSrp6Server(Srp6Server srp6Server)
{
this.m_srp6Server = srp6Server;
}
public BigInteger GenerateServerCredentials()
{
return m_srp6Server.GenerateServerCredentials();
}
public BigInteger CalculateSecret(BigInteger clientA)
{
try
{
return m_srp6Server.CalculateSecret(clientA);
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6bf7dfb7ec324f74285eae7d974ae28e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,27 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsSrp6VerifierGenerator
: TlsSrp6VerifierGenerator
{
private readonly Srp6VerifierGenerator m_srp6VerifierGenerator;
internal BcTlsSrp6VerifierGenerator(Srp6VerifierGenerator srp6VerifierGenerator)
{
this.m_srp6VerifierGenerator = srp6VerifierGenerator;
}
public BigInteger GenerateVerifier(byte[] salt, byte[] identity, byte[] password)
{
return m_srp6VerifierGenerator.GenerateVerifier(salt, identity, password);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7b8f68e434e3a3142977e4da775abc98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
internal sealed class BcTlsStreamSigner
: TlsStreamSigner
{
private readonly SignerSink m_output;
internal BcTlsStreamSigner(ISigner signer)
{
this.m_output = new SignerSink(signer);
}
public Stream Stream
{
get { return m_output; }
}
public byte[] GetSignature()
{
try
{
return m_output.Signer.GenerateSignature();
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.internal_error, e);
}
}
}
}
#pragma warning restore
#endif

Some files were not shown because too many files have changed in this diff Show More