Esempio n. 1
0
        internal async Task SendShortSingleMessageAsync(string messageText, UserCertificate senderUserCertificateWithPrivateKeys)
        {
            if (!DerivedDirectChannelSharedDhSecretsAE)
            {
                throw new InvalidOperationException("DerivedDirectChannelSharedDhSecretsAE = false");
            }
            if (Logger.WriteToLog_detail_enabled)
            {
                Logger.WriteToLog_detail(">> InviteSession.SendShortSingleMessageAsync()");
            }

            var messageSession = new MessageSession();
            var messageStart   = new MessageStartPacket()
            {
                MessageId32          = (uint)_insecureRandom.Next(),
                DirectChannelToken32 = RemoteSessionDescription.DirectChannelToken32,
                MessageTimestamp64   = _localDrpPeer.Engine.Timestamp64,
            };

            messageSession.DeriveKeys(_localDrpPeer.CryptoLibrary, SharedPingPongHmacKey, messageStart, DirectChannelSharedDhSecret);
            messageStart.EncryptedMessageData = messageSession.EncryptShortSingleMessage(_localDrpPeer.CryptoLibrary, messageText);

            // sign with HMAC
            messageStart.MessageHMAC = GetMessageHMAC(w => messageStart.GetSignedFieldsForMessageHMAC(w, true));

            // send msgstart, wait for msgack
            var messageStartUdpData = messageStart.Encode();

            if (Logger.WriteToLog_detail_enabled)
            {
                Logger.WriteToLog_detail("sending MSGSTART and waiting for MSGACK");
            }
            var messageAckUdpData = await _localDrpPeer.Engine.OptionallySendUdpRequestAsync_Retransmit_WaitForResponse("msgstart 4582", "remote user",
                                                                                                                        messageStartUdpData, RemoteSessionDescription.DirectChannelEndPoint,
                                                                                                                        MessageAckPacket.GetScanner(messageStart.MessageId32, this, MessageSessionStatusCode.encryptionDecryptionCompleted) // scanner also verifies HMAC
                                                                                                                        );

            var messageAck = MessageAckPacket.Decode(messageAckUdpData);

            if (Logger.WriteToLog_detail_enabled)
            {
                Logger.WriteToLog_detail("decoded MSGACK");
            }

            // send msgpart with status=encryptionDecryptionCompleted and signature
            if (messageSession.Status != MessageSessionStatusCode.encryptionDecryptionCompleted)
            {
                throw new InvalidOperationException();
            }
            var messagePart = new MessagePartPacket
            {
                MessageId32     = messageStart.MessageId32,
                SenderStatus    = messageSession.Status,
                SenderSignature = UserCertificateSignature.Sign(_localDrpPeer.CryptoLibrary, w =>
                {
                    w.Write(MessageHMACkey);
                    w.Write(messageSession.AesKey);
                    w.Write(messageStart.EncryptedMessageData);
                    w.Write(messageAck.ReceiverFinalNonce);
                }, senderUserCertificateWithPrivateKeys)
            };

            messagePart.MessageHMAC = GetMessageHMAC(messagePart.GetSignedFieldsForMessageHMAC);
            var messagePartUdpData = messagePart.Encode();

            // wait for msgack status=finalSignatureVerified
            if (Logger.WriteToLog_detail_enabled)
            {
                Logger.WriteToLog_detail("sending MSGPART with message data, waiting for MSGACK");
            }
            await _localDrpPeer.Engine.OptionallySendUdpRequestAsync_Retransmit_WaitForResponse("msgpart 3681", "remote user", messagePartUdpData,
                                                                                                RemoteSessionDescription.DirectChannelEndPoint,
                                                                                                MessageAckPacket.GetScanner(messageStart.MessageId32, this, MessageSessionStatusCode.finalSignatureVerified) // scanner also verifies HMAC
                                                                                                );
        }