private Message UpdateHandshakeMessagesDigest(Message message)
 {
     if (message.Type != 0)
     {
         byte[] body  = message.Body;
         byte[] array = new byte[12];
         TlsUtilities.WriteUint8(message.Type, array, 0);
         TlsUtilities.WriteUint24(body.Length, array, 1);
         TlsUtilities.WriteUint16(message.Seq, array, 4);
         TlsUtilities.WriteUint24(0, array, 6);
         TlsUtilities.WriteUint24(body.Length, array, 9);
         mHandshakeHash.BlockUpdate(array, 0, array.Length);
         mHandshakeHash.BlockUpdate(body, 0, body.Length);
     }
     return(message);
 }
예제 #2
0
 internal virtual void UpdateHandshakeData(byte[] message, int offset, int len)
 {
     mHandshakeHash.BlockUpdate(message, offset, len);
 }
예제 #3
0
        public List <IByteBuffer> Receive(IByteBuffer record)
        {
            List <IByteBuffer> outputList = new List <IByteBuffer>();

            while (record.ReadableBytes > RECORD_HEADER_LENGTH)
            {
                byte            type    = (byte)(record.ReadByte() & 0x00FF);
                ProtocolVersion version = ProtocolVersion.Get(record.ReadByte() & 0xFF, record.ReadByte() & 0xFF);
                int             epoch   = record.ReadUnsignedShort();
                long            seq     = DtlsHelper.ReadUint48(record);
                //just reading length,not using it
                short  packetLength = record.ReadShort();
                byte[] realData     = new byte[packetLength];
                record.ReadBytes(realData);

                AsyncDtlsEpoch recordEpoch = null;
                if (epoch == readEpoch.Epoch)
                {
                    recordEpoch = readEpoch;
                }

                if (recordEpoch == null)
                {
                    continue;
                }

                if (recordEpoch.ReplayWindow.ShouldDiscard(seq))
                {
                    continue;
                }

                if (!version.IsDtls)
                {
                    continue;
                }

                if (readVersion != null && !readVersion.Equals(version))
                {
                    continue;
                }

                byte[]      plaintext = recordEpoch.getCipher().DecodeCiphertext(GetMacSequenceNumber(recordEpoch.Epoch, seq), type, realData, 0, realData.Length);
                IByteBuffer output    = Unpooled.WrappedBuffer(plaintext);

                recordEpoch.ReplayWindow.ReportAuthenticated(seq);
                if (plaintext.Length > this.plaintextLimit)
                {
                    continue;
                }

                if (readVersion == null)
                {
                    readVersion = version;
                }

                switch (type)
                {
                case ContentType.alert:
                    if (output.ReadableBytes == 2)
                    {
                        byte alertLevel       = (byte)(output.ReadByte() & 0x0FF);
                        byte alertDescription = (byte)(output.ReadByte() & 0x0FF);

                        peer.NotifyAlertReceived(alertLevel, alertDescription);

                        if (alertLevel == AlertLevel.fatal)
                        {
                            Failed();
                            throw new TlsFatalAlert(alertDescription);
                        }

                        if (alertDescription == AlertDescription.close_notify)
                        {
                            CloseTransport();
                        }
                    }

                    continue;

                case ContentType.application_data:
                    if (inHandshake)
                    {
                        continue;
                    }
                    break;

                case ContentType.change_cipher_spec:
                    while (output.ReadableBytes > 0)
                    {
                        short message = (short)(output.ReadByte() & 0x0FF);
                        if (message != ChangeCipherSpec.change_cipher_spec)
                        {
                            continue;
                        }

                        if (pendingEpoch != null)
                        {
                            readEpoch = pendingEpoch;
                        }
                    }

                    continue;

                case ContentType.handshake:
                    if (!inHandshake)
                    {
                        continue;
                    }

                    HandshakeHeader handshakeHeader = DtlsHelper.ReadHandshakeHeader(output);

                    if (handshakeHeader != null)
                    {
                        if (!handshakeHeader.FragmentLength.Equals(handshakeHeader.TotalLength))
                        {
                            PendingMessageData data = null;
                            if (pendingBuffers.ContainsKey(handshakeHeader.MessageSequence))
                            {
                                data = pendingBuffers[handshakeHeader.MessageSequence];
                            }

                            if (data == null)
                            {
                                data = new PendingMessageData(Unpooled.Buffer(handshakeHeader.TotalLength));
                                pendingBuffers[handshakeHeader.MessageSequence] = data;
                            }

                            data.WriteBytes(output, handshakeHeader.FragmentOffset);
                            if (data.WrottenBytes.Equals(handshakeHeader.TotalLength))
                            {
                                data.Buffer.SetWriterIndex(handshakeHeader.TotalLength);
                                byte[]      packetData = null;
                                IByteBuffer copy       = data.Buffer.Copy();
                                packetData = new byte[copy.ReadableBytes];
                                copy.ReadBytes(packetData);

                                if (handshakeHeader.MessageType.HasValue && handshakeHandler != null)
                                {
                                    handshakeHandler.HandleHandshake(handshakeHeader.MessageType.Value, data.Buffer);
                                }

                                byte[]      pseudoHeader = new byte[DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH];
                                IByteBuffer headerBuffer = Unpooled.WrappedBuffer(pseudoHeader);
                                headerBuffer.SetWriterIndex(0);
                                DtlsHelper.WriteHandshakeHeader(handshakeHeader.MessageSequence, handshakeHeader.MessageType.Value, headerBuffer, handshakeHeader.TotalLength);
                                headerBuffer.SetReaderIndex(0);
                                handshakeHash.BlockUpdate(pseudoHeader, 0, pseudoHeader.Length);
                                handshakeHash.BlockUpdate(packetData, 0, packetData.Length);

                                if (handshakeHeader.MessageType.HasValue && handshakeHandler != null)
                                {
                                    handshakeHandler.PostProcessHandshake(handshakeHeader.MessageType.Value, data.Buffer);
                                }

                                pendingBuffers.Remove(handshakeHeader.MessageSequence);
                            }
                        }
                        else
                        {
                            byte[]      packetData = null;
                            IByteBuffer copy       = output.Copy();
                            packetData = new byte[copy.ReadableBytes];
                            copy.ReadBytes(packetData);

                            if (handshakeHeader.MessageType.HasValue && handshakeHandler != null)
                            {
                                handshakeHandler.HandleHandshake(handshakeHeader.MessageType.Value, output);
                            }

                            byte[]      pseudoHeader = new byte[DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH];
                            IByteBuffer headerBuffer = Unpooled.WrappedBuffer(pseudoHeader);
                            headerBuffer.SetWriterIndex(0);
                            DtlsHelper.WriteHandshakeHeader(handshakeHeader.MessageSequence, handshakeHeader.MessageType.Value, headerBuffer, handshakeHeader.TotalLength);
                            headerBuffer.SetReaderIndex(0);
                            handshakeHash.BlockUpdate(pseudoHeader, 0, pseudoHeader.Length);
                            handshakeHash.BlockUpdate(packetData, 0, packetData.Length);

                            if (handshakeHeader.MessageType.HasValue && handshakeHandler != null)
                            {
                                handshakeHandler.PostProcessHandshake(handshakeHeader.MessageType.Value, output);
                            }
                        }
                    }

                    continue;

                case ContentType.heartbeat:
                    continue;
                }

                outputList.Add(output);
            }

            return(outputList);
        }