public static Certificate Parse(Stream input)
    {
        int num = TlsUtilities.ReadUint24(input);

        if (num == 0)
        {
            return(EmptyChain);
        }
        byte[]       buffer       = TlsUtilities.ReadFully(num, input);
        MemoryStream memoryStream = new MemoryStream(buffer, writable: false);
        IList        list         = Platform.CreateArrayList();

        while (memoryStream.Position < memoryStream.Length)
        {
            byte[]     encoding = TlsUtilities.ReadOpaque24(memoryStream);
            Asn1Object obj      = TlsUtilities.ReadDerObject(encoding);
            list.Add(X509CertificateStructure.GetInstance(obj));
        }
        X509CertificateStructure[] array = new X509CertificateStructure[list.Count];
        for (int i = 0; i < list.Count; i++)
        {
            array[i] = (X509CertificateStructure)list[i];
        }
        return(new Certificate(array));
    }
Example #2
0
        /**
         * Parse a {@link Certificate} from a {@link Stream}.
         *
         * @param input the {@link Stream} to parse from.
         * @return a {@link Certificate} object.
         * @throws IOException
         */
        public static Certificate Parse(Stream input)
        {
            int totalLength = TlsUtilities.ReadUint24(input);

            if (totalLength == 0)
            {
                return(EmptyChain);
            }

            byte[] certListData = TlsUtilities.ReadFully(totalLength, input);

            MemoryStream buf = new MemoryStream(certListData, false);

            IList certificate_list = Platform.CreateArrayList();

            while (buf.Position < buf.Length)
            {
                byte[]     derEncoding = TlsUtilities.ReadOpaque24(buf);
                Asn1Object asn1Cert    = TlsUtilities.ReadDerObject(derEncoding);
                certificate_list.Add(X509CertificateStructure.GetInstance(asn1Cert));
            }

            X509CertificateStructure[] certificateList = new X509CertificateStructure[certificate_list.Count];
            for (int i = 0; i < certificate_list.Count; ++i)
            {
                certificateList[i] = (X509CertificateStructure)certificate_list[i];
            }
            return(new Certificate(certificateList));
        }
Example #3
0
    private void ProcessHandshake()
    {
        bool flag;

        do
        {
            flag = false;
            if (mHandshakeQueue.Available < 4)
            {
                continue;
            }
            byte[] array = new byte[4];
            mHandshakeQueue.Read(array, 0, 4, 0);
            byte b   = TlsUtilities.ReadUint8(array, 0);
            int  num = TlsUtilities.ReadUint24(array, 1);
            if (mHandshakeQueue.Available < num + 4)
            {
                continue;
            }
            byte[] array2 = mHandshakeQueue.RemoveData(num, 4);
            CheckReceivedChangeCipherSpec(mConnectionState == 16 || b == 20);
            if (b != 0)
            {
                TlsContext context = Context;
                if (b == 20 && mExpectedVerifyData == null && context.SecurityParameters.MasterSecret != null)
                {
                    mExpectedVerifyData = CreateVerifyData(!context.IsServer);
                }
                mRecordStream.UpdateHandshakeData(array, 0, 4);
                mRecordStream.UpdateHandshakeData(array2, 0, num);
            }
            HandleHandshakeMessage(b, array2);
            flag = true;
        }while (flag);
    }
        private void HandleRetransmittedHandshakeRecord(int epoch, byte[] buf, int off, int len)
        {
            /*
             * TODO Need to handle the case where the previous inbound flight contains
             * messages from two epochs.
             */
            if (len < 12)
            {
                return;
            }
            int fragment_length = TlsUtilities.ReadUint24(buf, off + 9);

            if (len != (fragment_length + 12))
            {
                return;
            }
            int seq = TlsUtilities.ReadUint16(buf, off + 4);

            if (seq >= mNextReceiveSeq)
            {
                return;
            }

            byte msg_type = TlsUtilities.ReadUint8(buf, off);

            // TODO This is a hack that only works until we try to support renegotiation
            int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0;

            if (epoch != expectedEpoch)
            {
                return;
            }

            int length          = TlsUtilities.ReadUint24(buf, off + 1);
            int fragment_offset = TlsUtilities.ReadUint24(buf, off + 6);

            if (fragment_offset + fragment_length > length)
            {
                return;
            }

            DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[seq];

            if (reassembler != null)
            {
                reassembler.ContributeFragment(msg_type, length, buf, off + 12, fragment_offset,
                                               fragment_length);
                if (CheckAll(mCurrentInboundFlight))
                {
                    ResendOutboundFlight();
                    ResetAll(mCurrentInboundFlight);
                }
            }
        }
    private void HandleRetransmittedHandshakeRecord(int epoch, byte[] buf, int off, int len)
    {
        if (len < 12)
        {
            return;
        }
        int num = TlsUtilities.ReadUint24(buf, off + 9);

        if (len != num + 12)
        {
            return;
        }
        int num2 = TlsUtilities.ReadUint16(buf, off + 4);

        if (num2 >= mNextReceiveSeq)
        {
            return;
        }
        byte b    = TlsUtilities.ReadUint8(buf, off);
        int  num3 = (b == 20) ? 1 : 0;

        if (epoch != num3)
        {
            return;
        }
        int num4 = TlsUtilities.ReadUint24(buf, off + 1);
        int num5 = TlsUtilities.ReadUint24(buf, off + 6);

        if (num5 + num > num4)
        {
            return;
        }
        DtlsReassembler dtlsReassembler = (DtlsReassembler)mCurrentInboundFlight[num2];

        if (dtlsReassembler != null)
        {
            dtlsReassembler.ContributeFragment(b, num4, buf, off + 12, num5, num);
            if (CheckAll(mCurrentInboundFlight))
            {
                ResendOutboundFlight();
                ResetAll(mCurrentInboundFlight);
            }
        }
    }
Example #6
0
        private bool ProcessRecord(int windowSize, int epoch, byte[] buf, int off, int len)
        {
            bool checkPreviousFlight = false;

            while (len >= MessageHeaderLength)
            {
                int fragment_length = TlsUtilities.ReadUint24(buf, off + 9);
                int message_length  = fragment_length + MessageHeaderLength;
                if (len < message_length)
                {
                    // NOTE: Truncated message - ignore it
                    break;
                }

                int length          = TlsUtilities.ReadUint24(buf, off + 1);
                int fragment_offset = TlsUtilities.ReadUint24(buf, off + 6);
                if (fragment_offset + fragment_length > length)
                {
                    // NOTE: Malformed fragment - ignore it and the rest of the record
                    break;
                }

                /*
                 * NOTE: This very simple epoch check will only work until we want to support
                 * renegotiation (and we're not likely to do that anyway).
                 */
                byte msg_type      = TlsUtilities.ReadUint8(buf, off + 0);
                int  expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0;
                if (epoch != expectedEpoch)
                {
                    break;
                }

                int message_seq = TlsUtilities.ReadUint16(buf, off + 4);
                if (message_seq >= (mNextReceiveSeq + windowSize))
                {
                    // NOTE: Too far ahead - ignore
                }
                else if (message_seq >= mNextReceiveSeq)
                {
                    DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[message_seq];
                    if (reassembler == null)
                    {
                        reassembler = new DtlsReassembler(msg_type, length);
                        mCurrentInboundFlight[message_seq] = reassembler;
                    }

                    reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset,
                                                   fragment_length);
                }
                else if (mPreviousInboundFlight != null)
                {
                    /*
                     * NOTE: If we receive the previous flight of incoming messages in full again,
                     * retransmit our last flight
                     */

                    DtlsReassembler reassembler = (DtlsReassembler)mPreviousInboundFlight[message_seq];
                    if (reassembler != null)
                    {
                        reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset,
                                                       fragment_length);
                        checkPreviousFlight = true;
                    }
                }

                off += message_length;
                len -= message_length;
            }

            bool result = checkPreviousFlight && CheckAll(mPreviousInboundFlight);

            if (result)
            {
                ResendOutboundFlight();
                ResetAll(mPreviousInboundFlight);
            }
            return(result);
        }
        internal Message ReceiveMessage()
        {
            if (mSending)
            {
                mSending = false;
                PrepareInboundFlight();
            }

            // Check if we already have the next message waiting
            {
                DtlsReassembler next = (DtlsReassembler)mCurrentInboundFlight[mNextReceiveSeq];
                if (next != null)
                {
                    byte[] body = next.GetBodyIfComplete();
                    if (body != null)
                    {
                        mPreviousInboundFlight = null;
                        return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, next.MsgType, body)));
                    }
                }
            }

            byte[] buf = null;

            // TODO Check the conditions under which we should reset this
            int readTimeoutMillis = 1000;

            for (;;)
            {
                int receiveLimit = mRecordLayer.GetReceiveLimit();
                if (buf == null || buf.Length < receiveLimit)
                {
                    buf = new byte[receiveLimit];
                }

                // TODO Handle records containing multiple handshake messages

                try
                {
                    for (; ;)
                    {
                        int received = mRecordLayer.Receive(buf, 0, receiveLimit, readTimeoutMillis);
                        if (received < 0)
                        {
                            break;
                        }
                        if (received < 12)
                        {
                            continue;
                        }
                        int fragment_length = TlsUtilities.ReadUint24(buf, 9);
                        if (received != (fragment_length + 12))
                        {
                            continue;
                        }
                        int seq = TlsUtilities.ReadUint16(buf, 4);
                        if (seq > (mNextReceiveSeq + MAX_RECEIVE_AHEAD))
                        {
                            continue;
                        }
                        byte msg_type        = TlsUtilities.ReadUint8(buf, 0);
                        int  length          = TlsUtilities.ReadUint24(buf, 1);
                        int  fragment_offset = TlsUtilities.ReadUint24(buf, 6);
                        if (fragment_offset + fragment_length > length)
                        {
                            continue;
                        }

                        if (seq < mNextReceiveSeq)
                        {
                            /*
                             * NOTE: If we Receive the previous flight of incoming messages in full
                             * again, retransmit our last flight
                             */
                            if (mPreviousInboundFlight != null)
                            {
                                DtlsReassembler reassembler = (DtlsReassembler)mPreviousInboundFlight[seq];
                                if (reassembler != null)
                                {
                                    reassembler.ContributeFragment(msg_type, length, buf, 12, fragment_offset,
                                                                   fragment_length);

                                    if (CheckAll(mPreviousInboundFlight))
                                    {
                                        ResendOutboundFlight();

                                        /*
                                         * TODO[DTLS] implementations SHOULD back off handshake packet
                                         * size during the retransmit backoff.
                                         */
                                        readTimeoutMillis = System.Math.Min(readTimeoutMillis * 2, 60000);

                                        ResetAll(mPreviousInboundFlight);
                                    }
                                }
                            }
                        }
                        else
                        {
                            DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[seq];
                            if (reassembler == null)
                            {
                                reassembler = new DtlsReassembler(msg_type, length);
                                mCurrentInboundFlight[seq] = reassembler;
                            }

                            reassembler.ContributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length);

                            if (seq == mNextReceiveSeq)
                            {
                                byte[] body = reassembler.GetBodyIfComplete();
                                if (body != null)
                                {
                                    mPreviousInboundFlight = null;
                                    return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++,
                                                                                     reassembler.MsgType, body)));
                                }
                            }
                        }
                    }
                }
                catch (IOException)
                {
                    // NOTE: Assume this is a timeout for the moment
                }

                ResendOutboundFlight();

                /*
                 * TODO[DTLS] implementations SHOULD back off handshake packet size during the
                 * retransmit backoff.
                 */
                readTimeoutMillis = System.Math.Min(readTimeoutMillis * 2, 60000);
            }
        }
    internal Message ReceiveMessage()
    {
        if (mSending)
        {
            mSending = false;
            PrepareInboundFlight();
        }
        DtlsReassembler dtlsReassembler = (DtlsReassembler)mCurrentInboundFlight[mNextReceiveSeq];

        if (dtlsReassembler != null)
        {
            byte[] bodyIfComplete = dtlsReassembler.GetBodyIfComplete();
            if (bodyIfComplete != null)
            {
                mPreviousInboundFlight = null;
                return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, dtlsReassembler.MsgType, bodyIfComplete)));
            }
        }
        byte[] array = null;
        int    num   = 1000;

        while (true)
        {
            int receiveLimit = mRecordLayer.GetReceiveLimit();
            if (array == null || array.Length < receiveLimit)
            {
                array = new byte[receiveLimit];
            }
            try
            {
                while (true)
                {
                    int num2 = mRecordLayer.Receive(array, 0, receiveLimit, num);
                    if (num2 < 0)
                    {
                        break;
                    }
                    if (num2 >= 12)
                    {
                        int num3 = TlsUtilities.ReadUint24(array, 9);
                        if (num2 == num3 + 12)
                        {
                            int num4 = TlsUtilities.ReadUint16(array, 4);
                            if (num4 <= mNextReceiveSeq + 10)
                            {
                                byte msg_type = TlsUtilities.ReadUint8(array, 0);
                                int  num5     = TlsUtilities.ReadUint24(array, 1);
                                int  num6     = TlsUtilities.ReadUint24(array, 6);
                                if (num6 + num3 <= num5)
                                {
                                    if (num4 < mNextReceiveSeq)
                                    {
                                        if (mPreviousInboundFlight != null)
                                        {
                                            DtlsReassembler dtlsReassembler2 = (DtlsReassembler)mPreviousInboundFlight[num4];
                                            if (dtlsReassembler2 != null)
                                            {
                                                dtlsReassembler2.ContributeFragment(msg_type, num5, array, 12, num6, num3);
                                                if (CheckAll(mPreviousInboundFlight))
                                                {
                                                    ResendOutboundFlight();
                                                    num = Math.Min(num * 2, 60000);
                                                    ResetAll(mPreviousInboundFlight);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        DtlsReassembler dtlsReassembler3 = (DtlsReassembler)mCurrentInboundFlight[num4];
                                        if (dtlsReassembler3 == null)
                                        {
                                            dtlsReassembler3            = new DtlsReassembler(msg_type, num5);
                                            mCurrentInboundFlight[num4] = dtlsReassembler3;
                                        }
                                        dtlsReassembler3.ContributeFragment(msg_type, num5, array, 12, num6, num3);
                                        if (num4 == mNextReceiveSeq)
                                        {
                                            byte[] bodyIfComplete2 = dtlsReassembler3.GetBodyIfComplete();
                                            if (bodyIfComplete2 != null)
                                            {
                                                mPreviousInboundFlight = null;
                                                return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, dtlsReassembler3.MsgType, bodyIfComplete2)));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (IOException)
            {
            }
            ResendOutboundFlight();
            num = Math.Min(num * 2, 60000);
        }
    }