diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 3997f84e8..5e92d8074 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -572,6 +572,7 @@ C31D1DE32521718E005D4DA8 /* UserSelectionVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31D1DE22521718E005D4DA8 /* UserSelectionVC.swift */; }; C31D1DE9252172D4005D4DA8 /* ContactUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31D1DE8252172D4005D4DA8 /* ContactUtilities.swift */; }; C31F812625258FB000DD9FD9 /* Storage+VolumeSamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31F812525258FB000DD9FD9 /* Storage+VolumeSamples.swift */; }; + C31FFE57254A5FFE00F19441 /* KeyPairUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */; }; C329FEEC24F7277900B1C64C /* LightModeSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C329FEEB24F7277900B1C64C /* LightModeSheet.swift */; }; C329FEEF24F7743F00B1C64C /* UIViewController+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C329FEED24F7742E00B1C64C /* UIViewController+Utilities.swift */; }; C34C8F7423A7830B00D82669 /* SpaceMono-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */; }; @@ -1373,6 +1374,7 @@ C31D1DE22521718E005D4DA8 /* UserSelectionVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSelectionVC.swift; sourceTree = ""; }; C31D1DE8252172D4005D4DA8 /* ContactUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactUtilities.swift; sourceTree = ""; }; C31F812525258FB000DD9FD9 /* Storage+VolumeSamples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+VolumeSamples.swift"; sourceTree = ""; }; + C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPairUtilities.swift; sourceTree = ""; }; C329FEEB24F7277900B1C64C /* LightModeSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LightModeSheet.swift; sourceTree = ""; }; C329FEED24F7742E00B1C64C /* UIViewController+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Utilities.swift"; sourceTree = ""; }; C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SpaceMono-Bold.ttf"; sourceTree = ""; }; @@ -2708,6 +2710,7 @@ C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */, C31D1DE8252172D4005D4DA8 /* ContactUtilities.swift */, C35E8AAD2485E51D00ACB629 /* IP2Country.swift */, + C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */, B84664F4235022F30083A1CD /* MentionUtilities.swift */, B886B4A82398BA1500211ABE /* QRCode.swift */, C3E7134E251C867C009649BB /* Sodium+Conversion.swift */, @@ -3890,6 +3893,7 @@ 3496957121A301A100DCFE74 /* OWSBackupImportJob.m in Sources */, 34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */, C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */, + C31FFE57254A5FFE00F19441 /* KeyPairUtilities.swift in Sources */, 343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */, 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */, 452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */, diff --git a/Signal/src/Loki/Utilities/KeyPairGeneration.swift b/Signal/src/Loki/Utilities/KeyPairGeneration.swift new file mode 100644 index 000000000..cfec4f311 --- /dev/null +++ b/Signal/src/Loki/Utilities/KeyPairGeneration.swift @@ -0,0 +1,23 @@ +import Sodium + +enum KeyPairUtilities { + + static func generate(from seed: Data) -> (ed25519KeyPair: Sign.KeyPair, x25519KeyPair: ECKeyPair) { + assert(seed.count == 16) + let padding = Data(repeating: 0, count: 16) + let ed25519KeyPair = Sodium().sign.keyPair(seed: (seed + padding).bytes)! + let x25519PublicKey = Sodium().sign.toX25519(ed25519PublicKey: ed25519KeyPair.publicKey)! + let x25519SecretKey = Sodium().sign.toX25519(ed25519SecretKey: ed25519KeyPair.secretKey)! + let x25519KeyPair = ECKeyPair(publicKey: Data(x25519PublicKey), privateKey: Data(x25519SecretKey))! + return (ed25519KeyPair: ed25519KeyPair, x25519KeyPair: x25519KeyPair) + } + + static func store(seed: Data, ed25519KeyPair: Sign.KeyPair, x25519KeyPair: ECKeyPair) { + let dbConnection = OWSIdentityManager.shared().dbConnection + let collection = OWSPrimaryStorageIdentityKeyStoreCollection + dbConnection.setObject(seed.toHexString(), forKey: LKSeedKey, inCollection: collection) + dbConnection.setObject(ed25519KeyPair.secretKey.toHexString(), forKey: LKED25519SecretKey, inCollection: collection) + dbConnection.setObject(ed25519KeyPair.publicKey.toHexString(), forKey: LKED25519PublicKey, inCollection: collection) + dbConnection.setObject(x25519KeyPair, forKey: OWSPrimaryStorageIdentityKeyStoreIdentityKey, inCollection: collection) + } +} diff --git a/Signal/src/Loki/View Controllers/RegisterVC.swift b/Signal/src/Loki/View Controllers/RegisterVC.swift index 5823950a1..08920d4d0 100644 --- a/Signal/src/Loki/View Controllers/RegisterVC.swift +++ b/Signal/src/Loki/View Controllers/RegisterVC.swift @@ -135,11 +135,7 @@ final class RegisterVC : BaseVC { } private func updateKeyPair() { - let padding = Data(repeating: 0, count: 16) - ed25519KeyPair = Sodium().sign.keyPair(seed: (seed + padding).bytes)! - let x25519PublicKey = Sodium().sign.toX25519(ed25519PublicKey: ed25519KeyPair.publicKey)! - let x25519SecretKey = Sodium().sign.toX25519(ed25519SecretKey: ed25519KeyPair.secretKey)! - x25519KeyPair = ECKeyPair(publicKey: Data(x25519PublicKey), privateKey: Data(x25519SecretKey)) + (ed25519KeyPair, x25519KeyPair) = KeyPairUtilities.generate(from: seed) } private func updatePublicKeyLabel() { @@ -171,12 +167,7 @@ final class RegisterVC : BaseVC { // MARK: Interaction @objc private func register() { - let dbConnection = OWSIdentityManager.shared().dbConnection - let collection = OWSPrimaryStorageIdentityKeyStoreCollection - dbConnection.setObject(seed.toHexString(), forKey: LKSeedKey, inCollection: collection) - dbConnection.setObject(ed25519KeyPair.secretKey.toHexString(), forKey: LKED25519SecretKey, inCollection: collection) - dbConnection.setObject(ed25519KeyPair.publicKey.toHexString(), forKey: LKED25519PublicKey, inCollection: collection) - dbConnection.setObject(x25519KeyPair!, forKey: OWSPrimaryStorageIdentityKeyStoreIdentityKey, inCollection: collection) + KeyPairUtilities.store(seed: seed, ed25519KeyPair: ed25519KeyPair, x25519KeyPair: x25519KeyPair) TSAccountManager.sharedInstance().phoneNumberAwaitingVerification = x25519KeyPair!.hexEncodedPublicKey OWSPrimaryStorage.shared().setRestorationTime(0) UserDefaults.standard[.hasViewedSeed] = false diff --git a/Signal/src/Loki/View Controllers/RestoreVC.swift b/Signal/src/Loki/View Controllers/RestoreVC.swift index e8b7b00da..e4c15109e 100644 --- a/Signal/src/Loki/View Controllers/RestoreVC.swift +++ b/Signal/src/Loki/View Controllers/RestoreVC.swift @@ -163,12 +163,9 @@ final class RestoreVC : BaseVC { do { let hexEncodedSeed = try Mnemonic.decode(mnemonic: mnemonic) let seed = Data(hex: hexEncodedSeed) - let keyPair = Curve25519.generateKeyPair(fromSeed: seed + seed) - let identityManager = OWSIdentityManager.shared() - let databaseConnection = identityManager.value(forKey: "dbConnection") as! YapDatabaseConnection - databaseConnection.setObject(seed.toHexString(), forKey: "LKLokiSeed", inCollection: OWSPrimaryStorageIdentityKeyStoreCollection) - databaseConnection.setObject(keyPair, forKey: OWSPrimaryStorageIdentityKeyStoreIdentityKey, inCollection: OWSPrimaryStorageIdentityKeyStoreCollection) - TSAccountManager.sharedInstance().phoneNumberAwaitingVerification = keyPair.hexEncodedPublicKey + let (ed25519KeyPair, x25519KeyPair) = KeyPairUtilities.generate(from: seed) + KeyPairUtilities.store(seed: seed, ed25519KeyPair: ed25519KeyPair, x25519KeyPair: x25519KeyPair) + TSAccountManager.sharedInstance().phoneNumberAwaitingVerification = x25519KeyPair.hexEncodedPublicKey OWSPrimaryStorage.shared().setRestorationTime(Date().timeIntervalSince1970) UserDefaults.standard[.hasViewedSeed] = true mnemonicTextView.resignFirstResponder()