Glue together remaining pieces

pull/55/head
Niels Andriesse 6 years ago
parent a42ffefec3
commit 6176c63a81

@ -341,8 +341,8 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
deviceLinkingModal.modalPresentationStyle = .overFullScreen
present(deviceLinkingModal, animated: true, completion: nil)
let masterHexEncodedPublicKey = masterHexEncodedPublicKeyTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces)
let thread = TSContactThread.getOrCreateThread(contactId: masterHexEncodedPublicKey)
ThreadUtil.enqueueDeviceLinkingMessage(in: thread)
let linkingRequestMessage = DeviceLinkingUtilities.getLinkingRequestMessage(for: masterHexEncodedPublicKey)
ThreadUtil.enqueue(linkingRequestMessage)
} else {
onboardingController.pushDisplayNameVC(from: self)
}

@ -61,7 +61,8 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
super.init(nibName: nil, bundle: nil)
}
@objc convenience init(modeAsString: String, delegate: DeviceLinkingModalDelegate?) {
@objc(initWithMode:delegate:)
convenience init(modeAsString: String, delegate: DeviceLinkingModalDelegate?) {
guard let mode = Mode(rawValue: modeAsString) else { preconditionFailure("Invalid mode: \(modeAsString).") }
self.init(mode: mode, delegate: delegate)
}
@ -110,10 +111,6 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
// MARK: Device Linking
func requestUserAuthorization(for deviceLink: DeviceLink) {
self.deviceLink = deviceLink
@ -128,9 +125,10 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
@objc private func authorizeDeviceLink() {
let deviceLink = self.deviceLink!
let linkingAuthorizationMessage = DeviceLinkingUtilities.getLinkingAuthorizationMessage(for: deviceLink)
ThreadUtil.enqueue(linkingAuthorizationMessage)
let session = DeviceLinkingSession.current!
session.stopListeningForLinkingRequests()
// TODO: Send device link authorized message
dismiss(animated: true, completion: nil)
}

@ -515,7 +515,7 @@
- (void)linkDevice
{
LKDeviceLinkingModal *deviceLinkingModal = [[LKDeviceLinkingModal alloc] initWithModeAsString:@"master" delegate:nil];
LKDeviceLinkingModal *deviceLinkingModal = [[LKDeviceLinkingModal alloc] initWithMode:@"master" delegate:nil];
deviceLinkingModal.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:deviceLinkingModal animated:YES completion:nil];
}

@ -4,6 +4,7 @@
NS_ASSUME_NONNULL_BEGIN
@class LKDeviceLinkingMessage;
@class OWSBlockingManager;
@class OWSContact;
@class OWSContactsManager;
@ -45,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Durable Message Enqueue
+ (TSOutgoingMessage *)enqueueFriendRequestAcceptanceMessageInThread:(TSThread *)thread;
+ (TSOutgoingMessage *)enqueueDeviceLinkingMessageInThread:(TSThread *)thread;
+ (void)enqueueDeviceLinkingMessage:(LKDeviceLinkingMessage *)message;
+ (TSOutgoingMessage *)enqueueMessageWithText:(NSString *)fullMessageText
inThread:(TSThread *)thread

@ -94,13 +94,11 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess
return message;
}
+ (LKDeviceLinkingMessage *)enqueueDeviceLinkingMessageInThread:(TSThread *)thread
+ (void)enqueueDeviceLinkingMessage:(LKDeviceLinkingMessage *)message
{
LKDeviceLinkingMessage *message = [[LKDeviceLinkingMessage alloc] initInThread:thread];
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self.messageSenderJobQueue addMessage:message transaction:transaction];
}];
return message;
}
+ (TSOutgoingMessage *)enqueueMessageWithText:(NSString *)fullMessageText

@ -0,0 +1,24 @@
public enum DeviceLinkingUtilities {
// When requesting a device link, the slave device signs the master device's public key. When authorizing
// a device link, the master device signs the slave device's public key.
public static func getLinkingRequestMessage(for masterHexEncodedPublicKey: String) -> DeviceLinkingMessage {
let slaveKeyPair = OWSIdentityManager.shared().identityKeyPair()!
let slaveHexEncodedPublicKey = slaveKeyPair.hexEncodedPublicKey
let slaveSignature = try! Ed25519.sign(Data(hex: masterHexEncodedPublicKey), with: slaveKeyPair)
let thread = TSContactThread.getOrCreateThread(contactId: masterHexEncodedPublicKey)
return DeviceLinkingMessage(in: thread, masterHexEncodedPublicKey: masterHexEncodedPublicKey, slaveHexEncodedPublicKey: slaveHexEncodedPublicKey, masterSignature: nil, slaveSignature: slaveSignature)
}
public static func getLinkingAuthorizationMessage(for deviceLink: DeviceLink) -> DeviceLinkingMessage {
let masterKeyPair = OWSIdentityManager.shared().identityKeyPair()!
let masterHexEncodedPublicKey = masterKeyPair.hexEncodedPublicKey
let slaveHexEncodedPublicKey = deviceLink.slave.hexEncodedPublicKey
let masterSignature = try! Ed25519.sign(Data(hex: slaveHexEncodedPublicKey), with: masterKeyPair)
let slaveSignature = deviceLink.slave.signature!
let thread = TSContactThread.getOrCreateThread(contactId: slaveHexEncodedPublicKey)
return DeviceLinkingMessage(in: thread, masterHexEncodedPublicKey: masterHexEncodedPublicKey, slaveHexEncodedPublicKey: slaveHexEncodedPublicKey, masterSignature: masterSignature, slaveSignature: slaveSignature)
}
}

@ -3,6 +3,11 @@
NS_SWIFT_NAME(DeviceLinkingMessage)
@interface LKDeviceLinkingMessage : TSOutgoingMessage
- (instancetype)initInThread:(TSThread *)thread;
@property (nonatomic, readonly) NSString *masterHexEncodedPublicKey;
@property (nonatomic, readonly) NSString *slaveHexEncodedPublicKey;
@property (nonatomic, readonly) NSData *masterSignature; // nil for device linking requests
@property (nonatomic, readonly) NSData *slaveSignature;
- (instancetype)initInThread:(TSThread *)thread masterHexEncodedPublicKey:(NSString *)masterHexEncodedPublicKey slaveHexEncodedPublicKey:(NSString *)slaveHexEncodedPublicKey masterSignature:(NSData *)masterSignature slaveSignature:(NSData *)slaveSignature;
@end

@ -7,29 +7,30 @@
@implementation LKDeviceLinkingMessage
- (instancetype)initInThread:(nullable TSThread *)thread {
return [self initOutgoingMessageWithTimestamp:NSDate.ows_millisecondTimeStamp inThread:thread messageBody:@"" attachmentIds:[NSMutableArray<NSString *> new]
- (instancetype)initInThread:(TSThread *)thread masterHexEncodedPublicKey:(NSString *)masterHexEncodedPublicKey slaveHexEncodedPublicKey:(NSString *)slaveHexEncodedPublicKey masterSignature:(NSData *)masterSignature slaveSignature:(NSData *)slaveSignature {
self = [self initOutgoingMessageWithTimestamp:NSDate.ows_millisecondTimeStamp inThread:thread messageBody:@"" attachmentIds:[NSMutableArray<NSString *> new]
expiresInSeconds:0 expireStartedAt:0 isVoiceMessage:NO groupMetaMessage:TSGroupMetaMessageUnspecified quotedMessage:nil contactShare:nil linkPreview:nil];
if (self) {
_masterHexEncodedPublicKey = masterHexEncodedPublicKey;
_slaveHexEncodedPublicKey = slaveHexEncodedPublicKey;
_masterSignature = masterSignature;
_slaveSignature = slaveSignature;
}
return self;
}
- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient {
SSKProtoContentBuilder *contentBuilder = [super contentBuilder:recipient];
// When authorizing a device link, the master device signs the slave device's public key. When requesting
// a device link, the slave device signs the master device's public key.
SSKProtoLokiDeviceLinkingMessageBuilder *deviceLinkingMessageBuilder = [SSKProtoLokiDeviceLinkingMessage builder];
NSString *masterHexEncodedPublicKey = recipient.recipientId;
NSData *masterPublicKey = [NSData dataFromHexString:masterHexEncodedPublicKey];
[deviceLinkingMessageBuilder setMasterHexEncodedPublicKey:masterHexEncodedPublicKey];
ECKeyPair *slaveKeyPair = OWSIdentityManager.sharedManager.identityKeyPair;
NSString *slaveHexEncodedPublicKey = slaveKeyPair.hexEncodedPublicKey;
[deviceLinkingMessageBuilder setSlaveHexEncodedPublicKey:slaveHexEncodedPublicKey];
NSData *slaveSignature = [Ed25519 sign:masterPublicKey withKeyPair:slaveKeyPair error:nil];
[deviceLinkingMessageBuilder setSlaveSignature:slaveSignature];
[deviceLinkingMessageBuilder setMasterHexEncodedPublicKey:self.masterHexEncodedPublicKey];
[deviceLinkingMessageBuilder setSlaveHexEncodedPublicKey:self.slaveHexEncodedPublicKey];
if (self.masterSignature != nil) { [deviceLinkingMessageBuilder setMasterSignature:self.masterSignature]; }
[deviceLinkingMessageBuilder setSlaveSignature:self.slaveSignature];
NSError *error;
SSKProtoLokiDeviceLinkingMessage *deviceLinkingMessage = [deviceLinkingMessageBuilder buildAndReturnError:&error];
if (error || deviceLinkingMessage == nil) {
OWSFailDebug(@"Failed to build device linking message for: %@ due to error: %@", masterHexEncodedPublicKey, error);
OWSFailDebug(@"Failed to build device linking message for: %@ due to error: %@", self.masterHexEncodedPublicKey, error);
}
SSKProtoContentBuilder *contentBuilder = [super contentBuilder:recipient];
[contentBuilder setLokiDeviceLinkingMessage:deviceLinkingMessage];
return contentBuilder;
}

@ -429,14 +429,27 @@ NS_ASSUME_NONNULL_BEGIN
OWSLogInfo(@"handling content: <Content: %@>", [self descriptionForContent:contentProto]);
// Loki: Handle device linking message
if (contentProto.lokiDeviceLinkingMessage != nil && contentProto.lokiDeviceLinkingMessage.type == SSKProtoLokiDeviceLinkingMessageTypeRequest) {
OWSLogInfo(@"[Loki] Received a device linking request from: %@", envelope.source);
if (contentProto.lokiDeviceLinkingMessage != nil) {
NSString *masterHexEncodedPublicKey = contentProto.lokiDeviceLinkingMessage.masterHexEncodedPublicKey;
NSString *slaveHexEncodedPublicKey = contentProto.lokiDeviceLinkingMessage.slaveHexEncodedPublicKey;
NSData *slaveSignature = contentProto.lokiDeviceLinkingMessage.slaveSignature;
if (slaveSignature == nil) {
OWSFailDebug(@"Received a device linking request without an attached slave signature.");
switch (contentProto.lokiDeviceLinkingMessage.type) {
case SSKProtoLokiDeviceLinkingMessageTypeRequest: {
OWSLogInfo(@"[Loki] Received a device linking request from: %@", envelope.source); // Not slaveHexEncodedPublicKey
if (slaveSignature == nil) { OWSFailDebug(@"Received a device linking request from: %@ without a slave signature.", envelope.source); }
[LKDeviceLinkingSession.current processLinkingRequestFrom:slaveHexEncodedPublicKey to:masterHexEncodedPublicKey with:slaveSignature];
break;
}
case SSKProtoLokiDeviceLinkingMessageTypeGrant: {
OWSLogInfo(@"[Loki] Received a device linking authorization from: %@", envelope.source); // Not slaveHexEncodedPublicKey
NSData *masterSignature = contentProto.lokiDeviceLinkingMessage.masterSignature;
if (masterSignature == nil) { OWSFailDebug(@"Received a device linking authorization from: %@ without a master signature.", envelope.source); }
if (slaveSignature == nil) { OWSFailDebug(@"Received a device linking authorization from: %@ without a slave signature.", envelope.source); }
[LKDeviceLinkingSession.current processLinkingAuthorizationFrom:masterHexEncodedPublicKey for:slaveHexEncodedPublicKey masterSignature:masterSignature slaveSignature:slaveSignature];
break;
}
default: break;
}
NSString *masterHexEncodedPublicKey = contentProto.lokiDeviceLinkingMessage.masterHexEncodedPublicKey;
[LKDeviceLinkingSession.current processLinkingRequestFrom:envelope.source to:masterHexEncodedPublicKey with:slaveSignature];
}
// Loki: Handle pre key bundle message

Loading…
Cancel
Save