예제 #1
0
        bool ProcessHandshakeMessage(TlsBuffer incoming, out SecurityStatus status)
        {
            var handshakeType = (HandshakeType)incoming.ReadByte();

                        #if DEBUG_FULL
            if (EnableDebugging)
            {
                DebugHelper.WriteLine(">>>> Processing Handshake record ({0})", handshakeType);
                DebugHelper.WriteRemaining("HANDSHAKE", incoming);
            }
                        #endif

            // Read message length
            int length = incoming.ReadInt24();
            if (incoming.Remaining < length)
            {
                cachedFragment          = new TlsBuffer(length + 4);
                cachedFragment.Position = incoming.Remaining + 4;
                Buffer.BlockCopy(incoming.Buffer, incoming.Position - 4, cachedFragment.Buffer, 0, cachedFragment.Position);
                incoming.Dispose();
                status = SecurityStatus.ContinueNeeded;
                return(false);
            }

            var buffer = incoming.ReadBuffer(length);
            return(negotiationHandler.ProcessHandshakeMessage(handshakeType, buffer, out status));
        }
예제 #2
0
        SecurityStatus _DecryptMessage(ref TlsBuffer incoming)
        {
            // Try to read the Record Content Type
            var contentType = (ContentType)incoming.ReadByte();

                        #if DEBUG_FULL
            if (EnableDebugging)
            {
                DebugHelper.WriteLine("DecryptMessage: {0}", contentType);
            }
                        #endif

            ReadStandardBuffer(contentType, ref incoming);

            if (contentType == ContentType.Alert)
            {
                var level       = (AlertLevel)incoming.ReadByte();
                var description = (AlertDescription)incoming.ReadByte();
                if (level == AlertLevel.Warning && description == AlertDescription.CloseNotify)
                {
                    ReceivedCloseNotify = true;
                    return(SecurityStatus.ContextExpired);
                }
                DebugHelper.WriteLine("ALERT: {0} {1}", level, description);
                throw new TlsException(level, description);
            }
            else if (contentType == ContentType.ApplicationData)
            {
                return(SecurityStatus.OK);
            }
            else if (contentType != ContentType.Handshake)
            {
                throw new TlsException(AlertDescription.UnexpectedMessage, "Unknown content type {0}", contentType);
            }

            try {
                SecurityStatus status;
                var            finished = ProcessHandshakeMessage(incoming, out status);
                DebugHelper.WriteLine("RENEGOTIATION REQUEST: {0} {1}", finished, status);
                return(status);
            } finally {
                incoming.Dispose();
                incoming = null;
            }
        }
예제 #3
0
        SecurityStatus ProcessAlert(TlsBuffer buffer)
        {
            bool decrypted = false;

            if ((session.Read != null && session.Read.Cipher != null) || (buffer.Remaining != 2))
            {
                decrypted = ReadStandardBuffer(ContentType.Alert, ref buffer);
            }
            if (buffer.Remaining != 2)
            {
                throw new TlsException(AlertDescription.IlegalParameter, "Invalid Alert message size");
            }

            var level       = (AlertLevel)buffer.ReadByte();
            var description = (AlertDescription)buffer.ReadByte();

            if (decrypted)
            {
                buffer.Dispose();
            }

            if (level == AlertLevel.Warning)
            {
                if (description == AlertDescription.CloseNotify)
                {
                    ReceivedCloseNotify = true;
                    if (eventSink != null)
                    {
                        eventSink.ReceivedCloseNotify();
                    }
                    return(SecurityStatus.ContextExpired);
                }

                DebugHelper.WriteLine("Received alert: {0}", description);
                return(SecurityStatus.ContinueNeeded);
            }
            else
            {
                throw new TlsException(description);
            }
        }
예제 #4
0
        SecurityStatus _GenerateNextToken(TlsBuffer incoming, TlsMultiBuffer outgoing)
        {
                        #if DEBUG_FULL
            if (EnableDebugging)
            {
                DebugHelper.WriteLine("GenerateNextToken: {0}", negotiationHandler);
                if (incoming != null)
                {
                    DebugHelper.WriteRemaining("  incoming", incoming);
                }
            }
                        #endif

            if (incoming == null)
            {
                negotiationHandler = negotiationHandler.GenerateReply(outgoing);
                return(SecurityStatus.ContinueNeeded);
            }

            var contentType = (ContentType)incoming.ReadByte();
                        #if DEBUG_FULL
            if (EnableDebugging)
            {
                DebugHelper.WriteLine("  received message type {0}", contentType);
            }
                        #endif

            if (skipToOffset >= 0 && contentType != ContentType.Handshake)
            {
                throw new TlsException(AlertDescription.InternalError);
            }

            if (contentType == ContentType.Alert)
            {
                return(ProcessAlert(incoming));
            }

            bool decrypted = false;
            if (cachedFragment != null)
            {
                if (contentType != ContentType.Handshake)
                {
                    throw new TlsException(AlertDescription.DecodeError);
                }
                decrypted = ReadStandardBuffer(ContentType.Handshake, ref incoming);
                cachedFragment.Write(incoming.Buffer, incoming.Position, incoming.Position + incoming.Remaining);
                if (cachedFragment.Remaining > 0)
                {
                    return(SecurityStatus.ContinueNeeded);
                }
                incoming.Dispose();
                incoming          = cachedFragment;
                cachedFragment    = null;
                incoming.Position = 0;
            }
            else
            {
                decrypted = ReadStandardBuffer(contentType, ref incoming);
            }

            if (Session.Read != null && Session.Read.Cipher != null && !decrypted)
            {
                throw new TlsException(AlertDescription.DecryptError, "Expected encrypted message.");
            }

            try {
                if (contentType == ContentType.ChangeCipherSpec)
                {
                    return(negotiationHandler.ProcessMessage(new TlsChangeCipherSpec()));
                }
                else if (contentType == ContentType.ApplicationData)
                {
                    if (session.Read == null || session.Read.Cipher == null || !session.SecureRenegotiation)
                    {
                        throw new TlsException(AlertDescription.DecodeError);
                    }
                    // FIXME
                    throw new NotImplementedException();
                }
                else if (contentType != ContentType.Handshake)
                {
                    throw new TlsException(AlertDescription.UnexpectedMessage);
                }

                if (skipToOffset >= 0)
                {
                    incoming.Position = skipToOffset;
                    skipToOffset      = -1;
                }

                SecurityStatus result;
                bool           finished;

                while (true)
                {
                    var startOffset = incoming.Position;
                    finished = ProcessHandshakeMessage(incoming, out result);
                    if (result == SecurityStatus.CredentialsNeeded)
                    {
                        // Caller will call us again with the same input.
                        skipToOffset = startOffset;
                        if (decrypted)
                        {
                            Session.Read.ReadSequenceNumber--;
                        }
                        return(result);
                    }
                    if (incoming.Remaining == 0)
                    {
                        break;
                    }
                    if (finished || result != SecurityStatus.ContinueNeeded)
                    {
                        throw new TlsException(AlertDescription.UnexpectedMessage);
                    }
                }

                if (finished)
                {
                    negotiationHandler = negotiationHandler.GenerateReply(outgoing);
                }

                return(result);
            } finally {
                if (decrypted)
                {
                    incoming.Dispose();
                }
            }
        }