mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-12-31 11:08:09 +00:00
提交Unity 联机Pro
This commit is contained in:
@@ -0,0 +1,488 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Base class for a TLS client.</summary>
|
||||
public abstract class AbstractTlsClient
|
||||
: AbstractTlsPeer, TlsClient
|
||||
{
|
||||
protected TlsClientContext m_context;
|
||||
protected ProtocolVersion[] m_protocolVersions;
|
||||
protected int[] m_cipherSuites;
|
||||
|
||||
protected IList<int> m_supportedGroups;
|
||||
protected IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithms;
|
||||
protected IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithmsCert;
|
||||
|
||||
protected AbstractTlsClient(TlsCrypto crypto)
|
||||
: base(crypto)
|
||||
{
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
protected virtual bool AllowUnexpectedServerExtension(int extensionType, byte[] extensionData)
|
||||
{
|
||||
switch (extensionType)
|
||||
{
|
||||
case ExtensionType.supported_groups:
|
||||
/*
|
||||
* Exception added based on field reports that some servers do send this, although the
|
||||
* Supported Elliptic Curves Extension is clearly intended to be client-only. If
|
||||
* present, we still require that it is a valid EllipticCurveList.
|
||||
*/
|
||||
TlsExtensionsUtilities.ReadSupportedGroupsExtension(extensionData);
|
||||
return true;
|
||||
|
||||
case ExtensionType.ec_point_formats:
|
||||
/*
|
||||
* Exception added based on field reports that some servers send this even when they
|
||||
* didn't negotiate an ECC cipher suite. If present, we still require that it is a valid
|
||||
* ECPointFormatList.
|
||||
*/
|
||||
TlsExtensionsUtilities.ReadSupportedPointFormatsExtension(extensionData);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IList<int> GetNamedGroupRoles()
|
||||
{
|
||||
var namedGroupRoles = TlsUtilities.GetNamedGroupRoles(GetCipherSuites());
|
||||
var sigAlgs = m_supportedSignatureAlgorithms;
|
||||
var sigAlgsCert = m_supportedSignatureAlgorithmsCert;
|
||||
|
||||
if ((null == sigAlgs || TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgs, SignatureAlgorithm.ecdsa)) ||
|
||||
(null != sigAlgsCert && TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgsCert, SignatureAlgorithm.ecdsa)))
|
||||
{
|
||||
TlsUtilities.AddToSet(namedGroupRoles, NamedGroupRole.ecdsa);
|
||||
}
|
||||
|
||||
return namedGroupRoles;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
protected virtual void CheckForUnexpectedServerExtension(IDictionary<int, byte[]> serverExtensions,
|
||||
int extensionType)
|
||||
{
|
||||
byte[] extensionData = TlsUtilities.GetExtensionData(serverExtensions, extensionType);
|
||||
if (extensionData != null && !AllowUnexpectedServerExtension(extensionType, extensionData))
|
||||
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual TlsPskIdentity GetPskIdentity()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual TlsSrpIdentity GetSrpIdentity()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual TlsDHGroupVerifier GetDHGroupVerifier()
|
||||
{
|
||||
return new DefaultTlsDHGroupVerifier();
|
||||
}
|
||||
|
||||
public virtual TlsSrpConfigVerifier GetSrpConfigVerifier()
|
||||
{
|
||||
return new DefaultTlsSrpConfigVerifier();
|
||||
}
|
||||
|
||||
protected virtual IList<X509Name> GetCertificateAuthorities()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual IList<ProtocolName> GetProtocolNames()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual CertificateStatusRequest GetCertificateStatusRequest()
|
||||
{
|
||||
return new CertificateStatusRequest(CertificateStatusType.ocsp, new OcspStatusRequest(null, null));
|
||||
}
|
||||
|
||||
/// <returns>an <see cref="IList{T}"/> of <see cref="CertificateStatusRequestItemV2"/> (or null).</returns>
|
||||
protected virtual IList<CertificateStatusRequestItemV2> GetMultiCertStatusRequest()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual IList<ServerName> GetSniServerNames()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>The default <see cref="GetClientExtensions"/> implementation calls this to determine which named
|
||||
/// groups to include in the supported_groups extension for the ClientHello.</summary>
|
||||
/// <param name="namedGroupRoles">The <see cref="NamedGroupRole">named group roles</see> for which there should
|
||||
/// be at least one supported group. By default this is inferred from the offered cipher suites and signature
|
||||
/// algorithms.</param>
|
||||
/// <returns>an <see cref="IList{T}"/> of <see cref="Int32"/>. See <see cref="NamedGroup"/> for group constants.
|
||||
/// </returns>
|
||||
protected virtual IList<int> GetSupportedGroups(IList<int> namedGroupRoles)
|
||||
{
|
||||
TlsCrypto crypto = Crypto;
|
||||
var supportedGroups = new List<int>();
|
||||
|
||||
if (namedGroupRoles.Contains(NamedGroupRole.ecdh))
|
||||
{
|
||||
TlsUtilities.AddIfSupported(supportedGroups, crypto,
|
||||
new int[]{ NamedGroup.x25519, NamedGroup.x448 });
|
||||
}
|
||||
|
||||
if (namedGroupRoles.Contains(NamedGroupRole.ecdh) ||
|
||||
namedGroupRoles.Contains(NamedGroupRole.ecdsa))
|
||||
{
|
||||
TlsUtilities.AddIfSupported(supportedGroups, crypto,
|
||||
new int[]{ NamedGroup.secp256r1, NamedGroup.secp384r1 });
|
||||
}
|
||||
|
||||
if (namedGroupRoles.Contains(NamedGroupRole.dh))
|
||||
{
|
||||
TlsUtilities.AddIfSupported(supportedGroups, crypto,
|
||||
new int[]{ NamedGroup.ffdhe2048, NamedGroup.ffdhe3072, NamedGroup.ffdhe4096 });
|
||||
}
|
||||
|
||||
return supportedGroups;
|
||||
}
|
||||
|
||||
protected virtual IList<SignatureAndHashAlgorithm> GetSupportedSignatureAlgorithms()
|
||||
{
|
||||
return TlsUtilities.GetDefaultSupportedSignatureAlgorithms(m_context);
|
||||
}
|
||||
|
||||
protected virtual IList<SignatureAndHashAlgorithm> GetSupportedSignatureAlgorithmsCert()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual IList<TrustedAuthority> GetTrustedCAIndication()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual short[] GetAllowedClientCertificateTypes()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual short[] GetAllowedServerCertificateTypes()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void Init(TlsClientContext context)
|
||||
{
|
||||
this.m_context = context;
|
||||
|
||||
this.m_protocolVersions = GetSupportedVersions();
|
||||
this.m_cipherSuites = GetSupportedCipherSuites();
|
||||
}
|
||||
|
||||
public override ProtocolVersion[] GetProtocolVersions()
|
||||
{
|
||||
return m_protocolVersions;
|
||||
}
|
||||
|
||||
public override int[] GetCipherSuites()
|
||||
{
|
||||
return m_cipherSuites;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public override void NotifyHandshakeBeginning()
|
||||
{
|
||||
base.NotifyHandshakeBeginning();
|
||||
|
||||
this.m_supportedGroups = null;
|
||||
this.m_supportedSignatureAlgorithms = null;
|
||||
this.m_supportedSignatureAlgorithmsCert = null;
|
||||
}
|
||||
|
||||
public virtual TlsSession GetSessionToResume()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual IList<TlsPskExternal> GetExternalPsks()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool IsFallback()
|
||||
{
|
||||
/*
|
||||
* RFC 7507 4. The TLS_FALLBACK_SCSV cipher suite value is meant for use by clients that
|
||||
* repeat a connection attempt with a downgraded protocol (perform a "fallback retry") in
|
||||
* order to work around interoperability problems with legacy servers.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual IDictionary<int, byte[]> GetClientExtensions()
|
||||
{
|
||||
var clientExtensions = new Dictionary<int, byte[]>();
|
||||
|
||||
bool offeringTlsV13Plus = false;
|
||||
bool offeringPreTlsV13 = false;
|
||||
{
|
||||
ProtocolVersion[] supportedVersions = GetProtocolVersions();
|
||||
for (int i = 0; i < supportedVersions.Length; ++i)
|
||||
{
|
||||
if (TlsUtilities.IsTlsV13(supportedVersions[i]))
|
||||
{
|
||||
offeringTlsV13Plus = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
offeringPreTlsV13 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var protocolNames = GetProtocolNames();
|
||||
if (protocolNames != null)
|
||||
{
|
||||
TlsExtensionsUtilities.AddAlpnExtensionClient(clientExtensions, protocolNames);
|
||||
}
|
||||
|
||||
var sniServerNames = GetSniServerNames();
|
||||
if (sniServerNames != null)
|
||||
{
|
||||
TlsExtensionsUtilities.AddServerNameExtensionClient(clientExtensions, sniServerNames);
|
||||
}
|
||||
|
||||
CertificateStatusRequest statusRequest = GetCertificateStatusRequest();
|
||||
if (statusRequest != null)
|
||||
{
|
||||
TlsExtensionsUtilities.AddStatusRequestExtension(clientExtensions, statusRequest);
|
||||
}
|
||||
|
||||
if (offeringTlsV13Plus)
|
||||
{
|
||||
var certificateAuthorities = GetCertificateAuthorities();
|
||||
if (certificateAuthorities != null)
|
||||
{
|
||||
TlsExtensionsUtilities.AddCertificateAuthoritiesExtension(clientExtensions, certificateAuthorities);
|
||||
}
|
||||
}
|
||||
|
||||
if (offeringPreTlsV13)
|
||||
{
|
||||
// TODO Shouldn't add if no offered cipher suite uses a block cipher?
|
||||
TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions);
|
||||
|
||||
var statusRequestV2 = GetMultiCertStatusRequest();
|
||||
if (statusRequestV2 != null)
|
||||
{
|
||||
TlsExtensionsUtilities.AddStatusRequestV2Extension(clientExtensions, statusRequestV2);
|
||||
}
|
||||
|
||||
var trustedCAKeys = GetTrustedCAIndication();
|
||||
if (trustedCAKeys != null)
|
||||
{
|
||||
TlsExtensionsUtilities.AddTrustedCAKeysExtensionClient(clientExtensions, trustedCAKeys);
|
||||
}
|
||||
}
|
||||
|
||||
ProtocolVersion clientVersion = m_context.ClientVersion;
|
||||
|
||||
/*
|
||||
* RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior to 1.2.
|
||||
* Clients MUST NOT offer it if they are offering prior versions.
|
||||
*/
|
||||
if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion))
|
||||
{
|
||||
var supportedSigAlgs = GetSupportedSignatureAlgorithms();
|
||||
if (null != supportedSigAlgs && supportedSigAlgs.Count > 0)
|
||||
{
|
||||
this.m_supportedSignatureAlgorithms = supportedSigAlgs;
|
||||
|
||||
TlsExtensionsUtilities.AddSignatureAlgorithmsExtension(clientExtensions, supportedSigAlgs);
|
||||
}
|
||||
|
||||
var supportedSigAlgsCert = GetSupportedSignatureAlgorithmsCert();
|
||||
if (null != supportedSigAlgsCert && supportedSigAlgsCert.Count > 0)
|
||||
{
|
||||
this.m_supportedSignatureAlgorithmsCert = supportedSigAlgsCert;
|
||||
|
||||
TlsExtensionsUtilities.AddSignatureAlgorithmsCertExtension(clientExtensions, supportedSigAlgsCert);
|
||||
}
|
||||
}
|
||||
|
||||
var namedGroupRoles = GetNamedGroupRoles();
|
||||
|
||||
var supportedGroups = GetSupportedGroups(namedGroupRoles);
|
||||
if (supportedGroups != null && supportedGroups.Count > 0)
|
||||
{
|
||||
this.m_supportedGroups = supportedGroups;
|
||||
|
||||
TlsExtensionsUtilities.AddSupportedGroupsExtension(clientExtensions, supportedGroups);
|
||||
}
|
||||
|
||||
if (offeringPreTlsV13)
|
||||
{
|
||||
if (namedGroupRoles.Contains(NamedGroupRole.ecdh) ||
|
||||
namedGroupRoles.Contains(NamedGroupRole.ecdsa))
|
||||
{
|
||||
TlsExtensionsUtilities.AddSupportedPointFormatsExtension(clientExtensions,
|
||||
new short[]{ ECPointFormat.uncompressed });
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 7250 4.1:
|
||||
*
|
||||
* If the client has no remaining certificate types to send in
|
||||
* the client hello, other than the default X.509 type, it MUST omit the
|
||||
* client_certificate_type extension in the client hello.
|
||||
*/
|
||||
short[] clientCertTypes = GetAllowedClientCertificateTypes();
|
||||
if (clientCertTypes != null && (clientCertTypes.Length > 1 || clientCertTypes[0] != CertificateType.X509))
|
||||
{
|
||||
TlsExtensionsUtilities.AddClientCertificateTypeExtensionClient(clientExtensions, clientCertTypes);
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 7250 4.1:
|
||||
*
|
||||
* If the client has no remaining certificate types to send in
|
||||
* the client hello, other than the default X.509 certificate type, it
|
||||
* MUST omit the entire server_certificate_type extension from the
|
||||
* client hello.
|
||||
*/
|
||||
short[] serverCertTypes = GetAllowedServerCertificateTypes();
|
||||
if (serverCertTypes != null && (serverCertTypes.Length > 1 || serverCertTypes[0] != CertificateType.X509))
|
||||
{
|
||||
TlsExtensionsUtilities.AddServerCertificateTypeExtensionClient(clientExtensions, serverCertTypes);
|
||||
}
|
||||
|
||||
return clientExtensions;
|
||||
}
|
||||
|
||||
public virtual IList<int> GetEarlyKeyShareGroups()
|
||||
{
|
||||
/*
|
||||
* RFC 8446 4.2.8. Each KeyShareEntry value MUST correspond to a group offered in the
|
||||
* "supported_groups" extension and MUST appear in the same order. However, the values MAY
|
||||
* be a non-contiguous subset of the "supported_groups" extension and MAY omit the most
|
||||
* preferred groups.
|
||||
*/
|
||||
|
||||
if (null == m_supportedGroups || m_supportedGroups.Count < 1)
|
||||
return null;
|
||||
|
||||
if (m_supportedGroups.Contains(NamedGroup.x25519))
|
||||
return TlsUtilities.VectorOfOne(NamedGroup.x25519);
|
||||
|
||||
if (m_supportedGroups.Contains(NamedGroup.secp256r1))
|
||||
return TlsUtilities.VectorOfOne(NamedGroup.secp256r1);
|
||||
|
||||
return TlsUtilities.VectorOfOne(m_supportedGroups[0]);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void NotifyServerVersion(ProtocolVersion serverVersion)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void NotifySessionToResume(TlsSession session)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void NotifySessionID(byte[] sessionID)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void NotifySelectedCipherSuite(int selectedCipherSuite)
|
||||
{
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void NotifySelectedPsk(TlsPsk selectedPsk)
|
||||
{
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void ProcessServerExtensions(IDictionary<int, byte[]> serverExtensions)
|
||||
{
|
||||
if (null == serverExtensions)
|
||||
return;
|
||||
|
||||
SecurityParameters securityParameters = m_context.SecurityParameters;
|
||||
bool isTlsV13 = TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion);
|
||||
|
||||
if (isTlsV13)
|
||||
{
|
||||
/*
|
||||
* NOTE: From TLS 1.3 the protocol classes are strict about what extensions can appear.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension.
|
||||
*/
|
||||
CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms);
|
||||
CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms_cert);
|
||||
|
||||
CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.supported_groups);
|
||||
|
||||
int selectedCipherSuite = securityParameters.CipherSuite;
|
||||
|
||||
if (TlsEccUtilities.IsEccCipherSuite(selectedCipherSuite))
|
||||
{
|
||||
// We only support uncompressed format, this is just to validate the extension, if present.
|
||||
TlsExtensionsUtilities.GetSupportedPointFormatsExtension(serverExtensions);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.ec_point_formats);
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 7685 3. The server MUST NOT echo the extension.
|
||||
*/
|
||||
CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.padding);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void ProcessServerSupplementalData(IList<SupplementalDataEntry> serverSupplementalData)
|
||||
{
|
||||
if (serverSupplementalData != null)
|
||||
throw new TlsFatalAlert(AlertDescription.unexpected_message);
|
||||
}
|
||||
|
||||
public abstract TlsAuthentication GetAuthentication();
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual IList<SupplementalDataEntry> GetClientSupplementalData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void NotifyNewSessionTicket(NewSessionTicket newSessionTicket)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8227cded6e5a6ec40ae81fd1d77da86c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,316 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
internal abstract class AbstractTlsContext
|
||||
: TlsContext
|
||||
{
|
||||
private static long counter = DateTime.UtcNow.Ticks;
|
||||
|
||||
private static long NextCounterValue()
|
||||
{
|
||||
return Interlocked.Increment(ref counter);
|
||||
}
|
||||
|
||||
private static TlsNonceGenerator CreateNonceGenerator(TlsCrypto crypto, int connectionEnd)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
Span<byte> additionalSeedMaterial = stackalloc byte[16];
|
||||
Pack.UInt64_To_BE((ulong)NextCounterValue(), additionalSeedMaterial);
|
||||
Pack.UInt64_To_BE((ulong)DateTime.UtcNow.Ticks, additionalSeedMaterial[8..]);
|
||||
#else
|
||||
byte[] additionalSeedMaterial = new byte[16];
|
||||
Pack.UInt64_To_BE((ulong)NextCounterValue(), additionalSeedMaterial, 0);
|
||||
Pack.UInt64_To_BE((ulong)DateTime.UtcNow.Ticks, additionalSeedMaterial, 8);
|
||||
#endif
|
||||
additionalSeedMaterial[0] &= 0x7F;
|
||||
additionalSeedMaterial[0] |= (byte)(connectionEnd << 7);
|
||||
|
||||
return crypto.CreateNonceGenerator(additionalSeedMaterial);
|
||||
}
|
||||
|
||||
private readonly TlsCrypto m_crypto;
|
||||
private readonly int m_connectionEnd;
|
||||
private readonly TlsNonceGenerator m_nonceGenerator;
|
||||
|
||||
private SecurityParameters m_securityParameters = null;
|
||||
private ProtocolVersion[] m_clientSupportedVersions = null;
|
||||
private ProtocolVersion m_clientVersion = null;
|
||||
private ProtocolVersion m_rsaPreMasterSecretVersion = null;
|
||||
private TlsSession m_session = null;
|
||||
private object m_userObject = null;
|
||||
private bool m_connected = false;
|
||||
|
||||
internal AbstractTlsContext(TlsCrypto crypto, int connectionEnd)
|
||||
{
|
||||
this.m_crypto = crypto;
|
||||
this.m_connectionEnd = connectionEnd;
|
||||
this.m_nonceGenerator = CreateNonceGenerator(crypto, connectionEnd);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
internal void HandshakeBeginning(TlsPeer peer)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
//if (null != m_securityParameters)
|
||||
// throw new TlsFatalAlert(AlertDescription.internal_error, "Handshake already started");
|
||||
|
||||
var tmp = this.m_securityParameters;
|
||||
|
||||
m_securityParameters = new SecurityParameters();
|
||||
m_securityParameters.m_entity = m_connectionEnd;
|
||||
|
||||
if (tmp != null)
|
||||
{
|
||||
this.m_securityParameters.IsRenegotiating = true;
|
||||
this.m_securityParameters.m_secureRenegotiation = tmp.m_secureRenegotiation;
|
||||
this.m_securityParameters.m_negotiatedVersion = tmp.m_negotiatedVersion;
|
||||
|
||||
this.m_securityParameters.m_localVerifyData = tmp.m_localVerifyData;
|
||||
this.m_securityParameters.m_peerVerifyData = tmp.m_peerVerifyData;
|
||||
this.m_securityParameters.PreRenegotiatingServerCert = tmp.m_peerCertificate;
|
||||
}
|
||||
}
|
||||
|
||||
peer.NotifyHandshakeBeginning();
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
internal void HandshakeComplete(TlsPeer peer, TlsSession session)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (null == m_securityParameters)
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
|
||||
this.m_session = session;
|
||||
this.m_connected = true;
|
||||
}
|
||||
|
||||
peer.NotifyHandshakeComplete();
|
||||
}
|
||||
|
||||
internal bool IsConnected
|
||||
{
|
||||
get { lock (this) return m_connected; }
|
||||
}
|
||||
|
||||
internal bool IsHandshaking
|
||||
{
|
||||
get { lock (this) return !m_connected && null != m_securityParameters; }
|
||||
}
|
||||
|
||||
public TlsCrypto Crypto
|
||||
{
|
||||
get { return m_crypto; }
|
||||
}
|
||||
|
||||
public virtual TlsNonceGenerator NonceGenerator
|
||||
{
|
||||
get { return m_nonceGenerator; }
|
||||
}
|
||||
|
||||
public SecurityParameters SecurityParameters
|
||||
{
|
||||
get { lock (this) return m_securityParameters; }
|
||||
}
|
||||
|
||||
public abstract bool IsServer { get; }
|
||||
|
||||
public virtual ProtocolVersion[] ClientSupportedVersions
|
||||
{
|
||||
get { return m_clientSupportedVersions; }
|
||||
}
|
||||
|
||||
internal void SetClientSupportedVersions(ProtocolVersion[] clientSupportedVersions)
|
||||
{
|
||||
this.m_clientSupportedVersions = clientSupportedVersions;
|
||||
}
|
||||
|
||||
public virtual ProtocolVersion ClientVersion
|
||||
{
|
||||
get { return m_clientVersion; }
|
||||
}
|
||||
|
||||
internal void SetClientVersion(ProtocolVersion clientVersion)
|
||||
{
|
||||
this.m_clientVersion = clientVersion;
|
||||
}
|
||||
|
||||
public virtual ProtocolVersion RsaPreMasterSecretVersion
|
||||
{
|
||||
get { return m_rsaPreMasterSecretVersion; }
|
||||
}
|
||||
|
||||
internal void SetRsaPreMasterSecretVersion(ProtocolVersion rsaPreMasterSecretVersion)
|
||||
{
|
||||
this.m_rsaPreMasterSecretVersion = rsaPreMasterSecretVersion;
|
||||
}
|
||||
|
||||
public virtual ProtocolVersion ServerVersion
|
||||
{
|
||||
get { return SecurityParameters.NegotiatedVersion; }
|
||||
}
|
||||
|
||||
public virtual TlsSession ResumableSession
|
||||
{
|
||||
get
|
||||
{
|
||||
TlsSession session = Session;
|
||||
if (session == null || !session.IsResumable)
|
||||
return null;
|
||||
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual TlsSession Session
|
||||
{
|
||||
get { return m_session; }
|
||||
}
|
||||
|
||||
public virtual object UserObject
|
||||
{
|
||||
get { return m_userObject; }
|
||||
set { this.m_userObject = value; }
|
||||
}
|
||||
|
||||
public virtual byte[] ExportChannelBinding(int channelBinding)
|
||||
{
|
||||
if (!IsConnected)
|
||||
throw new InvalidOperationException("Export of channel bindings unavailable before handshake completion");
|
||||
|
||||
SecurityParameters securityParameters = SecurityParameters;
|
||||
|
||||
if (ChannelBinding.tls_exporter == channelBinding)
|
||||
return ExportKeyingMaterial("EXPORTER-Channel-Binding", TlsUtilities.EmptyBytes, 32);
|
||||
|
||||
if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion))
|
||||
return null;
|
||||
|
||||
switch (channelBinding)
|
||||
{
|
||||
case ChannelBinding.tls_server_end_point:
|
||||
{
|
||||
byte[] tlsServerEndPoint = securityParameters.TlsServerEndPoint;
|
||||
|
||||
return TlsUtilities.IsNullOrEmpty(tlsServerEndPoint) ? null : Arrays.Clone(tlsServerEndPoint);
|
||||
}
|
||||
|
||||
case ChannelBinding.tls_unique:
|
||||
{
|
||||
return Arrays.Clone(securityParameters.TlsUnique);
|
||||
}
|
||||
|
||||
case ChannelBinding.tls_unique_for_telnet:
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] ExportEarlyKeyingMaterial(string asciiLabel, byte[] context, int length)
|
||||
{
|
||||
// TODO[tls13] Ensure early_exporter_master_secret is available suitably early!
|
||||
if (!IsConnected)
|
||||
throw new InvalidOperationException("Export of early key material only available during handshake");
|
||||
|
||||
SecurityParameters sp = SecurityParameters;
|
||||
|
||||
return ExportKeyingMaterial13(CheckEarlyExportSecret(sp.EarlyExporterMasterSecret),
|
||||
sp.PrfCryptoHashAlgorithm, asciiLabel, context, length);
|
||||
}
|
||||
|
||||
public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context, int length)
|
||||
{
|
||||
if (!IsConnected)
|
||||
throw new InvalidOperationException("Export of key material unavailable before handshake completion");
|
||||
|
||||
/*
|
||||
* TODO[tls13] Introduce a TlsExporter interface? Avoid calculating (early) exporter
|
||||
* secret(s) unless the peer actually uses it.
|
||||
*/
|
||||
SecurityParameters sp = SecurityParameters;
|
||||
|
||||
if (!sp.IsExtendedMasterSecret)
|
||||
{
|
||||
/*
|
||||
* RFC 7627 5.4. If a client or server chooses to continue with a full handshake without
|
||||
* the extended master secret extension, [..] the client or server MUST NOT export any
|
||||
* key material based on the new master secret for any subsequent application-level
|
||||
* authentication. In particular, it MUST disable [RFC5705] [..].
|
||||
*/
|
||||
throw new InvalidOperationException("Export of key material requires extended_master_secret");
|
||||
}
|
||||
|
||||
if (TlsUtilities.IsTlsV13(sp.NegotiatedVersion))
|
||||
{
|
||||
return ExportKeyingMaterial13(CheckExportSecret(sp.ExporterMasterSecret), sp.PrfCryptoHashAlgorithm,
|
||||
asciiLabel, context, length);
|
||||
}
|
||||
|
||||
byte[] seed = TlsUtilities.CalculateExporterSeed(sp, context);
|
||||
|
||||
return TlsUtilities.Prf(sp, CheckExportSecret(sp.MasterSecret), asciiLabel, seed, length).Extract();
|
||||
}
|
||||
|
||||
protected virtual byte[] ExportKeyingMaterial13(TlsSecret secret, int cryptoHashAlgorithm, string asciiLabel,
|
||||
byte[] context, int length)
|
||||
{
|
||||
if (null == context)
|
||||
{
|
||||
context = TlsUtilities.EmptyBytes;
|
||||
}
|
||||
else if (!TlsUtilities.IsValidUint16(context.Length))
|
||||
{
|
||||
throw new ArgumentException("must have length less than 2^16 (or be null)", "context");
|
||||
}
|
||||
|
||||
TlsHash exporterHash = Crypto.CreateHash(cryptoHashAlgorithm);
|
||||
byte[] emptyTranscriptHash = exporterHash.CalculateHash();
|
||||
|
||||
TlsSecret exporterSecret = TlsUtilities.DeriveSecret(SecurityParameters, secret, asciiLabel,
|
||||
emptyTranscriptHash);
|
||||
|
||||
byte[] exporterContext = emptyTranscriptHash;
|
||||
if (context.Length > 0)
|
||||
{
|
||||
exporterHash.Update(context, 0, context.Length);
|
||||
exporterContext = exporterHash.CalculateHash();
|
||||
}
|
||||
|
||||
return TlsCryptoUtilities
|
||||
.HkdfExpandLabel(exporterSecret, cryptoHashAlgorithm, "exporter", exporterContext, length).Extract();
|
||||
}
|
||||
|
||||
protected virtual TlsSecret CheckEarlyExportSecret(TlsSecret secret)
|
||||
{
|
||||
if (null == secret)
|
||||
{
|
||||
// TODO[tls13] For symmetry with normal export, ideally available for NotifyHandshakeBeginning() only
|
||||
//throw new InvalidOperationException("Export of early key material only available from NotifyHandshakeBeginning()");
|
||||
throw new InvalidOperationException("Export of early key material not available for this handshake");
|
||||
}
|
||||
return secret;
|
||||
}
|
||||
|
||||
protected virtual TlsSecret CheckExportSecret(TlsSecret secret)
|
||||
{
|
||||
if (null == secret)
|
||||
throw new InvalidOperationException(
|
||||
"Export of key material only available from NotifyHandshakeComplete()");
|
||||
|
||||
return secret;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a0e723f741842149a56a0c867090f42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,94 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Base class for supporting a TLS key exchange implementation.</summary>
|
||||
public abstract class AbstractTlsKeyExchange
|
||||
: TlsKeyExchange
|
||||
{
|
||||
protected readonly int m_keyExchange;
|
||||
|
||||
protected TlsContext m_context;
|
||||
|
||||
protected AbstractTlsKeyExchange(int keyExchange)
|
||||
{
|
||||
this.m_keyExchange = keyExchange;
|
||||
}
|
||||
|
||||
public virtual void Init(TlsContext context)
|
||||
{
|
||||
this.m_context = context;
|
||||
}
|
||||
|
||||
public abstract void SkipServerCredentials();
|
||||
|
||||
public abstract void ProcessServerCredentials(TlsCredentials serverCredentials);
|
||||
|
||||
public virtual void ProcessServerCertificate(Certificate serverCertificate)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual bool RequiresServerKeyExchange
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public virtual byte[] GenerateServerKeyExchange()
|
||||
{
|
||||
if (RequiresServerKeyExchange)
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void SkipServerKeyExchange()
|
||||
{
|
||||
if (RequiresServerKeyExchange)
|
||||
throw new TlsFatalAlert(AlertDescription.unexpected_message);
|
||||
}
|
||||
|
||||
public virtual void ProcessServerKeyExchange(Stream input)
|
||||
{
|
||||
if (!RequiresServerKeyExchange)
|
||||
throw new TlsFatalAlert(AlertDescription.unexpected_message);
|
||||
}
|
||||
|
||||
public virtual short[] GetClientCertificateTypes()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void SkipClientCredentials()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract void ProcessClientCredentials(TlsCredentials clientCredentials);
|
||||
|
||||
public virtual void ProcessClientCertificate(Certificate clientCertificate)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract void GenerateClientKeyExchange(Stream output);
|
||||
|
||||
public virtual void ProcessClientKeyExchange(Stream input)
|
||||
{
|
||||
// Key exchange implementation MUST support client key exchange
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual bool RequiresCertificateVerify
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public abstract TlsSecret GeneratePreMasterSecret();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71e571fbcdb3bc54eaebe0f3bcd8efa4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,94 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Base class for supporting a TLS key exchange factory implementation.</summary>
|
||||
public abstract class AbstractTlsKeyExchangeFactory
|
||||
: TlsKeyExchangeFactory
|
||||
{
|
||||
public virtual TlsKeyExchange CreateDHKeyExchange(int keyExchange)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateDHanonKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateDHanonKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateDheKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateDheKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateECDHanonKeyExchangeClient(int keyExchange)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateECDHanonKeyExchangeServer(int keyExchange, TlsECConfig ecConfig)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateECDheKeyExchangeClient(int keyExchange)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateECDheKeyExchangeServer(int keyExchange, TlsECConfig ecConfig)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreatePskKeyExchangeClient(int keyExchange, TlsPskIdentity pskIdentity,
|
||||
TlsDHGroupVerifier dhGroupVerifier)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreatePskKeyExchangeServer(int keyExchange,
|
||||
TlsPskIdentityManager pskIdentityManager, TlsDHConfig dhConfig, TlsECConfig ecConfig)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateRsaKeyExchange(int keyExchange)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateSrpKeyExchangeClient(int keyExchange, TlsSrpIdentity srpIdentity,
|
||||
TlsSrpConfigVerifier srpConfigVerifier)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual TlsKeyExchange CreateSrpKeyExchangeServer(int keyExchange,
|
||||
TlsSrpLoginParameters loginParameters)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a9336eaeaae34d40ace755bb025ac9d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,167 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Base class for a TLS client or server.</summary>
|
||||
public abstract class AbstractTlsPeer
|
||||
: TlsPeer
|
||||
{
|
||||
private readonly TlsCrypto m_crypto;
|
||||
|
||||
private volatile TlsCloseable m_closeHandle;
|
||||
|
||||
protected AbstractTlsPeer(TlsCrypto crypto)
|
||||
{
|
||||
this.m_crypto = crypto;
|
||||
}
|
||||
|
||||
/// <summary>Get the <see cref="ProtocolVersion"/> values that are supported by this peer.</summary>
|
||||
/// <remarks>
|
||||
/// WARNING: Mixing DTLS and TLS versions in the returned array is currently NOT supported. Use a separate
|
||||
/// (sub-)class for each case.
|
||||
/// </remarks>
|
||||
/// <returns>an array of supported <see cref="ProtocolVersion"/> values.</returns>
|
||||
protected virtual ProtocolVersion[] GetSupportedVersions()
|
||||
{
|
||||
return ProtocolVersion.TLSv13.DownTo(ProtocolVersion.TLSv12);
|
||||
}
|
||||
|
||||
protected abstract int[] GetSupportedCipherSuites();
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void Cancel()
|
||||
{
|
||||
TlsCloseable closeHandle = this.m_closeHandle;
|
||||
if (null != closeHandle)
|
||||
{
|
||||
closeHandle.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual TlsCrypto Crypto
|
||||
{
|
||||
get { return m_crypto; }
|
||||
}
|
||||
|
||||
public virtual void NotifyCloseHandle(TlsCloseable closeHandle)
|
||||
{
|
||||
this.m_closeHandle = closeHandle;
|
||||
}
|
||||
|
||||
public abstract ProtocolVersion[] GetProtocolVersions();
|
||||
|
||||
public abstract int[] GetCipherSuites();
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void NotifyHandshakeBeginning()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int GetHandshakeTimeoutMillis()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual bool AllowLegacyResumption()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual int GetMaxCertificateChainLength()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
public virtual int GetMaxHandshakeMessageSize()
|
||||
{
|
||||
return 32768;
|
||||
}
|
||||
|
||||
public virtual short[] GetPskKeyExchangeModes()
|
||||
{
|
||||
return new short[]{ PskKeyExchangeMode.psk_dhe_ke };
|
||||
}
|
||||
|
||||
public virtual bool RequiresCloseNotify()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool RequiresExtendedMasterSecret()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool ShouldCheckSigAlgOfPeerCerts()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool ShouldUseExtendedMasterSecret()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool ShouldUseExtendedPadding()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool ShouldUseGmtUnixTime()
|
||||
{
|
||||
/*
|
||||
* draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that
|
||||
* TLS implementors MUST by default set the entire value the ClientHello.Random and
|
||||
* ServerHello.Random fields, including gmt_unix_time, to a cryptographically random
|
||||
* sequence.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void NotifySecureRenegotiation(bool secureRenegotiation)
|
||||
{
|
||||
if (!secureRenegotiation)
|
||||
throw new TlsFatalAlert(AlertDescription.handshake_failure);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual TlsKeyExchangeFactory GetKeyExchangeFactory()
|
||||
{
|
||||
return new DefaultTlsKeyExchangeFactory();
|
||||
}
|
||||
|
||||
public virtual void NotifyAlertRaised(short alertLevel, short alertDescription, string message,
|
||||
Exception cause)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void NotifyAlertReceived(short alertLevel, short alertDescription)
|
||||
{
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public virtual void NotifyHandshakeComplete()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual TlsHeartbeat GetHeartbeat()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual short GetHeartbeatPolicy()
|
||||
{
|
||||
return HeartbeatMode.peer_not_allowed_to_send;
|
||||
}
|
||||
|
||||
public virtual bool IgnoreCorruptDtlsRecords => false;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98cb4dd632ab72f48a86a5fb31571547
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,658 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Base class for a TLS server.</summary>
|
||||
public abstract class AbstractTlsServer
|
||||
: AbstractTlsPeer, TlsServer
|
||||
{
|
||||
protected TlsServerContext m_context;
|
||||
protected ProtocolVersion[] m_protocolVersions;
|
||||
protected int[] m_cipherSuites;
|
||||
|
||||
protected int[] m_offeredCipherSuites;
|
||||
protected IDictionary<int, byte[]> m_clientExtensions;
|
||||
|
||||
protected bool m_encryptThenMACOffered;
|
||||
protected short m_maxFragmentLengthOffered;
|
||||
protected bool m_truncatedHMacOffered;
|
||||
protected bool m_clientSentECPointFormats;
|
||||
protected CertificateStatusRequest m_certificateStatusRequest;
|
||||
protected IList<CertificateStatusRequestItemV2> m_statusRequestV2;
|
||||
protected IList<TrustedAuthority> m_trustedCAKeys;
|
||||
|
||||
protected int m_selectedCipherSuite;
|
||||
protected IList<ProtocolName> m_clientProtocolNames;
|
||||
protected ProtocolName m_selectedProtocolName;
|
||||
|
||||
protected readonly IDictionary<int, byte[]> m_serverExtensions = new Dictionary<int, byte[]>();
|
||||
|
||||
public AbstractTlsServer(TlsCrypto crypto)
|
||||
: base(crypto)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual bool AllowCertificateStatus()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool AllowEncryptThenMac()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool AllowMultiCertStatus()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool AllowTruncatedHmac()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool AllowTrustedCAIndication()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual int GetMaximumNegotiableCurveBits()
|
||||
{
|
||||
int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups;
|
||||
if (clientSupportedGroups == null)
|
||||
{
|
||||
/*
|
||||
* RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these
|
||||
* extensions. In this case, the server is free to choose any one of the elliptic curves
|
||||
* or point formats [...].
|
||||
*/
|
||||
return NamedGroup.GetMaximumCurveBits();
|
||||
}
|
||||
|
||||
int maxBits = 0;
|
||||
for (int i = 0; i < clientSupportedGroups.Length; ++i)
|
||||
{
|
||||
maxBits = System.Math.Max(maxBits, NamedGroup.GetCurveBits(clientSupportedGroups[i]));
|
||||
}
|
||||
return maxBits;
|
||||
}
|
||||
|
||||
protected virtual int GetMaximumNegotiableFiniteFieldBits()
|
||||
{
|
||||
int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups;
|
||||
if (clientSupportedGroups == null)
|
||||
{
|
||||
return NamedGroup.GetMaximumFiniteFieldBits();
|
||||
}
|
||||
|
||||
int maxBits = 0;
|
||||
for (int i = 0; i < clientSupportedGroups.Length; ++i)
|
||||
{
|
||||
maxBits = System.Math.Max(maxBits, NamedGroup.GetFiniteFieldBits(clientSupportedGroups[i]));
|
||||
}
|
||||
return maxBits;
|
||||
}
|
||||
|
||||
protected virtual IList<ProtocolName> GetProtocolNames()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual bool IsSelectableCipherSuite(int cipherSuite, int availCurveBits, int availFiniteFieldBits,
|
||||
IList<short> sigAlgs)
|
||||
{
|
||||
// TODO[tls13] The version check should be separated out (eventually select ciphersuite before version)
|
||||
return TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, m_context.ServerVersion)
|
||||
&& availCurveBits >= TlsEccUtilities.GetMinimumCurveBits(cipherSuite)
|
||||
&& availFiniteFieldBits >= TlsDHUtilities.GetMinimumFiniteFieldBits(cipherSuite)
|
||||
&& TlsUtilities.IsValidCipherSuiteForSignatureAlgorithms(cipherSuite, sigAlgs);
|
||||
}
|
||||
|
||||
protected virtual bool PreferLocalCipherSuites()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
protected virtual bool SelectCipherSuite(int cipherSuite)
|
||||
{
|
||||
this.m_selectedCipherSuite = cipherSuite;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual int SelectDH(int minimumFiniteFieldBits)
|
||||
{
|
||||
int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups;
|
||||
if (clientSupportedGroups == null)
|
||||
return SelectDHDefault(minimumFiniteFieldBits);
|
||||
|
||||
// Try to find a supported named group of the required size from the client's list.
|
||||
for (int i = 0; i < clientSupportedGroups.Length; ++i)
|
||||
{
|
||||
int namedGroup = clientSupportedGroups[i];
|
||||
if (NamedGroup.GetFiniteFieldBits(namedGroup) >= minimumFiniteFieldBits)
|
||||
return namedGroup;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected virtual int SelectDHDefault(int minimumFiniteFieldBits)
|
||||
{
|
||||
return minimumFiniteFieldBits <= 2048 ? NamedGroup.ffdhe2048
|
||||
: minimumFiniteFieldBits <= 3072 ? NamedGroup.ffdhe3072
|
||||
: minimumFiniteFieldBits <= 4096 ? NamedGroup.ffdhe4096
|
||||
: minimumFiniteFieldBits <= 6144 ? NamedGroup.ffdhe6144
|
||||
: minimumFiniteFieldBits <= 8192 ? NamedGroup.ffdhe8192
|
||||
: -1;
|
||||
}
|
||||
|
||||
protected virtual int SelectECDH(int minimumCurveBits)
|
||||
{
|
||||
int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups;
|
||||
if (clientSupportedGroups == null)
|
||||
return SelectECDHDefault(minimumCurveBits);
|
||||
|
||||
// Try to find a supported named group of the required size from the client's list.
|
||||
for (int i = 0; i < clientSupportedGroups.Length; ++i)
|
||||
{
|
||||
int namedGroup = clientSupportedGroups[i];
|
||||
if (NamedGroup.GetCurveBits(namedGroup) >= minimumCurveBits)
|
||||
return namedGroup;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected virtual int SelectECDHDefault(int minimumCurveBits)
|
||||
{
|
||||
return minimumCurveBits <= 256 ? NamedGroup.secp256r1
|
||||
: minimumCurveBits <= 384 ? NamedGroup.secp384r1
|
||||
: minimumCurveBits <= 521 ? NamedGroup.secp521r1
|
||||
: -1;
|
||||
}
|
||||
|
||||
protected virtual ProtocolName SelectProtocolName()
|
||||
{
|
||||
IList<ProtocolName> serverProtocolNames = GetProtocolNames();
|
||||
if (null == serverProtocolNames || serverProtocolNames.Count < 1)
|
||||
return null;
|
||||
|
||||
ProtocolName result = SelectProtocolName(m_clientProtocolNames, serverProtocolNames);
|
||||
if (null == result)
|
||||
throw new TlsFatalAlert(AlertDescription.no_application_protocol);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual ProtocolName SelectProtocolName(IList<ProtocolName> clientProtocolNames,
|
||||
IList<ProtocolName> serverProtocolNames)
|
||||
{
|
||||
foreach (ProtocolName serverProtocolName in serverProtocolNames)
|
||||
{
|
||||
if (clientProtocolNames.Contains(serverProtocolName))
|
||||
return serverProtocolName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual bool ShouldSelectProtocolNameEarly()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool PreferLocalClientCertificateTypes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual short[] GetAllowedClientCertificateTypes()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void Init(TlsServerContext context)
|
||||
{
|
||||
this.m_context = context;
|
||||
|
||||
this.m_protocolVersions = GetSupportedVersions();
|
||||
this.m_cipherSuites = GetSupportedCipherSuites();
|
||||
}
|
||||
|
||||
public override ProtocolVersion[] GetProtocolVersions()
|
||||
{
|
||||
return m_protocolVersions;
|
||||
}
|
||||
|
||||
public override int[] GetCipherSuites()
|
||||
{
|
||||
return m_cipherSuites;
|
||||
}
|
||||
|
||||
public override void NotifyHandshakeBeginning()
|
||||
{
|
||||
base.NotifyHandshakeBeginning();
|
||||
|
||||
this.m_offeredCipherSuites = null;
|
||||
this.m_clientExtensions = null;
|
||||
this.m_encryptThenMACOffered = false;
|
||||
this.m_maxFragmentLengthOffered = 0;
|
||||
this.m_truncatedHMacOffered = false;
|
||||
this.m_clientSentECPointFormats = false;
|
||||
this.m_certificateStatusRequest = null;
|
||||
this.m_selectedCipherSuite = -1;
|
||||
this.m_selectedProtocolName = null;
|
||||
this.m_serverExtensions.Clear();
|
||||
}
|
||||
|
||||
public virtual TlsSession GetSessionToResume(byte[] sessionID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual byte[] GetNewSessionID()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual TlsPskExternal GetExternalPsk(IList<PskIdentity> identities)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void NotifySession(TlsSession session)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void NotifyClientVersion(ProtocolVersion clientVersion)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void NotifyFallback(bool isFallback)
|
||||
{
|
||||
/*
|
||||
* RFC 7507 3. If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest
|
||||
* protocol version supported by the server is higher than the version indicated in
|
||||
* ClientHello.client_version, the server MUST respond with a fatal inappropriate_fallback
|
||||
* alert [..].
|
||||
*/
|
||||
if (isFallback)
|
||||
{
|
||||
ProtocolVersion[] serverVersions = GetProtocolVersions();
|
||||
ProtocolVersion clientVersion = m_context.ClientVersion;
|
||||
|
||||
ProtocolVersion latestServerVersion;
|
||||
if (clientVersion.IsTls)
|
||||
{
|
||||
latestServerVersion = ProtocolVersion.GetLatestTls(serverVersions);
|
||||
}
|
||||
else if (clientVersion.IsDtls)
|
||||
{
|
||||
latestServerVersion = ProtocolVersion.GetLatestDtls(serverVersions);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
if (null != latestServerVersion && latestServerVersion.IsLaterVersionOf(clientVersion))
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.inappropriate_fallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void NotifyOfferedCipherSuites(int[] offeredCipherSuites)
|
||||
{
|
||||
this.m_offeredCipherSuites = offeredCipherSuites;
|
||||
}
|
||||
|
||||
public virtual void ProcessClientExtensions(IDictionary<int, byte[]> clientExtensions)
|
||||
{
|
||||
this.m_clientExtensions = clientExtensions;
|
||||
|
||||
if (null != clientExtensions)
|
||||
{
|
||||
this.m_clientProtocolNames = TlsExtensionsUtilities.GetAlpnExtensionClient(clientExtensions);
|
||||
|
||||
if (ShouldSelectProtocolNameEarly())
|
||||
{
|
||||
if (null != m_clientProtocolNames && m_clientProtocolNames.Count > 0)
|
||||
{
|
||||
this.m_selectedProtocolName = SelectProtocolName();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO[tls13] Don't need these if we have negotiated (D)TLS 1.3+
|
||||
{
|
||||
this.m_encryptThenMACOffered = TlsExtensionsUtilities.HasEncryptThenMacExtension(clientExtensions);
|
||||
this.m_truncatedHMacOffered = TlsExtensionsUtilities.HasTruncatedHmacExtension(clientExtensions);
|
||||
this.m_statusRequestV2 = TlsExtensionsUtilities.GetStatusRequestV2Extension(clientExtensions);
|
||||
this.m_trustedCAKeys = TlsExtensionsUtilities.GetTrustedCAKeysExtensionClient(clientExtensions);
|
||||
|
||||
// We only support uncompressed format, this is just to validate the extension, and note its presence.
|
||||
this.m_clientSentECPointFormats =
|
||||
null != TlsExtensionsUtilities.GetSupportedPointFormatsExtension(clientExtensions);
|
||||
}
|
||||
|
||||
this.m_certificateStatusRequest = TlsExtensionsUtilities.GetStatusRequestExtension(clientExtensions);
|
||||
|
||||
this.m_maxFragmentLengthOffered = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions);
|
||||
if (m_maxFragmentLengthOffered >= 0 && !MaxFragmentLength.IsValid(m_maxFragmentLengthOffered))
|
||||
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ProtocolVersion GetServerVersion()
|
||||
{
|
||||
ProtocolVersion[] serverVersions = GetProtocolVersions();
|
||||
ProtocolVersion[] clientVersions = m_context.ClientSupportedVersions;
|
||||
|
||||
foreach (ProtocolVersion clientVersion in clientVersions)
|
||||
{
|
||||
if (ProtocolVersion.Contains(serverVersions, clientVersion))
|
||||
return clientVersion;
|
||||
}
|
||||
|
||||
throw new TlsFatalAlert(AlertDescription.protocol_version);
|
||||
}
|
||||
|
||||
public virtual int[] GetSupportedGroups()
|
||||
{
|
||||
// TODO[tls13] The rest of this class assumes all named groups are supported
|
||||
return new int[]{ NamedGroup.x25519, NamedGroup.x448, NamedGroup.secp256r1, NamedGroup.secp384r1,
|
||||
NamedGroup.ffdhe2048, NamedGroup.ffdhe3072, NamedGroup.ffdhe4096 };
|
||||
}
|
||||
|
||||
public virtual int GetSelectedCipherSuite()
|
||||
{
|
||||
SecurityParameters securityParameters = m_context.SecurityParameters;
|
||||
ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion;
|
||||
|
||||
if (TlsUtilities.IsTlsV13(negotiatedVersion))
|
||||
{
|
||||
int commonCipherSuite13 = TlsUtilities.GetCommonCipherSuite13(negotiatedVersion, m_offeredCipherSuites,
|
||||
GetCipherSuites(), PreferLocalCipherSuites());
|
||||
|
||||
if (commonCipherSuite13 >= 0 && SelectCipherSuite(commonCipherSuite13))
|
||||
{
|
||||
return commonCipherSuite13;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* RFC 5246 7.4.3. In order to negotiate correctly, the server MUST check any candidate
|
||||
* cipher suites against the "signature_algorithms" extension before selecting them. This is
|
||||
* somewhat inelegant but is a compromise designed to minimize changes to the original
|
||||
* cipher suite design.
|
||||
*/
|
||||
var sigAlgs = TlsUtilities.GetUsableSignatureAlgorithms(securityParameters.ClientSigAlgs);
|
||||
|
||||
/*
|
||||
* RFC 4429 5.1. A server that receives a ClientHello containing one or both of these
|
||||
* extensions MUST use the client's enumerated capabilities to guide its selection of an
|
||||
* appropriate cipher suite. One of the proposed ECC cipher suites must be negotiated only
|
||||
* if the server can successfully complete the handshake while using the curves and point
|
||||
* formats supported by the client [...].
|
||||
*/
|
||||
int availCurveBits = GetMaximumNegotiableCurveBits();
|
||||
int availFiniteFieldBits = GetMaximumNegotiableFiniteFieldBits();
|
||||
|
||||
int[] cipherSuites = TlsUtilities.GetCommonCipherSuites(m_offeredCipherSuites, GetCipherSuites(),
|
||||
PreferLocalCipherSuites());
|
||||
|
||||
for (int i = 0; i < cipherSuites.Length; ++i)
|
||||
{
|
||||
int cipherSuite = cipherSuites[i];
|
||||
if (IsSelectableCipherSuite(cipherSuite, availCurveBits, availFiniteFieldBits, sigAlgs)
|
||||
&& SelectCipherSuite(cipherSuite))
|
||||
{
|
||||
return cipherSuite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new TlsFatalAlert(AlertDescription.handshake_failure, "No selectable cipher suite");
|
||||
}
|
||||
|
||||
// IDictionary is (Int32 -> byte[])
|
||||
public virtual IDictionary<int, byte[]> GetServerExtensions()
|
||||
{
|
||||
bool isTlsV13 = TlsUtilities.IsTlsV13(m_context);
|
||||
|
||||
if (isTlsV13)
|
||||
{
|
||||
if (null != m_certificateStatusRequest && AllowCertificateStatus())
|
||||
{
|
||||
/*
|
||||
* TODO[tls13] RFC 8446 4.4.2.1. OCSP Status and SCT Extensions.
|
||||
*
|
||||
* OCSP information is carried in an extension for a CertificateEntry.
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_encryptThenMACOffered && AllowEncryptThenMac())
|
||||
{
|
||||
/*
|
||||
* RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client
|
||||
* and then selects a stream or Authenticated Encryption with Associated Data (AEAD)
|
||||
* ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the
|
||||
* client.
|
||||
*/
|
||||
if (TlsUtilities.IsBlockCipherSuite(m_selectedCipherSuite))
|
||||
{
|
||||
TlsExtensionsUtilities.AddEncryptThenMacExtension(m_serverExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_truncatedHMacOffered && AllowTruncatedHmac())
|
||||
{
|
||||
TlsExtensionsUtilities.AddTruncatedHmacExtension(m_serverExtensions);
|
||||
}
|
||||
|
||||
if (m_clientSentECPointFormats && TlsEccUtilities.IsEccCipherSuite(m_selectedCipherSuite))
|
||||
{
|
||||
/*
|
||||
* RFC 4492 5.2. A server that selects an ECC cipher suite in response to a ClientHello
|
||||
* message including a Supported Point Formats Extension appends this extension (along
|
||||
* with others) to its ServerHello message, enumerating the point formats it can parse.
|
||||
*/
|
||||
TlsExtensionsUtilities.AddSupportedPointFormatsExtension(m_serverExtensions,
|
||||
new short[]{ ECPointFormat.uncompressed });
|
||||
}
|
||||
|
||||
// TODO[tls13] See RFC 8446 4.4.2.1
|
||||
if (null != m_statusRequestV2 && AllowMultiCertStatus())
|
||||
{
|
||||
/*
|
||||
* RFC 6961 2.2. If a server returns a "CertificateStatus" message in response to a
|
||||
* "status_request_v2" request, then the server MUST have included an extension of type
|
||||
* "status_request_v2" with empty "extension_data" in the extended server hello..
|
||||
*/
|
||||
TlsExtensionsUtilities.AddEmptyExtensionData(m_serverExtensions, ExtensionType.status_request_v2);
|
||||
}
|
||||
else if (null != this.m_certificateStatusRequest && AllowCertificateStatus())
|
||||
{
|
||||
/*
|
||||
* RFC 6066 8. If a server returns a "CertificateStatus" message, then the server MUST
|
||||
* have included an extension of type "status_request" with empty "extension_data" in
|
||||
* the extended server hello.
|
||||
*/
|
||||
TlsExtensionsUtilities.AddEmptyExtensionData(m_serverExtensions, ExtensionType.status_request);
|
||||
}
|
||||
|
||||
if (null != m_trustedCAKeys && AllowTrustedCAIndication())
|
||||
{
|
||||
TlsExtensionsUtilities.AddTrustedCAKeysExtensionServer(m_serverExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_maxFragmentLengthOffered >= 0 && MaxFragmentLength.IsValid(m_maxFragmentLengthOffered))
|
||||
{
|
||||
TlsExtensionsUtilities.AddMaxFragmentLengthExtension(m_serverExtensions, m_maxFragmentLengthOffered);
|
||||
}
|
||||
|
||||
// RFC 7250 4.2 for server_certificate_type
|
||||
short[] serverCertTypes = TlsExtensionsUtilities.GetServerCertificateTypeExtensionClient(
|
||||
m_clientExtensions);
|
||||
if (serverCertTypes != null)
|
||||
{
|
||||
TlsCredentials credentials = GetCredentials();
|
||||
|
||||
if (credentials == null || !Arrays.Contains(serverCertTypes, credentials.Certificate.CertificateType))
|
||||
{
|
||||
// outcome 2: we support the extension but have no common types
|
||||
throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
|
||||
}
|
||||
|
||||
// outcome 3: we support the extension and have a common type
|
||||
TlsExtensionsUtilities.AddServerCertificateTypeExtensionServer(m_serverExtensions,
|
||||
credentials.Certificate.CertificateType);
|
||||
}
|
||||
|
||||
// RFC 7250 4.2 for client_certificate_type
|
||||
short[] remoteClientCertTypes = TlsExtensionsUtilities.GetClientCertificateTypeExtensionClient(
|
||||
m_clientExtensions);
|
||||
if (remoteClientCertTypes != null)
|
||||
{
|
||||
short[] localClientCertTypes = GetAllowedClientCertificateTypes();
|
||||
if (localClientCertTypes != null)
|
||||
{
|
||||
short[] preferredTypes;
|
||||
short[] nonPreferredTypes;
|
||||
if (PreferLocalClientCertificateTypes())
|
||||
{
|
||||
preferredTypes = localClientCertTypes;
|
||||
nonPreferredTypes = remoteClientCertTypes;
|
||||
}
|
||||
else
|
||||
{
|
||||
preferredTypes = remoteClientCertTypes;
|
||||
nonPreferredTypes = localClientCertTypes;
|
||||
}
|
||||
|
||||
short selectedType = -1;
|
||||
for (int i = 0; i < preferredTypes.Length; i++)
|
||||
{
|
||||
if (Arrays.Contains(nonPreferredTypes, preferredTypes[i]))
|
||||
{
|
||||
selectedType = preferredTypes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedType == -1)
|
||||
{
|
||||
// outcome 2: we support the extension but have no common types
|
||||
throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
|
||||
}
|
||||
|
||||
// outcome 3: we support the extension and have a common type
|
||||
TlsExtensionsUtilities.AddClientCertificateTypeExtensionServer(m_serverExtensions, selectedType);
|
||||
} // else outcome 1: we don't support the extension
|
||||
}
|
||||
|
||||
return m_serverExtensions;
|
||||
}
|
||||
|
||||
public virtual void GetServerExtensionsForConnection(IDictionary<int, byte[]> serverExtensions)
|
||||
{
|
||||
if (!ShouldSelectProtocolNameEarly())
|
||||
{
|
||||
if (null != m_clientProtocolNames && m_clientProtocolNames.Count > 0)
|
||||
{
|
||||
this.m_selectedProtocolName = SelectProtocolName();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous
|
||||
* contents of this extension are irrelevant, and only the values in the new handshake
|
||||
* messages are considered.
|
||||
*/
|
||||
if (null == m_selectedProtocolName)
|
||||
{
|
||||
serverExtensions.Remove(ExtensionType.application_layer_protocol_negotiation);
|
||||
}
|
||||
else
|
||||
{
|
||||
TlsExtensionsUtilities.AddAlpnExtensionServer(serverExtensions, m_selectedProtocolName);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IList<SupplementalDataEntry> GetServerSupplementalData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract TlsCredentials GetCredentials();
|
||||
|
||||
public virtual CertificateStatus GetCertificateStatus()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual CertificateRequest GetCertificateRequest()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual TlsPskIdentityManager GetPskIdentityManager()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual TlsSrpLoginParameters GetSrpLoginParameters()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual TlsDHConfig GetDHConfig()
|
||||
{
|
||||
int minimumFiniteFieldBits = TlsDHUtilities.GetMinimumFiniteFieldBits(m_selectedCipherSuite);
|
||||
int namedGroup = SelectDH(minimumFiniteFieldBits);
|
||||
return TlsDHUtilities.CreateNamedDHConfig(m_context, namedGroup);
|
||||
}
|
||||
|
||||
public virtual TlsECConfig GetECDHConfig()
|
||||
{
|
||||
int minimumCurveBits = TlsEccUtilities.GetMinimumCurveBits(m_selectedCipherSuite);
|
||||
int namedGroup = SelectECDH(minimumCurveBits);
|
||||
return TlsEccUtilities.CreateNamedECConfig(m_context, namedGroup);
|
||||
}
|
||||
|
||||
public virtual void ProcessClientSupplementalData(IList<SupplementalDataEntry> clientSupplementalData)
|
||||
{
|
||||
if (clientSupplementalData != null)
|
||||
throw new TlsFatalAlert(AlertDescription.unexpected_message);
|
||||
}
|
||||
|
||||
public virtual void NotifyClientCertificate(Certificate clientCertificate)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
public virtual NewSessionTicket GetNewSessionTicket()
|
||||
{
|
||||
/*
|
||||
* RFC 5077 3.3. If the server determines that it does not want to include a ticket after it
|
||||
* has included the SessionTicket extension in the ServerHello, then it sends a zero-length
|
||||
* ticket in the NewSessionTicket handshake message.
|
||||
*/
|
||||
return new NewSessionTicket(0L, TlsUtilities.EmptyBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b71b0eb5769d3f54e8ede6d1d170c2e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,327 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 5246 7.2.</summary>
|
||||
public abstract class AlertDescription
|
||||
{
|
||||
/// <summary>This message notifies the recipient that the sender will not send any more messages on this
|
||||
/// connection.</summary>
|
||||
/// <remarks>
|
||||
/// Note that as of TLS 1.1, failure to properly close a connection no longer requires that a session not be
|
||||
/// resumed. This is a change from TLS 1.0 ("The session becomes unresumable if any connection is terminated
|
||||
/// without proper close_notify messages with level equal to warning.") to conform with widespread
|
||||
/// implementation practice.
|
||||
/// </remarks>
|
||||
public const short close_notify = 0;
|
||||
|
||||
/// <summary>An inappropriate message was received.</summary>
|
||||
/// <remarks>
|
||||
/// This alert is always fatal and should never be observed in communication between proper implementations.
|
||||
/// </remarks>
|
||||
public const short unexpected_message = 10;
|
||||
|
||||
/// <summary>This alert is returned if a record is received with an incorrect MAC.</summary>
|
||||
/// <remarks>
|
||||
/// This alert also MUST be returned if an alert is sent because a TLSCiphertext decrypted in an invalid way:
|
||||
/// either it wasn't an even multiple of the block length, or its padding values, when checked, weren't
|
||||
/// correct. This message is always fatal and should never be observed in communication between proper
|
||||
/// implementations (except when messages were corrupted in the network).
|
||||
/// </remarks>
|
||||
public const short bad_record_mac = 20;
|
||||
|
||||
/// <remarks>
|
||||
/// This alert was used in some earlier versions of TLS, and may have permitted certain attacks against the CBC
|
||||
/// mode [CBCATT]. It MUST NOT be sent by compliant implementations.
|
||||
/// </remarks>
|
||||
public const short decryption_failed = 21;
|
||||
|
||||
/// <summary>A TLSCiphertext record was received that had a length more than 2^14+2048 bytes, or a record
|
||||
/// decrypted to a TLSCompressed record with more than 2^14+1024 bytes.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal and should never be observed in communication between proper implementations
|
||||
/// (except when messages were corrupted in the network).
|
||||
/// </remarks>
|
||||
public const short record_overflow = 22;
|
||||
|
||||
/// <summary>The decompression function received improper input (e.g., data that would expand to excessive
|
||||
/// length).</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal and should never be observed in communication between proper implementations.
|
||||
/// </remarks>
|
||||
public const short decompression_failure = 30;
|
||||
|
||||
/// <summary>Reception of a handshake_failure alert message indicates that the sender was unable to negotiate
|
||||
/// an acceptable set of security parameters given the options available.</summary>
|
||||
/// <remarks>
|
||||
/// This is a fatal error.
|
||||
/// </remarks>
|
||||
public const short handshake_failure = 40;
|
||||
|
||||
/// <remarks>
|
||||
/// This alert was used in SSLv3 but not any version of TLS. It MUST NOT be sent by compliant implementations.
|
||||
/// </remarks>
|
||||
public const short no_certificate = 41;
|
||||
|
||||
/// <summary>A certificate was corrupt, contained signatures that did not verify correctly, etc.</summary>
|
||||
public const short bad_certificate = 42;
|
||||
|
||||
/// <summary>A certificate was of an unsupported type.</summary>
|
||||
public const short unsupported_certificate = 43;
|
||||
|
||||
/// <summary>A certificate was revoked by its signer.</summary>
|
||||
public const short certificate_revoked = 44;
|
||||
|
||||
/// <summary>A certificate has expired or is not currently valid.</summary>
|
||||
public const short certificate_expired = 45;
|
||||
|
||||
/// <summary>Some other (unspecified) issue arose in processing the certificate, rendering it unacceptable.
|
||||
/// </summary>
|
||||
public const short certificate_unknown = 46;
|
||||
|
||||
/// <summary>A field in the handshake was out of range or inconsistent with other fields.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short illegal_parameter = 47;
|
||||
|
||||
/// <summary>A valid certificate chain or partial chain was received, but the certificate was not accepted
|
||||
/// because the CA certificate could not be located or couldn't be matched with a known, trusted CA.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short unknown_ca = 48;
|
||||
|
||||
/// <summary>A valid certificate was received, but when access control was applied, the sender decided not to
|
||||
/// proceed with negotiation.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short access_denied = 49;
|
||||
|
||||
/// <summary>A message could not be decoded because some field was out of the specified range or the length of
|
||||
/// the message was incorrect.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal and should never be observed in communication between proper
|
||||
/// implementations (except when messages were corrupted in the network).
|
||||
/// </remarks>
|
||||
public const short decode_error = 50;
|
||||
|
||||
/// <summary>A handshake cryptographic operation failed, including being unable to correctly verify a signature
|
||||
/// or validate a Finished message.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short decrypt_error = 51;
|
||||
|
||||
/// <remarks>
|
||||
/// This alert was used in some earlier versions of TLS. It MUST NOT be sent by compliant implementations.
|
||||
/// </remarks>
|
||||
public const short export_restriction = 60;
|
||||
|
||||
/// <summary>The protocol version the client has attempted to negotiate is recognized but not supported.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// (For example, old protocol versions might be avoided for security reasons.) This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short protocol_version = 70;
|
||||
|
||||
/// <summary>Returned instead of handshake_failure when a negotiation has failed specifically because the
|
||||
/// server requires ciphers more secure than those supported by the client.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short insufficient_security = 71;
|
||||
|
||||
/// <summary>An internal error unrelated to the peer or the correctness of the protocol (such as a memory
|
||||
/// allocation failure) makes it impossible to continue.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short internal_error = 80;
|
||||
|
||||
/// <summary>This handshake is being canceled for some reason unrelated to a protocol failure.</summary>
|
||||
/// <remarks>
|
||||
/// If the user cancels an operation after the handshake is complete, just closing the connection by sending a
|
||||
/// close_notify is more appropriate. This alert should be followed by a close_notify. This message is
|
||||
/// generally a warning.
|
||||
/// </remarks>
|
||||
public const short user_canceled = 90;
|
||||
|
||||
/// <summary>Sent by the client in response to a hello request or by the server in response to a client hello
|
||||
/// after initial handshaking.</summary>
|
||||
/// <remarks>
|
||||
/// Either of these would normally lead to renegotiation; when that is not appropriate, the recipient should
|
||||
/// respond with this alert. At that point, the original requester can decide whether to proceed with the
|
||||
/// connection. One case where this would be appropriate is where a server has spawned a process to satisfy a
|
||||
/// request; the process might receive security parameters (key length, authentication, etc.) at startup, and
|
||||
/// it might be difficult to communicate changes to these parameters after that point. This message is always a
|
||||
/// warning.
|
||||
/// </remarks>
|
||||
public const short no_renegotiation = 100;
|
||||
|
||||
/// <summary>Sent by clients that receive an extended server hello containing an extension that they did not
|
||||
/// put in the corresponding client hello.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short unsupported_extension = 110;
|
||||
|
||||
/*
|
||||
* RFC 3546
|
||||
*/
|
||||
|
||||
/// <summary>This alert is sent by servers who are unable to retrieve a certificate chain from the URL supplied
|
||||
/// by the client(see Section 3.3).</summary>
|
||||
/// <remarks>
|
||||
/// This message MAY be fatal - for example if client authentication is required by the server for the
|
||||
/// handshake to continue and the server is unable to retrieve the certificate chain, it may send a fatal
|
||||
/// alert.
|
||||
/// </remarks>
|
||||
public const short certificate_unobtainable = 111;
|
||||
|
||||
/// <summary>This alert is sent by servers that receive a server_name extension request, but do not recognize
|
||||
/// the server name.</summary>
|
||||
/// <remarks>
|
||||
/// This message MAY be fatal.
|
||||
/// </remarks>
|
||||
public const short unrecognized_name = 112;
|
||||
|
||||
/// <summary>This alert is sent by clients that receive an invalid certificate status response (see Section 3.6
|
||||
/// ).</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short bad_certificate_status_response = 113;
|
||||
|
||||
/// <summary>This alert is sent by servers when a certificate hash does not match a client provided
|
||||
/// certificate_hash.</summary>
|
||||
/// <remarks>
|
||||
/// This message is always fatal.
|
||||
/// </remarks>
|
||||
public const short bad_certificate_hash_value = 114;
|
||||
|
||||
/*
|
||||
* RFC 4279
|
||||
*/
|
||||
|
||||
/// <summary>If the server does not recognize the PSK identity, it MAY respond with an "unknown_psk_identity"
|
||||
/// alert message.</summary>
|
||||
public const short unknown_psk_identity = 115;
|
||||
|
||||
/*
|
||||
* RFC 7301
|
||||
*/
|
||||
|
||||
/// <summary>In the event that the server supports no protocols that the client advertises, then the server
|
||||
/// SHALL respond with a fatal "no_application_protocol" alert.</summary>
|
||||
public const short no_application_protocol = 120;
|
||||
|
||||
/*
|
||||
* RFC 7507
|
||||
*/
|
||||
|
||||
/// <summary>If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest protocol version
|
||||
/// supported by the server is higher than the version indicated in ClientHello.client_version, the server MUST
|
||||
/// respond with a fatal inappropriate_fallback alert[..].</summary>
|
||||
public const short inappropriate_fallback = 86;
|
||||
|
||||
/*
|
||||
* RFC 8446
|
||||
*/
|
||||
|
||||
/// <summary>Sent by endpoints that receive a handshake message not containing an extension that is mandatory
|
||||
/// to send for the offered TLS version or other negotiated parameters.</summary>
|
||||
public const short missing_extension = 109;
|
||||
|
||||
/// <summary>Sent by servers when a client certificate is desired but none was provided by the client.
|
||||
/// </summary>
|
||||
public const short certificate_required = 116;
|
||||
|
||||
public static string GetName(short alertDescription)
|
||||
{
|
||||
switch (alertDescription)
|
||||
{
|
||||
case close_notify:
|
||||
return "close_notify";
|
||||
case unexpected_message:
|
||||
return "unexpected_message";
|
||||
case bad_record_mac:
|
||||
return "bad_record_mac";
|
||||
case decryption_failed:
|
||||
return "decryption_failed";
|
||||
case record_overflow:
|
||||
return "record_overflow";
|
||||
case decompression_failure:
|
||||
return "decompression_failure";
|
||||
case handshake_failure:
|
||||
return "handshake_failure";
|
||||
case no_certificate:
|
||||
return "no_certificate";
|
||||
case bad_certificate:
|
||||
return "bad_certificate";
|
||||
case unsupported_certificate:
|
||||
return "unsupported_certificate";
|
||||
case certificate_revoked:
|
||||
return "certificate_revoked";
|
||||
case certificate_expired:
|
||||
return "certificate_expired";
|
||||
case certificate_unknown:
|
||||
return "certificate_unknown";
|
||||
case illegal_parameter:
|
||||
return "illegal_parameter";
|
||||
case unknown_ca:
|
||||
return "unknown_ca";
|
||||
case access_denied:
|
||||
return "access_denied";
|
||||
case decode_error:
|
||||
return "decode_error";
|
||||
case decrypt_error:
|
||||
return "decrypt_error";
|
||||
case export_restriction:
|
||||
return "export_restriction";
|
||||
case protocol_version:
|
||||
return "protocol_version";
|
||||
case insufficient_security:
|
||||
return "insufficient_security";
|
||||
case internal_error:
|
||||
return "internal_error";
|
||||
case user_canceled:
|
||||
return "user_canceled";
|
||||
case no_renegotiation:
|
||||
return "no_renegotiation";
|
||||
case unsupported_extension:
|
||||
return "unsupported_extension";
|
||||
case certificate_unobtainable:
|
||||
return "certificate_unobtainable";
|
||||
case unrecognized_name:
|
||||
return "unrecognized_name";
|
||||
case bad_certificate_status_response:
|
||||
return "bad_certificate_status_response";
|
||||
case bad_certificate_hash_value:
|
||||
return "bad_certificate_hash_value";
|
||||
case unknown_psk_identity:
|
||||
return "unknown_psk_identity";
|
||||
case no_application_protocol:
|
||||
return "no_application_protocol";
|
||||
case inappropriate_fallback:
|
||||
return "inappropriate_fallback";
|
||||
case missing_extension:
|
||||
return "missing_extension";
|
||||
case certificate_required:
|
||||
return "certificate_required";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(short alertDescription)
|
||||
{
|
||||
return GetName(alertDescription) + "(" + alertDescription + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a2505255561f804d9face696a7d5923
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 5246 7.2</summary>
|
||||
public abstract class AlertLevel
|
||||
{
|
||||
public const short warning = 1;
|
||||
public const short fatal = 2;
|
||||
|
||||
public static string GetName(short alertDescription)
|
||||
{
|
||||
switch (alertDescription)
|
||||
{
|
||||
case warning:
|
||||
return "warning";
|
||||
case fatal:
|
||||
return "fatal";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(short alertDescription)
|
||||
{
|
||||
return GetName(alertDescription) + "(" + alertDescription + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80a9110c93088b84ca2cf1c27ddbaff8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public class BasicTlsPskExternal
|
||||
: TlsPskExternal
|
||||
{
|
||||
protected readonly byte[] m_identity;
|
||||
protected readonly TlsSecret m_key;
|
||||
protected readonly int m_prfAlgorithm;
|
||||
|
||||
public BasicTlsPskExternal(byte[] identity, TlsSecret key)
|
||||
: this(identity, key, Tls.PrfAlgorithm.tls13_hkdf_sha256)
|
||||
{
|
||||
}
|
||||
|
||||
public BasicTlsPskExternal(byte[] identity, TlsSecret key, int prfAlgorithm)
|
||||
{
|
||||
this.m_identity = Arrays.Clone(identity);
|
||||
this.m_key = key;
|
||||
this.m_prfAlgorithm = prfAlgorithm;
|
||||
}
|
||||
|
||||
public virtual byte[] Identity
|
||||
{
|
||||
get { return m_identity; }
|
||||
}
|
||||
|
||||
public virtual TlsSecret Key
|
||||
{
|
||||
get { return m_key; }
|
||||
}
|
||||
|
||||
public virtual int PrfAlgorithm
|
||||
{
|
||||
get { return m_prfAlgorithm; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce39a0f4d47ebe6469e28fe78f37cd54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>A basic PSK Identity holder.</summary>
|
||||
public class BasicTlsPskIdentity
|
||||
: TlsPskIdentity
|
||||
{
|
||||
protected readonly byte[] m_identity;
|
||||
protected readonly byte[] m_psk;
|
||||
|
||||
public BasicTlsPskIdentity(byte[] identity, byte[] psk)
|
||||
{
|
||||
this.m_identity = Arrays.Clone(identity);
|
||||
this.m_psk = Arrays.Clone(psk);
|
||||
}
|
||||
|
||||
public BasicTlsPskIdentity(string identity, byte[] psk)
|
||||
{
|
||||
this.m_identity = Strings.ToUtf8ByteArray(identity);
|
||||
this.m_psk = Arrays.Clone(psk);
|
||||
}
|
||||
|
||||
public virtual void SkipIdentityHint()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void NotifyIdentityHint(byte[] psk_identity_hint)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual byte[] GetPskIdentity()
|
||||
{
|
||||
return m_identity;
|
||||
}
|
||||
|
||||
public byte[] GetPsk()
|
||||
{
|
||||
return Arrays.Clone(m_psk);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f6cb8fe208ca2b4c81ba0f64184751a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,40 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>A basic SRP Identity holder.</summary>
|
||||
public class BasicTlsSrpIdentity
|
||||
: TlsSrpIdentity
|
||||
{
|
||||
protected readonly byte[] m_identity;
|
||||
protected readonly byte[] m_password;
|
||||
|
||||
public BasicTlsSrpIdentity(byte[] identity, byte[] password)
|
||||
{
|
||||
this.m_identity = Arrays.Clone(identity);
|
||||
this.m_password = Arrays.Clone(password);
|
||||
}
|
||||
|
||||
public BasicTlsSrpIdentity(string identity, string password)
|
||||
{
|
||||
this.m_identity = Strings.ToUtf8ByteArray(identity);
|
||||
this.m_password = Strings.ToUtf8ByteArray(password);
|
||||
}
|
||||
|
||||
public virtual byte[] GetSrpIdentity()
|
||||
{
|
||||
return m_identity;
|
||||
}
|
||||
|
||||
public virtual byte[] GetSrpPassword()
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5eb24435ba998a34da78e3d8e1ec29fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,268 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>A queue for bytes. This file could be more optimized.</summary>
|
||||
public sealed class ByteQueue
|
||||
{
|
||||
/// <returns>The smallest number which can be written as 2^x which is bigger than i.</returns>
|
||||
private static int GetAllocationSize(int i)
|
||||
{
|
||||
return Integers.HighestOneBit((256 | i) << 1);
|
||||
}
|
||||
|
||||
/// <summary>The buffer where we store our data.</summary>
|
||||
private byte[] m_databuf;
|
||||
|
||||
/// <summary>How many bytes at the beginning of the buffer are skipped.</summary>
|
||||
private int m_skipped = 0;
|
||||
|
||||
/// <summary>How many bytes in the buffer are valid data.</summary>
|
||||
private int m_available = 0;
|
||||
|
||||
private bool m_readOnlyBuf = false;
|
||||
|
||||
public ByteQueue()
|
||||
: this(0)
|
||||
{
|
||||
}
|
||||
|
||||
public ByteQueue(int capacity)
|
||||
{
|
||||
this.m_databuf = capacity == 0 ? TlsUtilities.EmptyBytes : new byte[capacity];
|
||||
}
|
||||
|
||||
public ByteQueue(byte[] buf, int off, int len)
|
||||
{
|
||||
this.m_databuf = buf;
|
||||
this.m_skipped = off;
|
||||
this.m_available = len;
|
||||
this.m_readOnlyBuf = true;
|
||||
}
|
||||
|
||||
/// <summary>Add some data to our buffer.</summary>
|
||||
/// <param name="buf">A byte-array to read data from.</param>
|
||||
/// <param name="off">How many bytes to skip at the beginning of the array.</param>
|
||||
/// <param name="len">How many bytes to read from the array.</param>
|
||||
public void AddData(byte[] buf, int off, int len)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
AddData(buf.AsSpan(off, len));
|
||||
#else
|
||||
if (m_readOnlyBuf)
|
||||
throw new InvalidOperationException("Cannot add data to read-only buffer");
|
||||
|
||||
if (m_available == 0)
|
||||
{
|
||||
if (len > m_databuf.Length)
|
||||
{
|
||||
int desiredSize = GetAllocationSize(len);
|
||||
m_databuf = new byte[desiredSize];
|
||||
}
|
||||
m_skipped = 0;
|
||||
}
|
||||
else if ((m_skipped + m_available + len) > m_databuf.Length)
|
||||
{
|
||||
int desiredSize = GetAllocationSize(m_available + len);
|
||||
if (desiredSize > m_databuf.Length)
|
||||
{
|
||||
byte[] tmp = new byte[desiredSize];
|
||||
Array.Copy(m_databuf, m_skipped, tmp, 0, m_available);
|
||||
m_databuf = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(m_databuf, m_skipped, m_databuf, 0, m_available);
|
||||
}
|
||||
m_skipped = 0;
|
||||
}
|
||||
|
||||
Array.Copy(buf, off, m_databuf, m_skipped + m_available, len);
|
||||
m_available += len;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public void AddData(ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
if (m_readOnlyBuf)
|
||||
throw new InvalidOperationException("Cannot add data to read-only buffer");
|
||||
|
||||
int len = buffer.Length;
|
||||
if (m_available == 0)
|
||||
{
|
||||
if (len > m_databuf.Length)
|
||||
{
|
||||
int desiredSize = GetAllocationSize(len);
|
||||
m_databuf = new byte[desiredSize];
|
||||
}
|
||||
m_skipped = 0;
|
||||
}
|
||||
else if ((m_skipped + m_available + len) > m_databuf.Length)
|
||||
{
|
||||
int desiredSize = GetAllocationSize(m_available + len);
|
||||
if (desiredSize > m_databuf.Length)
|
||||
{
|
||||
byte[] tmp = new byte[desiredSize];
|
||||
Array.Copy(m_databuf, m_skipped, tmp, 0, m_available);
|
||||
m_databuf = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(m_databuf, m_skipped, m_databuf, 0, m_available);
|
||||
}
|
||||
m_skipped = 0;
|
||||
}
|
||||
|
||||
buffer.CopyTo(m_databuf.AsSpan(m_skipped + m_available));
|
||||
m_available += len;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <returns>The number of bytes which are available in this buffer.</returns>
|
||||
public int Available
|
||||
{
|
||||
get { return m_available; }
|
||||
}
|
||||
|
||||
/// <summary>Copy some bytes from the beginning of the data to the provided <see cref="Stream"/>.</summary>
|
||||
/// <param name="output">The <see cref="Stream"/> to copy the bytes to.</param>
|
||||
/// <param name="length">How many bytes to copy.</param>
|
||||
public void CopyTo(Stream output, int length)
|
||||
{
|
||||
if (length > m_available)
|
||||
throw new InvalidOperationException("Cannot copy " + length + " bytes, only got " + m_available);
|
||||
|
||||
output.Write(m_databuf, m_skipped, length);
|
||||
}
|
||||
|
||||
/// <summary>Read data from the buffer.</summary>
|
||||
/// <param name="buf">The buffer where the read data will be copied to.</param>
|
||||
/// <param name="offset">How many bytes to skip at the beginning of buf.</param>
|
||||
/// <param name="len">How many bytes to read at all.</param>
|
||||
/// <param name="skip">How many bytes from our data to skip.</param>
|
||||
public void Read(byte[] buf, int offset, int len, int skip)
|
||||
{
|
||||
if ((buf.Length - offset) < len)
|
||||
{
|
||||
throw new ArgumentException("Buffer size of " + buf.Length
|
||||
+ " is too small for a read of " + len + " bytes");
|
||||
}
|
||||
if ((m_available - skip) < len)
|
||||
{
|
||||
throw new InvalidOperationException("Not enough data to read");
|
||||
}
|
||||
Array.Copy(m_databuf, m_skipped + skip, buf, offset, len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public void Read(Span<byte> buffer, int skip)
|
||||
{
|
||||
if ((m_available - skip) < buffer.Length)
|
||||
throw new InvalidOperationException("Not enough data to read");
|
||||
|
||||
buffer.CopyFrom(m_databuf.AsSpan(m_skipped + skip));
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>Return a <see cref="HandshakeMessageInput"/> over some bytes at the beginning of the data.
|
||||
/// </summary>
|
||||
/// <param name="length">How many bytes will be readable.</param>
|
||||
/// <returns>A <see cref="HandshakeMessageInput"/> over the data.</returns>
|
||||
internal HandshakeMessageInput ReadHandshakeMessage(int length)
|
||||
{
|
||||
if (length > m_available)
|
||||
throw new InvalidOperationException("Cannot read " + length + " bytes, only got " + m_available);
|
||||
|
||||
int position = m_skipped;
|
||||
|
||||
m_available -= length;
|
||||
m_skipped += length;
|
||||
|
||||
return new HandshakeMessageInput(m_databuf, position, length);
|
||||
}
|
||||
|
||||
public int ReadInt32()
|
||||
{
|
||||
if (m_available < 4)
|
||||
throw new InvalidOperationException("Not enough data to read");
|
||||
|
||||
return TlsUtilities.ReadInt32(m_databuf, m_skipped);
|
||||
}
|
||||
|
||||
public int ReadUint16(int skip)
|
||||
{
|
||||
if (m_available < skip + 2)
|
||||
throw new InvalidOperationException("Not enough data to read");
|
||||
|
||||
return TlsUtilities.ReadUint16(m_databuf, m_skipped + skip);
|
||||
}
|
||||
|
||||
/// <summary>Remove some bytes from our data from the beginning.</summary>
|
||||
/// <param name="i">How many bytes to remove.</param>
|
||||
public void RemoveData(int i)
|
||||
{
|
||||
if (i > m_available)
|
||||
throw new InvalidOperationException("Cannot remove " + i + " bytes, only got " + m_available);
|
||||
|
||||
/*
|
||||
* Skip the data.
|
||||
*/
|
||||
m_available -= i;
|
||||
m_skipped += i;
|
||||
}
|
||||
|
||||
/// <summary>Remove data from the buffer.</summary>
|
||||
/// <param name="buf">The buffer where the removed data will be copied to.</param>
|
||||
/// <param name="off">How many bytes to skip at the beginning of buf.</param>
|
||||
/// <param name="len">How many bytes to read at all.</param>
|
||||
/// <param name="skip">How many bytes from our data to skip.</param>
|
||||
public void RemoveData(byte[] buf, int off, int len, int skip)
|
||||
{
|
||||
Read(buf, off, len, skip);
|
||||
RemoveData(skip + len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public void RemoveData(Span<byte> buffer, int skip)
|
||||
{
|
||||
Read(buffer, skip);
|
||||
RemoveData(skip + buffer.Length);
|
||||
}
|
||||
#endif
|
||||
|
||||
public byte[] RemoveData(int len, int skip)
|
||||
{
|
||||
byte[] buf = new byte[len];
|
||||
RemoveData(buf, 0, len, skip);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public void Shrink()
|
||||
{
|
||||
if (m_available == 0)
|
||||
{
|
||||
m_databuf = TlsUtilities.EmptyBytes;
|
||||
m_skipped = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int desiredSize = GetAllocationSize(m_available);
|
||||
if (desiredSize < m_databuf.Length)
|
||||
{
|
||||
byte[] tmp = new byte[desiredSize];
|
||||
Array.Copy(m_databuf, m_skipped, tmp, 0, m_available);
|
||||
m_databuf = tmp;
|
||||
m_skipped = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b37c92d467d028b4eb34c1c68778fa8a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public sealed class ByteQueueInputStream
|
||||
: BaseInputStream
|
||||
{
|
||||
private readonly ByteQueue m_buffer;
|
||||
|
||||
public ByteQueueInputStream()
|
||||
{
|
||||
this.m_buffer = new ByteQueue();
|
||||
}
|
||||
|
||||
public void AddBytes(byte[] buf)
|
||||
{
|
||||
m_buffer.AddData(buf, 0, buf.Length);
|
||||
}
|
||||
|
||||
public void AddBytes(byte[] buf, int bufOff, int bufLen)
|
||||
{
|
||||
m_buffer.AddData(buf, bufOff, bufLen);
|
||||
}
|
||||
|
||||
public int Peek(byte[] buf)
|
||||
{
|
||||
int bytesToRead = System.Math.Min(m_buffer.Available, buf.Length);
|
||||
m_buffer.Read(buf, 0, bytesToRead, 0);
|
||||
return bytesToRead;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Streams.ValidateBufferArguments(buffer, offset, count);
|
||||
|
||||
int bytesToRead = System.Math.Min(m_buffer.Available, count);
|
||||
m_buffer.RemoveData(buffer, offset, bytesToRead, 0);
|
||||
return bytesToRead;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public override int Read(Span<byte> buffer)
|
||||
{
|
||||
int bytesToRead = System.Math.Min(m_buffer.Available, buffer.Length);
|
||||
m_buffer.RemoveData(buffer[..bytesToRead], 0);
|
||||
return bytesToRead;
|
||||
}
|
||||
#endif
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
if (m_buffer.Available == 0)
|
||||
return -1;
|
||||
|
||||
return m_buffer.RemoveData(1, 0)[0];
|
||||
}
|
||||
|
||||
public long Skip(long n)
|
||||
{
|
||||
int bytesToRemove = System.Math.Min((int)n, m_buffer.Available);
|
||||
m_buffer.RemoveData(bytesToRemove);
|
||||
return bytesToRemove;
|
||||
}
|
||||
|
||||
public int Available
|
||||
{
|
||||
get { return m_buffer.Available; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eeea8a9089688d54297d8a29e984e5e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>OutputStream based on a ByteQueue implementation.</summary>
|
||||
public sealed class ByteQueueOutputStream
|
||||
: BaseOutputStream
|
||||
{
|
||||
private readonly ByteQueue m_buffer;
|
||||
|
||||
public ByteQueueOutputStream()
|
||||
{
|
||||
this.m_buffer = new ByteQueue();
|
||||
}
|
||||
|
||||
public ByteQueue Buffer
|
||||
{
|
||||
get { return m_buffer; }
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Streams.ValidateBufferArguments(buffer, offset, count);
|
||||
|
||||
m_buffer.AddData(buffer, offset, count);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public override void Write(ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
m_buffer.AddData(buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
public override void WriteByte(byte value)
|
||||
{
|
||||
m_buffer.AddData(new byte[]{ value }, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbefd50f95714a349ae44de163b24b1d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public abstract class CachedInformationType
|
||||
{
|
||||
public const short cert = 1;
|
||||
public const short cert_req = 2;
|
||||
|
||||
public static string GetName(short cachedInformationType)
|
||||
{
|
||||
switch (cachedInformationType)
|
||||
{
|
||||
case cert:
|
||||
return "cert";
|
||||
case cert_req:
|
||||
return "cert_req";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(short cachedInformationType)
|
||||
{
|
||||
return GetName(cachedInformationType) + "(" + cachedInformationType + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 514caa9f24897c64788e1f68f5a3fd01
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Implementation of the RFC 3546 3.3. CertChainType.</summary>
|
||||
public abstract class CertChainType
|
||||
{
|
||||
public const short individual_certs = 0;
|
||||
public const short pkipath = 1;
|
||||
|
||||
public static string GetName(short certChainType)
|
||||
{
|
||||
switch (certChainType)
|
||||
{
|
||||
case individual_certs:
|
||||
return "individual_certs";
|
||||
case pkipath:
|
||||
return "pkipath";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(short certChainType)
|
||||
{
|
||||
return GetName(certChainType) + "(" + certChainType + ")";
|
||||
}
|
||||
|
||||
public static bool IsValid(short certChainType)
|
||||
{
|
||||
return certChainType >= individual_certs && certChainType <= pkipath;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27a6ada069c4b854dabb3c92bf7818cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,300 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Parsing and encoding of a <i>Certificate</i> struct from RFC 4346.</summary>
|
||||
/// <remarks>
|
||||
/// <pre>
|
||||
/// opaque ASN.1Cert<2^24-1>;
|
||||
/// struct {
|
||||
/// ASN.1Cert certificate_list<0..2^24-1>;
|
||||
/// } Certificate;
|
||||
/// </pre>
|
||||
/// </remarks>
|
||||
public sealed class Certificate
|
||||
{
|
||||
private static readonly TlsCertificate[] EmptyCerts = new TlsCertificate[0];
|
||||
private static readonly CertificateEntry[] EmptyCertEntries = new CertificateEntry[0];
|
||||
|
||||
public static readonly Certificate EmptyChain = new Certificate(EmptyCerts);
|
||||
public static readonly Certificate EmptyChainTls13 = new Certificate(TlsUtilities.EmptyBytes, EmptyCertEntries);
|
||||
|
||||
public sealed class ParseOptions
|
||||
{
|
||||
public short CertificateType { get; set; } = Tls.CertificateType.X509;
|
||||
public int MaxChainLength { get; set; } = int.MaxValue;
|
||||
}
|
||||
|
||||
private static CertificateEntry[] Convert(TlsCertificate[] certificateList)
|
||||
{
|
||||
if (TlsUtilities.IsNullOrContainsNull(certificateList))
|
||||
throw new ArgumentException("cannot be null or contain any nulls", "certificateList");
|
||||
|
||||
int count = certificateList.Length;
|
||||
CertificateEntry[] result = new CertificateEntry[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
result[i] = new CertificateEntry(certificateList[i], null);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private readonly byte[] m_certificateRequestContext;
|
||||
private readonly CertificateEntry[] m_certificateEntryList;
|
||||
private readonly short m_certificateType;
|
||||
|
||||
public Certificate(TlsCertificate[] certificateList)
|
||||
: this(null, Convert(certificateList))
|
||||
{
|
||||
}
|
||||
|
||||
public Certificate(byte[] certificateRequestContext, CertificateEntry[] certificateEntryList)
|
||||
: this(Tls.CertificateType.X509, certificateRequestContext, certificateEntryList)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO[tls13] Prefer to manage the certificateRequestContext internally only?
|
||||
public Certificate(short certificateType, byte[] certificateRequestContext, CertificateEntry[] certificateEntryList)
|
||||
{
|
||||
if (null != certificateRequestContext && !TlsUtilities.IsValidUint8(certificateRequestContext.Length))
|
||||
throw new ArgumentException("cannot be longer than 255", "certificateRequestContext");
|
||||
if (TlsUtilities.IsNullOrContainsNull(certificateEntryList))
|
||||
throw new ArgumentException("cannot be null or contain any nulls", "certificateEntryList");
|
||||
|
||||
m_certificateRequestContext = TlsUtilities.Clone(certificateRequestContext);
|
||||
m_certificateEntryList = certificateEntryList;
|
||||
m_certificateType = certificateType;
|
||||
}
|
||||
|
||||
public byte[] GetCertificateRequestContext()
|
||||
{
|
||||
return TlsUtilities.Clone(m_certificateRequestContext);
|
||||
}
|
||||
|
||||
/// <returns>an array of <see cref="TlsCertificate"/> representing a certificate chain.</returns>
|
||||
public TlsCertificate[] GetCertificateList()
|
||||
{
|
||||
return CloneCertificateList();
|
||||
}
|
||||
|
||||
public TlsCertificate GetCertificateAt(int index)
|
||||
{
|
||||
return m_certificateEntryList[index].Certificate;
|
||||
}
|
||||
|
||||
public CertificateEntry GetCertificateEntryAt(int index)
|
||||
{
|
||||
return m_certificateEntryList[index];
|
||||
}
|
||||
|
||||
public CertificateEntry[] GetCertificateEntryList()
|
||||
{
|
||||
return CloneCertificateEntryList();
|
||||
}
|
||||
|
||||
public short CertificateType => m_certificateType;
|
||||
|
||||
public int Length => m_certificateEntryList.Length;
|
||||
|
||||
/// <returns><c>true</c> if this certificate chain contains no certificates, or <c>false</c> otherwise.
|
||||
/// </returns>
|
||||
public bool IsEmpty => m_certificateEntryList.Length == 0;
|
||||
|
||||
/// <summary>Encode this <see cref="Certificate"/> to a <see cref="Stream"/>, and optionally calculate the
|
||||
/// "end point hash" (per RFC 5929's tls-server-end-point binding).</summary>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="messageOutput">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <param name="endPointHashOutput">the <see cref="Stream"/> to write the "end point hash" to (or null).
|
||||
/// </param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(TlsContext context, Stream messageOutput, Stream endPointHashOutput)
|
||||
{
|
||||
bool isTlsV13 = TlsUtilities.IsTlsV13(context);
|
||||
|
||||
if ((null != m_certificateRequestContext) != isTlsV13)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
if (isTlsV13)
|
||||
{
|
||||
TlsUtilities.WriteOpaque8(m_certificateRequestContext, messageOutput);
|
||||
}
|
||||
|
||||
int count = m_certificateEntryList.Length;
|
||||
var certEncodings = new List<byte[]>(count);
|
||||
var extEncodings = isTlsV13 ? new List<byte[]>(count) : null;
|
||||
|
||||
long totalLength = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
CertificateEntry entry = m_certificateEntryList[i];
|
||||
TlsCertificate cert = entry.Certificate;
|
||||
byte[] derEncoding = cert.GetEncoded();
|
||||
|
||||
if (i == 0 && endPointHashOutput != null)
|
||||
{
|
||||
CalculateEndPointHash(context, cert, derEncoding, endPointHashOutput);
|
||||
}
|
||||
|
||||
certEncodings.Add(derEncoding);
|
||||
totalLength += derEncoding.Length;
|
||||
totalLength += 3;
|
||||
|
||||
if (isTlsV13)
|
||||
{
|
||||
var extensions = entry.Extensions;
|
||||
byte[] extEncoding = (null == extensions)
|
||||
? TlsUtilities.EmptyBytes
|
||||
: TlsProtocol.WriteExtensionsData(extensions);
|
||||
|
||||
extEncodings.Add(extEncoding);
|
||||
totalLength += extEncoding.Length;
|
||||
totalLength += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// RFC 7250 indicates the raw key is not wrapped in a cert list like X509 is
|
||||
// but RFC 8446 wraps it in a CertificateEntry, which is inside certificate_list
|
||||
if (isTlsV13 || m_certificateType != Tls.CertificateType.RawPublicKey)
|
||||
{
|
||||
TlsUtilities.CheckUint24(totalLength);
|
||||
TlsUtilities.WriteUint24((int)totalLength, messageOutput);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
TlsUtilities.WriteOpaque24(certEncodings[i], messageOutput);
|
||||
|
||||
if (isTlsV13)
|
||||
{
|
||||
TlsUtilities.WriteOpaque16(extEncodings[i], messageOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="Certificate"/> from a <see cref="Stream"/>.</summary>
|
||||
/// <param name="options">the <see cref="ParseOptions"/> to apply during parsing.</param>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="messageInput">the <see cref="Stream"/> to parse from.</param>
|
||||
/// <param name="endPointHashOutput">the <see cref="Stream"/> to write the "end point hash" to (or null).
|
||||
/// </param>
|
||||
/// <returns>a <see cref="Certificate"/> object.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
public static Certificate Parse(ParseOptions options, TlsContext context, Stream messageInput,
|
||||
Stream endPointHashOutput)
|
||||
{
|
||||
SecurityParameters securityParameters = context.SecurityParameters;
|
||||
bool isTlsV13 = TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion);
|
||||
short certType = options.CertificateType;
|
||||
|
||||
byte[] certificateRequestContext = null;
|
||||
if (isTlsV13)
|
||||
{
|
||||
certificateRequestContext = TlsUtilities.ReadOpaque8(messageInput);
|
||||
}
|
||||
|
||||
int totalLength = TlsUtilities.ReadUint24(messageInput);
|
||||
if (totalLength == 0)
|
||||
{
|
||||
return !isTlsV13 ? EmptyChain
|
||||
: certificateRequestContext.Length < 1 ? EmptyChainTls13
|
||||
: new Certificate(certType, certificateRequestContext, EmptyCertEntries);
|
||||
}
|
||||
|
||||
byte[] certListData = TlsUtilities.ReadFully(totalLength, messageInput);
|
||||
MemoryStream buf = new MemoryStream(certListData, false);
|
||||
|
||||
TlsCrypto crypto = context.Crypto;
|
||||
int maxChainLength = System.Math.Max(1, options.MaxChainLength);
|
||||
|
||||
var certificate_list = new List<CertificateEntry>();
|
||||
while (buf.Position < buf.Length)
|
||||
{
|
||||
if (certificate_list.Count >= maxChainLength)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error,
|
||||
"Certificate chain longer than maximum (" + maxChainLength + ")");
|
||||
}
|
||||
|
||||
// RFC 7250 indicates the raw key is not wrapped in a cert list like X509 is
|
||||
// but RFC 8446 wraps it in a CertificateEntry, which is inside certificate_list
|
||||
byte[] derEncoding;
|
||||
if (isTlsV13 || certType != Tls.CertificateType.RawPublicKey)
|
||||
{
|
||||
derEncoding = TlsUtilities.ReadOpaque24(buf, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
derEncoding = certListData;
|
||||
buf.Seek(totalLength, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
TlsCertificate cert = crypto.CreateCertificate(certType, derEncoding);
|
||||
|
||||
if (certificate_list.Count < 1 && endPointHashOutput != null)
|
||||
{
|
||||
CalculateEndPointHash(context, cert, derEncoding, endPointHashOutput);
|
||||
}
|
||||
|
||||
IDictionary<int, byte[]> extensions = null;
|
||||
if (isTlsV13)
|
||||
{
|
||||
byte[] extEncoding = TlsUtilities.ReadOpaque16(buf);
|
||||
|
||||
extensions = TlsProtocol.ReadExtensionsData13(HandshakeType.certificate, extEncoding);
|
||||
}
|
||||
|
||||
certificate_list.Add(new CertificateEntry(cert, extensions));
|
||||
}
|
||||
|
||||
CertificateEntry[] certificateList = new CertificateEntry[certificate_list.Count];
|
||||
for (int i = 0; i < certificate_list.Count; i++)
|
||||
{
|
||||
certificateList[i] = (CertificateEntry)certificate_list[i];
|
||||
}
|
||||
|
||||
return new Certificate(certType, certificateRequestContext, certificateList);
|
||||
}
|
||||
|
||||
private static void CalculateEndPointHash(TlsContext context, TlsCertificate cert, byte[] encoding,
|
||||
Stream output)
|
||||
{
|
||||
byte[] endPointHash = TlsUtilities.CalculateEndPointHash(context, cert, encoding);
|
||||
if (endPointHash != null && endPointHash.Length > 0)
|
||||
{
|
||||
output.Write(endPointHash, 0, endPointHash.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private TlsCertificate[] CloneCertificateList()
|
||||
{
|
||||
int count = m_certificateEntryList.Length;
|
||||
if (0 == count)
|
||||
return EmptyCerts;
|
||||
|
||||
TlsCertificate[] result = new TlsCertificate[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
result[i] = m_certificateEntryList[i].Certificate;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private CertificateEntry[] CloneCertificateEntryList()
|
||||
{
|
||||
int count = m_certificateEntryList.Length;
|
||||
if (0 == count)
|
||||
return EmptyCertEntries;
|
||||
|
||||
CertificateEntry[] result = new CertificateEntry[count];
|
||||
Array.Copy(m_certificateEntryList, 0, result, 0, count);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e02b2aa10a45b044d88fb5f1f2bb3fa2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/**
|
||||
* RFC 8879
|
||||
*/
|
||||
public abstract class CertificateCompressionAlgorithm
|
||||
{
|
||||
public const int zlib = 1;
|
||||
public const int brotli = 2;
|
||||
public const int zstd = 3;
|
||||
|
||||
public static string GetName(int certificateCompressionAlgorithm)
|
||||
{
|
||||
switch (certificateCompressionAlgorithm)
|
||||
{
|
||||
case zlib:
|
||||
return "zlib";
|
||||
case brotli:
|
||||
return "brotli";
|
||||
case zstd:
|
||||
return "zstd";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(int certificateCompressionAlgorithm)
|
||||
{
|
||||
return GetName(certificateCompressionAlgorithm) + "(" + certificateCompressionAlgorithm + ")";
|
||||
}
|
||||
|
||||
public static bool IsRecognized(int certificateCompressionAlgorithm)
|
||||
{
|
||||
switch (certificateCompressionAlgorithm)
|
||||
{
|
||||
case zlib:
|
||||
case brotli:
|
||||
case zstd:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e946795c64c7bf45be136ba500d866f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public sealed class CertificateEntry
|
||||
{
|
||||
private readonly TlsCertificate m_certificate;
|
||||
private readonly IDictionary<int, byte[]> m_extensions;
|
||||
|
||||
public CertificateEntry(TlsCertificate certificate, IDictionary<int, byte[]> extensions)
|
||||
{
|
||||
if (null == certificate)
|
||||
throw new ArgumentNullException("certificate");
|
||||
|
||||
this.m_certificate = certificate;
|
||||
this.m_extensions = extensions;
|
||||
}
|
||||
|
||||
public TlsCertificate Certificate
|
||||
{
|
||||
get { return m_certificate; }
|
||||
}
|
||||
|
||||
public IDictionary<int, byte[]> Extensions
|
||||
{
|
||||
get { return m_extensions; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87ba950718cec0c4cabc3759850322a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,283 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Parsing and encoding of a <i>CertificateRequest</i> struct from RFC 4346.</summary>
|
||||
/// <remarks>
|
||||
/// <pre>
|
||||
/// struct {
|
||||
/// ClientCertificateType certificate_types<1..2^8-1>;
|
||||
/// DistinguishedName certificate_authorities<3..2^16-1>;
|
||||
/// } CertificateRequest;
|
||||
/// </pre>
|
||||
/// Updated for RFC 5246:
|
||||
/// <pre>
|
||||
/// struct {
|
||||
/// ClientCertificateType certificate_types <1..2 ^ 8 - 1>;
|
||||
/// SignatureAndHashAlgorithm supported_signature_algorithms <2 ^ 16 - 1>;
|
||||
/// DistinguishedName certificate_authorities <0..2 ^ 16 - 1>;
|
||||
/// } CertificateRequest;
|
||||
/// </pre>
|
||||
/// Revised for RFC 8446:
|
||||
/// <pre>
|
||||
/// struct {
|
||||
/// opaque certificate_request_context <0..2 ^ 8 - 1>;
|
||||
/// Extension extensions <2..2 ^ 16 - 1>;
|
||||
/// } CertificateRequest;
|
||||
/// </pre>
|
||||
/// </remarks>
|
||||
/// <seealso cref="ClientCertificateType"/>
|
||||
/// <seealso cref="X509Name"/>
|
||||
public sealed class CertificateRequest
|
||||
{
|
||||
/// <exception cref="IOException"/>
|
||||
private static IList<SignatureAndHashAlgorithm> CheckSupportedSignatureAlgorithms(
|
||||
IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, short alertDescription)
|
||||
{
|
||||
if (null == supportedSignatureAlgorithms)
|
||||
throw new TlsFatalAlert(alertDescription, "'signature_algorithms' is required");
|
||||
|
||||
return supportedSignatureAlgorithms;
|
||||
}
|
||||
|
||||
private readonly byte[] m_certificateRequestContext;
|
||||
private readonly short[] m_certificateTypes;
|
||||
private readonly IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithms;
|
||||
private readonly IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithmsCert;
|
||||
private readonly IList<X509Name> m_certificateAuthorities;
|
||||
|
||||
/// <param name="certificateTypes">see <see cref="ClientCertificateType"/> for valid constants.</param>
|
||||
/// <param name="supportedSignatureAlgorithms"></param>
|
||||
/// <param name="certificateAuthorities">an <see cref="IList{T}"/> of <see cref="X509Name"/>.</param>
|
||||
public CertificateRequest(short[] certificateTypes,
|
||||
IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, IList<X509Name> certificateAuthorities)
|
||||
: this(null, certificateTypes, supportedSignatureAlgorithms, null, certificateAuthorities)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO[tls13] Prefer to manage the certificateRequestContext internally only?
|
||||
/// <exception cref="IOException"/>
|
||||
public CertificateRequest(byte[] certificateRequestContext,
|
||||
IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms,
|
||||
IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithmsCert, IList<X509Name> certificateAuthorities)
|
||||
: this(certificateRequestContext, null,
|
||||
CheckSupportedSignatureAlgorithms(supportedSignatureAlgorithms, AlertDescription.internal_error),
|
||||
supportedSignatureAlgorithmsCert, certificateAuthorities)
|
||||
{
|
||||
/*
|
||||
* TODO[tls13] Removed certificateTypes, added certificate_request_context, added extensions
|
||||
* (required: signature_algorithms, optional: status_request, signed_certificate_timestamp,
|
||||
* certificate_authorities, oid_filters, signature_algorithms_cert)
|
||||
*/
|
||||
}
|
||||
|
||||
private CertificateRequest(byte[] certificateRequestContext, short[] certificateTypes,
|
||||
IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms,
|
||||
IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithmsCert, IList<X509Name> certificateAuthorities)
|
||||
{
|
||||
if (null != certificateRequestContext && !TlsUtilities.IsValidUint8(certificateRequestContext.Length))
|
||||
throw new ArgumentException("cannot be longer than 255", "certificateRequestContext");
|
||||
if (null != certificateTypes
|
||||
&& (certificateTypes.Length < 1 || !TlsUtilities.IsValidUint8(certificateTypes.Length)))
|
||||
{
|
||||
throw new ArgumentException("should have length from 1 to 255", "certificateTypes");
|
||||
}
|
||||
|
||||
this.m_certificateRequestContext = TlsUtilities.Clone(certificateRequestContext);
|
||||
this.m_certificateTypes = certificateTypes;
|
||||
this.m_supportedSignatureAlgorithms = supportedSignatureAlgorithms;
|
||||
this.m_supportedSignatureAlgorithmsCert = supportedSignatureAlgorithmsCert;
|
||||
this.m_certificateAuthorities = certificateAuthorities;
|
||||
}
|
||||
|
||||
public byte[] GetCertificateRequestContext()
|
||||
{
|
||||
return TlsUtilities.Clone(m_certificateRequestContext);
|
||||
}
|
||||
|
||||
/// <returns>an array of certificate types</returns>
|
||||
/// <seealso cref="ClientCertificateType"/>
|
||||
public short[] CertificateTypes
|
||||
{
|
||||
get { return m_certificateTypes; }
|
||||
}
|
||||
|
||||
/// <returns>an <see cref="IList{T}"/> of <see cref="SignatureAndHashAlgorithm"/> (or null before TLS 1.2).
|
||||
/// </returns>
|
||||
public IList<SignatureAndHashAlgorithm> SupportedSignatureAlgorithms
|
||||
{
|
||||
get { return m_supportedSignatureAlgorithms; }
|
||||
}
|
||||
|
||||
/// <returns>an optional <see cref="IList{T}"/> of <see cref="SignatureAndHashAlgorithm"/>. May be non-null from
|
||||
/// TLS 1.3 onwards.</returns>
|
||||
public IList<SignatureAndHashAlgorithm> SupportedSignatureAlgorithmsCert
|
||||
{
|
||||
get { return m_supportedSignatureAlgorithmsCert; }
|
||||
}
|
||||
|
||||
/// <returns>an <see cref="IList{T}"/> of <see cref="X509Name"/>.</returns>
|
||||
public IList<X509Name> CertificateAuthorities
|
||||
{
|
||||
get { return m_certificateAuthorities; }
|
||||
}
|
||||
|
||||
public bool HasCertificateRequestContext(byte[] certificateRequestContext)
|
||||
{
|
||||
return Arrays.AreEqual(m_certificateRequestContext, certificateRequestContext);
|
||||
}
|
||||
|
||||
/// <summary>Encode this <see cref="CertificateRequest"/> to a <see cref="Stream"/>.</summary>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="output">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(TlsContext context, Stream output)
|
||||
{
|
||||
ProtocolVersion negotiatedVersion = context.ServerVersion;
|
||||
bool isTlsV12 = TlsUtilities.IsTlsV12(negotiatedVersion);
|
||||
bool isTlsV13 = TlsUtilities.IsTlsV13(negotiatedVersion);
|
||||
|
||||
if (isTlsV13 != (null != m_certificateRequestContext) ||
|
||||
isTlsV13 != (null == m_certificateTypes) ||
|
||||
isTlsV12 != (null != m_supportedSignatureAlgorithms) ||
|
||||
(!isTlsV13 && (null != m_supportedSignatureAlgorithmsCert)))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (isTlsV13)
|
||||
{
|
||||
TlsUtilities.WriteOpaque8(m_certificateRequestContext, output);
|
||||
|
||||
var extensions = new Dictionary<int, byte[]>();
|
||||
TlsExtensionsUtilities.AddSignatureAlgorithmsExtension(extensions, m_supportedSignatureAlgorithms);
|
||||
|
||||
if (null != m_supportedSignatureAlgorithmsCert)
|
||||
{
|
||||
TlsExtensionsUtilities.AddSignatureAlgorithmsCertExtension(extensions,
|
||||
m_supportedSignatureAlgorithmsCert);
|
||||
}
|
||||
|
||||
if (null != m_certificateAuthorities)
|
||||
{
|
||||
TlsExtensionsUtilities.AddCertificateAuthoritiesExtension(extensions, m_certificateAuthorities);
|
||||
}
|
||||
|
||||
byte[] extEncoding = TlsProtocol.WriteExtensionsData(extensions);
|
||||
|
||||
TlsUtilities.WriteOpaque16(extEncoding, output);
|
||||
return;
|
||||
}
|
||||
|
||||
TlsUtilities.WriteUint8ArrayWithUint8Length(m_certificateTypes, output);
|
||||
|
||||
if (isTlsV12)
|
||||
{
|
||||
// TODO Check whether SignatureAlgorithm.anonymous is allowed here
|
||||
TlsUtilities.EncodeSupportedSignatureAlgorithms(m_supportedSignatureAlgorithms, output);
|
||||
}
|
||||
|
||||
if (m_certificateAuthorities == null || m_certificateAuthorities.Count < 1)
|
||||
{
|
||||
TlsUtilities.WriteUint16(0, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
var derEncodings = new List<byte[]>(m_certificateAuthorities.Count);
|
||||
|
||||
int totalLength = 0;
|
||||
foreach (X509Name certificateAuthority in m_certificateAuthorities)
|
||||
{
|
||||
byte[] derEncoding = certificateAuthority.GetEncoded(Asn1Encodable.Der);
|
||||
derEncodings.Add(derEncoding);
|
||||
totalLength += derEncoding.Length + 2;
|
||||
}
|
||||
|
||||
TlsUtilities.CheckUint16(totalLength);
|
||||
TlsUtilities.WriteUint16(totalLength, output);
|
||||
|
||||
foreach (byte[] derEncoding in derEncodings)
|
||||
{
|
||||
TlsUtilities.WriteOpaque16(derEncoding, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="CertificateRequest"/> from a <see cref="Stream"/></summary>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="input">the <see cref="Stream"/> to parse from.</param>
|
||||
/// <returns>a <see cref="CertificateRequest"/> object.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
public static CertificateRequest Parse(TlsContext context, Stream input)
|
||||
{
|
||||
ProtocolVersion negotiatedVersion = context.ServerVersion;
|
||||
bool isTlsV13 = TlsUtilities.IsTlsV13(negotiatedVersion);
|
||||
|
||||
if (isTlsV13)
|
||||
{
|
||||
byte[] certificateRequestContext = TlsUtilities.ReadOpaque8(input);
|
||||
|
||||
/*
|
||||
* TODO[tls13] required: signature_algorithms; optional: status_request,
|
||||
* signed_certificate_timestamp, certificate_authorities, oid_filters,
|
||||
* signature_algorithms_cert
|
||||
*/
|
||||
|
||||
byte[] extEncoding = TlsUtilities.ReadOpaque16(input);
|
||||
|
||||
var extensions = TlsProtocol.ReadExtensionsData13(HandshakeType.certificate_request, extEncoding);
|
||||
|
||||
var supportedSignatureAlgorithms13 = CheckSupportedSignatureAlgorithms(
|
||||
TlsExtensionsUtilities.GetSignatureAlgorithmsExtension(extensions),
|
||||
AlertDescription.missing_extension);
|
||||
var supportedSignatureAlgorithmsCert13 = TlsExtensionsUtilities
|
||||
.GetSignatureAlgorithmsCertExtension(extensions);
|
||||
var certificateAuthorities13 = TlsExtensionsUtilities.GetCertificateAuthoritiesExtension(extensions);
|
||||
|
||||
return new CertificateRequest(certificateRequestContext, supportedSignatureAlgorithms13,
|
||||
supportedSignatureAlgorithmsCert13, certificateAuthorities13);
|
||||
}
|
||||
|
||||
bool isTLSv12 = TlsUtilities.IsTlsV12(negotiatedVersion);
|
||||
|
||||
short[] certificateTypes = TlsUtilities.ReadUint8ArrayWithUint8Length(input, 1);
|
||||
|
||||
IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms = null;
|
||||
if (isTLSv12)
|
||||
{
|
||||
supportedSignatureAlgorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(input);
|
||||
}
|
||||
|
||||
IList<X509Name> certificateAuthorities = null;
|
||||
{
|
||||
byte[] certAuthData = TlsUtilities.ReadOpaque16(input);
|
||||
if (certAuthData.Length > 0)
|
||||
{
|
||||
certificateAuthorities = new List<X509Name>();
|
||||
MemoryStream bis = new MemoryStream(certAuthData, false);
|
||||
do
|
||||
{
|
||||
byte[] derEncoding = TlsUtilities.ReadOpaque16(bis, 1);
|
||||
Asn1Object asn1 = TlsUtilities.ReadAsn1Object(derEncoding);
|
||||
X509Name ca = X509Name.GetInstance(asn1);
|
||||
TlsUtilities.RequireDerEncoding(ca, derEncoding);
|
||||
certificateAuthorities.Add(ca);
|
||||
}
|
||||
while (bis.Position < bis.Length);
|
||||
}
|
||||
}
|
||||
|
||||
return new CertificateRequest(certificateTypes, supportedSignatureAlgorithms, certificateAuthorities);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2079c1a478381f24892668463073ce18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,215 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Ocsp;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public sealed class CertificateStatus
|
||||
{
|
||||
private readonly short m_statusType;
|
||||
private readonly object m_response;
|
||||
|
||||
public CertificateStatus(short statusType, object response)
|
||||
{
|
||||
if (!IsCorrectType(statusType, response))
|
||||
throw new ArgumentException("not an instance of the correct type", "response");
|
||||
|
||||
this.m_statusType = statusType;
|
||||
this.m_response = response;
|
||||
}
|
||||
|
||||
public short StatusType
|
||||
{
|
||||
get { return m_statusType; }
|
||||
}
|
||||
|
||||
public object Response
|
||||
{
|
||||
get { return m_response; }
|
||||
}
|
||||
|
||||
public OcspResponse OcspResponse
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsCorrectType(CertificateStatusType.ocsp, m_response))
|
||||
throw new InvalidOperationException("'response' is not an OCSPResponse");
|
||||
|
||||
return (OcspResponse)m_response;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>an <see cref="IList{T}"/> of (possibly null) <see cref="Asn1.Ocsp.OcspResponse"/>.</summary>
|
||||
public IList<OcspResponse> OcspResponseList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsCorrectType(CertificateStatusType.ocsp_multi, m_response))
|
||||
throw new InvalidOperationException("'response' is not an OCSPResponseList");
|
||||
|
||||
return (IList<OcspResponse>)m_response;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Encode this <see cref="CertificateStatus"/> to a <see cref="Stream"/>.</summary>
|
||||
/// <param name="output">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(Stream output)
|
||||
{
|
||||
TlsUtilities.WriteUint8(m_statusType, output);
|
||||
|
||||
switch (m_statusType)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
{
|
||||
OcspResponse ocspResponse = (OcspResponse)m_response;
|
||||
byte[] derEncoding = ocspResponse.GetEncoded(Asn1Encodable.Der);
|
||||
TlsUtilities.WriteOpaque24(derEncoding, output);
|
||||
break;
|
||||
}
|
||||
case CertificateStatusType.ocsp_multi:
|
||||
{
|
||||
var ocspResponseList = (IList<OcspResponse>)m_response;
|
||||
int count = ocspResponseList.Count;
|
||||
|
||||
var derEncodings = new List<byte[]>(count);
|
||||
long totalLength = 0;
|
||||
foreach (OcspResponse ocspResponse in ocspResponseList)
|
||||
{
|
||||
if (ocspResponse == null)
|
||||
{
|
||||
derEncodings.Add(TlsUtilities.EmptyBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] derEncoding = ocspResponse.GetEncoded(Asn1Encodable.Der);
|
||||
derEncodings.Add(derEncoding);
|
||||
totalLength += derEncoding.Length;
|
||||
}
|
||||
totalLength += 3;
|
||||
}
|
||||
|
||||
TlsUtilities.CheckUint24(totalLength);
|
||||
TlsUtilities.WriteUint24((int)totalLength, output);
|
||||
|
||||
foreach (byte[] derEncoding in derEncodings)
|
||||
{
|
||||
TlsUtilities.WriteOpaque24(derEncoding, output);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="CertificateStatus"/> from a <see cref="Stream"/>.</summary>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="input">the <see cref="Stream"/> to parse from.</param>
|
||||
/// <returns>a <see cref="CertificateStatus"/> object.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
public static CertificateStatus Parse(TlsContext context, Stream input)
|
||||
{
|
||||
SecurityParameters securityParameters = context.SecurityParameters;
|
||||
|
||||
Certificate peerCertificate = securityParameters.PeerCertificate;
|
||||
if (null == peerCertificate || peerCertificate.IsEmpty
|
||||
|| CertificateType.X509 != peerCertificate.CertificateType)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
int certificateCount = peerCertificate.Length;
|
||||
int statusRequestVersion = securityParameters.StatusRequestVersion;
|
||||
|
||||
short status_type = TlsUtilities.ReadUint8(input);
|
||||
object response;
|
||||
|
||||
switch (status_type)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
{
|
||||
RequireStatusRequestVersion(1, statusRequestVersion);
|
||||
|
||||
byte[] derEncoding = TlsUtilities.ReadOpaque24(input, 1);
|
||||
response = ParseOcspResponse(derEncoding);
|
||||
break;
|
||||
}
|
||||
case CertificateStatusType.ocsp_multi:
|
||||
{
|
||||
RequireStatusRequestVersion(2, statusRequestVersion);
|
||||
|
||||
byte[] ocsp_response_list = TlsUtilities.ReadOpaque24(input, 1);
|
||||
MemoryStream buf = new MemoryStream(ocsp_response_list, false);
|
||||
|
||||
var ocspResponseList = new List<OcspResponse>();
|
||||
while (buf.Position < buf.Length)
|
||||
{
|
||||
if (ocspResponseList.Count >= certificateCount)
|
||||
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
|
||||
|
||||
int length = TlsUtilities.ReadUint24(buf);
|
||||
if (length < 1)
|
||||
{
|
||||
ocspResponseList.Add(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] derEncoding = TlsUtilities.ReadFully(length, buf);
|
||||
ocspResponseList.Add(ParseOcspResponse(derEncoding));
|
||||
}
|
||||
}
|
||||
|
||||
response = ocspResponseList;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
}
|
||||
|
||||
return new CertificateStatus(status_type, response);
|
||||
}
|
||||
|
||||
private static bool IsCorrectType(short statusType, object response)
|
||||
{
|
||||
switch (statusType)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
return response is OcspResponse;
|
||||
case CertificateStatusType.ocsp_multi:
|
||||
return IsOcspResponseList(response);
|
||||
default:
|
||||
throw new ArgumentException("unsupported CertificateStatusType", "statusType");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsOcspResponseList(object response)
|
||||
{
|
||||
return response is IList<OcspResponse> v && v.Count > 0;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
private static OcspResponse ParseOcspResponse(byte[] derEncoding)
|
||||
{
|
||||
Asn1Object asn1 = TlsUtilities.ReadAsn1Object(derEncoding);
|
||||
OcspResponse ocspResponse = OcspResponse.GetInstance(asn1);
|
||||
TlsUtilities.RequireDerEncoding(ocspResponse, derEncoding);
|
||||
return ocspResponse;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
private static void RequireStatusRequestVersion(int minVersion, int statusRequestVersion)
|
||||
{
|
||||
if (statusRequestVersion < minVersion)
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b07e64da0e64f4649bd505dce0fe7b36
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Implementation of the RFC 3546 3.6. CertificateStatusRequest.</summary>
|
||||
public sealed class CertificateStatusRequest
|
||||
{
|
||||
private short m_statusType;
|
||||
private object m_request;
|
||||
|
||||
public CertificateStatusRequest(short statusType, object request)
|
||||
{
|
||||
if (!IsCorrectType(statusType, request))
|
||||
throw new ArgumentException("not an instance of the correct type", "request");
|
||||
|
||||
this.m_statusType = statusType;
|
||||
this.m_request = request;
|
||||
}
|
||||
|
||||
public short StatusType
|
||||
{
|
||||
get { return m_statusType; }
|
||||
}
|
||||
|
||||
public object Request
|
||||
{
|
||||
get { return m_request; }
|
||||
}
|
||||
|
||||
public OcspStatusRequest OcspStatusRequest
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsCorrectType(CertificateStatusType.ocsp, m_request))
|
||||
throw new InvalidOperationException("'request' is not an OCSPStatusRequest");
|
||||
|
||||
return (OcspStatusRequest)m_request;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Encode this <see cref="CertificateStatusRequest"/> to a <see cref="Stream"/>.</summary>
|
||||
/// <param name="output">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(Stream output)
|
||||
{
|
||||
TlsUtilities.WriteUint8(m_statusType, output);
|
||||
|
||||
switch (m_statusType)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
((OcspStatusRequest)m_request).Encode(output);
|
||||
break;
|
||||
default:
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="CertificateStatusRequest"/> from a <see cref="Stream"/>.</summary>
|
||||
/// <param name="input">the <see cref="Stream"/> to parse from.</param>
|
||||
/// <returns>a <see cref="CertificateStatusRequest"/> object.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
public static CertificateStatusRequest Parse(Stream input)
|
||||
{
|
||||
short status_type = TlsUtilities.ReadUint8(input);
|
||||
object request;
|
||||
|
||||
switch (status_type)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
request = OcspStatusRequest.Parse(input);
|
||||
break;
|
||||
default:
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
}
|
||||
|
||||
return new CertificateStatusRequest(status_type, request);
|
||||
}
|
||||
|
||||
private static bool IsCorrectType(short statusType, object request)
|
||||
{
|
||||
switch (statusType)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
return request is OcspStatusRequest;
|
||||
default:
|
||||
throw new ArgumentException("unsupported CertificateStatusType", "statusType");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db1b20f898a4975458cbae73c442ec69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,104 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Implementation of the RFC 6961 2.2. CertificateStatusRequestItemV2.</summary>
|
||||
public sealed class CertificateStatusRequestItemV2
|
||||
{
|
||||
private readonly short m_statusType;
|
||||
private readonly object m_request;
|
||||
|
||||
public CertificateStatusRequestItemV2(short statusType, object request)
|
||||
{
|
||||
if (!IsCorrectType(statusType, request))
|
||||
throw new ArgumentException("not an instance of the correct type", "request");
|
||||
|
||||
this.m_statusType = statusType;
|
||||
this.m_request = request;
|
||||
}
|
||||
|
||||
public short StatusType
|
||||
{
|
||||
get { return m_statusType; }
|
||||
}
|
||||
|
||||
public object Request
|
||||
{
|
||||
get { return m_request; }
|
||||
}
|
||||
|
||||
public OcspStatusRequest OcspStatusRequest
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!(m_request is OcspStatusRequest))
|
||||
throw new InvalidOperationException("'request' is not an OcspStatusRequest");
|
||||
|
||||
return (OcspStatusRequest)m_request;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Encode this <see cref="CertificateStatusRequestItemV2"/> to a <see cref="Stream"/>.</summary>
|
||||
/// <param name="output">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(Stream output)
|
||||
{
|
||||
TlsUtilities.WriteUint8(m_statusType, output);
|
||||
|
||||
MemoryStream buf = new MemoryStream();
|
||||
switch (m_statusType)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
case CertificateStatusType.ocsp_multi:
|
||||
((OcspStatusRequest)m_request).Encode(buf);
|
||||
break;
|
||||
default:
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
byte[] requestBytes = buf.ToArray();
|
||||
TlsUtilities.WriteOpaque16(requestBytes, output);
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="CertificateStatusRequestItemV2"/> from a <see cref="Stream"/>.</summary>
|
||||
/// <param name="input">the <see cref="Stream"/> to parse from.</param>
|
||||
/// <returns>a <see cref="CertificateStatusRequestItemV2"/> object.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
public static CertificateStatusRequestItemV2 Parse(Stream input)
|
||||
{
|
||||
short status_type = TlsUtilities.ReadUint8(input);
|
||||
|
||||
object request;
|
||||
byte[] requestBytes = TlsUtilities.ReadOpaque16(input);
|
||||
MemoryStream buf = new MemoryStream(requestBytes, false);
|
||||
switch (status_type)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
case CertificateStatusType.ocsp_multi:
|
||||
request = OcspStatusRequest.Parse(buf);
|
||||
break;
|
||||
default:
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
}
|
||||
TlsProtocol.AssertEmpty(buf);
|
||||
|
||||
return new CertificateStatusRequestItemV2(status_type, request);
|
||||
}
|
||||
|
||||
private static bool IsCorrectType(short statusType, object request)
|
||||
{
|
||||
switch (statusType)
|
||||
{
|
||||
case CertificateStatusType.ocsp:
|
||||
case CertificateStatusType.ocsp_multi:
|
||||
return request is OcspStatusRequest;
|
||||
default:
|
||||
throw new ArgumentException("unsupported CertificateStatusType", "statusType");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29350c23b9213954189a64330e6f160a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public abstract class CertificateStatusType
|
||||
{
|
||||
/*
|
||||
* RFC 6066
|
||||
*/
|
||||
public const short ocsp = 1;
|
||||
|
||||
/*
|
||||
* RFC 6961
|
||||
*/
|
||||
public const short ocsp_multi = 2;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e16b73164d04fb459a642ebfa576ca2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 6091</summary>
|
||||
public abstract class CertificateType
|
||||
{
|
||||
public const short X509 = 0;
|
||||
public const short OpenPGP = 1;
|
||||
|
||||
/*
|
||||
* RFC 7250
|
||||
*/
|
||||
public const short RawPublicKey = 2;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94887caf243e88146898802a791af23f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,120 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 3546 3.3</summary>
|
||||
public sealed class CertificateUrl
|
||||
{
|
||||
private readonly short m_type;
|
||||
private readonly IList<UrlAndHash> m_urlAndHashList;
|
||||
|
||||
/// <param name="type">see <see cref="CertChainType"/> for valid constants.</param>
|
||||
/// <param name="urlAndHashList">an <see cref="IList{T}"/> of <see cref="UrlAndHash"/>.</param>
|
||||
public CertificateUrl(short type, IList<UrlAndHash> urlAndHashList)
|
||||
{
|
||||
if (!CertChainType.IsValid(type))
|
||||
throw new ArgumentException("not a valid CertChainType value", "type");
|
||||
if (urlAndHashList == null || urlAndHashList.Count < 1)
|
||||
throw new ArgumentException("must have length > 0", "urlAndHashList");
|
||||
if (type == CertChainType.pkipath && urlAndHashList.Count != 1)
|
||||
throw new ArgumentException("must contain exactly one entry when type is "
|
||||
+ CertChainType.GetText(type), "urlAndHashList");
|
||||
|
||||
this.m_type = type;
|
||||
this.m_urlAndHashList = urlAndHashList;
|
||||
}
|
||||
|
||||
/// <returns><see cref="CertChainType"/></returns>
|
||||
public short Type
|
||||
{
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
/// <returns>an <see cref="IList{T}"/> of <see cref="UrlAndHash"/>.</returns>
|
||||
public IList<UrlAndHash> UrlAndHashList
|
||||
{
|
||||
get { return m_urlAndHashList; }
|
||||
}
|
||||
|
||||
/// <summary>Encode this <see cref="CertificateUrl"/> to a <see cref="Stream"/>.</summary>
|
||||
/// <param name="output">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(Stream output)
|
||||
{
|
||||
TlsUtilities.WriteUint8(m_type, output);
|
||||
|
||||
ListBuffer16 buf = new ListBuffer16();
|
||||
foreach (UrlAndHash urlAndHash in m_urlAndHashList)
|
||||
{
|
||||
urlAndHash.Encode(buf);
|
||||
}
|
||||
buf.EncodeTo(output);
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="CertificateUrl"/> from a <see cref="Stream"/>.</summary>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="input">the <see cref="Stream"/> to parse from.</param>
|
||||
/// <returns>a <see cref="CertificateUrl"/> object.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
public static CertificateUrl Parse(TlsContext context, Stream input)
|
||||
{
|
||||
short type = TlsUtilities.ReadUint8(input);
|
||||
if (!CertChainType.IsValid(type))
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
|
||||
int totalLength = TlsUtilities.ReadUint16(input);
|
||||
if (totalLength < 1)
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
|
||||
byte[] urlAndHashListData = TlsUtilities.ReadFully(totalLength, input);
|
||||
|
||||
MemoryStream buf = new MemoryStream(urlAndHashListData, false);
|
||||
|
||||
var url_and_hash_list = new List<UrlAndHash>();
|
||||
while (buf.Position < buf.Length)
|
||||
{
|
||||
UrlAndHash url_and_hash = UrlAndHash.Parse(context, buf);
|
||||
url_and_hash_list.Add(url_and_hash);
|
||||
}
|
||||
|
||||
if (type == CertChainType.pkipath && url_and_hash_list.Count != 1)
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
|
||||
return new CertificateUrl(type, url_and_hash_list);
|
||||
}
|
||||
|
||||
// TODO Could be more generally useful
|
||||
internal class ListBuffer16
|
||||
: MemoryStream
|
||||
{
|
||||
internal ListBuffer16()
|
||||
{
|
||||
// Reserve space for length
|
||||
TlsUtilities.WriteUint16(0, this);
|
||||
}
|
||||
|
||||
internal void EncodeTo(Stream output)
|
||||
{
|
||||
// Patch actual length back in
|
||||
int length = Convert.ToInt32(Length) - 2;
|
||||
TlsUtilities.CheckUint16(length);
|
||||
|
||||
Seek(0L, SeekOrigin.Begin);
|
||||
TlsUtilities.WriteUint16(length, this);
|
||||
|
||||
WriteTo(output);
|
||||
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84ef8dab85a46a449810d359fcb16551
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,61 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public sealed class CertificateVerify
|
||||
{
|
||||
private readonly int m_algorithm;
|
||||
private readonly byte[] m_signature;
|
||||
|
||||
public CertificateVerify(int algorithm, byte[] signature)
|
||||
{
|
||||
if (!TlsUtilities.IsValidUint16(algorithm))
|
||||
throw new ArgumentException("algorithm");
|
||||
if (signature == null)
|
||||
throw new ArgumentNullException("signature");
|
||||
|
||||
this.m_algorithm = algorithm;
|
||||
this.m_signature = signature;
|
||||
}
|
||||
|
||||
/// <returns>a <see cref="SignatureScheme"/> value.</returns>
|
||||
public int Algorithm
|
||||
{
|
||||
get { return m_algorithm; }
|
||||
}
|
||||
|
||||
public byte[] Signature
|
||||
{
|
||||
get { return m_signature; }
|
||||
}
|
||||
|
||||
/// <summary>Encode this <see cref="CertificateVerify"/> to a <see cref="Stream"/>.</summary>
|
||||
/// <param name="output">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(Stream output)
|
||||
{
|
||||
TlsUtilities.WriteUint16(m_algorithm, output);
|
||||
TlsUtilities.WriteOpaque16(m_signature, output);
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="CertificateVerify"/> from a <see cref="Stream"/>.</summary>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="input">the <see cref="Stream"/> to parse from.</param>
|
||||
/// <returns>a <see cref="CertificateVerify"/> object.</returns>
|
||||
/// <exception cref="IOException"/>
|
||||
public static CertificateVerify Parse(TlsContext context, Stream input)
|
||||
{
|
||||
if (!TlsUtilities.IsTlsV13(context))
|
||||
throw new InvalidOperationException();
|
||||
|
||||
int algorithm = TlsUtilities.ReadUint16(input);
|
||||
byte[] signature = TlsUtilities.ReadOpaque16(input);
|
||||
return new CertificateVerify(algorithm, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e72d5eef8356da2429d50ff32b574022
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public abstract class ChangeCipherSpec
|
||||
{
|
||||
public const short change_cipher_spec = 1;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abd61c678ec2de2479a9b76e4d22047d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 5056</summary>
|
||||
/// <remarks>
|
||||
/// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the
|
||||
/// particular values (e.g.serialization).
|
||||
/// </remarks>
|
||||
public abstract class ChannelBinding
|
||||
{
|
||||
/*
|
||||
* RFC 5929
|
||||
*/
|
||||
public const int tls_server_end_point = 0;
|
||||
public const int tls_unique = 1;
|
||||
public const int tls_unique_for_telnet = 2;
|
||||
|
||||
/*
|
||||
* RFC 9266
|
||||
*/
|
||||
public const int tls_exporter = 3;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bcbccea8f960014c9a97a53a5fb8ddb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,465 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 2246 A.5</summary>
|
||||
public abstract class CipherSuite
|
||||
{
|
||||
public static bool IsScsv(int cipherSuite)
|
||||
{
|
||||
switch (cipherSuite)
|
||||
{
|
||||
case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
|
||||
case TLS_FALLBACK_SCSV:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public const int TLS_NULL_WITH_NULL_NULL = 0x0000;
|
||||
public const int TLS_RSA_WITH_NULL_MD5 = 0x0001;
|
||||
public const int TLS_RSA_WITH_NULL_SHA = 0x0002;
|
||||
public const int TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003;
|
||||
public const int TLS_RSA_WITH_RC4_128_MD5 = 0x0004;
|
||||
public const int TLS_RSA_WITH_RC4_128_SHA = 0x0005;
|
||||
public const int TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006;
|
||||
public const int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007;
|
||||
public const int TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008;
|
||||
public const int TLS_RSA_WITH_DES_CBC_SHA = 0x0009;
|
||||
public const int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A;
|
||||
public const int TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B;
|
||||
public const int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C;
|
||||
public const int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D;
|
||||
public const int TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E;
|
||||
public const int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F;
|
||||
public const int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010;
|
||||
public const int TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011;
|
||||
public const int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012;
|
||||
public const int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013;
|
||||
public const int TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014;
|
||||
public const int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015;
|
||||
public const int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016;
|
||||
public const int TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017;
|
||||
public const int TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018;
|
||||
public const int TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x0019;
|
||||
public const int TLS_DH_anon_WITH_DES_CBC_SHA = 0x001A;
|
||||
public const int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B;
|
||||
|
||||
/*
|
||||
* Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are reserved to avoid
|
||||
* collision with Fortezza-based cipher suites in SSL 3.
|
||||
*/
|
||||
|
||||
/*
|
||||
* RFC 3268
|
||||
*/
|
||||
public const int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F;
|
||||
public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030;
|
||||
public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031;
|
||||
public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032;
|
||||
public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033;
|
||||
public const int TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034;
|
||||
public const int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035;
|
||||
public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036;
|
||||
public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037;
|
||||
public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038;
|
||||
public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039;
|
||||
public const int TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A;
|
||||
|
||||
/*
|
||||
* RFC 5932
|
||||
*/
|
||||
public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041;
|
||||
public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042;
|
||||
public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043;
|
||||
public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044;
|
||||
public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045;
|
||||
public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046;
|
||||
|
||||
public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084;
|
||||
public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085;
|
||||
public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086;
|
||||
public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087;
|
||||
public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088;
|
||||
public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089;
|
||||
|
||||
public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA;
|
||||
public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB;
|
||||
public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC;
|
||||
public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD;
|
||||
public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE;
|
||||
public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF;
|
||||
|
||||
public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0;
|
||||
public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1;
|
||||
public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2;
|
||||
public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3;
|
||||
public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4;
|
||||
public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5;
|
||||
|
||||
/*
|
||||
* RFC 4162
|
||||
*/
|
||||
public const int TLS_RSA_WITH_SEED_CBC_SHA = 0x0096;
|
||||
public const int TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097;
|
||||
public const int TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098;
|
||||
public const int TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099;
|
||||
public const int TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A;
|
||||
public const int TLS_DH_anon_WITH_SEED_CBC_SHA = 0x009B;
|
||||
|
||||
/*
|
||||
* RFC 4279
|
||||
*/
|
||||
public const int TLS_PSK_WITH_RC4_128_SHA = 0x008A;
|
||||
public const int TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B;
|
||||
public const int TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C;
|
||||
public const int TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D;
|
||||
public const int TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E;
|
||||
public const int TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F;
|
||||
public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090;
|
||||
public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091;
|
||||
public const int TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092;
|
||||
public const int TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093;
|
||||
public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094;
|
||||
public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095;
|
||||
|
||||
/*
|
||||
* RFC 4492
|
||||
*/
|
||||
public const int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001;
|
||||
public const int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002;
|
||||
public const int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003;
|
||||
public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004;
|
||||
public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A;
|
||||
public const int TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B;
|
||||
public const int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C;
|
||||
public const int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D;
|
||||
public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E;
|
||||
public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F;
|
||||
public const int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010;
|
||||
public const int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011;
|
||||
public const int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012;
|
||||
public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013;
|
||||
public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
|
||||
public const int TLS_ECDH_anon_WITH_NULL_SHA = 0xC015;
|
||||
public const int TLS_ECDH_anon_WITH_RC4_128_SHA = 0xC016;
|
||||
public const int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017;
|
||||
public const int TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018;
|
||||
public const int TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019;
|
||||
|
||||
/*
|
||||
* RFC 4785
|
||||
*/
|
||||
public const int TLS_PSK_WITH_NULL_SHA = 0x002C;
|
||||
public const int TLS_DHE_PSK_WITH_NULL_SHA = 0x002D;
|
||||
public const int TLS_RSA_PSK_WITH_NULL_SHA = 0x002E;
|
||||
|
||||
/*
|
||||
* RFC 5054
|
||||
*/
|
||||
public const int TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A;
|
||||
public const int TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B;
|
||||
public const int TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C;
|
||||
public const int TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D;
|
||||
public const int TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E;
|
||||
public const int TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F;
|
||||
public const int TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020;
|
||||
public const int TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021;
|
||||
public const int TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022;
|
||||
|
||||
/*
|
||||
* RFC 5246
|
||||
*/
|
||||
public const int TLS_RSA_WITH_NULL_SHA256 = 0x003B;
|
||||
public const int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C;
|
||||
public const int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D;
|
||||
public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E;
|
||||
public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F;
|
||||
public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040;
|
||||
public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067;
|
||||
public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068;
|
||||
public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069;
|
||||
public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A;
|
||||
public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B;
|
||||
public const int TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C;
|
||||
public const int TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D;
|
||||
|
||||
/*
|
||||
* RFC 5288
|
||||
*/
|
||||
public const int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C;
|
||||
public const int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D;
|
||||
public const int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E;
|
||||
public const int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F;
|
||||
public const int TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0;
|
||||
public const int TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1;
|
||||
public const int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2;
|
||||
public const int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3;
|
||||
public const int TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4;
|
||||
public const int TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5;
|
||||
public const int TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6;
|
||||
public const int TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7;
|
||||
|
||||
/*
|
||||
* RFC 5289
|
||||
*/
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024;
|
||||
public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025;
|
||||
public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026;
|
||||
public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027;
|
||||
public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028;
|
||||
public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029;
|
||||
public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C;
|
||||
public const int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D;
|
||||
public const int TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E;
|
||||
public const int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F;
|
||||
public const int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030;
|
||||
public const int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031;
|
||||
public const int TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032;
|
||||
|
||||
/*
|
||||
* RFC 5487
|
||||
*/
|
||||
public const int TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8;
|
||||
public const int TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9;
|
||||
public const int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA;
|
||||
public const int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB;
|
||||
public const int TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC;
|
||||
public const int TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD;
|
||||
public const int TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE;
|
||||
public const int TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF;
|
||||
public const int TLS_PSK_WITH_NULL_SHA256 = 0x00B0;
|
||||
public const int TLS_PSK_WITH_NULL_SHA384 = 0x00B1;
|
||||
public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2;
|
||||
public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3;
|
||||
public const int TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4;
|
||||
public const int TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5;
|
||||
public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6;
|
||||
public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7;
|
||||
public const int TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8;
|
||||
public const int TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9;
|
||||
|
||||
/*
|
||||
* RFC 5489
|
||||
*/
|
||||
public const int TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033;
|
||||
public const int TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034;
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035;
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036;
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037;
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038;
|
||||
public const int TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039;
|
||||
public const int TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A;
|
||||
public const int TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B;
|
||||
|
||||
/*
|
||||
* RFC 5746
|
||||
*/
|
||||
public const int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF;
|
||||
|
||||
/*
|
||||
* RFC 6209
|
||||
*/
|
||||
public const int TLS_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC03C;
|
||||
public const int TLS_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC03D;
|
||||
public const int TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC03E;
|
||||
public const int TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC03F;
|
||||
public const int TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC040;
|
||||
public const int TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC041;
|
||||
public const int TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC042;
|
||||
public const int TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC043;
|
||||
public const int TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC044;
|
||||
public const int TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC045;
|
||||
public const int TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 = 0xC046;
|
||||
public const int TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 = 0xC047;
|
||||
|
||||
public const int TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC048;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC049;
|
||||
public const int TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC04A;
|
||||
public const int TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC04B;
|
||||
public const int TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04C;
|
||||
public const int TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04D;
|
||||
public const int TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04E;
|
||||
public const int TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04F;
|
||||
|
||||
public const int TLS_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC050;
|
||||
public const int TLS_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC051;
|
||||
public const int TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC052;
|
||||
public const int TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC053;
|
||||
public const int TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC054;
|
||||
public const int TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC055;
|
||||
public const int TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC056;
|
||||
public const int TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC057;
|
||||
public const int TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC058;
|
||||
public const int TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC059;
|
||||
public const int TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 = 0xC05A;
|
||||
public const int TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 = 0xC05B;
|
||||
|
||||
public const int TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05C;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05D;
|
||||
public const int TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05E;
|
||||
public const int TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05F;
|
||||
public const int TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC060;
|
||||
public const int TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC061;
|
||||
public const int TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC062;
|
||||
public const int TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC063;
|
||||
|
||||
public const int TLS_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC064;
|
||||
public const int TLS_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC065;
|
||||
public const int TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC066;
|
||||
public const int TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC067;
|
||||
public const int TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC068;
|
||||
public const int TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC069;
|
||||
public const int TLS_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06A;
|
||||
public const int TLS_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06B;
|
||||
public const int TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06C;
|
||||
public const int TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06D;
|
||||
public const int TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06E;
|
||||
public const int TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06F;
|
||||
public const int TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC070;
|
||||
public const int TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC071;
|
||||
|
||||
/*
|
||||
* RFC 6367
|
||||
*/
|
||||
public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073;
|
||||
public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074;
|
||||
public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075;
|
||||
public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076;
|
||||
public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077;
|
||||
public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078;
|
||||
public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079;
|
||||
|
||||
public const int TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A;
|
||||
public const int TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B;
|
||||
public const int TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C;
|
||||
public const int TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D;
|
||||
public const int TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E;
|
||||
public const int TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F;
|
||||
public const int TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080;
|
||||
public const int TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081;
|
||||
public const int TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082;
|
||||
public const int TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083;
|
||||
public const int TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084;
|
||||
public const int TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087;
|
||||
public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088;
|
||||
public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089;
|
||||
public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A;
|
||||
public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B;
|
||||
public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C;
|
||||
public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D;
|
||||
|
||||
public const int TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E;
|
||||
public const int TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F;
|
||||
public const int TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090;
|
||||
public const int TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091;
|
||||
public const int TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092;
|
||||
public const int TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093;
|
||||
public const int TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094;
|
||||
public const int TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095;
|
||||
public const int TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096;
|
||||
public const int TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097;
|
||||
public const int TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098;
|
||||
public const int TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099;
|
||||
public const int TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A;
|
||||
public const int TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B;
|
||||
|
||||
/*
|
||||
* RFC 6655
|
||||
*/
|
||||
public const int TLS_RSA_WITH_AES_128_CCM = 0xC09C;
|
||||
public const int TLS_RSA_WITH_AES_256_CCM = 0xC09D;
|
||||
public const int TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E;
|
||||
public const int TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F;
|
||||
public const int TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0;
|
||||
public const int TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1;
|
||||
public const int TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2;
|
||||
public const int TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3;
|
||||
public const int TLS_PSK_WITH_AES_128_CCM = 0xC0A4;
|
||||
public const int TLS_PSK_WITH_AES_256_CCM = 0xC0A5;
|
||||
public const int TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6;
|
||||
public const int TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7;
|
||||
public const int TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8;
|
||||
public const int TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9;
|
||||
public const int TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA;
|
||||
public const int TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB;
|
||||
|
||||
/*
|
||||
* RFC 7251
|
||||
*/
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF;
|
||||
|
||||
/*
|
||||
* RFC 7507
|
||||
*/
|
||||
public const int TLS_FALLBACK_SCSV = 0x5600;
|
||||
|
||||
/*
|
||||
* RFC 7905
|
||||
*/
|
||||
public const int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8;
|
||||
public const int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9;
|
||||
public const int TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA;
|
||||
public const int TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB;
|
||||
public const int TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC;
|
||||
public const int TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD;
|
||||
public const int TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAE;
|
||||
|
||||
/*
|
||||
* RFC 8442
|
||||
*/
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = 0xD001;
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = 0xD002;
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256 = 0xD003;
|
||||
public const int TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 = 0xD005;
|
||||
|
||||
/*
|
||||
* TLS 1.3 Section
|
||||
*
|
||||
* Although TLS 1.3 uses the same cipher suite space as previous versions of TLS, TLS 1.3 cipher
|
||||
* suites are defined differently, only specifying the symmetric ciphers, and cannot be used for
|
||||
* TLS 1.2. Similarly, cipher suites for TLS 1.2 and lower cannot be used with TLS 1.3.
|
||||
*/
|
||||
|
||||
/*
|
||||
* RFC 8446
|
||||
*/
|
||||
public const int TLS_AES_128_GCM_SHA256 = 0x1301;
|
||||
public const int TLS_AES_256_GCM_SHA384 = 0x1302;
|
||||
public const int TLS_CHACHA20_POLY1305_SHA256 = 0x1303;
|
||||
public const int TLS_AES_128_CCM_SHA256 = 0x1304;
|
||||
public const int TLS_AES_128_CCM_8_SHA256 = 0x1305;
|
||||
|
||||
/*
|
||||
* RFC 8998
|
||||
*/
|
||||
public const int TLS_SM4_GCM_SM3 = 0x00C6;
|
||||
public const int TLS_SM4_CCM_SM3 = 0x00C7;
|
||||
|
||||
/*
|
||||
* draft-smyshlyaev-tls12-gost-suites-10
|
||||
*/
|
||||
public const int TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC = 0xC100;
|
||||
public const int TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC = 0xC101;
|
||||
public const int TLS_GOSTR341112_256_WITH_28147_CNT_IMIT = 0xC102;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 425a37738dc6b3746bb219567a5a4f15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 2246</summary>
|
||||
/// <remarks>
|
||||
/// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the
|
||||
/// particular values (e.g. serialization).
|
||||
/// </remarks>
|
||||
public abstract class CipherType
|
||||
{
|
||||
public const int stream = 0;
|
||||
public const int block = 1;
|
||||
|
||||
/*
|
||||
* RFC 5246
|
||||
*/
|
||||
public const int aead = 2;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b405b048b793e8f4488759616ce161c9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public abstract class ClientAuthenticationType
|
||||
{
|
||||
/*
|
||||
* RFC 5077 4
|
||||
*/
|
||||
public const short anonymous = 0;
|
||||
public const short certificate_based = 1;
|
||||
public const short psk = 2;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d9bfacecd6d3b041be7d33b3a51aebb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public abstract class ClientCertificateType
|
||||
{
|
||||
/*
|
||||
* RFC 4346 7.4.4
|
||||
*/
|
||||
public const short rsa_sign = 1;
|
||||
public const short dss_sign = 2;
|
||||
public const short rsa_fixed_dh = 3;
|
||||
public const short dss_fixed_dh = 4;
|
||||
public const short rsa_ephemeral_dh_RESERVED = 5;
|
||||
public const short dss_ephemeral_dh_RESERVED = 6;
|
||||
public const short fortezza_dms_RESERVED = 20;
|
||||
|
||||
/*
|
||||
* RFC 4492 5.5
|
||||
*/
|
||||
public const short ecdsa_sign = 64;
|
||||
public const short rsa_fixed_ecdh = 65;
|
||||
public const short ecdsa_fixed_ecdh = 66;
|
||||
|
||||
/*
|
||||
* draft-smyshlyaev-tls12-gost-suites-10
|
||||
*/
|
||||
public const short gost_sign256 = 67;
|
||||
public const short gost_sign512 = 68;
|
||||
|
||||
public static string GetName(short clientCertificateType)
|
||||
{
|
||||
switch (clientCertificateType)
|
||||
{
|
||||
case rsa_sign:
|
||||
return "rsa_sign";
|
||||
case dss_sign:
|
||||
return "dss_sign";
|
||||
case rsa_fixed_dh:
|
||||
return "rsa_fixed_dh";
|
||||
case dss_fixed_dh:
|
||||
return "dss_fixed_dh";
|
||||
case rsa_ephemeral_dh_RESERVED:
|
||||
return "rsa_ephemeral_dh_RESERVED";
|
||||
case dss_ephemeral_dh_RESERVED:
|
||||
return "dss_ephemeral_dh_RESERVED";
|
||||
case fortezza_dms_RESERVED:
|
||||
return "fortezza_dms_RESERVED";
|
||||
case ecdsa_sign:
|
||||
return "ecdsa_sign";
|
||||
case rsa_fixed_ecdh:
|
||||
return "rsa_fixed_ecdh";
|
||||
case ecdsa_fixed_ecdh:
|
||||
return "ecdsa_fixed_ecdh";
|
||||
case gost_sign256:
|
||||
return "gost_sign256";
|
||||
case gost_sign512:
|
||||
return "gost_sign512";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(short clientCertificateType)
|
||||
{
|
||||
return GetName(clientCertificateType) + "(" + clientCertificateType + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cec7dd44279bd7d44b134bdac988039d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,181 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public sealed class ClientHello
|
||||
{
|
||||
private readonly ProtocolVersion m_version;
|
||||
private readonly byte[] m_random;
|
||||
private readonly byte[] m_sessionID;
|
||||
private readonly byte[] m_cookie;
|
||||
private readonly int[] m_cipherSuites;
|
||||
private readonly IDictionary<int, byte[]> m_extensions;
|
||||
private readonly int m_bindersSize;
|
||||
|
||||
public ClientHello(ProtocolVersion version, byte[] random, byte[] sessionID, byte[] cookie,
|
||||
int[] cipherSuites, IDictionary<int, byte[]> extensions, int bindersSize)
|
||||
{
|
||||
this.m_version = version;
|
||||
this.m_random = random;
|
||||
this.m_sessionID = sessionID;
|
||||
this.m_cookie = cookie;
|
||||
this.m_cipherSuites = cipherSuites;
|
||||
this.m_extensions = extensions;
|
||||
this.m_bindersSize = bindersSize;
|
||||
}
|
||||
|
||||
public int BindersSize
|
||||
{
|
||||
get { return m_bindersSize; }
|
||||
}
|
||||
|
||||
public int[] CipherSuites
|
||||
{
|
||||
get { return m_cipherSuites; }
|
||||
}
|
||||
|
||||
public byte[] Cookie
|
||||
{
|
||||
get { return m_cookie; }
|
||||
}
|
||||
|
||||
public IDictionary<int, byte[]> Extensions
|
||||
{
|
||||
get { return m_extensions; }
|
||||
}
|
||||
|
||||
public byte[] Random
|
||||
{
|
||||
get { return m_random; }
|
||||
}
|
||||
|
||||
public byte[] SessionID
|
||||
{
|
||||
get { return m_sessionID; }
|
||||
}
|
||||
|
||||
public ProtocolVersion Version
|
||||
{
|
||||
get { return m_version; }
|
||||
}
|
||||
|
||||
/// <summary>Encode this <see cref="ClientHello"/> to a <see cref="Stream"/>.</summary>
|
||||
/// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
|
||||
/// <param name="output">the <see cref="Stream"/> to encode to.</param>
|
||||
/// <exception cref="IOException"/>
|
||||
public void Encode(TlsContext context, Stream output)
|
||||
{
|
||||
if (m_bindersSize < 0)
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
|
||||
TlsUtilities.WriteVersion(m_version, output);
|
||||
|
||||
output.Write(m_random, 0, m_random.Length);
|
||||
|
||||
TlsUtilities.WriteOpaque8(m_sessionID, output);
|
||||
|
||||
if (null != m_cookie)
|
||||
{
|
||||
TlsUtilities.WriteOpaque8(m_cookie, output);
|
||||
}
|
||||
|
||||
TlsUtilities.WriteUint16ArrayWithUint16Length(m_cipherSuites, output);
|
||||
|
||||
TlsUtilities.WriteUint8ArrayWithUint8Length(new short[]{ CompressionMethod.cls_null }, output);
|
||||
|
||||
TlsProtocol.WriteExtensions(output, m_extensions, m_bindersSize);
|
||||
}
|
||||
|
||||
/// <summary>Parse a <see cref="ClientHello"/> from a <see cref="MemoryStream"/>.</summary>
|
||||
/// <param name="messageInput">the <see cref="MemoryStream"/> to parse from.</param>
|
||||
/// <param name="dtlsOutput">for DTLS this should be non-null; the input is copied to this
|
||||
/// <see cref="Stream"/>, minus the cookie field.</param>
|
||||
/// <returns>a <see cref="ClientHello"/> object.</returns>
|
||||
/// <exception cref="TlsFatalAlert"/>
|
||||
public static ClientHello Parse(MemoryStream messageInput, Stream dtlsOutput)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ImplParse(messageInput, dtlsOutput);
|
||||
}
|
||||
catch (TlsFatalAlert e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
private static ClientHello ImplParse(MemoryStream messageInput, Stream dtlsOutput)
|
||||
{
|
||||
Stream input = messageInput;
|
||||
if (null != dtlsOutput)
|
||||
{
|
||||
input = new TeeInputStream(input, dtlsOutput);
|
||||
}
|
||||
|
||||
ProtocolVersion clientVersion = TlsUtilities.ReadVersion(input);
|
||||
|
||||
byte[] random = TlsUtilities.ReadFully(32, input);
|
||||
|
||||
byte[] sessionID = TlsUtilities.ReadOpaque8(input, 0, 32);
|
||||
|
||||
byte[] cookie = null;
|
||||
if (null != dtlsOutput)
|
||||
{
|
||||
/*
|
||||
* RFC 6347 This specification increases the cookie size limit to 255 bytes for greater
|
||||
* future flexibility. The limit remains 32 for previous versions of DTLS.
|
||||
*/
|
||||
int maxCookieLength = ProtocolVersion.DTLSv12.IsEqualOrEarlierVersionOf(clientVersion) ? 255 : 32;
|
||||
|
||||
cookie = TlsUtilities.ReadOpaque8(messageInput, 0, maxCookieLength);
|
||||
}
|
||||
|
||||
int cipher_suites_length = TlsUtilities.ReadUint16(input);
|
||||
if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0
|
||||
|| Convert.ToInt32(messageInput.Length - messageInput.Position) < cipher_suites_length)
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: "If the session_id field is not empty (implying a session resumption request) this
|
||||
* vector must include at least the cipher_suite from that session."
|
||||
*/
|
||||
int[] cipherSuites = TlsUtilities.ReadUint16Array(cipher_suites_length / 2, input);
|
||||
|
||||
short[] compressionMethods = TlsUtilities.ReadUint8ArrayWithUint8Length(input, 1);
|
||||
if (!Arrays.Contains(compressionMethods, CompressionMethod.cls_null))
|
||||
throw new TlsFatalAlert(AlertDescription.handshake_failure);
|
||||
|
||||
/*
|
||||
* NOTE: Can't use TlsProtocol.ReadExtensions directly because TeeInputStream a) won't have
|
||||
* 'Length' or 'Position' properties in the FIPS provider, b) isn't a MemoryStream.
|
||||
*/
|
||||
IDictionary<int, byte[]> extensions = null;
|
||||
if (messageInput.Position < messageInput.Length)
|
||||
{
|
||||
byte[] extBytes = TlsUtilities.ReadOpaque16(input);
|
||||
|
||||
TlsProtocol.AssertEmpty(messageInput);
|
||||
|
||||
extensions = TlsProtocol.ReadExtensionsDataClientHello(extBytes);
|
||||
}
|
||||
|
||||
return new ClientHello(clientVersion, random, sessionID, cookie, cipherSuites, extensions, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79bf6a99ebdfa7447a7e8db8429b7045
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>A combined hash, which implements md5(m) || sha1(m).</summary>
|
||||
public class CombinedHash
|
||||
: TlsHash
|
||||
{
|
||||
protected readonly TlsContext m_context;
|
||||
protected readonly TlsCrypto m_crypto;
|
||||
protected readonly TlsHash m_md5;
|
||||
protected readonly TlsHash m_sha1;
|
||||
|
||||
internal CombinedHash(TlsContext context, TlsHash md5, TlsHash sha1)
|
||||
{
|
||||
this.m_context = context;
|
||||
this.m_crypto = context.Crypto;
|
||||
this.m_md5 = md5;
|
||||
this.m_sha1 = sha1;
|
||||
}
|
||||
|
||||
public CombinedHash(TlsCrypto crypto)
|
||||
{
|
||||
this.m_crypto = crypto;
|
||||
this.m_md5 = crypto.CreateHash(CryptoHashAlgorithm.md5);
|
||||
this.m_sha1 = crypto.CreateHash(CryptoHashAlgorithm.sha1);
|
||||
}
|
||||
|
||||
public CombinedHash(CombinedHash t)
|
||||
{
|
||||
this.m_context = t.m_context;
|
||||
this.m_crypto = t.m_crypto;
|
||||
this.m_md5 = t.m_md5.CloneHash();
|
||||
this.m_sha1 = t.m_sha1.CloneHash();
|
||||
}
|
||||
|
||||
public virtual void Update(byte[] input, int inOff, int len)
|
||||
{
|
||||
m_md5.Update(input, inOff, len);
|
||||
m_sha1.Update(input, inOff, len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public void Update(ReadOnlySpan<byte> input)
|
||||
{
|
||||
m_md5.Update(input);
|
||||
m_sha1.Update(input);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual byte[] CalculateHash()
|
||||
{
|
||||
if (null != m_context && TlsUtilities.IsSsl(m_context))
|
||||
{
|
||||
Ssl3Utilities.CompleteCombinedHash(m_context, m_md5, m_sha1);
|
||||
}
|
||||
|
||||
return Arrays.Concatenate(m_md5.CalculateHash(), m_sha1.CalculateHash());
|
||||
}
|
||||
|
||||
public virtual TlsHash CloneHash()
|
||||
{
|
||||
return new CombinedHash(this);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
m_md5.Reset();
|
||||
m_sha1.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee4acf699dca9064b8e29a2c0f999456
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 2246 6.1</summary>
|
||||
public abstract class CompressionMethod
|
||||
{
|
||||
public const short cls_null = 0;
|
||||
|
||||
/*
|
||||
* RFC 3749 2
|
||||
*/
|
||||
public const short DEFLATE = 1;
|
||||
|
||||
/*
|
||||
* Values from 224 decimal (0xE0) through 255 decimal (0xFF)
|
||||
* inclusive are reserved for private use.
|
||||
*/
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b20d7a5d708bbab40983e29a05322a03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 2246</summary>
|
||||
/// <remarks>
|
||||
/// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the
|
||||
/// particular values(e.g.serialization).
|
||||
/// </remarks>
|
||||
public abstract class ConnectionEnd
|
||||
{
|
||||
public const int server = 0;
|
||||
public const int client = 1;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 509c5f8c2b8be8540a69b8b93b0188b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>RFC 2246 6.2.1</summary>
|
||||
public abstract class ContentType
|
||||
{
|
||||
public const short change_cipher_spec = 20;
|
||||
public const short alert = 21;
|
||||
public const short handshake = 22;
|
||||
public const short application_data = 23;
|
||||
public const short heartbeat = 24;
|
||||
|
||||
public static string GetName(short contentType)
|
||||
{
|
||||
switch (contentType)
|
||||
{
|
||||
case alert:
|
||||
return "alert";
|
||||
case application_data:
|
||||
return "application_data";
|
||||
case change_cipher_spec:
|
||||
return "change_cipher_spec";
|
||||
case handshake:
|
||||
return "handshake";
|
||||
case heartbeat:
|
||||
return "heartbeat";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(short contentType)
|
||||
{
|
||||
return GetName(contentType) + "(" + contentType + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14836a5f99a425545bdc1a08bd7b3467
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public interface DatagramReceiver
|
||||
{
|
||||
/// <exception cref="IOException"/>
|
||||
int GetReceiveLimit();
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
int Receive(byte[] buf, int off, int len, int waitMillis);
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
/// <exception cref="IOException"/>
|
||||
int Receive(Span<byte> buffer, int waitMillis);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4991430345dc35478aebc69807d33d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public interface DatagramSender
|
||||
{
|
||||
/// <exception cref="IOException"/>
|
||||
int GetSendLimit();
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
void Send(byte[] buf, int off, int len);
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
/// <exception cref="IOException"/>
|
||||
void Send(ReadOnlySpan<byte> buffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d8e332e062b12b4fb2ee69bb3ea9729
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Base interface for an object sending and receiving DTLS data.</summary>
|
||||
public interface DatagramTransport
|
||||
: DatagramReceiver, DatagramSender, TlsCloseable
|
||||
{
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 968c0f58d4cd5bc43848df9a1ee167c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public abstract class DefaultTlsClient
|
||||
: AbstractTlsClient
|
||||
{
|
||||
private static readonly int[] DefaultCipherSuites = new int[]
|
||||
{
|
||||
/*
|
||||
* TLS 1.3
|
||||
*/
|
||||
CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite.TLS_AES_128_GCM_SHA256,
|
||||
|
||||
/*
|
||||
* pre-TLS 1.3
|
||||
*/
|
||||
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256,
|
||||
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
};
|
||||
|
||||
public DefaultTlsClient(TlsCrypto crypto)
|
||||
: base(crypto)
|
||||
{
|
||||
}
|
||||
|
||||
protected override int[] GetSupportedCipherSuites()
|
||||
{
|
||||
return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d1f5a57a4dddc64f858a5c168e225cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Container class for generating signatures that carries the signature type, parameters, public key
|
||||
/// certificate and public key's associated signer object.</summary>
|
||||
public class DefaultTlsCredentialedSigner
|
||||
: TlsCredentialedSigner
|
||||
{
|
||||
protected readonly TlsCryptoParameters m_cryptoParams;
|
||||
protected readonly Certificate m_certificate;
|
||||
protected readonly SignatureAndHashAlgorithm m_signatureAndHashAlgorithm;
|
||||
protected readonly TlsSigner m_signer;
|
||||
|
||||
public DefaultTlsCredentialedSigner(TlsCryptoParameters cryptoParams, TlsSigner signer,
|
||||
Certificate certificate, SignatureAndHashAlgorithm signatureAndHashAlgorithm)
|
||||
{
|
||||
if (certificate == null)
|
||||
throw new ArgumentNullException("certificate");
|
||||
if (certificate.IsEmpty)
|
||||
throw new ArgumentException("cannot be empty", "certificate");
|
||||
if (signer == null)
|
||||
throw new ArgumentNullException("signer");
|
||||
|
||||
this.m_cryptoParams = cryptoParams;
|
||||
this.m_certificate = certificate;
|
||||
this.m_signatureAndHashAlgorithm = signatureAndHashAlgorithm;
|
||||
this.m_signer = signer;
|
||||
}
|
||||
|
||||
public virtual Certificate Certificate
|
||||
{
|
||||
get { return m_certificate; }
|
||||
}
|
||||
|
||||
public virtual byte[] GenerateRawSignature(byte[] hash)
|
||||
{
|
||||
return m_signer.GenerateRawSignature(GetEffectiveAlgorithm(), hash);
|
||||
}
|
||||
|
||||
public virtual SignatureAndHashAlgorithm SignatureAndHashAlgorithm
|
||||
{
|
||||
get { return m_signatureAndHashAlgorithm; }
|
||||
}
|
||||
|
||||
public virtual TlsStreamSigner GetStreamSigner()
|
||||
{
|
||||
return m_signer.GetStreamSigner(GetEffectiveAlgorithm());
|
||||
}
|
||||
|
||||
protected virtual SignatureAndHashAlgorithm GetEffectiveAlgorithm()
|
||||
{
|
||||
SignatureAndHashAlgorithm algorithm = null;
|
||||
if (TlsImplUtilities.IsTlsV12(m_cryptoParams))
|
||||
{
|
||||
algorithm = SignatureAndHashAlgorithm;
|
||||
if (algorithm == null)
|
||||
throw new InvalidOperationException("'signatureAndHashAlgorithm' cannot be null for (D)TLS 1.2+");
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25d031312974584478be22ad3b3870c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,110 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public class DefaultTlsDHGroupVerifier
|
||||
: TlsDHGroupVerifier
|
||||
{
|
||||
public static readonly int DefaultMinimumPrimeBits = 2048;
|
||||
|
||||
private static readonly List<DHGroup> DefaultGroups = new List<DHGroup>();
|
||||
|
||||
private static void AddDefaultGroup(DHGroup dhGroup)
|
||||
{
|
||||
DefaultGroups.Add(dhGroup);
|
||||
}
|
||||
|
||||
static DefaultTlsDHGroupVerifier()
|
||||
{
|
||||
/*
|
||||
* These 10 standard groups are those specified in NIST SP 800-56A Rev. 3 Appendix D. Make
|
||||
* sure to consider the impact on BCJSSE's FIPS mode and/or usage with the BCFIPS provider
|
||||
* before modifying this list.
|
||||
*/
|
||||
|
||||
AddDefaultGroup(DHStandardGroups.rfc3526_2048);
|
||||
AddDefaultGroup(DHStandardGroups.rfc3526_3072);
|
||||
AddDefaultGroup(DHStandardGroups.rfc3526_4096);
|
||||
AddDefaultGroup(DHStandardGroups.rfc3526_6144);
|
||||
AddDefaultGroup(DHStandardGroups.rfc3526_8192);
|
||||
|
||||
AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe2048);
|
||||
AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe3072);
|
||||
AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe4096);
|
||||
AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe6144);
|
||||
AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe8192);
|
||||
}
|
||||
|
||||
// IList is (DHGroup)
|
||||
protected readonly IList<DHGroup> m_groups;
|
||||
protected readonly int m_minimumPrimeBits;
|
||||
|
||||
/// <summary>Accept named groups and various standard DH groups with 'P' at least
|
||||
/// <see cref="DefaultMinimumPrimeBits"/> bits.</summary>
|
||||
public DefaultTlsDHGroupVerifier()
|
||||
: this(DefaultMinimumPrimeBits)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Accept named groups and various standard DH groups with 'P' at least the specified number of bits.
|
||||
/// </summary>
|
||||
/// <param name="minimumPrimeBits">the minimum bitlength of 'P'.</param>
|
||||
public DefaultTlsDHGroupVerifier(int minimumPrimeBits)
|
||||
: this(DefaultGroups, minimumPrimeBits)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Accept named groups and a custom set of group parameters, subject to a minimum bitlength for 'P'.
|
||||
/// </summary>
|
||||
/// <param name="groups">a <see cref="IList{T}">list</see> of acceptable <see cref="DHGroup"/>s.</param>
|
||||
/// <param name="minimumPrimeBits">the minimum bitlength of 'P'.</param>
|
||||
public DefaultTlsDHGroupVerifier(IList<DHGroup> groups, int minimumPrimeBits)
|
||||
{
|
||||
this.m_groups = new List<DHGroup>(groups);
|
||||
this.m_minimumPrimeBits = minimumPrimeBits;
|
||||
}
|
||||
|
||||
public virtual bool Accept(DHGroup dhGroup)
|
||||
{
|
||||
return CheckMinimumPrimeBits(dhGroup) && CheckGroup(dhGroup);
|
||||
}
|
||||
|
||||
public virtual int MinimumPrimeBits
|
||||
{
|
||||
get { return m_minimumPrimeBits; }
|
||||
}
|
||||
|
||||
protected virtual bool AreGroupsEqual(DHGroup a, DHGroup b)
|
||||
{
|
||||
return a == b || (AreParametersEqual(a.P, b.P) && AreParametersEqual(a.G, b.G));
|
||||
}
|
||||
|
||||
protected virtual bool AreParametersEqual(BigInteger a, BigInteger b)
|
||||
{
|
||||
return a == b || a.Equals(b);
|
||||
}
|
||||
|
||||
protected virtual bool CheckGroup(DHGroup dhGroup)
|
||||
{
|
||||
foreach (DHGroup group in m_groups)
|
||||
{
|
||||
if (AreGroupsEqual(dhGroup, group))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool CheckMinimumPrimeBits(DHGroup dhGroup)
|
||||
{
|
||||
return dhGroup.P.BitLength >= MinimumPrimeBits;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 577b30bd159b5ab459df3f258a3b7c6f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public class DefaultTlsHeartbeat
|
||||
: TlsHeartbeat
|
||||
{
|
||||
private readonly int idleMillis, timeoutMillis;
|
||||
|
||||
private uint counter = 0U;
|
||||
|
||||
public DefaultTlsHeartbeat(int idleMillis, int timeoutMillis)
|
||||
{
|
||||
if (idleMillis <= 0)
|
||||
throw new ArgumentException("must be > 0", "idleMillis");
|
||||
if (timeoutMillis <= 0)
|
||||
throw new ArgumentException("must be > 0", "timeoutMillis");
|
||||
|
||||
this.idleMillis = idleMillis;
|
||||
this.timeoutMillis = timeoutMillis;
|
||||
}
|
||||
|
||||
public virtual byte[] GeneratePayload()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
// NOTE: The counter naturally wraps back to 0
|
||||
return Pack.UInt32_To_BE(++counter);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int IdleMillis
|
||||
{
|
||||
get { return idleMillis; }
|
||||
}
|
||||
|
||||
public virtual int TimeoutMillis
|
||||
{
|
||||
get { return timeoutMillis; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8465826a6c3e6b949ac7c9e8a4c572b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public class DefaultTlsKeyExchangeFactory
|
||||
: AbstractTlsKeyExchangeFactory
|
||||
{
|
||||
public override TlsKeyExchange CreateDHKeyExchange(int keyExchange)
|
||||
{
|
||||
return new TlsDHKeyExchange(keyExchange);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateDHanonKeyExchangeClient(int keyExchange,
|
||||
TlsDHGroupVerifier dhGroupVerifier)
|
||||
{
|
||||
return new TlsDHanonKeyExchange(keyExchange, dhGroupVerifier);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateDHanonKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig)
|
||||
{
|
||||
return new TlsDHanonKeyExchange(keyExchange, dhConfig);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateDheKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier)
|
||||
{
|
||||
return new TlsDheKeyExchange(keyExchange, dhGroupVerifier);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateDheKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig)
|
||||
{
|
||||
return new TlsDheKeyExchange(keyExchange, dhConfig);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateECDHKeyExchange(int keyExchange)
|
||||
{
|
||||
return new TlsECDHKeyExchange(keyExchange);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateECDHanonKeyExchangeClient(int keyExchange)
|
||||
{
|
||||
return new TlsECDHanonKeyExchange(keyExchange);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateECDHanonKeyExchangeServer(int keyExchange, TlsECConfig ecConfig)
|
||||
{
|
||||
return new TlsECDHanonKeyExchange(keyExchange, ecConfig);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateECDheKeyExchangeClient(int keyExchange)
|
||||
{
|
||||
return new TlsECDheKeyExchange(keyExchange);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateECDheKeyExchangeServer(int keyExchange, TlsECConfig ecConfig)
|
||||
{
|
||||
return new TlsECDheKeyExchange(keyExchange, ecConfig);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreatePskKeyExchangeClient(int keyExchange, TlsPskIdentity pskIdentity,
|
||||
TlsDHGroupVerifier dhGroupVerifier)
|
||||
{
|
||||
return new TlsPskKeyExchange(keyExchange, pskIdentity, dhGroupVerifier);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreatePskKeyExchangeServer(int keyExchange,
|
||||
TlsPskIdentityManager pskIdentityManager, TlsDHConfig dhConfig, TlsECConfig ecConfig)
|
||||
{
|
||||
return new TlsPskKeyExchange(keyExchange, pskIdentityManager, dhConfig, ecConfig);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateRsaKeyExchange(int keyExchange)
|
||||
{
|
||||
return new TlsRsaKeyExchange(keyExchange);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateSrpKeyExchangeClient(int keyExchange, TlsSrpIdentity srpIdentity,
|
||||
TlsSrpConfigVerifier srpConfigVerifier)
|
||||
{
|
||||
return new TlsSrpKeyExchange(keyExchange, srpIdentity, srpConfigVerifier);
|
||||
}
|
||||
|
||||
public override TlsKeyExchange CreateSrpKeyExchangeServer(int keyExchange, TlsSrpLoginParameters loginParameters)
|
||||
{
|
||||
return new TlsSrpKeyExchange(keyExchange, loginParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de66321bb455cd14b913f20feeb89812
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,108 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public abstract class DefaultTlsServer
|
||||
: AbstractTlsServer
|
||||
{
|
||||
private static readonly int[] DefaultCipherSuites = new int[]
|
||||
{
|
||||
/*
|
||||
* TLS 1.3
|
||||
*/
|
||||
CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite.TLS_AES_256_GCM_SHA384,
|
||||
CipherSuite.TLS_AES_128_GCM_SHA256,
|
||||
|
||||
/*
|
||||
* pre-TLS 1.3
|
||||
*/
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256,
|
||||
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256,
|
||||
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
};
|
||||
|
||||
public DefaultTlsServer(TlsCrypto crypto)
|
||||
: base(crypto)
|
||||
{
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
protected virtual TlsCredentialedSigner GetDsaSignerCredentials()
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
protected virtual TlsCredentialedSigner GetECDsaSignerCredentials()
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
protected virtual TlsCredentialedDecryptor GetRsaEncryptionCredentials()
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
protected virtual TlsCredentialedSigner GetRsaSignerCredentials()
|
||||
{
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
|
||||
protected override int[] GetSupportedCipherSuites()
|
||||
{
|
||||
return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites);
|
||||
}
|
||||
|
||||
public override TlsCredentials GetCredentials()
|
||||
{
|
||||
int keyExchangeAlgorithm = m_context.SecurityParameters.KeyExchangeAlgorithm;
|
||||
|
||||
switch (keyExchangeAlgorithm)
|
||||
{
|
||||
case KeyExchangeAlgorithm.DHE_DSS:
|
||||
return GetDsaSignerCredentials();
|
||||
|
||||
case KeyExchangeAlgorithm.ECDHE_ECDSA:
|
||||
return GetECDsaSignerCredentials();
|
||||
|
||||
case KeyExchangeAlgorithm.DHE_RSA:
|
||||
case KeyExchangeAlgorithm.ECDHE_RSA:
|
||||
return GetRsaSignerCredentials();
|
||||
|
||||
case KeyExchangeAlgorithm.RSA:
|
||||
return GetRsaEncryptionCredentials();
|
||||
|
||||
default:
|
||||
// Note: internal error here; selected a key exchange we don't implement!
|
||||
throw new TlsFatalAlert(AlertDescription.internal_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85c5c2e4344a02547a6d09066d95f3fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
public class DefaultTlsSrpConfigVerifier
|
||||
: TlsSrpConfigVerifier
|
||||
{
|
||||
private static readonly List<Srp6Group> DefaultGroups = new List<Srp6Group>();
|
||||
|
||||
static DefaultTlsSrpConfigVerifier()
|
||||
{
|
||||
DefaultGroups.Add(Srp6StandardGroups.rfc5054_1024);
|
||||
DefaultGroups.Add(Srp6StandardGroups.rfc5054_1536);
|
||||
DefaultGroups.Add(Srp6StandardGroups.rfc5054_2048);
|
||||
DefaultGroups.Add(Srp6StandardGroups.rfc5054_3072);
|
||||
DefaultGroups.Add(Srp6StandardGroups.rfc5054_4096);
|
||||
DefaultGroups.Add(Srp6StandardGroups.rfc5054_6144);
|
||||
DefaultGroups.Add(Srp6StandardGroups.rfc5054_8192);
|
||||
}
|
||||
|
||||
// IList is (SRP6Group)
|
||||
protected readonly IList<Srp6Group> m_groups;
|
||||
|
||||
/// <summary>Accept only the group parameters specified in RFC 5054 Appendix A.</summary>
|
||||
public DefaultTlsSrpConfigVerifier()
|
||||
: this(DefaultGroups)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specify a custom set of acceptable group parameters.</summary>
|
||||
/// <param name="groups">an <see cref="IList{T}"/> of acceptable <see cref="Srp6Group"/>.</param>
|
||||
public DefaultTlsSrpConfigVerifier(IList<Srp6Group> groups)
|
||||
{
|
||||
this.m_groups = new List<Srp6Group>(groups);
|
||||
}
|
||||
|
||||
public virtual bool Accept(TlsSrpConfig srpConfig)
|
||||
{
|
||||
foreach (Srp6Group group in m_groups)
|
||||
{
|
||||
if (AreGroupsEqual(srpConfig, group))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool AreGroupsEqual(TlsSrpConfig a, Srp6Group b)
|
||||
{
|
||||
BigInteger[] ng = a.GetExplicitNG();
|
||||
return AreParametersEqual(ng[0], b.N) && AreParametersEqual(ng[1], b.G);
|
||||
}
|
||||
|
||||
protected virtual bool AreParametersEqual(BigInteger a, BigInteger b)
|
||||
{
|
||||
return a == b || a.Equals(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 228995bc4bcda8e4abaf5414b67c51c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,260 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
/// <summary>Buffers input until the hash algorithm is determined.</summary>
|
||||
internal sealed class DeferredHash
|
||||
: TlsHandshakeHash
|
||||
{
|
||||
private const int BufferingHashLimit = 4;
|
||||
|
||||
private readonly TlsContext m_context;
|
||||
|
||||
private DigestInputBuffer m_buf;
|
||||
private IDictionary<int, TlsHash> m_hashes;
|
||||
private bool m_forceBuffering;
|
||||
private bool m_sealed;
|
||||
|
||||
internal DeferredHash(TlsContext context)
|
||||
{
|
||||
this.m_context = context;
|
||||
this.m_buf = new DigestInputBuffer();
|
||||
this.m_hashes = new Dictionary<int, TlsHash>();
|
||||
this.m_forceBuffering = false;
|
||||
this.m_sealed = false;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
public void CopyBufferTo(Stream output)
|
||||
{
|
||||
if (m_buf == null)
|
||||
{
|
||||
// If you see this, you need to call ForceBuffering() before SealHashAlgorithms()
|
||||
throw new InvalidOperationException("Not buffering");
|
||||
}
|
||||
|
||||
m_buf.CopyInputTo(output);
|
||||
}
|
||||
|
||||
public void ForceBuffering()
|
||||
{
|
||||
if (m_sealed)
|
||||
throw new InvalidOperationException("Too late to force buffering");
|
||||
|
||||
this.m_forceBuffering = true;
|
||||
}
|
||||
|
||||
public void NotifyPrfDetermined()
|
||||
{
|
||||
SecurityParameters securityParameters = m_context.SecurityParameters;
|
||||
|
||||
switch (securityParameters.PrfAlgorithm)
|
||||
{
|
||||
case PrfAlgorithm.ssl_prf_legacy:
|
||||
case PrfAlgorithm.tls_prf_legacy:
|
||||
{
|
||||
CheckTrackingHash(CryptoHashAlgorithm.md5);
|
||||
CheckTrackingHash(CryptoHashAlgorithm.sha1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
CheckTrackingHash(securityParameters.PrfCryptoHashAlgorithm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void TrackHashAlgorithm(int cryptoHashAlgorithm)
|
||||
{
|
||||
if (m_sealed)
|
||||
throw new InvalidOperationException("Too late to track more hash algorithms");
|
||||
|
||||
CheckTrackingHash(cryptoHashAlgorithm);
|
||||
}
|
||||
|
||||
public void SealHashAlgorithms()
|
||||
{
|
||||
if (m_sealed)
|
||||
throw new InvalidOperationException("Already sealed");
|
||||
|
||||
this.m_sealed = true;
|
||||
CheckStopBuffering();
|
||||
}
|
||||
|
||||
public void StopTracking()
|
||||
{
|
||||
SecurityParameters securityParameters = m_context.SecurityParameters;
|
||||
|
||||
IDictionary<int, TlsHash> newHashes = new Dictionary<int, TlsHash>();
|
||||
switch (securityParameters.PrfAlgorithm)
|
||||
{
|
||||
case PrfAlgorithm.ssl_prf_legacy:
|
||||
case PrfAlgorithm.tls_prf_legacy:
|
||||
{
|
||||
CloneHash(newHashes, CryptoHashAlgorithm.md5);
|
||||
CloneHash(newHashes, CryptoHashAlgorithm.sha1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
CloneHash(newHashes, securityParameters.PrfCryptoHashAlgorithm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.m_buf = null;
|
||||
this.m_hashes = newHashes;
|
||||
this.m_forceBuffering = false;
|
||||
this.m_sealed = true;
|
||||
}
|
||||
|
||||
public TlsHash ForkPrfHash()
|
||||
{
|
||||
CheckStopBuffering();
|
||||
|
||||
SecurityParameters securityParameters = m_context.SecurityParameters;
|
||||
|
||||
TlsHash prfHash;
|
||||
switch (securityParameters.PrfAlgorithm)
|
||||
{
|
||||
case PrfAlgorithm.ssl_prf_legacy:
|
||||
case PrfAlgorithm.tls_prf_legacy:
|
||||
{
|
||||
TlsHash md5Hash = CloneHash(CryptoHashAlgorithm.md5);
|
||||
TlsHash sha1Hash = CloneHash(CryptoHashAlgorithm.sha1);
|
||||
prfHash = new CombinedHash(m_context, md5Hash, sha1Hash);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
prfHash = CloneHash(securityParameters.PrfCryptoHashAlgorithm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_buf != null)
|
||||
{
|
||||
m_buf.UpdateDigest(prfHash);
|
||||
}
|
||||
|
||||
return prfHash;
|
||||
}
|
||||
|
||||
public byte[] GetFinalHash(int cryptoHashAlgorithm)
|
||||
{
|
||||
if (!m_hashes.TryGetValue(cryptoHashAlgorithm, out var hash))
|
||||
throw new InvalidOperationException("CryptoHashAlgorithm." + cryptoHashAlgorithm
|
||||
+ " is not being tracked");
|
||||
|
||||
CheckStopBuffering();
|
||||
|
||||
hash = hash.CloneHash();
|
||||
if (m_buf != null)
|
||||
{
|
||||
m_buf.UpdateDigest(hash);
|
||||
}
|
||||
|
||||
return hash.CalculateHash();
|
||||
}
|
||||
|
||||
public void Update(byte[] input, int inOff, int len)
|
||||
{
|
||||
if (m_buf != null)
|
||||
{
|
||||
m_buf.Write(input, inOff, len);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (TlsHash hash in m_hashes.Values)
|
||||
{
|
||||
hash.Update(input, inOff, len);
|
||||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public void Update(ReadOnlySpan<byte> input)
|
||||
{
|
||||
if (m_buf != null)
|
||||
{
|
||||
m_buf.Write(input);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (TlsHash hash in m_hashes.Values)
|
||||
{
|
||||
hash.Update(input);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public byte[] CalculateHash()
|
||||
{
|
||||
throw new InvalidOperationException("Use 'ForkPrfHash' to get a definite hash");
|
||||
}
|
||||
|
||||
public TlsHash CloneHash()
|
||||
{
|
||||
throw new InvalidOperationException("attempt to clone a DeferredHash");
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (m_buf != null)
|
||||
{
|
||||
m_buf.SetLength(0);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (TlsHash hash in m_hashes.Values)
|
||||
{
|
||||
hash.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckStopBuffering()
|
||||
{
|
||||
if (!m_forceBuffering && m_sealed && m_buf != null && m_hashes.Count <= BufferingHashLimit)
|
||||
{
|
||||
foreach (TlsHash hash in m_hashes.Values)
|
||||
{
|
||||
m_buf.UpdateDigest(hash);
|
||||
}
|
||||
|
||||
this.m_buf = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTrackingHash(int cryptoHashAlgorithm)
|
||||
{
|
||||
if (!m_hashes.ContainsKey(cryptoHashAlgorithm))
|
||||
{
|
||||
TlsHash hash = m_context.Crypto.CreateHash(cryptoHashAlgorithm);
|
||||
m_hashes[cryptoHashAlgorithm] = hash;
|
||||
}
|
||||
}
|
||||
|
||||
private TlsHash CloneHash(int cryptoHashAlgorithm)
|
||||
{
|
||||
return m_hashes[cryptoHashAlgorithm].CloneHash();
|
||||
}
|
||||
|
||||
private void CloneHash(IDictionary<int, TlsHash> newHashes, int cryptoHashAlgorithm)
|
||||
{
|
||||
TlsHash hash = CloneHash(cryptoHashAlgorithm);
|
||||
if (m_buf != null)
|
||||
{
|
||||
m_buf.UpdateDigest(hash);
|
||||
}
|
||||
newHashes[cryptoHashAlgorithm] = hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc14c8f46d63ab24aa903171e71c2f9d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
|
||||
{
|
||||
internal class DigestInputBuffer
|
||||
: MemoryStream
|
||||
{
|
||||
internal void UpdateDigest(TlsHash hash)
|
||||
{
|
||||
WriteTo(new TlsHashSink(hash));
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"/>
|
||||
internal void CopyInputTo(Stream output)
|
||||
{
|
||||
// TODO[tls] Consider defensive copy if 'output' might be external code
|
||||
WriteTo(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 094d1c0928915c04683e61973dbbaa76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user