Re-implement Signal protocol encryption

This commit is contained in:
nielsandriesse 2020-11-09 10:08:57 +11:00
parent 82b12901b9
commit a9755631e3
8 changed files with 22 additions and 54 deletions

View File

@ -1,6 +1,8 @@
import SessionProtocolKit
public struct Configuration {
public let storage: SessionMessagingKitStorageProtocol
public let sessionRestorationImplementation: SessionRestorationProtocol
public let pnServerURL: String
public let pnServerPublicKey: String

View File

@ -3,55 +3,19 @@ import SessionUtilities
internal extension MessageSender {
static func encryptWithSignalProtocol(_ plaintext: Data, for publicKey: String, using transaction: Any) throws -> Data {
static func encryptWithSignalProtocol(_ plaintext: Data, associatedWith message: Message, for publicKey: String, using transaction: Any) throws -> Data {
let storage = Configuration.shared.storage
let cipher = try SMKSecretSessionCipher(sessionResetImplementation: Configuration.shared.sessionRestorationImplementation,
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: storage)
let useFallbackEncryption: Bool = {
if (message is SessionRequest) { return true }
return !Configuration.shared.storage.containsSession(publicKey, deviceId: 1, protocolContext: transaction)
}()
let certificate = Configuration.shared.storage.getSenderCertificate(for: publicKey)
return try cipher.throwswrapped_encryptMessage(recipientPublicKey: publicKey, deviceID: 1, paddedPlaintext: (plaintext as NSData).paddedMessageBody(),
senderCertificate: certificate, protocolContext: transaction, useFallbackSessionCipher: useFallbackEncryption)
}
// NSError *error;
// LKSessionResetImplementation *sessionResetImplementation = [LKSessionResetImplementation new];
//
// SMKSecretSessionCipher *_Nullable secretCipher =
// [[SMKSecretSessionCipher alloc] initWithSessionResetImplementation:sessionResetImplementation
// sessionStore:self.primaryStorage
// preKeyStore:self.primaryStorage
// signedPreKeyStore:self.primaryStorage
// identityStore:self.identityManager
// error:&error];
// if (error || !secretCipher) {
// OWSRaiseException(@"SecretSessionCipherFailure", @"Can't create secret session cipher.");
// }
//
// // Loki: The way this works is:
// // Alice sends a session request (i.e. a pre key bundle) to Bob using fallback encryption.
// // She may send any number of subsequent messages also encrypted using fallback encryption.
// // When Bob receives the session request, he sets up his Signal cipher session locally and sends back a null message,
// // now encrypted using Signal encryption.
// // Alice receives this, sets up her Signal cipher session locally, and sends any subsequent messages
// // using Signal encryption.
//
// BOOL shouldUseFallbackEncryption = [LKSessionManagementProtocol shouldUseFallbackEncryptionForMessage:message recipientID:recipientID transaction:transaction];
//
// if (shouldUseFallbackEncryption) {
// [LKLogger print:@"[Loki] Using fallback encryption"];
// } else {
// [LKLogger print:@"[Loki] Using Signal Encryption"];
// }
//
// serializedMessage = [secretCipher throwswrapped_encryptMessageWithRecipientPublicKey:recipientID
// deviceID:@(OWSDevicePrimaryDeviceId).intValue
// paddedPlaintext:plainText.paddedMessageBody
// senderCertificate:messageSend.senderCertificate
// protocolContext:transaction
// useFallbackSessionCipher:shouldUseFallbackEncryption
// error:&error];
//
// SCKRaiseIfExceptionWrapperError(error);
// if (serializedMessage == nil || error != nil) {
// OWSFailDebug(@"Error while UD encrypting message: %@.", error);
// return nil;
// }
// messageType = TSUnidentifiedSenderMessageType;
static func encryptWithSharedSenderKeys(_ plaintext: Data, for groupPublicKey: String, using transaction: Any) throws -> Data {
// 1. ) Encrypt the data with the user's sender key
guard let userPublicKey = Configuration.shared.storage.getUserPublicKey() else {

View File

@ -49,7 +49,7 @@ internal enum MessageSender {
let ciphertext: Data
do {
switch destination {
case .contact(let publicKey): ciphertext = try encryptWithSignalProtocol(plaintext, for: publicKey, using: transaction)
case .contact(let publicKey): ciphertext = try encryptWithSignalProtocol(plaintext, associatedWith: message, for: publicKey, using: transaction)
case .closedGroup(let groupPublicKey): ciphertext = try encryptWithSharedSenderKeys(plaintext, for: groupPublicKey, using: transaction)
case .openGroup(_, _): preconditionFailure()
}

View File

@ -1,6 +1,6 @@
import SessionProtocolKit
public protocol SessionMessagingKitStorageProtocol {
public protocol SessionMessagingKitStorageProtocol : SessionStore, PreKeyStore, SignedPreKeyStore, IdentityKeyStore {
func with(_ work: (Any) -> Void)
func withAsync(_ work: (Any) -> Void, completion: () -> Void)
@ -12,4 +12,5 @@ public protocol SessionMessagingKitStorageProtocol {
func persist(_ job: Job, using transaction: Any)
func markJobAsSucceeded(_ job: Job, using transaction: Any)
func markJobAsFailed(_ job: Job, using transaction: Any)
func getSenderCertificate(for publicKey: String) -> SMKSenderCertificate
}

View File

@ -7,6 +7,7 @@ FOUNDATION_EXPORT const unsigned char SessionProtocolKitVersionString[];
#import <SessionProtocolKit/ClosedGroupCiphertextMessage.h>
#import <SessionProtocolKit/Cryptography.h>
#import <SessionProtocolKit/FallbackMessage.h>
#import <SessionProtocolKit/NSData+messagePadding.h>
#import <SessionProtocolKit/NSData+OWS.h>
#import <SessionProtocolKit/NSObject+OWS.h>
#import <SessionProtocolKit/NSString+OWS.h>

View File

@ -38,7 +38,7 @@ public final class LokiSessionCipher : SessionCipher {
// Note that while decrypting our state may change internally
let currentState = getCurrentState(protocolContext: protocolContext)
if (currentState == nil && whisperMessage.cipherMessageType == .prekey) {
try sessionResetImplementation?.validatePreKeyWhisperMessage(for: recipientID, whisperMessage: whisperMessage, using: protocolContext!)
try sessionResetImplementation?.validatePreKeyWhisperMessage(for: recipientID, preKeyWhisperMessage: whisperMessage as! PreKeyWhisperMessage, using: protocolContext!)
}
let plainText = try super.decrypt(whisperMessage, protocolContext: protocolContext)
handleSessionReset(for: whisperMessage, previousState: currentState, protocolContext: protocolContext!)

View File

@ -2,7 +2,7 @@
@objc(LKSessionRestorationProtocol)
public protocol SessionRestorationProtocol {
func validatePreKeyWhisperMessage(for recipientPublicKey: String, whisperMessage: CipherMessage, using transaction: Any) throws
func getSessionRestorationStatus(for recipientPublicKey: String) -> SessionRestorationStatus
func handleNewSessionAdopted(for recipientPublicKey: String, using transaction: Any)
func validatePreKeyWhisperMessage(for publicKey: String, preKeyWhisperMessage: PreKeyWhisperMessage, using transaction: Any) throws
func getSessionRestorationStatus(for publicKey: String) -> SessionRestorationStatus
func handleNewSessionAdopted(for publicKey: String, using transaction: Any)
}

View File

@ -646,7 +646,7 @@
C3A71D5725589FF30043A11F /* SMKCertificateValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D4B25589FF20043A11F /* SMKCertificateValidator.swift */; };
C3A71D5825589FF30043A11F /* SMKSecretSessionCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D4C25589FF30043A11F /* SMKSecretSessionCipher.swift */; };
C3A71D5925589FF30043A11F /* SMKUnidentifiedSenderMessageContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D4D25589FF30043A11F /* SMKUnidentifiedSenderMessageContent.swift */; };
C3A71D5A25589FF30043A11F /* NSData+messagePadding.h in Headers */ = {isa = PBXBuildFile; fileRef = C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */; };
C3A71D5A25589FF30043A11F /* NSData+messagePadding.h in Headers */ = {isa = PBXBuildFile; fileRef = C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */; settings = {ATTRIBUTES = (Public, ); }; };
C3A71D5B25589FF30043A11F /* SMKUnidentifiedSenderMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D4F25589FF30043A11F /* SMKUnidentifiedSenderMessage.swift */; };
C3A71D672558A0170043A11F /* FallbackSessionCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D642558A0170043A11F /* FallbackSessionCipher.swift */; };
C3A71D682558A0170043A11F /* LokiSessionCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D652558A0170043A11F /* LokiSessionCipher.swift */; };