Example #1
0
        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);
        }
Example #2
0
 internal void GetSharedSignedFields(BinaryWriter w)
 {
     w.Write(ReqTimestamp32S);
     RequesterRegistrationId.Encode(w);
     ResponderRegistrationId.Encode(w);
     BinaryProcedures.EncodeByteArray65536(w, ToRequesterSessionDescriptionEncrypted);
 }
Example #3
0
        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);
        }
Example #6
0
        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);
 }
Example #8
0
        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));
        }
Example #9
0
        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
        }
Example #10
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  = 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);
        }
Example #11
0
        /// <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());
        }
Example #12
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  = 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);
                }
            }
        }
Example #13
0
 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))
                ));
 }
Example #14
0
 public static RegistrationId Decode(byte[] data)
 {
     if (data == null)
     {
         return(null);
     }
     return(Decode(BinaryProcedures.CreateBinaryReader(data, 0)));
 }
Example #15
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);
        }
Example #16
0
        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);
        }
Example #17
0
 public static UserMetadata Decode(byte[] data)
 {
     if (data == null)
     {
         return(null);
     }
     using var reader = BinaryProcedures.CreateBinaryReader(data, 0);
     return(Decode(reader));
 }
Example #18
0
        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);
        }
Example #19
0
 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);
     }
 }
Example #20
0
 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);
 }
Example #21
0
 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);
     }
 }
Example #22
0
        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());
        }
Example #23
0
 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);
 }
Example #24
0
        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));
            }
        }
Example #25
0
        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);
        }
Example #26
0
        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();
        }
Example #28
0
        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);
            }
        }
Example #29
0
 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);
     }
 }
Example #30
0
        /// <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);
        }