Пример #1
0
        public static MessagePartPacket Decode(byte[] udpData)
        {
            var r = new MessagePartPacket();

            r.DecodedUdpData = udpData;
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);

            r.MessageId32  = reader.ReadUInt32();
            r.SenderStatus = (MessageSessionStatusCode)reader.ReadByte();
            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            if (r.SenderStatus == MessageSessionStatusCode.inProgress)
            {
                r.ContinuedEncryptedData = PacketProcedures.DecodeByteArray65536(reader);
            }
            else if (r.SenderStatus == MessageSessionStatusCode.encryptionDecryptionCompleted)
            {
                r.SenderSignature = UserCertificateSignature.Decode(reader);
            }

            r.MessageHMAC = HMAC.Decode(reader);
            return(r);
        }
Пример #2
0
        /// <summary>
        /// decodes the packet, verifies match to REQ
        /// </summary>
        /// <param name="reader">is positioned after first byte = packet type</param>
        public static FailurePacket DecodeAndOptionallyVerify(byte[] failureUdpData, RequestP2pSequenceNumber16 reqP2pSeq16)
        {
            var reader  = PacketProcedures.CreateBinaryReader(failureUdpData, 1);
            var failure = new FailurePacket();

            failure.DecodedUdpPayloadData = failureUdpData;
            failure.Flags = reader.ReadByte();
            if ((failure.Flags & Flag_EPtoA) == 0)
            {
                failure.NeighborToken32 = NeighborToken32.Decode(reader);
            }
            if ((failure.Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            failure.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader);
            failure.AssertMatchToReq(reqP2pSeq16);
            failure.ResponseCode = (ResponseOrFailureCode)reader.ReadByte();

            if ((failure.Flags & Flag_EPtoA) == 0)
            {
                failure.NeighborHMAC = HMAC.Decode(reader);
            }

            return(failure);
        }
Пример #3
0
        public PeerHelloPacket(byte[] packetUdpPayloadData)
        {
            //  if (packetUdpPayloadData.Length < MinEncodedSize) throw new ArgumentException(nameof(packetUdpPayloadData));
            var index = P2ptpCommon.HeaderSize;

            FromPeerId      = PeerId.Decode(packetUdpPayloadData, ref index);
            StreamId        = StreamId.Decode(packetUdpPayloadData, ref index);
            ToPeerId        = PeerId.Decode(packetUdpPayloadData, ref index);
            LibraryVersion  = PacketProcedures.DecodeUInt32(packetUdpPayloadData, ref index);
            ProtocolVersion = PacketProcedures.DecodeUInt16(packetUdpPayloadData, ref index);
            Status          = (PeerHelloRequestStatus)packetUdpPayloadData[index++];
            RequestTime32   = PacketProcedures.DecodeUInt32(packetUdpPayloadData, ref index);
            Flags           = packetUdpPayloadData[index++];
            var extensionIdsLength = packetUdpPayloadData[index++];

            ExtensionIds = new string[extensionIdsLength];
            for (byte i = 0; i < extensionIdsLength; i++)
            {
                ExtensionIds[i] = PacketProcedures.DecodeString1ASCII(packetUdpPayloadData, ref index);
            }
            if (index < packetUdpPayloadData.Length)
            { // after version 190608
                RequestSequenceNumber = PacketProcedures.DecodeUInt16(packetUdpPayloadData, ref index);
                ResponseCpuDelayMs    = PacketProcedures.DecodeUInt16(packetUdpPayloadData, ref index);
                RequestedFromIp       = PacketProcedures.DecodeString1ASCII(packetUdpPayloadData, ref index);
                var reader = PacketProcedures.CreateBinaryReader(packetUdpPayloadData, index);
                if (FlagIshareMyIpLocation)
                {
                    IpLocationData = IpLocationData.Decode(reader);
                }
            }
        }
Пример #4
0
        public static InviteRequestPacket Decode_VerifyNeighborHMAC(byte[] udpData, ConnectionToNeighbor receivedFromNeighbor)
        {
            var r = new InviteRequestPacket();

            r.DecodedUdpPayloadData = udpData;
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);
            var flags  = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            r.NeighborToken32 = NeighborToken32.Decode(reader);
            if (receivedFromNeighbor.LocalNeighborToken32.Equals(r.NeighborToken32) == false)
            {
                throw new UnmatchedFieldsException();
            }

            r.ReqTimestamp32S                = reader.ReadUInt32();
            r.RequesterRegistrationId        = RegistrationId.Decode(reader);
            r.ResponderRegistrationId        = RegistrationId.Decode(reader);
            r.RequesterEcdhePublicKey        = EcdhPublicKey.Decode(reader);
            r.RequesterRegistrationSignature = RegistrationSignature.Decode(reader);
            r.NumberOfHopsRemaining          = reader.ReadByte();
            r.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader);

            r.NeighborHMAC = HMAC.Decode(reader);
            if (r.NeighborHMAC.Equals(receivedFromNeighbor.GetNeighborHMAC(r.GetSignedFieldsForNeighborHMAC)) == false)
            {
                throw new BadSignatureException("invalid INVITE REQ NeighborHMAC 5902");
            }

            return(r);
        }
Пример #5
0
        public static InviteConfirmationPacket Decode(byte[] udpData)
        {
            var r = new InviteConfirmationPacket();

            r.DecodedUdpPayloadData = udpData;
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);
            var flags  = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            r.NeighborToken32 = NeighborToken32.Decode(reader);

            r.ReqTimestamp32S                = reader.ReadUInt32();
            r.RequesterRegistrationId        = RegistrationId.Decode(reader);
            r.ResponderRegistrationId        = RegistrationId.Decode(reader);
            r.ResponderRegistrationSignature = RegistrationSignature.Decode(reader);
            r.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader);

            r.NeighborHMAC = HMAC.Decode(reader);

            return(r);
        }
Пример #6
0
        /// <param name="reader">positioned after first byte = packet type</param>
        public RegisterPow1RequestPacket(byte[] originalPacketUdpPayload)
        {
            var reader = PacketProcedures.CreateBinaryReader(originalPacketUdpPayload, 1);

            Flags = reader.ReadByte();
            if ((Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            Timestamp32S  = reader.ReadUInt32();
            ProofOfWork1  = reader.ReadBytes(64);
            Pow1RequestId = reader.ReadUInt32();
        }
Пример #7
0
        public ServerHelloPacket0(byte[] udpData)
        {
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);

            Flags   = reader.ReadUInt16();
            Status  = (ServerHello0Status)reader.ReadByte();
            Cnonce0 = PacketProcedures.DecodeByteArray256(reader);
            if (Status == ServerHello0Status.OK)
            {
                StatefulProofOfWorkType = (StatefulProofOfWorkType)reader.ReadByte();
                Snonce0 = PacketProcedures.DecodeByteArray256(reader);
            }
        }
Пример #8
0
        public static RegisterConfirmationPacket DecodeAndOptionallyVerify(byte[] regCfmUdpPayload, RegisterRequestPacket reqNullable, ConnectionToNeighbor newConnectionToRequesterAtResponderNullable)
        {
            var reader = PacketProcedures.CreateBinaryReader(regCfmUdpPayload, 1);

            var cfm = new RegisterConfirmationPacket();

            cfm.DecodedUdpPayloadData = regCfmUdpPayload;

            cfm.Flags = reader.ReadByte();
            if ((cfm.Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            if ((cfm.Flags & Flag_AtoEP) == 0)
            {
                cfm.NeighborToken32 = NeighborToken32.Decode(reader);
            }

            cfm.ReqTimestamp64          = reader.ReadInt64();
            cfm.RequesterRegistrationId = RegistrationId.Decode(reader);
            if (reqNullable != null)
            {
                cfm.AssertMatchToRegisterReq(reqNullable);
            }

            if (newConnectionToRequesterAtResponderNullable != null)
            {
                cfm.ResponderRegistrationConfirmationSignature = RegistrationSignature.DecodeAndVerify(reader, newConnectionToRequesterAtResponderNullable.Engine.CryptoLibrary,
                                                                                                       w => newConnectionToRequesterAtResponderNullable.GetResponderRegistrationConfirmationSignatureFields(w),
                                                                                                       newConnectionToRequesterAtResponderNullable.LocalDrpPeer.Configuration.LocalPeerRegistrationId
                                                                                                       );
                cfm.RequesterRegistrationConfirmationSignature = RegistrationSignature.DecodeAndVerify(reader, newConnectionToRequesterAtResponderNullable.Engine.CryptoLibrary,
                                                                                                       w => newConnectionToRequesterAtResponderNullable.GetRequesterRegistrationConfirmationSignatureFields(w, cfm.ResponderRegistrationConfirmationSignature),
                                                                                                       newConnectionToRequesterAtResponderNullable.RemoteRegistrationId
                                                                                                       );
            }
            else
            {
                cfm.ResponderRegistrationConfirmationSignature = RegistrationSignature.Decode(reader);
                cfm.RequesterRegistrationConfirmationSignature = RegistrationSignature.Decode(reader);
            }

            cfm.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader);
            if ((cfm.Flags & Flag_AtoEP) == 0)
            {
                cfm.NeighborHMAC = HMAC.Decode(reader);
            }

            return(cfm);
        }
Пример #9
0
        public static NatTest1RequestPacket Decode(byte[] udpData)
        {
            var r      = new NatTest1RequestPacket();
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);

            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            r.Token32 = reader.ReadUInt32();
            return(r);
        }
Пример #10
0
        public RegisterPow1ResponsePacket(byte[] rpPow1ResponsePacketData)
        {
            var reader = PacketProcedures.CreateBinaryReader(rpPow1ResponsePacketData, 1);

            Pow1RequestId = reader.ReadUInt32();
            Flags         = reader.ReadByte();
            if ((Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            StatusCode = (RegisterPow1ResponseStatusCode)reader.ReadByte();
            if (StatusCode == RegisterPow1ResponseStatusCode.succeeded_Pow2Challenge)
            {
                ProofOfWork2Request = reader.ReadBytes(16);
            }
        }
Пример #11
0
        /// <returns>true if there are more packets in queue, and need to call this procedure again</returns>
        bool PacketProcessorThreadProcedure()
        {
            ReceivedPacket p;

            lock (_packetsToProcess)
            {
                if (_packetsToProcess.Count == 0)
                {
                    return(false);
                }
                p = _packetsToProcess.Dequeue();
            }

            try
            {
                var reader     = PacketProcedures.CreateBinaryReader(p.Data, 0);
                var packetType = (CcpPacketType)reader.ReadByte();
                switch (packetType)
                {
                case CcpPacketType.ClientHelloPacket0:
                    ProcessClientHello0(p.ClientEndpoint, reader, p.Data);
                    break;

                case CcpPacketType.ClientHelloPacket1:
                    ProcessClientHello1(p.ClientEndpoint, reader, p.Data);
                    break;

                default:
                    HandleMalformedPacket(p.ClientEndpoint);
                    break;
                }
            }
            catch (Exception exc)
            {
                HandleExceptionInPacketProcessorThread(exc);
                HandleMalformedPacket(p.ClientEndpoint);
                if (_config.RespondErrors)
                {
                    RespondToHello0(p.ClientEndpoint, ServerHello0Status.ErrorBadPacket, null);
                }
            }

            return(true);
        }
Пример #12
0
        /// <param name="receivedFromUser">comes from local contact book</param>
        internal static InviteSessionDescription Decrypt_Verify(ICryptoLibrary cryptoLibrary, byte[] encryptedSdData,
                                                                InviteRequestPacket req,
                                                                InviteAck1Packet ack1,
                                                                bool ack1SdIsReady,
                                                                InviteSession session,
                                                                UserId receivedFromUser,
                                                                DateTime localTimeNowUtc
                                                                )
        {
            #region key, iv
            PacketProcedures.CreateBinaryWriter(out var ms2, out var w2);
            req.GetSharedSignedFields(w2);
            ack1.GetSharedSignedFields(w2, ack1SdIsReady);
            var iv = cryptoLibrary.GetHashSHA256(ms2.ToArray()).Take(16).ToArray();
            ms2.Write(session.SharedInviteAckDhSecret, 0, session.SharedInviteAckDhSecret.Length);
            var aesKey = cryptoLibrary.GetHashSHA256(ms2.ToArray()); // here SHA256 is used as KDF, together with common fields from packets, including both ECDH public keys and timestamp
            #endregion

            // decrypt
            var plainTextSdData = new byte[encryptedSdData.Length];
            cryptoLibrary.ProcessAesCbcBlocks(false, aesKey, iv, encryptedSdData, plainTextSdData);

            var r      = new InviteSessionDescription();
            var reader = PacketProcedures.CreateBinaryReader(plainTextSdData, 0);
            r.Flags = reader.ReadByte();
            if ((r.Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            r.UserCertificate          = UserCertificate.Decode_AssertIsValidNow(reader, cryptoLibrary, receivedFromUser, localTimeNowUtc);
            r.DirectChannelEndPoint    = PacketProcedures.DecodeIPEndPoint(reader);
            r.DirectChannelToken32     = DirectChannelToken32.Decode(reader);
            r.SessionType              = (SessionType)reader.ReadByte();
            r.UserCertificateSignature = UserCertificateSignature.DecodeAndVerify(reader, cryptoLibrary,
                                                                                  w =>
            {
                req.GetSharedSignedFields(w);
                ack1.GetSharedSignedFields(w, ack1SdIsReady);
                r.WriteSignedFields(w);
            },
                                                                                  r.UserCertificate);
            return(r);
        }
Пример #13
0
        public NeighborPeerAckPacket(byte[] nextHopResponsePacketData)
        {
            var reader = PacketProcedures.CreateBinaryReader(nextHopResponsePacketData, 1);

            ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader);
            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            if ((flags & Flag_EPtoA) == 0)
            {
                NeighborToken32 = NeighborToken32.Decode(reader);
            }
            ResponseCode = (ResponseOrFailureCode)reader.ReadByte();
            if ((flags & Flag_EPtoA) == 0)
            {
                NeighborHMAC = HMAC.Decode(reader);
            }
        }
Пример #14
0
        public static MessageStartPacket Decode(byte[] udpData)
        {
            var r = new MessageStartPacket();

            r.DecodedUdpData = udpData;
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);

            r.DirectChannelToken32 = DirectChannelToken32.Decode(reader);
            r.MessageId32          = reader.ReadUInt32();

            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            r.MessageTimestamp64   = reader.ReadInt64();
            r.EncryptedMessageData = PacketProcedures.DecodeByteArray65536(reader);
            r.MessageHMAC          = HMAC.Decode(reader);
            return(r);
        }
Пример #15
0
        public static MessageAckPacket Decode(byte[] udpData)
        {
            var r      = new MessageAckPacket();
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);

            r.MessageId32    = reader.ReadUInt32();
            r.ReceiverStatus = (MessageSessionStatusCode)reader.ReadByte();

            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            if (r.ReceiverStatus == MessageSessionStatusCode.encryptionDecryptionCompleted)
            {
                r.ReceiverFinalNonce = reader.ReadBytes(ReceiverFinalNonceSize);
            }

            r.MessageHMAC = HMAC.Decode(reader);
            return(r);
        }
Пример #16
0
        public static DmpPingPacket DecodeAndVerify(byte[] udpData, InviteSession session)
        {
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);

            var r = new DmpPingPacket();

            r.DirectChannelToken32 = DirectChannelToken32.Decode(reader);
            r.PingRequestId32      = reader.ReadUInt32();

            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            if ((flags & Flags_PublicEcdheKeySet) != 0)
            {
                r.PublicEcdheKey = EcdhPublicKey.Decode(reader);
            }

            r.PingPongHMAC = HMAC.Decode(reader);

            // verify DirectChannelToken32
            if (!r.DirectChannelToken32.Equals(session.LocalSessionDescription.DirectChannelToken32))
            {
                throw new BadSignatureException("invalid DMP PING DirectChannelToken32 136");
            }

            // verify PingPongHMAC
            if (r.PingPongHMAC.Equals(
                    session.GetPingPongHMAC(r.GetSignedFieldsForPingPongHMAC)
                    ) == false)
            {
                throw new BadSignatureException("invalid DMP PING PingPongHMAC 1237");
            }

            return(r);
        }
Пример #17
0
        public static DmpPongPacket Decode(byte[] udpData)
        {
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);
            var r      = new DmpPongPacket();

            r.DirectChannelToken32 = DirectChannelToken32.Decode(reader);
            r.PingRequestId32      = reader.ReadUInt32();
            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            if ((flags & Flags_PublicEcdheKeySet) != 0)
            {
                r.PublicEcdheKey = EcdhPublicKey.Decode(reader);
            }

            r.PingPongHMAC = HMAC.Decode(reader);

            return(r);
        }
Пример #18
0
        /// <summary>
        /// decodes the packet, decrypts ToNeighborTxParametersEncrypted, verifies NeighborSignature, verifies match to register REQ
        /// </summary>
        /// <param name="newConnectionToNeighborAtRequesterNullable">if not null (at requester) - this procedure verifies ResponderSignature</param>
        /// <param name="reader">is positioned after first byte = packet type</param>
        public static RegisterAck1Packet DecodeAndOptionallyVerify(Logger logger, byte[] ack1UdpData, RegisterRequestPacket reqNullable,
                                                                   ConnectionToNeighbor newConnectionToNeighborAtRequesterNullable)
        {
            var reader = PacketProcedures.CreateBinaryReader(ack1UdpData, 1);
            var ack1   = new RegisterAck1Packet();

            ack1.DecodedUdpPayloadData = ack1UdpData;
            ack1.Flags = reader.ReadByte();
            if ((ack1.Flags & Flag_EPtoA) == 0)
            {
                ack1.NeighborToken32 = NeighborToken32.Decode(reader);
            }
            if ((ack1.Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            ack1.RequesterRegistrationId          = RegistrationId.Decode(reader);
            ack1.ReqTimestamp64                   = reader.ReadInt64();
            ack1.ResponderEcdhePublicKey          = EcdhPublicKey.Decode(reader);
            ack1.ToResponderTxParametersEncrypted = reader.ReadBytes(ToResponderTxParametersEncryptedLength);
            ack1.ResponderRegistrationId          = RegistrationId.Decode(reader);

            if (newConnectionToNeighborAtRequesterNullable != null)
            {
                if (reqNullable == null)
                {
                    throw new ArgumentException();
                }
                ack1.ResponderSignature = RegistrationSignature.DecodeAndVerify(
                    reader, newConnectionToNeighborAtRequesterNullable.Engine.CryptoLibrary,
                    w =>
                {
                    reqNullable.GetSharedSignedFields(w, true);
                    ack1.GetSharedSignedFields(w, false, true);
                },
                    ack1.ResponderRegistrationId);
            }
            else
            { // at proxy we don't verify responder's signature, to avoid high spending of resources
                ack1.ResponderSignature = RegistrationSignature.Decode(reader);
            }

            if (reqNullable != null)
            {
                ack1.AssertMatchToRegisterReq(reqNullable);
                if (newConnectionToNeighborAtRequesterNullable != null)
                {
                    newConnectionToNeighborAtRequesterNullable.Decrypt_ack1_ToResponderTxParametersEncrypted_AtRequester_DeriveSharedDhSecret(logger, reqNullable, ack1);
                }
            }

            if ((ack1.Flags & Flag_EPtoA) != 0)
            {
                ack1.RequesterEndpoint = PacketProcedures.DecodeIPEndPoint(reader);
            }
            else
            {
                ack1.ReqP2pSeq16  = RequestP2pSequenceNumber16.Decode(reader);
                ack1.NeighborHMAC = HMAC.Decode(reader);
            }

            return(ack1);
        }
Пример #19
0
        /// <summary>
        /// when REQ is received from neighbor, verifies senderHMAC and NeighborToken32
        /// </summary>
        /// <param name="receivedFromNeighborNullable">is NULL when decoding REQ from A at EP</param>
        public static RegisterRequestPacket Decode_OptionallyVerifyNeighborHMAC(byte[] udpData, ConnectionToNeighbor receivedFromNeighborNullable, int numberOfDimensions)
        {
            var r = new RegisterRequestPacket();

            r.DecodedUdpPayloadData = udpData;
            var reader = PacketProcedures.CreateBinaryReader(udpData, 1);

            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            if ((flags & Flag_AtoEP) == 0)
            {
                if (receivedFromNeighborNullable == null)
                {
                    throw new UnmatchedFieldsException();
                }
                r.NeighborToken32 = NeighborToken32.Decode(reader);
                if (receivedFromNeighborNullable.LocalNeighborToken32.Equals(r.NeighborToken32) == false)
                {
                    throw new UnmatchedFieldsException();
                }
            }
            else
            {
                if (receivedFromNeighborNullable != null)
                {
                    throw new UnmatchedFieldsException();
                }
            }

            r.RequesterRegistrationId         = RegistrationId.Decode(reader);
            r.RequesterNeighborsBusySectorIds = reader.ReadUInt16();
            r.RequesterEcdhePublicKey         = EcdhPublicKey.Decode(reader);
            r.ReqTimestamp64            = reader.ReadInt64();
            r.MinimalDistanceToNeighbor = reader.ReadUInt32();

            if ((flags & Flag_DirectionVectorExists) != 0)
            {
                r.DirectionVectorNullable = new sbyte[numberOfDimensions];
                for (int i = 0; i < numberOfDimensions; i++)
                {
                    r.DirectionVectorNullable[i] = reader.ReadSByte();
                }
            }

            r.EpEndpoint         = PacketProcedures.DecodeIPEndPoint(reader);
            r.RequesterSignature = RegistrationSignature.Decode(reader);

            if ((flags & Flag_AtoEP) != 0)
            {
                r.ProofOfWork2 = reader.ReadBytes(64);
            }
            r.NumberOfHopsRemaining       = reader.ReadByte();
            r.NumberOfRandomHopsRemaining = reader.ReadByte();
            r.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader);
            if ((flags & Flag_AtoEP) == 0)
            {
                r.NeighborHMAC = HMAC.Decode(reader);
                if (r.NeighborHMAC.Equals(receivedFromNeighborNullable.GetNeighborHMAC(r.GetSignedFieldsForNeighborHMAC)) == false)
                {
                    throw new BadSignatureException("invalid REGISTER REQ NeighborHMAC 1573");
                }
            }

            return(r);
        }
Пример #20
0
        /// <param name="newConnectionAtResponderToRequesterNullable">
        /// direct P2P stream from N to A
        /// if newConnectionAtResponderToRequesterNullable is specified, the procedure
        /// verifies RequesterHMAC, decrypts endpoint of A (ToRequesterTxParametersEncrypted), initializes P2P stream
        /// </param>
        public static RegisterAck2Packet Decode_OptionallyVerify_InitializeP2pStreamAtResponder(Logger logger, byte[] registerAckPacketData,
                                                                                                RegisterRequestPacket reqNullable,
                                                                                                RegisterAck1Packet ack1Nullable,
                                                                                                ConnectionToNeighbor newConnectionAtResponderToRequesterNullable
                                                                                                )
        {
            var reader = PacketProcedures.CreateBinaryReader(registerAckPacketData, 1);

            var ack = new RegisterAck2Packet();

            ack.DecodedUdpPayloadData = registerAckPacketData;
            ack.Flags = reader.ReadByte();
            if ((ack.Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            if ((ack.Flags & Flag_AtoEP) == 0)
            {
                ack.NeighborToken32 = NeighborToken32.Decode(reader);
            }

            ack.ReqTimestamp64          = reader.ReadInt64();
            ack.RequesterRegistrationId = RegistrationId.Decode(reader);
            if (reqNullable != null)
            {
                ack.AssertMatchToSyn(reqNullable);
            }

            ack.ToRequesterTxParametersEncrypted = reader.ReadBytes(ToRequesterTxParametersEncryptedLength);
            if (newConnectionAtResponderToRequesterNullable != null)
            {
                newConnectionAtResponderToRequesterNullable.Decrypt_ack2_ToRequesterTxParametersEncrypted_AtResponder_InitializeP2pStream(logger, reqNullable, ack1Nullable, ack);
            }

            ack.RequesterSignature = RegistrationSignature.Decode(reader);
            if (newConnectionAtResponderToRequesterNullable != null)
            {
                if (reqNullable == null)
                {
                    throw new ArgumentException();
                }
                if (ack1Nullable == null)
                {
                    throw new ArgumentException();
                }
                if (!ack.RequesterSignature.Verify(newConnectionAtResponderToRequesterNullable.Engine.CryptoLibrary,
                                                   w =>
                {
                    reqNullable.GetSharedSignedFields(w, true);
                    ack1Nullable.GetSharedSignedFields(w, true, true);
                    ack.GetSharedSignedFields(w, false, true);
                },
                                                   reqNullable.RequesterRegistrationId))
                {
                    throw new BadSignatureException("invalid REGISTER ACK2 RequesterSignature 6106");
                }
            }

            ack.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader);

            if ((ack.Flags & Flag_AtoEP) == 0)
            {
                ack.NeighborHMAC = HMAC.Decode(reader); // is verified by Filter
            }

            return(ack);
        }
Пример #21
0
        void ThreadEntry()
        {
            IPEndPoint remoteEndpoint = default(IPEndPoint);

            while (!_disposing)
            {
                try
                {
                    _actionsQueue.ExecuteQueued();

                    var udpData = UdpSocket.Receive(ref remoteEndpoint);

                    var timestamp32 = _localPeer.Time32;
                    if (_previousTimestamp32.HasValue)
                    {
                        var timePassed32 = unchecked (timestamp32 - _previousTimestamp32.Value);
                        _pps.Input(1, timePassed32);
                        _bps.Input((udpData.Length + LocalLogicConfiguration.IpAndUdpHeadersSizeBytes) * 8, timePassed32);
                    }
                    _previousTimestamp32 = timestamp32;

                    var manager = _localPeer.Manager;
                    if (manager != null && _localPeer.Firewall.PacketIsAllowed(remoteEndpoint))
                    {
                        var packetType = P2ptpCommon.DecodeHeader(udpData);
                        if (packetType.HasValue)
                        {
                            switch (packetType.Value)
                            {
                            case PacketTypes.hello:
                                manager.ProcessReceivedHello(udpData, remoteEndpoint, this, timestamp32);
                                break;

                            case PacketTypes.peersListIpv4:
                                manager.ProcessReceivedSharedPeers(udpData, remoteEndpoint);
                                break;

                            case PacketTypes.extensionSignaling:
                                manager.ProcessReceivedExtensionSignalingPacket(PacketProcedures.CreateBinaryReader(udpData, P2ptpCommon.HeaderSize), remoteEndpoint);
                                break;
                            }
                        }
                        else
                        {
                            (var extension, var streamId, var index) = ExtensionProcedures.ParseReceivedExtensionPayloadPacket(udpData, _localPeer.Configuration.Extensions);
                            if (extension != null)
                            {
                                if (_streams.TryGetValue(streamId, out var stream))
                                {
                                    stream.Extensions.TryGetValue(extension, out var streamExtension);
                                    streamExtension.OnReceivedPayloadPacket(udpData, index);
                                }
                                //else _localPeer.WriteToLog(LogModules.Receiver, $"receiver {SocketInfo} got packet from bad stream id {streamId}");
                            }
                        }
                    }
                }
                //   catch (InvalidOperationException)
                //   {// intentionally ignored   (before "connection")
                //   }
                catch (SocketException exc)
                {
                    if (_disposing)
                    {
                        return;
                    }
                    if (exc.ErrorCode != 10054) // forcibly closed - ICMP port unreachable - it is normal when peer gets down
                    {
                        _localPeer.HandleException(LogModules.Receiver, exc);
                    }
                    // else ignore it
                }
                catch (Exception exc)
                {
                    _localPeer.HandleException(LogModules.Receiver, exc);
                }
            }
        }