Example #1
0
 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);
 }
Example #2
0
        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;
        }
Example #3
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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        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;
        }
Example #10
0
        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;
            }
        }
Example #11
0
        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;
            }
        }
Example #12
0
        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;
            }
        }
Example #13
0
        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;
        }
Example #14
0
        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);
        }
Example #15
0
        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);
        }
Example #16
0
        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;
        }
Example #17
0
        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;
        }
Example #18
0
        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);
        }
Example #19
0
        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;
            }
        }