Remove the Signal protocol
This commit is contained in:
parent
ef1d6392a7
commit
71758b0c00
|
@ -38,7 +38,6 @@
|
||||||
#import "OWSQRCodeScanningViewController.h"
|
#import "OWSQRCodeScanningViewController.h"
|
||||||
#import "SignalApp.h"
|
#import "SignalApp.h"
|
||||||
#import "UIViewController+Permissions.h"
|
#import "UIViewController+Permissions.h"
|
||||||
#import <SessionProtocolKit/NSData+keyVersionByte.h>
|
|
||||||
#import <PureLayout/PureLayout.h>
|
#import <PureLayout/PureLayout.h>
|
||||||
#import <Reachability/Reachability.h>
|
#import <Reachability/Reachability.h>
|
||||||
#import <SignalCoreKit/Cryptography.h>
|
#import <SignalCoreKit/Cryptography.h>
|
||||||
|
@ -74,7 +73,6 @@
|
||||||
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
||||||
#import <SessionMessagingKit/OWSIdentityManager.h>
|
#import <SessionMessagingKit/OWSIdentityManager.h>
|
||||||
#import <SessionMessagingKit/OWSMediaGalleryFinder.h>
|
#import <SessionMessagingKit/OWSMediaGalleryFinder.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage+SessionStore.h>
|
|
||||||
#import <SessionMessagingKit/OWSRecipientIdentity.h>
|
#import <SessionMessagingKit/OWSRecipientIdentity.h>
|
||||||
#import <SignalUtilitiesKit/SignalAccount.h>
|
#import <SignalUtilitiesKit/SignalAccount.h>
|
||||||
#import <SessionMessagingKit/SignalRecipient.h>
|
#import <SessionMessagingKit/SignalRecipient.h>
|
||||||
|
@ -88,7 +86,6 @@
|
||||||
#import <SessionMessagingKit/TSIncomingMessage.h>
|
#import <SessionMessagingKit/TSIncomingMessage.h>
|
||||||
#import <SessionMessagingKit/TSInfoMessage.h>
|
#import <SessionMessagingKit/TSInfoMessage.h>
|
||||||
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSPreKeyManager.h>
|
|
||||||
#import <SessionMessagingKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
#import <SessionUtilitiesKit/LKGroupUtilities.h>
|
#import <SessionUtilitiesKit/LKGroupUtilities.h>
|
||||||
#import <SessionUtilitiesKit/UIImage+OWS.h>
|
#import <SessionUtilitiesKit/UIImage+OWS.h>
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SessionMessagingKit/TSAccountManager.h>
|
#import <SessionMessagingKit/TSAccountManager.h>
|
||||||
#import <SessionMessagingKit/TSDatabaseView.h>
|
#import <SessionMessagingKit/TSDatabaseView.h>
|
||||||
#import <SignalUtilitiesKit/TSPreKeyManager.h>
|
|
||||||
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
||||||
#import <sys/utsname.h>
|
#import <sys/utsname.h>
|
||||||
|
|
||||||
|
@ -72,13 +71,6 @@ static NSTimeInterval launchStartedAt;
|
||||||
return [OWSReadReceiptManager sharedManager];
|
return [OWSReadReceiptManager sharedManager];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id<OWSUDManager>)udManager
|
|
||||||
{
|
|
||||||
OWSAssertDebug(SSKEnvironment.shared.udManager);
|
|
||||||
|
|
||||||
return SSKEnvironment.shared.udManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (OWSPrimaryStorage *)primaryStorage
|
- (OWSPrimaryStorage *)primaryStorage
|
||||||
{
|
{
|
||||||
OWSAssertDebug(SSKEnvironment.shared.primaryStorage);
|
OWSAssertDebug(SSKEnvironment.shared.primaryStorage);
|
||||||
|
@ -377,9 +369,6 @@ static NSTimeInterval launchStartedAt;
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
OWSAssertIsOnMainThread();
|
||||||
|
|
||||||
// Always check prekeys after app launches, and sometimes check on app activation.
|
|
||||||
[TSPreKeyManager checkPreKeysIfNecessary];
|
|
||||||
|
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
RTCInitializeSSL();
|
RTCInitializeSSL();
|
||||||
|
@ -525,8 +514,6 @@ static NSTimeInterval launchStartedAt;
|
||||||
|
|
||||||
[self ensureRootViewController];
|
[self ensureRootViewController];
|
||||||
|
|
||||||
[self.udManager setup];
|
|
||||||
|
|
||||||
[self preheatDatabaseViews];
|
[self preheatDatabaseViews];
|
||||||
|
|
||||||
[self.primaryStorage touchDbAsync];
|
[self.primaryStorage touchDbAsync];
|
||||||
|
|
|
@ -34,9 +34,6 @@ import SignalUtilitiesKit
|
||||||
@objc
|
@objc
|
||||||
public var pushRegistrationManager: PushRegistrationManager
|
public var pushRegistrationManager: PushRegistrationManager
|
||||||
|
|
||||||
@objc
|
|
||||||
public var sessionResetJobQueue: SessionResetJobQueue
|
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
public var backup: OWSBackup
|
public var backup: OWSBackup
|
||||||
|
|
||||||
|
@ -71,7 +68,6 @@ import SignalUtilitiesKit
|
||||||
self.accountManager = AccountManager()
|
self.accountManager = AccountManager()
|
||||||
self.notificationPresenter = NotificationPresenter()
|
self.notificationPresenter = NotificationPresenter()
|
||||||
self.pushRegistrationManager = PushRegistrationManager()
|
self.pushRegistrationManager = PushRegistrationManager()
|
||||||
self.sessionResetJobQueue = SessionResetJobQueue()
|
|
||||||
self.backup = OWSBackup()
|
self.backup = OWSBackup()
|
||||||
self.backupLazyRestore = BackupLazyRestore()
|
self.backupLazyRestore = BackupLazyRestore()
|
||||||
if #available(iOS 10.0, *) {
|
if #available(iOS 10.0, *) {
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#import "TSGroupThread.h"
|
#import "TSGroupThread.h"
|
||||||
#import "TSIncomingMessage.h"
|
#import "TSIncomingMessage.h"
|
||||||
#import "TSInfoMessage.h"
|
#import "TSInfoMessage.h"
|
||||||
#import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
|
|
||||||
#import "UIFont+OWS.h"
|
#import "UIFont+OWS.h"
|
||||||
#import "UIViewController+Permissions.h"
|
#import "UIViewController+Permissions.h"
|
||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
@ -63,7 +62,6 @@
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SessionMessagingKit/TSAccountManager.h>
|
#import <SessionMessagingKit/TSAccountManager.h>
|
||||||
#import <SessionMessagingKit/TSGroupModel.h>
|
#import <SessionMessagingKit/TSGroupModel.h>
|
||||||
#import <SessionMessagingKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
|
|
||||||
#import <SessionMessagingKit/TSQuotedMessage.h>
|
#import <SessionMessagingKit/TSQuotedMessage.h>
|
||||||
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
#import <YapDatabase/YapDatabase.h>
|
#import <YapDatabase/YapDatabase.h>
|
||||||
|
@ -247,11 +245,6 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
#pragma mark - Dependencies
|
#pragma mark - Dependencies
|
||||||
|
|
||||||
- (OWSSessionResetJobQueue *)sessionResetJobQueue
|
|
||||||
{
|
|
||||||
return AppEnvironment.shared.sessionResetJobQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (OWSAudioSession *)audioSession
|
- (OWSAudioSession *)audioSession
|
||||||
{
|
{
|
||||||
return Environment.shared.audioSession;
|
return Environment.shared.audioSession;
|
||||||
|
@ -1525,23 +1518,6 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
[alert addAction:[OWSAlerts cancelAction]];
|
[alert addAction:[OWSAlerts cancelAction]];
|
||||||
|
|
||||||
UIAlertAction *resetSessionAction = [UIAlertAction
|
|
||||||
actionWithTitle:NSLocalizedString(@"FINGERPRINT_SHRED_KEYMATERIAL_BUTTON", @"")
|
|
||||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"reset_session")
|
|
||||||
style:UIAlertActionStyleDefault
|
|
||||||
handler:^(UIAlertAction *action) {
|
|
||||||
if (![self.thread isKindOfClass:[TSContactThread class]]) {
|
|
||||||
// Corrupt Message errors only appear in contact threads.
|
|
||||||
OWSLogError(@"Unexpected request to reset session in group thread. Refusing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TSContactThread *contactThread = (TSContactThread *)self.thread;
|
|
||||||
[LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
|
||||||
[self.sessionResetJobQueue addContactThread:contactThread transaction:transaction];
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
[alert addAction:resetSessionAction];
|
|
||||||
|
|
||||||
[self dismissKeyBoard];
|
[self dismissKeyBoard];
|
||||||
[self presentAlert:alert];
|
[self presentAlert:alert];
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,11 +56,6 @@ static NSString *const kSealedSenderInfoURL = @"https://signal.org/blog/sealed-s
|
||||||
|
|
||||||
#pragma mark - Dependencies
|
#pragma mark - Dependencies
|
||||||
|
|
||||||
- (id<OWSUDManager>)udManager
|
|
||||||
{
|
|
||||||
return SSKEnvironment.shared.udManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (OWSPreferences *)preferences
|
- (OWSPreferences *)preferences
|
||||||
{
|
{
|
||||||
return Environment.shared.preferences;
|
return Environment.shared.preferences;
|
||||||
|
@ -291,8 +286,7 @@ static NSString *const kSealedSenderInfoURL = @"https://signal.org/blog/sealed-s
|
||||||
|
|
||||||
- (void)didToggleUDUnrestrictedAccessSwitch:(UISwitch *)sender
|
- (void)didToggleUDUnrestrictedAccessSwitch:(UISwitch *)sender
|
||||||
{
|
{
|
||||||
OWSLogInfo(@"toggled to: %@", (sender.isOn ? @"ON" : @"OFF"));
|
|
||||||
[self.udManager setShouldAllowUnrestrictedAccessLocal:sender.isOn];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didToggleUDShowIndicatorsSwitch:(UISwitch *)sender
|
- (void)didToggleUDShowIndicatorsSwitch:(UISwitch *)sender
|
||||||
|
|
|
@ -1,194 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import PromiseKit
|
|
||||||
import SignalUtilitiesKit
|
|
||||||
|
|
||||||
@objc(OWSSessionResetJobQueue)
|
|
||||||
public class SessionResetJobQueue: NSObject, SignalUtilitiesKit.JobQueue {
|
|
||||||
|
|
||||||
@objc(addContactThread:transaction:)
|
|
||||||
public func add(contactThread: TSContactThread, transaction: YapDatabaseReadWriteTransaction) {
|
|
||||||
let jobRecord = OWSSessionResetJobRecord(contactThread: contactThread, label: self.jobRecordLabel)
|
|
||||||
self.add(jobRecord: jobRecord, transaction: transaction)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: JobQueue
|
|
||||||
|
|
||||||
public typealias DurableOperationType = SessionResetOperation
|
|
||||||
public let jobRecordLabel: String = "SessionReset"
|
|
||||||
public static let maxRetries: UInt = 10
|
|
||||||
public let requiresInternet: Bool = true
|
|
||||||
public var runningOperations: [SessionResetOperation] = []
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public override init() {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
AppReadiness.runNowOrWhenAppWillBecomeReady {
|
|
||||||
self.setup()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func setup() {
|
|
||||||
defaultSetup()
|
|
||||||
}
|
|
||||||
|
|
||||||
public var isSetup: Bool = false
|
|
||||||
|
|
||||||
public func didMarkAsReady(oldJobRecord: JobRecordType, transaction: YapDatabaseReadWriteTransaction) {
|
|
||||||
// no special handling
|
|
||||||
}
|
|
||||||
|
|
||||||
let operationQueue: OperationQueue = {
|
|
||||||
// no need to serialize the operation queuing, since sending will ultimately be serialized by MessageSender
|
|
||||||
let operationQueue = OperationQueue()
|
|
||||||
operationQueue.name = "SessionReset.OperationQueue"
|
|
||||||
return operationQueue
|
|
||||||
}()
|
|
||||||
|
|
||||||
public func operationQueue(jobRecord: OWSSessionResetJobRecord) -> OperationQueue {
|
|
||||||
return self.operationQueue
|
|
||||||
}
|
|
||||||
|
|
||||||
public func buildOperation(jobRecord: OWSSessionResetJobRecord, transaction: YapDatabaseReadTransaction) throws -> SessionResetOperation {
|
|
||||||
guard let contactThread = TSThread.fetch(uniqueId: jobRecord.contactThreadId, transaction: transaction) as? TSContactThread else {
|
|
||||||
throw JobError.obsolete(description: "thread for session reset no longer exists")
|
|
||||||
}
|
|
||||||
|
|
||||||
return SessionResetOperation(contactThread: contactThread, jobRecord: jobRecord)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SessionResetOperation: OWSOperation, DurableOperation {
|
|
||||||
|
|
||||||
// MARK: DurableOperation
|
|
||||||
|
|
||||||
public let jobRecord: OWSSessionResetJobRecord
|
|
||||||
|
|
||||||
weak public var durableOperationDelegate: SessionResetJobQueue?
|
|
||||||
|
|
||||||
public var operation: OWSOperation {
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK:
|
|
||||||
|
|
||||||
let contactThread: TSContactThread
|
|
||||||
var recipientId: String {
|
|
||||||
return contactThread.contactIdentifier()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public required init(contactThread: TSContactThread, jobRecord: OWSSessionResetJobRecord) {
|
|
||||||
self.contactThread = contactThread
|
|
||||||
self.jobRecord = jobRecord
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Dependencies
|
|
||||||
|
|
||||||
var dbConnection: YapDatabaseConnection {
|
|
||||||
return SSKEnvironment.shared.primaryStorage.dbReadWriteConnection
|
|
||||||
}
|
|
||||||
|
|
||||||
var primaryStorage: OWSPrimaryStorage {
|
|
||||||
return SSKEnvironment.shared.primaryStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK:
|
|
||||||
|
|
||||||
var firstAttempt = true
|
|
||||||
|
|
||||||
override public func run() {
|
|
||||||
assert(self.durableOperationDelegate != nil)
|
|
||||||
|
|
||||||
/*
|
|
||||||
let endSessionMessage = EndSessionMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: self.contactThread)
|
|
||||||
|
|
||||||
firstly {
|
|
||||||
return self.messageSender.sendPromise(message: endSessionMessage)
|
|
||||||
}.done {
|
|
||||||
Logger.info("successfully sent EndSessionMessage.")
|
|
||||||
Storage.writeSync { transaction in
|
|
||||||
// Archive the just-created session since the recipient should delete their corresponding
|
|
||||||
// session upon receiving and decrypting our EndSession message.
|
|
||||||
// Otherwise if we send another message before them, they wont have the session to decrypt it.
|
|
||||||
self.primaryStorage.archiveAllSessions(forContact: self.recipientId, protocolContext: transaction)
|
|
||||||
|
|
||||||
/* Loki: Original code
|
|
||||||
* ================
|
|
||||||
let message = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(),
|
|
||||||
in: self.contactThread,
|
|
||||||
messageType: TSInfoMessageType.typeSessionDidEnd)
|
|
||||||
message.save(with: transaction)
|
|
||||||
* ================
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (self.contactThread.sessionResetStatus != .requestReceived) {
|
|
||||||
let message = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: self.contactThread, messageType: .typeLokiSessionResetInProgress)
|
|
||||||
message.save(with: transaction)
|
|
||||||
|
|
||||||
// Loki: We have initiated a session reset
|
|
||||||
SNLog("Session reset initiated.")
|
|
||||||
self.contactThread.sessionResetStatus = .initiated
|
|
||||||
self.contactThread.save(with: transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.reportSuccess()
|
|
||||||
}.catch { error in
|
|
||||||
Logger.error("sending error: \(error.localizedDescription)")
|
|
||||||
self.reportError(error)
|
|
||||||
}.retainUntilComplete()
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func didSucceed() {
|
|
||||||
Storage.writeSync { transaction in
|
|
||||||
self.durableOperationDelegate?.durableOperationDidSucceed(self, transaction: transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func didReportError(_ error: Error) {
|
|
||||||
Logger.debug("remainingRetries: \(self.remainingRetries)")
|
|
||||||
|
|
||||||
Storage.writeSync { transaction in
|
|
||||||
self.durableOperationDelegate?.durableOperation(self, didReportError: error, transaction: transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func retryInterval() -> TimeInterval {
|
|
||||||
// Arbitrary backoff factor...
|
|
||||||
// With backOffFactor of 1.9
|
|
||||||
// try 1 delay: 0.00s
|
|
||||||
// try 2 delay: 0.19s
|
|
||||||
// ...
|
|
||||||
// try 5 delay: 1.30s
|
|
||||||
// ...
|
|
||||||
// try 11 delay: 61.31s
|
|
||||||
let backoffFactor = 1.9
|
|
||||||
let maxBackoff = kHourInterval
|
|
||||||
|
|
||||||
let seconds = 0.1 * min(maxBackoff, pow(backoffFactor, Double(self.jobRecord.failureCount)))
|
|
||||||
|
|
||||||
return seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func didFail(error: Error) {
|
|
||||||
Logger.error("failed to send EndSessionMessage with error: \(error.localizedDescription)")
|
|
||||||
Storage.writeSync { transaction in
|
|
||||||
self.durableOperationDelegate?.durableOperation(self, didFailWithError: error, transaction: transaction)
|
|
||||||
|
|
||||||
// Even though this is the failure handler - which means probably the recipient didn't receive the message
|
|
||||||
// there's a chance that our send did succeed and the server just timed out our repsonse or something.
|
|
||||||
// Since the cost of sending a future message using a session the recipient doesn't have is so high,
|
|
||||||
// we archive the session just in case.
|
|
||||||
//
|
|
||||||
// Archive the just-created session since the recipient should delete their corresponding
|
|
||||||
// session upon receiving and decrypting our EndSession message.
|
|
||||||
// Otherwise if we send another message before them, they wont have the session to decrypt it.
|
|
||||||
self.primaryStorage.archiveAllSessions(forContact: self.recipientId, protocolContext: transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,43 +3,17 @@ import SessionProtocolKit
|
||||||
@objc
|
@objc
|
||||||
public final class SNMessagingKitConfiguration : NSObject {
|
public final class SNMessagingKitConfiguration : NSObject {
|
||||||
public let storage: SessionMessagingKitStorageProtocol
|
public let storage: SessionMessagingKitStorageProtocol
|
||||||
@objc public let signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore
|
|
||||||
public let identityKeyStore: IdentityKeyStore
|
|
||||||
public let sessionRestorationImplementation: SessionRestorationProtocol
|
|
||||||
public let certificateValidator: SMKCertificateValidator
|
|
||||||
|
|
||||||
@objc public static var shared: SNMessagingKitConfiguration!
|
@objc public static var shared: SNMessagingKitConfiguration!
|
||||||
|
|
||||||
fileprivate init(
|
fileprivate init(storage: SessionMessagingKitStorageProtocol) {
|
||||||
storage: SessionMessagingKitStorageProtocol,
|
|
||||||
signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore,
|
|
||||||
identityKeyStore: IdentityKeyStore,
|
|
||||||
sessionRestorationImplementation: SessionRestorationProtocol,
|
|
||||||
certificateValidator: SMKCertificateValidator
|
|
||||||
) {
|
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.signalStorage = signalStorage
|
|
||||||
self.identityKeyStore = identityKeyStore
|
|
||||||
self.sessionRestorationImplementation = sessionRestorationImplementation
|
|
||||||
self.certificateValidator = certificateValidator
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SNMessagingKit { // Just to make the external API nice
|
public enum SNMessagingKit { // Just to make the external API nice
|
||||||
|
|
||||||
public static func configure(
|
public static func configure(storage: SessionMessagingKitStorageProtocol) {
|
||||||
storage: SessionMessagingKitStorageProtocol,
|
SNMessagingKitConfiguration.shared = SNMessagingKitConfiguration(storage: storage)
|
||||||
signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore,
|
|
||||||
identityKeyStore: IdentityKeyStore,
|
|
||||||
sessionRestorationImplementation: SessionRestorationProtocol,
|
|
||||||
certificateValidator: SMKCertificateValidator
|
|
||||||
) {
|
|
||||||
SNMessagingKitConfiguration.shared = SNMessagingKitConfiguration(
|
|
||||||
storage: storage,
|
|
||||||
signalStorage: signalStorage,
|
|
||||||
identityKeyStore: identityKeyStore,
|
|
||||||
sessionRestorationImplementation: sessionRestorationImplementation,
|
|
||||||
certificateValidator: certificateValidator
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,6 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage)
|
||||||
|
|
||||||
[TSDatabaseView asyncRegisterUnseenDatabaseView:self];
|
[TSDatabaseView asyncRegisterUnseenDatabaseView:self];
|
||||||
[TSDatabaseView asyncRegisterThreadOutgoingMessagesDatabaseView:self];
|
[TSDatabaseView asyncRegisterThreadOutgoingMessagesDatabaseView:self];
|
||||||
[TSDatabaseView asyncRegisterThreadSpecialMessagesDatabaseView:self];
|
|
||||||
|
|
||||||
[FullTextSearchFinder asyncRegisterDatabaseExtensionWithStorage:self];
|
[FullTextSearchFinder asyncRegisterDatabaseExtensionWithStorage:self];
|
||||||
[OWSIncomingMessageFinder asyncRegisterExtensionWithPrimaryStorage:self];
|
[OWSIncomingMessageFinder asyncRegisterExtensionWithPrimaryStorage:self];
|
||||||
|
|
|
@ -6,16 +6,6 @@ extension Storage {
|
||||||
SSKEnvironment.shared.tsAccountManager.getOrGenerateRegistrationId(transaction as! YapDatabaseReadWriteTransaction)
|
SSKEnvironment.shared.tsAccountManager.getOrGenerateRegistrationId(transaction as! YapDatabaseReadWriteTransaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getSenderCertificate(for publicKey: String) -> SMKSenderCertificate {
|
|
||||||
let (promise, seal) = Promise<SMKSenderCertificate>.pending()
|
|
||||||
SSKEnvironment.shared.udManager.ensureSenderCertificate { senderCertificate in
|
|
||||||
seal.fulfill(senderCertificate)
|
|
||||||
} failure: { error in
|
|
||||||
// Should never fail
|
|
||||||
}
|
|
||||||
return try! promise.wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the ID of the thread.
|
/// Returns the ID of the thread.
|
||||||
public func getOrCreateThread(for publicKey: String, groupPublicKey: String?, openGroupID: String?, using transaction: Any) -> String? {
|
public func getOrCreateThread(for publicKey: String, groupPublicKey: String?, openGroupID: String?, using transaction: Any) -> String? {
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
|
|
|
@ -63,8 +63,6 @@ extern NSString *const TSLazyRestoreAttachmentsDatabaseViewExtensionName;
|
||||||
// Instances of OWSReadTracking for wasRead is NO.
|
// Instances of OWSReadTracking for wasRead is NO.
|
||||||
+ (void)asyncRegisterUnseenDatabaseView:(OWSStorage *)storage;
|
+ (void)asyncRegisterUnseenDatabaseView:(OWSStorage *)storage;
|
||||||
|
|
||||||
+ (void)asyncRegisterThreadSpecialMessagesDatabaseView:(OWSStorage *)storage;
|
|
||||||
|
|
||||||
+ (void)asyncRegisterLazyRestoreAttachmentsDatabaseView:(OWSStorage *)storage;
|
+ (void)asyncRegisterLazyRestoreAttachmentsDatabaseView:(OWSStorage *)storage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#import "TSAttachment.h"
|
#import "TSAttachment.h"
|
||||||
#import "TSAttachmentPointer.h"
|
#import "TSAttachmentPointer.h"
|
||||||
#import "TSIncomingMessage.h"
|
#import "TSIncomingMessage.h"
|
||||||
#import "TSInvalidIdentityKeyErrorMessage.h"
|
|
||||||
#import "TSOutgoingMessage.h"
|
#import "TSOutgoingMessage.h"
|
||||||
#import "TSThread.h"
|
#import "TSThread.h"
|
||||||
#import <YapDatabase/YapDatabaseAutoView.h>
|
#import <YapDatabase/YapDatabaseAutoView.h>
|
||||||
|
@ -128,33 +127,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
storage:storage];
|
storage:storage];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)asyncRegisterThreadSpecialMessagesDatabaseView:(OWSStorage *)storage
|
|
||||||
{
|
|
||||||
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
|
||||||
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
|
||||||
if (![object isKindOfClass:[TSInteraction class]]) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
TSInteraction *interaction = (TSInteraction *)object;
|
|
||||||
if ([interaction isDynamicInteraction]) {
|
|
||||||
return interaction.uniqueThreadId;
|
|
||||||
} else if ([object isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
|
|
||||||
return interaction.uniqueThreadId;
|
|
||||||
} else if ([object isKindOfClass:[TSErrorMessage class]]) {
|
|
||||||
TSErrorMessage *errorMessage = (TSErrorMessage *)object;
|
|
||||||
if (errorMessage.errorType == TSErrorMessageNonBlockingIdentityChange) {
|
|
||||||
return errorMessage.uniqueThreadId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil;
|
|
||||||
}];
|
|
||||||
|
|
||||||
[self registerMessageDatabaseViewWithName:TSThreadSpecialMessagesDatabaseViewExtensionName
|
|
||||||
viewGrouping:viewGrouping
|
|
||||||
version:@"2"
|
|
||||||
storage:storage];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage
|
+ (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage
|
||||||
{
|
{
|
||||||
YapDatabaseView *existingView = [storage registeredExtension:TSMessageDatabaseViewExtensionName_Legacy];
|
YapDatabaseView *existingView = [storage registeredExtension:TSMessageDatabaseViewExtensionName_Legacy];
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
import SessionProtocolKit
|
|
||||||
import SessionUtilitiesKit
|
|
||||||
|
|
||||||
@objc(SNNullMessage)
|
|
||||||
public final class NullMessage : ControlMessage {
|
|
||||||
|
|
||||||
// MARK: Initialization
|
|
||||||
public override init() { super.init() }
|
|
||||||
|
|
||||||
// MARK: Coding
|
|
||||||
public required init?(coder: NSCoder) {
|
|
||||||
super.init(coder: coder)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func encode(with coder: NSCoder) {
|
|
||||||
super.encode(with: coder)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Proto Conversion
|
|
||||||
public override class func fromProto(_ proto: SNProtoContent) -> NullMessage? {
|
|
||||||
guard proto.nullMessage != nil else { return nil }
|
|
||||||
return NullMessage()
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
|
|
||||||
let nullMessageProto = SNProtoNullMessage.builder()
|
|
||||||
let paddingSize = UInt.random(in: 0..<512) // random(in:) uses the system's default random generator, which is cryptographically secure
|
|
||||||
let padding = Data.getSecureRandomData(ofSize: paddingSize)!
|
|
||||||
nullMessageProto.setPadding(padding)
|
|
||||||
let contentProto = SNProtoContent.builder()
|
|
||||||
do {
|
|
||||||
contentProto.setNullMessage(try nullMessageProto.build())
|
|
||||||
return try contentProto.build()
|
|
||||||
} catch {
|
|
||||||
SNLog("Couldn't construct null message proto from: \(self).")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
import SessionProtocolKit
|
|
||||||
import SessionUtilitiesKit
|
|
||||||
|
|
||||||
@objc(SNSessionRequest)
|
|
||||||
public final class SessionRequest : ControlMessage {
|
|
||||||
public var preKeyBundle: PreKeyBundle?
|
|
||||||
|
|
||||||
// MARK: Initialization
|
|
||||||
public override init() { super.init() }
|
|
||||||
|
|
||||||
internal init(preKeyBundle: PreKeyBundle) {
|
|
||||||
super.init()
|
|
||||||
self.preKeyBundle = preKeyBundle
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Validation
|
|
||||||
public override var isValid: Bool {
|
|
||||||
guard super.isValid else { return false }
|
|
||||||
return preKeyBundle != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Coding
|
|
||||||
public required init?(coder: NSCoder) {
|
|
||||||
super.init(coder: coder)
|
|
||||||
if let preKeyBundle = coder.decodeObject(forKey: "preKeyBundle") as! PreKeyBundle? { self.preKeyBundle = preKeyBundle }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func encode(with coder: NSCoder) {
|
|
||||||
super.encode(with: coder)
|
|
||||||
coder.encode(preKeyBundle, forKey: "preKeyBundle")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Proto Conversion
|
|
||||||
public override class func fromProto(_ proto: SNProtoContent) -> SessionRequest? {
|
|
||||||
guard proto.nullMessage != nil, let preKeyBundleProto = proto.prekeyBundleMessage else { return nil }
|
|
||||||
var registrationID: UInt32 = 0
|
|
||||||
SNMessagingKitConfiguration.shared.storage.writeSync { transaction in
|
|
||||||
registrationID = SNMessagingKitConfiguration.shared.storage.getOrGenerateRegistrationID(using: transaction)
|
|
||||||
}
|
|
||||||
guard let preKeyBundle = PreKeyBundle(
|
|
||||||
registrationId: Int32(registrationID),
|
|
||||||
deviceId: 1,
|
|
||||||
preKeyId: Int32(preKeyBundleProto.prekeyID),
|
|
||||||
preKeyPublic: preKeyBundleProto.prekey,
|
|
||||||
signedPreKeyPublic: preKeyBundleProto.signedKey,
|
|
||||||
signedPreKeyId: Int32(preKeyBundleProto.signedKeyID),
|
|
||||||
signedPreKeySignature: preKeyBundleProto.signature,
|
|
||||||
identityKey: preKeyBundleProto.identityKey
|
|
||||||
) else { return nil }
|
|
||||||
return SessionRequest(preKeyBundle: preKeyBundle)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
|
|
||||||
guard let preKeyBundle = preKeyBundle else {
|
|
||||||
SNLog("Couldn't construct session request proto from: \(self).")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
let nullMessageProto = SNProtoNullMessage.builder()
|
|
||||||
let paddingSize = UInt.random(in: 0..<512) // random(in:) uses the system's default random generator, which is cryptographically secure
|
|
||||||
let padding = Data.getSecureRandomData(ofSize: paddingSize)!
|
|
||||||
nullMessageProto.setPadding(padding)
|
|
||||||
let preKeyBundleProto = SNProtoPrekeyBundleMessage.builder()
|
|
||||||
preKeyBundleProto.setIdentityKey(preKeyBundle.identityKey)
|
|
||||||
preKeyBundleProto.setDeviceID(UInt32(preKeyBundle.deviceId))
|
|
||||||
preKeyBundleProto.setPrekeyID(UInt32(preKeyBundle.preKeyId))
|
|
||||||
preKeyBundleProto.setPrekey(preKeyBundle.preKeyPublic)
|
|
||||||
preKeyBundleProto.setSignedKeyID(UInt32(preKeyBundle.signedPreKeyId))
|
|
||||||
preKeyBundleProto.setSignedKey(preKeyBundle.signedPreKeyPublic)
|
|
||||||
preKeyBundleProto.setSignature(preKeyBundle.signedPreKeySignature)
|
|
||||||
let contentProto = SNProtoContent.builder()
|
|
||||||
do {
|
|
||||||
contentProto.setNullMessage(try nullMessageProto.build())
|
|
||||||
contentProto.setPrekeyBundleMessage(try preKeyBundleProto.build())
|
|
||||||
return try contentProto.build()
|
|
||||||
} catch {
|
|
||||||
SNLog("Couldn't construct session request proto from: \(self).")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <SessionMessagingKit/TSErrorMessage.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
|
|
||||||
|
|
||||||
- (void)throws_acceptNewIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
- (nullable NSData *)throws_newIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
- (NSString *)theirSignalId;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,29 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "TSInvalidIdentityKeyErrorMessage.h"
|
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@implementation TSInvalidIdentityKeyErrorMessage
|
|
||||||
|
|
||||||
- (void)throws_acceptNewIdentityKey
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable NSData *)throws_newIdentityKey
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)theirSignalId
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,22 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@class SNProtoEnvelope;
|
|
||||||
|
|
||||||
// DEPRECATED - we no longer create new instances of this class (as of mid-2017); However, existing instances may
|
|
||||||
// exist, so we should keep this class around to honor their old behavior.
|
|
||||||
__attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage : TSInvalidIdentityKeyErrorMessage
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
+ (nullable instancetype)untrustedKeyWithEnvelope:(SNProtoEnvelope *)envelope
|
|
||||||
withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,141 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "TSInvalidIdentityKeyReceivingErrorMessage.h"
|
|
||||||
#import "OWSIdentityManager.h"
|
|
||||||
#import "OWSPrimaryStorage.h"
|
|
||||||
#import "SSKEnvironment.h"
|
|
||||||
#import "TSContactThread.h"
|
|
||||||
#import "TSDatabaseView.h"
|
|
||||||
#import "TSErrorMessage_privateConstructor.h"
|
|
||||||
#import <SessionProtocolKit/NSData+keyVersionByte.h>
|
|
||||||
#import <SessionProtocolKit/PreKeyWhisperMessage.h>
|
|
||||||
#import <YapDatabase/YapDatabaseTransaction.h>
|
|
||||||
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
__attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage()
|
|
||||||
|
|
||||||
@property (nonatomic, readonly, copy) NSString *authorId;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation TSInvalidIdentityKeyReceivingErrorMessage {
|
|
||||||
// Not using a property declaration in order to exclude from DB serialization
|
|
||||||
SNProtoEnvelope *_Nullable _envelope;
|
|
||||||
}
|
|
||||||
|
|
||||||
@synthesize envelopeData = _envelopeData;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
// We no longer create these messages, but they might exist on legacy clients so it's useful to be able to
|
|
||||||
// create them with the debug UI
|
|
||||||
+ (nullable instancetype)untrustedKeyWithEnvelope:(SNProtoEnvelope *)envelope
|
|
||||||
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
||||||
{
|
|
||||||
TSContactThread *contactThread =
|
|
||||||
[TSContactThread getOrCreateThreadWithContactId:envelope.source transaction:transaction];
|
|
||||||
|
|
||||||
// Legit usage of senderTimestamp, references message which failed to decrypt
|
|
||||||
TSInvalidIdentityKeyReceivingErrorMessage *errorMessage =
|
|
||||||
[[self alloc] initForUnknownIdentityKeyWithTimestamp:envelope.timestamp
|
|
||||||
inThread:contactThread
|
|
||||||
incomingEnvelope:envelope];
|
|
||||||
return errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable instancetype)initForUnknownIdentityKeyWithTimestamp:(uint64_t)timestamp
|
|
||||||
inThread:(TSThread *)thread
|
|
||||||
incomingEnvelope:(SNProtoEnvelope *)envelope
|
|
||||||
{
|
|
||||||
self = [self initWithTimestamp:timestamp inThread:thread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
|
|
||||||
if (!self) {
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSError *error;
|
|
||||||
_envelopeData = [envelope serializedDataAndReturnError:&error];
|
|
||||||
if (!_envelopeData || error != nil) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
_authorId = envelope.source;
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (nullable SNProtoEnvelope *)envelope
|
|
||||||
{
|
|
||||||
if (!_envelope) {
|
|
||||||
NSError *error;
|
|
||||||
SNProtoEnvelope *_Nullable envelope = [SNProtoEnvelope parseData:self.envelopeData error:&error];
|
|
||||||
if (error || envelope == nil) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_envelope = envelope;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _envelope;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)throws_acceptNewIdentityKey
|
|
||||||
{
|
|
||||||
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSData *_Nullable newKey = [self throws_newIdentityKey];
|
|
||||||
if (!newKey) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[OWSIdentityManager sharedManager] saveRemoteIdentity:newKey recipientId:self.envelope.source];
|
|
||||||
|
|
||||||
// Decrypt this and any old messages for the newly accepted key
|
|
||||||
NSArray<TSInvalidIdentityKeyReceivingErrorMessage *> *messagesToDecrypt =
|
|
||||||
[self.thread receivedMessagesForInvalidKey:newKey];
|
|
||||||
|
|
||||||
for (TSInvalidIdentityKeyReceivingErrorMessage *errorMessage in messagesToDecrypt) {
|
|
||||||
|
|
||||||
// Here we remove the existing error message because handleReceivedEnvelope will either
|
|
||||||
// 1.) succeed and create a new successful message in the thread or...
|
|
||||||
// 2.) fail and create a new identical error message in the thread.
|
|
||||||
[errorMessage remove];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable NSData *)throws_newIdentityKey
|
|
||||||
{
|
|
||||||
if (!self.envelope) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.envelope.type != SNProtoEnvelopeTypePrekeyBundle) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSData *pkwmData = self.envelope.content;
|
|
||||||
if (!pkwmData) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] init_throws_withData:pkwmData];
|
|
||||||
return [message.identityKey throws_removeKeyType];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)theirSignalId
|
|
||||||
{
|
|
||||||
if (self.authorId) {
|
|
||||||
return self.authorId;
|
|
||||||
} else {
|
|
||||||
// for existing messages before we were storing author id.
|
|
||||||
return self.envelope.source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -6,6 +6,11 @@
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, TSMessageDirection) {
|
||||||
|
TSMessageDirectionIncoming,
|
||||||
|
TSMessageDirectionOutgoing
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract message class.
|
* Abstract message class.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,8 +48,6 @@ FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[];
|
||||||
#import <SessionMessagingKit/TSIncomingMessage.h>
|
#import <SessionMessagingKit/TSIncomingMessage.h>
|
||||||
#import <SessionMessagingKit/TSInfoMessage.h>
|
#import <SessionMessagingKit/TSInfoMessage.h>
|
||||||
#import <SessionMessagingKit/TSInteraction.h>
|
#import <SessionMessagingKit/TSInteraction.h>
|
||||||
#import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
|
|
||||||
#import <SessionMessagingKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
|
|
||||||
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
||||||
#import <SessionMessagingKit/TSQuotedMessage.h>
|
#import <SessionMessagingKit/TSQuotedMessage.h>
|
||||||
#import <SessionMessagingKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
|
|
|
@ -5,18 +5,6 @@ import Sodium
|
||||||
|
|
||||||
internal extension MessageReceiver {
|
internal extension MessageReceiver {
|
||||||
|
|
||||||
static func decryptWithSignalProtocol(envelope: SNProtoEnvelope, using transaction: Any) throws -> (plaintext: Data, senderPublicKey: String) {
|
|
||||||
let storage = SNMessagingKitConfiguration.shared.signalStorage
|
|
||||||
let certificateValidator = SNMessagingKitConfiguration.shared.certificateValidator
|
|
||||||
guard let data = envelope.content else { throw Error.noData }
|
|
||||||
guard let userPublicKey = SNMessagingKitConfiguration.shared.storage.getUserPublicKey() else { throw Error.noUserX25519KeyPair }
|
|
||||||
let cipher = try SMKSecretSessionCipher(sessionResetImplementation: SNMessagingKitConfiguration.shared.sessionRestorationImplementation,
|
|
||||||
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: SNMessagingKitConfiguration.shared.identityKeyStore)
|
|
||||||
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 decryptWithSessionProtocol(envelope: SNProtoEnvelope) throws -> (plaintext: Data, senderX25519PublicKey: String) {
|
static func decryptWithSessionProtocol(envelope: SNProtoEnvelope) throws -> (plaintext: Data, senderX25519PublicKey: String) {
|
||||||
guard let ciphertext = envelope.content else { throw Error.noData }
|
guard let ciphertext = envelope.content else { throw Error.noData }
|
||||||
let recipientX25519PrivateKey: Data
|
let recipientX25519PrivateKey: Data
|
||||||
|
@ -53,38 +41,4 @@ internal extension MessageReceiver {
|
||||||
|
|
||||||
return (Data(plaintext), "05" + senderX25519PublicKey.toHexString())
|
return (Data(plaintext), "05" + senderX25519PublicKey.toHexString())
|
||||||
}
|
}
|
||||||
|
|
||||||
static func decryptWithSharedSenderKeys(envelope: SNProtoEnvelope, using transaction: Any) throws -> (plaintext: Data, senderPublicKey: String) {
|
|
||||||
// 1. ) Check preconditions
|
|
||||||
guard let groupPublicKey = envelope.source, SNMessagingKitConfiguration.shared.storage.isClosedGroup(groupPublicKey) else {
|
|
||||||
throw Error.invalidGroupPublicKey
|
|
||||||
}
|
|
||||||
guard let data = envelope.content else {
|
|
||||||
throw Error.noData
|
|
||||||
}
|
|
||||||
guard let hexEncodedGroupPrivateKey = SNMessagingKitConfiguration.shared.storage.getClosedGroupPrivateKey(for: groupPublicKey) else {
|
|
||||||
throw Error.noGroupPrivateKey
|
|
||||||
}
|
|
||||||
let groupPrivateKey = Data(hex: hexEncodedGroupPrivateKey)
|
|
||||||
// 2. ) Parse the wrapper
|
|
||||||
let wrapper = try SNProtoClosedGroupCiphertextMessageWrapper.parseData(data)
|
|
||||||
let ivAndCiphertext = wrapper.ciphertext
|
|
||||||
let ephemeralPublicKey = wrapper.ephemeralPublicKey
|
|
||||||
// 3. ) Decrypt the data inside
|
|
||||||
guard let ephemeralSharedSecret = try? Curve25519.generateSharedSecret(fromPublicKey: ephemeralPublicKey, privateKey: groupPrivateKey) else {
|
|
||||||
throw Error.sharedSecretGenerationFailed
|
|
||||||
}
|
|
||||||
let salt = "LOKI".data(using: String.Encoding.utf8, allowLossyConversion: true)!.bytes
|
|
||||||
let symmetricKey = try HMAC(key: salt, variant: .sha256).authenticate(ephemeralSharedSecret.bytes)
|
|
||||||
let closedGroupCiphertextMessageAsData = try AESGCM.decrypt(ivAndCiphertext, with: Data(symmetricKey))
|
|
||||||
// 4. ) Parse the closed group ciphertext message
|
|
||||||
let closedGroupCiphertextMessage = ClosedGroupCiphertextMessage(_throws_with: closedGroupCiphertextMessageAsData)
|
|
||||||
let senderPublicKey = closedGroupCiphertextMessage.senderPublicKey.toHexString()
|
|
||||||
guard senderPublicKey != SNMessagingKitConfiguration.shared.storage.getUserPublicKey() else { throw Error.selfSend }
|
|
||||||
// 5. ) Use the info inside the closed group ciphertext message to decrypt the actual message content
|
|
||||||
let plaintext = try SharedSenderKeys.decrypt(closedGroupCiphertextMessage.ivAndCiphertext, for: groupPublicKey,
|
|
||||||
senderPublicKey: senderPublicKey, keyIndex: UInt(closedGroupCiphertextMessage.keyIndex), using: transaction)
|
|
||||||
// 6. ) Return
|
|
||||||
return (plaintext, senderPublicKey)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
import SessionProtocolKit
|
||||||
|
|
||||||
extension MessageSender : SharedSenderKeysDelegate {
|
extension MessageSender : SharedSenderKeysDelegate {
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,6 @@ import Sodium
|
||||||
|
|
||||||
internal extension MessageSender {
|
internal extension MessageSender {
|
||||||
|
|
||||||
static func encryptWithSignalProtocol(_ plaintext: Data, associatedWith message: Message, for publicKey: String, using transaction: Any) throws -> Data {
|
|
||||||
let storage = SNMessagingKitConfiguration.shared.signalStorage
|
|
||||||
let cipher = try SMKSecretSessionCipher(sessionResetImplementation: SNMessagingKitConfiguration.shared.sessionRestorationImplementation,
|
|
||||||
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: SNMessagingKitConfiguration.shared.identityKeyStore)
|
|
||||||
let certificate = SMKSenderCertificate(senderDeviceId: 1, senderRecipientId: SNMessagingKitConfiguration.shared.storage.getUserPublicKey()!)
|
|
||||||
return try cipher.throwswrapped_encryptMessage(recipientPublicKey: publicKey, deviceID: 1, paddedPlaintext: (plaintext as NSData).paddedMessageBody(),
|
|
||||||
senderCertificate: certificate, protocolContext: transaction, useFallbackSessionCipher: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func encryptWithSessionProtocol(_ plaintext: Data, for recipientHexEncodedX25519PublicKey: String) throws -> Data {
|
static func encryptWithSessionProtocol(_ plaintext: Data, for recipientHexEncodedX25519PublicKey: String) throws -> Data {
|
||||||
guard let userED25519KeyPair = SNMessagingKitConfiguration.shared.storage.getUserED25519KeyPair() else { throw Error.noUserED25519KeyPair }
|
guard let userED25519KeyPair = SNMessagingKitConfiguration.shared.storage.getUserED25519KeyPair() else { throw Error.noUserED25519KeyPair }
|
||||||
let recipientX25519PublicKey = Data(hex: recipientHexEncodedX25519PublicKey.removing05PrefixIfNeeded())
|
let recipientX25519PublicKey = Data(hex: recipientHexEncodedX25519PublicKey.removing05PrefixIfNeeded())
|
||||||
|
@ -25,18 +16,4 @@ internal extension MessageSender {
|
||||||
|
|
||||||
return Data(ciphertext)
|
return Data(ciphertext)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = SNMessagingKitConfiguration.shared.storage.getUserPublicKey() else {
|
|
||||||
SNLog("Couldn't find user key pair.")
|
|
||||||
throw Error.noUserX25519KeyPair
|
|
||||||
}
|
|
||||||
let (ivAndCiphertext, keyIndex) = try SharedSenderKeys.encrypt((plaintext as NSData).paddedMessageBody(), for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction)
|
|
||||||
let encryptedMessage = ClosedGroupCiphertextMessage(_throws_withIVAndCiphertext: ivAndCiphertext, senderPublicKey: Data(hex: userPublicKey), keyIndex: UInt32(keyIndex))
|
|
||||||
// 2. ) Encrypt the result for the group's public key to hide the sender public key and key index
|
|
||||||
let intermediate = try AESGCM.encrypt(encryptedMessage.serialized, for: groupPublicKey.removing05PrefixIfNeeded())
|
|
||||||
// 3. ) Wrap the result
|
|
||||||
return try SNProtoClosedGroupCiphertextMessageWrapper.builder(ciphertext: intermediate.ciphertext, ephemeralPublicKey: intermediate.ephemeralPublicKey).build().serializedData()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ public protocol SessionMessagingKitStorageProtocol {
|
||||||
// MARK: - Signal Protocol
|
// MARK: - Signal Protocol
|
||||||
|
|
||||||
func getOrGenerateRegistrationID(using transaction: Any) -> UInt32
|
func getOrGenerateRegistrationID(using transaction: Any) -> UInt32
|
||||||
func getSenderCertificate(for publicKey: String) -> SMKSenderCertificate
|
|
||||||
|
|
||||||
// MARK: - Shared Sender Keys
|
// MARK: - Shared Sender Keys
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ NSString *const TSContactThreadPrefix = @"c";
|
||||||
|
|
||||||
- (BOOL)hasSafetyNumbers
|
- (BOOL)hasSafetyNumbers
|
||||||
{
|
{
|
||||||
return !![[OWSIdentityManager sharedManager] identityKeyForRecipientId:self.contactIdentifier];
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)name
|
- (NSString *)name
|
||||||
|
|
|
@ -60,14 +60,6 @@ BOOL IsNoteToSelfEnabled(void);
|
||||||
*/
|
*/
|
||||||
- (NSUInteger)numberOfInteractions;
|
- (NSUInteger)numberOfInteractions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all messages in the thread we weren't able to decrypt
|
|
||||||
*/
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
- (NSArray<TSInvalidIdentityKeyReceivingErrorMessage *> *)receivedMessagesForInvalidKey:(NSData *)key;
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
|
|
||||||
- (NSUInteger)unreadMessageCountWithTransaction:(YapDatabaseReadTransaction *)transaction
|
- (NSUInteger)unreadMessageCountWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||||
NS_SWIFT_NAME(unreadMessageCount(transaction:));
|
NS_SWIFT_NAME(unreadMessageCount(transaction:));
|
||||||
|
|
||||||
|
|
|
@ -224,28 +224,6 @@ BOOL IsNoteToSelfEnabled(void)
|
||||||
return [interactions copy];
|
return [interactions copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
- (NSArray<TSInvalidIdentityKeyReceivingErrorMessage *> *)receivedMessagesForInvalidKey:(NSData *)key
|
|
||||||
{
|
|
||||||
NSMutableArray *errorMessages = [NSMutableArray new];
|
|
||||||
[self enumerateInteractionsUsingBlock:^(TSInteraction *interaction) {
|
|
||||||
if ([interaction isKindOfClass:[TSInvalidIdentityKeyReceivingErrorMessage class]]) {
|
|
||||||
TSInvalidIdentityKeyReceivingErrorMessage *error = (TSInvalidIdentityKeyReceivingErrorMessage *)interaction;
|
|
||||||
@try {
|
|
||||||
if ([[error throws_newIdentityKey] isEqualToData:key]) {
|
|
||||||
[errorMessages addObject:(TSInvalidIdentityKeyReceivingErrorMessage *)interaction];
|
|
||||||
}
|
|
||||||
} @catch (NSException *exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
return [errorMessages copy];
|
|
||||||
}
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
|
|
||||||
- (NSUInteger)numberOfInteractions
|
- (NSUInteger)numberOfInteractions
|
||||||
{
|
{
|
||||||
__block NSUInteger count;
|
__block NSUInteger count;
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
|
|
||||||
@objc
|
|
||||||
public enum UnidentifiedAccessMode: Int {
|
|
||||||
case unknown
|
|
||||||
case enabled
|
|
||||||
case disabled
|
|
||||||
case unrestricted
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public class OWSUDAccess: NSObject {
|
|
||||||
@objc
|
|
||||||
public let udAccessKey: SMKUDAccessKey
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public let udAccessMode: UnidentifiedAccessMode
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public let isRandomKey: Bool
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public required init(udAccessKey: SMKUDAccessKey,
|
|
||||||
udAccessMode: UnidentifiedAccessMode,
|
|
||||||
isRandomKey: Bool) {
|
|
||||||
self.udAccessKey = udAccessKey
|
|
||||||
self.udAccessMode = udAccessMode
|
|
||||||
self.isRandomKey = isRandomKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public protocol OWSUDManager: class {
|
|
||||||
|
|
||||||
@objc func setup()
|
|
||||||
|
|
||||||
@objc func trustRoot() -> ECPublicKey
|
|
||||||
|
|
||||||
@objc func isUDVerboseLoggingEnabled() -> Bool
|
|
||||||
|
|
||||||
// MARK: - Recipient State
|
|
||||||
|
|
||||||
@objc
|
|
||||||
func setUnidentifiedAccessMode(_ mode: UnidentifiedAccessMode, recipientId: String)
|
|
||||||
|
|
||||||
@objc
|
|
||||||
func unidentifiedAccessMode(forRecipientId recipientId: String) -> UnidentifiedAccessMode
|
|
||||||
|
|
||||||
@objc
|
|
||||||
func udAccessKey(forRecipientId recipientId: String) -> SMKUDAccessKey?
|
|
||||||
|
|
||||||
@objc
|
|
||||||
func udAccess(forRecipientId recipientId: String,
|
|
||||||
requireSyncAccess: Bool) -> OWSUDAccess?
|
|
||||||
|
|
||||||
// MARK: Sender Certificate
|
|
||||||
|
|
||||||
// We use completion handlers instead of a promise so that message sending
|
|
||||||
// logic can access the strongly typed certificate data.
|
|
||||||
@objc
|
|
||||||
func ensureSenderCertificate(success:@escaping (SMKSenderCertificate) -> Void,
|
|
||||||
failure:@escaping (Error) -> Void)
|
|
||||||
|
|
||||||
// MARK: Unrestricted Access
|
|
||||||
|
|
||||||
@objc
|
|
||||||
func shouldAllowUnrestrictedAccessLocal() -> Bool
|
|
||||||
@objc
|
|
||||||
func setShouldAllowUnrestrictedAccessLocal(_ value: Bool)
|
|
||||||
|
|
||||||
@objc
|
|
||||||
func getSenderCertificate() -> SMKSenderCertificate?
|
|
||||||
}
|
|
|
@ -27,11 +27,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
return SSKEnvironment.shared.profileManager;
|
return SSKEnvironment.shared.profileManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id<OWSUDManager>)udManager
|
|
||||||
{
|
|
||||||
return SSKEnvironment.shared.udManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (TSAccountManager *)tsAccountManager
|
- (TSAccountManager *)tsAccountManager
|
||||||
{
|
{
|
||||||
return SSKEnvironment.shared.tsAccountManager;
|
return SSKEnvironment.shared.tsAccountManager;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SessionProtocolKit/IdentityKeyStore.h>
|
#import <Curve25519Kit/Curve25519.h>
|
||||||
#import <YapDatabase/YapDatabase.h>
|
#import <YapDatabase/YapDatabase.h>
|
||||||
|
|
||||||
@class OWSPrimaryStorage;
|
@class OWSPrimaryStorage;
|
||||||
|
@ -34,7 +34,7 @@ extern const NSUInteger kStoredIdentityKeyLength;
|
||||||
@class YapDatabaseReadWriteTransaction;
|
@class YapDatabaseReadWriteTransaction;
|
||||||
|
|
||||||
// This class can be safely accessed and used from any thread.
|
// This class can be safely accessed and used from any thread.
|
||||||
@interface OWSIdentityManager : NSObject <IdentityKeyStore>
|
@interface OWSIdentityManager : NSObject
|
||||||
|
|
||||||
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
|
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
#import "TSContactThread.h"
|
#import "TSContactThread.h"
|
||||||
#import "TSErrorMessage.h"
|
#import "TSErrorMessage.h"
|
||||||
#import "TSGroupThread.h"
|
#import "TSGroupThread.h"
|
||||||
|
#import "TSMessage.h"
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
#import <SessionProtocolKit/SessionProtocolKit.h>
|
||||||
#import "YapDatabaseConnection+OWS.h"
|
#import "YapDatabaseConnection+OWS.h"
|
||||||
#import "YapDatabaseTransaction+OWS.h"
|
#import "YapDatabaseTransaction+OWS.h"
|
||||||
#import <SessionProtocolKit/NSData+keyVersionByte.h>
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
#import <Curve25519Kit/Curve25519.h>
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
|
@ -223,8 +223,6 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
|
||||||
createdAt:[NSDate new]
|
createdAt:[NSDate new]
|
||||||
verificationState:verificationState] saveWithTransaction:transaction];
|
verificationState:verificationState] saveWithTransaction:transaction];
|
||||||
|
|
||||||
[SNMessagingKitConfiguration.shared.signalStorage archiveAllSessionsForContact:recipientId protocolContext:protocolContext];
|
|
||||||
|
|
||||||
[self fireIdentityStateChangeNotification];
|
[self fireIdentityStateChangeNotification];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
|
|
@ -41,7 +41,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
primaryStorage:(OWSPrimaryStorage *)primaryStorage
|
primaryStorage:(OWSPrimaryStorage *)primaryStorage
|
||||||
blockingManager:(OWSBlockingManager *)blockingManager
|
blockingManager:(OWSBlockingManager *)blockingManager
|
||||||
identityManager:(OWSIdentityManager *)identityManager
|
identityManager:(OWSIdentityManager *)identityManager
|
||||||
udManager:(id<OWSUDManager>)udManager
|
|
||||||
tsAccountManager:(TSAccountManager *)tsAccountManager
|
tsAccountManager:(TSAccountManager *)tsAccountManager
|
||||||
disappearingMessagesJob:(OWSDisappearingMessagesJob *)disappearingMessagesJob
|
disappearingMessagesJob:(OWSDisappearingMessagesJob *)disappearingMessagesJob
|
||||||
readReceiptManager:(OWSReadReceiptManager *)readReceiptManager
|
readReceiptManager:(OWSReadReceiptManager *)readReceiptManager
|
||||||
|
@ -64,7 +63,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
@property (nonatomic, readonly) OWSPrimaryStorage *primaryStorage;
|
@property (nonatomic, readonly) OWSPrimaryStorage *primaryStorage;
|
||||||
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
|
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
|
||||||
@property (nonatomic, readonly) OWSIdentityManager *identityManager;
|
@property (nonatomic, readonly) OWSIdentityManager *identityManager;
|
||||||
@property (nonatomic, readonly) id<OWSUDManager> udManager;
|
|
||||||
@property (nonatomic, readonly) TSAccountManager *tsAccountManager;
|
@property (nonatomic, readonly) TSAccountManager *tsAccountManager;
|
||||||
@property (nonatomic, readonly) OWSDisappearingMessagesJob *disappearingMessagesJob;
|
@property (nonatomic, readonly) OWSDisappearingMessagesJob *disappearingMessagesJob;
|
||||||
@property (nonatomic, readonly) OWSReadReceiptManager *readReceiptManager;
|
@property (nonatomic, readonly) OWSReadReceiptManager *readReceiptManager;
|
||||||
|
|
|
@ -17,7 +17,6 @@ static SSKEnvironment *sharedSSKEnvironment;
|
||||||
@property (nonatomic) OWSPrimaryStorage *primaryStorage;
|
@property (nonatomic) OWSPrimaryStorage *primaryStorage;
|
||||||
@property (nonatomic) OWSBlockingManager *blockingManager;
|
@property (nonatomic) OWSBlockingManager *blockingManager;
|
||||||
@property (nonatomic) OWSIdentityManager *identityManager;
|
@property (nonatomic) OWSIdentityManager *identityManager;
|
||||||
@property (nonatomic) id<OWSUDManager> udManager;
|
|
||||||
@property (nonatomic) TSAccountManager *tsAccountManager;
|
@property (nonatomic) TSAccountManager *tsAccountManager;
|
||||||
@property (nonatomic) OWSDisappearingMessagesJob *disappearingMessagesJob;
|
@property (nonatomic) OWSDisappearingMessagesJob *disappearingMessagesJob;
|
||||||
@property (nonatomic) OWSReadReceiptManager *readReceiptManager;
|
@property (nonatomic) OWSReadReceiptManager *readReceiptManager;
|
||||||
|
@ -41,7 +40,6 @@ static SSKEnvironment *sharedSSKEnvironment;
|
||||||
primaryStorage:(OWSPrimaryStorage *)primaryStorage
|
primaryStorage:(OWSPrimaryStorage *)primaryStorage
|
||||||
blockingManager:(OWSBlockingManager *)blockingManager
|
blockingManager:(OWSBlockingManager *)blockingManager
|
||||||
identityManager:(OWSIdentityManager *)identityManager
|
identityManager:(OWSIdentityManager *)identityManager
|
||||||
udManager:(id<OWSUDManager>)udManager
|
|
||||||
tsAccountManager:(TSAccountManager *)tsAccountManager
|
tsAccountManager:(TSAccountManager *)tsAccountManager
|
||||||
disappearingMessagesJob:(OWSDisappearingMessagesJob *)disappearingMessagesJob
|
disappearingMessagesJob:(OWSDisappearingMessagesJob *)disappearingMessagesJob
|
||||||
readReceiptManager:(OWSReadReceiptManager *)readReceiptManager
|
readReceiptManager:(OWSReadReceiptManager *)readReceiptManager
|
||||||
|
@ -59,7 +57,6 @@ static SSKEnvironment *sharedSSKEnvironment;
|
||||||
_primaryStorage = primaryStorage;
|
_primaryStorage = primaryStorage;
|
||||||
_blockingManager = blockingManager;
|
_blockingManager = blockingManager;
|
||||||
_identityManager = identityManager;
|
_identityManager = identityManager;
|
||||||
_udManager = udManager;
|
|
||||||
_tsAccountManager = tsAccountManager;
|
_tsAccountManager = tsAccountManager;
|
||||||
_disappearingMessagesJob = disappearingMessagesJob;
|
_disappearingMessagesJob = disappearingMessagesJob;
|
||||||
_readReceiptManager = readReceiptManager;
|
_readReceiptManager = readReceiptManager;
|
||||||
|
|
|
@ -23,9 +23,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection;
|
- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||||
- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection;
|
- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||||
- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection;
|
- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||||
- (nullable PreKeyRecord *)preKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection;
|
|
||||||
- (nullable PreKeyBundle *)preKeyBundleForKey:(NSString *)key inCollection:(NSString *)collection;
|
|
||||||
- (nullable SignedPreKeyRecord *)signedPreKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection;
|
|
||||||
|
|
||||||
- (NSUInteger)numberOfKeysInCollection:(NSString *)collection;
|
- (NSUInteger)numberOfKeysInCollection:(NSString *)collection;
|
||||||
|
|
||||||
|
|
|
@ -65,21 +65,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:[ECKeyPair class]];
|
return [self objectForKey:key inCollection:collection ofExpectedType:[ECKeyPair class]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable PreKeyRecord *)preKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection
|
|
||||||
{
|
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:[PreKeyRecord class]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable PreKeyBundle *)preKeyBundleForKey:(NSString *)key inCollection:(NSString *)collection
|
|
||||||
{
|
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:PreKeyBundle.class];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable SignedPreKeyRecord *)signedPreKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection
|
|
||||||
{
|
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:[SignedPreKeyRecord class]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int)intForKey:(NSString *)key inCollection:(NSString *)collection
|
- (int)intForKey:(NSString *)key inCollection:(NSString *)collection
|
||||||
{
|
{
|
||||||
NSNumber *_Nullable number = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]];
|
NSNumber *_Nullable number = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]];
|
||||||
|
|
|
@ -20,9 +20,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection;
|
- (nullable NSString *)stringForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||||
- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection;
|
- (nullable NSData *)dataForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||||
- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection;
|
- (nullable ECKeyPair *)keyPairForKey:(NSString *)key inCollection:(NSString *)collection;
|
||||||
- (nullable PreKeyRecord *)preKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection;
|
|
||||||
- (nullable PreKeyBundle *)preKeyBundleForKey:(NSString *)key inCollection:(NSString *)collection;
|
|
||||||
- (nullable SignedPreKeyRecord *)signedPreKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -41,21 +41,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:[ECKeyPair class]];
|
return [self objectForKey:key inCollection:collection ofExpectedType:[ECKeyPair class]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable PreKeyRecord *)preKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection
|
|
||||||
{
|
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:[PreKeyRecord class]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable PreKeyBundle *)preKeyBundleForKey:(NSString *)key inCollection:(NSString *)collection
|
|
||||||
{
|
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:PreKeyBundle.class];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable SignedPreKeyRecord *)signedPreKeyRecordForKey:(NSString *)key inCollection:(NSString *)collection
|
|
||||||
{
|
|
||||||
return [self objectForKey:key inCollection:collection ofExpectedType:[SignedPreKeyRecord class]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int)intForKey:(NSString *)key inCollection:(NSString *)collection
|
- (int)intForKey:(NSString *)key inCollection:(NSString *)collection
|
||||||
{
|
{
|
||||||
NSNumber *_Nullable number = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]];
|
NSNumber *_Nullable number = [self objectForKey:key inCollection:collection ofExpectedType:[NSNumber class]];
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import CryptoSwift
|
||||||
|
|
||||||
public final class ClosedGroupSenderKey : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
public final class ClosedGroupSenderKey : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
||||||
public let chainKey: Data
|
public let chainKey: Data
|
|
@ -3,14 +3,4 @@
|
||||||
FOUNDATION_EXPORT double SessionProtocolKitVersionNumber;
|
FOUNDATION_EXPORT double SessionProtocolKitVersionNumber;
|
||||||
FOUNDATION_EXPORT const unsigned char SessionProtocolKitVersionString[];
|
FOUNDATION_EXPORT const unsigned char SessionProtocolKitVersionString[];
|
||||||
|
|
||||||
#import <SessionProtocolKit/AxolotlStore.h>
|
|
||||||
#import <SessionProtocolKit/AxolotlExceptions.h>
|
|
||||||
#import <SessionProtocolKit/ClosedGroupCiphertextMessage.h>
|
|
||||||
#import <SessionProtocolKit/FallbackMessage.h>
|
|
||||||
#import <SessionProtocolKit/IdentityKeyStore.h>
|
|
||||||
#import <SessionProtocolKit/NSData+keyVersionByte.h>
|
|
||||||
#import <SessionProtocolKit/NSData+messagePadding.h>
|
#import <SessionProtocolKit/NSData+messagePadding.h>
|
||||||
#import <SessionProtocolKit/PreKeyBundle.h>
|
|
||||||
#import <SessionProtocolKit/SerializationUtilities.h>
|
|
||||||
#import <SessionProtocolKit/SessionBuilder.h>
|
|
||||||
#import <SessionProtocolKit/SessionCipher.h>
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
//
|
|
||||||
// AxolotlExceptions.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 23/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AxolotlKit_AxolotlExceptions_h
|
|
||||||
#define AxolotlKit_AxolotlExceptions_h
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when the user is:
|
|
||||||
|
|
||||||
1) Sending a message with a PreKeyBundle that contains a different identity key than the previously known one.
|
|
||||||
2) Receiving a new PreKeyWhisperMessage that has a different identity key than the previously known one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *UntrustedIdentityKeyException = @"AxolotlUnstrustedIdentityKeyException";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown thrown when a message is received with an unknown PreKeyID.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *InvalidKeyIdException = @"AxolotlInvalidKeyIdException";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when:
|
|
||||||
|
|
||||||
1) Signature of Prekeys are not correctly signed.
|
|
||||||
2) We received a key type that is not compatible with this version. (All keys should be Curve25519).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *InvalidKeyException = @"AxolotlInvalidKeyException";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when receiving a message with no associated session for decryption.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *NoSessionException = @"AxolotlNoSessionException";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when receiving a malformatted message.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *InvalidMessageException = @"AxolotlInvalidMessageException";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when experiencing issues encrypting/decrypting a message symetrically.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *CipherException = @"AxolotlCipherIssue";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when detecting a message being sent a second time. (Replay attacks/bugs)
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *DuplicateMessageException = @"AxolotlDuplicateMessage";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when receiving a message send with a non-supported version of the TextSecure protocol.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *LegacyMessageException = @"AxolotlLegacyMessageException";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when a client tries to initiate a session with a non-supported version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NSString *InvalidVersionException = @"AxolotlInvalidVersionException";
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,24 +0,0 @@
|
||||||
//
|
|
||||||
// CipherMessage.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 26/10/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, CipherMessageType) {
|
|
||||||
CipherMessageType_Prekey = 0,
|
|
||||||
CipherMessageType_Whisper,
|
|
||||||
CipherMessageType_Fallback = 3,
|
|
||||||
CipherMessageType_ClosedGroupCiphertext = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
@protocol CipherMessage <NSObject>
|
|
||||||
|
|
||||||
- (NSData *)serialized;
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) CipherMessageType cipherMessageType;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,18 +0,0 @@
|
||||||
#import "CipherMessage.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface ClosedGroupCiphertextMessage : NSObject<CipherMessage>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSData *serialized;
|
|
||||||
@property (nonatomic, readonly) NSData *ivAndCiphertext;
|
|
||||||
@property (nonatomic, readonly) NSData *senderPublicKey;
|
|
||||||
@property (nonatomic, readonly) uint32_t keyIndex;
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withIVAndCiphertext:(NSData *)ivAndCiphertext senderPublicKey:(NSData *)senderPublicKey keyIndex:(uint32_t)keyIndex;
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
#import "ClosedGroupCiphertextMessage.h"
|
|
||||||
#import "AxolotlExceptions.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
#import <SessionProtocolKit/SessionProtocolKit-Swift.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@implementation ClosedGroupCiphertextMessage
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withIVAndCiphertext:(NSData *)ivAndCiphertext senderPublicKey:(NSData *)senderPublicKey keyIndex:(uint32_t)keyIndex
|
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
|
||||||
_ivAndCiphertext = ivAndCiphertext;
|
|
||||||
_senderPublicKey = senderPublicKey;
|
|
||||||
_keyIndex = keyIndex;
|
|
||||||
|
|
||||||
SPKProtoClosedGroupCiphertextMessageBuilder *builder = [SPKProtoClosedGroupCiphertextMessage builderWithCiphertext:ivAndCiphertext
|
|
||||||
senderPublicKey:senderPublicKey
|
|
||||||
keyIndex:keyIndex];
|
|
||||||
|
|
||||||
NSError *error;
|
|
||||||
NSData *_Nullable serialized = [builder buildSerializedDataAndReturnError:&error];
|
|
||||||
if (serialized == nil || error != nil) {
|
|
||||||
OWSFailDebug(@"Couldn't serialize proto due to error: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Couldn't serialize proto.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_serialized = serialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized
|
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
|
||||||
NSError *error;
|
|
||||||
SPKProtoClosedGroupCiphertextMessage *_Nullable ciphertextMessage = [SPKProtoClosedGroupCiphertextMessage parseData:serialized error:&error];
|
|
||||||
if (ciphertextMessage == nil || error != nil) {
|
|
||||||
OWSFailDebug(@"Couldn't parse proto due to error: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Couldn't parse proto.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_serialized = serialized;
|
|
||||||
_ivAndCiphertext = ciphertextMessage.ciphertext;
|
|
||||||
_senderPublicKey = ciphertextMessage.senderPublicKey;
|
|
||||||
_keyIndex = ciphertextMessage.keyIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CipherMessageType)cipherMessageType
|
|
||||||
{
|
|
||||||
return CipherMessageType_ClosedGroupCiphertext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,13 +0,0 @@
|
||||||
#import "CipherMessage.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface FallbackMessage : NSObject<CipherMessage>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSData *serialized;
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,18 +0,0 @@
|
||||||
#import "FallbackMessage.h"
|
|
||||||
|
|
||||||
@implementation FallbackMessage
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized
|
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
|
||||||
_serialized = serialized;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CipherMessageType)cipherMessageType
|
|
||||||
{
|
|
||||||
return CipherMessageType_Fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,32 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "WhisperMessage.h"
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface PreKeyWhisperMessage : NSObject <CipherMessage>
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
- (nullable instancetype)initWithData:(NSData *)serialized error:(NSError **)outError;
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withWhisperMessage:(WhisperMessage *)whisperMessage
|
|
||||||
registrationId:(int)registrationId
|
|
||||||
prekeyId:(int)prekeyId
|
|
||||||
signedPrekeyId:(int)signedPrekeyId
|
|
||||||
baseKey:(NSData *)baseKey
|
|
||||||
identityKey:(NSData *)identityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) int registrationId;
|
|
||||||
@property (nonatomic, readonly) int version;
|
|
||||||
@property (nonatomic, readonly) int prekeyID;
|
|
||||||
@property (nonatomic, readonly) int signedPrekeyId;
|
|
||||||
@property (nonatomic, readonly) NSData *baseKey;
|
|
||||||
@property (nonatomic, readonly) NSData *identityKey;
|
|
||||||
@property (nonatomic, readonly) WhisperMessage *message;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,149 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "PreKeyWhisperMessage.h"
|
|
||||||
#import "AxolotlExceptions.h"
|
|
||||||
#import "Constants.h"
|
|
||||||
#import "SerializationUtilities.h"
|
|
||||||
#import <SessionProtocolKit/SessionProtocolKit-Swift.h>
|
|
||||||
#import <SignalCoreKit/SCKExceptionWrapper.h>
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface PreKeyWhisperMessage ()
|
|
||||||
|
|
||||||
@property (nonatomic, readwrite) NSData *identityKey;
|
|
||||||
@property (nonatomic, readwrite) NSData *baseKey;
|
|
||||||
@property (nonatomic, readwrite) NSData *serialized;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
|
|
||||||
@implementation PreKeyWhisperMessage
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withWhisperMessage:(WhisperMessage *)whisperMessage
|
|
||||||
registrationId:(int)registrationId
|
|
||||||
prekeyId:(int)prekeyId
|
|
||||||
signedPrekeyId:(int)signedPrekeyId
|
|
||||||
baseKey:(NSData *)baseKey
|
|
||||||
identityKey:(NSData *)identityKey
|
|
||||||
{
|
|
||||||
OWSAssert(whisperMessage);
|
|
||||||
OWSAssert(baseKey);
|
|
||||||
OWSAssert(identityKey);
|
|
||||||
|
|
||||||
if (self = [super init]) {
|
|
||||||
_registrationId = registrationId;
|
|
||||||
_version = whisperMessage.version;
|
|
||||||
_prekeyID = prekeyId;
|
|
||||||
_signedPrekeyId = signedPrekeyId;
|
|
||||||
_baseKey = baseKey;
|
|
||||||
_identityKey = identityKey;
|
|
||||||
_message = whisperMessage;
|
|
||||||
|
|
||||||
SPKProtoTSProtoPreKeyWhisperMessageBuilder *messageBuilder = [SPKProtoTSProtoPreKeyWhisperMessage builderWithSignedPreKeyID:signedPrekeyId
|
|
||||||
baseKey:baseKey
|
|
||||||
identityKey:identityKey
|
|
||||||
message:whisperMessage.serialized];
|
|
||||||
[messageBuilder setRegistrationID:registrationId];
|
|
||||||
|
|
||||||
if (prekeyId != -1) {
|
|
||||||
[messageBuilder setPreKeyID:prekeyId];
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte versionByte = [SerializationUtilities intsToByteHigh:_version low:CURRENT_VERSION];
|
|
||||||
NSMutableData *serialized = [NSMutableData dataWithBytes:&versionByte length:1];
|
|
||||||
|
|
||||||
NSError *error;
|
|
||||||
NSData *_Nullable messageData = [messageBuilder buildSerializedDataAndReturnError:&error];
|
|
||||||
if (!messageData || error) {
|
|
||||||
OWSFailDebug(@"Could not serialize proto: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Could not serialize proto.");
|
|
||||||
}
|
|
||||||
[serialized appendData:messageData];
|
|
||||||
|
|
||||||
_serialized = [serialized copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable instancetype)initWithData:(NSData *)serialized error:(NSError **)outError
|
|
||||||
{
|
|
||||||
@try {
|
|
||||||
self = [self init_throws_withData:serialized];
|
|
||||||
return self;
|
|
||||||
} @catch (NSException *exception) {
|
|
||||||
*outError = SCKExceptionWrapperErrorMake(exception);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized
|
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
|
||||||
if (serialized.length < 1) {
|
|
||||||
OWSFailDebug(@"Empty data");
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Empty data");
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte version;
|
|
||||||
[serialized getBytes:&version length:1];
|
|
||||||
_version = [SerializationUtilities highBitsToIntFromByte:version];
|
|
||||||
|
|
||||||
if (_version > CURRENT_VERSION && _version < MINIMUM_SUPPORTED_VERSION) {
|
|
||||||
@throw [NSException exceptionWithName:InvalidVersionException
|
|
||||||
reason:@"Unknown version"
|
|
||||||
userInfo:@{ @"version" : [NSNumber numberWithInt:_version] }];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSUInteger messageDataLength;
|
|
||||||
ows_sub_overflow(serialized.length, 1, &messageDataLength);
|
|
||||||
NSData *messageData = [serialized subdataWithRange:NSMakeRange(1, messageDataLength)];
|
|
||||||
|
|
||||||
NSError *error;
|
|
||||||
SPKProtoTSProtoPreKeyWhisperMessage *_Nullable preKeyWhisperMessage =
|
|
||||||
[SPKProtoTSProtoPreKeyWhisperMessage parseData:messageData error:&error];
|
|
||||||
if (!preKeyWhisperMessage || error) {
|
|
||||||
OWSFailDebug(@"Could not parse proto: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Could not parse proto.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_serialized = serialized;
|
|
||||||
_registrationId = preKeyWhisperMessage.registrationID;
|
|
||||||
|
|
||||||
// This method is called when decrypting a received PreKeyMessage, but to be symmetrical with
|
|
||||||
// encrypting a PreKeyWhisperMessage before sending, we use "-1" to indicate *no* unsigned prekey was
|
|
||||||
// included.
|
|
||||||
_prekeyID = preKeyWhisperMessage.hasPreKeyID ? preKeyWhisperMessage.preKeyID : -1;
|
|
||||||
_signedPrekeyId = preKeyWhisperMessage.signedPreKeyID;
|
|
||||||
_baseKey = preKeyWhisperMessage.baseKey;
|
|
||||||
_identityKey = preKeyWhisperMessage.identityKey;
|
|
||||||
_message = [[WhisperMessage alloc] init_throws_withData:preKeyWhisperMessage.message];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CipherMessageType)cipherMessageType {
|
|
||||||
return CipherMessageType_Prekey;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Logging
|
|
||||||
|
|
||||||
+ (NSString *)logTag
|
|
||||||
{
|
|
||||||
return [NSString stringWithFormat:@"[%@]", self.class];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)logTag
|
|
||||||
{
|
|
||||||
return self.class.logTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,40 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "CipherMessage.h"
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@class ECKeyPair;
|
|
||||||
|
|
||||||
@interface WhisperMessage : NSObject <CipherMessage>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) int version;
|
|
||||||
@property (nonatomic, readonly) NSData *senderRatchetKey;
|
|
||||||
@property (nonatomic, readonly) int previousCounter;
|
|
||||||
@property (nonatomic, readonly) int counter;
|
|
||||||
@property (nonatomic, readonly) NSData *cipherText;
|
|
||||||
@property (nonatomic, readonly) NSData *serialized;
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
- (nullable instancetype)initWithData:(NSData *)serialized error:(NSError **)outError;
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withVersion:(int)version
|
|
||||||
macKey:(NSData *)macKey
|
|
||||||
senderRatchetKey:(NSData *)senderRatchetKey
|
|
||||||
counter:(int)counter
|
|
||||||
previousCounter:(int)previousCounter
|
|
||||||
cipherText:(NSData *)cipherText
|
|
||||||
senderIdentityKey:(NSData *)senderIdentityKey
|
|
||||||
receiverIdentityKey:(NSData *)receiverIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
- (void)throws_verifyMacWithVersion:(int)messageVersion
|
|
||||||
senderIdentityKey:(NSData *)senderIdentityKey
|
|
||||||
receiverIdentityKey:(NSData *)receiverIdentityKey
|
|
||||||
macKey:(NSData *)macKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,202 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "WhisperMessage.h"
|
|
||||||
#import "AxolotlExceptions.h"
|
|
||||||
#import "Constants.h"
|
|
||||||
#import "NSData+keyVersionByte.h"
|
|
||||||
#import "SerializationUtilities.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
#import <SessionProtocolKit/SessionProtocolKit-Swift.h>
|
|
||||||
#import <SignalCoreKit/NSData+OWS.h>
|
|
||||||
#import <SignalCoreKit/SCKExceptionWrapper.h>
|
|
||||||
#import <SignalCoreKit/SignalCoreKit-Swift.h>
|
|
||||||
#import <SessionProtocolKit/SessionProtocolKit-Swift.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
#define VERSION_LENGTH 1
|
|
||||||
|
|
||||||
@implementation WhisperMessage
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withVersion:(int)version
|
|
||||||
macKey:(NSData *)macKey
|
|
||||||
senderRatchetKey:(NSData *)senderRatchetKey
|
|
||||||
counter:(int)counter
|
|
||||||
previousCounter:(int)previousCounter
|
|
||||||
cipherText:(NSData *)cipherText
|
|
||||||
senderIdentityKey:(NSData *)senderIdentityKey
|
|
||||||
receiverIdentityKey:(NSData *)receiverIdentityKey
|
|
||||||
{
|
|
||||||
OWSAssert(macKey);
|
|
||||||
OWSAssert(senderRatchetKey);
|
|
||||||
OWSAssert(cipherText);
|
|
||||||
OWSAssert(cipherText);
|
|
||||||
OWSAssert(senderIdentityKey);
|
|
||||||
OWSAssert(receiverIdentityKey);
|
|
||||||
|
|
||||||
if (self = [super init]) {
|
|
||||||
Byte versionByte = [SerializationUtilities intsToByteHigh:version low:CURRENT_VERSION];
|
|
||||||
NSMutableData *serialized = [NSMutableData dataWithBytes:&versionByte length:1];
|
|
||||||
|
|
||||||
SPKProtoTSProtoWhisperMessageBuilder *messageBuilder = [SPKProtoTSProtoWhisperMessage builderWithRatchetKey:senderRatchetKey
|
|
||||||
counter:counter
|
|
||||||
ciphertext:cipherText];
|
|
||||||
[messageBuilder setPreviousCounter:previousCounter];
|
|
||||||
NSError *error;
|
|
||||||
NSData *_Nullable messageData = [messageBuilder buildSerializedDataAndReturnError:&error];
|
|
||||||
if (!messageData || error) {
|
|
||||||
OWSFailDebug(@"Could not serialize proto: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Could not serialize proto.");
|
|
||||||
}
|
|
||||||
[serialized appendData:messageData];
|
|
||||||
|
|
||||||
NSData *mac = [SerializationUtilities throws_macWithVersion:version
|
|
||||||
identityKey:[senderIdentityKey prependKeyType]
|
|
||||||
receiverIdentityKey:[receiverIdentityKey prependKeyType]
|
|
||||||
macKey:macKey
|
|
||||||
serialized:serialized];
|
|
||||||
|
|
||||||
[serialized appendData:mac];
|
|
||||||
|
|
||||||
_version = version;
|
|
||||||
_senderRatchetKey = senderRatchetKey;
|
|
||||||
_previousCounter = previousCounter;
|
|
||||||
_counter = counter;
|
|
||||||
_cipherText = cipherText;
|
|
||||||
_serialized = [serialized copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable instancetype)initWithData:(NSData *)serialized error:(NSError **)outError
|
|
||||||
{
|
|
||||||
@try {
|
|
||||||
self = [self init_throws_withData:serialized];
|
|
||||||
return self;
|
|
||||||
} @catch (NSException *exception) {
|
|
||||||
*outError = SCKExceptionWrapperErrorMake(exception);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withData:(NSData *)serialized
|
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
|
||||||
if (serialized.length <= (VERSION_LENGTH + MAC_LENGTH)) {
|
|
||||||
@throw [NSException exceptionWithName:InvalidMessageException
|
|
||||||
reason:@"Message size is too short to have content"
|
|
||||||
userInfo:@{}];
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte version;
|
|
||||||
[serialized getBytes:&version length:VERSION_LENGTH];
|
|
||||||
|
|
||||||
NSUInteger messageAndMacLength;
|
|
||||||
ows_sub_overflow(serialized.length, VERSION_LENGTH, &messageAndMacLength);
|
|
||||||
NSData *messageAndMac = [serialized subdataWithRange:NSMakeRange(VERSION_LENGTH, messageAndMacLength)];
|
|
||||||
|
|
||||||
NSUInteger messageLength;
|
|
||||||
ows_sub_overflow(messageAndMac.length, MAC_LENGTH, &messageLength);
|
|
||||||
NSData *messageData = [messageAndMac subdataWithRange:NSMakeRange(0, messageLength)];
|
|
||||||
|
|
||||||
if ([SerializationUtilities highBitsToIntFromByte:version] < MINIMUM_SUPPORTED_VERSION) {
|
|
||||||
@throw [NSException
|
|
||||||
exceptionWithName:LegacyMessageException
|
|
||||||
reason:@"Message was sent with an unsupported version of the TextSecure protocol."
|
|
||||||
userInfo:@{}];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([SerializationUtilities highBitsToIntFromByte:version] > CURRENT_VERSION) {
|
|
||||||
@throw [NSException exceptionWithName:InvalidMessageException
|
|
||||||
reason:@"Unknown Version"
|
|
||||||
userInfo:@{
|
|
||||||
@"Version" : [NSNumber
|
|
||||||
numberWithChar:[SerializationUtilities highBitsToIntFromByte:version]]
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSError *error;
|
|
||||||
SPKProtoTSProtoWhisperMessage *_Nullable whisperMessage =
|
|
||||||
[SPKProtoTSProtoWhisperMessage parseData:messageData error:&error];
|
|
||||||
if (!whisperMessage || error) {
|
|
||||||
OWSFailDebug(@"Could not parse proto: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Could not parse proto.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_serialized = serialized;
|
|
||||||
_senderRatchetKey = [whisperMessage.ratchetKey throws_removeKeyType];
|
|
||||||
_version = [SerializationUtilities highBitsToIntFromByte:version];
|
|
||||||
_counter = whisperMessage.counter;
|
|
||||||
_previousCounter = whisperMessage.previousCounter;
|
|
||||||
_cipherText = whisperMessage.ciphertext;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)throws_verifyMacWithVersion:(int)messageVersion
|
|
||||||
senderIdentityKey:(NSData *)senderIdentityKey
|
|
||||||
receiverIdentityKey:(NSData *)receiverIdentityKey
|
|
||||||
macKey:(NSData *)macKey
|
|
||||||
{
|
|
||||||
OWSAssert(senderIdentityKey);
|
|
||||||
OWSAssert(receiverIdentityKey);
|
|
||||||
OWSAssert(macKey);
|
|
||||||
|
|
||||||
OWSDataParser *dataParser = [[OWSDataParser alloc] initWithData:self.serialized];
|
|
||||||
NSError *error;
|
|
||||||
|
|
||||||
NSUInteger messageLength;
|
|
||||||
if (__builtin_sub_overflow(self.serialized.length, MAC_LENGTH, &messageLength)) {
|
|
||||||
OWSFailDebug(@"Data too short");
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Data too short");
|
|
||||||
}
|
|
||||||
NSData *_Nullable data = [dataParser nextDataWithLength:messageLength
|
|
||||||
name:@"message data"
|
|
||||||
error:&error];
|
|
||||||
if (!data || error) {
|
|
||||||
OWSFailDebug(@"Could not parse data: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Could not parse data.");
|
|
||||||
}
|
|
||||||
NSData *_Nullable theirMac = [dataParser nextDataWithLength:MAC_LENGTH
|
|
||||||
name:@"mac data"
|
|
||||||
error:&error];
|
|
||||||
if (!theirMac || error) {
|
|
||||||
OWSFailDebug(@"Could not parse their mac: %@.", error);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Could not parse their mac.");
|
|
||||||
}
|
|
||||||
|
|
||||||
NSData *ourMac = [SerializationUtilities throws_macWithVersion:messageVersion
|
|
||||||
identityKey:[senderIdentityKey prependKeyType]
|
|
||||||
receiverIdentityKey:[receiverIdentityKey prependKeyType]
|
|
||||||
macKey:macKey
|
|
||||||
serialized:data];
|
|
||||||
|
|
||||||
if (![theirMac ows_constantTimeIsEqualToData:ourMac]) {
|
|
||||||
OWSFailDebug(@"Bad Mac! Their Mac: %@ Our Mac: %@", theirMac, ourMac);
|
|
||||||
OWSRaiseException(InvalidMessageException, @"Bad Mac!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CipherMessageType)cipherMessageType {
|
|
||||||
return CipherMessageType_Whisper;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Logging
|
|
||||||
|
|
||||||
+ (NSString *)logTag
|
|
||||||
{
|
|
||||||
return [NSString stringWithFormat:@"[%@]", self.class];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)logTag
|
|
||||||
{
|
|
||||||
return self.class.logTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,15 +0,0 @@
|
||||||
//
|
|
||||||
// Constants.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 14/10/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AxolotlKit_Constants_h
|
|
||||||
#define AxolotlKit_Constants_h
|
|
||||||
|
|
||||||
#define MINIMUM_SUPPORTED_VERSION 3
|
|
||||||
#define CURRENT_VERSION 3
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,41 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface AES_CBC : NSObject
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypts with AES in CBC mode
|
|
||||||
*
|
|
||||||
* @param data data to encrypt
|
|
||||||
* @param key AES key
|
|
||||||
* @param iv Initialization vector for CBC
|
|
||||||
*
|
|
||||||
* @return ciphertext
|
|
||||||
*/
|
|
||||||
|
|
||||||
+ (NSData *)throws_encryptCBCMode:(NSData *)data
|
|
||||||
withKey:(NSData *)key
|
|
||||||
withIV:(NSData *)iv NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypts with AES in CBC mode
|
|
||||||
*
|
|
||||||
* @param data data to decrypt
|
|
||||||
* @param key AES key
|
|
||||||
* @param iv Initialization vector for CBC
|
|
||||||
*
|
|
||||||
* @return plaintext
|
|
||||||
*/
|
|
||||||
|
|
||||||
+ (NSData *)throws_decryptCBCMode:(NSData *)data
|
|
||||||
withKey:(NSData *)key
|
|
||||||
withIV:(NSData *)iv NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,105 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "AES-CBC.h"
|
|
||||||
#import "AxolotlExceptions.h"
|
|
||||||
#import "MessageKeys.h"
|
|
||||||
#import <CommonCrypto/CommonCryptor.h>
|
|
||||||
#import <CommonCrypto/CommonHMAC.h>
|
|
||||||
#import <Security/Security.h>
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@implementation AES_CBC
|
|
||||||
|
|
||||||
#pragma mark AESCBC Mode
|
|
||||||
|
|
||||||
+ (NSData *)throws_encryptCBCMode:(NSData *)data withKey:(NSData *)key withIV:(NSData *)iv
|
|
||||||
{
|
|
||||||
if (!data) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"Missing data to encrypt." userInfo:nil];
|
|
||||||
}
|
|
||||||
if (data.length >= SIZE_MAX - kCCBlockSizeAES128) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"Oversize data." userInfo:nil];
|
|
||||||
}
|
|
||||||
if (key.length != 32) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"AES key should be 256 bits." userInfo:nil];
|
|
||||||
}
|
|
||||||
if (iv.length != 16) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"AES-CBC IV should be 128 bits." userInfo:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t bufferSize;
|
|
||||||
ows_add_overflow(data.length, kCCBlockSizeAES128, &bufferSize);
|
|
||||||
NSMutableData *_Nullable bufferData = [NSMutableData dataWithLength:bufferSize];
|
|
||||||
OWSAssert(bufferData != nil);
|
|
||||||
|
|
||||||
size_t bytesEncrypted = 0;
|
|
||||||
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
|
|
||||||
kCCAlgorithmAES128,
|
|
||||||
kCCOptionPKCS7Padding,
|
|
||||||
[key bytes],
|
|
||||||
[key length],
|
|
||||||
[iv bytes],
|
|
||||||
[data bytes],
|
|
||||||
[data length],
|
|
||||||
bufferData.mutableBytes,
|
|
||||||
bufferSize,
|
|
||||||
&bytesEncrypted);
|
|
||||||
|
|
||||||
if (cryptStatus == kCCSuccess) {
|
|
||||||
return [bufferData subdataWithRange:NSMakeRange(0, bytesEncrypted)];
|
|
||||||
} else {
|
|
||||||
@throw [NSException exceptionWithName:CipherException
|
|
||||||
reason:@"We encountered an issue while encrypting."
|
|
||||||
userInfo:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (NSData *)throws_decryptCBCMode:(NSData *)data withKey:(NSData *)key withIV:(NSData *)iv
|
|
||||||
{
|
|
||||||
if (!data) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"Missing data to decrypt." userInfo:nil];
|
|
||||||
}
|
|
||||||
if (data.length >= SIZE_MAX - kCCBlockSizeAES128) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"Oversize data." userInfo:nil];
|
|
||||||
}
|
|
||||||
if (key.length != 32) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"AES key should be 256 bits." userInfo:nil];
|
|
||||||
}
|
|
||||||
if (iv.length != 16) {
|
|
||||||
@throw [NSException exceptionWithName:CipherException reason:@"AES-CBC IV should be 128 bits." userInfo:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t bufferSize;
|
|
||||||
ows_add_overflow(data.length, kCCBlockSizeAES128, &bufferSize);
|
|
||||||
NSMutableData *_Nullable bufferData = [NSMutableData dataWithLength:bufferSize];
|
|
||||||
OWSAssert(bufferData != nil);
|
|
||||||
|
|
||||||
size_t bytesDecrypted = 0;
|
|
||||||
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
|
|
||||||
kCCAlgorithmAES128,
|
|
||||||
kCCOptionPKCS7Padding,
|
|
||||||
[key bytes],
|
|
||||||
[key length],
|
|
||||||
[iv bytes],
|
|
||||||
[data bytes],
|
|
||||||
[data length],
|
|
||||||
bufferData.mutableBytes,
|
|
||||||
bufferSize,
|
|
||||||
&bytesDecrypted);
|
|
||||||
|
|
||||||
if (cryptStatus == kCCSuccess) {
|
|
||||||
return [bufferData subdataWithRange:NSMakeRange(0, bytesDecrypted)];
|
|
||||||
} else {
|
|
||||||
@throw [NSException exceptionWithName:CipherException
|
|
||||||
reason:@"We encountered an issue while decrypting."
|
|
||||||
userInfo:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,51 +0,0 @@
|
||||||
import CryptoSwift
|
|
||||||
import Curve25519Kit
|
|
||||||
import SessionUtilitiesKit
|
|
||||||
|
|
||||||
/// A fallback session cipher which uses the the recipient's public key to encrypt data.
|
|
||||||
@objc public final class FallBackSessionCipher : NSObject {
|
|
||||||
/// The hex encoded public key of the recipient.
|
|
||||||
private let recipientPublicKey: String
|
|
||||||
private let privateKey: Data?
|
|
||||||
private let ivSize: Int32 = 16
|
|
||||||
|
|
||||||
private lazy var recipientPublicKeyAsData: Data = {
|
|
||||||
var recipientPublicKey = self.recipientPublicKey
|
|
||||||
if recipientPublicKey.count == 66 && recipientPublicKey.hasPrefix("05") {
|
|
||||||
let index = recipientPublicKey.index(recipientPublicKey.startIndex, offsetBy: 2)
|
|
||||||
recipientPublicKey = recipientPublicKey.substring(from: index)
|
|
||||||
}
|
|
||||||
return Data(hex: recipientPublicKey)
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var symmetricKey: Data? = {
|
|
||||||
guard let privateKey = privateKey else { return nil }
|
|
||||||
return try? Curve25519.generateSharedSecret(fromPublicKey: recipientPublicKeyAsData, privateKey: privateKey)
|
|
||||||
}()
|
|
||||||
|
|
||||||
@objc public init(recipientPublicKey: String, privateKey: Data?) {
|
|
||||||
self.recipientPublicKey = recipientPublicKey
|
|
||||||
self.privateKey = privateKey
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func encrypt(_ plaintext: Data) -> Data? {
|
|
||||||
guard let symmetricKey = symmetricKey else { return nil }
|
|
||||||
do {
|
|
||||||
return try DiffieHellman.encrypt(plaintext, using: symmetricKey)
|
|
||||||
} catch {
|
|
||||||
SNLog("Couldn't encrypt message using fallback session cipher due to error: \(error).")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func decrypt(_ ivAndCiphertext: Data) -> Data? {
|
|
||||||
guard let symmetricKey = symmetricKey else { return nil }
|
|
||||||
do {
|
|
||||||
return try DiffieHellman.decrypt(ivAndCiphertext, using: symmetricKey)
|
|
||||||
} catch {
|
|
||||||
SNLog("Couldn't decrypt message using fallback session cipher due to error: \(error).")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
import Foundation
|
|
||||||
|
|
||||||
@objc(SNSessionCipher)
|
|
||||||
public final class LokiSessionCipher : SessionCipher {
|
|
||||||
private let sessionResetImplementation: SessionRestorationProtocol?
|
|
||||||
private let sessionStore: SessionStore
|
|
||||||
private let preKeyStore: PreKeyStore
|
|
||||||
private let recipientID: String
|
|
||||||
private let deviceID: Int32
|
|
||||||
|
|
||||||
@objc public static let newSessionAdoptedNotification = "LKNewSessionAdoptedNotification"
|
|
||||||
@objc public static let contactKey = "LKContactKey"
|
|
||||||
|
|
||||||
@objc public init(sessionResetImplementation: SessionRestorationProtocol, sessionStore: SessionStore, preKeyStore: PreKeyStore, signedPreKeyStore: SignedPreKeyStore, identityKeyStore: IdentityKeyStore, recipientID: String, deviceID: Int32) {
|
|
||||||
self.sessionResetImplementation = sessionResetImplementation
|
|
||||||
self.sessionStore = sessionStore
|
|
||||||
self.preKeyStore = preKeyStore
|
|
||||||
self.recipientID = recipientID
|
|
||||||
self.deviceID = deviceID
|
|
||||||
super.init(sessionStore: sessionStore, preKeyStore: preKeyStore, signedPreKeyStore: signedPreKeyStore, identityKeyStore: identityKeyStore, recipientId: recipientID, deviceId: deviceID)
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, unavailable)
|
|
||||||
override convenience private init(axolotlStore sessionStore: AxolotlStore, recipientId: String, deviceId: Int32) {
|
|
||||||
self.init(sessionStore: sessionStore, preKeyStore: sessionStore, signedPreKeyStore: sessionStore, identityKeyStore: sessionStore, recipientId: recipientId, deviceId: deviceId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override private init(sessionStore: SessionStore, preKeyStore: PreKeyStore, signedPreKeyStore: SignedPreKeyStore, identityKeyStore: IdentityKeyStore, recipientId: String, deviceId: Int32) {
|
|
||||||
self.sessionResetImplementation = nil
|
|
||||||
self.sessionStore = sessionStore
|
|
||||||
self.preKeyStore = preKeyStore
|
|
||||||
self.recipientID = recipientId
|
|
||||||
self.deviceID = deviceId
|
|
||||||
super.init(sessionStore: sessionStore, preKeyStore: preKeyStore, signedPreKeyStore: signedPreKeyStore, identityKeyStore: identityKeyStore, recipientId: recipientId, deviceId: deviceId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func decrypt(_ whisperMessage: CipherMessage, protocolContext: Any?) throws -> Data {
|
|
||||||
// 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, preKeyWhisperMessage: whisperMessage as! PreKeyWhisperMessage, using: protocolContext!)
|
|
||||||
}
|
|
||||||
let plainText = try super.decrypt(whisperMessage, protocolContext: protocolContext)
|
|
||||||
handleSessionReset(for: whisperMessage, previousState: currentState, protocolContext: protocolContext!)
|
|
||||||
return plainText
|
|
||||||
}
|
|
||||||
|
|
||||||
private func getCurrentState(protocolContext: Any?) -> SessionState? {
|
|
||||||
let record = sessionStore.loadSession(recipientID, deviceId: deviceID, protocolContext: protocolContext)
|
|
||||||
return record.isFresh() ? nil : record.sessionState()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleSessionReset(for whisperMessage: CipherMessage, previousState: SessionState?, protocolContext: Any) {
|
|
||||||
// Don't bother doing anything if we didn't have a session before
|
|
||||||
guard let previousState = previousState else { return }
|
|
||||||
let sessionResetStatus = sessionResetImplementation?.getSessionRestorationStatus(for: recipientID) ?? SessionRestorationStatus.none
|
|
||||||
// Bail early if no session reset is in progress
|
|
||||||
guard sessionResetStatus != .none else { return }
|
|
||||||
let currentState = getCurrentState(protocolContext: protocolContext)
|
|
||||||
// Check if our previous state and our current state differ
|
|
||||||
if (currentState == nil || currentState!.aliceBaseKey != previousState.aliceBaseKey) {
|
|
||||||
if sessionResetStatus == .requestReceived {
|
|
||||||
// The other user used an old session to contact us. Wait for them to use a new one
|
|
||||||
restoreSession(previousState, protocolContext: protocolContext)
|
|
||||||
} else {
|
|
||||||
// Our session reset went through successfully.
|
|
||||||
// We initiated a session reset and got a different session back from the user.
|
|
||||||
deleteAllSessions(except: currentState, protocolContext: protocolContext)
|
|
||||||
notifySessionAdopted(protocolContext)
|
|
||||||
}
|
|
||||||
} else if sessionResetStatus == .requestReceived {
|
|
||||||
// Our session reset went through successfully.
|
|
||||||
// We got a message with the same session from the other user.
|
|
||||||
deleteAllSessions(except: previousState, protocolContext: protocolContext)
|
|
||||||
notifySessionAdopted(protocolContext)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func notifySessionAdopted(_ protocolContext: Any) {
|
|
||||||
self.sessionResetImplementation?.handleNewSessionAdopted(for: recipientID, using: protocolContext)
|
|
||||||
NotificationCenter.default.post(name: NSNotification.Name(rawValue: LokiSessionCipher.newSessionAdoptedNotification), object: nil, userInfo: [ LokiSessionCipher.contactKey : recipientID ])
|
|
||||||
}
|
|
||||||
|
|
||||||
private func deleteAllSessions(except state: SessionState?, protocolContext: Any?) {
|
|
||||||
let record = sessionStore.loadSession(recipientID, deviceId: deviceID, protocolContext: protocolContext)
|
|
||||||
record.removePreviousSessionStates()
|
|
||||||
let newState = state ?? SessionState()
|
|
||||||
record.setState(newState)
|
|
||||||
sessionStore.storeSession(recipientID, deviceId: deviceID, session: record, protocolContext: protocolContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func restoreSession(_ state: SessionState, protocolContext: Any?) {
|
|
||||||
let record = sessionStore.loadSession(recipientID, deviceId: deviceID, protocolContext: protocolContext)
|
|
||||||
// Remove the state from previous session states
|
|
||||||
record.previousSessionStates()?.enumerateObjects(options: .reverse) { obj, index, stop in
|
|
||||||
guard let obj = obj as? SessionState, state.aliceBaseKey == obj.aliceBaseKey else { return }
|
|
||||||
record.previousSessionStates()?.removeObject(at: index)
|
|
||||||
stop.pointee = true
|
|
||||||
}
|
|
||||||
// Promote so the previous state gets archived
|
|
||||||
record.promoteState(state)
|
|
||||||
sessionStore.storeSession(recipientID, deviceId: deviceID, session: record, protocolContext: protocolContext)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
//
|
|
||||||
// AxolotlKeyFetch.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 21/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@interface PreKeyBundle : NSObject <NSSecureCoding>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSData *identityKey;
|
|
||||||
@property (nonatomic, readonly) int registrationId;
|
|
||||||
@property (nonatomic, readonly) int deviceId;
|
|
||||||
@property (nonatomic, readonly) NSData *signedPreKeyPublic;
|
|
||||||
@property (nonatomic, readonly) NSData *preKeyPublic;
|
|
||||||
@property (nonatomic, readonly) int preKeyId;
|
|
||||||
@property (nonatomic, readonly) int signedPreKeyId;
|
|
||||||
@property (nonatomic, readonly) NSData *signedPreKeySignature;
|
|
||||||
|
|
||||||
- (nullable instancetype)initWithRegistrationId:(int)registrationId
|
|
||||||
deviceId:(int)deviceId
|
|
||||||
preKeyId:(int)preKeyId
|
|
||||||
preKeyPublic:(NSData *)preKeyPublic
|
|
||||||
signedPreKeyPublic:(NSData *)signedPreKeyPublic
|
|
||||||
signedPreKeyId:(int)signedPreKeyId
|
|
||||||
signedPreKeySignature:(NSData *)signedPreKeySignature
|
|
||||||
identityKey:(NSData *)identityKey;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,106 +0,0 @@
|
||||||
//
|
|
||||||
// AxolotlKeyFetch.m
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 21/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "PreKeyBundle.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
|
|
||||||
static NSString* const kCoderPKBIdentityKey = @"kCoderPKBIdentityKey";
|
|
||||||
static NSString* const kCoderPKBregistrationId = @"kCoderPKBregistrationId";
|
|
||||||
static NSString* const kCoderPKBdeviceId = @"kCoderPKBdeviceId";
|
|
||||||
static NSString* const kCoderPKBsignedPreKeyPublic = @"kCoderPKBsignedPreKeyPublic";
|
|
||||||
static NSString* const kCoderPKBpreKeyPublic = @"kCoderPKBpreKeyPublic";
|
|
||||||
static NSString* const kCoderPKBpreKeyId = @"kCoderPKBpreKeyId";
|
|
||||||
static NSString* const kCoderPKBsignedPreKeyId = @"kCoderPKBsignedPreKeyId";
|
|
||||||
static NSString* const kCoderPKBsignedPreKeySignature = @"kCoderPKBsignedPreKeySignature";
|
|
||||||
|
|
||||||
@implementation PreKeyBundle
|
|
||||||
|
|
||||||
- (nullable instancetype)initWithRegistrationId:(int)registrationId
|
|
||||||
deviceId:(int)deviceId
|
|
||||||
preKeyId:(int)preKeyId
|
|
||||||
preKeyPublic:(NSData *)preKeyPublic
|
|
||||||
signedPreKeyPublic:(NSData *)signedPreKeyPublic
|
|
||||||
signedPreKeyId:(int)signedPreKeyId
|
|
||||||
signedPreKeySignature:(NSData *)signedPreKeySignature
|
|
||||||
identityKey:(NSData *)identityKey
|
|
||||||
{
|
|
||||||
if (preKeyPublic && preKeyPublic.length != 33) {
|
|
||||||
OWSFailDebug(@"preKeyPublic && preKeyPublic.length != 33");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
if (signedPreKeyPublic.length != 33) {
|
|
||||||
OWSFailDebug(@"signedPreKeyPublic.length != 33");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
if (!signedPreKeySignature) {
|
|
||||||
OWSFailDebug(@"!signedPreKeySignature");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
if (identityKey.length != 33) {
|
|
||||||
OWSFailDebug(@"identityKey.length != 33");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_identityKey = identityKey;
|
|
||||||
_registrationId = registrationId;
|
|
||||||
_deviceId = deviceId;
|
|
||||||
_preKeyPublic = preKeyPublic;
|
|
||||||
_preKeyId = preKeyId;
|
|
||||||
_signedPreKeyPublic = signedPreKeyPublic;
|
|
||||||
_signedPreKeyId = signedPreKeyId;
|
|
||||||
_signedPreKeySignature = signedPreKeySignature;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
|
||||||
int registrationId = [aDecoder decodeIntForKey:kCoderPKBregistrationId];
|
|
||||||
int deviceId = [aDecoder decodeIntForKey:kCoderPKBdeviceId];
|
|
||||||
int preKeyId = [aDecoder decodeIntForKey:kCoderPKBpreKeyId];
|
|
||||||
int signedPreKeyId = [aDecoder decodeIntForKey:kCoderPKBsignedPreKeyId];
|
|
||||||
|
|
||||||
NSData *preKeyPublic = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderPKBpreKeyPublic];
|
|
||||||
NSData *signedPreKeyPublic = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderPKBsignedPreKeyPublic];
|
|
||||||
NSData *signedPreKeySignature = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderPKBsignedPreKeySignature];
|
|
||||||
NSData *identityKey = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderPKBIdentityKey];
|
|
||||||
|
|
||||||
|
|
||||||
self = [self initWithRegistrationId:registrationId
|
|
||||||
deviceId:deviceId
|
|
||||||
preKeyId:preKeyId
|
|
||||||
preKeyPublic:preKeyPublic
|
|
||||||
signedPreKeyPublic:signedPreKeyPublic
|
|
||||||
signedPreKeyId:signedPreKeyId
|
|
||||||
signedPreKeySignature:signedPreKeySignature
|
|
||||||
identityKey:identityKey];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder{
|
|
||||||
[aCoder encodeInt:_registrationId forKey:kCoderPKBregistrationId];
|
|
||||||
[aCoder encodeInt:_deviceId forKey:kCoderPKBdeviceId];
|
|
||||||
[aCoder encodeInt:_preKeyId forKey:kCoderPKBpreKeyId];
|
|
||||||
[aCoder encodeInt:_signedPreKeyId forKey:kCoderPKBsignedPreKeyId];
|
|
||||||
|
|
||||||
[aCoder encodeObject:_preKeyPublic forKey:kCoderPKBpreKeyPublic];
|
|
||||||
[aCoder encodeObject:_signedPreKeyPublic forKey:kCoderPKBsignedPreKeyPublic];
|
|
||||||
[aCoder encodeObject:_signedPreKeySignature forKey:kCoderPKBsignedPreKeySignature];
|
|
||||||
[aCoder encodeObject:_identityKey forKey:kCoderPKBIdentityKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
+(BOOL)supportsSecureCoding{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,16 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
|
|
||||||
@interface PreKeyRecord : NSObject <NSSecureCoding>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) int Id;
|
|
||||||
@property (nonatomic, readonly) ECKeyPair *keyPair;
|
|
||||||
|
|
||||||
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair*)keyPair;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,45 +0,0 @@
|
||||||
//
|
|
||||||
// PreKeyRecord.m
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 26/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "PreKeyRecord.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
static NSString* const kCoderPreKeyId = @"kCoderPreKeyId";
|
|
||||||
static NSString* const kCoderPreKeyPair = @"kCoderPreKeyPair";
|
|
||||||
|
|
||||||
@implementation PreKeyRecord
|
|
||||||
|
|
||||||
+ (BOOL)supportsSecureCoding{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair*)keyPair{
|
|
||||||
OWSAssert(keyPair);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_Id = identifier;
|
|
||||||
_keyPair = keyPair;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
|
||||||
return [self initWithId:[aDecoder decodeIntForKey:kCoderPreKeyId] keyPair:[aDecoder decodeObjectOfClass:[ECKeyPair class] forKey:kCoderPreKeyPair]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder{
|
|
||||||
[aCoder encodeInteger:_Id forKey:kCoderPreKeyId];
|
|
||||||
[aCoder encodeObject:_keyPair forKey:kCoderPreKeyPair];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,21 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import "PreKeyRecord.h"
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
|
|
||||||
@interface SignedPreKeyRecord : PreKeyRecord <NSSecureCoding>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSData *signature;
|
|
||||||
@property (nonatomic, readonly) NSDate *generatedAt;
|
|
||||||
// Defaults to NO. Should only be set after the service accepts this record.
|
|
||||||
@property (nonatomic, readonly) BOOL wasAcceptedByService;
|
|
||||||
|
|
||||||
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair *)keyPair signature:(NSData*)signature generatedAt:(NSDate*)generatedAt;
|
|
||||||
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair *)keyPair NS_UNAVAILABLE;
|
|
||||||
|
|
||||||
- (void)markAsAcceptedByService;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,78 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "SignedPrekeyRecord.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
static NSString* const kCoderPreKeyId = @"kCoderPreKeyId";
|
|
||||||
static NSString* const kCoderPreKeyPair = @"kCoderPreKeyPair";
|
|
||||||
static NSString* const kCoderPreKeyDate = @"kCoderPreKeyDate";
|
|
||||||
static NSString* const kCoderPreKeySignature = @"kCoderPreKeySignature";
|
|
||||||
static NSString *const kCoderPreKeyWasAcceptedByService = @"kCoderPreKeyWasAcceptedByService";
|
|
||||||
|
|
||||||
@implementation SignedPreKeyRecord
|
|
||||||
|
|
||||||
+ (BOOL)supportsSecureCoding{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithId:(int)identifier
|
|
||||||
keyPair:(ECKeyPair *)keyPair
|
|
||||||
signature:(NSData *)signature
|
|
||||||
generatedAt:(NSDate *)generatedAt
|
|
||||||
wasAcceptedByService:(BOOL)wasAcceptedByService
|
|
||||||
{
|
|
||||||
OWSAssert(keyPair);
|
|
||||||
OWSAssert(signature);
|
|
||||||
OWSAssert(generatedAt);
|
|
||||||
|
|
||||||
self = [super initWithId:identifier keyPair:keyPair];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_signature = signature;
|
|
||||||
_generatedAt = generatedAt;
|
|
||||||
_wasAcceptedByService = wasAcceptedByService;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair *)keyPair signature:(NSData*)signature generatedAt:(NSDate *)generatedAt{
|
|
||||||
self = [super initWithId:identifier keyPair:keyPair];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_signature = signature;
|
|
||||||
_generatedAt = generatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
|
||||||
return [self initWithId:[aDecoder decodeIntForKey:kCoderPreKeyId]
|
|
||||||
keyPair:[aDecoder decodeObjectOfClass:[ECKeyPair class] forKey:kCoderPreKeyPair]
|
|
||||||
signature:[aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderPreKeySignature]
|
|
||||||
generatedAt:[aDecoder decodeObjectOfClass:[NSDate class] forKey:kCoderPreKeyDate]
|
|
||||||
wasAcceptedByService:[aDecoder decodeBoolForKey:kCoderPreKeyWasAcceptedByService]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder{
|
|
||||||
[aCoder encodeInt:self.Id forKey:kCoderPreKeyId];
|
|
||||||
[aCoder encodeObject:self.keyPair forKey:kCoderPreKeyPair];
|
|
||||||
[aCoder encodeObject:self.signature forKey:kCoderPreKeySignature];
|
|
||||||
[aCoder encodeObject:self.generatedAt forKey:kCoderPreKeyDate];
|
|
||||||
[aCoder encodeBool:self.wasAcceptedByService forKey:kCoderPreKeyWasAcceptedByService];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair*)keyPair{
|
|
||||||
OWSAbstractMethod();
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)markAsAcceptedByService
|
|
||||||
{
|
|
||||||
_wasAcceptedByService = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,571 +0,0 @@
|
||||||
// DO NOT EDIT.
|
|
||||||
// swift-format-ignore-file
|
|
||||||
//
|
|
||||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
|
||||||
// Source: OWSUnidentifiedDelivery.proto
|
|
||||||
//
|
|
||||||
// For information on using the generated types, please see the documentation:
|
|
||||||
// https://github.com/apple/swift-protobuf/
|
|
||||||
|
|
||||||
//*
|
|
||||||
// Copyright (C) 2014-2016 Open Whisper Systems
|
|
||||||
//
|
|
||||||
// Licensed according to the LICENSE file in this repository.
|
|
||||||
|
|
||||||
/// iOS - since we use a modern proto-compiler, we must specify
|
|
||||||
/// the legacy proto format.
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SwiftProtobuf
|
|
||||||
|
|
||||||
// If the compiler emits an error on this type, it is because this file
|
|
||||||
// was generated by a version of the `protoc` Swift plug-in that is
|
|
||||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
|
||||||
// Please ensure that you are building against the same version of the API
|
|
||||||
// that was used to generate this file.
|
|
||||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
|
||||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
|
||||||
typealias Version = _2
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SMKProtos_ServerCertificate {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var certificate: Data {
|
|
||||||
get {return _certificate ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_certificate = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `certificate` has been explicitly set.
|
|
||||||
var hasCertificate: Bool {return self._certificate != nil}
|
|
||||||
/// Clears the value of `certificate`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearCertificate() {self._certificate = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var signature: Data {
|
|
||||||
get {return _signature ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_signature = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `signature` has been explicitly set.
|
|
||||||
var hasSignature: Bool {return self._signature != nil}
|
|
||||||
/// Clears the value of `signature`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSignature() {self._signature = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
struct Certificate {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var id: UInt32 {
|
|
||||||
get {return _id ?? 0}
|
|
||||||
set {_id = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `id` has been explicitly set.
|
|
||||||
var hasID: Bool {return self._id != nil}
|
|
||||||
/// Clears the value of `id`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearID() {self._id = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var key: Data {
|
|
||||||
get {return _key ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_key = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `key` has been explicitly set.
|
|
||||||
var hasKey: Bool {return self._key != nil}
|
|
||||||
/// Clears the value of `key`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearKey() {self._key = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _id: UInt32? = nil
|
|
||||||
fileprivate var _key: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _certificate: Data? = nil
|
|
||||||
fileprivate var _signature: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SMKProtos_SenderCertificate {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var sender: String {
|
|
||||||
get {return _sender ?? String()}
|
|
||||||
set {_sender = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `sender` has been explicitly set.
|
|
||||||
var hasSender: Bool {return self._sender != nil}
|
|
||||||
/// Clears the value of `sender`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSender() {self._sender = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var senderDevice: UInt32 {
|
|
||||||
get {return _senderDevice ?? 0}
|
|
||||||
set {_senderDevice = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `senderDevice` has been explicitly set.
|
|
||||||
var hasSenderDevice: Bool {return self._senderDevice != nil}
|
|
||||||
/// Clears the value of `senderDevice`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSenderDevice() {self._senderDevice = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
struct Certificate {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var sender: String {
|
|
||||||
get {return _sender ?? String()}
|
|
||||||
set {_sender = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `sender` has been explicitly set.
|
|
||||||
var hasSender: Bool {return self._sender != nil}
|
|
||||||
/// Clears the value of `sender`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSender() {self._sender = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var senderDevice: UInt32 {
|
|
||||||
get {return _senderDevice ?? 0}
|
|
||||||
set {_senderDevice = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `senderDevice` has been explicitly set.
|
|
||||||
var hasSenderDevice: Bool {return self._senderDevice != nil}
|
|
||||||
/// Clears the value of `senderDevice`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSenderDevice() {self._senderDevice = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var expires: UInt64 {
|
|
||||||
get {return _expires ?? 0}
|
|
||||||
set {_expires = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `expires` has been explicitly set.
|
|
||||||
var hasExpires: Bool {return self._expires != nil}
|
|
||||||
/// Clears the value of `expires`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearExpires() {self._expires = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var identityKey: Data {
|
|
||||||
get {return _identityKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_identityKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `identityKey` has been explicitly set.
|
|
||||||
var hasIdentityKey: Bool {return self._identityKey != nil}
|
|
||||||
/// Clears the value of `identityKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearIdentityKey() {self._identityKey = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var signer: SMKProtos_ServerCertificate {
|
|
||||||
get {return _signer ?? SMKProtos_ServerCertificate()}
|
|
||||||
set {_signer = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `signer` has been explicitly set.
|
|
||||||
var hasSigner: Bool {return self._signer != nil}
|
|
||||||
/// Clears the value of `signer`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSigner() {self._signer = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _sender: String? = nil
|
|
||||||
fileprivate var _senderDevice: UInt32? = nil
|
|
||||||
fileprivate var _expires: UInt64? = nil
|
|
||||||
fileprivate var _identityKey: Data? = nil
|
|
||||||
fileprivate var _signer: SMKProtos_ServerCertificate? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _sender: String? = nil
|
|
||||||
fileprivate var _senderDevice: UInt32? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SMKProtos_UnidentifiedSenderMessage {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var ephemeralPublic: Data {
|
|
||||||
get {return _ephemeralPublic ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_ephemeralPublic = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `ephemeralPublic` has been explicitly set.
|
|
||||||
var hasEphemeralPublic: Bool {return self._ephemeralPublic != nil}
|
|
||||||
/// Clears the value of `ephemeralPublic`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearEphemeralPublic() {self._ephemeralPublic = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var encryptedStatic: Data {
|
|
||||||
get {return _encryptedStatic ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_encryptedStatic = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `encryptedStatic` has been explicitly set.
|
|
||||||
var hasEncryptedStatic: Bool {return self._encryptedStatic != nil}
|
|
||||||
/// Clears the value of `encryptedStatic`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearEncryptedStatic() {self._encryptedStatic = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var encryptedMessage: Data {
|
|
||||||
get {return _encryptedMessage ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_encryptedMessage = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `encryptedMessage` has been explicitly set.
|
|
||||||
var hasEncryptedMessage: Bool {return self._encryptedMessage != nil}
|
|
||||||
/// Clears the value of `encryptedMessage`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearEncryptedMessage() {self._encryptedMessage = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
struct Message {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var type: SMKProtos_UnidentifiedSenderMessage.Message.TypeEnum {
|
|
||||||
get {return _type ?? .prekeyMessage}
|
|
||||||
set {_type = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `type` has been explicitly set.
|
|
||||||
var hasType: Bool {return self._type != nil}
|
|
||||||
/// Clears the value of `type`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearType() {self._type = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var senderCertificate: SMKProtos_SenderCertificate {
|
|
||||||
get {return _senderCertificate ?? SMKProtos_SenderCertificate()}
|
|
||||||
set {_senderCertificate = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `senderCertificate` has been explicitly set.
|
|
||||||
var hasSenderCertificate: Bool {return self._senderCertificate != nil}
|
|
||||||
/// Clears the value of `senderCertificate`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSenderCertificate() {self._senderCertificate = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var content: Data {
|
|
||||||
get {return _content ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_content = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `content` has been explicitly set.
|
|
||||||
var hasContent: Bool {return self._content != nil}
|
|
||||||
/// Clears the value of `content`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearContent() {self._content = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
enum TypeEnum: SwiftProtobuf.Enum {
|
|
||||||
typealias RawValue = Int
|
|
||||||
case prekeyMessage // = 1
|
|
||||||
case message // = 2
|
|
||||||
case fallbackMessage // = 3
|
|
||||||
|
|
||||||
init() {
|
|
||||||
self = .prekeyMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
init?(rawValue: Int) {
|
|
||||||
switch rawValue {
|
|
||||||
case 1: self = .prekeyMessage
|
|
||||||
case 2: self = .message
|
|
||||||
case 3: self = .fallbackMessage
|
|
||||||
default: return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var rawValue: Int {
|
|
||||||
switch self {
|
|
||||||
case .prekeyMessage: return 1
|
|
||||||
case .message: return 2
|
|
||||||
case .fallbackMessage: return 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _type: SMKProtos_UnidentifiedSenderMessage.Message.TypeEnum? = nil
|
|
||||||
fileprivate var _senderCertificate: SMKProtos_SenderCertificate? = nil
|
|
||||||
fileprivate var _content: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _ephemeralPublic: Data? = nil
|
|
||||||
fileprivate var _encryptedStatic: Data? = nil
|
|
||||||
fileprivate var _encryptedMessage: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
#if swift(>=4.2)
|
|
||||||
|
|
||||||
extension SMKProtos_UnidentifiedSenderMessage.Message.TypeEnum: CaseIterable {
|
|
||||||
// Support synthesized by the compiler.
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // swift(>=4.2)
|
|
||||||
|
|
||||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
|
||||||
|
|
||||||
fileprivate let _protobuf_package = "SMKProtos"
|
|
||||||
|
|
||||||
extension SMKProtos_ServerCertificate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".ServerCertificate"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "certificate"),
|
|
||||||
2: .same(proto: "signature"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularBytesField(value: &self._certificate)
|
|
||||||
case 2: try decoder.decodeSingularBytesField(value: &self._signature)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._certificate {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._signature {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SMKProtos_ServerCertificate, rhs: SMKProtos_ServerCertificate) -> Bool {
|
|
||||||
if lhs._certificate != rhs._certificate {return false}
|
|
||||||
if lhs._signature != rhs._signature {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtos_ServerCertificate.Certificate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = SMKProtos_ServerCertificate.protoMessageName + ".Certificate"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "id"),
|
|
||||||
2: .same(proto: "key"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularUInt32Field(value: &self._id)
|
|
||||||
case 2: try decoder.decodeSingularBytesField(value: &self._key)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._id {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._key {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SMKProtos_ServerCertificate.Certificate, rhs: SMKProtos_ServerCertificate.Certificate) -> Bool {
|
|
||||||
if lhs._id != rhs._id {return false}
|
|
||||||
if lhs._key != rhs._key {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtos_SenderCertificate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".SenderCertificate"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "sender"),
|
|
||||||
2: .same(proto: "senderDevice"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self._sender)
|
|
||||||
case 2: try decoder.decodeSingularUInt32Field(value: &self._senderDevice)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._sender {
|
|
||||||
try visitor.visitSingularStringField(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._senderDevice {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SMKProtos_SenderCertificate, rhs: SMKProtos_SenderCertificate) -> Bool {
|
|
||||||
if lhs._sender != rhs._sender {return false}
|
|
||||||
if lhs._senderDevice != rhs._senderDevice {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtos_SenderCertificate.Certificate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = SMKProtos_SenderCertificate.protoMessageName + ".Certificate"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "sender"),
|
|
||||||
2: .same(proto: "senderDevice"),
|
|
||||||
3: .same(proto: "expires"),
|
|
||||||
4: .same(proto: "identityKey"),
|
|
||||||
5: .same(proto: "signer"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self._sender)
|
|
||||||
case 2: try decoder.decodeSingularUInt32Field(value: &self._senderDevice)
|
|
||||||
case 3: try decoder.decodeSingularFixed64Field(value: &self._expires)
|
|
||||||
case 4: try decoder.decodeSingularBytesField(value: &self._identityKey)
|
|
||||||
case 5: try decoder.decodeSingularMessageField(value: &self._signer)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._sender {
|
|
||||||
try visitor.visitSingularStringField(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._senderDevice {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._expires {
|
|
||||||
try visitor.visitSingularFixed64Field(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if let v = self._identityKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
if let v = self._signer {
|
|
||||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SMKProtos_SenderCertificate.Certificate, rhs: SMKProtos_SenderCertificate.Certificate) -> Bool {
|
|
||||||
if lhs._sender != rhs._sender {return false}
|
|
||||||
if lhs._senderDevice != rhs._senderDevice {return false}
|
|
||||||
if lhs._expires != rhs._expires {return false}
|
|
||||||
if lhs._identityKey != rhs._identityKey {return false}
|
|
||||||
if lhs._signer != rhs._signer {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtos_UnidentifiedSenderMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".UnidentifiedSenderMessage"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "ephemeralPublic"),
|
|
||||||
2: .same(proto: "encryptedStatic"),
|
|
||||||
3: .same(proto: "encryptedMessage"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularBytesField(value: &self._ephemeralPublic)
|
|
||||||
case 2: try decoder.decodeSingularBytesField(value: &self._encryptedStatic)
|
|
||||||
case 3: try decoder.decodeSingularBytesField(value: &self._encryptedMessage)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._ephemeralPublic {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._encryptedStatic {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._encryptedMessage {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SMKProtos_UnidentifiedSenderMessage, rhs: SMKProtos_UnidentifiedSenderMessage) -> Bool {
|
|
||||||
if lhs._ephemeralPublic != rhs._ephemeralPublic {return false}
|
|
||||||
if lhs._encryptedStatic != rhs._encryptedStatic {return false}
|
|
||||||
if lhs._encryptedMessage != rhs._encryptedMessage {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtos_UnidentifiedSenderMessage.Message: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = SMKProtos_UnidentifiedSenderMessage.protoMessageName + ".Message"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "type"),
|
|
||||||
2: .same(proto: "senderCertificate"),
|
|
||||||
3: .same(proto: "content"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularEnumField(value: &self._type)
|
|
||||||
case 2: try decoder.decodeSingularMessageField(value: &self._senderCertificate)
|
|
||||||
case 3: try decoder.decodeSingularBytesField(value: &self._content)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._type {
|
|
||||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._senderCertificate {
|
|
||||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._content {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SMKProtos_UnidentifiedSenderMessage.Message, rhs: SMKProtos_UnidentifiedSenderMessage.Message) -> Bool {
|
|
||||||
if lhs._type != rhs._type {return false}
|
|
||||||
if lhs._senderCertificate != rhs._senderCertificate {return false}
|
|
||||||
if lhs._content != rhs._content {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtos_UnidentifiedSenderMessage.Message.TypeEnum: SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "PREKEY_MESSAGE"),
|
|
||||||
2: .same(proto: "MESSAGE"),
|
|
||||||
3: .same(proto: "FALLBACK_MESSAGE"),
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,782 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
// WARNING: This code is generated. Only edit within the markers.
|
|
||||||
|
|
||||||
public enum SMKProtoError: Error {
|
|
||||||
case invalidProtobuf(description: String)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - SMKProtoServerCertificateCertificate
|
|
||||||
|
|
||||||
@objc public class SMKProtoServerCertificateCertificate: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SMKProtoServerCertificateCertificateBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(id: UInt32, key: Data) -> SMKProtoServerCertificateCertificateBuilder {
|
|
||||||
return SMKProtoServerCertificateCertificateBuilder(id: id, key: key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SMKProtoServerCertificateCertificateBuilder {
|
|
||||||
let builder = SMKProtoServerCertificateCertificateBuilder(id: id, key: key)
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SMKProtoServerCertificateCertificateBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SMKProtos_ServerCertificate.Certificate()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(id: UInt32, key: Data) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setId(id)
|
|
||||||
setKey(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setId(_ valueParam: UInt32) {
|
|
||||||
proto.id = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setKey(_ valueParam: Data) {
|
|
||||||
proto.key = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SMKProtoServerCertificateCertificate {
|
|
||||||
return try SMKProtoServerCertificateCertificate.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SMKProtoServerCertificateCertificate.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SMKProtos_ServerCertificate.Certificate
|
|
||||||
|
|
||||||
@objc public let id: UInt32
|
|
||||||
|
|
||||||
@objc public let key: Data
|
|
||||||
|
|
||||||
private init(proto: SMKProtos_ServerCertificate.Certificate,
|
|
||||||
id: UInt32,
|
|
||||||
key: Data) {
|
|
||||||
self.proto = proto
|
|
||||||
self.id = id
|
|
||||||
self.key = key
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SMKProtoServerCertificateCertificate {
|
|
||||||
let proto = try SMKProtos_ServerCertificate.Certificate(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SMKProtos_ServerCertificate.Certificate) throws -> SMKProtoServerCertificateCertificate {
|
|
||||||
guard proto.hasID else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: id")
|
|
||||||
}
|
|
||||||
let id = proto.id
|
|
||||||
|
|
||||||
guard proto.hasKey else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: key")
|
|
||||||
}
|
|
||||||
let key = proto.key
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SMKProtoServerCertificateCertificate -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SMKProtoServerCertificateCertificate -
|
|
||||||
|
|
||||||
let result = SMKProtoServerCertificateCertificate(proto: proto,
|
|
||||||
id: id,
|
|
||||||
key: key)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SMKProtoServerCertificateCertificate {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtoServerCertificateCertificate.SMKProtoServerCertificateCertificateBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SMKProtoServerCertificateCertificate? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SMKProtoServerCertificate
|
|
||||||
|
|
||||||
@objc public class SMKProtoServerCertificate: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SMKProtoServerCertificateBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(certificate: Data, signature: Data) -> SMKProtoServerCertificateBuilder {
|
|
||||||
return SMKProtoServerCertificateBuilder(certificate: certificate, signature: signature)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SMKProtoServerCertificateBuilder {
|
|
||||||
let builder = SMKProtoServerCertificateBuilder(certificate: certificate, signature: signature)
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SMKProtoServerCertificateBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SMKProtos_ServerCertificate()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(certificate: Data, signature: Data) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setCertificate(certificate)
|
|
||||||
setSignature(signature)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setCertificate(_ valueParam: Data) {
|
|
||||||
proto.certificate = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSignature(_ valueParam: Data) {
|
|
||||||
proto.signature = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SMKProtoServerCertificate {
|
|
||||||
return try SMKProtoServerCertificate.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SMKProtoServerCertificate.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SMKProtos_ServerCertificate
|
|
||||||
|
|
||||||
@objc public let certificate: Data
|
|
||||||
|
|
||||||
@objc public let signature: Data
|
|
||||||
|
|
||||||
private init(proto: SMKProtos_ServerCertificate,
|
|
||||||
certificate: Data,
|
|
||||||
signature: Data) {
|
|
||||||
self.proto = proto
|
|
||||||
self.certificate = certificate
|
|
||||||
self.signature = signature
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SMKProtoServerCertificate {
|
|
||||||
let proto = try SMKProtos_ServerCertificate(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SMKProtos_ServerCertificate) throws -> SMKProtoServerCertificate {
|
|
||||||
guard proto.hasCertificate else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: certificate")
|
|
||||||
}
|
|
||||||
let certificate = proto.certificate
|
|
||||||
|
|
||||||
guard proto.hasSignature else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: signature")
|
|
||||||
}
|
|
||||||
let signature = proto.signature
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SMKProtoServerCertificate -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SMKProtoServerCertificate -
|
|
||||||
|
|
||||||
let result = SMKProtoServerCertificate(proto: proto,
|
|
||||||
certificate: certificate,
|
|
||||||
signature: signature)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SMKProtoServerCertificate {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtoServerCertificate.SMKProtoServerCertificateBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SMKProtoServerCertificate? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SMKProtoSenderCertificateCertificate
|
|
||||||
|
|
||||||
@objc public class SMKProtoSenderCertificateCertificate: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SMKProtoSenderCertificateCertificateBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(sender: String, senderDevice: UInt32, expires: UInt64, identityKey: Data, signer: SMKProtoServerCertificate) -> SMKProtoSenderCertificateCertificateBuilder {
|
|
||||||
return SMKProtoSenderCertificateCertificateBuilder(sender: sender, senderDevice: senderDevice, expires: expires, identityKey: identityKey, signer: signer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SMKProtoSenderCertificateCertificateBuilder {
|
|
||||||
let builder = SMKProtoSenderCertificateCertificateBuilder(sender: sender, senderDevice: senderDevice, expires: expires, identityKey: identityKey, signer: signer)
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SMKProtoSenderCertificateCertificateBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SMKProtos_SenderCertificate.Certificate()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(sender: String, senderDevice: UInt32, expires: UInt64, identityKey: Data, signer: SMKProtoServerCertificate) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setSender(sender)
|
|
||||||
setSenderDevice(senderDevice)
|
|
||||||
setExpires(expires)
|
|
||||||
setIdentityKey(identityKey)
|
|
||||||
setSigner(signer)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSender(_ valueParam: String) {
|
|
||||||
proto.sender = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSenderDevice(_ valueParam: UInt32) {
|
|
||||||
proto.senderDevice = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setExpires(_ valueParam: UInt64) {
|
|
||||||
proto.expires = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setIdentityKey(_ valueParam: Data) {
|
|
||||||
proto.identityKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSigner(_ valueParam: SMKProtoServerCertificate) {
|
|
||||||
proto.signer = valueParam.proto
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SMKProtoSenderCertificateCertificate {
|
|
||||||
return try SMKProtoSenderCertificateCertificate.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SMKProtoSenderCertificateCertificate.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SMKProtos_SenderCertificate.Certificate
|
|
||||||
|
|
||||||
@objc public let sender: String
|
|
||||||
|
|
||||||
@objc public let senderDevice: UInt32
|
|
||||||
|
|
||||||
@objc public let expires: UInt64
|
|
||||||
|
|
||||||
@objc public let identityKey: Data
|
|
||||||
|
|
||||||
@objc public let signer: SMKProtoServerCertificate
|
|
||||||
|
|
||||||
private init(proto: SMKProtos_SenderCertificate.Certificate,
|
|
||||||
sender: String,
|
|
||||||
senderDevice: UInt32,
|
|
||||||
expires: UInt64,
|
|
||||||
identityKey: Data,
|
|
||||||
signer: SMKProtoServerCertificate) {
|
|
||||||
self.proto = proto
|
|
||||||
self.sender = sender
|
|
||||||
self.senderDevice = senderDevice
|
|
||||||
self.expires = expires
|
|
||||||
self.identityKey = identityKey
|
|
||||||
self.signer = signer
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SMKProtoSenderCertificateCertificate {
|
|
||||||
let proto = try SMKProtos_SenderCertificate.Certificate(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SMKProtos_SenderCertificate.Certificate) throws -> SMKProtoSenderCertificateCertificate {
|
|
||||||
guard proto.hasSender else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: sender")
|
|
||||||
}
|
|
||||||
let sender = proto.sender
|
|
||||||
|
|
||||||
guard proto.hasSenderDevice else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: senderDevice")
|
|
||||||
}
|
|
||||||
let senderDevice = proto.senderDevice
|
|
||||||
|
|
||||||
guard proto.hasExpires else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: expires")
|
|
||||||
}
|
|
||||||
let expires = proto.expires
|
|
||||||
|
|
||||||
guard proto.hasIdentityKey else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: identityKey")
|
|
||||||
}
|
|
||||||
let identityKey = proto.identityKey
|
|
||||||
|
|
||||||
guard proto.hasSigner else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: signer")
|
|
||||||
}
|
|
||||||
let signer = try SMKProtoServerCertificate.parseProto(proto.signer)
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SMKProtoSenderCertificateCertificate -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SMKProtoSenderCertificateCertificate -
|
|
||||||
|
|
||||||
let result = SMKProtoSenderCertificateCertificate(proto: proto,
|
|
||||||
sender: sender,
|
|
||||||
senderDevice: senderDevice,
|
|
||||||
expires: expires,
|
|
||||||
identityKey: identityKey,
|
|
||||||
signer: signer)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SMKProtoSenderCertificateCertificate {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtoSenderCertificateCertificate.SMKProtoSenderCertificateCertificateBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SMKProtoSenderCertificateCertificate? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SMKProtoSenderCertificate
|
|
||||||
|
|
||||||
@objc public class SMKProtoSenderCertificate: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SMKProtoSenderCertificateBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(sender: String, senderDevice: UInt32) -> SMKProtoSenderCertificateBuilder {
|
|
||||||
return SMKProtoSenderCertificateBuilder(sender: sender, senderDevice: senderDevice)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SMKProtoSenderCertificateBuilder {
|
|
||||||
let builder = SMKProtoSenderCertificateBuilder(sender: sender, senderDevice: senderDevice)
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SMKProtoSenderCertificateBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SMKProtos_SenderCertificate()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(sender: String, senderDevice: UInt32) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setSender(sender)
|
|
||||||
setSenderDevice(senderDevice)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSender(_ valueParam: String) {
|
|
||||||
proto.sender = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSenderDevice(_ valueParam: UInt32) {
|
|
||||||
proto.senderDevice = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SMKProtoSenderCertificate {
|
|
||||||
return try SMKProtoSenderCertificate.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SMKProtoSenderCertificate.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SMKProtos_SenderCertificate
|
|
||||||
|
|
||||||
@objc public let sender: String
|
|
||||||
|
|
||||||
@objc public let senderDevice: UInt32
|
|
||||||
|
|
||||||
private init(proto: SMKProtos_SenderCertificate,
|
|
||||||
sender: String,
|
|
||||||
senderDevice: UInt32) {
|
|
||||||
self.proto = proto
|
|
||||||
self.sender = sender
|
|
||||||
self.senderDevice = senderDevice
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SMKProtoSenderCertificate {
|
|
||||||
let proto = try SMKProtos_SenderCertificate(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SMKProtos_SenderCertificate) throws -> SMKProtoSenderCertificate {
|
|
||||||
guard proto.hasSender else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: sender")
|
|
||||||
}
|
|
||||||
let sender = proto.sender
|
|
||||||
|
|
||||||
guard proto.hasSenderDevice else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: senderDevice")
|
|
||||||
}
|
|
||||||
let senderDevice = proto.senderDevice
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SMKProtoSenderCertificate -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SMKProtoSenderCertificate -
|
|
||||||
|
|
||||||
let result = SMKProtoSenderCertificate(proto: proto,
|
|
||||||
sender: sender,
|
|
||||||
senderDevice: senderDevice)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SMKProtoSenderCertificate {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtoSenderCertificate.SMKProtoSenderCertificateBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SMKProtoSenderCertificate? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SMKProtoUnidentifiedSenderMessageMessage
|
|
||||||
|
|
||||||
@objc public class SMKProtoUnidentifiedSenderMessageMessage: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SMKProtoUnidentifiedSenderMessageMessageType
|
|
||||||
|
|
||||||
@objc public enum SMKProtoUnidentifiedSenderMessageMessageType: Int32 {
|
|
||||||
case prekeyMessage = 1
|
|
||||||
case message = 2
|
|
||||||
case fallbackMessage = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
private class func SMKProtoUnidentifiedSenderMessageMessageTypeWrap(_ value: SMKProtos_UnidentifiedSenderMessage.Message.TypeEnum) -> SMKProtoUnidentifiedSenderMessageMessageType {
|
|
||||||
switch value {
|
|
||||||
case .prekeyMessage: return .prekeyMessage
|
|
||||||
case .message: return .message
|
|
||||||
case .fallbackMessage: return .fallbackMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class func SMKProtoUnidentifiedSenderMessageMessageTypeUnwrap(_ value: SMKProtoUnidentifiedSenderMessageMessageType) -> SMKProtos_UnidentifiedSenderMessage.Message.TypeEnum {
|
|
||||||
switch value {
|
|
||||||
case .prekeyMessage: return .prekeyMessage
|
|
||||||
case .message: return .message
|
|
||||||
case .fallbackMessage: return .fallbackMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - SMKProtoUnidentifiedSenderMessageMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(type: SMKProtoUnidentifiedSenderMessageMessageType, senderCertificate: SMKProtoSenderCertificate, content: Data) -> SMKProtoUnidentifiedSenderMessageMessageBuilder {
|
|
||||||
return SMKProtoUnidentifiedSenderMessageMessageBuilder(type: type, senderCertificate: senderCertificate, content: content)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SMKProtoUnidentifiedSenderMessageMessageBuilder {
|
|
||||||
let builder = SMKProtoUnidentifiedSenderMessageMessageBuilder(type: type, senderCertificate: senderCertificate, content: content)
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SMKProtoUnidentifiedSenderMessageMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SMKProtos_UnidentifiedSenderMessage.Message()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(type: SMKProtoUnidentifiedSenderMessageMessageType, senderCertificate: SMKProtoSenderCertificate, content: Data) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setType(type)
|
|
||||||
setSenderCertificate(senderCertificate)
|
|
||||||
setContent(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setType(_ valueParam: SMKProtoUnidentifiedSenderMessageMessageType) {
|
|
||||||
proto.type = SMKProtoUnidentifiedSenderMessageMessageTypeUnwrap(valueParam)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSenderCertificate(_ valueParam: SMKProtoSenderCertificate) {
|
|
||||||
proto.senderCertificate = valueParam.proto
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setContent(_ valueParam: Data) {
|
|
||||||
proto.content = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SMKProtoUnidentifiedSenderMessageMessage {
|
|
||||||
return try SMKProtoUnidentifiedSenderMessageMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SMKProtoUnidentifiedSenderMessageMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SMKProtos_UnidentifiedSenderMessage.Message
|
|
||||||
|
|
||||||
@objc public let type: SMKProtoUnidentifiedSenderMessageMessageType
|
|
||||||
|
|
||||||
@objc public let senderCertificate: SMKProtoSenderCertificate
|
|
||||||
|
|
||||||
@objc public let content: Data
|
|
||||||
|
|
||||||
private init(proto: SMKProtos_UnidentifiedSenderMessage.Message,
|
|
||||||
type: SMKProtoUnidentifiedSenderMessageMessageType,
|
|
||||||
senderCertificate: SMKProtoSenderCertificate,
|
|
||||||
content: Data) {
|
|
||||||
self.proto = proto
|
|
||||||
self.type = type
|
|
||||||
self.senderCertificate = senderCertificate
|
|
||||||
self.content = content
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SMKProtoUnidentifiedSenderMessageMessage {
|
|
||||||
let proto = try SMKProtos_UnidentifiedSenderMessage.Message(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SMKProtos_UnidentifiedSenderMessage.Message) throws -> SMKProtoUnidentifiedSenderMessageMessage {
|
|
||||||
guard proto.hasType else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: type")
|
|
||||||
}
|
|
||||||
let type = SMKProtoUnidentifiedSenderMessageMessageTypeWrap(proto.type)
|
|
||||||
|
|
||||||
guard proto.hasSenderCertificate else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: senderCertificate")
|
|
||||||
}
|
|
||||||
let senderCertificate = try SMKProtoSenderCertificate.parseProto(proto.senderCertificate)
|
|
||||||
|
|
||||||
guard proto.hasContent else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: content")
|
|
||||||
}
|
|
||||||
let content = proto.content
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SMKProtoUnidentifiedSenderMessageMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SMKProtoUnidentifiedSenderMessageMessage -
|
|
||||||
|
|
||||||
let result = SMKProtoUnidentifiedSenderMessageMessage(proto: proto,
|
|
||||||
type: type,
|
|
||||||
senderCertificate: senderCertificate,
|
|
||||||
content: content)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SMKProtoUnidentifiedSenderMessageMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtoUnidentifiedSenderMessageMessage.SMKProtoUnidentifiedSenderMessageMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SMKProtoUnidentifiedSenderMessageMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SMKProtoUnidentifiedSenderMessage
|
|
||||||
|
|
||||||
@objc public class SMKProtoUnidentifiedSenderMessage: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SMKProtoUnidentifiedSenderMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(ephemeralPublic: Data, encryptedStatic: Data, encryptedMessage: Data) -> SMKProtoUnidentifiedSenderMessageBuilder {
|
|
||||||
return SMKProtoUnidentifiedSenderMessageBuilder(ephemeralPublic: ephemeralPublic, encryptedStatic: encryptedStatic, encryptedMessage: encryptedMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SMKProtoUnidentifiedSenderMessageBuilder {
|
|
||||||
let builder = SMKProtoUnidentifiedSenderMessageBuilder(ephemeralPublic: ephemeralPublic, encryptedStatic: encryptedStatic, encryptedMessage: encryptedMessage)
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SMKProtoUnidentifiedSenderMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SMKProtos_UnidentifiedSenderMessage()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(ephemeralPublic: Data, encryptedStatic: Data, encryptedMessage: Data) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setEphemeralPublic(ephemeralPublic)
|
|
||||||
setEncryptedStatic(encryptedStatic)
|
|
||||||
setEncryptedMessage(encryptedMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setEphemeralPublic(_ valueParam: Data) {
|
|
||||||
proto.ephemeralPublic = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setEncryptedStatic(_ valueParam: Data) {
|
|
||||||
proto.encryptedStatic = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setEncryptedMessage(_ valueParam: Data) {
|
|
||||||
proto.encryptedMessage = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SMKProtoUnidentifiedSenderMessage {
|
|
||||||
return try SMKProtoUnidentifiedSenderMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SMKProtoUnidentifiedSenderMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SMKProtos_UnidentifiedSenderMessage
|
|
||||||
|
|
||||||
@objc public let ephemeralPublic: Data
|
|
||||||
|
|
||||||
@objc public let encryptedStatic: Data
|
|
||||||
|
|
||||||
@objc public let encryptedMessage: Data
|
|
||||||
|
|
||||||
private init(proto: SMKProtos_UnidentifiedSenderMessage,
|
|
||||||
ephemeralPublic: Data,
|
|
||||||
encryptedStatic: Data,
|
|
||||||
encryptedMessage: Data) {
|
|
||||||
self.proto = proto
|
|
||||||
self.ephemeralPublic = ephemeralPublic
|
|
||||||
self.encryptedStatic = encryptedStatic
|
|
||||||
self.encryptedMessage = encryptedMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SMKProtoUnidentifiedSenderMessage {
|
|
||||||
let proto = try SMKProtos_UnidentifiedSenderMessage(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SMKProtos_UnidentifiedSenderMessage) throws -> SMKProtoUnidentifiedSenderMessage {
|
|
||||||
guard proto.hasEphemeralPublic else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: ephemeralPublic")
|
|
||||||
}
|
|
||||||
let ephemeralPublic = proto.ephemeralPublic
|
|
||||||
|
|
||||||
guard proto.hasEncryptedStatic else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: encryptedStatic")
|
|
||||||
}
|
|
||||||
let encryptedStatic = proto.encryptedStatic
|
|
||||||
|
|
||||||
guard proto.hasEncryptedMessage else {
|
|
||||||
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: encryptedMessage")
|
|
||||||
}
|
|
||||||
let encryptedMessage = proto.encryptedMessage
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SMKProtoUnidentifiedSenderMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SMKProtoUnidentifiedSenderMessage -
|
|
||||||
|
|
||||||
let result = SMKProtoUnidentifiedSenderMessage(proto: proto,
|
|
||||||
ephemeralPublic: ephemeralPublic,
|
|
||||||
encryptedStatic: encryptedStatic,
|
|
||||||
encryptedMessage: encryptedMessage)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SMKProtoUnidentifiedSenderMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SMKProtoUnidentifiedSenderMessage.SMKProtoUnidentifiedSenderMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SMKProtoUnidentifiedSenderMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,873 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
// WARNING: This code is generated. Only edit within the markers.
|
|
||||||
|
|
||||||
public enum SPKProtoError: Error {
|
|
||||||
case invalidProtobuf(description: String)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoWhisperMessage
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoWhisperMessage: NSObject {
|
|
||||||
|
|
||||||
class var logTag: String { "SPKProtoTSProtoWhisperMessage" }
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoWhisperMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(ratchetKey: Data, counter: UInt32, ciphertext: Data) -> SPKProtoTSProtoWhisperMessageBuilder {
|
|
||||||
return SPKProtoTSProtoWhisperMessageBuilder(ratchetKey: ratchetKey, counter: counter, ciphertext: ciphertext)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SPKProtoTSProtoWhisperMessageBuilder {
|
|
||||||
let builder = SPKProtoTSProtoWhisperMessageBuilder(ratchetKey: ratchetKey, counter: counter, ciphertext: ciphertext)
|
|
||||||
if hasPreviousCounter {
|
|
||||||
builder.setPreviousCounter(previousCounter)
|
|
||||||
}
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoWhisperMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SPKProtos_TSProtoWhisperMessage()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(ratchetKey: Data, counter: UInt32, ciphertext: Data) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setRatchetKey(ratchetKey)
|
|
||||||
setCounter(counter)
|
|
||||||
setCiphertext(ciphertext)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setRatchetKey(_ valueParam: Data) {
|
|
||||||
proto.ratchetKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setCounter(_ valueParam: UInt32) {
|
|
||||||
proto.counter = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setPreviousCounter(_ valueParam: UInt32) {
|
|
||||||
proto.previousCounter = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setCiphertext(_ valueParam: Data) {
|
|
||||||
proto.ciphertext = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SPKProtoTSProtoWhisperMessage {
|
|
||||||
return try SPKProtoTSProtoWhisperMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SPKProtoTSProtoWhisperMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SPKProtos_TSProtoWhisperMessage
|
|
||||||
|
|
||||||
@objc public let ratchetKey: Data
|
|
||||||
|
|
||||||
@objc public let counter: UInt32
|
|
||||||
|
|
||||||
@objc public let ciphertext: Data
|
|
||||||
|
|
||||||
@objc public var previousCounter: UInt32 {
|
|
||||||
return proto.previousCounter
|
|
||||||
}
|
|
||||||
@objc public var hasPreviousCounter: Bool {
|
|
||||||
return proto.hasPreviousCounter
|
|
||||||
}
|
|
||||||
|
|
||||||
private init(proto: SPKProtos_TSProtoWhisperMessage,
|
|
||||||
ratchetKey: Data,
|
|
||||||
counter: UInt32,
|
|
||||||
ciphertext: Data) {
|
|
||||||
self.proto = proto
|
|
||||||
self.ratchetKey = ratchetKey
|
|
||||||
self.counter = counter
|
|
||||||
self.ciphertext = ciphertext
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SPKProtoTSProtoWhisperMessage {
|
|
||||||
let proto = try SPKProtos_TSProtoWhisperMessage(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SPKProtos_TSProtoWhisperMessage) throws -> SPKProtoTSProtoWhisperMessage {
|
|
||||||
guard proto.hasRatchetKey else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: ratchetKey")
|
|
||||||
}
|
|
||||||
let ratchetKey = proto.ratchetKey
|
|
||||||
|
|
||||||
guard proto.hasCounter else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: counter")
|
|
||||||
}
|
|
||||||
let counter = proto.counter
|
|
||||||
|
|
||||||
guard proto.hasCiphertext else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: ciphertext")
|
|
||||||
}
|
|
||||||
let ciphertext = proto.ciphertext
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SPKProtoTSProtoWhisperMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SPKProtoTSProtoWhisperMessage -
|
|
||||||
|
|
||||||
let result = SPKProtoTSProtoWhisperMessage(proto: proto,
|
|
||||||
ratchetKey: ratchetKey,
|
|
||||||
counter: counter,
|
|
||||||
ciphertext: ciphertext)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoWhisperMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoWhisperMessage.SPKProtoTSProtoWhisperMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SPKProtoTSProtoWhisperMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoPreKeyWhisperMessage
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoPreKeyWhisperMessage: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoPreKeyWhisperMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(signedPreKeyID: UInt32, baseKey: Data, identityKey: Data, message: Data) -> SPKProtoTSProtoPreKeyWhisperMessageBuilder {
|
|
||||||
return SPKProtoTSProtoPreKeyWhisperMessageBuilder(signedPreKeyID: signedPreKeyID, baseKey: baseKey, identityKey: identityKey, message: message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SPKProtoTSProtoPreKeyWhisperMessageBuilder {
|
|
||||||
let builder = SPKProtoTSProtoPreKeyWhisperMessageBuilder(signedPreKeyID: signedPreKeyID, baseKey: baseKey, identityKey: identityKey, message: message)
|
|
||||||
if hasRegistrationID {
|
|
||||||
builder.setRegistrationID(registrationID)
|
|
||||||
}
|
|
||||||
if hasPreKeyID {
|
|
||||||
builder.setPreKeyID(preKeyID)
|
|
||||||
}
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoPreKeyWhisperMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SPKProtos_TSProtoPreKeyWhisperMessage()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(signedPreKeyID: UInt32, baseKey: Data, identityKey: Data, message: Data) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setSignedPreKeyID(signedPreKeyID)
|
|
||||||
setBaseKey(baseKey)
|
|
||||||
setIdentityKey(identityKey)
|
|
||||||
setMessage(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setRegistrationID(_ valueParam: UInt32) {
|
|
||||||
proto.registrationID = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setPreKeyID(_ valueParam: UInt32) {
|
|
||||||
proto.preKeyID = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSignedPreKeyID(_ valueParam: UInt32) {
|
|
||||||
proto.signedPreKeyID = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setBaseKey(_ valueParam: Data) {
|
|
||||||
proto.baseKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setIdentityKey(_ valueParam: Data) {
|
|
||||||
proto.identityKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setMessage(_ valueParam: Data) {
|
|
||||||
proto.message = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SPKProtoTSProtoPreKeyWhisperMessage {
|
|
||||||
return try SPKProtoTSProtoPreKeyWhisperMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SPKProtoTSProtoPreKeyWhisperMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SPKProtos_TSProtoPreKeyWhisperMessage
|
|
||||||
|
|
||||||
@objc public let signedPreKeyID: UInt32
|
|
||||||
|
|
||||||
@objc public let baseKey: Data
|
|
||||||
|
|
||||||
@objc public let identityKey: Data
|
|
||||||
|
|
||||||
@objc public let message: Data
|
|
||||||
|
|
||||||
@objc public var registrationID: UInt32 {
|
|
||||||
return proto.registrationID
|
|
||||||
}
|
|
||||||
@objc public var hasRegistrationID: Bool {
|
|
||||||
return proto.hasRegistrationID
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var preKeyID: UInt32 {
|
|
||||||
return proto.preKeyID
|
|
||||||
}
|
|
||||||
@objc public var hasPreKeyID: Bool {
|
|
||||||
return proto.hasPreKeyID
|
|
||||||
}
|
|
||||||
|
|
||||||
private init(proto: SPKProtos_TSProtoPreKeyWhisperMessage,
|
|
||||||
signedPreKeyID: UInt32,
|
|
||||||
baseKey: Data,
|
|
||||||
identityKey: Data,
|
|
||||||
message: Data) {
|
|
||||||
self.proto = proto
|
|
||||||
self.signedPreKeyID = signedPreKeyID
|
|
||||||
self.baseKey = baseKey
|
|
||||||
self.identityKey = identityKey
|
|
||||||
self.message = message
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SPKProtoTSProtoPreKeyWhisperMessage {
|
|
||||||
let proto = try SPKProtos_TSProtoPreKeyWhisperMessage(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SPKProtos_TSProtoPreKeyWhisperMessage) throws -> SPKProtoTSProtoPreKeyWhisperMessage {
|
|
||||||
guard proto.hasSignedPreKeyID else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: signedPreKeyID")
|
|
||||||
}
|
|
||||||
let signedPreKeyID = proto.signedPreKeyID
|
|
||||||
|
|
||||||
guard proto.hasBaseKey else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: baseKey")
|
|
||||||
}
|
|
||||||
let baseKey = proto.baseKey
|
|
||||||
|
|
||||||
guard proto.hasIdentityKey else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: identityKey")
|
|
||||||
}
|
|
||||||
let identityKey = proto.identityKey
|
|
||||||
|
|
||||||
guard proto.hasMessage else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: message")
|
|
||||||
}
|
|
||||||
let message = proto.message
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SPKProtoTSProtoPreKeyWhisperMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SPKProtoTSProtoPreKeyWhisperMessage -
|
|
||||||
|
|
||||||
let result = SPKProtoTSProtoPreKeyWhisperMessage(proto: proto,
|
|
||||||
signedPreKeyID: signedPreKeyID,
|
|
||||||
baseKey: baseKey,
|
|
||||||
identityKey: identityKey,
|
|
||||||
message: message)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoPreKeyWhisperMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoPreKeyWhisperMessage.SPKProtoTSProtoPreKeyWhisperMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SPKProtoTSProtoPreKeyWhisperMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoKeyExchangeMessage
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoKeyExchangeMessage: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoKeyExchangeMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder() -> SPKProtoTSProtoKeyExchangeMessageBuilder {
|
|
||||||
return SPKProtoTSProtoKeyExchangeMessageBuilder()
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SPKProtoTSProtoKeyExchangeMessageBuilder {
|
|
||||||
let builder = SPKProtoTSProtoKeyExchangeMessageBuilder()
|
|
||||||
if hasID {
|
|
||||||
builder.setId(id)
|
|
||||||
}
|
|
||||||
if let _value = baseKey {
|
|
||||||
builder.setBaseKey(_value)
|
|
||||||
}
|
|
||||||
if let _value = ratchetKey {
|
|
||||||
builder.setRatchetKey(_value)
|
|
||||||
}
|
|
||||||
if let _value = identityKey {
|
|
||||||
builder.setIdentityKey(_value)
|
|
||||||
}
|
|
||||||
if let _value = baseKeySignature {
|
|
||||||
builder.setBaseKeySignature(_value)
|
|
||||||
}
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoKeyExchangeMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SPKProtos_TSProtoKeyExchangeMessage()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc public func setId(_ valueParam: UInt32) {
|
|
||||||
proto.id = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setBaseKey(_ valueParam: Data) {
|
|
||||||
proto.baseKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setRatchetKey(_ valueParam: Data) {
|
|
||||||
proto.ratchetKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setIdentityKey(_ valueParam: Data) {
|
|
||||||
proto.identityKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setBaseKeySignature(_ valueParam: Data) {
|
|
||||||
proto.baseKeySignature = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SPKProtoTSProtoKeyExchangeMessage {
|
|
||||||
return try SPKProtoTSProtoKeyExchangeMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SPKProtoTSProtoKeyExchangeMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SPKProtos_TSProtoKeyExchangeMessage
|
|
||||||
|
|
||||||
@objc public var id: UInt32 {
|
|
||||||
return proto.id
|
|
||||||
}
|
|
||||||
@objc public var hasID: Bool {
|
|
||||||
return proto.hasID
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var baseKey: Data? {
|
|
||||||
guard proto.hasBaseKey else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return proto.baseKey
|
|
||||||
}
|
|
||||||
@objc public var hasBaseKey: Bool {
|
|
||||||
return proto.hasBaseKey
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var ratchetKey: Data? {
|
|
||||||
guard proto.hasRatchetKey else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return proto.ratchetKey
|
|
||||||
}
|
|
||||||
@objc public var hasRatchetKey: Bool {
|
|
||||||
return proto.hasRatchetKey
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var identityKey: Data? {
|
|
||||||
guard proto.hasIdentityKey else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return proto.identityKey
|
|
||||||
}
|
|
||||||
@objc public var hasIdentityKey: Bool {
|
|
||||||
return proto.hasIdentityKey
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var baseKeySignature: Data? {
|
|
||||||
guard proto.hasBaseKeySignature else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return proto.baseKeySignature
|
|
||||||
}
|
|
||||||
@objc public var hasBaseKeySignature: Bool {
|
|
||||||
return proto.hasBaseKeySignature
|
|
||||||
}
|
|
||||||
|
|
||||||
private init(proto: SPKProtos_TSProtoKeyExchangeMessage) {
|
|
||||||
self.proto = proto
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SPKProtoTSProtoKeyExchangeMessage {
|
|
||||||
let proto = try SPKProtos_TSProtoKeyExchangeMessage(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SPKProtos_TSProtoKeyExchangeMessage) throws -> SPKProtoTSProtoKeyExchangeMessage {
|
|
||||||
// MARK: - Begin Validation Logic for SPKProtoTSProtoKeyExchangeMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SPKProtoTSProtoKeyExchangeMessage -
|
|
||||||
|
|
||||||
let result = SPKProtoTSProtoKeyExchangeMessage(proto: proto)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoKeyExchangeMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoKeyExchangeMessage.SPKProtoTSProtoKeyExchangeMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SPKProtoTSProtoKeyExchangeMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoSenderKeyMessage
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoSenderKeyMessage: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoSenderKeyMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder() -> SPKProtoTSProtoSenderKeyMessageBuilder {
|
|
||||||
return SPKProtoTSProtoSenderKeyMessageBuilder()
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SPKProtoTSProtoSenderKeyMessageBuilder {
|
|
||||||
let builder = SPKProtoTSProtoSenderKeyMessageBuilder()
|
|
||||||
if hasID {
|
|
||||||
builder.setId(id)
|
|
||||||
}
|
|
||||||
if hasIteration {
|
|
||||||
builder.setIteration(iteration)
|
|
||||||
}
|
|
||||||
if let _value = ciphertext {
|
|
||||||
builder.setCiphertext(_value)
|
|
||||||
}
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoSenderKeyMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SPKProtos_TSProtoSenderKeyMessage()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc public func setId(_ valueParam: UInt32) {
|
|
||||||
proto.id = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setIteration(_ valueParam: UInt32) {
|
|
||||||
proto.iteration = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setCiphertext(_ valueParam: Data) {
|
|
||||||
proto.ciphertext = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SPKProtoTSProtoSenderKeyMessage {
|
|
||||||
return try SPKProtoTSProtoSenderKeyMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SPKProtoTSProtoSenderKeyMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SPKProtos_TSProtoSenderKeyMessage
|
|
||||||
|
|
||||||
@objc public var id: UInt32 {
|
|
||||||
return proto.id
|
|
||||||
}
|
|
||||||
@objc public var hasID: Bool {
|
|
||||||
return proto.hasID
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var iteration: UInt32 {
|
|
||||||
return proto.iteration
|
|
||||||
}
|
|
||||||
@objc public var hasIteration: Bool {
|
|
||||||
return proto.hasIteration
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var ciphertext: Data? {
|
|
||||||
guard proto.hasCiphertext else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return proto.ciphertext
|
|
||||||
}
|
|
||||||
@objc public var hasCiphertext: Bool {
|
|
||||||
return proto.hasCiphertext
|
|
||||||
}
|
|
||||||
|
|
||||||
private init(proto: SPKProtos_TSProtoSenderKeyMessage) {
|
|
||||||
self.proto = proto
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SPKProtoTSProtoSenderKeyMessage {
|
|
||||||
let proto = try SPKProtos_TSProtoSenderKeyMessage(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SPKProtos_TSProtoSenderKeyMessage) throws -> SPKProtoTSProtoSenderKeyMessage {
|
|
||||||
// MARK: - Begin Validation Logic for SPKProtoTSProtoSenderKeyMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SPKProtoTSProtoSenderKeyMessage -
|
|
||||||
|
|
||||||
let result = SPKProtoTSProtoSenderKeyMessage(proto: proto)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoSenderKeyMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoSenderKeyMessage.SPKProtoTSProtoSenderKeyMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SPKProtoTSProtoSenderKeyMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoSenderKeyDistributionMessage
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoSenderKeyDistributionMessage: NSObject {
|
|
||||||
|
|
||||||
// MARK: - SPKProtoTSProtoSenderKeyDistributionMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder() -> SPKProtoTSProtoSenderKeyDistributionMessageBuilder {
|
|
||||||
return SPKProtoTSProtoSenderKeyDistributionMessageBuilder()
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SPKProtoTSProtoSenderKeyDistributionMessageBuilder {
|
|
||||||
let builder = SPKProtoTSProtoSenderKeyDistributionMessageBuilder()
|
|
||||||
if hasID {
|
|
||||||
builder.setId(id)
|
|
||||||
}
|
|
||||||
if hasIteration {
|
|
||||||
builder.setIteration(iteration)
|
|
||||||
}
|
|
||||||
if let _value = chainKey {
|
|
||||||
builder.setChainKey(_value)
|
|
||||||
}
|
|
||||||
if let _value = signingKey {
|
|
||||||
builder.setSigningKey(_value)
|
|
||||||
}
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SPKProtoTSProtoSenderKeyDistributionMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SPKProtos_TSProtoSenderKeyDistributionMessage()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc public func setId(_ valueParam: UInt32) {
|
|
||||||
proto.id = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setIteration(_ valueParam: UInt32) {
|
|
||||||
proto.iteration = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setChainKey(_ valueParam: Data) {
|
|
||||||
proto.chainKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSigningKey(_ valueParam: Data) {
|
|
||||||
proto.signingKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SPKProtoTSProtoSenderKeyDistributionMessage {
|
|
||||||
return try SPKProtoTSProtoSenderKeyDistributionMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SPKProtoTSProtoSenderKeyDistributionMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SPKProtos_TSProtoSenderKeyDistributionMessage
|
|
||||||
|
|
||||||
@objc public var id: UInt32 {
|
|
||||||
return proto.id
|
|
||||||
}
|
|
||||||
@objc public var hasID: Bool {
|
|
||||||
return proto.hasID
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var iteration: UInt32 {
|
|
||||||
return proto.iteration
|
|
||||||
}
|
|
||||||
@objc public var hasIteration: Bool {
|
|
||||||
return proto.hasIteration
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var chainKey: Data? {
|
|
||||||
guard proto.hasChainKey else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return proto.chainKey
|
|
||||||
}
|
|
||||||
@objc public var hasChainKey: Bool {
|
|
||||||
return proto.hasChainKey
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public var signingKey: Data? {
|
|
||||||
guard proto.hasSigningKey else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return proto.signingKey
|
|
||||||
}
|
|
||||||
@objc public var hasSigningKey: Bool {
|
|
||||||
return proto.hasSigningKey
|
|
||||||
}
|
|
||||||
|
|
||||||
private init(proto: SPKProtos_TSProtoSenderKeyDistributionMessage) {
|
|
||||||
self.proto = proto
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SPKProtoTSProtoSenderKeyDistributionMessage {
|
|
||||||
let proto = try SPKProtos_TSProtoSenderKeyDistributionMessage(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SPKProtos_TSProtoSenderKeyDistributionMessage) throws -> SPKProtoTSProtoSenderKeyDistributionMessage {
|
|
||||||
// MARK: - Begin Validation Logic for SPKProtoTSProtoSenderKeyDistributionMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SPKProtoTSProtoSenderKeyDistributionMessage -
|
|
||||||
|
|
||||||
let result = SPKProtoTSProtoSenderKeyDistributionMessage(proto: proto)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoSenderKeyDistributionMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtoTSProtoSenderKeyDistributionMessage.SPKProtoTSProtoSenderKeyDistributionMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SPKProtoTSProtoSenderKeyDistributionMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - SPKProtoClosedGroupCiphertextMessage
|
|
||||||
|
|
||||||
@objc public class SPKProtoClosedGroupCiphertextMessage: NSObject {
|
|
||||||
|
|
||||||
class var logTag: String { "SPKProtoClosedGroupCiphertextMessage" }
|
|
||||||
|
|
||||||
// MARK: - SPKProtoClosedGroupCiphertextMessageBuilder
|
|
||||||
|
|
||||||
@objc public class func builder(ciphertext: Data, senderPublicKey: Data, keyIndex: UInt32) -> SPKProtoClosedGroupCiphertextMessageBuilder {
|
|
||||||
return SPKProtoClosedGroupCiphertextMessageBuilder(ciphertext: ciphertext, senderPublicKey: senderPublicKey, keyIndex: keyIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
|
||||||
@objc public func asBuilder() -> SPKProtoClosedGroupCiphertextMessageBuilder {
|
|
||||||
let builder = SPKProtoClosedGroupCiphertextMessageBuilder(ciphertext: ciphertext, senderPublicKey: senderPublicKey, keyIndex: keyIndex)
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class SPKProtoClosedGroupCiphertextMessageBuilder: NSObject {
|
|
||||||
|
|
||||||
private var proto = SPKProtos_ClosedGroupCiphertextMessage()
|
|
||||||
|
|
||||||
@objc fileprivate override init() {}
|
|
||||||
|
|
||||||
@objc fileprivate init(ciphertext: Data, senderPublicKey: Data, keyIndex: UInt32) {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
setCiphertext(ciphertext)
|
|
||||||
setSenderPublicKey(senderPublicKey)
|
|
||||||
setKeyIndex(keyIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setCiphertext(_ valueParam: Data) {
|
|
||||||
proto.ciphertext = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setSenderPublicKey(_ valueParam: Data) {
|
|
||||||
proto.senderPublicKey = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setKeyIndex(_ valueParam: UInt32) {
|
|
||||||
proto.keyIndex = valueParam
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func build() throws -> SPKProtoClosedGroupCiphertextMessage {
|
|
||||||
return try SPKProtoClosedGroupCiphertextMessage.parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func buildSerializedData() throws -> Data {
|
|
||||||
return try SPKProtoClosedGroupCiphertextMessage.parseProto(proto).serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate let proto: SPKProtos_ClosedGroupCiphertextMessage
|
|
||||||
|
|
||||||
@objc public let ciphertext: Data
|
|
||||||
|
|
||||||
@objc public let senderPublicKey: Data
|
|
||||||
|
|
||||||
@objc public let keyIndex: UInt32
|
|
||||||
|
|
||||||
private init(proto: SPKProtos_ClosedGroupCiphertextMessage,
|
|
||||||
ciphertext: Data,
|
|
||||||
senderPublicKey: Data,
|
|
||||||
keyIndex: UInt32) {
|
|
||||||
self.proto = proto
|
|
||||||
self.ciphertext = ciphertext
|
|
||||||
self.senderPublicKey = senderPublicKey
|
|
||||||
self.keyIndex = keyIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func serializedData() throws -> Data {
|
|
||||||
return try self.proto.serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parseData(_ serializedData: Data) throws -> SPKProtoClosedGroupCiphertextMessage {
|
|
||||||
let proto = try SPKProtos_ClosedGroupCiphertextMessage(serializedData: serializedData)
|
|
||||||
return try parseProto(proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate class func parseProto(_ proto: SPKProtos_ClosedGroupCiphertextMessage) throws -> SPKProtoClosedGroupCiphertextMessage {
|
|
||||||
guard proto.hasCiphertext else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: ciphertext")
|
|
||||||
}
|
|
||||||
let ciphertext = proto.ciphertext
|
|
||||||
|
|
||||||
guard proto.hasSenderPublicKey else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: senderPublicKey")
|
|
||||||
}
|
|
||||||
let senderPublicKey = proto.senderPublicKey
|
|
||||||
|
|
||||||
guard proto.hasKeyIndex else {
|
|
||||||
throw SPKProtoError.invalidProtobuf(description: "\(logTag) missing required field: keyIndex")
|
|
||||||
}
|
|
||||||
let keyIndex = proto.keyIndex
|
|
||||||
|
|
||||||
// MARK: - Begin Validation Logic for SPKProtoClosedGroupCiphertextMessage -
|
|
||||||
|
|
||||||
// MARK: - End Validation Logic for SPKProtoClosedGroupCiphertextMessage -
|
|
||||||
|
|
||||||
let result = SPKProtoClosedGroupCiphertextMessage(proto: proto,
|
|
||||||
ciphertext: ciphertext,
|
|
||||||
senderPublicKey: senderPublicKey,
|
|
||||||
keyIndex: keyIndex)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public override var debugDescription: String {
|
|
||||||
return "\(proto)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
extension SPKProtoClosedGroupCiphertextMessage {
|
|
||||||
@objc public func serializedDataIgnoringErrors() -> Data? {
|
|
||||||
return try! self.serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtoClosedGroupCiphertextMessage.SPKProtoClosedGroupCiphertextMessageBuilder {
|
|
||||||
@objc public func buildIgnoringErrors() -> SPKProtoClosedGroupCiphertextMessage? {
|
|
||||||
return try! self.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,642 +0,0 @@
|
||||||
// DO NOT EDIT.
|
|
||||||
// swift-format-ignore-file
|
|
||||||
//
|
|
||||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
|
||||||
// Source: WhisperTextProtocol.proto
|
|
||||||
//
|
|
||||||
// For information on using the generated types, please see the documentation:
|
|
||||||
// https://github.com/apple/swift-protobuf/
|
|
||||||
|
|
||||||
/// iOS - since we use a modern proto-compiler, we must specify
|
|
||||||
/// the legacy proto format.
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SwiftProtobuf
|
|
||||||
|
|
||||||
// If the compiler emits an error on this type, it is because this file
|
|
||||||
// was generated by a version of the `protoc` Swift plug-in that is
|
|
||||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
|
||||||
// Please ensure that you are building against the same version of the API
|
|
||||||
// that was used to generate this file.
|
|
||||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
|
||||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
|
||||||
typealias Version = _2
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SPKProtos_TSProtoWhisperMessage {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var ratchetKey: Data {
|
|
||||||
get {return _ratchetKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_ratchetKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `ratchetKey` has been explicitly set.
|
|
||||||
var hasRatchetKey: Bool {return self._ratchetKey != nil}
|
|
||||||
/// Clears the value of `ratchetKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearRatchetKey() {self._ratchetKey = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var counter: UInt32 {
|
|
||||||
get {return _counter ?? 0}
|
|
||||||
set {_counter = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `counter` has been explicitly set.
|
|
||||||
var hasCounter: Bool {return self._counter != nil}
|
|
||||||
/// Clears the value of `counter`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearCounter() {self._counter = nil}
|
|
||||||
|
|
||||||
var previousCounter: UInt32 {
|
|
||||||
get {return _previousCounter ?? 0}
|
|
||||||
set {_previousCounter = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `previousCounter` has been explicitly set.
|
|
||||||
var hasPreviousCounter: Bool {return self._previousCounter != nil}
|
|
||||||
/// Clears the value of `previousCounter`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearPreviousCounter() {self._previousCounter = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var ciphertext: Data {
|
|
||||||
get {return _ciphertext ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_ciphertext = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `ciphertext` has been explicitly set.
|
|
||||||
var hasCiphertext: Bool {return self._ciphertext != nil}
|
|
||||||
/// Clears the value of `ciphertext`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearCiphertext() {self._ciphertext = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _ratchetKey: Data? = nil
|
|
||||||
fileprivate var _counter: UInt32? = nil
|
|
||||||
fileprivate var _previousCounter: UInt32? = nil
|
|
||||||
fileprivate var _ciphertext: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SPKProtos_TSProtoPreKeyWhisperMessage {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
var registrationID: UInt32 {
|
|
||||||
get {return _registrationID ?? 0}
|
|
||||||
set {_registrationID = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `registrationID` has been explicitly set.
|
|
||||||
var hasRegistrationID: Bool {return self._registrationID != nil}
|
|
||||||
/// Clears the value of `registrationID`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearRegistrationID() {self._registrationID = nil}
|
|
||||||
|
|
||||||
var preKeyID: UInt32 {
|
|
||||||
get {return _preKeyID ?? 0}
|
|
||||||
set {_preKeyID = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `preKeyID` has been explicitly set.
|
|
||||||
var hasPreKeyID: Bool {return self._preKeyID != nil}
|
|
||||||
/// Clears the value of `preKeyID`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearPreKeyID() {self._preKeyID = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var signedPreKeyID: UInt32 {
|
|
||||||
get {return _signedPreKeyID ?? 0}
|
|
||||||
set {_signedPreKeyID = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `signedPreKeyID` has been explicitly set.
|
|
||||||
var hasSignedPreKeyID: Bool {return self._signedPreKeyID != nil}
|
|
||||||
/// Clears the value of `signedPreKeyID`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSignedPreKeyID() {self._signedPreKeyID = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var baseKey: Data {
|
|
||||||
get {return _baseKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_baseKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `baseKey` has been explicitly set.
|
|
||||||
var hasBaseKey: Bool {return self._baseKey != nil}
|
|
||||||
/// Clears the value of `baseKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearBaseKey() {self._baseKey = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var identityKey: Data {
|
|
||||||
get {return _identityKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_identityKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `identityKey` has been explicitly set.
|
|
||||||
var hasIdentityKey: Bool {return self._identityKey != nil}
|
|
||||||
/// Clears the value of `identityKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearIdentityKey() {self._identityKey = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var message: Data {
|
|
||||||
get {return _message ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_message = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `message` has been explicitly set.
|
|
||||||
var hasMessage: Bool {return self._message != nil}
|
|
||||||
/// Clears the value of `message`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearMessage() {self._message = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _registrationID: UInt32? = nil
|
|
||||||
fileprivate var _preKeyID: UInt32? = nil
|
|
||||||
fileprivate var _signedPreKeyID: UInt32? = nil
|
|
||||||
fileprivate var _baseKey: Data? = nil
|
|
||||||
fileprivate var _identityKey: Data? = nil
|
|
||||||
fileprivate var _message: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SPKProtos_TSProtoKeyExchangeMessage {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
var id: UInt32 {
|
|
||||||
get {return _id ?? 0}
|
|
||||||
set {_id = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `id` has been explicitly set.
|
|
||||||
var hasID: Bool {return self._id != nil}
|
|
||||||
/// Clears the value of `id`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearID() {self._id = nil}
|
|
||||||
|
|
||||||
var baseKey: Data {
|
|
||||||
get {return _baseKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_baseKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `baseKey` has been explicitly set.
|
|
||||||
var hasBaseKey: Bool {return self._baseKey != nil}
|
|
||||||
/// Clears the value of `baseKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearBaseKey() {self._baseKey = nil}
|
|
||||||
|
|
||||||
var ratchetKey: Data {
|
|
||||||
get {return _ratchetKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_ratchetKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `ratchetKey` has been explicitly set.
|
|
||||||
var hasRatchetKey: Bool {return self._ratchetKey != nil}
|
|
||||||
/// Clears the value of `ratchetKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearRatchetKey() {self._ratchetKey = nil}
|
|
||||||
|
|
||||||
var identityKey: Data {
|
|
||||||
get {return _identityKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_identityKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `identityKey` has been explicitly set.
|
|
||||||
var hasIdentityKey: Bool {return self._identityKey != nil}
|
|
||||||
/// Clears the value of `identityKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearIdentityKey() {self._identityKey = nil}
|
|
||||||
|
|
||||||
var baseKeySignature: Data {
|
|
||||||
get {return _baseKeySignature ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_baseKeySignature = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `baseKeySignature` has been explicitly set.
|
|
||||||
var hasBaseKeySignature: Bool {return self._baseKeySignature != nil}
|
|
||||||
/// Clears the value of `baseKeySignature`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearBaseKeySignature() {self._baseKeySignature = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _id: UInt32? = nil
|
|
||||||
fileprivate var _baseKey: Data? = nil
|
|
||||||
fileprivate var _ratchetKey: Data? = nil
|
|
||||||
fileprivate var _identityKey: Data? = nil
|
|
||||||
fileprivate var _baseKeySignature: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SPKProtos_TSProtoSenderKeyMessage {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
var id: UInt32 {
|
|
||||||
get {return _id ?? 0}
|
|
||||||
set {_id = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `id` has been explicitly set.
|
|
||||||
var hasID: Bool {return self._id != nil}
|
|
||||||
/// Clears the value of `id`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearID() {self._id = nil}
|
|
||||||
|
|
||||||
var iteration: UInt32 {
|
|
||||||
get {return _iteration ?? 0}
|
|
||||||
set {_iteration = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `iteration` has been explicitly set.
|
|
||||||
var hasIteration: Bool {return self._iteration != nil}
|
|
||||||
/// Clears the value of `iteration`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearIteration() {self._iteration = nil}
|
|
||||||
|
|
||||||
var ciphertext: Data {
|
|
||||||
get {return _ciphertext ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_ciphertext = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `ciphertext` has been explicitly set.
|
|
||||||
var hasCiphertext: Bool {return self._ciphertext != nil}
|
|
||||||
/// Clears the value of `ciphertext`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearCiphertext() {self._ciphertext = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _id: UInt32? = nil
|
|
||||||
fileprivate var _iteration: UInt32? = nil
|
|
||||||
fileprivate var _ciphertext: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SPKProtos_TSProtoSenderKeyDistributionMessage {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
var id: UInt32 {
|
|
||||||
get {return _id ?? 0}
|
|
||||||
set {_id = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `id` has been explicitly set.
|
|
||||||
var hasID: Bool {return self._id != nil}
|
|
||||||
/// Clears the value of `id`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearID() {self._id = nil}
|
|
||||||
|
|
||||||
var iteration: UInt32 {
|
|
||||||
get {return _iteration ?? 0}
|
|
||||||
set {_iteration = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `iteration` has been explicitly set.
|
|
||||||
var hasIteration: Bool {return self._iteration != nil}
|
|
||||||
/// Clears the value of `iteration`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearIteration() {self._iteration = nil}
|
|
||||||
|
|
||||||
var chainKey: Data {
|
|
||||||
get {return _chainKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_chainKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `chainKey` has been explicitly set.
|
|
||||||
var hasChainKey: Bool {return self._chainKey != nil}
|
|
||||||
/// Clears the value of `chainKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearChainKey() {self._chainKey = nil}
|
|
||||||
|
|
||||||
var signingKey: Data {
|
|
||||||
get {return _signingKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_signingKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `signingKey` has been explicitly set.
|
|
||||||
var hasSigningKey: Bool {return self._signingKey != nil}
|
|
||||||
/// Clears the value of `signingKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSigningKey() {self._signingKey = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _id: UInt32? = nil
|
|
||||||
fileprivate var _iteration: UInt32? = nil
|
|
||||||
fileprivate var _chainKey: Data? = nil
|
|
||||||
fileprivate var _signingKey: Data? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SPKProtos_ClosedGroupCiphertextMessage {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var ciphertext: Data {
|
|
||||||
get {return _ciphertext ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_ciphertext = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `ciphertext` has been explicitly set.
|
|
||||||
var hasCiphertext: Bool {return self._ciphertext != nil}
|
|
||||||
/// Clears the value of `ciphertext`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearCiphertext() {self._ciphertext = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var senderPublicKey: Data {
|
|
||||||
get {return _senderPublicKey ?? SwiftProtobuf.Internal.emptyData}
|
|
||||||
set {_senderPublicKey = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `senderPublicKey` has been explicitly set.
|
|
||||||
var hasSenderPublicKey: Bool {return self._senderPublicKey != nil}
|
|
||||||
/// Clears the value of `senderPublicKey`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearSenderPublicKey() {self._senderPublicKey = nil}
|
|
||||||
|
|
||||||
/// @required
|
|
||||||
var keyIndex: UInt32 {
|
|
||||||
get {return _keyIndex ?? 0}
|
|
||||||
set {_keyIndex = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `keyIndex` has been explicitly set.
|
|
||||||
var hasKeyIndex: Bool {return self._keyIndex != nil}
|
|
||||||
/// Clears the value of `keyIndex`. Subsequent reads from it will return its default value.
|
|
||||||
mutating func clearKeyIndex() {self._keyIndex = nil}
|
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
fileprivate var _ciphertext: Data? = nil
|
|
||||||
fileprivate var _senderPublicKey: Data? = nil
|
|
||||||
fileprivate var _keyIndex: UInt32? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
|
||||||
|
|
||||||
fileprivate let _protobuf_package = "SPKProtos"
|
|
||||||
|
|
||||||
extension SPKProtos_TSProtoWhisperMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".TSProtoWhisperMessage"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "ratchetKey"),
|
|
||||||
2: .same(proto: "counter"),
|
|
||||||
3: .same(proto: "previousCounter"),
|
|
||||||
4: .same(proto: "ciphertext"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularBytesField(value: &self._ratchetKey)
|
|
||||||
case 2: try decoder.decodeSingularUInt32Field(value: &self._counter)
|
|
||||||
case 3: try decoder.decodeSingularUInt32Field(value: &self._previousCounter)
|
|
||||||
case 4: try decoder.decodeSingularBytesField(value: &self._ciphertext)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._ratchetKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._counter {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._previousCounter {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if let v = self._ciphertext {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SPKProtos_TSProtoWhisperMessage, rhs: SPKProtos_TSProtoWhisperMessage) -> Bool {
|
|
||||||
if lhs._ratchetKey != rhs._ratchetKey {return false}
|
|
||||||
if lhs._counter != rhs._counter {return false}
|
|
||||||
if lhs._previousCounter != rhs._previousCounter {return false}
|
|
||||||
if lhs._ciphertext != rhs._ciphertext {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtos_TSProtoPreKeyWhisperMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".TSProtoPreKeyWhisperMessage"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
5: .same(proto: "registrationId"),
|
|
||||||
1: .same(proto: "preKeyId"),
|
|
||||||
6: .same(proto: "signedPreKeyId"),
|
|
||||||
2: .same(proto: "baseKey"),
|
|
||||||
3: .same(proto: "identityKey"),
|
|
||||||
4: .same(proto: "message"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularUInt32Field(value: &self._preKeyID)
|
|
||||||
case 2: try decoder.decodeSingularBytesField(value: &self._baseKey)
|
|
||||||
case 3: try decoder.decodeSingularBytesField(value: &self._identityKey)
|
|
||||||
case 4: try decoder.decodeSingularBytesField(value: &self._message)
|
|
||||||
case 5: try decoder.decodeSingularUInt32Field(value: &self._registrationID)
|
|
||||||
case 6: try decoder.decodeSingularUInt32Field(value: &self._signedPreKeyID)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._preKeyID {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._baseKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._identityKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if let v = self._message {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
if let v = self._registrationID {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 5)
|
|
||||||
}
|
|
||||||
if let v = self._signedPreKeyID {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 6)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SPKProtos_TSProtoPreKeyWhisperMessage, rhs: SPKProtos_TSProtoPreKeyWhisperMessage) -> Bool {
|
|
||||||
if lhs._registrationID != rhs._registrationID {return false}
|
|
||||||
if lhs._preKeyID != rhs._preKeyID {return false}
|
|
||||||
if lhs._signedPreKeyID != rhs._signedPreKeyID {return false}
|
|
||||||
if lhs._baseKey != rhs._baseKey {return false}
|
|
||||||
if lhs._identityKey != rhs._identityKey {return false}
|
|
||||||
if lhs._message != rhs._message {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtos_TSProtoKeyExchangeMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".TSProtoKeyExchangeMessage"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "id"),
|
|
||||||
2: .same(proto: "baseKey"),
|
|
||||||
3: .same(proto: "ratchetKey"),
|
|
||||||
4: .same(proto: "identityKey"),
|
|
||||||
5: .same(proto: "baseKeySignature"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularUInt32Field(value: &self._id)
|
|
||||||
case 2: try decoder.decodeSingularBytesField(value: &self._baseKey)
|
|
||||||
case 3: try decoder.decodeSingularBytesField(value: &self._ratchetKey)
|
|
||||||
case 4: try decoder.decodeSingularBytesField(value: &self._identityKey)
|
|
||||||
case 5: try decoder.decodeSingularBytesField(value: &self._baseKeySignature)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._id {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._baseKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._ratchetKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if let v = self._identityKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
if let v = self._baseKeySignature {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 5)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SPKProtos_TSProtoKeyExchangeMessage, rhs: SPKProtos_TSProtoKeyExchangeMessage) -> Bool {
|
|
||||||
if lhs._id != rhs._id {return false}
|
|
||||||
if lhs._baseKey != rhs._baseKey {return false}
|
|
||||||
if lhs._ratchetKey != rhs._ratchetKey {return false}
|
|
||||||
if lhs._identityKey != rhs._identityKey {return false}
|
|
||||||
if lhs._baseKeySignature != rhs._baseKeySignature {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtos_TSProtoSenderKeyMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".TSProtoSenderKeyMessage"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "id"),
|
|
||||||
2: .same(proto: "iteration"),
|
|
||||||
3: .same(proto: "ciphertext"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularUInt32Field(value: &self._id)
|
|
||||||
case 2: try decoder.decodeSingularUInt32Field(value: &self._iteration)
|
|
||||||
case 3: try decoder.decodeSingularBytesField(value: &self._ciphertext)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._id {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._iteration {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._ciphertext {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SPKProtos_TSProtoSenderKeyMessage, rhs: SPKProtos_TSProtoSenderKeyMessage) -> Bool {
|
|
||||||
if lhs._id != rhs._id {return false}
|
|
||||||
if lhs._iteration != rhs._iteration {return false}
|
|
||||||
if lhs._ciphertext != rhs._ciphertext {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtos_TSProtoSenderKeyDistributionMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".TSProtoSenderKeyDistributionMessage"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "id"),
|
|
||||||
2: .same(proto: "iteration"),
|
|
||||||
3: .same(proto: "chainKey"),
|
|
||||||
4: .same(proto: "signingKey"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularUInt32Field(value: &self._id)
|
|
||||||
case 2: try decoder.decodeSingularUInt32Field(value: &self._iteration)
|
|
||||||
case 3: try decoder.decodeSingularBytesField(value: &self._chainKey)
|
|
||||||
case 4: try decoder.decodeSingularBytesField(value: &self._signingKey)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._id {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._iteration {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._chainKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if let v = self._signingKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SPKProtos_TSProtoSenderKeyDistributionMessage, rhs: SPKProtos_TSProtoSenderKeyDistributionMessage) -> Bool {
|
|
||||||
if lhs._id != rhs._id {return false}
|
|
||||||
if lhs._iteration != rhs._iteration {return false}
|
|
||||||
if lhs._chainKey != rhs._chainKey {return false}
|
|
||||||
if lhs._signingKey != rhs._signingKey {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPKProtos_ClosedGroupCiphertextMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
static let protoMessageName: String = _protobuf_package + ".ClosedGroupCiphertextMessage"
|
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "ciphertext"),
|
|
||||||
2: .same(proto: "senderPublicKey"),
|
|
||||||
3: .same(proto: "keyIndex"),
|
|
||||||
]
|
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularBytesField(value: &self._ciphertext)
|
|
||||||
case 2: try decoder.decodeSingularBytesField(value: &self._senderPublicKey)
|
|
||||||
case 3: try decoder.decodeSingularUInt32Field(value: &self._keyIndex)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if let v = self._ciphertext {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if let v = self._senderPublicKey {
|
|
||||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if let v = self._keyIndex {
|
|
||||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: SPKProtos_ClosedGroupCiphertextMessage, rhs: SPKProtos_ClosedGroupCiphertextMessage) -> Bool {
|
|
||||||
if lhs._ciphertext != rhs._ciphertext {return false}
|
|
||||||
if lhs._senderPublicKey != rhs._senderPublicKey {return false}
|
|
||||||
if lhs._keyIndex != rhs._keyIndex {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
//
|
|
||||||
// AliceAxolotlParameters.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 26/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import "AxolotlParameters.h"
|
|
||||||
|
|
||||||
@interface AliceAxolotlParameters : NSObject<AxolotlParameters>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly)ECKeyPair *ourBaseKey;
|
|
||||||
@property (nonatomic, readonly)NSData* theirSignedPreKey;
|
|
||||||
@property (nonatomic, readonly)NSData* theirRatchetKey;
|
|
||||||
@property (nonatomic, readonly)NSData* theirOneTimePrekey;
|
|
||||||
|
|
||||||
- (instancetype)initWithIdentityKey:(ECKeyPair*)myIdentityKey theirIdentityKey:(NSData*)theirIdentityKey ourBaseKey:(ECKeyPair*)ourBaseKey theirSignedPreKey:(NSData*)theirSignedPreKey theirOneTimePreKey:(NSData*)theirOneTimePreKey theirRatchetKey:(NSData*)theirRatchetKey;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,39 +0,0 @@
|
||||||
//
|
|
||||||
// AliceAxolotlParameters.m
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 26/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "AliceAxolotlParameters.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
@implementation AliceAxolotlParameters
|
|
||||||
|
|
||||||
@synthesize ourIdentityKeyPair=_ourIdentityKeyPair, theirIdentityKey=_theirIdentityKey;
|
|
||||||
|
|
||||||
- (instancetype)initWithIdentityKey:(ECKeyPair*)myIdentityKey theirIdentityKey:(NSData*)theirIdentityKey ourBaseKey:(ECKeyPair*)ourBaseKey theirSignedPreKey:(NSData*)theirSignedPreKey theirOneTimePreKey:(NSData*)theirOneTimePreKey theirRatchetKey:(NSData*)theirRatchetKey{
|
|
||||||
|
|
||||||
OWSAssert(myIdentityKey);
|
|
||||||
OWSAssert(theirIdentityKey);
|
|
||||||
OWSAssert(ourBaseKey);
|
|
||||||
OWSAssert(theirSignedPreKey);
|
|
||||||
OWSAssert(theirRatchetKey);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_ourIdentityKeyPair = myIdentityKey;
|
|
||||||
_theirIdentityKey = theirIdentityKey;
|
|
||||||
_ourBaseKey = ourBaseKey;
|
|
||||||
_theirSignedPreKey = theirSignedPreKey;
|
|
||||||
_theirOneTimePrekey = theirOneTimePreKey;
|
|
||||||
_theirRatchetKey = theirRatchetKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,13 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
|
|
||||||
@protocol AxolotlParameters <NSObject>
|
|
||||||
|
|
||||||
@property (nonatomic) ECKeyPair *ourIdentityKeyPair;
|
|
||||||
@property (nonatomic) NSData *theirIdentityKey;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,22 +0,0 @@
|
||||||
//
|
|
||||||
// BobAxolotlParameters.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 26/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import "AxolotlParameters.h"
|
|
||||||
|
|
||||||
@interface BobAxolotlParameters : NSObject<AxolotlParameters>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly)ECKeyPair *ourSignedPrekey;
|
|
||||||
@property (nonatomic, readonly)ECKeyPair *ourRatchetKey;
|
|
||||||
@property (nonatomic, readonly)ECKeyPair *ourOneTimePrekey;
|
|
||||||
|
|
||||||
@property (nonatomic, readonly)NSData *theirBaseKey;
|
|
||||||
|
|
||||||
- (instancetype)initWithMyIdentityKeyPair:(ECKeyPair*)ourIdentityKeyPair theirIdentityKey:(NSData*)theirIdentityKey ourSignedPrekey:(ECKeyPair*)ourSignedPrekey ourRatchetKey:(ECKeyPair*)ourRatchetKey ourOneTimePrekey:(ECKeyPair*)ourOneTimeKeyPair theirBaseKey:(NSData*)theirBaseKey;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,37 +0,0 @@
|
||||||
//
|
|
||||||
// BobAxolotlParameters.m
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 26/07/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "BobAxolotlParameters.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
@implementation BobAxolotlParameters
|
|
||||||
|
|
||||||
@synthesize theirIdentityKey=_theirIdentityKey, ourIdentityKeyPair=_ourIdentityKeyPair;
|
|
||||||
|
|
||||||
- (instancetype)initWithMyIdentityKeyPair:(ECKeyPair*)ourIdentityKeyPair theirIdentityKey:(NSData*)theirIdentityKey ourSignedPrekey:(ECKeyPair*)ourSignedPrekey ourRatchetKey:(ECKeyPair*)ourRatchetKey ourOneTimePrekey:(ECKeyPair*)ourOneTimeKeyPair theirBaseKey:(NSData*)theirBaseKey{
|
|
||||||
|
|
||||||
OWSAssert(ourIdentityKeyPair);
|
|
||||||
OWSAssert(theirIdentityKey);
|
|
||||||
OWSAssert(ourSignedPrekey);
|
|
||||||
OWSAssert(ourRatchetKey);
|
|
||||||
OWSAssert(theirBaseKey);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_ourIdentityKeyPair = ourIdentityKeyPair;
|
|
||||||
_theirIdentityKey = theirIdentityKey;
|
|
||||||
_ourSignedPrekey = ourSignedPrekey;
|
|
||||||
_ourRatchetKey = ourRatchetKey;
|
|
||||||
_ourOneTimePrekey = ourOneTimeKeyPair;
|
|
||||||
_theirBaseKey = theirBaseKey;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,17 +0,0 @@
|
||||||
//
|
|
||||||
// Chain.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 02/09/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
@class ChainKey;
|
|
||||||
|
|
||||||
@protocol Chain <NSObject, NSSecureCoding>
|
|
||||||
|
|
||||||
-(ChainKey*)chainKey;
|
|
||||||
-(void)setChainKey:(ChainKey*)chainKey;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,17 +0,0 @@
|
||||||
//
|
|
||||||
// ChainAndIndex.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 21/09/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import "ChainKey.h"
|
|
||||||
|
|
||||||
@interface ChainAndIndex : NSObject
|
|
||||||
|
|
||||||
@property id<Chain> chain;
|
|
||||||
@property int index;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,13 +0,0 @@
|
||||||
//
|
|
||||||
// ChainAndIndex.m
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 21/09/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "ChainAndIndex.h"
|
|
||||||
|
|
||||||
@implementation ChainAndIndex
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,25 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "Chain.h"
|
|
||||||
#import "MessageKeys.h"
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface ChainKey : NSObject <NSSecureCoding>
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) int index;
|
|
||||||
@property (nonatomic, readonly) NSData *key;
|
|
||||||
|
|
||||||
- (instancetype)init NS_UNAVAILABLE;
|
|
||||||
- (instancetype)initWithData:(NSData *)chainKey index:(int)index NS_DESIGNATED_INITIALIZER;
|
|
||||||
|
|
||||||
- (instancetype)nextChainKey;
|
|
||||||
|
|
||||||
- (MessageKeys *)throws_messageKeys NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,96 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "ChainKey.h"
|
|
||||||
#import "TSDerivedSecrets.h"
|
|
||||||
#import <CommonCrypto/CommonCrypto.h>
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@implementation ChainKey
|
|
||||||
|
|
||||||
static NSString *const kCoderKey = @"kCoderKey";
|
|
||||||
static NSString *const kCoderIndex = @"kCoderIndex";
|
|
||||||
|
|
||||||
#define kTSKeySeedLength 1
|
|
||||||
|
|
||||||
static uint8_t kMessageKeySeed[kTSKeySeedLength] = { 01 };
|
|
||||||
static uint8_t kChainKeySeed[kTSKeySeedLength] = { 02 };
|
|
||||||
|
|
||||||
+ (BOOL)supportsSecureCoding
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable id)initWithCoder:(NSCoder *)aDecoder
|
|
||||||
{
|
|
||||||
NSData *key = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderKey];
|
|
||||||
int index = [aDecoder decodeIntForKey:kCoderIndex];
|
|
||||||
|
|
||||||
return [self initWithData:key index:index];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder
|
|
||||||
{
|
|
||||||
[aCoder encodeObject:_key forKey:kCoderKey];
|
|
||||||
[aCoder encodeInt:_index forKey:kCoderIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithData:(NSData *)chainKey index:(int)index
|
|
||||||
{
|
|
||||||
OWSAssert(chainKey.length == 32);
|
|
||||||
OWSAssert(index >= 0);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_key = chainKey;
|
|
||||||
_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)nextChainKey
|
|
||||||
{
|
|
||||||
NSData *nextCK = [self baseMaterial:[NSData dataWithBytes:kChainKeySeed length:kTSKeySeedLength]];
|
|
||||||
OWSAssert(nextCK.length == 32);
|
|
||||||
|
|
||||||
int nextIndex;
|
|
||||||
ows_add_overflow(self.index, 1, &nextIndex);
|
|
||||||
return [[ChainKey alloc] initWithData:nextCK index:nextIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (MessageKeys *)throws_messageKeys
|
|
||||||
{
|
|
||||||
NSData *inputKeyMaterial = [self baseMaterial:[NSData dataWithBytes:kMessageKeySeed length:kTSKeySeedLength]];
|
|
||||||
TSDerivedSecrets *derivedSecrets = [TSDerivedSecrets throws_derivedMessageKeysWithData:inputKeyMaterial];
|
|
||||||
return [[MessageKeys alloc] initWithCipherKey:derivedSecrets.cipherKey
|
|
||||||
macKey:derivedSecrets.macKey
|
|
||||||
iv:derivedSecrets.iv
|
|
||||||
index:self.index];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSData *)baseMaterial:(NSData *)seed
|
|
||||||
{
|
|
||||||
OWSAssert(self.key);
|
|
||||||
OWSAssert(self.key.length == 32);
|
|
||||||
OWSAssert(seed);
|
|
||||||
OWSAssert(seed.length == kTSKeySeedLength);
|
|
||||||
|
|
||||||
NSMutableData *_Nullable bufferData = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
|
|
||||||
OWSAssert(bufferData);
|
|
||||||
|
|
||||||
CCHmacContext ctx;
|
|
||||||
CCHmacInit(&ctx, kCCHmacAlgSHA256, [self.key bytes], [self.key length]);
|
|
||||||
CCHmacUpdate(&ctx, [seed bytes], [seed length]);
|
|
||||||
CCHmacFinal(&ctx, bufferData.mutableBytes);
|
|
||||||
return [bufferData copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,20 +0,0 @@
|
||||||
//
|
|
||||||
// TSMessageKeys.h
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 09/03/14.
|
|
||||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@interface MessageKeys : NSObject <NSSecureCoding>
|
|
||||||
|
|
||||||
- (instancetype)initWithCipherKey:(NSData*)cipherKey macKey:(NSData*)macKey iv:(NSData*)data index:(int)index;
|
|
||||||
|
|
||||||
@property (readonly)NSData *cipherKey;
|
|
||||||
@property (readonly)NSData *macKey;
|
|
||||||
@property (readonly)NSData *iv;
|
|
||||||
@property (readonly)int index;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,62 +0,0 @@
|
||||||
//
|
|
||||||
// TSMessageKeys.m
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 09/03/14.
|
|
||||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "MessageKeys.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
static NSString* const kCoderMessageKeysCipherKey = @"kCoderMessageKeysCipherKey";
|
|
||||||
static NSString* const kCoderMessageKeysMacKey = @"kCoderMessageKeysMacKey";
|
|
||||||
static NSString* const kCoderMessageKeysIVKey = @"kCoderMessageKeysIVKey";
|
|
||||||
static NSString* const kCoderMessageKeysIndex = @"kCoderMessageKeysIndex";
|
|
||||||
|
|
||||||
|
|
||||||
@implementation MessageKeys
|
|
||||||
|
|
||||||
+ (BOOL)supportsSecureCoding{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
|
||||||
self = [self initWithCipherKey:[aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderMessageKeysCipherKey]
|
|
||||||
macKey:[aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderMessageKeysMacKey]
|
|
||||||
iv:[aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderMessageKeysIVKey]
|
|
||||||
index:[aDecoder decodeIntForKey:kCoderMessageKeysIndex]];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder{
|
|
||||||
[aCoder encodeObject:self.cipherKey forKey:kCoderMessageKeysCipherKey];
|
|
||||||
[aCoder encodeObject:self.macKey forKey:kCoderMessageKeysMacKey];
|
|
||||||
[aCoder encodeObject:self.iv forKey:kCoderMessageKeysIVKey];
|
|
||||||
[aCoder encodeInt:self.index forKey:kCoderMessageKeysIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (instancetype)initWithCipherKey:(NSData*)cipherKey macKey:(NSData*)macKey iv:(NSData *)data index:(int)index{
|
|
||||||
|
|
||||||
OWSAssert(cipherKey);
|
|
||||||
OWSAssert(macKey);
|
|
||||||
OWSAssert(data);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_cipherKey = cipherKey;
|
|
||||||
_macKey = macKey;
|
|
||||||
_iv = data;
|
|
||||||
_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(NSString*) debugDescription {
|
|
||||||
return [NSString stringWithFormat:@"cipherKey: %@\n macKey %@\n",self.cipherKey,self.macKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,19 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "Chain.h"
|
|
||||||
#import "RootKey.h"
|
|
||||||
#import "SessionState.h"
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@class ECKeyPair;
|
|
||||||
|
|
||||||
@interface RKCK : NSObject
|
|
||||||
|
|
||||||
@property (nonatomic,strong) RootKey *rootKey;
|
|
||||||
@property (nonatomic,strong) ChainKey *chainKey;
|
|
||||||
|
|
||||||
-(instancetype) initWithRK:(RootKey*)rootKey CK:(ChainKey*)chainKey;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,22 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "RKCK.h"
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
#import "TSDerivedSecrets.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
@implementation RKCK
|
|
||||||
|
|
||||||
- (instancetype)initWithRK:(RootKey*)rootKey CK:(ChainKey*)chainKey{
|
|
||||||
OWSAssert(rootKey);
|
|
||||||
OWSAssert(chainKey);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
self.rootKey = rootKey;
|
|
||||||
self.chainKey = chainKey;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,41 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@class AliceAxolotlParameters;
|
|
||||||
@class BobAxolotlParameters;
|
|
||||||
@class ECKeyPair;
|
|
||||||
@class SessionState;
|
|
||||||
|
|
||||||
@interface RatchetingSession : NSObject
|
|
||||||
|
|
||||||
+ (void)throws_initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
AliceParameters:(AliceAxolotlParameters *)parameters NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
+ (BOOL)initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
aliceParameters:(AliceAxolotlParameters *)aliceParameters
|
|
||||||
error:(NSError **)outError;
|
|
||||||
|
|
||||||
+ (void)throws_initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
BobParameters:(BobAxolotlParameters *)parameters NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
+ (BOOL)initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
bobParameters:(BobAxolotlParameters *)bobParameters
|
|
||||||
error:(NSError **)outError;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For testing purposes
|
|
||||||
*/
|
|
||||||
|
|
||||||
+ (void)throws_initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
AliceParameters:(AliceAxolotlParameters *)parameters
|
|
||||||
senderRatchet:(ECKeyPair *)ratchet NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,188 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "RatchetingSession.h"
|
|
||||||
#import "AliceAxolotlParameters.h"
|
|
||||||
#import "BobAxolotlParameters.h"
|
|
||||||
#import "ChainKey.h"
|
|
||||||
#import "RootKey.h"
|
|
||||||
#import "SessionState.h"
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
#import <HKDFKit/HKDFKit.h>
|
|
||||||
#import <SignalCoreKit/SCKExceptionWrapper.h>
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
@interface DHEResult : NSObject
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) RootKey *rootKey;
|
|
||||||
@property (nonatomic, readonly) NSData *chainKey;
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withMasterKey:(NSData *)data NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation DHEResult
|
|
||||||
|
|
||||||
- (instancetype)init_throws_withMasterKey:(NSData *)data
|
|
||||||
{
|
|
||||||
// DHE Result is expected to be the result of 3 or 4 DHEs outputting 32 bytes each,
|
|
||||||
// plus the 32 discontinuity bytes added to make V3 incompatible with V2
|
|
||||||
OWSAssert([data length] == 32 * 4 || [data length] == 32 * 5);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
const char *HKDFDefaultSalt[4] = {0};
|
|
||||||
NSData *salt = [NSData dataWithBytes:HKDFDefaultSalt length:sizeof(HKDFDefaultSalt)];
|
|
||||||
NSData *info = [@"WhisperText" dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
NSData *derivedMaterial = [HKDFKit deriveKey:data info:info salt:salt outputSize:64];
|
|
||||||
OWSAssert(derivedMaterial.length == 64);
|
|
||||||
_rootKey = [[RootKey alloc] initWithData:[derivedMaterial subdataWithRange:NSMakeRange(0, 32)]];
|
|
||||||
_chainKey = [derivedMaterial subdataWithRange:NSMakeRange(32, 32)];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation RatchetingSession
|
|
||||||
|
|
||||||
+ (void)throws_initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
AliceParameters:(AliceAxolotlParameters *)parameters
|
|
||||||
{
|
|
||||||
OWSAssert(session);
|
|
||||||
OWSAssert(parameters);
|
|
||||||
|
|
||||||
ECKeyPair *sendingRatchetKey = [Curve25519 generateKeyPair];
|
|
||||||
OWSAssert(sendingRatchetKey);
|
|
||||||
[self throws_initializeSession:session
|
|
||||||
sessionVersion:sessionVersion
|
|
||||||
AliceParameters:parameters
|
|
||||||
senderRatchet:sendingRatchetKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (BOOL)initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
bobParameters:(BobAxolotlParameters *)bobParameters
|
|
||||||
error:(NSError **)outError
|
|
||||||
{
|
|
||||||
return [SCKExceptionWrapper
|
|
||||||
tryBlock:^{
|
|
||||||
[self throws_initializeSession:session sessionVersion:sessionVersion BobParameters:bobParameters];
|
|
||||||
}
|
|
||||||
error:outError];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)throws_initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
BobParameters:(BobAxolotlParameters *)parameters
|
|
||||||
{
|
|
||||||
OWSAssert(session);
|
|
||||||
OWSAssert(parameters);
|
|
||||||
|
|
||||||
[session setVersion:sessionVersion];
|
|
||||||
[session setRemoteIdentityKey:parameters.theirIdentityKey];
|
|
||||||
[session setLocalIdentityKey:parameters.ourIdentityKeyPair.publicKey];
|
|
||||||
|
|
||||||
DHEResult *result = [self throws_DHEKeyAgreement:parameters];
|
|
||||||
OWSAssert(result);
|
|
||||||
|
|
||||||
[session setSenderChain:parameters.ourRatchetKey chainKey:[[ChainKey alloc]initWithData:result.chainKey index:0]];
|
|
||||||
[session setRootKey:result.rootKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (BOOL)initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
aliceParameters:(AliceAxolotlParameters *)aliceParameters
|
|
||||||
error:(NSError **)outError
|
|
||||||
{
|
|
||||||
return [SCKExceptionWrapper
|
|
||||||
tryBlock:^{
|
|
||||||
[self throws_initializeSession:session sessionVersion:sessionVersion AliceParameters:aliceParameters];
|
|
||||||
}
|
|
||||||
error:outError];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)throws_initializeSession:(SessionState *)session
|
|
||||||
sessionVersion:(int)sessionVersion
|
|
||||||
AliceParameters:(AliceAxolotlParameters *)parameters
|
|
||||||
senderRatchet:(ECKeyPair *)sendingRatchet
|
|
||||||
{
|
|
||||||
|
|
||||||
OWSAssert(session);
|
|
||||||
OWSAssert(parameters);
|
|
||||||
OWSAssert(sendingRatchet);
|
|
||||||
|
|
||||||
[session setVersion:sessionVersion];
|
|
||||||
[session setRemoteIdentityKey:parameters.theirIdentityKey];
|
|
||||||
[session setLocalIdentityKey:parameters.ourIdentityKeyPair.publicKey];
|
|
||||||
|
|
||||||
DHEResult *result = [self throws_DHEKeyAgreement:parameters];
|
|
||||||
OWSAssert(result);
|
|
||||||
RKCK *sendingChain =
|
|
||||||
[result.rootKey throws_createChainWithTheirEphemeral:parameters.theirRatchetKey ourEphemeral:sendingRatchet];
|
|
||||||
OWSAssert(sendingChain);
|
|
||||||
|
|
||||||
[session addReceiverChain:parameters.theirRatchetKey chainKey:[[ChainKey alloc]initWithData:result.chainKey index:0]];
|
|
||||||
[session setSenderChain:sendingRatchet chainKey:sendingChain.chainKey];
|
|
||||||
[session setRootKey:sendingChain.rootKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (DHEResult *)throws_DHEKeyAgreement:(id<AxolotlParameters>)parameters
|
|
||||||
{
|
|
||||||
OWSAssert(parameters);
|
|
||||||
|
|
||||||
NSMutableData *masterKey = [NSMutableData data];
|
|
||||||
|
|
||||||
[masterKey appendData:[self discontinuityBytes]];
|
|
||||||
|
|
||||||
if ([parameters isKindOfClass:[AliceAxolotlParameters class]]) {
|
|
||||||
AliceAxolotlParameters *params = (AliceAxolotlParameters*)parameters;
|
|
||||||
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirSignedPreKey
|
|
||||||
andKeyPair:params.ourIdentityKeyPair]];
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirIdentityKey
|
|
||||||
andKeyPair:params.ourBaseKey]];
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirSignedPreKey
|
|
||||||
andKeyPair:params.ourBaseKey]];
|
|
||||||
if (params.theirOneTimePrekey) {
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirOneTimePrekey
|
|
||||||
andKeyPair:params.ourBaseKey]];
|
|
||||||
}
|
|
||||||
} else if ([parameters isKindOfClass:[BobAxolotlParameters class]]){
|
|
||||||
BobAxolotlParameters *params = (BobAxolotlParameters*)parameters;
|
|
||||||
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirIdentityKey
|
|
||||||
andKeyPair:params.ourSignedPrekey]];
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirBaseKey
|
|
||||||
andKeyPair:params.ourIdentityKeyPair]];
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirBaseKey
|
|
||||||
andKeyPair:params.ourSignedPrekey]];
|
|
||||||
if (params.ourOneTimePrekey) {
|
|
||||||
[masterKey appendData:[Curve25519 throws_generateSharedSecretFromPublicKey:params.theirBaseKey
|
|
||||||
andKeyPair:params.ourOneTimePrekey]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [[DHEResult alloc] init_throws_withMasterKey:masterKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The discontinuity bytes enforce that the session initialization is different between protocol V2 and V3.
|
|
||||||
*
|
|
||||||
* @return Returns 32-bytes of 0xFF
|
|
||||||
*/
|
|
||||||
|
|
||||||
+ (NSData*)discontinuityBytes{
|
|
||||||
NSMutableData *discontinuity = [NSMutableData data];
|
|
||||||
int8_t byte = 0xFF;
|
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++) {
|
|
||||||
[discontinuity appendBytes:&byte length:sizeof(int8_t)];
|
|
||||||
}
|
|
||||||
return [NSData dataWithData:discontinuity];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,16 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import "Chain.h"
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
|
|
||||||
@interface ReceivingChain : NSObject <Chain, NSSecureCoding>
|
|
||||||
|
|
||||||
- (instancetype)initWithChainKey:(ChainKey*)chainKey senderRatchetKey:(NSData*)senderRatchet;
|
|
||||||
|
|
||||||
@property NSMutableArray *messageKeysList;
|
|
||||||
@property NSData *senderRatchetKey;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,57 +0,0 @@
|
||||||
//
|
|
||||||
// ReceivingChain.m
|
|
||||||
// AxolotlKit
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 02/09/14.
|
|
||||||
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "ReceivingChain.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
@interface ReceivingChain ()
|
|
||||||
|
|
||||||
@property (nonatomic)ChainKey *chainKey;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ReceivingChain
|
|
||||||
|
|
||||||
static NSString* const kCoderChainKey = @"kCoderChainKey";
|
|
||||||
static NSString* const kCoderSenderRatchet = @"kCoderSenderRatchet";
|
|
||||||
static NSString* const kCoderMessageKeys = @"kCoderMessageKeys";
|
|
||||||
|
|
||||||
+ (BOOL)supportsSecureCoding{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
|
||||||
self = [self initWithChainKey:[aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderChainKey]
|
|
||||||
senderRatchetKey:[aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderSenderRatchet]];
|
|
||||||
if (self) {
|
|
||||||
self.messageKeysList = [aDecoder decodeObjectOfClass:[NSMutableArray class] forKey:kCoderMessageKeys];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder{
|
|
||||||
[aCoder encodeObject:self.chainKey forKey:kCoderChainKey];
|
|
||||||
[aCoder encodeObject:self.senderRatchetKey forKey:kCoderSenderRatchet];
|
|
||||||
[aCoder encodeObject:self.messageKeysList forKey:kCoderMessageKeys];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithChainKey:(ChainKey *)chainKey senderRatchetKey:(NSData *)senderRatchet{
|
|
||||||
OWSAssert(chainKey);
|
|
||||||
OWSAssert(senderRatchet);
|
|
||||||
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
self.chainKey = chainKey;
|
|
||||||
self.senderRatchetKey = senderRatchet;
|
|
||||||
self.messageKeysList = [NSMutableArray array];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,18 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@class ECKeyPair;
|
|
||||||
@class RKCK;
|
|
||||||
|
|
||||||
@interface RootKey : NSObject <NSSecureCoding>
|
|
||||||
|
|
||||||
- (instancetype)initWithData:(NSData *)data;
|
|
||||||
- (RKCK *)throws_createChainWithTheirEphemeral:(NSData *)theirEphemeral
|
|
||||||
ourEphemeral:(ECKeyPair *)ourEphemeral NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSData *keyData;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,64 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "RootKey.h"
|
|
||||||
#import "ChainKey.h"
|
|
||||||
#import "RKCK.h"
|
|
||||||
#import "TSDerivedSecrets.h"
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
static NSString* const kCoderData = @"kCoderData";
|
|
||||||
|
|
||||||
@implementation RootKey
|
|
||||||
|
|
||||||
+(BOOL)supportsSecureCoding{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder{
|
|
||||||
[aCoder encodeObject:_keyData forKey:kCoderData];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_keyData = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderData];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithData:(NSData *)data{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
OWSAssert(data.length == 32);
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_keyData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (RKCK *)throws_createChainWithTheirEphemeral:(NSData *)theirEphemeral ourEphemeral:(ECKeyPair *)ourEphemeral
|
|
||||||
{
|
|
||||||
OWSAssert(theirEphemeral);
|
|
||||||
OWSAssert(ourEphemeral);
|
|
||||||
|
|
||||||
NSData *sharedSecret = [Curve25519 throws_generateSharedSecretFromPublicKey:theirEphemeral andKeyPair:ourEphemeral];
|
|
||||||
OWSAssert(sharedSecret.length == 32);
|
|
||||||
|
|
||||||
TSDerivedSecrets *secrets =
|
|
||||||
[TSDerivedSecrets throws_derivedRatchetedSecretsWithSharedSecret:sharedSecret rootKey:_keyData];
|
|
||||||
OWSAssert(secrets);
|
|
||||||
|
|
||||||
RKCK *newRKCK = [[RKCK alloc] initWithRK:[[RootKey alloc] initWithData:secrets.cipherKey]
|
|
||||||
CK:[[ChainKey alloc] initWithData:secrets.macKey index:0]];
|
|
||||||
|
|
||||||
return newRKCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,16 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import "Chain.h"
|
|
||||||
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
|
|
||||||
@interface SendingChain : NSObject <Chain, NSSecureCoding>
|
|
||||||
|
|
||||||
-(instancetype)initWithChainKey:(ChainKey*)chainKey senderRatchetKeyPair:(ECKeyPair*)keyPair;
|
|
||||||
|
|
||||||
@property ECKeyPair *senderRatchetKeyPair;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,54 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "SendingChain.h"
|
|
||||||
#import "ChainKey.h"
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
|
|
||||||
@interface SendingChain ()
|
|
||||||
|
|
||||||
@property (nonatomic)ChainKey *chainKey;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation SendingChain
|
|
||||||
|
|
||||||
static NSString* const kCoderChainKey = @"kCoderChainKey";
|
|
||||||
static NSString* const kCoderSenderRatchet = @"kCoderSenderRatchet";
|
|
||||||
|
|
||||||
+ (BOOL)supportsSecureCoding{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
|
||||||
self = [self initWithChainKey:[aDecoder decodeObjectOfClass:[ChainKey class] forKey:kCoderChainKey]
|
|
||||||
senderRatchetKeyPair:[aDecoder decodeObjectOfClass:[ECKeyPair class] forKey:kCoderSenderRatchet]];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder{
|
|
||||||
[aCoder encodeObject:self.chainKey forKey:kCoderChainKey];
|
|
||||||
[aCoder encodeObject:self.senderRatchetKeyPair forKey:kCoderSenderRatchet];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithChainKey:(ChainKey *)chainKey senderRatchetKeyPair:(ECKeyPair *)keyPair{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
OWSAssert(chainKey.key.length == 32);
|
|
||||||
OWSAssert(keyPair);
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_chainKey = chainKey;
|
|
||||||
_senderRatchetKeyPair = keyPair;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(ChainKey *)chainKey{
|
|
||||||
return _chainKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,20 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@interface TSDerivedSecrets : NSData
|
|
||||||
|
|
||||||
+ (instancetype)throws_derivedInitialSecretsWithMasterKey:(NSData *)masterKey
|
|
||||||
NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
+ (instancetype)throws_derivedRatchetedSecretsWithSharedSecret:(NSData *)masterKey
|
|
||||||
rootKey:(NSData *)rootKey
|
|
||||||
NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
+ (instancetype)throws_derivedMessageKeysWithData:(NSData *)data NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@property NSData *cipherKey;
|
|
||||||
@property NSData *macKey;
|
|
||||||
@property NSData *iv;
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,67 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "TSDerivedSecrets.h"
|
|
||||||
#import <Curve25519Kit/Curve25519.h>
|
|
||||||
#import <SignalCoreKit/OWSAsserts.h>
|
|
||||||
#import <HKDFKit/HKDFKit.h>
|
|
||||||
|
|
||||||
@implementation TSDerivedSecrets
|
|
||||||
|
|
||||||
+ (instancetype)throws_derivedSecretsWithSeed:(NSData *)masterKey salt:(NSData *)salt info:(NSData *)info
|
|
||||||
{
|
|
||||||
OWSAssert(masterKey.length == 32);
|
|
||||||
OWSAssert(info);
|
|
||||||
|
|
||||||
TSDerivedSecrets *secrets = [[TSDerivedSecrets alloc] init];
|
|
||||||
OWSAssert(secrets);
|
|
||||||
|
|
||||||
if (!salt) {
|
|
||||||
const char *HKDFDefaultSalt[4] = {0};
|
|
||||||
salt = [NSData dataWithBytes:HKDFDefaultSalt length:sizeof(HKDFDefaultSalt)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@try {
|
|
||||||
NSData *derivedMaterial = [HKDFKit deriveKey:masterKey info:info salt:salt outputSize:96];
|
|
||||||
secrets.cipherKey = [derivedMaterial subdataWithRange:NSMakeRange(0, 32)];
|
|
||||||
secrets.macKey = [derivedMaterial subdataWithRange:NSMakeRange(32, 32)];
|
|
||||||
secrets.iv = [derivedMaterial subdataWithRange:NSMakeRange(64, 16)];
|
|
||||||
}
|
|
||||||
@catch (NSException *exception) {
|
|
||||||
@throw NSInvalidArgumentException;
|
|
||||||
}
|
|
||||||
|
|
||||||
OWSAssert(secrets.cipherKey.length == 32);
|
|
||||||
OWSAssert(secrets.macKey.length == 32);
|
|
||||||
OWSAssert(secrets.iv.length == 16);
|
|
||||||
|
|
||||||
return secrets;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (instancetype)throws_derivedInitialSecretsWithMasterKey:(NSData *)masterKey
|
|
||||||
{
|
|
||||||
OWSAssert(masterKey);
|
|
||||||
|
|
||||||
NSData *info = [@"WhisperText" dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
return [self throws_derivedSecretsWithSeed:masterKey salt:nil info:info];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (instancetype)throws_derivedRatchetedSecretsWithSharedSecret:(NSData *)masterKey rootKey:(NSData *)rootKey
|
|
||||||
{
|
|
||||||
OWSAssert(masterKey);
|
|
||||||
OWSAssert(rootKey);
|
|
||||||
|
|
||||||
NSData *info = [@"WhisperRatchet" dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
return [self throws_derivedSecretsWithSeed:masterKey salt:rootKey info:info];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (instancetype)throws_derivedMessageKeysWithData:(NSData *)data
|
|
||||||
{
|
|
||||||
OWSAssert(data);
|
|
||||||
|
|
||||||
NSData *info = [@"WhisperMessageKeys" dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
return [self throws_derivedSecretsWithSeed:data salt:nil info:info];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,107 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SignalCoreKit
|
|
||||||
|
|
||||||
public enum SMKCertificateError: Error {
|
|
||||||
case invalidCertificate(description: String)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public protocol SMKCertificateValidator: class {
|
|
||||||
|
|
||||||
@objc func throwswrapped_validate(senderCertificate: SMKSenderCertificate, validationTime: UInt64) throws
|
|
||||||
|
|
||||||
@objc func throwswrapped_validate(serverCertificate: SMKServerCertificate) throws
|
|
||||||
}
|
|
||||||
|
|
||||||
// See: https://github.com/signalapp/libsignal-metadata-java/blob/master/java/src/main/java/org/signal/libsignal/metadata/certificate/CertificateValidator.java
|
|
||||||
//public class CertificateValidator {
|
|
||||||
@objc public class SMKCertificateDefaultValidator: NSObject, SMKCertificateValidator {
|
|
||||||
|
|
||||||
// @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
|
||||||
// private static final Set<Integer> REVOKED = new HashSet<Integer>() {{
|
|
||||||
//
|
|
||||||
// }};
|
|
||||||
private static let kRevokedCertificateIds = Set<UInt32>()
|
|
||||||
|
|
||||||
//
|
|
||||||
// private final ECPublicKey trustRoot;
|
|
||||||
private let trustRoot: ECPublicKey
|
|
||||||
|
|
||||||
// public CertificateValidator(ECPublicKey trustRoot) {
|
|
||||||
// this.trustRoot = trustRoot;
|
|
||||||
// }
|
|
||||||
@objc public init(trustRoot: ECPublicKey ) {
|
|
||||||
self.trustRoot = trustRoot
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void validate(SenderCertificate certificate, long validationTime) throws InvalidCertificateException {
|
|
||||||
@objc public func throwswrapped_validate(senderCertificate: SMKSenderCertificate, validationTime: UInt64) throws {
|
|
||||||
// try {
|
|
||||||
// ServerCertificate serverCertificate = certificate.getSigner();
|
|
||||||
// let serverCertificate = senderCertificate.signer
|
|
||||||
|
|
||||||
// validate(serverCertificate);
|
|
||||||
// try throwswrapped_validate(serverCertificate: serverCertificate)
|
|
||||||
|
|
||||||
// if (!Curve.verifySignature(serverCertificate.getKey(), certificate.getCertificate(), certificate.getSignature())) {
|
|
||||||
// throw new InvalidCertificateException("Signature failed");
|
|
||||||
// }
|
|
||||||
// let certificateData = try senderCertificate.toProto().certificate
|
|
||||||
// guard try Ed25519.verifySignature(senderCertificate.signatureData,
|
|
||||||
// publicKey: serverCertificate.key.keyData,
|
|
||||||
// data: certificateData) else {
|
|
||||||
// Logger.error("Sender certificate signature verification failed.")
|
|
||||||
// let error = SMKCertificateError.invalidCertificate(description: "Sender certificate signature verification failed.")
|
|
||||||
// Logger.error("\(error)")
|
|
||||||
// throw error
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (validationTime > certificate.getExpiration()) {
|
|
||||||
// throw new InvalidCertificateException("Certificate is expired");
|
|
||||||
// }
|
|
||||||
// guard validationTime <= senderCertificate.expirationTimestamp else {
|
|
||||||
// let error = SMKCertificateError.invalidCertificate(description: "Certficate is expired.")
|
|
||||||
// Logger.error("\(error)")
|
|
||||||
// throw error
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } catch (InvalidKeyException e) {
|
|
||||||
// throw new InvalidCertificateException(e);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// // VisibleForTesting
|
|
||||||
// void validate(ServerCertificate certificate) throws InvalidCertificateException {
|
|
||||||
@objc public func throwswrapped_validate(serverCertificate: SMKServerCertificate) throws {
|
|
||||||
// try {
|
|
||||||
// if (!Curve.verifySignature(trustRoot, certificate.getCertificate(), certificate.getSignature())) {
|
|
||||||
// throw new InvalidCertificateException("Signature failed");
|
|
||||||
// }
|
|
||||||
let certificateBuilder = SMKProtoServerCertificateCertificate.builder(id: serverCertificate.keyId,
|
|
||||||
key: serverCertificate.key.serialized)
|
|
||||||
let certificateData = try certificateBuilder.build().serializedData()
|
|
||||||
|
|
||||||
// let certificateData = try serverCertificate.toProto().certificate
|
|
||||||
guard try Ed25519.verifySignature(serverCertificate.signatureData,
|
|
||||||
publicKey: trustRoot.keyData,
|
|
||||||
data: certificateData) else {
|
|
||||||
let error = SMKCertificateError.invalidCertificate(description: "Server certificate signature verification failed.")
|
|
||||||
Logger.error("\(error)")
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
// if (REVOKED.contains(certificate.getKeyId())) {
|
|
||||||
// throw new InvalidCertificateException("Server certificate has been revoked");
|
|
||||||
// }
|
|
||||||
guard !SMKCertificateDefaultValidator.kRevokedCertificateIds.contains(serverCertificate.keyId) else {
|
|
||||||
let error = SMKCertificateError.invalidCertificate(description: "Revoked certificate.")
|
|
||||||
Logger.error("\(error)")
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
// } catch (InvalidKeyException e) {
|
|
||||||
// throw new InvalidCertificateException(e);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
public enum SMKError: Error {
|
|
||||||
case assertionError(description: String)
|
|
||||||
}
|
|
|
@ -1,563 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import HKDFKit
|
|
||||||
import SignalCoreKit
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public class SecretSessionKnownSenderError: NSObject, CustomNSError {
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public static let kSenderRecipientIdKey = "kSenderRecipientIdKey"
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public static let kSenderDeviceIdKey = "kSenderDeviceIdKey"
|
|
||||||
|
|
||||||
public let senderRecipientId: String
|
|
||||||
public let senderDeviceId: UInt32
|
|
||||||
public let underlyingError: Error
|
|
||||||
|
|
||||||
init(senderRecipientId: String, senderDeviceId: UInt32, underlyingError: Error) {
|
|
||||||
self.senderRecipientId = senderRecipientId
|
|
||||||
self.senderDeviceId = senderDeviceId
|
|
||||||
self.underlyingError = underlyingError
|
|
||||||
}
|
|
||||||
|
|
||||||
public var errorUserInfo: [String: Any] {
|
|
||||||
return [
|
|
||||||
type(of: self).kSenderRecipientIdKey: self.senderRecipientId,
|
|
||||||
type(of: self).kSenderDeviceIdKey: self.senderDeviceId,
|
|
||||||
NSUnderlyingErrorKey: (underlyingError as NSError)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public enum SMKSecretSessionCipherError: Int, Error {
|
|
||||||
case selfSentMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: -
|
|
||||||
|
|
||||||
private class SMKSecretKeySpec: NSObject {
|
|
||||||
|
|
||||||
@objc public let keyData: Data
|
|
||||||
@objc public let algorithm: String
|
|
||||||
|
|
||||||
init(keyData: Data, algorithm: String) {
|
|
||||||
self.keyData = keyData
|
|
||||||
self.algorithm = algorithm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: -
|
|
||||||
|
|
||||||
private class SMKEphemeralKeys: NSObject {
|
|
||||||
|
|
||||||
@objc public let chainKey: Data
|
|
||||||
@objc public let cipherKey: SMKSecretKeySpec
|
|
||||||
@objc public let macKey: SMKSecretKeySpec
|
|
||||||
|
|
||||||
init(chainKey: Data, cipherKey: Data, macKey: Data) {
|
|
||||||
self.chainKey = chainKey
|
|
||||||
self.cipherKey = SMKSecretKeySpec(keyData: cipherKey, algorithm: "AES")
|
|
||||||
self.macKey = SMKSecretKeySpec(keyData: macKey, algorithm: "HmacSHA256")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: -
|
|
||||||
|
|
||||||
private class SMKStaticKeys: NSObject {
|
|
||||||
|
|
||||||
@objc public let cipherKey: SMKSecretKeySpec
|
|
||||||
@objc public let macKey: SMKSecretKeySpec
|
|
||||||
|
|
||||||
init(cipherKey: Data, macKey: Data) {
|
|
||||||
self.cipherKey = SMKSecretKeySpec(keyData: cipherKey, algorithm: "AES")
|
|
||||||
self.macKey = SMKSecretKeySpec(keyData: macKey, algorithm: "HmacSHA256")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: -
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public class SMKDecryptResult: NSObject {
|
|
||||||
|
|
||||||
@objc public let senderRecipientId: String
|
|
||||||
@objc public let senderDeviceId: Int
|
|
||||||
@objc public let paddedPayload: Data
|
|
||||||
@objc public let messageType: SMKMessageType
|
|
||||||
|
|
||||||
init(senderRecipientId: String,
|
|
||||||
senderDeviceId: Int,
|
|
||||||
paddedPayload: Data,
|
|
||||||
messageType: SMKMessageType) {
|
|
||||||
self.senderRecipientId = senderRecipientId
|
|
||||||
self.senderDeviceId = senderDeviceId
|
|
||||||
self.paddedPayload = paddedPayload
|
|
||||||
self.messageType = messageType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: -
|
|
||||||
|
|
||||||
@objc public class SMKSecretSessionCipher: NSObject {
|
|
||||||
|
|
||||||
private let kUDPrefixString = "UnidentifiedDelivery"
|
|
||||||
|
|
||||||
private let kSMKSecretSessionCipherMacLength: UInt = 10
|
|
||||||
|
|
||||||
private let sessionResetImplementation: SessionRestorationProtocol!
|
|
||||||
private let sessionStore: SessionStore
|
|
||||||
private let preKeyStore: PreKeyStore
|
|
||||||
private let signedPreKeyStore: SignedPreKeyStore
|
|
||||||
private let identityStore: IdentityKeyStore
|
|
||||||
|
|
||||||
@objc public init(sessionResetImplementation: SessionRestorationProtocol!,
|
|
||||||
sessionStore: SessionStore,
|
|
||||||
preKeyStore: PreKeyStore,
|
|
||||||
signedPreKeyStore: SignedPreKeyStore,
|
|
||||||
identityStore: IdentityKeyStore) throws {
|
|
||||||
self.sessionResetImplementation = sessionResetImplementation
|
|
||||||
self.sessionStore = sessionStore
|
|
||||||
self.preKeyStore = preKeyStore
|
|
||||||
self.signedPreKeyStore = signedPreKeyStore
|
|
||||||
self.identityStore = identityStore
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public convenience init(sessionStore: SessionStore,
|
|
||||||
preKeyStore: PreKeyStore,
|
|
||||||
signedPreKeyStore: SignedPreKeyStore,
|
|
||||||
identityStore: IdentityKeyStore) throws {
|
|
||||||
try self.init(sessionResetImplementation: nil, sessionStore: sessionStore, preKeyStore: preKeyStore, signedPreKeyStore: signedPreKeyStore, identityStore: identityStore)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Public
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func throwswrapped_encryptMessage(recipientPublicKey: String,
|
|
||||||
deviceID: Int32,
|
|
||||||
paddedPlaintext: Data,
|
|
||||||
senderCertificate: SMKSenderCertificate,
|
|
||||||
protocolContext: Any,
|
|
||||||
useFallbackSessionCipher: Bool) throws -> Data {
|
|
||||||
guard recipientPublicKey.count > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(SMKSecretSessionCipher.logTag) invalid recipientId")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard deviceID > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(SMKSecretSessionCipher.logTag) invalid deviceId")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let ourIdentityKeyPair = identityStore.identityKeyPair(protocolContext) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Missing our identity key pair.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let encryptedMessage: CipherMessage
|
|
||||||
if useFallbackSessionCipher {
|
|
||||||
let cipher = FallBackSessionCipher(recipientPublicKey: recipientPublicKey, privateKey: try ourIdentityKeyPair.privateKey)
|
|
||||||
let ivAndCiphertext = cipher.encrypt(paddedPlaintext)!
|
|
||||||
encryptedMessage = FallbackMessage(_throws_with: ivAndCiphertext)
|
|
||||||
} else {
|
|
||||||
let cipher = SessionCipher(sessionStore: sessionStore,
|
|
||||||
preKeyStore: preKeyStore,
|
|
||||||
signedPreKeyStore: signedPreKeyStore,
|
|
||||||
identityKeyStore: identityStore,
|
|
||||||
recipientId: recipientPublicKey,
|
|
||||||
deviceId: deviceID)
|
|
||||||
encryptedMessage = try cipher.encryptMessage(paddedPlaintext, protocolContext: protocolContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let encryptedMessageData = encryptedMessage.serialized() else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Could not serialize encrypted message.")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let theirIdentityKeyData = Data.data(fromHex: recipientPublicKey.substring(from: recipientPublicKey.index(recipientPublicKey.startIndex, offsetBy: 2))) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Missing their public identity key.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: we don't use ECPublicKey(serializedKeyData) since the
|
|
||||||
// key data should not have a type byte.
|
|
||||||
let theirIdentityKey = try ECPublicKey(keyData: theirIdentityKeyData)
|
|
||||||
|
|
||||||
let ephemeral = Curve25519.generateKeyPair()
|
|
||||||
|
|
||||||
guard let prefixData = kUDPrefixString.data(using: String.Encoding.utf8) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Could not encode prefix.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let ephemeralSalt = NSData.join([
|
|
||||||
prefixData,
|
|
||||||
theirIdentityKey.serialized,
|
|
||||||
try ephemeral.ecPublicKey().serialized
|
|
||||||
])
|
|
||||||
|
|
||||||
let ephemeralKeys = try throwswrapped_calculateEphemeralKeys(ephemeralPublicKey: theirIdentityKey,
|
|
||||||
ephemeralPrivateKey: ephemeral.ecPrivateKey(),
|
|
||||||
salt: ephemeralSalt)
|
|
||||||
|
|
||||||
let staticKeyCipherData = try encrypt(cipherKey: ephemeralKeys.cipherKey,
|
|
||||||
macKey: ephemeralKeys.macKey,
|
|
||||||
plaintextData: ourIdentityKeyPair.ecPublicKey().serialized)
|
|
||||||
|
|
||||||
let staticSalt = NSData.join([
|
|
||||||
ephemeralKeys.chainKey,
|
|
||||||
staticKeyCipherData
|
|
||||||
])
|
|
||||||
|
|
||||||
let staticKeys = try throwswrapped_calculateStaticKeys(staticPublicKey: theirIdentityKey,
|
|
||||||
staticPrivateKey: ourIdentityKeyPair.ecPrivateKey(),
|
|
||||||
salt: staticSalt)
|
|
||||||
|
|
||||||
let messageType: SMKMessageType
|
|
||||||
switch encryptedMessage.cipherMessageType {
|
|
||||||
case .prekey:
|
|
||||||
messageType = .prekey
|
|
||||||
case .whisper:
|
|
||||||
messageType = .whisper
|
|
||||||
case .fallback:
|
|
||||||
messageType = .fallback
|
|
||||||
default:
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Unknown cipher message type.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let messageContent = SMKUnidentifiedSenderMessageContent(messageType: messageType,
|
|
||||||
senderCertificate: senderCertificate,
|
|
||||||
contentData: encryptedMessageData)
|
|
||||||
|
|
||||||
let messageData = try encrypt(cipherKey: staticKeys.cipherKey,
|
|
||||||
macKey: staticKeys.macKey,
|
|
||||||
plaintextData: try messageContent.serialized())
|
|
||||||
|
|
||||||
let message = SMKUnidentifiedSenderMessage(ephemeralKey: try ephemeral.ecPublicKey(),
|
|
||||||
encryptedStatic: staticKeyCipherData,
|
|
||||||
encryptedMessage: messageData)
|
|
||||||
|
|
||||||
return try message.serialized()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func throwswrapped_decryptMessage(certificateValidator: SMKCertificateValidator,
|
|
||||||
cipherTextData: Data,
|
|
||||||
timestamp: UInt64,
|
|
||||||
localRecipientId: String,
|
|
||||||
localDeviceId: Int32,
|
|
||||||
protocolContext: Any) throws -> SMKDecryptResult {
|
|
||||||
guard timestamp > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid timestamp")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let ourIdentityKeyPair = identityStore.identityKeyPair(protocolContext) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Missing our identity key pair.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let wrapper = try SMKUnidentifiedSenderMessage.parse(dataAndPrefix: cipherTextData)
|
|
||||||
|
|
||||||
guard let prefixData = kUDPrefixString.data(using: String.Encoding.utf8) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Could not encode prefix.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let ephemeralSalt = NSData.join([
|
|
||||||
prefixData,
|
|
||||||
try ourIdentityKeyPair.ecPublicKey().serialized,
|
|
||||||
wrapper.ephemeralKey.serialized
|
|
||||||
])
|
|
||||||
|
|
||||||
let ephemeralKeys = try throwswrapped_calculateEphemeralKeys(ephemeralPublicKey: wrapper.ephemeralKey,
|
|
||||||
ephemeralPrivateKey: ourIdentityKeyPair.ecPrivateKey(),
|
|
||||||
salt: ephemeralSalt)
|
|
||||||
|
|
||||||
let staticKeyBytes = try decrypt(cipherKey: ephemeralKeys.cipherKey,
|
|
||||||
macKey: ephemeralKeys.macKey,
|
|
||||||
cipherTextWithMac: wrapper.encryptedStatic)
|
|
||||||
|
|
||||||
let staticKey = try ECPublicKey(serializedKeyData: staticKeyBytes)
|
|
||||||
|
|
||||||
let staticSalt = NSData.join([
|
|
||||||
ephemeralKeys.chainKey,
|
|
||||||
wrapper.encryptedStatic
|
|
||||||
])
|
|
||||||
|
|
||||||
let staticKeys = try throwswrapped_calculateStaticKeys(staticPublicKey: staticKey,
|
|
||||||
staticPrivateKey: ourIdentityKeyPair.ecPrivateKey(),
|
|
||||||
salt: staticSalt)
|
|
||||||
|
|
||||||
let messageBytes = try decrypt(cipherKey: staticKeys.cipherKey,
|
|
||||||
macKey: staticKeys.macKey,
|
|
||||||
cipherTextWithMac: wrapper.encryptedMessage)
|
|
||||||
|
|
||||||
let messageContent = try SMKUnidentifiedSenderMessageContent.parse(data: messageBytes)
|
|
||||||
|
|
||||||
let senderRecipientId = messageContent.senderCertificate.senderRecipientId
|
|
||||||
let senderDeviceId = messageContent.senderCertificate.senderDeviceId
|
|
||||||
|
|
||||||
guard senderRecipientId != localRecipientId || senderDeviceId != localDeviceId else {
|
|
||||||
Logger.info("Discarding self-sent message")
|
|
||||||
throw SMKSecretSessionCipherError.selfSentMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
// validator.validate(content.getSenderCertificate(), timestamp);
|
|
||||||
|
|
||||||
let wrapAsKnownSenderError = { (underlyingError: Error) in
|
|
||||||
return SecretSessionKnownSenderError(senderRecipientId: senderRecipientId, senderDeviceId: senderDeviceId, underlyingError: underlyingError)
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
try certificateValidator.throwswrapped_validate(senderCertificate: messageContent.senderCertificate,
|
|
||||||
validationTime: timestamp)
|
|
||||||
} catch {
|
|
||||||
throw wrapAsKnownSenderError(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (!MessageDigest.isEqual(content.getSenderCertificate().getKey().serialize(), staticKeyBytes)) {
|
|
||||||
// throw new InvalidKeyException("Sender's certificate key does not match key used in message");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // NOTE: Constant time comparison.
|
|
||||||
// guard messageContent.senderCertificate.key.serialized.ows_constantTimeIsEqual(to: staticKeyBytes) else {
|
|
||||||
// let underlyingError = SMKError.assertionError(description: "\(logTag) Sender's certificate key does not match key used in message.")
|
|
||||||
// throw wrapAsKnownSenderError(underlyingError)
|
|
||||||
// }
|
|
||||||
|
|
||||||
let paddedMessagePlaintext: Data
|
|
||||||
do {
|
|
||||||
paddedMessagePlaintext = try throwswrapped_decrypt(messageContent: messageContent, protocolContext: protocolContext)
|
|
||||||
} catch {
|
|
||||||
throw wrapAsKnownSenderError(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: We use the sender properties from the sender certificate, not from this class' properties.
|
|
||||||
guard senderDeviceId >= 0 && senderDeviceId <= INT_MAX else {
|
|
||||||
let underlyingError = SMKError.assertionError(description: "\(logTag) Invalid senderDeviceId.")
|
|
||||||
throw wrapAsKnownSenderError(underlyingError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return SMKDecryptResult(senderRecipientId: senderRecipientId,
|
|
||||||
senderDeviceId: Int(senderDeviceId),
|
|
||||||
paddedPayload: paddedMessagePlaintext,
|
|
||||||
messageType: messageContent.messageType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Encrypt
|
|
||||||
|
|
||||||
// private EphemeralKeys calculateEphemeralKeys(ECPublicKey ephemeralPublic, ECPrivateKey ephemeralPrivate, byte[] salt)
|
|
||||||
// throws InvalidKeyException {
|
|
||||||
private func throwswrapped_calculateEphemeralKeys(ephemeralPublicKey: ECPublicKey,
|
|
||||||
ephemeralPrivateKey: ECPrivateKey,
|
|
||||||
salt: Data) throws -> SMKEphemeralKeys {
|
|
||||||
guard ephemeralPublicKey.keyData.count > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid ephemeralPublicKey")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard ephemeralPrivateKey.keyData.count > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid ephemeralPrivateKey")
|
|
||||||
}
|
|
||||||
|
|
||||||
guard salt.count > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid salt")
|
|
||||||
}
|
|
||||||
|
|
||||||
// byte[] ephemeralSecret = Curve.calculateAgreement(ephemeralPublic, ephemeralPrivate);
|
|
||||||
//
|
|
||||||
// See:
|
|
||||||
// https://github.com/signalapp/libsignal-protocol-java/blob/master/java/src/main/java/org/whispersystems/libsignal/ecc/Curve.java#L30
|
|
||||||
let ephemeralSecret = try Curve25519.generateSharedSecret(fromPublicKey: ephemeralPublicKey.keyData, privateKey: ephemeralPrivateKey.keyData)
|
|
||||||
|
|
||||||
// byte[] ephemeralDerived = new HKDFv3().deriveSecrets(ephemeralSecret, salt, new byte[0], 96);
|
|
||||||
let kEphemeralDerivedLength: UInt = 96
|
|
||||||
let ephemeralDerived: Data =
|
|
||||||
try HKDFKit.deriveKey(ephemeralSecret, info: Data(), salt: salt, outputSize: Int32(kEphemeralDerivedLength))
|
|
||||||
guard ephemeralDerived.count == kEphemeralDerivedLength else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) derived ephemeral has unexpected length: \(ephemeralDerived.count).")
|
|
||||||
}
|
|
||||||
|
|
||||||
let ephemeralDerivedParser = OWSDataParser(data: ephemeralDerived)
|
|
||||||
let chainKey = try ephemeralDerivedParser.nextData(length: 32, name: "chain key")
|
|
||||||
let cipherKey = try ephemeralDerivedParser.nextData(length: 32, name: "cipher key")
|
|
||||||
let macKey = try ephemeralDerivedParser.nextData(length: 32, name: "mac key")
|
|
||||||
guard ephemeralDerivedParser.isEmpty else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) could not parse derived ephemeral.")
|
|
||||||
}
|
|
||||||
|
|
||||||
return SMKEphemeralKeys(chainKey: chainKey, cipherKey: cipherKey, macKey: macKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// private StaticKeys calculateStaticKeys(ECPublicKey staticPublic, ECPrivateKey staticPrivate, byte[] salt) throws
|
|
||||||
// InvalidKeyException {
|
|
||||||
private func throwswrapped_calculateStaticKeys(staticPublicKey: ECPublicKey,
|
|
||||||
staticPrivateKey: ECPrivateKey,
|
|
||||||
salt: Data) throws -> SMKStaticKeys {
|
|
||||||
guard staticPublicKey.keyData.count > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid staticPublicKey")
|
|
||||||
}
|
|
||||||
guard staticPrivateKey.keyData.count > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid staticPrivateKey")
|
|
||||||
}
|
|
||||||
guard salt.count > 0 else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid salt")
|
|
||||||
}
|
|
||||||
|
|
||||||
// byte[] staticSecret = Curve.calculateAgreement(staticPublic, staticPrivate);
|
|
||||||
//
|
|
||||||
// See:
|
|
||||||
// https://github.com/signalapp/libsignal-protocol-java/blob/master/java/src/main/java/org/whispersystems/libsignal/ecc/Curve.java#L30
|
|
||||||
let staticSecret = try Curve25519.generateSharedSecret(fromPublicKey: staticPublicKey.keyData, privateKey: staticPrivateKey.keyData)
|
|
||||||
|
|
||||||
// byte[] staticDerived = new HKDFv3().deriveSecrets(staticSecret, salt, new byte[0], 96);
|
|
||||||
let kStaticDerivedLength: UInt = 96
|
|
||||||
let staticDerived: Data =
|
|
||||||
HKDFKit.deriveKey(staticSecret, info: Data(), salt: salt, outputSize: Int32(kStaticDerivedLength))
|
|
||||||
guard staticDerived.count == kStaticDerivedLength else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) could not derive static.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// byte[][] staticDerivedParts = ByteUtil.split(staticDerived, 32, 32, 32);
|
|
||||||
let staticDerivedParser = OWSDataParser(data: staticDerived)
|
|
||||||
_ = try staticDerivedParser.nextData(length: 32)
|
|
||||||
let cipherKey = try staticDerivedParser.nextData(length: 32)
|
|
||||||
let macKey = try staticDerivedParser.nextData(length: 32)
|
|
||||||
guard staticDerivedParser.isEmpty else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) invalid derived static.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// return new StaticKeys(staticDerivedParts[1], staticDerivedParts[2]);
|
|
||||||
return SMKStaticKeys(cipherKey: cipherKey, macKey: macKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// private byte[] encrypt(SecretKeySpec cipherKey, SecretKeySpec macKey, byte[] plaintext) {
|
|
||||||
private func encrypt(cipherKey: SMKSecretKeySpec,
|
|
||||||
macKey: SMKSecretKeySpec,
|
|
||||||
plaintextData: Data) throws -> Data {
|
|
||||||
|
|
||||||
// Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
|
|
||||||
// cipher.init(Cipher.ENCRYPT_MODE, cipherKey, new IvParameterSpec(new byte[16]));
|
|
||||||
// byte[] ciphertext = cipher.doFinal(plaintext);
|
|
||||||
guard let aesKey = OWSAES256Key(data: cipherKey.keyData) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Invalid encryption key.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: The IV is all zeroes. This is fine since we're using a unique key.
|
|
||||||
let initializationVector = Data(count: Int(kAES256CTR_IVLength))
|
|
||||||
|
|
||||||
guard let encryptionResult = Cryptography.encryptAESCTR(plaintextData: plaintextData, initializationVector: initializationVector, key: aesKey) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Could not encrypt data.")
|
|
||||||
}
|
|
||||||
let cipherText = encryptionResult.ciphertext
|
|
||||||
|
|
||||||
// Mac mac = Mac.getInstance("HmacSHA256");
|
|
||||||
// mac.init(macKey);
|
|
||||||
//
|
|
||||||
// byte[] ourFullMac = mac.doFinal(ciphertext);
|
|
||||||
// byte[] ourMac = ByteUtil.trim(ourFullMac, 10);
|
|
||||||
guard let ourMac = Cryptography.truncatedSHA256HMAC(cipherText, withHMACKey: macKey.keyData, truncation: 10) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Could not compute HmacSHA256.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// return ByteUtil.combine(ciphertext, ourMac);
|
|
||||||
let result = NSData.join([
|
|
||||||
cipherText,
|
|
||||||
ourMac
|
|
||||||
])
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Decrypt
|
|
||||||
|
|
||||||
private func throwswrapped_decrypt(messageContent: SMKUnidentifiedSenderMessageContent,
|
|
||||||
protocolContext: Any) throws -> Data {
|
|
||||||
// NOTE: We use the sender properties from the sender certificate, not from this class' properties.
|
|
||||||
let senderRecipientId = messageContent.senderCertificate.senderRecipientId
|
|
||||||
let senderDeviceId = messageContent.senderCertificate.senderDeviceId
|
|
||||||
guard senderDeviceId >= 0 && senderDeviceId <= INT32_MAX else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Invalid senderDeviceId.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let cipherMessage: CipherMessage
|
|
||||||
switch (messageContent.messageType) {
|
|
||||||
case .whisper:
|
|
||||||
cipherMessage = try WhisperMessage(data: messageContent.contentData)
|
|
||||||
case .prekey:
|
|
||||||
cipherMessage = try PreKeyWhisperMessage(data: messageContent.contentData)
|
|
||||||
case .fallback:
|
|
||||||
let privateKey = try? identityStore.identityKeyPair(protocolContext)?.privateKey
|
|
||||||
let cipher = FallBackSessionCipher(recipientPublicKey: senderRecipientId, privateKey: privateKey)
|
|
||||||
let plaintext = cipher.decrypt(messageContent.contentData)!
|
|
||||||
return plaintext
|
|
||||||
}
|
|
||||||
|
|
||||||
let cipher = LokiSessionCipher(sessionResetImplementation: sessionResetImplementation,
|
|
||||||
sessionStore: sessionStore,
|
|
||||||
preKeyStore: preKeyStore,
|
|
||||||
signedPreKeyStore: signedPreKeyStore,
|
|
||||||
identityKeyStore: identityStore,
|
|
||||||
recipientID: senderRecipientId,
|
|
||||||
deviceID: Int32(senderDeviceId))
|
|
||||||
|
|
||||||
let plaintextData = try cipher.decrypt(cipherMessage, protocolContext: protocolContext)
|
|
||||||
return plaintextData
|
|
||||||
}
|
|
||||||
|
|
||||||
// private byte[] decrypt(SecretKeySpec cipherKey, SecretKeySpec macKey, byte[] ciphertext) throws InvalidMacException {
|
|
||||||
private func decrypt(cipherKey: SMKSecretKeySpec,
|
|
||||||
macKey: SMKSecretKeySpec,
|
|
||||||
cipherTextWithMac: Data) throws -> Data {
|
|
||||||
|
|
||||||
// if (ciphertext.count < 10) {
|
|
||||||
// throw new InvalidMacException("Ciphertext not long enough for MAC!");
|
|
||||||
// }
|
|
||||||
if (cipherTextWithMac.count < kSMKSecretSessionCipherMacLength) {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Cipher text not long enough for MAC.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// byte[][] ciphertextParts = ByteUtil.split(ciphertext, ciphertext.count - 10, 10);
|
|
||||||
let cipherTextWithMacParser = OWSDataParser(data: cipherTextWithMac)
|
|
||||||
let cipherTextLength = UInt(cipherTextWithMac.count) - kSMKSecretSessionCipherMacLength
|
|
||||||
let cipherText = try cipherTextWithMacParser.nextData(length: cipherTextLength, name: "cipher text")
|
|
||||||
let theirMac = try cipherTextWithMacParser.nextData(length: kSMKSecretSessionCipherMacLength, name: "their mac")
|
|
||||||
guard cipherTextWithMacParser.isEmpty else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Could not parse cipher text.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mac mac = Mac.getInstance("HmacSHA256");
|
|
||||||
// mac.init(macKey);
|
|
||||||
//
|
|
||||||
// byte[] digest = mac.doFinal(ciphertextParts[0]);
|
|
||||||
guard let ourFullMac = Cryptography.computeSHA256HMAC(cipherText, withHMACKey: macKey.keyData) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) Could not compute HmacSHA256.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// byte[] ourMac = ByteUtil.trim(digest, 10);
|
|
||||||
guard ourFullMac.count >= kSMKSecretSessionCipherMacLength else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) HmacSHA256 has unexpected length.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let ourMac = ourFullMac[0..<kSMKSecretSessionCipherMacLength]
|
|
||||||
|
|
||||||
// if (!MessageDigest.isEqual(ourMac, theirMac)) {
|
|
||||||
// throw new InvalidMacException("Bad mac!");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// NOTE: Constant time comparison.
|
|
||||||
guard ourMac.ows_constantTimeIsEqual(to: theirMac) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) macs do not match.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
|
|
||||||
// cipher.init(Cipher.DECRYPT_MODE, cipherKey, new IvParameterSpec(new byte[16]));
|
|
||||||
guard let aesKey = OWSAES256Key(data: cipherKey.keyData) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) could not parse AES256 key.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: The IV is all zeroes. This is fine since we're using a unique key.
|
|
||||||
let initializationVector = Data(count: Int(kAES256CTR_IVLength))
|
|
||||||
|
|
||||||
guard let plaintext = Cryptography.decryptAESCTR(cipherText: cipherText, initializationVector: initializationVector, key: aesKey) else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) could not decrypt AESGCM.")
|
|
||||||
}
|
|
||||||
|
|
||||||
return plaintext
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
// See:
|
|
||||||
// https://github.com/signalapp/libsignal-metadata-java/blob/cac0dde9de416a192e64a8940503982820870090/java/src/main/java/org/signal/libsignal/metadata/certificate/SenderCertificate.java
|
|
||||||
@objc public class SMKSenderCertificate: NSObject {
|
|
||||||
|
|
||||||
@objc public let senderDeviceId: UInt32
|
|
||||||
@objc public let senderRecipientId: String
|
|
||||||
|
|
||||||
@objc public init(senderDeviceId: UInt32, senderRecipientId: String) {
|
|
||||||
self.senderDeviceId = senderDeviceId
|
|
||||||
self.senderRecipientId = senderRecipientId
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parse(data: Data) throws -> SMKSenderCertificate {
|
|
||||||
let proto = try SMKProtoSenderCertificate.parseData(data)
|
|
||||||
return try parse(proto: proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parse(proto: SMKProtoSenderCertificate) throws -> SMKSenderCertificate {
|
|
||||||
|
|
||||||
let sender = proto.sender
|
|
||||||
let senderDevice = proto.senderDevice
|
|
||||||
|
|
||||||
return SMKSenderCertificate(senderDeviceId: senderDevice, senderRecipientId: sender)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func toProto() throws -> SMKProtoSenderCertificate {
|
|
||||||
let builder =
|
|
||||||
SMKProtoSenderCertificate.builder(sender: senderRecipientId, senderDevice: senderDeviceId)
|
|
||||||
return try builder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func serialized() throws -> Data {
|
|
||||||
return try toProto().serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func isEqual(_ other: Any?) -> Bool {
|
|
||||||
if let other = other as? SMKSenderCertificate {
|
|
||||||
return (senderDeviceId == other.senderDeviceId && senderRecipientId == other.senderRecipientId)
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override var hash: Int {
|
|
||||||
return senderDeviceId.hashValue ^ senderRecipientId.hashValue
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
// See:
|
|
||||||
// https://github.com/signalapp/libsignal-metadata-java/blob/cac0dde9de416a192e64a8940503982820870090/java/src/main/java/org/signal/libsignal/metadata/certificate/ServerCertificate.java
|
|
||||||
@objc public class SMKServerCertificate: NSObject {
|
|
||||||
|
|
||||||
@objc public let keyId: UInt32
|
|
||||||
@objc public let key: ECPublicKey
|
|
||||||
@objc public let signatureData: Data
|
|
||||||
|
|
||||||
public init(keyId: UInt32,
|
|
||||||
key: ECPublicKey,
|
|
||||||
signatureData: Data) {
|
|
||||||
self.keyId = keyId
|
|
||||||
self.key = key
|
|
||||||
self.signatureData = signatureData
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parse(data: Data) throws -> SMKServerCertificate {
|
|
||||||
let proto = try SMKProtoServerCertificate.parseData(data)
|
|
||||||
return try parse(proto: proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parse(proto: SMKProtoServerCertificate) throws -> SMKServerCertificate {
|
|
||||||
let signatureData = proto.signature
|
|
||||||
let certificateData = proto.certificate
|
|
||||||
let certificateProto = try SMKProtoServerCertificateCertificate.parseData(certificateData)
|
|
||||||
let keyId = certificateProto.id
|
|
||||||
let keyData = certificateProto.key
|
|
||||||
let key = try ECPublicKey(serializedKeyData: keyData)
|
|
||||||
return SMKServerCertificate(keyId: keyId, key: key, signatureData: signatureData)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func toProto() throws -> SMKProtoServerCertificate {
|
|
||||||
let certificateBuilder = SMKProtoServerCertificateCertificate.builder(id: keyId, key: key.serialized)
|
|
||||||
|
|
||||||
let builder =
|
|
||||||
SMKProtoServerCertificate.builder(certificate: try certificateBuilder.buildSerializedData(),
|
|
||||||
signature: signatureData)
|
|
||||||
return try builder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func serialized() throws -> Data {
|
|
||||||
return try toProto().serializedData()
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func isEqual(_ other: Any?) -> Bool {
|
|
||||||
if let other = other as? SMKServerCertificate {
|
|
||||||
return (keyId == other.keyId &&
|
|
||||||
key.isEqual(other.key) &&
|
|
||||||
(signatureData == other.signatureData))
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override var hash: Int {
|
|
||||||
return keyId.hashValue ^ key.hashValue ^ signatureData.hashValue
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SignalCoreKit
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public class SMKUDAccessKey: NSObject {
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public static let kUDAccessKeyLength: Int = 16
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public let keyData: Data
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public init(profileKey: Data) throws {
|
|
||||||
guard let aesGcmKey = OWSAES256Key(data: profileKey) else {
|
|
||||||
throw SMKError.assertionError(description: "Profile key is not valid AES GCM key.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// We derive the "ud access key" from the private key by encrypting zeroes.
|
|
||||||
let emptyPlaintextLength = 16
|
|
||||||
let emptyPlaintext = Data(count: Int(emptyPlaintextLength))
|
|
||||||
let initializationVector = Data(count: Int(kAESGCM256_DefaultIVLength))
|
|
||||||
guard let keyData = Cryptography.encryptAESGCM(plainTextData: emptyPlaintext,
|
|
||||||
initializationVector: initializationVector,
|
|
||||||
additionalAuthenticatedData: nil,
|
|
||||||
key: aesGcmKey) else {
|
|
||||||
throw SMKError.assertionError(description: "Could not derive UD access key from profile key.")
|
|
||||||
}
|
|
||||||
guard keyData.ciphertext.count == SMKUDAccessKey.kUDAccessKeyLength else {
|
|
||||||
throw SMKError.assertionError(description: "\(SMKUDAccessKey.logTag) key has invalid length")
|
|
||||||
}
|
|
||||||
|
|
||||||
self.keyData = keyData.ciphertext
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public init(randomKeyData: ()) {
|
|
||||||
self.keyData = Randomness.generateRandomBytes(Int32(SMKUDAccessKey.kUDAccessKeyLength))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK:
|
|
||||||
|
|
||||||
override public func isEqual(_ object: Any?) -> Bool {
|
|
||||||
guard let other = object as? SMKUDAccessKey else { return false }
|
|
||||||
return self.keyData == other.keyData
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SignalCoreKit
|
|
||||||
|
|
||||||
// https://github.com/signalapp/libsignal-metadata-java/blob/master/java/src/main/java/org/signal/libsignal/metadata/protocol/UnidentifiedSenderMessage.java
|
|
||||||
@objc public class SMKUnidentifiedSenderMessage: NSObject {
|
|
||||||
|
|
||||||
@objc public static let kSMKMessageCipherTextVersion: UInt = 1
|
|
||||||
|
|
||||||
public let cipherTextVersion: UInt
|
|
||||||
public let ephemeralKey: ECPublicKey
|
|
||||||
public let encryptedStatic: Data
|
|
||||||
public let encryptedMessage: Data
|
|
||||||
|
|
||||||
public init(cipherTextVersion: UInt,
|
|
||||||
ephemeralKey: ECPublicKey,
|
|
||||||
encryptedStatic: Data,
|
|
||||||
encryptedMessage: Data) {
|
|
||||||
self.cipherTextVersion = cipherTextVersion
|
|
||||||
self.ephemeralKey = ephemeralKey
|
|
||||||
self.encryptedStatic = encryptedStatic
|
|
||||||
self.encryptedMessage = encryptedMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(ephemeralKey: ECPublicKey,
|
|
||||||
encryptedStatic: Data,
|
|
||||||
encryptedMessage: Data) {
|
|
||||||
self.cipherTextVersion = SMKUnidentifiedSenderMessage.kSMKMessageCipherTextVersion
|
|
||||||
self.ephemeralKey = ephemeralKey
|
|
||||||
self.encryptedStatic = encryptedStatic
|
|
||||||
self.encryptedMessage = encryptedMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parse(dataAndPrefix: Data) throws -> SMKUnidentifiedSenderMessage {
|
|
||||||
// public UnidentifiedSenderMessage(byte[] serialized)
|
|
||||||
// throws InvalidMetadataMessageException, InvalidMetadataVersionException
|
|
||||||
|
|
||||||
let parser = OWSDataParser(data: dataAndPrefix)
|
|
||||||
|
|
||||||
// this.version = ByteUtil.highBitsToInt(serialized[0]);
|
|
||||||
let versionByte = try parser.nextByte(name: "version byte")
|
|
||||||
let cipherTextVersion = UInt(SerializationUtilities.highBitsToInt(fromByte: versionByte))
|
|
||||||
|
|
||||||
// if (version > CIPHERTEXT_VERSION) {
|
|
||||||
// throw new InvalidMetadataVersionException("Unknown version: " + this.version);
|
|
||||||
// }
|
|
||||||
guard cipherTextVersion <= SMKUnidentifiedSenderMessage.kSMKMessageCipherTextVersion else {
|
|
||||||
throw SMKError.assertionError(description: "\(logTag) unknown cipher text version: \(cipherTextVersion)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignalProtos.UnidentifiedSenderMessage unidentifiedSenderMessage =
|
|
||||||
// SignalProtos.UnidentifiedSenderMessage.parseFrom(ByteString.copyFrom(serialized, 1, serialized.length - 1));
|
|
||||||
let protoData = try parser.remainder(name: "proto data")
|
|
||||||
let proto = try SMKProtoUnidentifiedSenderMessage.parseData(protoData)
|
|
||||||
|
|
||||||
// if (!unidentifiedSenderMessage.hasEphemeralPublic() ||
|
|
||||||
// !unidentifiedSenderMessage.hasEncryptedStatic() ||
|
|
||||||
// !unidentifiedSenderMessage.hasEncryptedMessage())
|
|
||||||
// {
|
|
||||||
// throw new InvalidMetadataMessageException("Missing fields");
|
|
||||||
// }
|
|
||||||
// NOTE: These fields are required in the proto schema.
|
|
||||||
|
|
||||||
// this.ephemeral = Curve.decodePoint(unidentifiedSenderMessage.getEphemeralPublic().toByteArray(), 0);
|
|
||||||
let ephemeralKeyData = proto.ephemeralPublic
|
|
||||||
let ephemeralKey = try ECPublicKey(serializedKeyData: ephemeralKeyData)
|
|
||||||
|
|
||||||
// this.encryptedStatic = unidentifiedSenderMessage.getEncryptedStatic().toByteArray();
|
|
||||||
let encryptedStatic = proto.encryptedStatic
|
|
||||||
|
|
||||||
// this.encryptedMessage = unidentifiedSenderMessage.getEncryptedMessage().toByteArray();
|
|
||||||
let encryptedMessage = proto.encryptedMessage
|
|
||||||
|
|
||||||
return SMKUnidentifiedSenderMessage(cipherTextVersion: cipherTextVersion, ephemeralKey: ephemeralKey, encryptedStatic: encryptedStatic, encryptedMessage: encryptedMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func toProto() throws -> SMKProtoUnidentifiedSenderMessage {
|
|
||||||
let builder = SMKProtoUnidentifiedSenderMessage.builder(ephemeralPublic: ephemeralKey.serialized,
|
|
||||||
encryptedStatic: encryptedStatic,
|
|
||||||
encryptedMessage: encryptedMessage)
|
|
||||||
return try builder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func serialized() throws -> Data {
|
|
||||||
let versionByte: UInt8 = UInt8((self.cipherTextVersion << 4 | self.cipherTextVersion) & 0xFF)
|
|
||||||
let versionBytes = [versionByte]
|
|
||||||
let versionData = Data(bytes: versionBytes)
|
|
||||||
let messageData = try toProto().serializedData()
|
|
||||||
|
|
||||||
return NSData.join([versionData, messageData])
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
@objc public enum SMKMessageType: Int {
|
|
||||||
case whisper
|
|
||||||
case prekey
|
|
||||||
case fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
// See:
|
|
||||||
// https://github.com/signalapp/libsignal-metadata-java/blob/0cbbbf23eaf9f46fdf2d9463f3dfab2fb3271292/java/src/main/java/org/signal/libsignal/metadata/protocol/UnidentifiedSenderMessageContent.java
|
|
||||||
@objc public class SMKUnidentifiedSenderMessageContent: NSObject {
|
|
||||||
|
|
||||||
@objc public let messageType: SMKMessageType
|
|
||||||
@objc public let senderCertificate: SMKSenderCertificate
|
|
||||||
@objc public let contentData: Data
|
|
||||||
|
|
||||||
@objc public init(messageType: SMKMessageType,
|
|
||||||
senderCertificate: SMKSenderCertificate,
|
|
||||||
contentData: Data) {
|
|
||||||
self.messageType = messageType
|
|
||||||
self.senderCertificate = senderCertificate
|
|
||||||
self.contentData = contentData
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public class func parse(data: Data) throws -> SMKUnidentifiedSenderMessageContent {
|
|
||||||
|
|
||||||
let proto = try SMKProtoUnidentifiedSenderMessageMessage.parseData(data)
|
|
||||||
|
|
||||||
// TODO: Should we have a default case in our switches? Probably.
|
|
||||||
var messageType: SMKMessageType
|
|
||||||
switch (proto.type) {
|
|
||||||
case .prekeyMessage:
|
|
||||||
messageType = .prekey
|
|
||||||
case .message:
|
|
||||||
messageType = .whisper
|
|
||||||
case .fallbackMessage:
|
|
||||||
messageType = .fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
let contentData = proto.content
|
|
||||||
let senderCertificateProto = proto.senderCertificate
|
|
||||||
let senderCertificate = try SMKSenderCertificate.parse(proto: senderCertificateProto)
|
|
||||||
|
|
||||||
return SMKUnidentifiedSenderMessageContent(messageType: messageType, senderCertificate: senderCertificate, contentData: contentData)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func toProto() throws -> SMKProtoUnidentifiedSenderMessageMessage {
|
|
||||||
let builderType: SMKProtoUnidentifiedSenderMessageMessage.SMKProtoUnidentifiedSenderMessageMessageType
|
|
||||||
switch messageType {
|
|
||||||
case .whisper:
|
|
||||||
builderType = .message
|
|
||||||
case .prekey:
|
|
||||||
builderType = .prekeyMessage
|
|
||||||
case .fallback:
|
|
||||||
builderType = .fallbackMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
let builder = SMKProtoUnidentifiedSenderMessageMessage.builder(type: builderType,
|
|
||||||
senderCertificate: try senderCertificate.toProto(),
|
|
||||||
content: contentData)
|
|
||||||
return try builder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func serialized() throws -> Data {
|
|
||||||
return try toProto().serializedData()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "AxolotlStore.h"
|
|
||||||
#import "IdentityKeyStore.h"
|
|
||||||
#import "PreKeyStore.h"
|
|
||||||
#import "PreKeyWhisperMessage.h"
|
|
||||||
#import "SessionState.h"
|
|
||||||
#import "SessionStore.h"
|
|
||||||
#import "SignedPreKeyStore.h"
|
|
||||||
#import "WhisperMessage.h"
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface SessionCipher : NSObject
|
|
||||||
|
|
||||||
- (instancetype)initWithAxolotlStore:(id<AxolotlStore>)sessionStore recipientId:(NSString*)recipientId deviceId:(int)deviceId;
|
|
||||||
|
|
||||||
- (instancetype)initWithSessionStore:(id<SessionStore>)sessionStore preKeyStore:(id<PreKeyStore>)preKeyStore signedPreKeyStore:(id<SignedPreKeyStore>)signedPreKeyStore identityKeyStore:(id<IdentityKeyStore>)identityKeyStore recipientId:(NSString*)recipientId deviceId:(int)deviceId;
|
|
||||||
|
|
||||||
// protocolContext is an optional parameter that can be used to ensure that all
|
|
||||||
// identity and session store writes are coordinated and/or occur within a single
|
|
||||||
// transaction.
|
|
||||||
- (id<CipherMessage>)throws_encryptMessage:(NSData *)paddedMessage
|
|
||||||
protocolContext:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
- (nullable id<CipherMessage>)encryptMessage:(NSData *)paddedMessage
|
|
||||||
protocolContext:(nullable id)protocolContext
|
|
||||||
error:(NSError **)outError;
|
|
||||||
|
|
||||||
- (NSData *)throws_decrypt:(id<CipherMessage>)whisperMessage
|
|
||||||
protocolContext:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
- (nullable NSData *)decrypt:(id<CipherMessage>)whisperMessage
|
|
||||||
protocolContext:(nullable id)protocolContext
|
|
||||||
error:(NSError **)outError;
|
|
||||||
|
|
||||||
- (int)throws_remoteRegistrationId:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
- (int)throws_sessionVersion:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue