<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

BcTlsCrypto

using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Agreement.Srp; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Macs; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Prng; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using System; using System.Collections.Generic; namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { public class BcTlsCrypto : AbstractTlsCrypto { private readonly SecureRandom m_entropySource; public override SecureRandom SecureRandom => m_entropySource; public BcTlsCrypto() : this(CryptoServicesRegistrar.GetSecureRandom()) { } public BcTlsCrypto(SecureRandom entropySource) { if (entropySource == null) throw new ArgumentNullException("entropySource"); m_entropySource = entropySource; } internal virtual BcTlsSecret AdoptLocalSecret(byte[] data) { return new BcTlsSecret(this, data); } public override TlsCertificate CreateCertificate(short type, byte[] encoding) { switch (type) { case 0: return new BcTlsCertificate(this, encoding); case 2: return new BcTlsRawKeyCertificate(this, encoding); default: throw new TlsFatalAlert(80); } } public override TlsCipher CreateCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm, int macAlgorithm) { switch (encryptionAlgorithm) { case 8: case 12: case 14: case 22: case 28: return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 16, macAlgorithm); case 7: return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 24, macAlgorithm); case 9: case 13: case 23: return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 32, macAlgorithm); case 15: return CreateCipher_Aes_Ccm(cryptoParams, 16, 16); case 16: return CreateCipher_Aes_Ccm(cryptoParams, 16, 8); case 10: return CreateCipher_Aes_Gcm(cryptoParams, 16, 16); case 17: return CreateCipher_Aes_Ccm(cryptoParams, 32, 16); case 18: return CreateCipher_Aes_Ccm(cryptoParams, 32, 8); case 11: return CreateCipher_Aes_Gcm(cryptoParams, 32, 16); case 24: return CreateCipher_Aria_Gcm(cryptoParams, 16, 16); case 25: return CreateCipher_Aria_Gcm(cryptoParams, 32, 16); case 19: return CreateCipher_Camellia_Gcm(cryptoParams, 16, 16); case 20: return CreateCipher_Camellia_Gcm(cryptoParams, 32, 16); case 21: return CreateChaCha20Poly1305(cryptoParams); case 0: return CreateNullCipher(cryptoParams, macAlgorithm); case 26: return CreateCipher_SM4_Ccm(cryptoParams); case 27: return CreateCipher_SM4_Gcm(cryptoParams); default: throw new TlsFatalAlert(80); } } public override TlsDHDomain CreateDHDomain(TlsDHConfig dhConfig) { return new BcTlsDHDomain(this, dhConfig); } public override TlsECDomain CreateECDomain(TlsECConfig ecConfig) { switch (ecConfig.NamedGroup) { case 29: return new BcX25519Domain(this); case 30: return new BcX448Domain(this); default: return new BcTlsECDomain(this, ecConfig); } } public override TlsKemDomain CreateKemDomain(TlsKemConfig kemConfig) { return new BcTlsMLKemDomain(this, kemConfig); } public override TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial) { int cryptoHashAlgorithm = 4; IDigest digest = CreateDigest(cryptoHashAlgorithm); byte[] array = new byte[2 * TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm)]; SecureRandom.NextBytes(array); DigestRandomGenerator digestRandomGenerator = new DigestRandomGenerator(digest); digestRandomGenerator.AddSeedMaterial(additionalSeedMaterial); digestRandomGenerator.AddSeedMaterial(array); return new BcTlsNonceGenerator(digestRandomGenerator); } public override bool HasAnyStreamVerifiers(IList<SignatureAndHashAlgorithm> signatureAndHashAlgorithms) { foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in signatureAndHashAlgorithms) { int num = SignatureScheme.From(signatureAndHashAlgorithm); if ((uint)(num - 2055) <= 1) return true; } return false; } public override bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes) { return false; } public override bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm) { if ((uint)(cryptoHashAlgorithm - 1) <= 7) return true; return false; } public override bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm) { if ((uint)(cryptoSignatureAlgorithm - 1) <= 10) return true; if ((uint)(cryptoSignatureAlgorithm - 64) > 1 && cryptoSignatureAlgorithm == 200) goto IL_001a; goto IL_001a; IL_001a: return false; } public override bool HasDHAgreement() { return true; } public override bool HasECDHAgreement() { return true; } public override bool HasEncryptionAlgorithm(int encryptionAlgorithm) { switch (encryptionAlgorithm) { case 0: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: return true; default: return false; } } public override bool HasHkdfAlgorithm(int cryptoHashAlgorithm) { if ((uint)(cryptoHashAlgorithm - 4) <= 3) return true; return false; } public override bool HasKemAgreement() { return true; } public override bool HasMacAlgorithm(int macAlgorithm) { if ((uint)(macAlgorithm - 1) <= 4) return true; return false; } public override bool HasNamedGroup(int namedGroup) { if (!NamedGroup.RefersToASpecificCurve(namedGroup) && !NamedGroup.RefersToASpecificFiniteField(namedGroup)) return NamedGroup.RefersToASpecificKem(namedGroup); return true; } public override bool HasRsaEncryption() { return true; } public override bool HasSignatureAlgorithm(short signatureAlgorithm) { if ((uint)(signatureAlgorithm - 1) <= 10 || (uint)(signatureAlgorithm - 26) <= 2) return true; if ((uint)(signatureAlgorithm - 64) <= 1) goto IL_0019; goto IL_0019; IL_0019: return false; } public override bool HasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm) { short signature = sigAndHashAlgorithm.Signature; if (sigAndHashAlgorithm.Hash == 1) { if (1 == signature) return HasSignatureAlgorithm(signature); return false; } return HasSignatureAlgorithm(signature); } public override bool HasSignatureScheme(int signatureScheme) { if (signatureScheme == 1800 || (uint)(signatureScheme - 2308) <= 2) return false; short signatureAlgorithm = SignatureScheme.GetSignatureAlgorithm(signatureScheme); if (SignatureScheme.GetCryptoHashAlgorithm(signatureScheme) == 1) { if (1 == signatureAlgorithm) return HasSignatureAlgorithm(signatureAlgorithm); return false; } return HasSignatureAlgorithm(signatureAlgorithm); } public override bool HasSrpAuthentication() { return true; } public override TlsSecret CreateHybridSecret(TlsSecret s1, TlsSecret s2) { return AdoptLocalSecret(Arrays.Concatenate(s1.Extract(), s2.Extract())); } public override TlsSecret CreateSecret(byte[] data) { return AdoptLocalSecret(Arrays.Clone(data)); } public override TlsSecret GenerateRsaPreMasterSecret(ProtocolVersion version) { byte[] array = new byte[48]; SecureRandom.NextBytes(array); TlsUtilities.WriteVersion(version, array, 0); return AdoptLocalSecret(array); } public virtual IDigest CloneDigest(int cryptoHashAlgorithm, IDigest digest) { switch (cryptoHashAlgorithm) { case 1: return new MD5Digest((MD5Digest)digest); case 2: return new Sha1Digest((Sha1Digest)digest); case 3: return new Sha224Digest((Sha224Digest)digest); case 4: return new Sha256Digest((Sha256Digest)digest); case 5: return new Sha384Digest((Sha384Digest)digest); case 6: return new Sha512Digest((Sha512Digest)digest); case 7: return new SM3Digest((SM3Digest)digest); case 8: return new Gost3411_2012_256Digest((Gost3411_2012_256Digest)digest); default: throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm.ToString()); } } public virtual IDigest CreateDigest(int cryptoHashAlgorithm) { switch (cryptoHashAlgorithm) { case 1: return new MD5Digest(); case 2: return new Sha1Digest(); case 3: return new Sha224Digest(); case 4: return new Sha256Digest(); case 5: return new Sha384Digest(); case 6: return new Sha512Digest(); case 7: return new SM3Digest(); case 8: return new Gost3411_2012_256Digest(); default: throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm.ToString()); } } public override TlsHash CreateHash(int cryptoHashAlgorithm) { return new BcTlsHash(this, cryptoHashAlgorithm); } protected virtual IBlockCipher CreateBlockCipher(int encryptionAlgorithm) { switch (encryptionAlgorithm) { default: if ((uint)(encryptionAlgorithm - 22) <= 1) return CreateAriaEngine(); if (encryptionAlgorithm == 28) return CreateSM4Engine(); break; case 7: return CreateDesEdeEngine(); case 8: case 9: return CreateAesEngine(); case 12: case 13: return CreateCamelliaEngine(); case 14: return CreateSeedEngine(); case 10: case 11: break; } throw new TlsFatalAlert(80); } protected virtual IBlockCipher CreateCbcBlockCipher(IBlockCipher blockCipher) { return new CbcBlockCipher(blockCipher); } protected virtual IBlockCipher CreateCbcBlockCipher(int encryptionAlgorithm) { return CreateCbcBlockCipher(CreateBlockCipher(encryptionAlgorithm)); } protected virtual TlsCipher CreateChaCha20Poly1305(TlsCryptoParameters cryptoParams) { BcChaCha20Poly1305 encryptCipher = new BcChaCha20Poly1305(true); BcChaCha20Poly1305 decryptCipher = new BcChaCha20Poly1305(false); return new TlsAeadCipher(cryptoParams, encryptCipher, decryptCipher, 32, 16, 2); } protected virtual TlsAeadCipher CreateCipher_Aes_Ccm(TlsCryptoParameters cryptoParams, int cipherKeySize, int macSize) { BcTlsCcmImpl encryptCipher = new BcTlsCcmImpl(CreateAeadCipher_Aes_Ccm(), true); BcTlsCcmImpl decryptCipher = new BcTlsCcmImpl(CreateAeadCipher_Aes_Ccm(), false); return new TlsAeadCipher(cryptoParams, encryptCipher, decryptCipher, cipherKeySize, macSize, 1); } protected virtual TlsAeadCipher CreateCipher_Aes_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize, int macSize) { BcTlsAeadCipherImpl encryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Gcm(), true); BcTlsAeadCipherImpl decryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Gcm(), false); return new TlsAeadCipher(cryptoParams, encryptCipher, decryptCipher, cipherKeySize, macSize, 3); } protected virtual TlsAeadCipher CreateCipher_Aria_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize, int macSize) { BcTlsAeadCipherImpl encryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_Aria_Gcm(), true); BcTlsAeadCipherImpl decryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_Aria_Gcm(), false); return new TlsAeadCipher(cryptoParams, encryptCipher, decryptCipher, cipherKeySize, macSize, 3); } protected virtual TlsAeadCipher CreateCipher_Camellia_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize, int macSize) { BcTlsAeadCipherImpl encryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_Camellia_Gcm(), true); BcTlsAeadCipherImpl decryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_Camellia_Gcm(), false); return new TlsAeadCipher(cryptoParams, encryptCipher, decryptCipher, cipherKeySize, macSize, 3); } protected virtual TlsCipher CreateCipher_Cbc(TlsCryptoParameters cryptoParams, int encryptionAlgorithm, int cipherKeySize, int macAlgorithm) { BcTlsBlockCipherImpl encryptCipher = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), true); BcTlsBlockCipherImpl decryptCipher = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), false); TlsHmac clientMac = CreateMac(cryptoParams, macAlgorithm); TlsHmac serverMac = CreateMac(cryptoParams, macAlgorithm); return new TlsBlockCipher(cryptoParams, encryptCipher, decryptCipher, clientMac, serverMac, cipherKeySize); } protected virtual TlsAeadCipher CreateCipher_SM4_Ccm(TlsCryptoParameters cryptoParams) { BcTlsCcmImpl encryptCipher = new BcTlsCcmImpl(CreateAeadCipher_SM4_Ccm(), true); BcTlsCcmImpl decryptCipher = new BcTlsCcmImpl(CreateAeadCipher_SM4_Ccm(), false); return new TlsAeadCipher(cryptoParams, encryptCipher, decryptCipher, 16, 16, 1); } protected virtual TlsAeadCipher CreateCipher_SM4_Gcm(TlsCryptoParameters cryptoParams) { BcTlsAeadCipherImpl encryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Gcm(), true); BcTlsAeadCipherImpl decryptCipher = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Gcm(), false); return new TlsAeadCipher(cryptoParams, encryptCipher, decryptCipher, 16, 16, 3); } protected virtual TlsNullCipher CreateNullCipher(TlsCryptoParameters cryptoParams, int macAlgorithm) { return new TlsNullCipher(cryptoParams, CreateMac(cryptoParams, macAlgorithm), CreateMac(cryptoParams, macAlgorithm)); } protected virtual IBlockCipher CreateAesEngine() { return AesUtilities.CreateEngine(); } protected virtual IBlockCipher CreateAriaEngine() { return new AriaEngine(); } protected virtual IBlockCipher CreateCamelliaEngine() { return new CamelliaEngine(); } protected virtual IBlockCipher CreateDesEdeEngine() { return new DesEdeEngine(); } protected virtual IBlockCipher CreateSeedEngine() { return new SeedEngine(); } protected virtual IBlockCipher CreateSM4Engine() { return new SM4Engine(); } protected virtual CcmBlockCipher CreateCcmMode(IBlockCipher engine) { return new CcmBlockCipher(engine); } protected virtual IAeadCipher CreateGcmMode(IBlockCipher engine) { return new GcmBlockCipher(engine); } protected virtual CcmBlockCipher CreateAeadCipher_Aes_Ccm() { return CreateCcmMode(CreateAesEngine()); } protected virtual IAeadCipher CreateAeadCipher_Aes_Gcm() { return CreateGcmMode(CreateAesEngine()); } protected virtual IAeadCipher CreateAeadCipher_Aria_Gcm() { return CreateGcmMode(CreateAriaEngine()); } protected virtual IAeadCipher CreateAeadCipher_Camellia_Gcm() { return CreateGcmMode(CreateCamelliaEngine()); } protected virtual CcmBlockCipher CreateAeadCipher_SM4_Ccm() { return CreateCcmMode(CreateSM4Engine()); } protected virtual IAeadCipher CreateAeadCipher_SM4_Gcm() { return CreateGcmMode(CreateSM4Engine()); } public override TlsHmac CreateHmac(int macAlgorithm) { if ((uint)(macAlgorithm - 1) <= 4) return CreateHmacForHash(TlsCryptoUtilities.GetHashForHmac(macAlgorithm)); throw new ArgumentException("invalid MacAlgorithm: " + macAlgorithm.ToString()); } public override TlsHmac CreateHmacForHash(int cryptoHashAlgorithm) { return new BcTlsHmac(new HMac(CreateDigest(cryptoHashAlgorithm))); } protected virtual TlsHmac CreateHmac_Ssl(int macAlgorithm) { switch (macAlgorithm) { case 1: return new BcSsl3Hmac(CreateDigest(1)); case 2: return new BcSsl3Hmac(CreateDigest(2)); case 3: return new BcSsl3Hmac(CreateDigest(4)); case 4: return new BcSsl3Hmac(CreateDigest(5)); case 5: return new BcSsl3Hmac(CreateDigest(6)); default: throw new TlsFatalAlert(80); } } protected virtual TlsHmac CreateMac(TlsCryptoParameters cryptoParams, int macAlgorithm) { if (TlsImplUtilities.IsSsl(cryptoParams)) return CreateHmac_Ssl(macAlgorithm); return CreateHmac(macAlgorithm); } public override TlsSrp6Client CreateSrp6Client(TlsSrpConfig srpConfig) { BigInteger[] explicitNG = srpConfig.GetExplicitNG(); Srp6GroupParameters group = new Srp6GroupParameters(explicitNG[0], explicitNG[1]); Srp6Client srp6Client = new Srp6Client(); srp6Client.Init(group, CreateDigest(2), SecureRandom); return new BcTlsSrp6Client(srp6Client); } public override TlsSrp6Server CreateSrp6Server(TlsSrpConfig srpConfig, BigInteger srpVerifier) { BigInteger[] explicitNG = srpConfig.GetExplicitNG(); Srp6GroupParameters group = new Srp6GroupParameters(explicitNG[0], explicitNG[1]); Srp6Server srp6Server = new Srp6Server(); srp6Server.Init(group, srpVerifier, CreateDigest(2), SecureRandom); return new BcTlsSrp6Server(srp6Server); } public override TlsSrp6VerifierGenerator CreateSrp6VerifierGenerator(TlsSrpConfig srpConfig) { BigInteger[] explicitNG = srpConfig.GetExplicitNG(); Srp6VerifierGenerator srp6VerifierGenerator = new Srp6VerifierGenerator(); srp6VerifierGenerator.Init(explicitNG[0], explicitNG[1], CreateDigest(2)); return new BcTlsSrp6VerifierGenerator(srp6VerifierGenerator); } public override TlsSecret HkdfInit(int cryptoHashAlgorithm) { return AdoptLocalSecret(new byte[TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm)]); } } }