private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(new byte[0], 0, 0);

            byte[] seed = m_localHash.Hash;
            m_localHash.Dispose();
            m_localHash = null;

            string label;

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                label = ServerFinishedLabel;
            }
            else
            {
                label = ClientFinshedLabel;
            }

            FinishedMessage finishedMessage = new FinishedMessage();

            finishedMessage.VerifyData =
                PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

            NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();

            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                HashRemote(outgoingMessage);
            }
        }
Example #2
0
        private void OnHelloRequest(OutgoingMessageBag outgoingMessages)
        {
            //客户端根据配置决定握手层版本号
            SubProtocolVersion = GetSubProtocol();
            var clientHelloMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3) ?
                                     new V0_2.HandshakeMessages.ClientHelloMessage() :
                                     new ClientHelloMessage();

            clientHelloMessage.RandomNumber = new byte[RandomNumberLength];

            clientHelloMessage.SessionID = SessionID;

            m_rng.GetBytes(clientHelloMessage.RandomNumber);
            ////TODO: 测试

            //string random = "5e c2 54 f6 fa cc f1 40 be ec 3b 43 44 1c 72 c3 25 ed 43 7a 5d cf a2 17 33 26 94 48 f7 cb 34 f9";
            //clientHelloMessage.RandomNumber = random.ConvertHexToByteArray();
            SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber;

            clientHelloMessage.CipherSuites = AllowedCipherSuites;

            NetMQMessage outgoingMessage = clientHelloMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);

            //第一个record的seqnum从0开始
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ClientHello;
        }
Example #3
0
        private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0);

            byte[] seed = m_localHash.Hash;
#if NET40
            m_localHash.Dispose();
#endif
            m_localHash = null;

            var label = SecurityParameters.Entity == ConnectionEnd.Server ? ServerFinishedLabel : ClientFinshedLabel;

            var finishedMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)?
                                  new V0_2.HandshakeMessages.FinishedMessage():
                                  new FinishedMessage();
            finishedMessage.VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);
#if DEBUG
            Debug.WriteLine("[verify_data]:" + BitConverter.ToString(finishedMessage.VerifyData));
#endif
            NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                HashRemote(outgoingMessage);
            }
        }
Example #4
0
        private void AddServerHelloMessage(OutgoingMessageBag outgoingMessages, CipherSuite[] cipherSuites)
        {
            var serverHelloMessage = new ServerHelloMessage {
                RandomNumber = new byte[RandomNumberLength]
            };

            m_rng.GetBytes(serverHelloMessage.RandomNumber);

            SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber;

            // in case there is no match the server will return this default
            serverHelloMessage.CipherSuite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA;

            foreach (var cipherSuite in cipherSuites)
            {
                if (AllowedCipherSuites.Contains(cipherSuite))
                {
                    serverHelloMessage.CipherSuite = cipherSuite;
                    SetCipherSuite(cipherSuite);
                    break;
                }
            }

            NetMQMessage outgoingMessage = serverHelloMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ServerHello;
        }
Example #5
0
        private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0);

            byte[] seed = m_localHash.Hash;
            m_localHash.Dispose();
            m_localHash = null;

            var label = SecurityParameters.Entity == ConnectionEnd.Server ? ServerFinishedLabel : ClientFinshedLabel;

            var finishedMessage = new FinishedMessage
            {
                VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength)
            };

            NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();

            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                HashRemote(outgoingMessage);
            }
        }
Example #6
0
        /// <summary>
        /// Create a new SecureChannel with the given <see cref="ConnectionEnd"/>.
        /// </summary>
        /// <param name="connectionEnd">the ConnectionEnd that this channel is to talk to</param>
        public SecureChannel(ConnectionEnd connectionEnd)
        {
            m_handshakeLayer = new HandshakeLayer(this, connectionEnd);
            m_handshakeLayer.CipherSuiteChange += OnCipherSuiteChangeFromHandshakeLayer;

            m_recordLayer = new RecordLayer(m_protocolVersion);

            m_outgoingMessageBag = new OutgoingMessageBag(this);
        }
Example #7
0
        /// <exception cref="NetMQSecurityException">The Finished message must not be received while expecting a another message.</exception>
        /// <exception cref="NetMQSecurityException">The peer verification data must be valid.</exception>
        private void OnFinished(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (
                (SecurityParameters.Entity == ConnectionEnd.Client &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ServerHelloDone || m_lastSentMessage != HandshakeType.Finished)) ||
                (SecurityParameters.Entity == ConnectionEnd.Server &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ClientKeyExchange || m_lastSentMessage != HandshakeType.ServerHelloDone)))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Finished received when expecting another message");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                HashLocal(incomingMessage);
            }

            var finishedMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)?
                                  new V0_2.HandshakeMessages.FinishedMessage():
                                  new FinishedMessage();

            finishedMessage.SetFromNetMQMessage(incomingMessage);

            m_remoteHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0);

            byte[] seed = m_remoteHash.Hash;

#if NET40
            m_remoteHash.Dispose();
#else
            m_remoteHash.Clear();
#endif
            m_remoteHash = null;

            var label = SecurityParameters.Entity == ConnectionEnd.Client ? ServerFinishedLabel : ClientFinshedLabel;

            var verifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

#if DEBUG
            Debug.WriteLine("[verify_data]:" + BitConverter.ToString(verifyData));
#endif
            if (!verifyData.SequenceEqual(finishedMessage.VerifyData))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeVerifyData, "peer verify data wrong");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                AddFinished(outgoingMessages);
#if DEBUG
                Debug.WriteLine("[finish]");
#endif
            }

            m_done = true;
        }
Example #8
0
        public SecureChannel(ConnectionEnd connectionEnd)
        {
            m_handshakeLayer = new HandshakeLayer(this, connectionEnd);
            m_handshakeLayer.CipherSuiteChange += OnCipherSuiteChangeFromHandshakeLayer;

            m_recordLayer = new RecordLayer(m_protocolVersion);

            m_outgoingMessageBag = new OutgoingMessageBag(this);
        }
Example #9
0
        private void AddServerHelloDone(OutgoingMessageBag outgoingMessages)
        {
            var          serverHelloDoneMessage = new ServerHelloDoneMessage();
            NetMQMessage outgoingMessage        = serverHelloDoneMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ServerHelloDone;
        }
        private void OnFinished(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (
                (SecurityParameters.Entity == ConnectionEnd.Client &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ServerHelloDone || m_lastSentMessage != HandshakeType.Finished)) ||
                (SecurityParameters.Entity == ConnectionEnd.Server &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ClientKeyExchange || m_lastSentMessage != HandshakeType.ServerHelloDone)))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Finished received when expecting another message");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                HashLocal(incomingMessage);
            }

            FinishedMessage finishedMessage = new FinishedMessage();

            finishedMessage.SetFromNetMQMessage(incomingMessage);

            m_remoteHash.TransformFinalBlock(new byte[0], 0, 0);

            byte[] seed = m_remoteHash.Hash;
            m_remoteHash.Dispose();
            m_remoteHash = null;

            string label;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                label = ServerFinishedLabel;
            }
            else
            {
                label = ClientFinshedLabel;
            }

            byte[] verifyData =
                PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

            if (!verifyData.SequenceEqual(finishedMessage.VerifyData))
            {
                throw  new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeVerifyData, "peer verify data wrong");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                AddFinished(outgoingMessages);
            }

            m_done = true;
        }
Example #11
0
        private void AddServerHelloDone(OutgoingMessageBag outgoingMessages)
        {
            var serverHelloDoneMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)?
                                         new V0_2.HandshakeMessages.ServerHelloDoneMessage():
                                         new ServerHelloDoneMessage();
            NetMQMessage outgoingMessage = serverHelloDoneMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ServerHelloDone;
        }
Example #12
0
        private void AddCertificateMessage(OutgoingMessageBag outgoingMessages)
        {
            var certificateMessage = new CertificateMessage {
                Certificate = LocalCertificate
            };

            NetMQMessage outgoingMessage = certificateMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Certificate;
        }
Example #13
0
        /// <summary>
        /// Given an incoming handshake-protocol message, route it to the corresponding handler.
        /// </summary>
        /// <param name="incomingMessage">the NetMQMessage that has come in</param>
        /// <param name="outgoingMessages">a collection of NetMQMessages that are to be sent</param>
        /// <returns>true if finished - ie, an incoming message of type Finished was received</returns>
        /// <exception cref="ArgumentNullException"><paramref name="incomingMessage"/> must not be <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="incomingMessage"/> must have a valid <see cref="HandshakeType"/>.</exception>
        public bool ProcessMessages(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (incomingMessage == null)
            {
                if (m_lastReceivedMessage == m_lastSentMessage &&
                    m_lastSentMessage == HandshakeType.HelloRequest &&
                    SecurityParameters.Entity == ConnectionEnd.Client)
                {
                    OnHelloRequest(outgoingMessages);
                    return(false);
                }
                else
                {
                    throw new ArgumentNullException(nameof(incomingMessage));
                }
            }

            var handshakeType = (HandshakeType)incomingMessage[0].Buffer[0];

            switch (handshakeType)
            {
            case HandshakeType.ClientHello:
                OnClientHello(incomingMessage, outgoingMessages);
                break;

            case HandshakeType.ServerHello:
                OnServerHello(incomingMessage);
                break;

            case HandshakeType.Certificate:
                OnCertificate(incomingMessage);
                break;

            case HandshakeType.ServerHelloDone:
                OnServerHelloDone(incomingMessage, outgoingMessages);
                break;

            case HandshakeType.ClientKeyExchange:
                OnClientKeyExchange(incomingMessage);
                break;

            case HandshakeType.Finished:
                OnFinished(incomingMessage, outgoingMessages);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            m_lastReceivedMessage = handshakeType;

            return(m_done);
        }
Example #14
0
        private void AddCertificateMessage(OutgoingMessageBag outgoingMessages)
        {
            var certificateMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)?
                                     new V0_2.HandshakeMessages.CertificateMessage():
                                     new CertificateMessage();

            certificateMessage.Certificate = LocalCertificate;
            NetMQMessage outgoingMessage = certificateMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Certificate;
        }
Example #15
0
        private void AddServerHelloMessage(OutgoingMessageBag outgoingMessages, CipherSuite[] cipherSuites)
        {
            var serverHelloMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)?
                                     new V0_2.HandshakeMessages.ServerHelloMessage():
                                     new ServerHelloMessage();

            serverHelloMessage.RandomNumber = new byte[RandomNumberLength];
            m_rng.GetBytes(serverHelloMessage.RandomNumber);


            ////TODO: 测试

            //string random = "ae f1 ba 12 3a 54 3c 51 7b 3d 49 87 05 80 6e 67 45 c5 76 77 74 26 01 d9 b9 da 69 79 e2 84 1d 37";
            //serverHelloMessage.RandomNumber = random.ConvertHexToByteArray();

            SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber;

            //客户端没有传sessionid则生成一个新的sessionid
            if (this.SessionID.Length == 0)
            {
                this.SessionID = Encoding.ASCII.GetBytes(Guid.NewGuid().ToString("N"));
            }

            ////TODO: 测试

            //this.SessionID = "37 61 36 36 35 64 37 38 36 62 61 36 34 32 62 64 38 36 61 62 32 61 63 39 36 31 35 34 37 34 33 61".ConvertHexToByteArray();

            serverHelloMessage.SessionID = this.SessionID;

            // in case there is no match the server will return this default
            serverHelloMessage.CipherSuite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA;

            foreach (var cipherSuite in cipherSuites)
            {
                if (AllowedCipherSuites.Contains(cipherSuite))
                {
                    serverHelloMessage.CipherSuite = cipherSuite;
                    SetCipherSuite(cipherSuite);
                    break;
                }
            }

            NetMQMessage outgoingMessage = serverHelloMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ServerHello;
        }
Example #16
0
        /// <summary>
        /// Create a new SecureChannel with the given <see cref="ConnectionEnd"/>.
        /// </summary>
        /// <param name="connectionEnd">the ConnectionEnd that this channel is to talk to</param>
        private SecureChannel(ConnectionEnd connectionEnd, Configuration configuration = null)
        {
            Configuration   = configuration ?? new Configuration();
            n_ConnectionEnd = connectionEnd;

            m_handshakeLayer = new HandshakeLayer(this, connectionEnd);
            m_handshakeLayer.CipherSuiteChange += OnCipherSuiteChangeFromHandshakeLayer;
            RecordLayer = new RecordLayer();

            m_outgoingMessageBag = new OutgoingMessageBag(this);
            if (!Configuration.VerifyCertificate)
            {
                //若不验证证书,则直接返回true
                SetVerifyCertificate(c => true);
            }
        }
        private void OnServerHello(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.HelloRequest || m_lastSentMessage != HandshakeType.ClientHello)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Server Hello received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            ServerHelloMessage serverHelloMessage = new ServerHelloMessage();

            serverHelloMessage.SetFromNetMQMessage(incomingMessage);

            SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber;

            SetCipherSuite(serverHelloMessage.CipherSuite);
        }
Example #18
0
        private void AddClientKeyExchange(OutgoingMessageBag outgoingMessages)
        {
            var clientKeyExchangeMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3) ?
                                           new V0_2.HandshakeMessages.ClientKeyExchangeMessage() :
                                           new ClientKeyExchangeMessage();
            //struct {
            //      ProtocolVersion client_version;
            //    opaque random[46];
            //}PreMasterSecret;
            var premasterSecret = new byte[ClientKeyExchangeMessage.PreMasterSecretLength];

            // The version number in the PreMasterSecret is the version
            // offered by the client in the ClientHello.client_version, not the
            // version negotiated for the connection.  This feature is designed to
            // prevent rollback attacks.Unfortunately, some old implementations
            // use the negotiated version instead, and therefore checking the
            // version number may lead to failure to interoperate with such
            // incorrect client implementations.
            // Client implementations MUST always send the correct version number in
            // PreMasterSecret.If ClientHello.client_version is TLS 1.1 or higher,
            // server implementations MUST check the version number as described in
            // the note below.If the version number is TLS 1.0 or earlier, server
            // implementations SHOULD check the version number, but MAY have a
            // configuration option to disable the check.
            premasterSecret[0] = 3;
            premasterSecret[1] = 3;
            byte[] random = new byte[46];
            m_rng.GetBytes(random);


            Buffer.BlockCopy(random, 0, premasterSecret, 2, random.Length);
            ////TODO :测试
            //premasterSecret = "03-03-11-41-D4-8F-8C-62-6F-31-12-40-D8-1D-F3-1C-8C-E3-6D-2F-0E-87-C6-DA-D1-17-96-CF-91-CD-EC-DB-F9-B5-52-FB-66-B6-E6-EB-65-71-1F-7A-05-25-0B-03".ConvertHexToByteArray('-');
            var rsa = RemoteCertificate.PublicKey.Key as RSACryptoServiceProvider;

            clientKeyExchangeMessage.EncryptedPreMasterSecret = rsa.Encrypt(premasterSecret, false);

            GenerateMasterSecret(premasterSecret);

            NetMQMessage outgoingMessage = clientKeyExchangeMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ClientKeyExchange;
        }
        private void OnHelloRequest(OutgoingMessageBag outgoingMessages)
        {
            ClientHelloMessage clientHelloMessage = new ClientHelloMessage();

            clientHelloMessage.RandomNumber = new byte[RandomNumberLength];
            m_rng.GetBytes(clientHelloMessage.RandomNumber);

            SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber;

            clientHelloMessage.CipherSuites = AllowedCipherSuites;

            NetMQMessage outgoingMessage = clientHelloMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);

            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ClientHello;
        }
Example #20
0
        /// <exception cref="NetMQSecurityException">The client hello message must not be received while expecting a different message.</exception>
        private void OnClientHello(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.HelloRequest || m_lastSentMessage != HandshakeType.HelloRequest)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Client Hello received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            var handShakeTypeFrame = incomingMessage.Pop();

            //服务端根据主版本号先判断
            if (m_secureChannel.ProtocolVersion.SequenceEqual(Constants.V0_1))
            {
                //没有长度,没有子版本号,使用Record的版本号一致
                SubProtocolVersion = m_secureChannel.ProtocolVersion;
            }
            else
            {
                //标准的获取长度和版本号,并校验
                var        handShakeLengthFrame = incomingMessage.Pop();
                NetMQFrame versionFrame         = incomingMessage.Pop();
                SubProtocolVersion = versionFrame.Buffer;
            }
            if (!Constants.SupposeSubVersions.Any(v => v.SequenceEqual(SubProtocolVersion)))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "the hand shake protocol version is not supposed");
            }
            //获取保存子协议版本
            var clientHelloMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3) ?
                                     new V0_2.HandshakeMessages.ClientHelloMessage() :
                                     new ClientHelloMessage();

            clientHelloMessage.SetFromNetMQMessage(incomingMessage);
            //获取到客户端的sessionid
            this.SessionID = clientHelloMessage.SessionID;
            SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber;

            AddServerHelloMessage(outgoingMessages, clientHelloMessage.CipherSuites);

            AddCertificateMessage(outgoingMessages);

            AddServerHelloDone(outgoingMessages);
        }
        private void AddClientKeyExchange(OutgoingMessageBag outgoingMessages)
        {
            ClientKeyExchangeMessage clientKeyExchangeMessage = new ClientKeyExchangeMessage();

            byte[] premasterSecret = new byte[ClientKeyExchangeMessage.PreMasterSecretLength];
            m_rng.GetBytes(premasterSecret);

            RSACryptoServiceProvider rsa = RemoteCertificate.PublicKey.Key as RSACryptoServiceProvider;

            clientKeyExchangeMessage.EncryptedPreMasterSecret = rsa.Encrypt(premasterSecret, false);

            GenerateMasterSecret(premasterSecret);

            NetMQMessage outgoingMessage = clientKeyExchangeMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ClientKeyExchange;
        }
        private void OnCertificate(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.ServerHello || m_lastSentMessage != HandshakeType.ClientHello)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Certificate received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            CertificateMessage certificateMessage = new CertificateMessage();

            certificateMessage.SetFromNetMQMessage(incomingMessage);

            if (!VerifyCertificate(certificateMessage.Certificate))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Unable to verify certificate");
            }

            RemoteCertificate = certificateMessage.Certificate;
        }
Example #23
0
        /// <exception cref="NetMQSecurityException">The server hello message must not be received while expecting another message.</exception>
        private void OnServerHelloDone(NetMQMessage incomingMessage,
                                       OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.Certificate || m_lastSentMessage != HandshakeType.ClientHello)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Server Hello Done received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            var serverHelloDoneMessage = new ServerHelloDoneMessage();

            serverHelloDoneMessage.SetFromNetMQMessage(incomingMessage);

            AddClientKeyExchange(outgoingMessages);

            InvokeChangeCipherSuite();

            AddFinished(outgoingMessages);
        }
        private void OnClientKeyExchange(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.ClientHello || m_lastSentMessage != HandshakeType.ServerHelloDone)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Client Key Exchange received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            ClientKeyExchangeMessage clientKeyExchangeMessage = new ClientKeyExchangeMessage();

            clientKeyExchangeMessage.SetFromNetMQMessage(incomingMessage);

            RSACryptoServiceProvider rsa = LocalCertificate.PrivateKey as RSACryptoServiceProvider;

            byte[] premasterSecret = rsa.Decrypt(clientKeyExchangeMessage.EncryptedPreMasterSecret, false);

            GenerateMasterSecret(premasterSecret);

            InvokeChangeCipherSuite();
        }
Example #25
0
        /// <exception cref="NetMQSecurityException">The client hello message must not be received while expecting a different message.</exception>
        private void OnClientHello(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.HelloRequest || m_lastSentMessage != HandshakeType.HelloRequest)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Client Hello received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            var clientHelloMessage = new ClientHelloMessage();

            clientHelloMessage.SetFromNetMQMessage(incomingMessage);

            SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber;

            AddServerHelloMessage(outgoingMessages, clientHelloMessage.CipherSuites);

            AddCertificateMessage(outgoingMessages);

            AddServerHelloDone(outgoingMessages);
        }
Example #26
0
        private void AddClientKeyExchange(OutgoingMessageBag outgoingMessages)
        {
            var clientKeyExchangeMessage = new ClientKeyExchangeMessage();

            var premasterSecret = new byte[ClientKeyExchangeMessage.PreMasterSecretLength];

            m_rng.GetBytes(premasterSecret);

            using (var rsa = RemoteCertificate.GetRSAPublicKey())                                                             // .PublicKey.Key as RSA; //RSACryptoServiceProvider;
            {
                clientKeyExchangeMessage.EncryptedPreMasterSecret = rsa.Encrypt(premasterSecret, RSAEncryptionPadding.Pkcs1); // false);
            }

            GenerateMasterSecret(premasterSecret);

            NetMQMessage outgoingMessage = clientKeyExchangeMessage.ToNetMQMessage();

            HashLocalAndRemote(outgoingMessage);
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ClientKeyExchange;
        }
Example #27
0
        /// <exception cref="NetMQSecurityException">The server hello message must not be received while expecting another message.</exception>
        private void OnServerHelloDone(NetMQMessage incomingMessage,
                                       OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.Certificate || m_lastSentMessage != HandshakeType.ClientHello)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Server Hello Done received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            var handShakeTypeFrame     = incomingMessage.Pop();
            var serverHelloDoneMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3) ?
                                         new V0_2.HandshakeMessages.ServerHelloDoneMessage() :
                                         new ServerHelloDoneMessage();

            serverHelloDoneMessage.SetFromNetMQMessage(incomingMessage);

            AddClientKeyExchange(outgoingMessages);

            InvokeChangeCipherSuite();

            AddFinished(outgoingMessages);
        }
Example #28
0
        private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(EmptyArray<byte>.Instance, 0, 0);

            byte[] seed = m_localHash.Hash;
            m_localHash.Dispose();
            m_localHash = null;

            var label = SecurityParameters.Entity == ConnectionEnd.Server ? ServerFinishedLabel : ClientFinshedLabel;

            var finishedMessage = new FinishedMessage
            {
                VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength)
            };

            NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                HashRemote(outgoingMessage);
            }
        }
Example #29
0
        private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(new byte[0], 0, 0);

              byte[] seed = m_localHash.Hash;
              m_localHash.Dispose();
              m_localHash = null;

              string label;

              if (SecurityParameters.Entity == ConnectionEnd.Server)
              {
            label = ServerFinishedLabel;
              }
              else
              {
            label = ClientFinshedLabel;
              }

              FinishedMessage finishedMessage = new FinishedMessage();

              finishedMessage.VerifyData =
            PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

              NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();
              outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

              if (SecurityParameters.Entity == ConnectionEnd.Client)
              {
            HashRemote(outgoingMessage);
              }
        }
Example #30
0
        private void AddServerHelloMessage(OutgoingMessageBag outgoingMessages, CipherSuite[] cipherSuites)
        {
            ServerHelloMessage serverHelloMessage = new ServerHelloMessage();
              serverHelloMessage.RandomNumber = new byte[RandomNumberLength];
              m_rng.GetBytes(serverHelloMessage.RandomNumber);

              SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber;

              // in case their is no much the server will return this defaul
              serverHelloMessage.CipherSuite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA;

              foreach (CipherSuite cipherSuite in cipherSuites)
              {
            if (AllowedCipherSuites.Contains(cipherSuite))
            {
              serverHelloMessage.CipherSuite = cipherSuite;
              SetCipherSuite(cipherSuite);
              break;
            }
              }

              NetMQMessage outgoingMessage = serverHelloMessage.ToNetMQMessage();
              HashLocalAndRemote(outgoingMessage);
              outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ServerHello;
        }
Example #31
0
        public bool ProcessMessages(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (incomingMessage == null)
              {
            if (m_lastReceivedMessage == m_lastSentMessage &&
                    m_lastSentMessage == HandshakeType.HelloRequest && SecurityParameters.Entity == ConnectionEnd.Client)
            {
              OnHelloRequest(outgoingMessages);
              return false;
            }
            else
            {
              throw new ArgumentNullException("handshakeMessage is null");
            }
              }

              HandshakeType handshakeType = (HandshakeType)incomingMessage[0].Buffer[0];

              switch (handshakeType)
              {
            case HandshakeType.ClientHello:
              OnClientHello(incomingMessage, outgoingMessages);
              break;
            case HandshakeType.ServerHello:
              OnServerHello(incomingMessage, outgoingMessages);
              break;
            case HandshakeType.Certificate:
              OnCertificate(incomingMessage, outgoingMessages);
              break;
            case HandshakeType.ServerHelloDone:
              OnServerHelloDone(incomingMessage, outgoingMessages);
              break;
            case HandshakeType.ClientKeyExchange:
              OnClientKeyExchange(incomingMessage, outgoingMessages);
              break;
            case HandshakeType.Finished:
              OnFinished(incomingMessage, outgoingMessages);
              break;
            default:
              throw new ArgumentOutOfRangeException();
              }

            m_lastReceivedMessage = handshakeType;

              return m_done;
        }
Example #32
0
        private void OnClientHello(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.HelloRequest || m_lastSentMessage != HandshakeType.HelloRequest)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Client Hello received when expecting another message");
            }

              HashLocalAndRemote(incomingMessage);

              ClientHelloMessage clientHelloMessage = new ClientHelloMessage();
              clientHelloMessage.SetFromNetMQMessage(incomingMessage);

              SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber;

              AddServerHelloMessage(outgoingMessages, clientHelloMessage.CipherSuites);

              AddCertificateMessage(outgoingMessages);

              AddServerHelloDone(outgoingMessages);
        }
Example #33
0
        private void OnCertificate(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.ServerHello || m_lastSentMessage != HandshakeType.ClientHello)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Certificate received when expecting another message");
            }

              HashLocalAndRemote(incomingMessage);

              CertificateMessage certificateMessage = new CertificateMessage();
              certificateMessage.SetFromNetMQMessage(incomingMessage);

              if (!VerifyCertificate(certificateMessage.Certificate))
              {
            throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage,  "Unable to verify certificate");
              }

              RemoteCertificate = certificateMessage.Certificate;
        }
Example #34
0
        private void OnServerHelloDone(NetMQMessage incomingMessage,
                                  OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.Certificate || m_lastSentMessage != HandshakeType.ClientHello)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Server Hello Done received when expecting another message");
            }

            HashLocalAndRemote(incomingMessage);

            ServerHelloDoneMessage serverHelloDoneMessage = new ServerHelloDoneMessage();
            serverHelloDoneMessage.SetFromNetMQMessage(incomingMessage);

              AddClientKeyExchange(outgoingMessages);

              InvokeChangeCipherSuite();

              AddFinished(outgoingMessages);
        }
Example #35
0
        private void OnServerHello(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.HelloRequest || m_lastSentMessage != HandshakeType.ClientHello)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Server Hello received when expecting another message");
            }

              HashLocalAndRemote(incomingMessage);

              ServerHelloMessage serverHelloMessage = new ServerHelloMessage();
              serverHelloMessage.SetFromNetMQMessage(incomingMessage);

              SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber;

              SetCipherSuite(serverHelloMessage.CipherSuite);
        }
Example #36
0
        private void OnHelloRequest(OutgoingMessageBag outgoingMessages)
        {
            ClientHelloMessage clientHelloMessage = new ClientHelloMessage();

              clientHelloMessage.RandomNumber = new byte[RandomNumberLength];
              m_rng.GetBytes(clientHelloMessage.RandomNumber);

              SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber;

              clientHelloMessage.CipherSuites = AllowedCipherSuites;

              NetMQMessage outgoingMessage = clientHelloMessage.ToNetMQMessage();

              HashLocalAndRemote(outgoingMessage);

              outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ClientHello;
        }
Example #37
0
        private void OnFinished(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (
                (SecurityParameters.Entity == ConnectionEnd.Client &&
                (!m_secureChannel.ChangeSuiteChangeArrived ||
                    m_lastReceivedMessage != HandshakeType.ServerHelloDone || m_lastSentMessage != HandshakeType.Finished)) ||
                (SecurityParameters.Entity == ConnectionEnd.Server &&
                (!m_secureChannel.ChangeSuiteChangeArrived ||
                m_lastReceivedMessage != HandshakeType.ClientKeyExchange || m_lastSentMessage != HandshakeType.ServerHelloDone)))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Finished received when expecting another message");
            }

              if (SecurityParameters.Entity == ConnectionEnd.Server)
              {
            HashLocal(incomingMessage);
              }

              FinishedMessage finishedMessage = new FinishedMessage();
              finishedMessage.SetFromNetMQMessage(incomingMessage);

              m_remoteHash.TransformFinalBlock(new byte[0], 0, 0);

              byte[] seed = m_remoteHash.Hash;
              m_remoteHash.Dispose();
              m_remoteHash = null;

              string label;

              if (SecurityParameters.Entity == ConnectionEnd.Client)
              {
            label = ServerFinishedLabel;
              }
              else
              {
            label = ClientFinshedLabel;
              }

              byte[] verifyData =
            PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

              if (!verifyData.SequenceEqual(finishedMessage.VerifyData))
              {
            throw  new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeVerifyData, "peer verify data wrong");
              }

              if (SecurityParameters.Entity == ConnectionEnd.Server)
              {
            AddFinished(outgoingMessages);
              }

              m_done = true;
        }
Example #38
0
        private void OnClientKeyExchange(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (m_lastReceivedMessage != HandshakeType.ClientHello || m_lastSentMessage != HandshakeType.ServerHelloDone)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Client Key Exchange received when expecting another message");
            }

              HashLocalAndRemote(incomingMessage);

              ClientKeyExchangeMessage clientKeyExchangeMessage = new ClientKeyExchangeMessage();
              clientKeyExchangeMessage.SetFromNetMQMessage(incomingMessage);

              RSACryptoServiceProvider rsa = LocalCertificate.PrivateKey as RSACryptoServiceProvider;

              byte[] premasterSecret = rsa.Decrypt(clientKeyExchangeMessage.EncryptedPreMasterSecret, false);

              GenerateMasterSecret(premasterSecret);

              InvokeChangeCipherSuite();
        }
Example #39
0
        private void AddCertificateMessage(OutgoingMessageBag outgoingMessages)
        {
            CertificateMessage certificateMessage = new CertificateMessage();
              certificateMessage.Certificate = LocalCertificate;

              NetMQMessage outgoingMessage = certificateMessage.ToNetMQMessage();
              HashLocalAndRemote(outgoingMessage);
              outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Certificate;
        }
Example #40
0
 private void AddServerHelloDone(OutgoingMessageBag outgoingMessages)
 {
     ServerHelloDoneMessage serverHelloDoneMessage = new ServerHelloDoneMessage();
       NetMQMessage outgoingMessage = serverHelloDoneMessage.ToNetMQMessage();
       HashLocalAndRemote(outgoingMessage);
       outgoingMessages.AddHandshakeMessage(outgoingMessage);
     m_lastSentMessage = HandshakeType.ServerHelloDone;
 }
Example #41
0
        private void AddClientKeyExchange(OutgoingMessageBag outgoingMessages)
        {
            ClientKeyExchangeMessage clientKeyExchangeMessage = new ClientKeyExchangeMessage();

              byte[] premasterSecret = new byte[ClientKeyExchangeMessage.PreMasterSecretLength];
              m_rng.GetBytes(premasterSecret);

              RSACryptoServiceProvider rsa = RemoteCertificate.PublicKey.Key as RSACryptoServiceProvider;
              clientKeyExchangeMessage.EncryptedPreMasterSecret = rsa.Encrypt(premasterSecret, false);

              GenerateMasterSecret(premasterSecret);

              NetMQMessage outgoingMessage = clientKeyExchangeMessage.ToNetMQMessage();
              HashLocalAndRemote(outgoingMessage);
              outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ClientKeyExchange;
        }
Example #42
0
        /// <summary>
        /// Given an incoming handshake-protocol message, route it to the corresponding handler.
        /// </summary>
        /// <param name="incomingMessage">the NetMQMessage that has come in</param>
        /// <param name="outgoingMessages">a collection of NetMQMessages that are to be sent</param>
        /// <returns>true if finished - ie, an incoming message of type Finished was received</returns>
        /// <exception cref="ArgumentNullException"><paramref name="incomingMessage"/> must not be <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="incomingMessage"/> must have a valid <see cref="HandshakeType"/>.</exception>
        public bool ProcessMessages(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (incomingMessage == null)
            {
                if (m_lastReceivedMessage == m_lastSentMessage &&
                    m_lastSentMessage == HandshakeType.HelloRequest &&
                    SecurityParameters.Entity == ConnectionEnd.Client)
                {
                    //客户端发送握手
                    OnHelloRequest(outgoingMessages);
                    return(false);
                }
                else
                {
                    throw new ArgumentNullException(nameof(incomingMessage));
                }
            }

#if DEBUG
            int size = incomingMessage.Sum(f => f.BufferSize);
            Debug.WriteLine("[handshake(" + size + ")]:");
            byte[] data   = new byte[size];
            int    offset = 0;
            foreach (var frame in incomingMessage)
            {
                Buffer.BlockCopy(frame.Buffer, 0, data, offset, frame.BufferSize);
            }
            Debug.WriteLine(BitConverter.ToString(data));
#endif

            //A Finished message is always sent immediately after a change cipher spec message to verify that the key exchange and authentication processes were successful.
            //It is essential that a change cipher spec message be received between the other handshake messages and the Finished message.
            //已经收到ChangeCipherSuite,接下来就是Finish
            HandshakeType handshakeType;

            if (m_secureChannel.ChangeSuiteChangeArrived)
            {
                handshakeType = HandshakeType.Finished;
            }
            else
            {
                handshakeType = (HandshakeType)incomingMessage[0].Buffer[0];
                ////起始计数从0开始,Finished在解密的时候会添加计数,其他record层都要在这里添加读计数
                //m_secureChannel.RecordLayer.GetAndIncreaseReadSequneceNumber();
            }

            switch (handshakeType)
            {
            case HandshakeType.HelloRequest:
            {
                //接收到对端的HelloRequest重新协商。暂时抛出异常重置连接
                NetMQMessage alert = m_secureChannel.HandshakeFailure(AlertLevel.Fatal, m_secureChannel.ProtocolVersion);
                //抛出异常,返回alert协议,通知客户端断开连接。
                throw new AlertException(alert, new Exception(AlertDescription.NoRenegotiation.ToString()));
            }

            case HandshakeType.ClientHello:
                OnClientHello(incomingMessage, outgoingMessages);
                break;

            case HandshakeType.ServerHello:
                OnServerHello(incomingMessage);
                break;

            case HandshakeType.Certificate:
                OnCertificate(incomingMessage);
                break;

            case HandshakeType.ServerHelloDone:
                OnServerHelloDone(incomingMessage, outgoingMessages);
                break;

            case HandshakeType.ClientKeyExchange:
                OnClientKeyExchange(incomingMessage);
                break;

            case HandshakeType.Finished:
                OnFinished(incomingMessage, outgoingMessages);
                break;

            default:
            {
                NetMQMessage alert = m_secureChannel.HandshakeFailure(AlertLevel.Fatal, m_secureChannel.ProtocolVersion);
                //抛出异常,返回alert协议,通知客户端断开连接。
                throw new AlertException(alert, new Exception(AlertDescription.UnexpectedMessage.ToString()));
            }
            }

            m_lastReceivedMessage = handshakeType;

            return(m_done);
        }