From 3f43a05df65c6fdffc8d8b62c7d4b9b0066b86e2 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Wed, 29 Jan 2020 10:31:57 +1100 Subject: [PATCH 1/7] enable send UD message --- Signal/Signal-Info.plist | 2 +- SignalServiceKit/src/Messages/OWSMessageSender.m | 3 ++- .../src/Messages/UD/OWSUDManager.swift | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index cb4b80d83..daba681ed 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -7,7 +7,7 @@ CarthageVersion 0.34.0 OSXVersion - 10.15.1 + 10.15.2 WebRTCCommit 1445d719bf05280270e9f77576f80f973fd847f8 M73 diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 9fdde8490..d5f10b5ca 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -620,6 +620,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; failure:(RetryableFailureHandler)failureHandlerParam { AssertIsOnSendingQueue(); + OWSAssert(senderCertificate); void (^successHandler)(void) = ^() { dispatch_async([OWSDispatch sendingQueue], ^{ @@ -958,7 +959,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSString *contactID = messageSend.recipient.recipientId; BOOL isGroupMessage = messageSend.thread.isGroupThread; BOOL isDeviceLinkMessage = [message isKindOfClass:LKDeviceLinkMessage.class]; - if (isGroupMessage || isDeviceLinkMessage) { + if (isGroupMessage || isDeviceLinkMessage || messageSend.isUDSend) { [self sendMessage:messageSend]; } else { BOOL isSilentMessage = message.isSilent || [message isKindOfClass:LKEphemeralMessage.class] || [message isKindOfClass:OWSOutgoingSyncMessage.class]; diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 3c1de038f..05caa3df0 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -417,7 +417,8 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { // Try to obtain a new sender certificate. return firstly { - requestSenderCertificate() +// requestSenderCertificate() + generateSenderCertificate() }.map { (certificateData: Data, certificate: SMKSenderCertificate) in // Cache the current sender certificate. @@ -426,6 +427,19 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { return certificate } } + + private func generateSenderCertificate() -> Promise<(certificateData: Data, certificate: SMKSenderCertificate)> { + return Promise<(certificateData: Data, certificate: SMKSenderCertificate)> { seal in + //Loki: Generate a sender certifate locally + let sender = OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey + let certificate = SMKSenderCertificate(senderDeviceId: OWSDevicePrimaryDeviceId, senderRecipientId: sender!) + let certificateData = try certificate.serialized() + guard self.isValidCertificate(certificate) else { + throw OWSUDError.invalidData(description: "Invalid sender certificate returned by server") + } + seal.fulfill((certificateData: certificateData, certificate: certificate)) + } + } private func requestSenderCertificate() -> Promise<(certificateData: Data, certificate: SMKSenderCertificate)> { return firstly { From def2221de81d51e87369167e61fc5a698feb2192 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Fri, 31 Jan 2020 17:01:29 +1100 Subject: [PATCH 2/7] enable sealed sender --- Pods | 2 +- .../src/Loki/API/SignalMessage.swift | 4 ++- .../src/Messages/OWSMessageDecrypter.m | 17 ++++------- .../src/Messages/OWSMessageManager.m | 18 ++++++------ .../src/Messages/OWSMessageSender.m | 28 +++++++++++-------- .../src/Messages/OWSMessageServiceParams.h | 6 +++- .../src/Messages/OWSMessageServiceParams.m | 2 ++ 7 files changed, 44 insertions(+), 33 deletions(-) diff --git a/Pods b/Pods index 8a4786d92..aae090da2 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 8a4786d9254efa9cba361afc603b60f30157d0a6 +Subproject commit aae090da2d6be24031417c0475baeced446cbb34 diff --git a/SignalServiceKit/src/Loki/API/SignalMessage.swift b/SignalServiceKit/src/Loki/API/SignalMessage.swift index f345fc01f..d2799dc7d 100644 --- a/SignalServiceKit/src/Loki/API/SignalMessage.swift +++ b/SignalServiceKit/src/Loki/API/SignalMessage.swift @@ -10,11 +10,12 @@ public final class SignalMessage : NSObject { @objc(ttl) public let objc_ttl: UInt64 @objc public let isPing: Bool + @objc public let isFriendRequest: Bool public var ttl: UInt64? { return objc_ttl != 0 ? objc_ttl : nil } @objc public init(type: SSKProtoEnvelope.SSKProtoEnvelopeType, timestamp: UInt64, senderID: String, senderDeviceID: UInt32, - content: String, recipientID: String, ttl: UInt64, isPing: Bool) { + content: String, recipientID: String, ttl: UInt64, isPing: Bool, isFriendRequest: Bool) { self.type = type self.timestamp = timestamp self.senderID = senderID @@ -23,6 +24,7 @@ public final class SignalMessage : NSObject { self.recipientID = recipientID self.objc_ttl = ttl self.isPing = isPing + self.isFriendRequest = isFriendRequest super.init() } } diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m index 50e06348f..4d04d68b6 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m @@ -480,16 +480,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes return failureBlock(error); } - if (!envelope.hasServerTimestamp) { - NSString *errorDescription = @"UD Envelope is missing server timestamp."; - // TODO: We're seeing incoming UD envelopes without a server timestamp on staging. - // Until this is fixed, disabling this assert. - // OWSFailDebug(@"%@", errorDescription); - OWSLogError(@"%@", errorDescription); - NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription); - return failureBlock(error); - } - UInt64 serverTimestamp = envelope.serverTimestamp; + UInt64 serverTimestamp = envelope.timestamp; id certificateValidator = [[SMKCertificateDefaultValidator alloc] initWithTrustRoot:self.udManager.trustRoot]; @@ -599,7 +590,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes } NSString *source = decryptResult.senderRecipientId; - if (source.length < 1 || !source.isValidE164) { + if (source.length < 1) { NSString *errorDescription = @"Invalid UD sender."; OWSFailDebug(@"%@", errorDescription); NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription); @@ -618,6 +609,10 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes SSKProtoEnvelopeBuilder *envelopeBuilder = [envelope asBuilder]; [envelopeBuilder setSource:source]; [envelopeBuilder setSourceDevice:(uint32_t)sourceDeviceId]; + if (decryptResult.messageType == SMKMessageTypeLokiFriendRequest) { + [envelopeBuilder setType:SSKProtoEnvelopeTypeFriendRequest]; + OWSLogInfo(@"SMKMessageTypeLokiFriendRequest"); + } NSError *envelopeBuilderError; NSData *_Nullable newEnvelopeData = [envelopeBuilder buildSerializedDataAndReturnError:&envelopeBuilderError]; if (envelopeBuilderError || !newEnvelopeData) { diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 820441300..32b1d7d0b 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -263,13 +263,15 @@ NS_ASSUME_NONNULL_BEGIN OWSLogInfo(@"handling decrypted envelope: %@", [self descriptionForEnvelope:envelope]); - if (!envelope.hasSource || envelope.source.length < 1) { - OWSFailDebug(@"incoming envelope has invalid source"); - return; - } - if (!envelope.hasSourceDevice || envelope.sourceDevice < 1) { - OWSFailDebug(@"incoming envelope has invalid source device"); - return; + if (!wasReceivedByUD) { + if (!envelope.hasSource || envelope.source.length < 1) { + OWSFailDebug(@"incoming envelope has invalid source"); + return; + } + if (!envelope.hasSourceDevice || envelope.sourceDevice < 1) { + OWSFailDebug(@"incoming envelope has invalid source device"); + return; + } } OWSAssertDebug(![self isEnvelopeSenderBlocked:envelope]); @@ -453,7 +455,7 @@ NS_ASSUME_NONNULL_BEGIN TSContactThread *thread = [TSContactThread getThreadWithContactId:envelope.source transaction:transaction]; if (thread && thread.isContactFriend) { [self resetSessionWithContact:envelope.source transaction:transaction]; - // Let our other devices know that we have reset the session + // Let our o ther devices know that we have reset the session [SSKEnvironment.shared.syncManager syncContact:envelope.source transaction:transaction]; } } diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index d5f10b5ca..63d3f08d2 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -959,7 +959,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSString *contactID = messageSend.recipient.recipientId; BOOL isGroupMessage = messageSend.thread.isGroupThread; BOOL isDeviceLinkMessage = [message isKindOfClass:LKDeviceLinkMessage.class]; - if (isGroupMessage || isDeviceLinkMessage || messageSend.isUDSend) { + if (isGroupMessage || isDeviceLinkMessage) { [self sendMessage:messageSend]; } else { BOOL isSilentMessage = message.isSilent || [message isKindOfClass:LKEphemeralMessage.class] || [message isKindOfClass:OWSOutgoingSyncMessage.class]; @@ -1259,7 +1259,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [message saveGroupChatServerID:groupMessage.serverID in:transaction]; [OWSPrimaryStorage.sharedManager setIDForMessageWithServerID:groupMessage.serverID to:message.uniqueId in:transaction]; }]; - [self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:false wasSentByWebsocket:false]; + [self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:messageSend.isUDSend wasSentByWebsocket:false]; }) .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // The snode is unreachable failedMessageSend(error); @@ -1281,19 +1281,22 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSDictionary *signalMessageInfo = deviceMessages.firstObject; SSKProtoEnvelopeType type = ((NSNumber *)signalMessageInfo[@"type"]).integerValue; uint64_t timestamp = message.timestamp; +// NSString *senderID = type == SSKProtoEnvelopeTypeUnidentifiedSender ? @"" : userHexEncodedPublicKey; +// uint32_t senderDeviceID = type == SSKProtoEnvelopeTypeUnidentifiedSender ? 0 : OWSDevicePrimaryDeviceId; NSString *senderID = userHexEncodedPublicKey; uint32_t senderDeviceID = OWSDevicePrimaryDeviceId; NSString *content = signalMessageInfo[@"content"]; NSString *recipientID = signalMessageInfo[@"destination"]; uint64_t ttl = ((NSNumber *)signalMessageInfo[@"ttl"]).unsignedIntegerValue; BOOL isPing = ((NSNumber *)signalMessageInfo[@"isPing"]).boolValue; - LKSignalMessage *signalMessage = [[LKSignalMessage alloc] initWithType:type timestamp:timestamp senderID:senderID senderDeviceID:senderDeviceID content:content recipientID:recipientID ttl:ttl isPing:isPing]; + BOOL isFriendRequest = ((NSNumber *)signalMessageInfo[@"isFriendRequest"]).boolValue; + LKSignalMessage *signalMessage = [[LKSignalMessage alloc] initWithType:type timestamp:timestamp senderID:senderID senderDeviceID:senderDeviceID content:content recipientID:recipientID ttl:ttl isPing:isPing isFriendRequest:isFriendRequest]; if (!message.skipSave) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { // Update the PoW calculation status [message saveIsCalculatingProofOfWork:YES withTransaction:transaction]; // Update the message and thread if needed - if (signalMessage.type == TSFriendRequestMessageType) { + if (signalMessage.isFriendRequest) { [message.thread saveFriendRequestStatus:LKThreadFriendRequestStatusRequestSending withTransaction:transaction]; [message saveFriendRequestStatus:LKMessageFriendRequestStatusSendingOrFailed withTransaction:transaction]; } @@ -1305,7 +1308,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (!message.skipSave) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { // Update the message and thread if needed - if (signalMessage.type == TSFriendRequestMessageType) { + if (signalMessage.isFriendRequest) { [message.thread saveFriendRequestStatus:LKThreadFriendRequestStatusNone withTransaction:transaction]; [message saveFriendRequestStatus:LKMessageFriendRequestStatusSendingOrFailed withTransaction:transaction]; } @@ -1329,7 +1332,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (isSuccess) { return; } // Succeed as soon as the first promise succeeds [NSNotificationCenter.defaultCenter postNotificationName:NSNotification.messageSent object:[[NSNumber alloc] initWithUnsignedLongLong:signalMessage.timestamp]]; isSuccess = YES; - if (signalMessage.type == TSFriendRequestMessageType) { + if (signalMessage.isFriendRequest) { if (!message.skipSave) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { // Update the thread @@ -1347,7 +1350,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } } // Invoke the completion handler - [self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:false wasSentByWebsocket:false]; + [self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:messageSend.isUDSend wasSentByWebsocket:false]; }) .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { errorCount += 1; @@ -1919,7 +1922,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; isOnline:false registrationId:0 ttl:message.ttl - isPing:false]; + isPing:false + isFriendRequest:true]; NSError *error; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; @@ -1948,12 +1952,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // Loki: Both for friend request messages and device link messages we use fallback encryption as we don't necessarily have a session yet BOOL isFriendRequest = [messageSend.message isKindOfClass:LKFriendRequestMessage.class]; BOOL isDeviceLinkMessage = [messageSend.message isKindOfClass:LKDeviceLinkMessage.class]; - if (isFriendRequest || (isDeviceLinkMessage && ((LKDeviceLinkMessage *)messageSend.message).kind == LKDeviceLinkMessageKindRequest)) { + if ((isDeviceLinkMessage && ((LKDeviceLinkMessage *)messageSend.message).kind == LKDeviceLinkMessageKindRequest)) { return [self throws_encryptedFriendRequestOrDeviceLinkMessageForMessageSend:messageSend deviceId:@(OWSDevicePrimaryDeviceId) plainText:plainText]; } // This may throw an exception. - if (![storage containsSession:recipientID deviceId:@(OWSDevicePrimaryDeviceId).intValue protocolContext:transaction]) { + if (!isFriendRequest && ![storage containsSession:recipientID deviceId:@(OWSDevicePrimaryDeviceId).intValue protocolContext:transaction]) { NSString *missingSessionException = @"missingSessionException"; OWSRaiseException(missingSessionException, @"Unexpectedly missing session for recipient: %@, device: %@", @@ -1987,6 +1991,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; paddedPlaintext:[plainText paddedMessageBody] senderCertificate:messageSend.senderCertificate protocolContext:transaction + isFriendRequest:isFriendRequest error:&error]; SCKRaiseIfExceptionWrapperError(error); if (!serializedMessage || error) { @@ -2016,7 +2021,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; isOnline:isOnline registrationId:[cipher throws_remoteRegistrationId:transaction] ttl:message.ttl - isPing:isPing]; + isPing:isPing + isFriendRequest:isFriendRequest]; NSError *error; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; diff --git a/SignalServiceKit/src/Messages/OWSMessageServiceParams.h b/SignalServiceKit/src/Messages/OWSMessageServiceParams.h index 83f00ce3f..dc9e8f04b 100644 --- a/SignalServiceKit/src/Messages/OWSMessageServiceParams.h +++ b/SignalServiceKit/src/Messages/OWSMessageServiceParams.h @@ -30,6 +30,9 @@ NS_ASSUME_NONNULL_BEGIN // Loki: Wether this message is a p2p ping @property (nonatomic, readonly) BOOL isPing; +// Loki: Wether this message is a friend request +@property (nonatomic, readonly) BOOL isFriendRequest; + - (instancetype)initWithType:(TSWhisperMessageType)type recipientId:(NSString *)destination device:(int)deviceId @@ -38,7 +41,8 @@ NS_ASSUME_NONNULL_BEGIN isOnline:(BOOL)isOnline registrationId:(int)registrationId ttl:(uint)ttl - isPing:(BOOL)isPing; + isPing:(BOOL)isPing + isFriendRequest:(BOOL)isFriendRequest; @end diff --git a/SignalServiceKit/src/Messages/OWSMessageServiceParams.m b/SignalServiceKit/src/Messages/OWSMessageServiceParams.m index d7a0cbf12..6f19dd89d 100644 --- a/SignalServiceKit/src/Messages/OWSMessageServiceParams.m +++ b/SignalServiceKit/src/Messages/OWSMessageServiceParams.m @@ -24,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN registrationId:(int)registrationId ttl:(uint)ttl isPing:(BOOL)isPing + isFriendRequest:(BOOL)isFriendRequest { self = [super init]; @@ -40,6 +41,7 @@ NS_ASSUME_NONNULL_BEGIN _online = isOnline; _ttl = ttl; _isPing = isPing; + _isFriendRequest = isFriendRequest; return self; } From fe158de3626f33085e0904c9463017b961f8c039 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Mon, 3 Feb 2020 09:44:11 +1100 Subject: [PATCH 3/7] hide the source on the envelope --- SignalServiceKit/src/Messages/OWSMessageSender.m | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 63d3f08d2..b47198159 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1281,10 +1281,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSDictionary *signalMessageInfo = deviceMessages.firstObject; SSKProtoEnvelopeType type = ((NSNumber *)signalMessageInfo[@"type"]).integerValue; uint64_t timestamp = message.timestamp; -// NSString *senderID = type == SSKProtoEnvelopeTypeUnidentifiedSender ? @"" : userHexEncodedPublicKey; -// uint32_t senderDeviceID = type == SSKProtoEnvelopeTypeUnidentifiedSender ? 0 : OWSDevicePrimaryDeviceId; - NSString *senderID = userHexEncodedPublicKey; - uint32_t senderDeviceID = OWSDevicePrimaryDeviceId; + NSString *senderID = type == SSKProtoEnvelopeTypeUnidentifiedSender ? @"" : userHexEncodedPublicKey; + uint32_t senderDeviceID = type == SSKProtoEnvelopeTypeUnidentifiedSender ? 0 : OWSDevicePrimaryDeviceId; NSString *content = signalMessageInfo[@"content"]; NSString *recipientID = signalMessageInfo[@"destination"]; uint64_t ttl = ((NSNumber *)signalMessageInfo[@"ttl"]).unsignedIntegerValue; From 774478a6e251c397e37eac4bc72e2b7a15f3f2be Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Mon, 3 Feb 2020 11:14:22 +1100 Subject: [PATCH 4/7] enable device link message with sealed sender --- SignalServiceKit/src/Messages/OWSMessageSender.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index b47198159..cdffbf5fc 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1949,13 +1949,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // Loki: Both for friend request messages and device link messages we use fallback encryption as we don't necessarily have a session yet BOOL isFriendRequest = [messageSend.message isKindOfClass:LKFriendRequestMessage.class]; - BOOL isDeviceLinkMessage = [messageSend.message isKindOfClass:LKDeviceLinkMessage.class]; - if ((isDeviceLinkMessage && ((LKDeviceLinkMessage *)messageSend.message).kind == LKDeviceLinkMessageKindRequest)) { - return [self throws_encryptedFriendRequestOrDeviceLinkMessageForMessageSend:messageSend deviceId:@(OWSDevicePrimaryDeviceId) plainText:plainText]; - } + BOOL isDeviceLinkMessage = [messageSend.message isKindOfClass:LKDeviceLinkMessage.class] && ((LKDeviceLinkMessage *)messageSend.message).kind == LKDeviceLinkMessageKindRequest; +// if ((isDeviceLinkMessage && ((LKDeviceLinkMessage *)messageSend.message).kind == LKDeviceLinkMessageKindRequest)) { +// return [self throws_encryptedFriendRequestOrDeviceLinkMessageForMessageSend:messageSend deviceId:@(OWSDevicePrimaryDeviceId) plainText:plainText]; +// } // This may throw an exception. - if (!isFriendRequest && ![storage containsSession:recipientID deviceId:@(OWSDevicePrimaryDeviceId).intValue protocolContext:transaction]) { + if (!isFriendRequest && !isDeviceLinkMessage && ![storage containsSession:recipientID deviceId:@(OWSDevicePrimaryDeviceId).intValue protocolContext:transaction]) { NSString *missingSessionException = @"missingSessionException"; OWSRaiseException(missingSessionException, @"Unexpectedly missing session for recipient: %@, device: %@", @@ -1989,7 +1989,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; paddedPlaintext:[plainText paddedMessageBody] senderCertificate:messageSend.senderCertificate protocolContext:transaction - isFriendRequest:isFriendRequest + isFriendRequest:isFriendRequest || isDeviceLinkMessage error:&error]; SCKRaiseIfExceptionWrapperError(error); if (!serializedMessage || error) { @@ -2020,7 +2020,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; registrationId:[cipher throws_remoteRegistrationId:transaction] ttl:message.ttl isPing:isPing - isFriendRequest:isFriendRequest]; + isFriendRequest:isFriendRequest || isDeviceLinkMessage]; NSError *error; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; From 0ff7b780cc93fd772d10ebd19f9409e447967d1a Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Mon, 3 Feb 2020 14:19:21 +1100 Subject: [PATCH 5/7] debug: when we clear all data, the sender certificate is not deleted, so just generate a new one each time we send a UD message --- SignalServiceKit/src/Messages/UD/OWSUDManager.swift | 8 -------- 1 file changed, 8 deletions(-) diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 05caa3df0..277fc6681 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -408,16 +408,8 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { } public func ensureSenderCertificate(certificateExpirationPolicy: OWSUDCertificateExpirationPolicy) -> Promise { - // If there is a valid cached sender certificate, use that. - // - // NOTE: We use a "strict" expiration policy. - if let certificate = senderCertificate(certificateExpirationPolicy: certificateExpirationPolicy) { - return Promise.value(certificate) - } - // Try to obtain a new sender certificate. return firstly { -// requestSenderCertificate() generateSenderCertificate() }.map { (certificateData: Data, certificate: SMKSenderCertificate) in From d497d6a1db9d561ef53bd4e9034de98ed4e11e80 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Mon, 3 Feb 2020 15:46:58 +1100 Subject: [PATCH 6/7] enable session restore and sync messages with sealed sender --- .../src/Messages/OWSMessageSender.m | 24 +++++++++++++++---- .../src/Messages/UD/OWSUDManager.swift | 18 ++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index cdffbf5fc..609b79b33 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -932,7 +932,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; message.skipSave = YES; SignalRecipient *recipient = [[SignalRecipient alloc] initWithUniqueId:hexEncodedPublicKey]; NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey; - return [[OWSMessageSend alloc] initWithMessage:message thread:thread recipient:recipient senderCertificate:nil udAccess:nil localNumber:userHexEncodedPublicKey success:^{ } failure:^(NSError *error) { }]; + SMKSenderCertificate *senderCertificate = [self.udManager getSenderCertificate]; + OWSUDAccess *theirUDAccess = nil; + if (senderCertificate != nil) { + theirUDAccess = [self.udManager udAccessForRecipientId:recipient.recipientId requireSyncAccess:YES]; + } + return [[OWSMessageSend alloc] initWithMessage:message thread:thread recipient:recipient senderCertificate:senderCertificate udAccess:theirUDAccess localNumber:userHexEncodedPublicKey success:^{ } failure:^(NSError *error) { }]; } - (OWSMessageSend *)getMultiDeviceFriendRequestMessageForHexEncodedPublicKey:(NSString *)hexEncodedPublicKey @@ -950,7 +955,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; message.skipSave = YES; SignalRecipient *recipient = [[SignalRecipient alloc] initWithUniqueId:hexEncodedPublicKey]; NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey; - return [[OWSMessageSend alloc] initWithMessage:message thread:thread recipient:recipient senderCertificate:nil udAccess:nil localNumber:userHexEncodedPublicKey success:^{ } failure:^(NSError *error) { }]; + SMKSenderCertificate *senderCertificate = [self.udManager getSenderCertificate]; + OWSUDAccess *theirUDAccess = nil; + if (senderCertificate != nil) { + theirUDAccess = [self.udManager udAccessForRecipientId:recipient.recipientId requireSyncAccess:YES]; + } + return [[OWSMessageSend alloc] initWithMessage:message thread:thread recipient:recipient senderCertificate:senderCertificate udAccess:theirUDAccess localNumber:userHexEncodedPublicKey success:^{ } failure:^(NSError *error) { }]; } - (void)sendMessageToDestinationAndLinkedDevices:(OWSMessageSend *)messageSend @@ -1651,12 +1661,18 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { recipient = [SignalRecipient markRecipientAsRegisteredAndGet:recipientId transaction:transaction]; }]; + + SMKSenderCertificate *senderCertificate = [self.udManager getSenderCertificate]; + OWSUDAccess *theirUDAccess = nil; + if (senderCertificate != nil) { + theirUDAccess = [self.udManager udAccessForRecipientId:recipient.recipientId requireSyncAccess:YES]; + } OWSMessageSend *messageSend = [[OWSMessageSend alloc] initWithMessage:sentMessageTranscript thread:message.thread recipient:recipient - senderCertificate:nil - udAccess:nil + senderCertificate:senderCertificate + udAccess:theirUDAccess localNumber:self.tsAccountManager.localNumber success:^{ OWSLogInfo(@"Successfully sent sync transcript."); diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 277fc6681..cdb3b5d99 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -100,6 +100,9 @@ public class OWSUDAccess: NSObject { func shouldAllowUnrestrictedAccessLocal() -> Bool @objc func setShouldAllowUnrestrictedAccessLocal(_ value: Bool) + + @objc + func getSenderCertificate() -> SMKSenderCertificate? } // MARK: - @@ -432,6 +435,21 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { seal.fulfill((certificateData: certificateData, certificate: certificate)) } } + + @objc + public func getSenderCertificate() -> SMKSenderCertificate? { + do { + let sender = OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey + let certificate = SMKSenderCertificate(senderDeviceId: OWSDevicePrimaryDeviceId, senderRecipientId: sender!) + guard self.isValidCertificate(certificate) else { + throw OWSUDError.invalidData(description: "Invalid sender certificate returned by server") + } + return certificate + } catch { + Logger.error("\(error)") + return nil + } + } private func requestSenderCertificate() -> Promise<(certificateData: Data, certificate: SMKSenderCertificate)> { return firstly { From f4e376bfb47d670f29ab970912d4004f694c1d69 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Tue, 4 Feb 2020 09:57:35 +1100 Subject: [PATCH 7/7] update pods --- Pods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pods b/Pods index aae090da2..80e273886 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit aae090da2d6be24031417c0475baeced446cbb34 +Subproject commit 80e2738867fb856fd52141306c1b02d503365379