public static MessagePartPacket Decode(byte[] udpData) { var r = new MessagePartPacket(); r.DecodedUdpData = udpData; var reader = BinaryProcedures.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 = BinaryProcedures.DecodeByteArray65536(reader); } else if (r.SenderStatus == MessageSessionStatusCode.encryptionDecryptionCompleted) { r.SenderSignature = UserCertificateSignature.Decode(reader); } r.MessageHMAC = HMAC.Decode(reader); return(r); }
internal void GetSharedSignedFields(BinaryWriter w) { w.Write(ReqTimestamp32S); RequesterRegistrationId.Encode(w); ResponderRegistrationId.Encode(w); BinaryProcedures.EncodeByteArray65536(w, ToRequesterSessionDescriptionEncrypted); }
public byte[] Encode() { BinaryProcedures.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) { BinaryProcedures.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="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 ) { BinaryProcedures.CreateBinaryWriter(out var ms, out var w); w.Write(Flags); UserCertificate.Encode(w, false); BinaryProcedures.EncodeIPEndPoint(w, DirectChannelEndPoint); NatBehaviour.Encode(w); 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 BinaryProcedures.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); }
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 = BinaryProcedures.DecodeUInt32(data, ref index); _timestamp32ToReflect = timestamp32; var sequence = BinaryProcedures.DecodeUInt16(data, ref index); var reflectedTimestamp32 = BinaryProcedures.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 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); }
internal void WriteSignedFields(BinaryWriter w) { BinaryProcedures.EncodeIPEndPoint(w, DirectChannelEndPoint); NatBehaviour.Encode(w); DirectChannelToken32.Encode(w); w.Write((byte)SessionType); }
internal byte[] DecryptAndVerify(byte[] encryptedNullable, byte[] hmacNullable, int id, EncryptedFieldIds fieldId) { if (encryptedNullable == null || hmacNullable == null) { return(null); } GetIVandKeys(id, fieldId, out var iv, out var aesKey, out var hmacKey); var hmac = _cryptoLibrary.GetSha256HMAC(hmacKey, encryptedNullable); if (!MiscProcedures.EqualByteArrays(hmacNullable, hmac)) { throw new BadSignatureException(); } var decrypted = new byte[encryptedNullable.Length]; _cryptoLibrary.ProcessAesCbcBlocks(false, aesKey, iv, encryptedNullable, decrypted); using var reader = BinaryProcedures.CreateBinaryReader(decrypted, 0); var dataLength = reader.ReadUInt16(); return(reader.ReadBytes(dataLength)); }
public List <User> GetUsers(bool local) { var query = _db_main.Table <User>(); if (local) { query = query.Where(x => x.OwnerLocalUserId == 0); } else { query = query.Where(x => x.OwnerLocalUserId != 0); } var users = query.ToList(); foreach (var u in users) { try { u.UserID = UserId.Decode(DecryptAndVerify(u.UserID_encrypted, u.UserID_hmac, u.Id, EncryptedFieldIds.User_UserID)); u.AliasID = BinaryProcedures.DecodeString2UTF8(DecryptAndVerify(u.AliasID_encrypted, u.AliasID_hmac, u.Id, EncryptedFieldIds.User_AliasID)); u.LocalUserCertificate = UserCertificate.Decode(DecryptAndVerify(u.LocalUserCertificate_encrypted, u.LocalUserCertificate_hmac, u.Id, EncryptedFieldIds.User_LocalUserCertificate)); u.Metadata = UserMetadata.Decode(DecryptAndVerify(u.Metadata_encrypted, u.Metadata_hmac, u.Id, EncryptedFieldIds.User_Metadata)); WriteToLog_deepDetail($"decrypted user '{u.AliasID}'"); } catch (Exception exc) { HandleException($"can not decrypt/verify user ID={u.UserID}: ", exc); } } return(users); // var user = db.Get<UserId>(5); // primary key id of 5 }
/// <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); }
/// <param name="reqReceivedFromInP2pMode">is not null for packets between registered peers</param> public byte[] Encode_OpionallySignNeighborHMAC(ConnectionToNeighbor reqReceivedFromInP2pMode) { BinaryProcedures.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 { BinaryProcedures.EncodeIPEndPoint(writer, RequesterEndpoint); } return(ms.ToArray()); }
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 = BinaryProcedures.DecodeUInt32(packetUdpPayloadData, ref index); ProtocolVersion = BinaryProcedures.DecodeUInt16(packetUdpPayloadData, ref index); Status = (PeerHelloRequestStatus)packetUdpPayloadData[index++]; RequestTime32 = BinaryProcedures.DecodeUInt32(packetUdpPayloadData, ref index); Flags = packetUdpPayloadData[index++]; var extensionIdsLength = packetUdpPayloadData[index++]; ExtensionIds = new string[extensionIdsLength]; for (byte i = 0; i < extensionIdsLength; i++) { ExtensionIds[i] = BinaryProcedures.DecodeString1ASCII(packetUdpPayloadData, ref index); } if (index < packetUdpPayloadData.Length) { // after version 190608 RequestSequenceNumber = BinaryProcedures.DecodeUInt16(packetUdpPayloadData, ref index); ResponseCpuDelayMs = BinaryProcedures.DecodeUInt16(packetUdpPayloadData, ref index); RequestedFromIp = BinaryProcedures.DecodeString1ASCII(packetUdpPayloadData, ref index); var reader = BinaryProcedures.CreateBinaryReader(packetUdpPayloadData, index); if (FlagIshareMyIpLocation) { IpLocationData = IpLocationData.Decode(reader); } } }
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(BinaryProcedures.DecodeUInt32(data, ref index)), BinaryProcedures.DecodeUInt16(data, ref index)) )); }
public static RegistrationId Decode(byte[] data) { if (data == null) { return(null); } return(Decode(BinaryProcedures.CreateBinaryReader(data, 0))); }
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 BinaryProcedures.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 BinaryProcedures.CreateBinaryWriter(out var msRxParameters, out var wRxParameters); BinaryProcedures.EncodeIPEndPoint(wRxParameters, localResponderEndpoint); // max 19 LocalNeighborToken32.Encode(wRxParameters); // +4 max 23 _engine.LocalNatBehaviour.Encode(wRxParameters); // +2 max 25 if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"encrypting local responder endpoint={localResponderEndpoint}, localNeighborToken={LocalNeighborToken32} into ACK1"); } wRxParameters.Write(Magic16_responderToRequester); // +2 max 27 var bytesRemaining = RegisterAck1Packet.ToResponderTxParametersEncryptedLength - (int)msRxParameters.Length; wRxParameters.Write(_engine.CryptoLibrary.GetRandomBytes(bytesRemaining)); var localRxParametersDecrypted = msRxParameters.ToArray(); // total 32 bytes = RegisterAck1Packet.ToResponderTxParametersEncryptedLength 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 void UpdateUser(User user) { // we update only following fields: EncryptAndSign(BinaryProcedures.EncodeString2UTF8(user.AliasID), user.Id, EncryptedFieldIds.User_AliasID, out var e, out var a); user.AliasID_encrypted = e; user.AliasID_hmac = a; _db_main.Update(user); }
public static UserMetadata Decode(byte[] data) { if (data == null) { return(null); } using var reader = BinaryProcedures.CreateBinaryReader(data, 0); return(Decode(reader)); }
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 = BinaryProcedures.DecodeString1ASCII(reader); return(fromPeerId, toPeerId, streamId, extensionId); }
public ServerHelloPacket1(BinaryReader reader) // after first byte = packet type { Flags = reader.ReadByte(); Status = (ServerHello1Status)reader.ReadByte(); Cnonce1 = BinaryProcedures.DecodeByteArray256(reader); if (Status == ServerHello1Status.OKready) { StatefulProofOfWorkType = (StatefulProofOfWorkType)reader.ReadByte(); Snonce1 = BinaryProcedures.DecodeByteArray256(reader); } }
public ClientHelloPacket1(BinaryReader reader, byte[] originalPacketPayload) // after first byte = packet type { OriginalPacketPayload = originalPacketPayload; Flags = reader.ReadByte(); Snonce0 = BinaryProcedures.DecodeByteArray256(reader); if (Snonce0.Length != ServerHelloPacket0.Snonce0SupportedSize) { throw new CcpBadPacketException(); } StatefulProofOfWorkResponseData = BinaryProcedures.DecodeByteArray256(reader); }
internal void GetSharedSignedFields(BinaryWriter w, bool includeToResponderSessionDescriptionEncrypted) { w.Write(ReqTimestamp32S); RequesterRegistrationId.Encode(w); ResponderRegistrationId.Encode(w); ResponderEcdhePublicKey.Encode(w); if (includeToResponderSessionDescriptionEncrypted) { BinaryProcedures.EncodeByteArray65536(w, ToResponderSessionDescriptionEncrypted); } }
public byte[] Encode() { BinaryProcedures.CreateBinaryWriter(out var ms, out var writer); writer.Write((byte)PacketTypes.NatTest1Response); byte flags = 0; writer.Write(flags); writer.Write(Token32); BinaryProcedures.EncodeIPEndPoint_ipv4(writer, RequesterEndpoint); return(ms.ToArray()); }
public ClientHelloPacket0(BinaryReader reader, byte[] originalPacketPayload) // after first byte = packet type { OriginalPacketPayload = originalPacketPayload; Flags = reader.ReadUInt16(); Cnonce0 = BinaryProcedures.DecodeByteArray256(reader); if (Cnonce0.Length != Cnonce0SupportedSize) { throw new CcpBadPacketException(); } StatelessProofOfWorkType = (StatelessProofOfWorkType)reader.ReadByte(); StatelessProofOfWorkData = BinaryProcedures.DecodeByteArray256(reader); }
public static StreamId Decode(byte[] data, ref int index) { var id = BinaryProcedures.DecodeUInt32(data, ref index); if (id == 0) { return(null); } else { return(new StreamId(id)); } }
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 BinaryProcedures.EncodeUInt32(data, ref index, (uint)ToEndPoint.Address.Address); #pragma warning restore CS0618 // Type or member is obsolete BinaryProcedures.EncodeUInt16(data, ref index, (ushort)ToEndPoint.Port); }
public static StreamId Decode(BinaryReader reader) { var id = BinaryProcedures.DecodeUInt32(reader); if (id == 0) { return(null); } else { return(new StreamId(id)); } }
/// <param name="reader">positioned after first byte = packet type</param> public RegisterPow1RequestPacket(byte[] originalPacketUdpPayload) { var reader = BinaryProcedures.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 ServerHelloPacket0(byte[] udpData) { var reader = BinaryProcedures.CreateBinaryReader(udpData, 1); Flags = reader.ReadUInt16(); Status = (ServerHello0Status)reader.ReadByte(); Cnonce0 = BinaryProcedures.DecodeByteArray256(reader); if (Status == ServerHello0Status.OK) { StatefulProofOfWorkType = (StatefulProofOfWorkType)reader.ReadByte(); Snonce0 = BinaryProcedures.DecodeByteArray256(reader); } }
internal void GetSignedFieldsForMessageHMAC(BinaryWriter writer) { writer.Write(MessageId32); writer.Write((byte)SenderStatus); if (SenderStatus == MessageSessionStatusCode.inProgress) { BinaryProcedures.EncodeByteArray65536(writer, ContinuedEncryptedData); } else if (SenderStatus == MessageSessionStatusCode.encryptionDecryptionCompleted) { SenderSignature.Encode(writer); } }
/// <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(); } BinaryProcedures.EncodeByteArray256(writer, Cnonce0); writer.Write((byte)StatelessProofOfWorkType); BinaryProcedures.EncodeByteArray256(writer, StatelessProofOfWorkData); return(1 + 2 + 1 + Cnonce0.Length + 1 + 1); }