Exemple #1
0
        public bool ProcessMessage(NetMQMessage incomingMessage, IList <NetMQMessage> outgoingMesssages)
        {
            ContentType contentType = ContentType.Handshake;

            if (incomingMessage != null)
            {
                NetMQFrame protocolVersionFrame = incomingMessage.Pop();
                byte[]     protocolVersionBytes = protocolVersionFrame.ToByteArray();

                if (protocolVersionBytes.Length != 2)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "Wrong length for protocol version frame");
                }

                if (!protocolVersionBytes.SequenceEqual(m_protocolVersion))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version");
                }

                NetMQFrame contentTypeFrame = incomingMessage.Pop();

                if (contentTypeFrame.MessageSize != 1)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "wrong length for message size");
                }

                contentType = (ContentType)contentTypeFrame.Buffer[0];

                if (contentType != ContentType.ChangeCipherSpec && contentType != ContentType.Handshake)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Unkown content type");
                }

                if (ChangeSuiteChangeArrived)
                {
                    incomingMessage = m_recordLayer.DecryptMessage(contentType, incomingMessage);
                }
            }

            bool result = false;

            if (contentType == ContentType.Handshake)
            {
                result = m_handshakeLayer.ProcessMessages(incomingMessage, m_outgoingMessageBag);

                foreach (NetMQMessage outgoingMesssage in m_outgoingMessageBag.Messages)
                {
                    outgoingMesssages.Add(outgoingMesssage);
                }

                m_outgoingMessageBag.Clear();
            }
            else
            {
                ChangeSuiteChangeArrived = true;
            }

            return(SecureChannelReady = result && ChangeSuiteChangeArrived);
        }
Exemple #2
0
        /// <summary>
        /// Process handshake and change cipher suite messages. This method should be called for every incoming message until the method returns true.
        /// You cannot encrypt or decrypt messages until the method return true.
        /// Each call to the method may include outgoing messages that need to be sent to the other peer.
        /// </summary>
        /// <param name="incomingMessage">the incoming message from the other peer</param>
        /// <param name="outgoingMesssages">the list of outgoing messages that need to be sent to the other peer</param>
        /// <returns>true when the method completes the handshake stage and the SecureChannel is ready to encrypt and decrypt messages</returns>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidContentType: Unknown content type.</exception>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidFrameLength: Wrong length for protocol version frame.</exception>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidFrameLength: Wrong length for message size.</exception>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidProtocolVersion: Wrong protocol version.</exception>
        /// <remarks>
        /// Note: Within this library, this method is ONLY called from within the unit-tests.
        /// </remarks>
        public bool ProcessMessage(NetMQMessage incomingMessage, IList <NetMQMessage> outgoingMesssages)
        {
#if DEBUG
            if (incomingMessage != null)
            {
                Debug.WriteLine("[record layer(" + incomingMessage.Sum(f => f.BufferSize) + ")]");
            }
#endif
            ContentType contentType = ContentType.Handshake;

            if (incomingMessage != null)
            {
                // Verify that the first two frames are the protocol-version and the content-type,

                NetMQFrame contentTypeFrame = incomingMessage.Pop();

                if (contentTypeFrame.MessageSize != 1)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "wrong length for Content Type  size");
                }

                // Verify that the content-type is either handshake, or change-cipher-suit..
                contentType = (ContentType)contentTypeFrame.Buffer[0];

                if (contentType != ContentType.ChangeCipherSpec && contentType != ContentType.Handshake && contentType != ContentType.Alert)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Unknown content type");
                }
                NetMQFrame protocolVersionFrame = incomingMessage.Pop();
                byte[]     protocolVersionBytes = protocolVersionFrame.ToByteArray();

                if (protocolVersionBytes.Length != 2)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "Wrong length for protocol version frame");
                }
                if (n_ConnectionEnd == ConnectionEnd.Server && contentType == ContentType.Handshake)
                {
                    //第一次握手时
                    if (ProtocolVersion == null)
                    {
                        //校验记录层版本号是否支持
                        if (Constants.SupposeVersions.Any(p => p.SequenceEqual(protocolVersionBytes)))
                        {
                            //支持版本
                            ProtocolVersion = protocolVersionBytes;
                        }
                        else
                        {
                            throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "the protocol version is not supposed");
                        }
                    }
                }
                //作为服务端首次接收到客户端
                if (!protocolVersionBytes.SequenceEqual(ProtocolVersion))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version");
                }
                RemoveLength(incomingMessage);
                if (ChangeSuiteChangeArrived)
                {
                    RecordLayer.SetSubProtocolVersion(m_handshakeLayer.SubProtocolVersion);

                    //已经收到ChangeCipherSuite,接下来就是Finish
                    //Finished报文是第一个解密报文。需要解密。
                    incomingMessage = RecordLayer.DecryptMessage(contentType, incomingMessage);
                }
                if (contentType == ContentType.Alert)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeException, "peer response alert[" + (AlertDescription)incomingMessage.Last.Buffer[0] + "]");
                }
            }
            else
            {
                //作为客户端确定使用的版本号,后续客户端和服务端通讯都要校验版本号一致性。
                //客户端使用3,3版本
                ProtocolVersion = GetVersion(Configuration.StandardTLSFormat);
            }

            bool result = false;
            if (contentType == ContentType.Handshake)
            {
                result         = m_handshakeLayer.ProcessMessages(incomingMessage, m_outgoingMessageBag);
                this.SessionId = m_handshakeLayer.SessionID;
                if (m_outgoingMessageBag.Messages.Count() > 1)
                {
                    // Move the messages from the saved list over to the outgoing Messages collection..
                    foreach (NetMQMessage outgoingMesssage in m_outgoingMessageBag.Messages)
                    {
                        outgoingMesssages.Add(outgoingMesssage);
                    }
                }
                else
                {
                    // Move the messages from the saved list over to the outgoing Messages collection..
                    foreach (NetMQMessage outgoingMesssage in m_outgoingMessageBag.Messages)
                    {
                        outgoingMesssages.Add(outgoingMesssage);
                    }
                }
                m_outgoingMessageBag.Clear();
            }
            else
            {
                ////每个record计数都+1
                //RecordLayer.GetAndIncreaseReadSequneceNumber();
                //接下去的是Finished,需要加密。
                ChangeSuiteChangeArrived = true;
            }

            return(SecureChannelReady = result && ChangeSuiteChangeArrived);
        }