public KeyBlock(CipherSuite cipherSuite, byte[] masterSecret, byte[] seed) { DeriveBytes deriveBytes = cipherSuite.PseudoRandomFunction.CreateDeriveBytes(masterSecret, "key expansion", seed); ClientWriteMACKey = deriveBytes.GetBytes(cipherSuite.MACAlgorithm.HashSize); ServerWriteMACKey = deriveBytes.GetBytes(cipherSuite.MACAlgorithm.HashSize); ClientWriteKey = deriveBytes.GetBytes(cipherSuite.BulkCipherAlgorithm.KeySize); ServerWriteKey = deriveBytes.GetBytes(cipherSuite.BulkCipherAlgorithm.KeySize); ClientWriteIV = deriveBytes.GetBytes(cipherSuite.BulkCipherAlgorithm.FixedIVLength); ServerWriteIV = deriveBytes.GetBytes(cipherSuite.BulkCipherAlgorithm.FixedIVLength); }
public RecordHandler(ProtocolVersion version, bool isClient) { _isClient = isClient; // Start with NULL cipher suite and key block _nextCipherSuite = new CipherSuite(version); _nextKeyBlock = new KeyBlock(); // Initialize all the other variables ChangeLocalState(); ChangeRemoteState(); _inputEpoch = 0; _outputEpoch = 0; }
public TLSRecordHandlerTest(string server, int port) { string path = System.Reflection.Assembly.GetAssembly(typeof(TLSRecordHandlerTest)).Location; string directory = Path.GetDirectoryName(path); _server = server; _port = port; _pluginManager = new CipherSuitePluginManager(directory); _cipherSuite = _pluginManager.GetCipherSuite(VERSION, CIPHER_SUITE); if (_cipherSuite != null) { Console.WriteLine("Got cipher suite"); } else { throw new Exception("Error finding cipher suite!"); } _recordHandler = new RecordHandler(VERSION, true); }
public CipherSuite GetCipherSuite(ProtocolVersion version, UInt16 id) { CipherSuiteInfo cipherSuiteInfo = null; foreach (CipherSuitePlugin plugin in _plugins) { List<UInt16> supported = new List<UInt16>(plugin.SupportedCipherSuites); if (supported.Contains(id)) { cipherSuiteInfo = plugin.GetCipherSuiteFromID(id); break; } } if (cipherSuiteInfo == null) { Console.WriteLine("CipherSuite ID 0x" + id.ToString("x").PadLeft(2, '0') + " not found"); return null; } CipherSuite cipherSuite = new CipherSuite(version, id, cipherSuiteInfo.CipherSuiteName); if (cipherSuiteInfo.KeyExchangeAlgorithmName == null) cipherSuite.KeyExchangeAlgorithm = new KeyExchangeAlgorithmNull(); if (cipherSuiteInfo.SignatureAlgorithmName == null) cipherSuite.SignatureAlgorithm = new SignatureAlgorithmNull(); if (cipherSuiteInfo.BulkCipherAlgorithmName == null) cipherSuite.BulkCipherAlgorithm = new BulkCipherAlgorithmNull(); if (cipherSuiteInfo.MACAlgorithmName == null) cipherSuite.MACAlgorithm = new MACAlgorithmNull(); // These need to be edited in different versions string prfName = cipherSuiteInfo.PseudoRandomFunctionName; string macName = cipherSuiteInfo.MACAlgorithmName; if (version == ProtocolVersion.SSL3_0) { if (prfName == null) { prfName = "SSLv3"; } else { // PRF selection not supported, but PRF defined, ignore this suite return null; } if (macName == null) { macName = null; } else if (macName.Equals("MD5")) { macName = "SSLv3_MD5"; } else if (macName.Equals("SHA1")) { macName = "SSLv3_SHA1"; } else { // Only MD5 and SHA1 MAC accepted in SSLv3, ignore this suite return null; } } else { if (version.HasSelectablePRF) { if (prfName == null) { prfName = "TLS_SHA256"; } } else { if (prfName == null) { prfName = "TLSv1"; } else { // PRF selection not supported, but PRF defined, ignore this suite return null; } } } foreach (CipherSuitePlugin plugin in _plugins) { if (cipherSuite.KeyExchangeAlgorithm == null) { cipherSuite.KeyExchangeAlgorithm = plugin.GetKeyExchangeAlgorithm(cipherSuiteInfo.KeyExchangeAlgorithmName); } if (cipherSuite.SignatureAlgorithm == null) { cipherSuite.SignatureAlgorithm = plugin.GetSignatureAlgorithm(cipherSuiteInfo.SignatureAlgorithmName); } if (cipherSuite.PseudoRandomFunction == null) { cipherSuite.PseudoRandomFunction = plugin.GetPseudoRandomFunction(prfName); /* Check that the PRF is valid as per RFC 5246 section 7.4.9 */ if (cipherSuite.PseudoRandomFunction != null && cipherSuite.PseudoRandomFunction.VerifyDataLength < 12) { Console.WriteLine("Invalid PseudoRandomFunction, verify data less than 12, ignored"); cipherSuite.PseudoRandomFunction = null; } } if (cipherSuite.BulkCipherAlgorithm == null) { cipherSuite.BulkCipherAlgorithm = plugin.GetBulkCipherAlgorithm(cipherSuiteInfo.BulkCipherAlgorithmName); } if (cipherSuite.MACAlgorithm == null) { cipherSuite.MACAlgorithm = plugin.GetMACAlgorithm(macName); } } if (cipherSuite.KeyExchangeAlgorithm == null || !cipherSuite.KeyExchangeAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("KeyExchangeAlgorithm '" + cipherSuiteInfo.KeyExchangeAlgorithmName + "' not found"); return null; } if (cipherSuite.SignatureAlgorithm == null || !cipherSuite.SignatureAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("SignatureAlgorithm '" + cipherSuiteInfo.SignatureAlgorithmName + "' not found"); return null; } if (cipherSuite.PseudoRandomFunction == null|| !cipherSuite.PseudoRandomFunction.SupportsProtocolVersion(version)) { Console.WriteLine("PseudoRandomFunction '" + cipherSuiteInfo.PseudoRandomFunctionName + "' not found"); return null; } if (cipherSuite.BulkCipherAlgorithm == null || !cipherSuite.BulkCipherAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("BulkCipherAlgorithm '" + cipherSuiteInfo.BulkCipherAlgorithmName + "' not found"); return null; } if (cipherSuite.MACAlgorithm == null || !cipherSuite.MACAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("MACAlgorithm '" + cipherSuiteInfo.MACAlgorithmName + "' not found"); return null; } return cipherSuite; }
private static int DefaultCertificateSelectionCallback(CipherSuite cipherSuite, X509CertificateCollection[] availableCertificates) { // No certificate for anonymous suites if (cipherSuite.IsAnonymous) return -1; for (int i=0; i<availableCertificates.Length; i++) { X509CertificateCollection certs = availableCertificates[i]; if (certs.Count == 0) continue; string keyexAlg = cipherSuite.KeyExchangeAlgorithm.CertificateKeyAlgorithm; string sigAlg = cipherSuite.SignatureAlgorithm.CertificateKeyAlgorithm; if (keyexAlg != null && !keyexAlg.Equals(certs[0].GetKeyAlgorithm())) continue; if (sigAlg != null && !sigAlg.Equals(certs[0].GetKeyAlgorithm())) continue; return i; } return -1; }
public CipherSuite GetCipherSuite(ProtocolVersion version, UInt16 id) { CipherSuiteInfo cipherSuiteInfo = null; foreach (CipherSuitePlugin plugin in _plugins) { List <UInt16> supported = new List <UInt16>(plugin.SupportedCipherSuites); if (supported.Contains(id)) { cipherSuiteInfo = plugin.GetCipherSuiteFromID(id); break; } } if (cipherSuiteInfo == null) { Console.WriteLine("CipherSuite ID 0x" + id.ToString("x").PadLeft(2, '0') + " not found"); return(null); } CipherSuite cipherSuite = new CipherSuite(version, id, cipherSuiteInfo.CipherSuiteName); if (cipherSuiteInfo.KeyExchangeAlgorithmName == null) { cipherSuite.KeyExchangeAlgorithm = new KeyExchangeAlgorithmNull(); } if (cipherSuiteInfo.SignatureAlgorithmName == null) { cipherSuite.SignatureAlgorithm = new SignatureAlgorithmNull(); } if (cipherSuiteInfo.BulkCipherAlgorithmName == null) { cipherSuite.BulkCipherAlgorithm = new BulkCipherAlgorithmNull(); } if (cipherSuiteInfo.MACAlgorithmName == null) { cipherSuite.MACAlgorithm = new MACAlgorithmNull(); } // These need to be edited in different versions string prfName = cipherSuiteInfo.PseudoRandomFunctionName; string macName = cipherSuiteInfo.MACAlgorithmName; if (version == ProtocolVersion.SSL3_0) { if (prfName == null) { prfName = "SSLv3"; } else { // PRF selection not supported, but PRF defined, ignore this suite return(null); } if (macName == null) { macName = null; } else if (macName.Equals("MD5")) { macName = "SSLv3_MD5"; } else if (macName.Equals("SHA1")) { macName = "SSLv3_SHA1"; } else { // Only MD5 and SHA1 MAC accepted in SSLv3, ignore this suite return(null); } } else { if (version.HasSelectablePRF) { if (prfName == null) { prfName = "TLS_SHA256"; } } else { if (prfName == null) { prfName = "TLSv1"; } else { // PRF selection not supported, but PRF defined, ignore this suite return(null); } } } foreach (CipherSuitePlugin plugin in _plugins) { if (cipherSuite.KeyExchangeAlgorithm == null) { cipherSuite.KeyExchangeAlgorithm = plugin.GetKeyExchangeAlgorithm(cipherSuiteInfo.KeyExchangeAlgorithmName); } if (cipherSuite.SignatureAlgorithm == null) { cipherSuite.SignatureAlgorithm = plugin.GetSignatureAlgorithm(cipherSuiteInfo.SignatureAlgorithmName); } if (cipherSuite.PseudoRandomFunction == null) { cipherSuite.PseudoRandomFunction = plugin.GetPseudoRandomFunction(prfName); /* Check that the PRF is valid as per RFC 5246 section 7.4.9 */ if (cipherSuite.PseudoRandomFunction != null && cipherSuite.PseudoRandomFunction.VerifyDataLength < 12) { Console.WriteLine("Invalid PseudoRandomFunction, verify data less than 12, ignored"); cipherSuite.PseudoRandomFunction = null; } } if (cipherSuite.BulkCipherAlgorithm == null) { cipherSuite.BulkCipherAlgorithm = plugin.GetBulkCipherAlgorithm(cipherSuiteInfo.BulkCipherAlgorithmName); } if (cipherSuite.MACAlgorithm == null) { cipherSuite.MACAlgorithm = plugin.GetMACAlgorithm(macName); } } if (cipherSuite.KeyExchangeAlgorithm == null || !cipherSuite.KeyExchangeAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("KeyExchangeAlgorithm '" + cipherSuiteInfo.KeyExchangeAlgorithmName + "' not found"); return(null); } if (cipherSuite.SignatureAlgorithm == null || !cipherSuite.SignatureAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("SignatureAlgorithm '" + cipherSuiteInfo.SignatureAlgorithmName + "' not found"); return(null); } if (cipherSuite.PseudoRandomFunction == null || !cipherSuite.PseudoRandomFunction.SupportsProtocolVersion(version)) { Console.WriteLine("PseudoRandomFunction '" + cipherSuiteInfo.PseudoRandomFunctionName + "' not found"); return(null); } if (cipherSuite.BulkCipherAlgorithm == null || !cipherSuite.BulkCipherAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("BulkCipherAlgorithm '" + cipherSuiteInfo.BulkCipherAlgorithmName + "' not found"); return(null); } if (cipherSuite.MACAlgorithm == null || !cipherSuite.MACAlgorithm.SupportsProtocolVersion(version)) { Console.WriteLine("MACAlgorithm '" + cipherSuiteInfo.MACAlgorithmName + "' not found"); return(null); } return(cipherSuite); }
public void ChangeLocalState() { _outputCipherSuite = _nextCipherSuite; _outputKeyBlock = _nextKeyBlock; _outputSequenceNumber = 0; _outputEpoch++; if (_isClient) { _outputHasher = _outputCipherSuite.MACAlgorithm.CreateHasher(_outputKeyBlock.ClientWriteMACKey); _encryptor = _outputCipherSuite.BulkCipherAlgorithm.CreateEncryptor(_outputKeyBlock.ClientWriteKey, _outputKeyBlock.ClientWriteIV); _outputKey = _outputKeyBlock.ClientWriteKey; _outputFixedIV = _outputKeyBlock.ClientWriteIV; } else { _outputHasher = _outputCipherSuite.MACAlgorithm.CreateHasher(_outputKeyBlock.ServerWriteMACKey); _encryptor = _outputCipherSuite.BulkCipherAlgorithm.CreateEncryptor(_outputKeyBlock.ServerWriteKey, _outputKeyBlock.ServerWriteIV); _outputKey = _outputKeyBlock.ServerWriteKey; _outputFixedIV = _outputKeyBlock.ServerWriteIV; } // IMPORTANT: This needs to be XORed with ie. sequence number to make sure it is unique _outputRecordIV = new byte[_outputCipherSuite.BulkCipherAlgorithm.RecordIVLength]; RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); rngCsp.GetBytes(_outputRecordIV); }
public void SetCipherSuite(CipherSuite cipherSuite, ConnectionState connectionState) { // Get master secret from connectionState byte[] masterSecret = connectionState.MasterSecret; // Generate seed for changing cipher suite byte[] seed = new byte[64]; Array.Copy(connectionState.ServerRandom, 0, seed, 0, 32); Array.Copy(connectionState.ClientRandom, 0, seed, 32, 32); _nextCipherSuite = cipherSuite; _nextKeyBlock = new KeyBlock(cipherSuite, masterSecret, seed); }
protected static byte[] GenerateMasterSecret(ProtocolVersion version, CipherSuite cipherSuite, ConnectionState connectionState) { byte[] seed = new byte[64]; Array.Copy(connectionState.ClientRandom, 0, seed, 0, 32); Array.Copy(connectionState.ServerRandom, 0, seed, 32, 32); byte[] masterSecret = cipherSuite.KeyExchangeAlgorithm.GetMasterSecret(cipherSuite.PseudoRandomFunction, seed); if (masterSecret == null) { throw new Exception("Could not generate master secret"); } return masterSecret; }
private static void GeneratePadding(CipherSuite cipherSuite, Record record) { BulkCipherAlgorithmType cipherType = cipherSuite.BulkCipherAlgorithm.Type; if (cipherType == BulkCipherAlgorithmType.Block) { int blockSize = cipherSuite.BulkCipherAlgorithm.BlockSize; // Add the required padding to the end of fragment if necessary, // minimum padding 1 bytes, the length byte of padding itself int paddingLength = blockSize - (record.Fragment.Length % blockSize); if (record.Version.HasVariablePadding) { // Add 0-1 additional blocks int extra = (new System.Random()).Next(2); if (paddingLength + extra*blockSize < 256) { paddingLength += extra*blockSize; } } // Add the actual padding bytes here byte[] padding = new byte[paddingLength]; if (record.Version == ProtocolVersion.SSL3_0) { RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); rngCsp.GetBytes(padding); padding[padding.Length-1] = (byte) (padding.Length-1); } else { for (int i=1; i<=padding.Length; i++) { padding[padding.Length-i] = (byte) (padding.Length-1); } } byte[] fragment = new byte[record.Fragment.Length + padding.Length]; Buffer.BlockCopy(record.Fragment, 0, fragment, 0, record.Fragment.Length); Buffer.BlockCopy(padding, 0, fragment, record.Fragment.Length, padding.Length); record.Fragment = fragment; } }
private static void GenerateMAC(CipherSuite cipherSuite, Record record, UInt64 seqNum, KeyedHashAlgorithm hasher) { BulkCipherAlgorithmType cipherType = cipherSuite.BulkCipherAlgorithm.Type; if (cipherType == BulkCipherAlgorithmType.Stream || cipherType == BulkCipherAlgorithmType.Block) { byte[] additional = GetAdditionalBytes(seqNum, record.Type, record.Version, record.Fragment.Length); // Calculate the MAC of the packet hasher.Initialize(); hasher.TransformBlock(additional, 0, additional.Length, additional, 0); hasher.TransformFinalBlock(record.Fragment, 0, record.Fragment.Length); byte[] MAC = hasher.Hash; /* Add MAC to the end of the fragment */ byte[] fragment = new byte[record.Fragment.Length + MAC.Length]; Buffer.BlockCopy(record.Fragment, 0, fragment, 0, record.Fragment.Length); Buffer.BlockCopy(MAC, 0, fragment, record.Fragment.Length, MAC.Length); record.Fragment = fragment; } }
private static void EncryptRecord(CipherSuite cipherSuite, Record record, ICryptoTransform cipher, byte[] nonceExplicit) { BulkCipherAlgorithmType cipherType = cipherSuite.BulkCipherAlgorithm.Type; int recordIVLength = cipherSuite.BulkCipherAlgorithm.RecordIVLength; // Add explicit IV if required by protocol version if (cipherType == BulkCipherAlgorithmType.Block && record.Version.HasExplicitIV) { byte[] explicitIV = new byte[recordIVLength]; RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); rngCsp.GetBytes(explicitIV); // Replace the fragment with a new fragment including explicit IV byte[] fragment = new byte[explicitIV.Length + record.Fragment.Length]; Buffer.BlockCopy(explicitIV, 0, fragment, 0, explicitIV.Length); Buffer.BlockCopy(record.Fragment, 0, fragment, explicitIV.Length, record.Fragment.Length); record.Fragment = fragment; } // Replace the unencrypted fragment with the encrypted fragment record.Fragment = TransformRecordBytes(cipherType, cipher, record.Fragment); // Add explicit part of the nonce if using AEAD if (cipherType == BulkCipherAlgorithmType.AEAD) { byte[] fragment = new byte[nonceExplicit.Length + record.Fragment.Length]; Buffer.BlockCopy(nonceExplicit, 0, fragment, 0, nonceExplicit.Length); Buffer.BlockCopy(record.Fragment, 0, fragment, nonceExplicit.Length, record.Fragment.Length); record.Fragment = fragment; } }
private static bool DecryptRecord(CipherSuite cipherSuite, Record record, ICryptoTransform cipher) { BulkCipherAlgorithmType cipherType = cipherSuite.BulkCipherAlgorithm.Type; int recordIVLength = cipherSuite.BulkCipherAlgorithm.RecordIVLength; if (cipherType == BulkCipherAlgorithmType.AEAD) { int authTagSize = cipherSuite.BulkCipherAlgorithm.AuthenticationTagSize; // Remove explicit nonce from the beginning of the fragment byte[] tmp = new byte[record.Fragment.Length-recordIVLength]; Buffer.BlockCopy(record.Fragment, recordIVLength, tmp, 0, tmp.Length); record.Fragment = tmp; // Make sure there is enough data for the authentication tag if (record.Fragment.Length < authTagSize) { return false; } } // Replace the encrypted fragment with the decrypted fragment byte[] fragment = TransformRecordBytes(cipherType, cipher, record.Fragment); if (fragment == null) { return false; } record.Fragment = fragment; // Remove explicit IV from the beginning of the fragment if necessary if (cipherType == BulkCipherAlgorithmType.Block && record.Version.HasExplicitIV) { fragment = new byte[record.Fragment.Length-recordIVLength]; Buffer.BlockCopy(record.Fragment, recordIVLength, fragment, 0, record.Fragment.Length-recordIVLength); record.Fragment = fragment; } return true; }
private static ICryptoTransform CreateAEADEncryptor(CipherSuite cipherSuite, Record record, byte[] key, byte[] fixedIV, byte[] recordIV, UInt64 seqNum, out byte[] nonceExplicit) { // Construct the nonce for AEAD cipher nonceExplicit = GenerateAEADNonceExplicit(recordIV, seqNum); byte[] nonce = GenerateAEADNonce(fixedIV, nonceExplicit); // Construct the additional bytes for AEAD cipher byte[] additional = GetAdditionalBytes(seqNum, record.Type, record.Version, record.Fragment.Length); return cipherSuite.BulkCipherAlgorithm.CreateEncryptor(key, nonce, additional); }
private static ICryptoTransform CreateAEADDecryptor(CipherSuite cipherSuite, Record record, byte[] key, byte[] fixedIV, UInt64 seqNum) { // Get the explicit nonce from the beginning of fragment int recordIVLength = cipherSuite.BulkCipherAlgorithm.RecordIVLength; byte[] nonceExplicit = new byte[recordIVLength]; Buffer.BlockCopy(record.Fragment, 0, nonceExplicit, 0, nonceExplicit.Length); // Construct the nonce for AEAD cipher byte[] nonce = GenerateAEADNonce(fixedIV, nonceExplicit); // Construct the additional bytes for AEAD cipher int compressedLength = record.Fragment.Length - recordIVLength - cipherSuite.BulkCipherAlgorithm.AuthenticationTagSize; byte[] additional = GetAdditionalBytes(seqNum, record.Type, record.Version, compressedLength); return cipherSuite.BulkCipherAlgorithm.CreateDecryptor(key, nonce, additional); }
private static bool RemoveMAC(CipherSuite cipherSuite, Record record, UInt64 seqNum, KeyedHashAlgorithm hasher) { BulkCipherAlgorithmType cipherType = cipherSuite.BulkCipherAlgorithm.Type; bool verified = true; if (cipherType == BulkCipherAlgorithmType.Stream || cipherType == BulkCipherAlgorithmType.Block) { int MACLength = cipherSuite.MACAlgorithm.HashSize; if (record.Fragment.Length < MACLength) { verified = false; } else { // Allocate a fragment without the MAC value byte[] newFragment = new byte[record.Fragment.Length - MACLength]; Buffer.BlockCopy(record.Fragment, 0, newFragment, 0, newFragment.Length); // Calculate the MAC again for new fragment byte[] oldFragment = record.Fragment; record.Fragment = newFragment; GenerateMAC(cipherSuite, record, seqNum, hasher); // Compare our MAC value with theirs verified = true; for (int i=1; i<=MACLength; i++) { if (oldFragment[oldFragment.Length-i] != record.Fragment[record.Fragment.Length-i]) { verified = false; } } // Replace fragment with the one without MAC value record.Fragment = newFragment; } } return verified; }
private static bool RemovePadding(CipherSuite cipherSuite, Record record) { BulkCipherAlgorithmType cipherType = cipherSuite.BulkCipherAlgorithm.Type; bool verified = true; if (cipherType == BulkCipherAlgorithmType.Block) { // Get padding bytes from the end of the fragment int padding = record.Fragment[record.Fragment.Length-1]+1; // Verify the correctness of padding if (padding > record.Fragment.Length) { verified = false; } else { verified = true; if (record.Version.HasVerifiablePadding) { for (int i=1; i<=padding; i++) { if (record.Fragment[record.Fragment.Length-i] != (padding-1)) { verified = false; } } } // Remove padding from the fragment data if (verified) { byte[] fragment = new byte[record.Fragment.Length-padding]; Buffer.BlockCopy(record.Fragment, 0, fragment, 0, fragment.Length); record.Fragment = fragment; } } } return verified; }
protected HandshakeSession(SecurityParameters securityParameters) { string path = System.Reflection.Assembly.GetAssembly(typeof(HandshakeSession)).Location; string directory = Path.GetDirectoryName(path); _pluginManager = new CipherSuitePluginManager(directory); _state = HandshakeState.Initial; _minVersion = securityParameters.MinimumVersion; _maxVersion = securityParameters.MaximumVersion; _supportedCipherSuites = securityParameters.CipherSuiteIDs.ToArray(); _supportedCompressions = securityParameters.CompressionIDs.ToArray(); _availableCertificates = new List<X509CertificateCollection>(securityParameters.AvailableCertificates); _availablePrivateKeys = new List<CertificatePrivateKey>(securityParameters.AvailablePrivateKeys); _clientCertificates = new X509CertificateCollection(); _serverCertificates = new X509CertificateCollection(); // Initialize the default ClientHello version, to // be as compatible as possible based on maxVersion if (_maxVersion == ProtocolVersion.SSL3_0) { _version = ProtocolVersion.SSL3_0; } else if (_maxVersion.IsUsingDatagrams) { _version = ProtocolVersion.DTLS1_0; } else { _version = ProtocolVersion.TLS1_0; } _cipherSuite = new CipherSuite(_version); }
public void ChangeRemoteState() { _inputCipherSuite = _nextCipherSuite; _inputKeyBlock = _nextKeyBlock; _inputSequenceNumber = 0; _inputEpoch++; if (_isClient) { _inputHasher = _inputCipherSuite.MACAlgorithm.CreateHasher(_inputKeyBlock.ServerWriteMACKey); _decryptor = _inputCipherSuite.BulkCipherAlgorithm.CreateDecryptor(_inputKeyBlock.ServerWriteKey, _inputKeyBlock.ServerWriteIV); _inputKey = _inputKeyBlock.ServerWriteKey; _inputFixedIV = _inputKeyBlock.ServerWriteIV; } else { _inputHasher = _inputCipherSuite.MACAlgorithm.CreateHasher(_inputKeyBlock.ClientWriteMACKey); _decryptor = _inputCipherSuite.BulkCipherAlgorithm.CreateDecryptor(_inputKeyBlock.ClientWriteKey, _inputKeyBlock.ClientWriteIV); _inputKey = _inputKeyBlock.ClientWriteKey; _inputFixedIV = _inputKeyBlock.ClientWriteIV; } }