コード例 #1
0
        private void AwaitEncryptedMessage(Byte[] l7Data, PmFrameBase pdu)
        {
            if (l7Data[0] == Record)
            {
                // record protocol
                this._state = this.Decrypter.DoDecryption(l7Data, pdu, ref this._decryptedBytes)? SslSessionState.DataExchange : SslSessionState.Intermezzo;
            }
            else if (l7Data[0] == Handshake)
            {
                // tls handshaking protocol
                // renegotiation
                // TODO could be Finished?
                this._msgUnderReview--;
                // TODO isn't renegotiation encrypted??
                this._state = SslSessionState.NegotiationInit;
            }
            else if (l7Data[0] == ChangeCipherSpec && l7Data.Length > 6) // ChangeCipherSpec message has 6 bytes
            {
                // 'Finished' is in this pdu - TODO can be in next pdu?
                var finished = new Byte[l7Data.Length - 6];
                Array.Copy(l7Data, 6, finished, 0, finished.Length);
                this.Decrypter.DoDecryption(finished, pdu, ref this._decryptedBytes);
                this._decryptedBytes = null;

                this._state = SslSessionState.Intermezzo;
            }
            else if (l7Data[0] == Alert)
            {
                // alert protocol
                // ignore
                this._state = SslSessionState.Intermezzo;
            }
            // else something wrong
        }
コード例 #2
0
        private void AwaitFinishedMessage(Byte[] l7Data, PmFrameBase pdu)
        {
            if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor)
            {
                this.Decrypter.DoDecryption(l7Data, pdu, ref this._decryptedBytes);
                this._decryptedBytes = null;

                this._state = SslSessionState.Intermezzo;
            }
        }
コード例 #3
0
        private void AwaitClientKeyExchange(Byte[] l7Data, PmFrameBase pdu)
        {
            if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor && l7Data[5] == ClientKeyExchange)
            {
                this.Decrypter.ClientDirection = pdu.SrcAddress.GetAddressBytes();
                this.Decrypter.KeyDecrypter.ParseClientKeyExchange(l7Data);
                var preMaster = this.Decrypter.KeyDecrypter.DecryptKey();

                // use premaster to get ciphering key
                var master = this.Decrypter.Prf(preMaster, "master secret", this.Decrypter.ClientRnd, this.Decrypter.ServerRnd, 48, l7Data[2]);

                // Save Master key for current session
                SessionsMasterKeys.Add(this._currentSessionID, master);


                var keyBlock = this.Decrypter.Prf(master, "key expansion", this.Decrypter.ServerRnd, this.Decrypter.ClientRnd,
                                                  this.Decrypter.DataDecrypter.MacKeyLength * 2 + this.Decrypter.DataDecrypter.KeyLength * 2 + this.Decrypter.DataDecrypter.IvLength * 2, l7Data[2]);

                this.Decrypter.ClientHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];
                this.Decrypter.ServerHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];

                Array.Copy(keyBlock, 0, this.Decrypter.ClientHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);
                Array.Copy(keyBlock, this.Decrypter.DataDecrypter.MacKeyLength, this.Decrypter.ServerHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);

                // Only part of key_block is used to encrypt data
                this.Decrypter.DataDecrypter.Init(keyBlock);

                // Look for finished - sent immediately after change cipher spec
                var totalLen = 0;
                do
                {
                    var t = new Byte[2];
                    Array.Copy(l7Data, 3, t, 0, 2);
                    Array.Reverse(t);
                    totalLen += 5;
                    totalLen += BitConverter.ToInt16(t, 0);
                } while(totalLen < l7Data.Length && l7Data[totalLen] != ChangeCipherSpec);

                if (totalLen < l7Data.Length)
                {
                    // 'Finished' is in this pdu
                    totalLen += 6; // ChangeCipherSpec message has 6 bytes
                    var finished = new Byte[l7Data.Length - totalLen];
                    Array.Copy(l7Data, totalLen, finished, 0, finished.Length);
                    this.Decrypter.DoDecryption(finished, pdu, ref this._decryptedBytes);
                    this._decryptedBytes = null;

                    this._state = SslSessionState.Intermezzo;
                }
                else
                {
                    this._state = SslSessionState.NegotiationChangeCipherSpec;
                }
            }
        }
コード例 #4
0
        public override Boolean Reset()
        {
            this._state               = SslSessionState.NegotiationInit;
            this._msgUnderReview      = 0;
            this._decryptedDataCnt    = 0;
            this._decryptedDataOffset = 0;
            this.DataList.Clear();
            this._decryptedBytes = null;
            this._processedPdus.Clear();
            this._dataDecrypted = false;
            this._lastPDU       = false;
            this.Pdus           = this._conversation.L7PDUs.ToArray();
            this.Decrypter      = new PDUDecrypter();
            SessionsMasterKeys.Clear();

            return(this.ResetSoft());
        }
コード例 #5
0
 private void AwaitChangeCipherSpecMessage(Byte[] l7Data, PmFrameBase pdu)
 {
     if (l7Data[0] == ChangeCipherSpec && l7Data[1] == Ssl3VerMajor && l7Data[5] == ChangeCipherSpecMessage)
     {
         //1 byte for content type
         //2 bytes for protocol version
         //2 bytes for message length
         //1 byte for change cypher spec message
         if (l7Data.Length > 6) //If finished message follows directly after Change Cipher Spec
         {
             var l7FinishedMsg = new byte[l7Data.Length - 6];
             Array.Copy(l7Data, 6, l7FinishedMsg, 0, l7Data.Length - 6);
             this.AwaitFinishedMessage(l7FinishedMsg, pdu);
         }
         else
         {
             this._state = SslSessionState.NegotiationFinished;
         }
     }
 }
コード例 #6
0
 extern static /* OSStatus */ SslStatus SSLGetSessionState(/* SSLContextRef */ IntPtr context, ref SslSessionState state);
コード例 #7
0
        private void AwaitHelloMessages(Byte[] l7Data, PmFrameBase pdu)
        {
            // Get server hello message
            if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor && l7Data[5] == ServerHello)
            {
                this.Decrypter.ServerRnd = new Byte[32];

                Array.Copy(l7Data, 11, this.Decrypter.ServerRnd, 0, this.Decrypter.ServerRnd.Length);

                ConversationCipherSuite conversationCipherSuite;
                KeyDecrypter            keyDecrypter;
                DataDecrypter           dataDecrypter;

                this.Decrypter.ChangeCipherSuite(l7Data, out conversationCipherSuite);
                this._conversation.CipherSuite = conversationCipherSuite;

                CipherSuiteInitializer.PrepareDecryptingAlgorithms(this._conversation.Key.ServerPrivateKey, this._conversation.CipherSuite, out keyDecrypter, out dataDecrypter);

                this.Decrypter.KeyDecrypter  = keyDecrypter;
                this.Decrypter.DataDecrypter = dataDecrypter;

                // Get SSL Session ID and save it
                var sessionID = new Byte[32];
                Array.Copy(l7Data, 44, sessionID, 0, 32);
                Array.Copy(sessionID, this._currentSessionID, this._currentSessionID.Length);

                // Get ServerHello content length
                var serverHelloContentLengthBytes = new Byte[2];
                Array.Copy(l7Data, 3, serverHelloContentLengthBytes, 0, 2);
                Array.Reverse(serverHelloContentLengthBytes);
                var serverHelloContentLength = BitConverter.ToUInt16(serverHelloContentLengthBytes, 0);

                // Get total ServerHello length
                // ContentType(1B) Version(2B) Length(2B) Content
                var serverHelloLength = 1 + 2 + 2 + serverHelloContentLength;

                // Check whether there is something else after ServerHello message and whether it is ChangeCipherSpec message
                // If yes, session resumption is used
                if (serverHelloLength < l7Data.Length && l7Data[serverHelloLength + 0] == ChangeCipherSpec && SessionsMasterKeys.ContainsKey(sessionID))
                {
                    this.Decrypter.ClientDirection = pdu.DstAddress.GetAddressBytes();

                    // Load saved Master key for given Session ID
                    var master = SessionsMasterKeys[sessionID];


                    var keyBlock = this.Decrypter.Prf(master, "key expansion", this.Decrypter.ServerRnd, this.Decrypter.ClientRnd,
                                                      this.Decrypter.DataDecrypter.MacKeyLength * 2 + this.Decrypter.DataDecrypter.KeyLength * 2 + this.Decrypter.DataDecrypter.IvLength * 2, l7Data[2]);

                    this.Decrypter.ClientHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];
                    this.Decrypter.ServerHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];

                    Array.Copy(keyBlock, 0, this.Decrypter.ClientHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);
                    Array.Copy(keyBlock, this.Decrypter.DataDecrypter.MacKeyLength, this.Decrypter.ServerHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);

                    // Only part of key_block is used to encrypt data
                    this.Decrypter.DataDecrypter.Init(keyBlock);

                    var changeCipherSpecLength = 6;
                    if (serverHelloLength + changeCipherSpecLength < l7Data.Length)
                    {
                        var finishedOffset = serverHelloLength + changeCipherSpecLength;
                        var finished       = new Byte[l7Data.Length - finishedOffset];
                        Array.Copy(l7Data, finishedOffset, finished, 0, finished.Length);
                        this.Decrypter.DoDecryption(finished, pdu, ref this._decryptedBytes);
                        this._decryptedBytes = null;
                    }

                    this._state = SslSessionState.NegotiationChangeCipherSpec;
                }
                // Otherwise, new session is made
                else
                {
                    this._state = SslSessionState.Negotiation;
                }
            }
            else if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor && l7Data[5] == ClientHello)
            {
                // client hello - should be found before server hello message
                this.Decrypter.ClientRnd = new Byte[32];
                Array.Copy(l7Data, 11, this.Decrypter.ClientRnd, 0, this.Decrypter.ClientRnd.Length);
            }
        }
コード例 #8
0
 static extern SslStatus SSLGetSessionState(/* SSLContextRef */ IntPtr context, ref SslSessionState state);