Re-implement Signal protocol decryption

This commit is contained in:
nielsandriesse 2020-11-09 10:33:26 +11:00
parent 8520ec59dd
commit 41d078d012
4 changed files with 31 additions and 6 deletions

View File

@ -3,6 +3,7 @@ import SessionProtocolKit
public struct Configuration {
public let storage: SessionMessagingKitStorageProtocol
public let sessionRestorationImplementation: SessionRestorationProtocol
public let certificateValidator: SMKCertificateValidator
public let pnServerURL: String
public let pnServerPublicKey: String

View File

@ -30,7 +30,7 @@ public final class MessageReceiveJob : NSObject, Job, NSCoding { // NSObject/NS
Configuration.shared.storage.with { transaction in // Intentionally capture self
Threading.workQueue.async {
do {
let _ = try MessageReceiver.parse(self.data)
let _ = try MessageReceiver.parse(self.data, using: transaction)
self.handleSuccess()
} catch {
SNLog("Couldn't parse message due to error: \(error).")

View File

@ -4,6 +4,18 @@ import SessionUtilities
internal extension MessageReceiver {
static func decryptWithSignalProtocol(envelope: SNProtoEnvelope, using transaction: Any) throws -> (plaintext: Data, senderPublicKey: String) {
let storage = Configuration.shared.storage
let certificateValidator = Configuration.shared.certificateValidator
guard let data = envelope.content else { throw Error.noData }
guard let userPublicKey = storage.getUserPublicKey() else { throw Error.noUserPublicKey }
let cipher = try SMKSecretSessionCipher(sessionResetImplementation: Configuration.shared.sessionRestorationImplementation,
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: storage)
let result = try cipher.throwswrapped_decryptMessage(certificateValidator: certificateValidator, cipherTextData: data,
timestamp: envelope.timestamp, localRecipientId: userPublicKey, localDeviceId: 1, protocolContext: transaction)
return (result.paddedPayload, result.senderRecipientId)
}
static func decryptWithSharedSenderKeys(envelope: SNProtoEnvelope, using transaction: Any) throws -> (plaintext: Data, senderPublicKey: String) {
// 1. ) Check preconditions
guard let groupPublicKey = envelope.source, Configuration.shared.storage.isClosedGroup(groupPublicKey) else {

View File

@ -5,9 +5,11 @@ internal enum MessageReceiver {
internal enum Error : LocalizedError {
case invalidMessage
case unknownMessage
case unknownEnvelopeType
case noUserPublicKey
case noData
// Shared sender keys
case invalidGroupPublicKey
case noData
case noGroupPrivateKey
case sharedSecretGenerationFailed
case selfSend
@ -16,9 +18,11 @@ internal enum MessageReceiver {
switch self {
case .invalidMessage: return "Invalid message."
case .unknownMessage: return "Unknown message type."
case .unknownEnvelopeType: return "Unknown envelope type."
case .noUserPublicKey: return "Couldn't find user key pair."
case .noData: return "Received an empty envelope."
// Shared sender keys
case .invalidGroupPublicKey: return "Invalid group public key."
case .noData: return "Received an empty envelope."
case .noGroupPrivateKey: return "Missing group private key."
case .sharedSecretGenerationFailed: return "Couldn't generate a shared secret."
case .selfSend: return "Message addressed at self."
@ -26,11 +30,19 @@ internal enum MessageReceiver {
}
}
internal static func parse(_ ciphertext: Data) throws -> Message {
let plaintext = ciphertext
internal static func parse(_ data: Data, using transaction: Any) throws -> Message {
// Parse the envelope
let envelope = try MessageWrapper.unwrap(data: data)
// Decrypt the contents
let plaintext: Data
switch envelope.type {
case .unidentifiedSender: (plaintext, _) = try decryptWithSignalProtocol(envelope: envelope, using: transaction)
case .closedGroupCiphertext: (plaintext, _) = try decryptWithSharedSenderKeys(envelope: envelope, using: transaction)
default: throw Error.unknownEnvelopeType
}
let proto: SNProtoContent
do {
proto = try SNProtoContent.parseData(plaintext)
proto = try SNProtoContent.parseData((plaintext as NSData).removePadding())
} catch {
SNLog("Couldn't parse proto due to error: \(error).")
throw error