pull/52/head
Niels Andriesse 6 years ago
parent cba676623a
commit 0743fbf855

@ -62,7 +62,8 @@ final class AccountDetailsViewController : OnboardingBaseViewController {
guard !OWSProfileManager.shared().isProfileNameTooLong(normalizedName) else { guard !OWSProfileManager.shared().isProfileNameTooLong(normalizedName) else {
return OWSAlerts.showErrorAlert(message: NSLocalizedString("PROFILE_VIEW_ERROR_PROFILE_NAME_TOO_LONG", comment: "Error message shown when user tries to update profile with a profile name that is too long")) return OWSAlerts.showErrorAlert(message: NSLocalizedString("PROFILE_VIEW_ERROR_PROFILE_NAME_TOO_LONG", comment: "Error message shown when user tries to update profile with a profile name that is too long"))
} }
OWSProfileManager.shared().updateLocalProfileName(normalizedUserName, avatarImage: nil, success: { }, failure: { }) // Try to save the user name but ignore the result
} }
onboardingController.pushKeyPairViewController(from: self, userName: normalizedUserName) onboardingController.pushKeyPairViewController(from: self)
} }
} }

@ -3,7 +3,6 @@ final class SeedViewController : OnboardingBaseViewController {
private var mode: Mode = .register { didSet { if mode != oldValue { handleModeChanged() } } } private var mode: Mode = .register { didSet { if mode != oldValue { handleModeChanged() } } }
private var seed: Data! { didSet { updateMnemonic() } } private var seed: Data! { didSet { updateMnemonic() } }
private var mnemonic: String! { didSet { handleMnemonicChanged() } } private var mnemonic: String! { didSet { handleMnemonicChanged() } }
private var userName: String?
// MARK: Components // MARK: Components
private lazy var registerStackView: UIStackView = { private lazy var registerStackView: UIStackView = {
@ -111,11 +110,6 @@ final class SeedViewController : OnboardingBaseViewController {
enum Mode { case register, restore } enum Mode { case register, restore }
// MARK: Lifecycle // MARK: Lifecycle
init(onboardingController: OnboardingController, userName: String?) {
super.init(onboardingController: onboardingController)
self.userName = userName
}
override func viewDidLoad() { override func viewDidLoad() {
super.loadView() super.loadView()
setUpViewHierarchy() setUpViewHierarchy()
@ -232,19 +226,11 @@ final class SeedViewController : OnboardingBaseViewController {
let accountManager = TSAccountManager.sharedInstance() let accountManager = TSAccountManager.sharedInstance()
accountManager.phoneNumberAwaitingVerification = hexEncodedPublicKey accountManager.phoneNumberAwaitingVerification = hexEncodedPublicKey
accountManager.didRegister() accountManager.didRegister()
let onSuccess = { [weak self] in switch mode {
switch mode { case .register: Analytics.shared.track("Seed Created")
case .register: Analytics.shared.track("Seed Created") case .restore: Analytics.shared.track("Seed Restored")
case .restore: Analytics.shared.track("Seed Restored")
}
guard let strongSelf = self else { return }
strongSelf.onboardingController.verificationDidComplete(fromView: strongSelf)
UserDefaults.standard.set(true, forKey: "didUpdateForMainnet")
}
if let userName = userName {
OWSProfileManager.shared().updateLocalProfileName(userName, avatarImage: nil, success: onSuccess, failure: onSuccess) // Try to save the user name but ignore the result
} else {
onSuccess()
} }
onboardingController.verificationDidComplete(fromView: self)
UserDefaults.standard.set(true, forKey: "didUpdateForMainnet")
} }
} }

@ -78,7 +78,6 @@
#import <SignalServiceKit/Contact.h> #import <SignalServiceKit/Contact.h>
#import <SignalServiceKit/ContactsUpdater.h> #import <SignalServiceKit/ContactsUpdater.h>
#import <SignalServiceKit/DataSource.h> #import <SignalServiceKit/DataSource.h>
#import <SignalServiceKit/ECKeyPair+Loki.h>
#import <SignalServiceKit/MIMETypeUtil.h> #import <SignalServiceKit/MIMETypeUtil.h>
#import <SignalServiceKit/NSData+Image.h> #import <SignalServiceKit/NSData+Image.h>
#import <SignalServiceKit/NSNotificationCenter+OWS.h> #import <SignalServiceKit/NSNotificationCenter+OWS.h>

@ -123,9 +123,9 @@ public class OnboardingController: NSObject {
viewController.navigationController?.pushViewController(accountDetailsVC, animated: true) viewController.navigationController?.pushViewController(accountDetailsVC, animated: true)
} }
func pushKeyPairViewController(from viewController: UIViewController, userName: String?) { func pushKeyPairViewController(from viewController: UIViewController) {
AssertIsOnMainThread() AssertIsOnMainThread()
let seedVC = SeedViewController(onboardingController: self, userName: userName) let seedVC = SeedViewController(onboardingController: self)
viewController.navigationController?.pushViewController(seedVC, animated: true) viewController.navigationController?.pushViewController(seedVC, animated: true)
} }

@ -182,8 +182,8 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess
BOOL isVoiceMessage = (attachments.count == 1 && attachments.lastObject.isVoiceMessage); BOOL isVoiceMessage = (attachments.count == 1 && attachments.lastObject.isVoiceMessage);
// Loki: If we're not friends then always set the message to a friend request message // Loki: If we're not friends then always set the message to a friend request message.
// If we're friends then the assumption is that we have the other user's prekey bundle // If we're friends then the assumption is that we have the other user's pre key bundle.
NSString *messageClassAsString = (thread.isContactFriend || thread.isGroupThread) ? @"TSOutgoingMessage" : @"LKFriendRequestMessage"; NSString *messageClassAsString = (thread.isContactFriend || thread.isGroupThread) ? @"TSOutgoingMessage" : @"LKFriendRequestMessage";
Class messageClass = NSClassFromString(messageClassAsString); Class messageClass = NSClassFromString(messageClassAsString);

@ -1,8 +0,0 @@
@import Curve25519Kit;
@interface ECKeyPair (ECKeyPairExtension)
/// Based on `ECKeyPair.generateKeyPair()`.
+ (nonnull ECKeyPair *)generateKeyPairWithHexEncodedPrivateKey:(nonnull NSString *)hexEncodedPrivateKey;
@end

@ -1,28 +0,0 @@
#import "ECKeyPair+Loki.h"
extern void curve25519_donna(unsigned char *output, const unsigned char *a, const unsigned char *b);
@implementation ECKeyPair (ECKeyPairExtension)
+ (nonnull ECKeyPair *)generateKeyPairWithHexEncodedPrivateKey:(nonnull NSString *)hexEncodedPrivateKey {
NSMutableData *privateKey = [NSMutableData new];
for (NSUInteger i = 0; i < hexEncodedPrivateKey.length; i += 2) {
char buffer[3];
buffer[0] = (char)[hexEncodedPrivateKey characterAtIndex:i];
buffer[1] = (char)[hexEncodedPrivateKey characterAtIndex:i + 1];
buffer[2] = '\0';
unsigned char byte = (unsigned char)strtol(buffer, NULL, 16);
[privateKey appendBytes:&byte length:1];
}
static const uint8_t basepoint[ECCKeyLength] = { 9 };
NSMutableData *publicKey = [NSMutableData dataWithLength:ECCKeyLength];
if (!publicKey) { OWSFail(@"Couldn't allocate buffer."); }
curve25519_donna(publicKey.mutableBytes, privateKey.mutableBytes, basepoint);
// Use KVC to access privateKey and publicKey even though they're private
ECKeyPair *result = [ECKeyPair new];
[result setValue:[privateKey copy] forKey:@"privateKey"];
[result setValue:[publicKey copy] forKey:@"publicKey"];
return result;
}
@end

@ -7,92 +7,28 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSPrimaryStorage (Loki) @interface OWSPrimaryStorage (Loki)
# pragma mark - Prekey for Contact # pragma mark - Pre Key for Contact
/**
Check if we have a `PreKeyRecord` for the given contact.
@param pubKey The hex encoded public key of the contact.
@return Whether we have a prekey or not.
*/
- (BOOL)hasPreKeyForContact:(NSString *)pubKey; - (BOOL)hasPreKeyForContact:(NSString *)pubKey;
/**
Get the `PreKeyRecord` associated with the given contact.
@param pubKey The hex encoded public key of the contact.
@param transaction A `YapDatabaseReadTransaction`.
@return The record associated with the contact or `nil` if it doesn't exist.
*/
- (PreKeyRecord *_Nullable)getPreKeyForContact:(NSString *)pubKey transaction:(YapDatabaseReadTransaction *)transaction; - (PreKeyRecord *_Nullable)getPreKeyForContact:(NSString *)pubKey transaction:(YapDatabaseReadTransaction *)transaction;
/**
Get the `PreKeyRecord` associated with the given contact.
If the record doesn't exist then this will create a new one.
@param pubKey The hex encoded public key of the contact.
@return The record associated with the contact.
*/
- (PreKeyRecord *)getOrCreatePreKeyForContact:(NSString *)pubKey; - (PreKeyRecord *)getOrCreatePreKeyForContact:(NSString *)pubKey;
# pragma mark - PreKeyBundle # pragma mark - Pre Key Bundle
/** /**
Generate a `PreKeyBundle` for the given contact. * Generates a pre key bundle but doesn't store it as pre key bundles are supposed to be sent to other users without ever being stored.
This doesn't store the prekey bundle, and you shouldn't store this bundle.
It's used for generating bundles to send to other users.
@param pubKey The hex encoded public key of the contact.
@return A prekey bundle for the contact.
*/ */
- (PreKeyBundle *)generatePreKeyBundleForContact:(NSString *)pubKey; - (PreKeyBundle *)generatePreKeyBundleForContact:(NSString *)pubKey;
/**
Get the `PreKeyBundle` associated with the given contact.
@param pubKey The hex encoded public key of the contact.
@return The prekey bundle or `nil` if it doesn't exist.
*/
- (PreKeyBundle *_Nullable)getPreKeyBundleForContact:(NSString *)pubKey; - (PreKeyBundle *_Nullable)getPreKeyBundleForContact:(NSString *)pubKey;
/**
Set the `PreKeyBundle` for the given contact.
@param bundle The prekey bundle.
@param transaction A `YapDatabaseReadWriteTransaction`.
@param pubKey The hex encoded public key of the contact.
*/
- (void)setPreKeyBundle:(PreKeyBundle *)bundle forContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)setPreKeyBundle:(PreKeyBundle *)bundle forContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction;
/**
Remove the `PreKeyBundle` for the given contact.
@param pubKey The hex encoded public key of the contact.
@param transaction A `YapDatabaseReadWriteTransaction`.
*/
- (void)removePreKeyBundleForContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)removePreKeyBundleForContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction;
# pragma mark - Last Hash # pragma mark - Last Message Hash
/** /**
Get the last message hash for the given service node. * Gets the last message hash and removes it if its `expiresAt` has already passed.
This function will check the stored last hash and remove it if the `expiresAt` has already passed.
@param serviceNode The service node ID.
@param transaction A read write transaction.
@return The last hash or `nil` if it doesn't exist.
*/ */
- (NSString *_Nullable)getLastMessageHashForServiceNode:(NSString *)serviceNode transaction:(YapDatabaseReadWriteTransaction *)transaction; - (NSString *_Nullable)getLastMessageHashForServiceNode:(NSString *)serviceNode transaction:(YapDatabaseReadWriteTransaction *)transaction;
/**
Set the last message hash for the given service node.
This will override any previous hashes stored for the given service node.
@param serviceNode The service node ID.
@param hash The last message hash.
@param expiresAt The time the message expires on the server.
@param transaction A read write transaction.
*/
- (void)setLastMessageHashForServiceNode:(NSString *)serviceNode hash:(NSString *)hash expiresAt:(u_int64_t)expiresAt transaction:(YapDatabaseReadWriteTransaction *)transaction NS_SWIFT_NAME(setLastMessageHash(forServiceNode:hash:expiresAt:transaction:)); - (void)setLastMessageHashForServiceNode:(NSString *)serviceNode hash:(NSString *)hash expiresAt:(u_int64_t)expiresAt transaction:(YapDatabaseReadWriteTransaction *)transaction NS_SWIFT_NAME(setLastMessageHash(forServiceNode:hash:expiresAt:transaction:));
# pragma mark - Group Chat # pragma mark - Group Chat

@ -12,18 +12,12 @@
#import <AxolotlKit/NSData+keyVersionByte.h> #import <AxolotlKit/NSData+keyVersionByte.h>
#import "NSObject+Casting.h" #import "NSObject+Casting.h"
#define OWSPrimaryStoragePreKeyStoreCollection @"TSStorageManagerPreKeyStoreCollection"
#define LKPreKeyContactCollection @"LKPreKeyContactCollection"
#define LKPreKeyBundleCollection @"LKPreKeyBundleCollection"
#define LKLastMessageHashCollection @"LKLastMessageHashCollection"
#define LKReceivedMessageHashesKey @"LKReceivedMessageHashesKey"
#define LKReceivedMessageHashesCollection @"LKReceivedMessageHashesCollection"
#define LKMessageIDCollection @"LKMessageIDCollection"
#define LKModerationPermissionCollection @"LKModerationPermissionCollection"
@implementation OWSPrimaryStorage (Loki) @implementation OWSPrimaryStorage (Loki)
# pragma mark - Dependencies # pragma mark - Convenience
#define OWSPrimaryStoragePreKeyStoreCollection @"TSStorageManagerPreKeyStoreCollection"
#define LKPreKeyContactCollection @"LKPreKeyContactCollection"
- (OWSIdentityManager *)identityManager { - (OWSIdentityManager *)identityManager {
return OWSIdentityManager.sharedManager; return OWSIdentityManager.sharedManager;
@ -33,7 +27,7 @@
return TSAccountManager.sharedInstance; return TSAccountManager.sharedInstance;
} }
# pragma mark - Prekey for Contact # pragma mark - Pre Key for Contact
- (BOOL)hasPreKeyForContact:(NSString *)pubKey { - (BOOL)hasPreKeyForContact:(NSString *)pubKey {
int preKeyId = [self.dbReadWriteConnection intForKey:pubKey inCollection:LKPreKeyContactCollection]; int preKeyId = [self.dbReadWriteConnection intForKey:pubKey inCollection:LKPreKeyContactCollection];
@ -64,7 +58,7 @@
@try { @try {
return [self throws_loadPreKey:preKeyId]; return [self throws_loadPreKey:preKeyId];
} @catch (NSException *exception) { } @catch (NSException *exception) {
NSLog(@"[Loki] New prekey generated for %@.", pubKey); NSLog(@"[Loki] New pre key generated for %@.", pubKey);
return [self generateAndStorePreKeyForContact:pubKey]; return [self generateAndStorePreKeyForContact:pubKey];
} }
} }
@ -83,10 +77,12 @@
return record; return record;
} }
# pragma mark - PreKeyBundle # pragma mark - Pre Key Bundle
#define LKPreKeyBundleCollection @"LKPreKeyBundleCollection"
- (PreKeyBundle *)generatePreKeyBundleForContact:(NSString *)pubKey { - (PreKeyBundle *)generatePreKeyBundleForContact:(NSString *)pubKey {
// Check prekeys to make sure we have them for this function // Check pre keys to make sure we have them
[TSPreKeyManager checkPreKeys]; [TSPreKeyManager checkPreKeys];
ECKeyPair *_Nullable keyPair = self.identityManager.identityKeyPair; ECKeyPair *_Nullable keyPair = self.identityManager.identityKeyPair;
@ -103,7 +99,7 @@
SignedPreKeyRecord *_Nullable signedPreKey = self.currentSignedPreKey; SignedPreKeyRecord *_Nullable signedPreKey = self.currentSignedPreKey;
if (!signedPreKey) { if (!signedPreKey) {
OWSFailDebug(@"Signed prekey is null"); OWSFailDebug(@"Signed pre key is null.");
} }
PreKeyRecord *preKey = [self getOrCreatePreKeyForContact:pubKey]; PreKeyRecord *preKey = [self getOrCreatePreKeyForContact:pubKey];
@ -125,16 +121,16 @@
} }
- (void)setPreKeyBundle:(PreKeyBundle *)bundle forContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction { - (void)setPreKeyBundle:(PreKeyBundle *)bundle forContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction {
[transaction setObject:bundle [transaction setObject:bundle forKey:pubKey inCollection:LKPreKeyBundleCollection];
forKey:pubKey
inCollection:LKPreKeyBundleCollection];
} }
- (void)removePreKeyBundleForContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction { - (void)removePreKeyBundleForContact:(NSString *)pubKey transaction:(YapDatabaseReadWriteTransaction *)transaction {
[transaction removeObjectForKey:pubKey inCollection:LKPreKeyBundleCollection]; [transaction removeObjectForKey:pubKey inCollection:LKPreKeyBundleCollection];
} }
# pragma mark - Last Hash # pragma mark - Last Message Hash
#define LKLastMessageHashCollection @"LKLastMessageHashCollection"
- (NSString *_Nullable)getLastMessageHashForServiceNode:(NSString *)serviceNode transaction:(YapDatabaseReadWriteTransaction *)transaction { - (NSString *_Nullable)getLastMessageHashForServiceNode:(NSString *)serviceNode transaction:(YapDatabaseReadWriteTransaction *)transaction {
NSDictionary *_Nullable dict = [transaction objectForKey:serviceNode inCollection:LKLastMessageHashCollection]; NSDictionary *_Nullable dict = [transaction objectForKey:serviceNode inCollection:LKLastMessageHashCollection];
@ -166,6 +162,8 @@
# pragma mark - Group Chat # pragma mark - Group Chat
#define LKMessageIDCollection @"LKMessageIDCollection"
- (void)setIDForMessageWithServerID:(NSUInteger)serverID to:(NSString *)messageID in:(YapDatabaseReadWriteTransaction *)transaction { - (void)setIDForMessageWithServerID:(NSUInteger)serverID to:(NSString *)messageID in:(YapDatabaseReadWriteTransaction *)transaction {
NSString *key = [NSString stringWithFormat:@"%@", @(serverID)]; NSString *key = [NSString stringWithFormat:@"%@", @(serverID)];
[transaction setObject:messageID forKey:key inCollection:LKMessageIDCollection]; [transaction setObject:messageID forKey:key inCollection:LKMessageIDCollection];

@ -18,7 +18,7 @@
NSError *error; NSError *error;
SSKProtoPrekeyBundleMessage *_Nullable message = [preKeyBuilder buildAndReturnError:&error]; SSKProtoPrekeyBundleMessage *_Nullable message = [preKeyBuilder buildAndReturnError:&error];
if (error || !message) { if (error || !message) {
OWSFailDebug(@"Failed to build preKeyBundle for %@: %@", recipient.recipientId, error); OWSFailDebug(@"Failed to build pre key bundle for %@: %@", recipient.recipientId, error);
} else { } else {
[contentBuilder setPrekeyBundleMessage:message]; [contentBuilder setPrekeyBundleMessage:message];
} }

@ -1803,7 +1803,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
OWSAssertDebug(recipientId.length > 0); OWSAssertDebug(recipientId.length > 0);
// Loki: Handle friend requests differently // Loki: Handle friend requests differently
Boolean isFriendRequest = [messageSend.message isKindOfClass:LKFriendRequestMessage.class]; BOOL isFriendRequest = [messageSend.message isKindOfClass:LKFriendRequestMessage.class];
if (isFriendRequest) { if (isFriendRequest) {
return [self throws_encryptedFriendMessageForMessageSend:messageSend deviceId:deviceId plainText:plainText]; return [self throws_encryptedFriendMessageForMessageSend:messageSend deviceId:deviceId plainText:plainText];
} }

Loading…
Cancel
Save