internal void GetSharedSignedFields(BinaryWriter w) { w.Write(ReqTimestamp32S); RequesterRegistrationId.Encode(w); ResponderRegistrationId.Encode(w); PacketProcedures.EncodeByteArray65536(w, ToRequesterSessionDescriptionEncrypted); }
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); }
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); }
/// <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); }
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); } } }
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); }
IirFilterCounter _rxBwBeforeJB = new IirFilterCounter(TimeSpan.TicksPerMillisecond * 500, TimeSpan.TicksPerSecond); // locked void IConnectedPeerStreamExtension.OnReceivedPayloadPacket(byte[] data, int index) { _stream.MarkAsActiveByExtension(); // _totalUdpBytesReceived += (UInt64)data.Length; var timeNow32 = SubtLocalPeer.LocalPeer.Time32; lock (_rxBwBeforeJB) { _rxBwBeforeJB.Input((data.Length + LocalLogicConfiguration.IpAndUdpHeadersSizeBytes) * 8); _rxBwBeforeJB.OnTimeObserved(timeNow32); } var timestamp32 = PacketProcedures.DecodeUInt32(data, ref index); _timestamp32ToReflect = timestamp32; var sequence = PacketProcedures.DecodeUInt16(data, ref index); var reflectedTimestamp32 = PacketProcedures.DecodeUInt32(data, ref index); if (reflectedTimestamp32 != 0) { RecentRtt = TimeSpan.FromTicks(unchecked (SubtLocalPeer.LocalPeer.Time32 - reflectedTimestamp32)); } _rxMeasurement.OnReceivedPacket((ushort)(data.Length * 8 + LocalLogicConfiguration.IpAndUdpHeadersSizeBits), sequence, timestamp32, timeNow32); }
public byte[] Encode() { PacketProcedures.CreateBinaryWriter(out var ms, out var writer); writer.Write((byte)PacketTypes.MessagePart); writer.Write(MessageId32); writer.Write((byte)SenderStatus); byte flags = 0; writer.Write(flags); if (SenderStatus == MessageSessionStatusCode.inProgress) { PacketProcedures.EncodeByteArray65536(writer, ContinuedEncryptedData); } else if (SenderStatus == MessageSessionStatusCode.encryptionDecryptionCompleted) { SenderSignature.Encode(writer); } MessageHMAC.Encode(writer); var r = ms.ToArray(); if (r.Length > 500) { throw new ArgumentException(); } return(r); }
/// <param name="reqReceivedFromInP2pMode">is not null for packets between registered peers</param> public byte[] Encode_OpionallySignNeighborHMAC(ConnectionToNeighbor reqReceivedFromInP2pMode) { PacketProcedures.CreateBinaryWriter(out var ms, out var writer); writer.Write((byte)PacketTypes.RegisterAck1); byte flags = 0; if (reqReceivedFromInP2pMode == null) { flags |= Flag_EPtoA; } writer.Write(flags); if (reqReceivedFromInP2pMode != null) { NeighborToken32 = reqReceivedFromInP2pMode.RemoteNeighborToken32; NeighborToken32.Encode(writer); } GetSharedSignedFields(writer, true, true); if (reqReceivedFromInP2pMode != null) { ReqP2pSeq16.Encode(writer); this.NeighborHMAC = reqReceivedFromInP2pMode.GetNeighborHMAC(this.GetSignedFieldsForNeighborHMAC); this.NeighborHMAC.Encode(writer); } else { PacketProcedures.EncodeIPEndPoint(writer, RequesterEndpoint); } return(ms.ToArray()); }
/// <param name="ack1SdIsReady"> /// =true for SD in ACK2 /// =false for SD in ACK1 (since the SessionDescription is not initialized yet) /// </param> internal byte[] Encrypt(ICryptoLibrary cryptoLibrary, InviteRequestPacket req, InviteAck1Packet ack1, InviteSession session, bool ack1SdIsReady ) { PacketProcedures.CreateBinaryWriter(out var ms, out var w); w.Write(Flags); UserCertificate.Encode(w); PacketProcedures.EncodeIPEndPoint(w, DirectChannelEndPoint); DirectChannelToken32.Encode(w); w.Write((byte)SessionType); UserCertificateSignature.Encode(w); var bytesInLastBlock = (int)ms.Position % CryptoLibraries.AesBlockSize; if (bytesInLastBlock != 0) { var bytesRemainingTillFullAesBlock = CryptoLibraries.AesBlockSize - bytesInLastBlock; w.Write(cryptoLibrary.GetRandomBytes(bytesRemainingTillFullAesBlock)); } var plainTextSdData = ms.ToArray(); var encryptedSdData = new byte[plainTextSdData.Length]; #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 cryptoLibrary.ProcessAesCbcBlocks(true, aesKey, iv, plainTextSdData, encryptedSdData); return(encryptedSdData); }
internal static PeersListPacket_SharedPeerIpv4 Decode(byte[] data, ref int index) { return(new PeersListPacket_SharedPeerIpv4( StreamId.Decode(data, ref index), PeerId.Decode(data, ref index), new IPEndPoint(new IPAddress(PacketProcedures.DecodeUInt32(data, ref index)), PacketProcedures.DecodeUInt16(data, ref index)) )); }
internal static (PeerId fromPeerId, PeerId toPeerId, StreamId streamId, string extensionId) ParseExtensionSignalingPacket(BinaryReader reader) { var fromPeerId = PeerId.Decode(reader); var toPeerId = PeerId.Decode(reader); var streamId = StreamId.Decode(reader); var extensionId = PacketProcedures.DecodeString1ASCII(reader); return(fromPeerId, toPeerId, streamId, extensionId); }
const ushort Magic16_responderToRequester = 0x60C1; // is used to validate decrypted data /// <summary> /// when sending ACK1 /// </summary> public byte[] Encrypt_ack1_ToResponderTxParametersEncrypted_AtResponder_DeriveSharedDhSecret(Logger logger, RegisterRequestPacket req, RegisterAck1Packet ack1, ConnectionToNeighbor neighbor) { IPEndPoint localResponderEndpoint; if (neighbor != null) { localResponderEndpoint = neighbor.LocalEndpoint; } else { localResponderEndpoint = req.EpEndpoint; } if (localResponderEndpoint.Address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) { throw new NotImplementedException(); } SharedDhSecret = _engine.CryptoLibrary.DeriveEcdh25519SharedSecret(LocalEcdhe25519PrivateKey, req.RequesterEcdhePublicKey.Ecdh25519PublicKey); #region key, iv PacketProcedures.CreateBinaryWriter(out var ms, out var writer); req.GetSharedSignedFields(writer, true); ack1.GetSharedSignedFields(writer, false, false); var iv = _engine.CryptoLibrary.GetHashSHA256(ms.ToArray()).Take(16).ToArray();; ms.Write(SharedDhSecret, 0, SharedDhSecret.Length); var aesKey = _engine.CryptoLibrary.GetHashSHA256(ms.ToArray()); // here SHA256 is used as KDF, together with common fields from packets, including both ECDH public keys and timestamp #endregion // encode localRxParameters PacketProcedures.CreateBinaryWriter(out var msRxParameters, out var wRxParameters); PacketProcedures.EncodeIPEndPoint(wRxParameters, localResponderEndpoint); // max 19 LocalNeighborToken32.Encode(wRxParameters); // +4 max 23 if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"encrypting local responder endpoint={localResponderEndpoint}, localNeighborToken={LocalNeighborToken32} into ACK1"); } wRxParameters.Write(Magic16_responderToRequester); // +2 max 25 var bytesRemaining = RegisterAck1Packet.ToResponderTxParametersEncryptedLength - (int)msRxParameters.Length; wRxParameters.Write(_engine.CryptoLibrary.GetRandomBytes(bytesRemaining)); var localRxParametersDecrypted = msRxParameters.ToArray(); // total 16 bytes var localRxParametersEncrypted = new byte[localRxParametersDecrypted.Length]; _engine.CryptoLibrary.ProcessAesCbcBlocks(true, aesKey, iv, localRxParametersDecrypted, localRxParametersEncrypted); if (localRxParametersEncrypted.Length != RegisterAck1Packet.ToResponderTxParametersEncryptedLength) { throw new Exception(); } return(localRxParametersEncrypted); }
public ServerHelloPacket1(BinaryReader reader) // after first byte = packet type { Flags = reader.ReadByte(); Status = (ServerHello1Status)reader.ReadByte(); Cnonce1 = PacketProcedures.DecodeByteArray256(reader); if (Status == ServerHello1Status.OKready) { StatefulProofOfWorkType = (StatefulProofOfWorkType)reader.ReadByte(); Snonce1 = PacketProcedures.DecodeByteArray256(reader); } }
public ClientHelloPacket1(BinaryReader reader, byte[] originalPacketPayload) // after first byte = packet type { OriginalPacketPayload = originalPacketPayload; Flags = reader.ReadByte(); Snonce0 = PacketProcedures.DecodeByteArray256(reader); if (Snonce0.Length != ServerHelloPacket0.Snonce0SupportedSize) { throw new CcpBadPacketException(); } StatefulProofOfWorkResponseData = PacketProcedures.DecodeByteArray256(reader); }
public byte[] Encode() { PacketProcedures.CreateBinaryWriter(out var ms, out var writer); writer.Write((byte)PacketTypes.NatTest1Response); byte flags = 0; writer.Write(flags); writer.Write(Token32); PacketProcedures.EncodeIPEndPoint_ipv4(writer, RequesterEndpoint); return(ms.ToArray()); }
internal void GetSharedSignedFields(BinaryWriter w, bool includeToResponderSessionDescriptionEncrypted) { w.Write(ReqTimestamp32S); RequesterRegistrationId.Encode(w); ResponderRegistrationId.Encode(w); ResponderEcdhePublicKey.Encode(w); if (includeToResponderSessionDescriptionEncrypted) { PacketProcedures.EncodeByteArray65536(w, ToResponderSessionDescriptionEncrypted); } }
public ClientHelloPacket0(BinaryReader reader, byte[] originalPacketPayload) // after first byte = packet type { OriginalPacketPayload = originalPacketPayload; Flags = reader.ReadUInt16(); Cnonce0 = PacketProcedures.DecodeByteArray256(reader); if (Cnonce0.Length != Cnonce0SupportedSize) { throw new CcpBadPacketException(); } StatelessProofOfWorkType = (StatelessProofOfWorkType)reader.ReadByte(); StatelessProofOfWorkData = PacketProcedures.DecodeByteArray256(reader); }
internal void GetSignedFieldsForMessageHMAC(BinaryWriter writer) { writer.Write(MessageId32); writer.Write((byte)SenderStatus); if (SenderStatus == MessageSessionStatusCode.inProgress) { PacketProcedures.EncodeByteArray65536(writer, ContinuedEncryptedData); } else if (SenderStatus == MessageSessionStatusCode.encryptionDecryptionCompleted) { SenderSignature.Encode(writer); } }
public static StreamId Decode(BinaryReader reader) { var id = PacketProcedures.DecodeUInt32(reader); if (id == 0) { return(null); } else { return(new StreamId(id)); } }
public static StreamId Decode(byte[] data, ref int index) { var id = PacketProcedures.DecodeUInt32(data, ref index); if (id == 0) { return(null); } else { return(new StreamId(id)); } }
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); } }
internal void Encode(byte[] data, ref int index) { StreamId.Encode(FromSocketAtStreamId, data, ref index); PeerId.Encode(ToPeerId, data, ref index); if (ToEndPoint.Address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) { throw new NotSupportedException("only IPv4 is supported"); } #pragma warning disable CS0618 // Type or member is obsolete PacketProcedures.EncodeUInt32(data, ref index, (uint)ToEndPoint.Address.Address); #pragma warning restore CS0618 // Type or member is obsolete PacketProcedures.EncodeUInt16(data, ref index, (ushort)ToEndPoint.Port); }
/// <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(); }
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); }
/// <returns>offset to StatelessProofOfWorkData</returns> public int Encode(BinaryWriter writer) { writer.Write((byte)CcpPacketType.ClientHelloPacket0); writer.Write(Flags); if (Cnonce0.Length != Cnonce0SupportedSize) { throw new CcpBadPacketException(); } PacketProcedures.EncodeByteArray256(writer, Cnonce0); writer.Write((byte)StatelessProofOfWorkType); PacketProcedures.EncodeByteArray256(writer, StatelessProofOfWorkData); return(1 + 2 + 1 + Cnonce0.Length + 1 + 1); }
public void Encode(BinaryWriter writer) { writer.Write(Flags); writer.Write(Longitude); writer.Write(Latitude); PacketProcedures.EncodeString1UTF8(writer, Country); PacketProcedures.EncodeString1UTF8(writer, CountryCode); PacketProcedures.EncodeString1UTF8(writer, City); PacketProcedures.EncodeString1UTF8(writer, State); PacketProcedures.EncodeString1UTF8(writer, StateCode); PacketProcedures.EncodeString1UTF8(writer, ZIP); PacketProcedures.EncodeString1UTF8(writer, Organization_ISP); PacketProcedures.EncodeString1UTF8(writer, AS); PacketProcedures.EncodeString1UTF8(writer, ASname); }
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); }
} // = pow request data // set if status=okready public byte[] Encode() { PacketProcedures.CreateBinaryWriter(out var ms, out var writer); writer.Write((byte)CcpPacketType.ServerHelloPacket1); writer.Write(Flags); writer.Write((byte)Status); PacketProcedures.EncodeByteArray256(writer, Cnonce1); if (Status == ServerHello1Status.OKready) { writer.Write((byte)StatefulProofOfWorkType); PacketProcedures.EncodeByteArray256(writer, Snonce1); } return(ms.ToArray()); }
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); } }