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); }
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); }
/// <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 = BinaryProcedures.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); }
public static InviteAck1Packet Decode(byte[] udpData) { var r = new InviteAck1Packet(); r.DecodedUdpPayloadData = udpData; var reader = BinaryProcedures.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.ResponderEcdhePublicKey = EcdhPublicKey.Decode(reader); r.ToResponderSessionDescriptionEncrypted = BinaryProcedures.DecodeByteArray65536(reader); r.ResponderRegistrationSignature = RegistrationSignature.Decode(reader); r.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader); r.NeighborHMAC = HMAC.Decode(reader); return(r); }
public static RegisterConfirmationPacket DecodeAndOptionallyVerify(byte[] regCfmUdpPayload, RegisterRequestPacket reqNullable, ConnectionToNeighbor newConnectionToRequesterAtResponderNullable) { var reader = BinaryProcedures.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); }
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); } }
/// <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 = BinaryProcedures.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); }
/// <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); }
/// <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 = BinaryProcedures.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 = BinaryProcedures.DecodeIPEndPoint(reader); } else { ack1.ReqP2pSeq16 = RequestP2pSequenceNumber16.Decode(reader); ack1.NeighborHMAC = HMAC.Decode(reader); } return(ack1); }