示例#1
0
        public void ProcessFinished(byte[] payload)
        {
            if (m_HandshakePhase != HandshakeDataType.Finished)
            {
                throw new SslAlertException(AlertLevel.Fatal, AlertDescription.UnexpectedMessage);
            }

            byte[] data = GetAllHandshakeInBytes();

            byte[] sha1data = (new SHA1Managed()).ComputeHash(data);
            byte[] md5data  = (new MD5Managed()).ComputeHash(data);

            PrfDeriveBytes prf = new PrfDeriveBytes(m_SecurityParameters.MasterSecret,
                                                    "server finished", ByteArray.Concat(md5data, sha1data));

            byte[] result = prf.GetBytes(12);

            prf.Dispose();

            if (!ByteArray.AreEqual(result, payload))
            {
                throw new SslAlertException(AlertLevel.Fatal, AlertDescription.DecryptError);
            }
            else
            {
                /* Clear out list of handshake messages */
                m_ListOfHandshakeMsgs.Clear();
                throw new SslHandshakeCompleteException();
            }
        }
示例#2
0
        public void ProcessServerHelloDone()
        {
            m_HandshakePhase = HandshakeDataType.ServerHelloDone;
            PreMasterSecret pms = new PreMasterSecret();

            byte[] keyExchangeData = GenerateKeyExchangeData(pms.GetBytes());

            /* Generate Master Secret */
            PrfDeriveBytes prf = new PrfDeriveBytes(pms.GetBytes(),
                                                    "master secret",
                                                    ByteArray.Concat(m_SecurityParameters.ClientRandom,
                                                                     m_SecurityParameters.ServerRandom));

            m_Session.MasterSecret            = prf.GetBytes(48);
            m_SecurityParameters.MasterSecret = m_Session.MasterSecret;
            prf.Dispose();

            /* clear pre-master secret from memory */
            pms.Dispose();

            /* Create handshake messages */
            m_ProtocolQueue.Enqueue(CreateClientKeyExchange(keyExchangeData));
            m_ProtocolQueue.Enqueue(CreateChangeCipherSpec());
            m_ProtocolQueue.Enqueue(CreateFinishedMsg(m_SecurityParameters.MasterSecret));

            ParametersReady(m_SecurityParameters);
        }
示例#3
0
        internal IProtocolMessage CreateFinishedMsg(byte[] masterSecret)
        {
            byte[] data = GetAllHandshakeInBytes();

            byte[] md5data  = (new MD5Managed()).ComputeHash(data);
            byte[] sha1data = (new SHA1Managed()).ComputeHash(data);

            PrfDeriveBytes prf = new PrfDeriveBytes(masterSecret,
                                                    "client finished", ByteArray.Concat(md5data, sha1data));

            byte[] result = prf.GetBytes(12);

            prf.Dispose();

            HandshakeProtocolMessage hpm = new HandshakeProtocolMessage(new Finished(result));

            m_ListOfHandshakeMsgs.Add(hpm);
            m_HandshakePhase = HandshakeDataType.Finished;
            return(hpm);
        }
示例#4
0
        public CipherSuite(TlsCipherSuite suite, byte[] master,
                           byte[] clientRandom, byte[] serverRandom)
        {
            if (master == null)
            {
                throw new ArgumentNullException();
            }
            if (clientRandom == null)
            {
                throw new ArgumentNullException();
            }
            if (serverRandom == null)
            {
                throw new ArgumentNullException();
            }

            CipherDefinition cipherDef = CipherSuites.GetCipherDefinition(suite);

            int size = cipherDef.HashSize * 2 + cipherDef.BulkKeySize * 2;

            if (cipherDef.BulkIVSize != 0)
            {
                size += cipherDef.BulkIVSize * 2;
            }

            PrfDeriveBytes prf = new PrfDeriveBytes(master,
                                                    "key expansion", ByteArray.Concat(serverRandom, clientRandom));

            byte[] keyBlock = prf.GetBytes(size);

            prf.Dispose();

            int offset = 0;

            byte[] client_write_mac = new byte[cipherDef.HashSize];
            System.Buffer.BlockCopy(keyBlock, offset, client_write_mac, 0, cipherDef.HashSize);
            offset += cipherDef.HashSize;

            byte[] server_write_mac = new byte[cipherDef.HashSize];
            System.Buffer.BlockCopy(keyBlock, offset, server_write_mac, 0, cipherDef.HashSize);
            offset += cipherDef.HashSize;

            byte[] client_write_key = new byte[cipherDef.BulkKeySize];
            System.Buffer.BlockCopy(keyBlock, offset, client_write_key, 0, cipherDef.BulkKeySize);
            offset += cipherDef.BulkKeySize;

            byte[] server_write_key = new byte[cipherDef.BulkKeySize];
            System.Buffer.BlockCopy(keyBlock, offset, server_write_key, 0, cipherDef.BulkKeySize);
            offset += cipherDef.BulkKeySize;

            byte[] client_write_iv = null;
            byte[] server_write_iv = null;

            if (cipherDef.BulkIVSize != 0)
            {
                client_write_iv = new byte[cipherDef.BulkIVSize];
                System.Buffer.BlockCopy(keyBlock, offset, client_write_iv, 0, cipherDef.BulkIVSize);
                offset += cipherDef.BulkIVSize;

                server_write_iv = new byte[cipherDef.BulkIVSize];
                System.Buffer.BlockCopy(keyBlock, offset, server_write_iv, 0, cipherDef.BulkIVSize);
                offset += cipherDef.BulkIVSize;
            }

            prf.Dispose();

            SymmetricAlgorithm sAlg = (SymmetricAlgorithm)Activator.CreateInstance(cipherDef.BulkCipherAlgorithm);

            sAlg.BlockSize = cipherDef.BulkIVSize * 8;

            if (cipherDef.Exportable)
            {
                //TODO: Make amends to support export cipher suites
            }

            m_Encryptor    = sAlg.CreateEncryptor(client_write_key, client_write_iv);
            m_Decryptor    = sAlg.CreateDecryptor(server_write_key, server_write_iv);
            m_ClientHasher = (KeyedHashAlgorithm)Activator.CreateInstance(cipherDef.HashAlgorithm, client_write_mac);
            m_ServerHasher = (KeyedHashAlgorithm)Activator.CreateInstance(cipherDef.HashAlgorithm, server_write_mac);

            /* clear up */
            Array.Clear(client_write_mac, 0, client_write_mac.Length);
            Array.Clear(server_write_mac, 0, server_write_mac.Length);
            Array.Clear(client_write_key, 0, client_write_key.Length);
            Array.Clear(server_write_key, 0, server_write_key.Length);

            if (client_write_iv != null && server_write_iv != null)
            {
                Array.Clear(client_write_iv, 0, client_write_iv.Length);
                Array.Clear(server_write_iv, 0, server_write_iv.Length);
            }
        }