/// <param name="receivedFromUser">comes from local contact book. is null if it is contact invitation</param>
        internal static InviteSessionDescription Decrypt_Verify(ICryptoLibrary cryptoLibrary, byte[] encryptedSdData,
                                                                InviteRequestPacket req,
                                                                InviteAck1Packet ack1,
                                                                bool ack1SdIsReady,
                                                                InviteSession session,
                                                                UserId receivedFromUserNullable,
                                                                DateTime localTimeNowUtc
                                                                )
        {
            #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

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

            var r      = new InviteSessionDescription();
            var reader = BinaryProcedures.CreateBinaryReader(plainTextSdData, 0);
            r.Flags = reader.ReadByte();
            if ((r.Flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }
            r.UserCertificate          = UserCertificate.Decode_AssertIsValidNow(reader, cryptoLibrary, receivedFromUserNullable, localTimeNowUtc);
            r.DirectChannelEndPoint    = BinaryProcedures.DecodeIPEndPoint(reader);
            r.NatBehaviour             = NatBehaviourModel.Decode(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);
        }
Esempio n. 2
0
        public static InviteRequestPacket Decode_VerifyNeighborHMAC(byte[] udpData, ConnectionToNeighbor receivedFromNeighbor)
        {
            var r = new InviteRequestPacket();

            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);
            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.RequesterNatBehaviour   = NatBehaviourModel.Decode(reader);
            if ((flags & FlagsMask_ContactInvitationTokenExists) != 0)
            {
                r.ContactInvitationTokenNullable = reader.ReadBytes(ContactInvitationTokenSize);
            }
            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);
        }