Merge pull request #300 from loki-project/security-2

Switch Key Pair Generation Mechanism
pull/301/head
Niels Andriesse 4 years ago committed by GitHub
commit 45d6d59034
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -74,10 +74,10 @@ target 'Signal' do
# Loki third party pods
###
pod 'GCDWebServer', '~> 3.5.2', :inhibit_warnings => true # TODO: We can probably ditch this as we're not doing P2P anymore
pod 'FeedKit', '~> 8.1', :inhibit_warnings => true
pod 'CryptoSwift', '~> 1.3', :inhibit_warnings => true
pod 'FeedKit', '~> 8.1', :inhibit_warnings => true
pod 'NVActivityIndicatorView', '~> 4.7', :inhibit_warnings => true
pod 'Sodium', '~> 0.8.0', :inhibit_warnings => true
target 'SignalTests' do
inherit! :search_paths

@ -17,11 +17,8 @@ PODS:
- CocoaLumberjack (3.6.2):
- CocoaLumberjack/Core (= 3.6.2)
- CocoaLumberjack/Core (3.6.2)
- CryptoSwift (1.3.1)
- CryptoSwift (1.3.2)
- FeedKit (8.1.1)
- GCDWebServer (3.5.4):
- GCDWebServer/Core (= 3.5.4)
- GCDWebServer/Core (3.5.4)
- GRKOpenSSLFramework (1.0.2.12)
- libPhoneNumber-iOS (0.9.15)
- Mantle (2.1.0):
@ -122,6 +119,7 @@ PODS:
- Starscream
- SwiftProtobuf (~> 1.5.0)
- YapDatabase/SQLCipher
- Sodium (0.8.0)
- SQLCipher (4.4.0):
- SQLCipher/standard (= 4.4.0)
- SQLCipher/common (4.4.0)
@ -203,7 +201,6 @@ DEPENDENCIES:
- AFNetworking (~> 3.2.1)
- CryptoSwift (~> 1.3)
- FeedKit (~> 8.1)
- GCDWebServer (~> 3.5.2)
- GRKOpenSSLFramework (from `https://github.com/signalapp/GRKOpenSSLFramework`)
- Mantle (from `https://github.com/signalapp/Mantle`, branch `signal-master`)
- NVActivityIndicatorView (~> 4.7)
@ -222,6 +219,7 @@ DEPENDENCIES:
- SessionMetadataKit/Tests (from `https://github.com/loki-project/session-ios-metadata-kit`)
- SessionServiceKit (from `.`)
- SessionServiceKit/Tests (from `.`)
- Sodium (~> 0.8.0)
- SQLCipher (>= 4.0.1)
- SSZipArchive
- Starscream (from `https://github.com/signalapp/Starscream.git`, branch `signal-release`)
@ -235,13 +233,13 @@ SPEC REPOS:
- CocoaLumberjack
- CryptoSwift
- FeedKit
- GCDWebServer
- libPhoneNumber-iOS
- NVActivityIndicatorView
- PromiseKit
- PureLayout
- Reachability
- SAMKeychain
- Sodium
- SQLCipher
- SSZipArchive
- SwiftProtobuf
@ -306,9 +304,8 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057
CocoaLumberjack: bd155f2dd06c0e0b03f876f7a3ee55693122ec94
CryptoSwift: f12f037f6d0fcd6d48c96db0071b653de64e6c4d
CryptoSwift: 093499be1a94b0cae36e6c26b70870668cb56060
FeedKit: 3418eed25f0b493b205b4de1b8511ac21d413fa9
GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
GRKOpenSSLFramework: 8a3735ad41e7dc1daff460467bccd32ca5d6ae3e
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
@ -323,6 +320,7 @@ SPEC CHECKSUMS:
SessionHKDFKit: b0f4e669411703ab925aba07491c5611564d1419
SessionMetadataKit: d37afdc47d20c7046faa139a92e68fa99f76c95b
SessionServiceKit: b12afb3975b33a9579802111f948838861d914bb
Sodium: 63c0ca312a932e6da481689537d4b35568841bdc
SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
Starscream: 8aaf1a7feb805c816d0e7d3190ef23856f6665b9
@ -331,6 +329,6 @@ SPEC CHECKSUMS:
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
PODFILE CHECKSUM: c26d913ac0e7de8c047412658746634a46681fed
PODFILE CHECKSUM: 128e2d9df0c3e7862c266dd4be1d512a8d88ef65
COCOAPODS: 1.9.3
COCOAPODS: 1.10.0.rc.1

@ -1 +1 @@
Subproject commit 11d995a37fa82d8a3592e98d1d16bdf81dc21e7c
Subproject commit 32824be1acfe0c86778bec9d95970b271eb80ceb

@ -602,6 +602,7 @@
C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */; };
C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; };
C3DFFAC823E970080058DAF8 /* OpenGroupSuggestionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */; };
C3E7134F251C867C009649BB /* Sodium+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E7134E251C867C009649BB /* Sodium+Conversion.swift */; };
C3E5C2FA251DBABB0040DFFC /* EditClosedGroupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */; };
CC875800737563D6891B741D /* Pods_SignalTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 748A5CAEDD7C919FC64C6807 /* Pods_SignalTests.framework */; };
D202868116DBE0E7009068E9 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AEACDB16C426DA00C364C0 /* CFNetwork.framework */; };
@ -1406,6 +1407,7 @@
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = "<group>"; };
C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = "<group>"; };
C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupSuggestionSheet.swift; sourceTree = "<group>"; };
C3E7134E251C867C009649BB /* Sodium+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sodium+Conversion.swift"; sourceTree = "<group>"; };
C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditClosedGroupVC.swift; sourceTree = "<group>"; };
D17BB5C25D615AB49813100C /* Pods_Signal.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Signal.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D2179CFB16BB0B3A0006F3AB /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; };
@ -2708,6 +2710,7 @@
C35E8AAD2485E51D00ACB629 /* IP2Country.swift */,
B84664F4235022F30083A1CD /* MentionUtilities.swift */,
B886B4A82398BA1500211ABE /* QRCode.swift */,
C3E7134E251C867C009649BB /* Sodium+Conversion.swift */,
B8783E9D23EB948D00404FB8 /* UILabel+Interaction.swift */,
B83F2B87240CB75A000A54AB /* UIImage+Scaling.swift */,
C31A6C59247F214E001123EF /* UIView+Glow.swift */,
@ -3450,7 +3453,6 @@
"${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework",
"${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework",
"${BUILT_PRODUCTS_DIR}/FeedKit/FeedKit.framework",
"${BUILT_PRODUCTS_DIR}/GCDWebServer/GCDWebServer.framework",
"${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework",
"${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework",
"${BUILT_PRODUCTS_DIR}/NVActivityIndicatorView/NVActivityIndicatorView.framework",
@ -3466,6 +3468,7 @@
"${BUILT_PRODUCTS_DIR}/SessionHKDFKit/SessionHKDFKit.framework",
"${BUILT_PRODUCTS_DIR}/SessionMetadataKit/SessionMetadataKit.framework",
"${BUILT_PRODUCTS_DIR}/SessionServiceKit/SessionServiceKit.framework",
"${BUILT_PRODUCTS_DIR}/Sodium/Sodium.framework",
"${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
@ -3479,7 +3482,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FeedKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GCDWebServer.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NVActivityIndicatorView.framework",
@ -3495,6 +3497,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionHKDFKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionMetadataKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionServiceKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sodium.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
@ -3992,6 +3995,7 @@
34D1F0831F8678AA0066283D /* ConversationInputTextView.m in Sources */,
340FC8B6204DAC8D007AEB0F /* OWSQRCodeScanningViewController.m in Sources */,
4CB5F26920F7D060004D1B42 /* MessageActions.swift in Sources */,
C3E7134F251C867C009649BB /* Sodium+Conversion.swift in Sources */,
340FC8B5204DAC8D007AEB0F /* AboutTableViewController.m in Sources */,
34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */,
340FC8B9204DAC8D007AEB0F /* UpdateGroupViewController.m in Sources */,

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
<key>PreviewsEnabled</key>
<false/>
</dict>

@ -6,10 +6,14 @@
<dict>
<key>CarthageVersion</key>
<string>0.36.0</string>
<key>DateTime</key>
<string>Tue Oct 27 21:55:52 UTC 2020</string>
<key>OSXVersion</key>
<string>10.15.6</string>
<key>WebRTCCommit</key>
<string>1445d719bf05280270e9f77576f80f973fd847f8 M73</string>
<key>XCodeVersion</key>
<string>1200.1210</string>
</dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>

@ -0,0 +1,41 @@
import Clibsodium
import Sodium
extension Sign {
/**
Converts an Ed25519 public key to an X25519 public key.
- Parameter ed25519PublicKey: The Ed25519 public key to convert.
- Returns: The X25519 public key if conversion is successful.
*/
public func toX25519(ed25519PublicKey: PublicKey) -> PublicKey? {
var x25519PublicKey = PublicKey(repeating: 0, count: 32)
// FIXME: It'd be nice to check the exit code here, but all the properties of the object
// returned by the call below are internal.
let _ = crypto_sign_ed25519_pk_to_curve25519 (
&x25519PublicKey,
ed25519PublicKey
)
return x25519PublicKey
}
/**
Converts an Ed25519 secret key to an X25519 secret key.
- Parameter ed25519SecretKey: The Ed25519 secret key to convert.
- Returns: The X25519 secret key if conversion is successful.
*/
public func toX25519(ed25519SecretKey: SecretKey) -> SecretKey? {
var x25519SecretKey = SecretKey(repeating: 0, count: 32)
// FIXME: It'd be nice to check the exit code here, but all the properties of the object
// returned by the call below are internal.
let _ = crypto_sign_ed25519_sk_to_curve25519 (
&x25519SecretKey,
ed25519SecretKey
)
return x25519SecretKey
}
}

@ -158,39 +158,13 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
DispatchQueue.global(qos: .utility).async {
let _ = IP2Country.shared.populateCacheIfNeeded()
}
// Preload device links to make message sending quicker
var publicKeys: Set<String> = []
let storage = OWSPrimaryStorage.shared()
storage.dbReadConnection.read { transaction in
TSContactThread.enumerateCollectionObjects(with: transaction) { object, _ in
guard let thread = object as? TSContactThread, thread.shouldThreadBeVisible else { return }
let publicKey = thread.contactIdentifier()
guard UserDisplayNameUtilities.getPrivateChatDisplayName(for: publicKey) != nil,
storage.getMasterHexEncodedPublicKey(for: publicKey, in: transaction) == nil else { return }
publicKeys.insert(publicKey)
}
}
let _ = FileServerAPI.getDeviceLinks(associatedWith: publicKeys)
// Do initial update
reload()
// Clear all data if this is a secondary device
if UserDefaults.standard[.masterHexEncodedPublicKey] != nil {
UserDefaults.standard[.wasUnlinked] = true
NotificationCenter.default.post(name: .dataNukeRequested, object: nil, userInfo: nil)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
isViewVisible = true
let hasSeenLightModeSheet = UserDefaults.standard[.hasSeenLightModeSheet]
if !hasSeenLightModeSheet {
let lightModeSheet = LightModeSheet()
lightModeSheet.modalPresentationStyle = .overFullScreen
lightModeSheet.modalTransitionStyle = .crossDissolve
present(lightModeSheet, animated: true, completion: nil)
UserDefaults.standard[.hasSeenLightModeSheet] = true
}
UserDefaults.standard[.hasLaunchedOnce] = true
}

@ -69,9 +69,4 @@ final class OpenGroupSuggestionSheet : Sheet {
}
close()
}
override func close() {
UserDefaults.standard[.hasSeenOpenGroupSuggestionSheet] = true
super.close()
}
}

@ -89,8 +89,6 @@ final class PNModeVC : BaseVC, OptionViewDelegate {
return present(alert, animated: true, completion: nil)
}
UserDefaults.standard[.isUsingFullAPNs] = (selectedOptionView == apnsOptionView)
UserDefaults.standard[.hasSeenMultiDeviceRemovalSheet] = true
UserDefaults.standard[.hasSeenLightModeSheet] = true
TSAccountManager.sharedInstance().didRegister()
let homeVC = HomeVC()
navigationController!.setViewControllers([ homeVC ], animated: true)

@ -1,7 +1,9 @@
import Sodium
final class RegisterVC : BaseVC {
private var seed: Data! { didSet { updateKeyPair() } }
private var keyPair: ECKeyPair! { didSet { updatePublicKeyLabel() } }
private var ed25519KeyPair: Sign.KeyPair!
private var x25519KeyPair: ECKeyPair! { didSet { updatePublicKeyLabel() } }
// MARK: Components
private lazy var publicKeyLabel: UILabel = {
@ -129,15 +131,19 @@ final class RegisterVC : BaseVC {
// MARK: Updating
private func updateSeed() {
seed = Randomness.generateRandomBytes(16)
seed = Data.getSecureRandomData(ofSize: 16)!
}
private func updateKeyPair() {
keyPair = Curve25519.generateKeyPair(fromSeed: seed + seed)
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))
}
private func updatePublicKeyLabel() {
let hexEncodedPublicKey = keyPair.hexEncodedPublicKey
let hexEncodedPublicKey = x25519KeyPair.hexEncodedPublicKey
let characterCount = hexEncodedPublicKey.count
var count = 0
let limit = 32
@ -165,11 +171,13 @@ final class RegisterVC : BaseVC {
// MARK: Interaction
@objc private func register() {
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 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)
TSAccountManager.sharedInstance().phoneNumberAwaitingVerification = x25519KeyPair!.hexEncodedPublicKey
OWSPrimaryStorage.shared().setRestorationTime(0)
UserDefaults.standard[.hasViewedSeed] = false
let displayNameVC = DisplayNameVC()
@ -177,7 +185,7 @@ final class RegisterVC : BaseVC {
}
@objc private func copyPublicKey() {
UIPasteboard.general.string = keyPair.hexEncodedPublicKey
UIPasteboard.general.string = x25519KeyPair.hexEncodedPublicKey
copyPublicKeyButton.isUserInteractionEnabled = false
UIView.transition(with: copyPublicKeyButton, duration: 0.25, options: .transitionCrossDissolve, animations: {
self.copyPublicKeyButton.setTitle("Copied", for: UIControl.State.normal)

@ -5,13 +5,10 @@ public enum LKUserDefaults {
public enum Bool : Swift.String {
case hasLaunchedOnce
case hasSeenGIFMetadataWarning
case hasSeenLightModeSheet
case hasSeenMultiDeviceRemovalSheet
case hasSeenOpenGroupSuggestionSheet
case hasViewedSeed
case isUsingFullAPNs
/// Whether the device was unlinked as a slave device (used to notify the user on the landing screen).
case wasUnlinked
case isUsingFullAPNs
}
public enum Date : Swift.String {

@ -8,6 +8,9 @@
NS_ASSUME_NONNULL_BEGIN
extern NSString *const OWSPrimaryStorageIdentityKeyStoreIdentityKey;
extern NSString *const LKSeedKey;
extern NSString *const LKED25519SecretKey;
extern NSString *const LKED25519PublicKey;
extern NSString *const OWSPrimaryStorageIdentityKeyStoreCollection;
extern NSString *const OWSPrimaryStorageTrustedKeysCollection;
@ -31,6 +34,8 @@ extern const NSUInteger kStoredIdentityKeyLength;
// This class can be safely accessed and used from any thread.
@interface OWSIdentityManager : NSObject <IdentityKeyStore>
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage NS_DESIGNATED_INITIALIZER;
@ -70,10 +75,10 @@ extern const NSUInteger kStoredIdentityKeyLength;
- (BOOL)saveRemoteIdentity:(NSData *)identityKey recipientId:(NSString *)recipientId;
#pragma mark - Debug
- (nullable ECKeyPair *)identityKeyPair;
#pragma mark - Debug
#if DEBUG
// Clears everything except the local identity key.
- (void)clearIdentityState:(YapDatabaseReadWriteTransaction *)transaction;

@ -33,6 +33,9 @@ NS_ASSUME_NONNULL_BEGIN
// Storing our own identity key
NSString *const OWSPrimaryStorageIdentityKeyStoreIdentityKey = @"TSStorageManagerIdentityKeyStoreIdentityKey";
NSString *const LKSeedKey = @"LKLokiSeed";
NSString *const LKED25519SecretKey = @"LKED25519SecretKey";
NSString *const LKED25519PublicKey = @"LKED25519PublicKey";
NSString *const OWSPrimaryStorageIdentityKeyStoreCollection = @"TSStorageManagerIdentityKeyStoreCollection";
// Storing recipients identity keys
@ -57,7 +60,6 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
@interface OWSIdentityManager ()
@property (nonatomic, readonly) OWSPrimaryStorage *primaryStorage;
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@end

Loading…
Cancel
Save