From 87c1b1f39b8d4e6368cdd4244da9ec73f4d7e37e Mon Sep 17 00:00:00 2001 From: Mitch Capper Date: Fri, 17 Aug 2018 15:05:10 -0700 Subject: [PATCH] Improved callback support added Task support and passing SessionRecord This modifies the existing callback support to work with Task based callbacks. It also passes the SessionRecord (when available) to the callback (as not yet committed for prekey), needed for protocol version check code that already exists). --- .../DecryptionCallback.cs | 37 ++++++++++--------- libsignal-protocol-dotnet/SessionCipher.cs | 23 +++++++----- .../groups/GroupCipher.cs | 9 +++-- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/libsignal-protocol-dotnet/DecryptionCallback.cs b/libsignal-protocol-dotnet/DecryptionCallback.cs index b72b20d..d974872 100644 --- a/libsignal-protocol-dotnet/DecryptionCallback.cs +++ b/libsignal-protocol-dotnet/DecryptionCallback.cs @@ -1,24 +1,25 @@ -/** - * Copyright (C) 2016 smndtrl, langboost - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - +using libsignal.state; +using System.Threading.Tasks; +/** +* Copyright (C) 2016 smndtrl, langboost +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ namespace libsignal { public interface DecryptionCallback { - void handlePlaintext(byte[] plaintext); + Task handlePlaintext(byte[] plaintext, SessionRecord sessionRecord); } } diff --git a/libsignal-protocol-dotnet/SessionCipher.cs b/libsignal-protocol-dotnet/SessionCipher.cs index 36f9977..c4edef1 100644 --- a/libsignal-protocol-dotnet/SessionCipher.cs +++ b/libsignal-protocol-dotnet/SessionCipher.cs @@ -24,6 +24,7 @@ using Strilanc.Value; using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace libsignal { @@ -141,7 +142,9 @@ public CiphertextMessage encrypt(byte[] paddedMessage) */ public byte[] decrypt(PreKeySignalMessage ciphertext) { - return decrypt(ciphertext, new NullDecryptionCallback()); + var tsk = (decrypt(ciphertext, new NullDecryptionCallback())); + tsk.Wait(); + return tsk.Result; } /** @@ -165,7 +168,7 @@ public byte[] decrypt(PreKeySignalMessage ciphertext) * @throws InvalidKeyException when the message is formatted incorrectly. * @throws UntrustedIdentityException when the {@link IdentityKey} of the sender is untrusted. */ - public byte[] decrypt(PreKeySignalMessage ciphertext, DecryptionCallback callback) + public Task decrypt(PreKeySignalMessage ciphertext, DecryptionCallback callback) { lock (SESSION_LOCK) { @@ -175,7 +178,7 @@ public byte[] decrypt(PreKeySignalMessage ciphertext, DecryptionCallback callbac identityKeyStore.SaveIdentity(remoteAddress, sessionRecord.getSessionState().getRemoteIdentityKey()); - callback.handlePlaintext(plaintext); + callback.handlePlaintext(plaintext, sessionRecord).Wait(); sessionStore.StoreSession(remoteAddress, sessionRecord); @@ -184,7 +187,7 @@ public byte[] decrypt(PreKeySignalMessage ciphertext, DecryptionCallback callbac preKeyStore.RemovePreKey(unsignedPreKeyId.ForceGetValue()); } - return plaintext; + return Task.FromResult(plaintext); } } @@ -202,7 +205,9 @@ public byte[] decrypt(PreKeySignalMessage ciphertext, DecryptionCallback callbac */ public byte[] decrypt(SignalMessage ciphertext) { - return decrypt(ciphertext, new NullDecryptionCallback()); + var tsk = decrypt(ciphertext, new NullDecryptionCallback()); + tsk.Wait(); + return tsk.Result; } /** @@ -223,7 +228,7 @@ public byte[] decrypt(SignalMessage ciphertext) * is no longer supported. * @throws NoSessionException if there is no established session for this contact. */ - public byte[] decrypt(SignalMessage ciphertext, DecryptionCallback callback) + public Task decrypt(SignalMessage ciphertext, DecryptionCallback callback) { lock (SESSION_LOCK) { @@ -241,11 +246,11 @@ public byte[] decrypt(SignalMessage ciphertext, DecryptionCallback callback) throw new UntrustedIdentityException(remoteAddress.Name, sessionRecord.getSessionState().getRemoteIdentityKey()); } - callback.handlePlaintext(plaintext); + callback.handlePlaintext(plaintext, sessionRecord).Wait();//no async in a lock sessionStore.StoreSession(remoteAddress, sessionRecord); - return plaintext; + return Task.FromResult(plaintext); } } @@ -425,7 +430,7 @@ private byte[] getPlaintext(MessageKeys messageKeys, byte[] cipherText) private class NullDecryptionCallback : DecryptionCallback { - public void handlePlaintext(byte[] plaintext) { } + public Task handlePlaintext(byte[] plaintext, SessionRecord sessionRecord) => Task.CompletedTask; } } } diff --git a/libsignal-protocol-dotnet/groups/GroupCipher.cs b/libsignal-protocol-dotnet/groups/GroupCipher.cs index 8c0f977..f7de31d 100644 --- a/libsignal-protocol-dotnet/groups/GroupCipher.cs +++ b/libsignal-protocol-dotnet/groups/GroupCipher.cs @@ -18,8 +18,10 @@ using libsignal.groups.ratchet; using libsignal.groups.state; using libsignal.protocol; +using libsignal.state; using libsignal.util; using System; +using System.Threading.Tasks; namespace libsignal.groups { @@ -134,7 +136,7 @@ public byte[] decrypt(byte[] senderKeyMessageBytes, DecryptionCallback callback) byte[] plaintext = getPlainText(senderKey.getIv(), senderKey.getCipherKey(), senderKeyMessage.getCipherText()); - callback.handlePlaintext(plaintext); + callback.handlePlaintext(plaintext, null).Wait(); senderKeyStore.storeSenderKey(senderKeyId, record); @@ -217,8 +219,9 @@ private byte[] getCipherText(byte[] iv, byte[] key, byte[] plaintext) private class NullDecryptionCallback : DecryptionCallback { - public void handlePlaintext(byte[] plaintext) { } - } + public Task handlePlaintext(byte[] plaintext, SessionRecord sessionRecord) => Task.CompletedTask; + + } } }