From 37cee04eebbe0ecbf61bd415383be9b1773dccef Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 16 Nov 2018 17:22:04 -0600 Subject: [PATCH] update pods --- Manifest.lock | 4 +- .../src/SMKSecretSessionCipher.swift | 217 ++++++++++------- .../src/SMKMiscTest.swift | 4 +- .../src/SMKSecretSessionCipherTest.swift | 18 +- .../src/SMKTestUtils.swift | 225 +++--------------- 5 files changed, 172 insertions(+), 296 deletions(-) diff --git a/Manifest.lock b/Manifest.lock index e284a4cd..0b7c433b 100644 --- a/Manifest.lock +++ b/Manifest.lock @@ -261,7 +261,7 @@ CHECKOUT OPTIONS: :commit: b60dc7d58dfc93ca6eafbb3ea5300c6d67ebc69a :git: https://github.com/signalapp/SignalCoreKit.git SignalMetadataKit: - :commit: d6b0186cc5b15019e85c375bce3bf78e7a7fc162 + :commit: a5473c8d33602775e00253afce78eef01a69260e :git: https://github.com/signalapp/SignalMetadataKit SocketRocket: :commit: 9f9563a83cd8960503074aa8de72206f83fb7a69 @@ -296,6 +296,6 @@ SPEC CHECKSUMS: YapDatabase: b418a4baa6906e8028748938f9159807fd039af4 YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 -PODFILE CHECKSUM: 820287bc7925d7c20e02a02923976c60b1f5386b +PODFILE CHECKSUM: 55c6b62a23df23853a2af68917716a56a813c3f0 COCOAPODS: 1.5.3 diff --git a/SignalMetadataKit/SignalMetadataKit/src/SMKSecretSessionCipher.swift b/SignalMetadataKit/SignalMetadataKit/src/SMKSecretSessionCipher.swift index ee6b600c..4d70b2d3 100644 --- a/SignalMetadataKit/SignalMetadataKit/src/SMKSecretSessionCipher.swift +++ b/SignalMetadataKit/SignalMetadataKit/src/SMKSecretSessionCipher.swift @@ -4,6 +4,33 @@ import Foundation +@objc +public class SecretSessionKnownSenderError: NSObject, CustomNSError { + @objc + public static let kSenderRecipientIdKey = "kSenderRecipientIdKey" + + @objc + public static let kSenderDeviceIdKey = "kSenderDeviceIdKey" + + let senderRecipientId: String + let senderDeviceId: UInt32 + 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 + ] + } +} + @objc public enum SMKSecretSessionCipherError: Int, Error { case selfSentMessage @@ -245,97 +272,113 @@ public class SMKDecryptResult: NSObject { localDeviceId: Int32, protocolContext: Any?) throws -> SMKDecryptResult { - guard timestamp > 0 else { - throw SMKError.assertionError(description: "\(logTag) invalid timestamp") - } - - // IdentityKeyPair ourIdentity = signalProtocolStore.getIdentityKeyPair(); - guard let ourIdentityKeyPair = identityStore.identityKeyPair(protocolContext) else { - throw SMKError.assertionError(description: "\(logTag) Missing our identity key pair.") - } - - // UnidentifiedSenderMessage wrapper = new UnidentifiedSenderMessage(ciphertext); - let wrapper = try SMKUnidentifiedSenderMessage.parse(dataAndPrefix: cipherTextData) - - // byte[] ephemeralSalt = ByteUtil.combine("UnidentifiedDelivery".getBytes(), - // ourIdentity.getPublicKey().getPublicKey().serialize(), wrapper.getEphemeral().serialize()); - 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 - ]) - - // EphemeralKeys ephemeralKeys = calculateEphemeralKeys(wrapper.getEphemeral(), ourIdentity.getPrivateKey(), - // ephemeralSalt); - let ephemeralKeys = try throwswrapped_calculateEphemeralKeys(ephemeralPublicKey: wrapper.ephemeralKey, - ephemeralPrivateKey: ourIdentityKeyPair.ecPrivateKey(), - salt: ephemeralSalt) - - // byte[] staticKeyBytes = decrypt(ephemeralKeys.cipherKey, ephemeralKeys.macKey, wrapper.getEncryptedStatic()); - let staticKeyBytes = try decrypt(cipherKey: ephemeralKeys.cipherKey, - macKey: ephemeralKeys.macKey, - cipherTextWithMac: wrapper.encryptedStatic) - - // ECPublicKey staticKey = Curve.decodePoint(staticKeyBytes, 0); - let staticKey = try ECPublicKey(serializedKeyData: staticKeyBytes) - - // byte[] staticSalt = ByteUtil.combine(ephemeralKeys.chainKey, wrapper.getEncryptedStatic()); - let staticSalt = NSData.join([ - ephemeralKeys.chainKey, - wrapper.encryptedStatic - ]) - - // StaticKeys staticKeys = calculateStaticKeys(staticKey, ourIdentity.getPrivateKey(), staticSalt); - let staticKeys = try throwswrapped_calculateStaticKeys(staticPublicKey: staticKey, - staticPrivateKey: ourIdentityKeyPair.ecPrivateKey(), - salt: staticSalt) - - // byte[] messageBytes = decrypt(staticKeys.cipherKey, staticKeys.macKey, wrapper.getEncryptedMessage()); - let messageBytes = try decrypt(cipherKey: staticKeys.cipherKey, - macKey: staticKeys.macKey, - cipherTextWithMac: wrapper.encryptedMessage) - - // content = new UnidentifiedSenderMessageContent(messageBytes); - let messageContent = try SMKUnidentifiedSenderMessageContent.parse(data: messageBytes) - - guard messageContent.senderCertificate.senderRecipientId != localRecipientId || - messageContent.senderCertificate.senderDeviceId != localDeviceId else { + guard timestamp > 0 else { + throw SMKError.assertionError(description: "\(logTag) invalid timestamp") + } + + // IdentityKeyPair ourIdentity = signalProtocolStore.getIdentityKeyPair(); + guard let ourIdentityKeyPair = identityStore.identityKeyPair(protocolContext) else { + throw SMKError.assertionError(description: "\(logTag) Missing our identity key pair.") + } + + // UnidentifiedSenderMessage wrapper = new UnidentifiedSenderMessage(ciphertext); + let wrapper = try SMKUnidentifiedSenderMessage.parse(dataAndPrefix: cipherTextData) + + // byte[] ephemeralSalt = ByteUtil.combine("UnidentifiedDelivery".getBytes(), + // ourIdentity.getPublicKey().getPublicKey().serialize(), wrapper.getEphemeral().serialize()); + 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 + ]) + + // EphemeralKeys ephemeralKeys = calculateEphemeralKeys(wrapper.getEphemeral(), ourIdentity.getPrivateKey(), + // ephemeralSalt); + let ephemeralKeys = try throwswrapped_calculateEphemeralKeys(ephemeralPublicKey: wrapper.ephemeralKey, + ephemeralPrivateKey: ourIdentityKeyPair.ecPrivateKey(), + salt: ephemeralSalt) + + // byte[] staticKeyBytes = decrypt(ephemeralKeys.cipherKey, ephemeralKeys.macKey, wrapper.getEncryptedStatic()); + let staticKeyBytes = try decrypt(cipherKey: ephemeralKeys.cipherKey, + macKey: ephemeralKeys.macKey, + cipherTextWithMac: wrapper.encryptedStatic) + + // ECPublicKey staticKey = Curve.decodePoint(staticKeyBytes, 0); + let staticKey = try ECPublicKey(serializedKeyData: staticKeyBytes) + + // byte[] staticSalt = ByteUtil.combine(ephemeralKeys.chainKey, wrapper.getEncryptedStatic()); + let staticSalt = NSData.join([ + ephemeralKeys.chainKey, + wrapper.encryptedStatic + ]) + + // StaticKeys staticKeys = calculateStaticKeys(staticKey, ourIdentity.getPrivateKey(), staticSalt); + let staticKeys = try throwswrapped_calculateStaticKeys(staticPublicKey: staticKey, + staticPrivateKey: ourIdentityKeyPair.ecPrivateKey(), + salt: staticSalt) + + // byte[] messageBytes = decrypt(staticKeys.cipherKey, staticKeys.macKey, wrapper.getEncryptedMessage()); + let messageBytes = try decrypt(cipherKey: staticKeys.cipherKey, + macKey: staticKeys.macKey, + cipherTextWithMac: wrapper.encryptedMessage) + + // content = new UnidentifiedSenderMessageContent(messageBytes); + 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); - // 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) - - // 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 { - throw SMKError.assertionError(description: "\(logTag) Sender's certificate key does not match key used in message.") - } - - let paddedMessagePlaintext = try throwswrapped_decrypt(messageContent: messageContent, protocolContext: protocolContext) - - // return new Pair<>(new SignalProtocolAddress(content.getSenderCertificate().getSender(), - // content.getSenderCertificate().getSenderDeviceId()), - // decrypt(content)); - // - // 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 <= INT_MAX else { - throw SMKError.assertionError(description: "\(logTag) Invalid senderDeviceId.") - } - return SMKDecryptResult(senderRecipientId: senderRecipientId, - senderDeviceId: Int(senderDeviceId), - paddedPayload: paddedMessagePlaintext, - messageType: messageContent.messageType) + 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) + } + + // return new Pair<>(new SignalProtocolAddress(content.getSenderCertificate().getSender(), + // content.getSenderCertificate().getSenderDeviceId()), + // decrypt(content)); + // + // 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 diff --git a/SignalMetadataKit/SignalMetadataKitTests/src/SMKMiscTest.swift b/SignalMetadataKit/SignalMetadataKitTests/src/SMKMiscTest.swift index a869766e..27f71425 100644 --- a/SignalMetadataKit/SignalMetadataKitTests/src/SMKMiscTest.swift +++ b/SignalMetadataKit/SignalMetadataKitTests/src/SMKMiscTest.swift @@ -125,8 +125,8 @@ class SMKTest: XCTestCase { let certificateValidator = MockCertificateValidator() - let bobPrekey = bobMockClient.preKeyStore.createKey() - let bobSignedPrekey = bobMockClient.signedPreKeyStore.createKey() + let bobPrekey = bobMockClient.generateMockPreKey() + let bobSignedPrekey = bobMockClient.generateMockSignedPreKey() let bobPreKeyBundle = PreKeyBundle(registrationId: bobMockClient.registrationId, deviceId: bobMockClient.deviceId, diff --git a/SignalMetadataKit/SignalMetadataKitTests/src/SMKSecretSessionCipherTest.swift b/SignalMetadataKit/SignalMetadataKitTests/src/SMKSecretSessionCipherTest.swift index 4a2d6e39..13b4fc72 100644 --- a/SignalMetadataKit/SignalMetadataKitTests/src/SMKSecretSessionCipherTest.swift +++ b/SignalMetadataKit/SignalMetadataKitTests/src/SMKSecretSessionCipherTest.swift @@ -329,21 +329,21 @@ class SMKSecretSessionCipherTest: XCTestCase { private func initializeSessions(aliceMockClient: MockClient, bobMockClient: MockClient) { // ECKeyPair bobPreKey = Curve.generateKeyPair(); - let bobPreKey = bobMockClient.preKeyStore.createKey() + let bobPreKey = bobMockClient.generateMockPreKey() // IdentityKeyPair bobIdentityKey = bobStore.getIdentityKeyPair(); let bobIdentityKey = bobMockClient.identityKeyPair // SignedPreKeyRecord bobSignedPreKey = KeyHelper.generateSignedPreKey(bobIdentityKey, 2); - let bobSignedPreKey = bobMockClient.signedPreKeyStore.createKey() + let bobSignedPreKey = bobMockClient.generateMockSignedPreKey() // // PreKeyBundle bobBundle = new PreKeyBundle(1, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey()); let bobBundle = PreKeyBundle(registrationId: bobMockClient.registrationId, - deviceId: bobMockClient.deviceId, - preKeyId: bobPreKey.id, - preKeyPublic: try! bobPreKey.keyPair.ecPublicKey().serialized, - signedPreKeyPublic: try! bobSignedPreKey.keyPair.ecPublicKey().keyData.prependKeyType(), - signedPreKeyId: bobSignedPreKey.id, - signedPreKeySignature: bobSignedPreKey.signature, - identityKey: try! bobIdentityKey.ecPublicKey().keyData.prependKeyType())! + deviceId: bobMockClient.deviceId, + preKeyId: bobPreKey.id, + preKeyPublic: try! bobPreKey.keyPair.ecPublicKey().serialized, + signedPreKeyPublic: try! bobSignedPreKey.keyPair.ecPublicKey().keyData.prependKeyType(), + signedPreKeyId: bobSignedPreKey.id, + signedPreKeySignature: bobSignedPreKey.signature, + identityKey: try! bobIdentityKey.ecPublicKey().keyData.prependKeyType())! // SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, new SignalProtocolAddress("+14152222222", 1)); let aliceSessionBuilder = aliceMockClient.createSessionBuilder(forRecipient: bobMockClient) diff --git a/SignalMetadataKit/SignalMetadataKitTests/src/SMKTestUtils.swift b/SignalMetadataKit/SignalMetadataKitTests/src/SMKTestUtils.swift index 7ccf8fef..a319e744 100644 --- a/SignalMetadataKit/SignalMetadataKitTests/src/SMKTestUtils.swift +++ b/SignalMetadataKit/SignalMetadataKitTests/src/SMKTestUtils.swift @@ -16,193 +16,6 @@ class MockCertificateValidator: NSObject, SMKCertificateValidator { } } -// MARK: - - -class MockIdentityStore: NSObject, IdentityKeyStore { - - private let localIdentityKeyPair: ECKeyPair? - private let localRegistrationId: Int32 - private var identityKeyMap = [String: Data]() - - init(localIdentityKeyPair: ECKeyPair?, localRegistrationId: Int32) { - self.localIdentityKeyPair = localIdentityKeyPair - self.localRegistrationId = localRegistrationId - } - - public func identityKeyPair(_ protocolContext: Any?) -> ECKeyPair? { - return localIdentityKeyPair - } - - public func localRegistrationId(_ protocolContext: Any?) -> Int32 { - return localRegistrationId - } - - // @returns YES if we are replacing an existing known identity key for recipientId. - // NO if there was no previously stored identity key for the recipient. - public func saveRemoteIdentity(_ identityKey: Data, recipientId: String, protocolContext: Any?) -> Bool { - let didReplace = identityKeyMap[recipientId] != nil - identityKeyMap[recipientId] = identityKey - return didReplace - } - - public func isTrustedIdentityKey(_ identityKey: Data, recipientId: String, direction: TSMessageDirection, protocolContext: Any?) -> Bool { - return true - } - - public func identityKey(forRecipientId recipientId: String) -> Data? { - if let identityKey = identityKeyMap[recipientId] { - return identityKey - } - let identityKey = Randomness.generateRandomBytes(100)! - identityKeyMap[recipientId] = identityKey - return identityKey - } - - public func identityKey(forRecipientId recipientId: String, protocolContext: Any?) -> Data? { - return identityKey(forRecipientId: recipientId) - } -} - -// MARK: - - -private class MockSessionKey: NSObject { - let contactIdentifier: String - let deviceId: Int32 - - init(contactIdentifier: String, deviceId: Int32) { - self.contactIdentifier = contactIdentifier - self.deviceId = deviceId - } - - open override func isEqual(_ other: Any?) -> Bool { - if let other = other as? MockSessionKey { - return contactIdentifier == other.contactIdentifier && deviceId == other.deviceId - } else { - return false - } - } - - public override var hash: Int { - return contactIdentifier.hashValue ^ deviceId.hashValue - } -} - -// MARK: - - -class MockSessionStore: NSObject, SessionStore { - - private var sessionMap = [MockSessionKey: SessionRecord]() - - public func loadSession(_ contactIdentifier: String, deviceId: Int32, protocolContext: Any?) -> SessionRecord { - let sessionKey = MockSessionKey(contactIdentifier: contactIdentifier, deviceId: deviceId) - if let sessionRecord = sessionMap[sessionKey] { - return sessionRecord - } - let sessionRecord = SessionRecord()! - return sessionRecord - } - - public func subDevicesSessions(_ contactIdentifier: String, protocolContext: Any?) -> [Any] { - notImplemented() - } - - public func storeSession(_ contactIdentifier: String, deviceId: Int32, session: SessionRecord, protocolContext: Any?) { - let sessionKey = MockSessionKey(contactIdentifier: contactIdentifier, deviceId: deviceId) - sessionMap[sessionKey] = session - } - - public func containsSession(_ contactIdentifier: String, deviceId: Int32, protocolContext: Any?) -> Bool { - return self.loadSession(contactIdentifier, deviceId: deviceId, protocolContext: protocolContext).sessionState().hasSenderChain() - } - - public func deleteSession(forContact contactIdentifier: String, deviceId: Int32, protocolContext: Any?) { - let sessionKey = MockSessionKey(contactIdentifier: contactIdentifier, deviceId: deviceId) - sessionMap.removeValue(forKey: sessionKey) - } - - public func deleteAllSessions(forContact contactIdentifier: String, protocolContext: Any?) { - sessionMap.removeAll() - } -} - -// MARK: - - -class MockPreKeyStore: NSObject, PreKeyStore { - - private var keyMap = [Int32: PreKeyRecord]() - - func createKey() -> PreKeyRecord { - let preKeyId: Int32 = Int32(arc4random_uniform(UInt32(INT32_MAX))) - let keyPair = Curve25519.generateKeyPair() - let preKey = PreKeyRecord(id: preKeyId, keyPair: keyPair)! - keyMap[preKeyId] = preKey - return preKey - } - - public func loadPreKey(_ preKeyId: Int32) -> PreKeyRecord { - return keyMap[preKeyId]! - } - - public func storePreKey(_ preKeyId: Int32, preKeyRecord record: PreKeyRecord) { - notImplemented() - } - - public func containsPreKey(_ preKeyId: Int32) -> Bool { - notImplemented() - } - - public func removePreKey(_ preKeyId: Int32) { - notImplemented() - } -} - -// MARK: - - -class MockSignedPreKeyStore: NSObject, SignedPreKeyStore { - let identityKeyPair: ECKeyPair - - init(identityKeyPair: ECKeyPair) { - self.identityKeyPair = identityKeyPair - } - private var keyMap = [Int32: SignedPreKeyRecord]() - - func createKey() -> SignedPreKeyRecord { - let signedPreKeyId: Int32 = Int32(arc4random_uniform(UInt32(INT32_MAX))) - let keyPair = Curve25519.generateKeyPair() - let generatedAt = Date() - let signature = try! Ed25519.sign((keyPair.publicKey as NSData).prependKeyType() as Data, with: identityKeyPair) - let signedPreKey = SignedPreKeyRecord(id: signedPreKeyId, keyPair: keyPair, signature: signature, generatedAt: generatedAt)! - keyMap[signedPreKeyId] = signedPreKey - return signedPreKey - } - - public func loadSignedPrekey(_ signedPreKeyId: Int32) -> SignedPreKeyRecord { - return keyMap[signedPreKeyId]! - } - - public func loadSignedPrekeyOrNil(_ signedPreKeyId: Int32) -> SignedPreKeyRecord? { - notImplemented() - } - - public func loadSignedPreKeys() -> [SignedPreKeyRecord] { - notImplemented() - } - - public func storeSignedPreKey(_ signedPreKeyId: Int32, signedPreKeyRecord: SignedPreKeyRecord) { - notImplemented() - } - - public func containsSignedPreKey(_ signedPreKeyId: Int32) -> Bool { - notImplemented() - } - - public func removeSignedPreKey(_ signedPrekeyId: Int32) { - notImplemented() - } -} - -// MARK: - - class MockClient: NSObject { let recipientId: String @@ -211,22 +24,23 @@ class MockClient: NSObject { let identityKeyPair: ECKeyPair - let sessionStore: MockSessionStore - let preKeyStore: MockPreKeyStore - let signedPreKeyStore: MockSignedPreKeyStore - let identityStore: MockIdentityStore + let sessionStore: SPKMockProtocolStore + let preKeyStore: SPKMockProtocolStore + let signedPreKeyStore: SPKMockProtocolStore + let identityStore: SPKMockProtocolStore init(recipientId: String, deviceId: Int32, registrationId: Int32) { self.recipientId = recipientId self.deviceId = deviceId self.registrationId = registrationId + self.identityKeyPair = Curve25519.generateKeyPair() - identityKeyPair = Curve25519.generateKeyPair() + let protocolStore = SPKMockProtocolStore(identityKeyPair: identityKeyPair, localRegistrationId: registrationId) - sessionStore = MockSessionStore() - preKeyStore = MockPreKeyStore() - signedPreKeyStore = MockSignedPreKeyStore(identityKeyPair: identityKeyPair) - identityStore = MockIdentityStore(localIdentityKeyPair: identityKeyPair, localRegistrationId: registrationId) + sessionStore = protocolStore + preKeyStore = protocolStore + signedPreKeyStore = protocolStore + identityStore = protocolStore } func createSessionCipher() -> SessionCipher { @@ -253,4 +67,23 @@ class MockClient: NSObject { recipientId: recipient.recipientId, deviceId: recipient.deviceId) } + + func generateMockPreKey() -> PreKeyRecord { + let preKeyId: Int32 = Int32(arc4random_uniform(UInt32(INT32_MAX))) + let keyPair = Curve25519.generateKeyPair() + let preKey = PreKeyRecord(id: preKeyId, keyPair: keyPair)! + self.preKeyStore.storePreKey(preKeyId, preKeyRecord: preKey) + return preKey + } + + func generateMockSignedPreKey() -> SignedPreKeyRecord { + let signedPreKeyId: Int32 = Int32(arc4random_uniform(UInt32(INT32_MAX))) + let keyPair = Curve25519.generateKeyPair() + let generatedAt = Date() + let identityKeyPair = self.identityStore.identityKeyPair(nil) + let signature = try! Ed25519.sign((keyPair.publicKey as NSData).prependKeyType() as Data, with: identityKeyPair) + let signedPreKey = SignedPreKeyRecord(id: signedPreKeyId, keyPair: keyPair, signature: signature, generatedAt: generatedAt)! + self.signedPreKeyStore.storeSignedPreKey(signedPreKeyId, signedPreKeyRecord: signedPreKey) + return signedPreKey + } }