Swift Exception wrap NSData+keyVersionByte

pull/1/head
Michael Kirk 7 years ago
parent 5f5ec9b82a
commit 3a6aafc454

@ -1,12 +1,14 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved. //
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface OWSDeviceProvisioningURLParser : NSObject @interface OWSDeviceProvisioningURLParser : NSObject
@property (readonly, getter=isValid) BOOL valid; @property (readonly, getter=isValid) BOOL valid;
@property (nonatomic, readonly) NSString *ephemeralDeviceId; @property (nonatomic, readonly, nullable) NSString *ephemeralDeviceId;
@property (nonatomic, readonly) NSData *publicKey; @property (nonatomic, readonly, nullable) NSData *publicKey;
- (instancetype)initWithProvisioningURL:(NSString *)provisioningURL; - (instancetype)initWithProvisioningURL:(NSString *)provisioningURL;

@ -26,7 +26,11 @@ NSString *const OWSQueryItemNameEncodedPublicKeyKey = @"pub_key";
_ephemeralDeviceId = queryItem.value; _ephemeralDeviceId = queryItem.value;
} else if ([queryItem.name isEqualToString:OWSQueryItemNameEncodedPublicKeyKey]) { } else if ([queryItem.name isEqualToString:OWSQueryItemNameEncodedPublicKeyKey]) {
NSString *encodedPublicKey = queryItem.value; NSString *encodedPublicKey = queryItem.value;
_publicKey = [[NSData dataFromBase64String:encodedPublicKey] removeKeyType]; @try {
_publicKey = [[NSData dataFromBase64String:encodedPublicKey] try_removeKeyType];
} @catch (NSException *exception) {
OWSFailDebug(@"exception: %@", exception);
}
} else { } else {
OWSLogWarn(@"Unkown query item in provisioning string: %@", queryItem.name); OWSLogWarn(@"Unkown query item in provisioning string: %@", queryItem.name);
} }

@ -1901,7 +1901,9 @@ typedef enum : NSUInteger {
// but there will be some legacy ones in the wild, behind which await // but there will be some legacy ones in the wild, behind which await
// as-of-yet-undecrypted messages // as-of-yet-undecrypted messages
if ([errorMessage isKindOfClass:[TSInvalidIdentityKeyReceivingErrorMessage class]]) { if ([errorMessage isKindOfClass:[TSInvalidIdentityKeyReceivingErrorMessage class]]) {
[errorMessage acceptNewIdentityKey]; // Deliberately crash if the user fails to explicitly accept the new identity
// key. In practice we haven't been creating these messags in over a year.
[errorMessage try_acceptNewIdentityKey];
} }
}]; }];
[actionSheetController addAction:acceptSafetyNumberAction]; [actionSheetController addAction:acceptSafetyNumberAction];

@ -631,13 +631,17 @@ NS_ASSUME_NONNULL_BEGIN
continue; continue;
} }
NSData *_Nullable newIdentityKey = safetyNumberChange.newIdentityKey; @try {
NSData *_Nullable newIdentityKey = [safetyNumberChange try_newIdentityKey];
if (newIdentityKey == nil) { if (newIdentityKey == nil) {
OWSFailDebug(@"Safety number change was missing it's new identity key."); OWSFailDebug(@"Safety number change was missing it's new identity key.");
continue; continue;
} }
[missingUnseenSafetyNumberChanges addObject:newIdentityKey]; [missingUnseenSafetyNumberChanges addObject:newIdentityKey];
} @catch (NSException *exception) {
OWSFailDebug(@"exception: %@", exception);
}
} }
// Count the de-duplicated "blocking" safety number changes and all // Count the de-duplicated "blocking" safety number changes and all

@ -248,9 +248,13 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa
[self enumerateInteractionsUsingBlock:^(TSInteraction *interaction) { [self enumerateInteractionsUsingBlock:^(TSInteraction *interaction) {
if ([interaction isKindOfClass:[TSInvalidIdentityKeyReceivingErrorMessage class]]) { if ([interaction isKindOfClass:[TSInvalidIdentityKeyReceivingErrorMessage class]]) {
TSInvalidIdentityKeyReceivingErrorMessage *error = (TSInvalidIdentityKeyReceivingErrorMessage *)interaction; TSInvalidIdentityKeyReceivingErrorMessage *error = (TSInvalidIdentityKeyReceivingErrorMessage *)interaction;
if ([[error newIdentityKey] isEqualToData:key]) { @try {
if ([[error try_newIdentityKey] isEqualToData:key]) {
[errorMessages addObject:(TSInvalidIdentityKeyReceivingErrorMessage *)interaction]; [errorMessages addObject:(TSInvalidIdentityKeyReceivingErrorMessage *)interaction];
} }
} @catch (NSException *exception) {
OWSFailDebug(@"exception: %@", exception);
}
} }
}]; }];

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSErrorMessage.h" #import "TSErrorMessage.h"
@ -10,8 +10,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage @interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
- (void)acceptNewIdentityKey; - (void)try_acceptNewIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (nullable NSData *)newIdentityKey; - (nullable NSData *)try_newIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (NSString *)theirSignalId; - (NSString *)theirSignalId;
@end @end

@ -8,12 +8,12 @@ NS_ASSUME_NONNULL_BEGIN
@implementation TSInvalidIdentityKeyErrorMessage @implementation TSInvalidIdentityKeyErrorMessage
- (void)acceptNewIdentityKey - (void)try_acceptNewIdentityKey
{ {
OWSAbstractMethod(); OWSAbstractMethod();
} }
- (nullable NSData *)newIdentityKey - (nullable NSData *)try_newIdentityKey
{ {
OWSAbstractMethod(); OWSAbstractMethod();
return nil; return nil;

@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN
return _envelope; return _envelope;
} }
- (void)acceptNewIdentityKey - (void)try_acceptNewIdentityKey
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
@ -90,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
return; return;
} }
NSData *_Nullable newKey = [self newIdentityKey]; NSData *_Nullable newKey = [self try_newIdentityKey];
if (!newKey) { if (!newKey) {
OWSFailDebug(@"Couldn't extract identity key to accept"); OWSFailDebug(@"Couldn't extract identity key to accept");
return; return;
@ -131,7 +131,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] init_try_withData:pkwmData]; PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] init_try_withData:pkwmData];
return [message.identityKey removeKeyType]; return [message.identityKey try_removeKeyType];
} }
- (NSString *)theirSignalId - (NSString *)theirSignalId

@ -45,13 +45,13 @@ NSString *TSInvalidRecipientKey = @"TSInvalidRecipientKey";
return self; return self;
} }
- (void)acceptNewIdentityKey - (void)try_acceptNewIdentityKey
{ {
// Shouldn't really get here, since we're no longer creating blocking SN changes. // Shouldn't really get here, since we're no longer creating blocking SN changes.
// But there may still be some old unaccepted SN errors in the wild that need to be accepted. // But there may still be some old unaccepted SN errors in the wild that need to be accepted.
OWSFailDebug(@"accepting new identity key is deprecated."); OWSFailDebug(@"accepting new identity key is deprecated.");
NSData *_Nullable newIdentityKey = self.newIdentityKey; NSData *_Nullable newIdentityKey = [self try_newIdentityKey];
if (!newIdentityKey) { if (!newIdentityKey) {
OWSFailDebug(@"newIdentityKey is unexpectedly nil. Bad Prekey bundle?: %@", self.preKeyBundle); OWSFailDebug(@"newIdentityKey is unexpectedly nil. Bad Prekey bundle?: %@", self.preKeyBundle);
return; return;
@ -60,9 +60,9 @@ NSString *TSInvalidRecipientKey = @"TSInvalidRecipientKey";
[[OWSIdentityManager sharedManager] saveRemoteIdentity:newIdentityKey recipientId:self.recipientId]; [[OWSIdentityManager sharedManager] saveRemoteIdentity:newIdentityKey recipientId:self.recipientId];
} }
- (nullable NSData *)newIdentityKey - (nullable NSData *)try_newIdentityKey
{ {
return [self.preKeyBundle.identityKey removeKeyType]; return [self.preKeyBundle.identityKey try_removeKeyType];
} }
- (NSString *)theirSignalId - (NSString *)theirSignalId

@ -403,7 +403,7 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
if (!envelope) { if (!envelope) {
reportFailure(transaction); reportFailure(transaction);
} else { } else {
[self.messageManager processEnvelope:envelope [self.messageManager try_processEnvelope:envelope
plaintextData:job.plaintextData plaintextData:job.plaintextData
transaction:transaction]; transaction:transaction];
} }

@ -60,7 +60,7 @@ extern const NSUInteger kStoredIdentityKeyLength;
- (nullable OWSRecipientIdentity *)untrustedIdentityForSendingToRecipientId:(NSString *)recipientId; - (nullable OWSRecipientIdentity *)untrustedIdentityForSendingToRecipientId:(NSString *)recipientId;
// This method can be called from any thread. // This method can be called from any thread.
- (void)processIncomingSyncMessage:(SSKProtoVerified *)verified - (void)try_processIncomingSyncMessage:(SSKProtoVerified *)verified
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (BOOL)saveRemoteIdentity:(NSData *)identityKey recipientId:(NSString *)recipientId; - (BOOL)saveRemoteIdentity:(NSData *)identityKey recipientId:(NSString *)recipientId;

@ -678,7 +678,7 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
[transaction removeObjectForKey:recipientId inCollection:OWSIdentityManager_QueuedVerificationStateSyncMessages]; [transaction removeObjectForKey:recipientId inCollection:OWSIdentityManager_QueuedVerificationStateSyncMessages];
} }
- (void)processIncomingSyncMessage:(SSKProtoVerified *)verified - (void)try_processIncomingSyncMessage:(SSKProtoVerified *)verified
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(verified); OWSAssertDebug(verified);
@ -696,7 +696,7 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
rawIdentityKey); rawIdentityKey);
return; return;
} }
NSData *identityKey = [rawIdentityKey removeKeyType]; NSData *identityKey = [rawIdentityKey try_removeKeyType];
switch (verified.state) { switch (verified.state) {
case SSKProtoVerifiedStateDefault: case SSKProtoVerifiedStateDefault:

@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage NS_DESIGNATED_INITIALIZER; - (instancetype)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage NS_DESIGNATED_INITIALIZER;
// processEnvelope: can be called from any thread. // processEnvelope: can be called from any thread.
- (void)processEnvelope:(SSKProtoEnvelope *)envelope - (void)try_processEnvelope:(SSKProtoEnvelope *)envelope
plaintextData:(NSData *_Nullable)plaintextData plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;

@ -212,7 +212,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - message handling #pragma mark - message handling
- (void)processEnvelope:(SSKProtoEnvelope *)envelope - (void)try_processEnvelope:(SSKProtoEnvelope *)envelope
plaintextData:(NSData *_Nullable)plaintextData plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
@ -256,7 +256,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSFailDebug(@"missing decrypted data for envelope: %@", [self descriptionForEnvelope:envelope]); OWSFailDebug(@"missing decrypted data for envelope: %@", [self descriptionForEnvelope:envelope]);
return; return;
} }
[self handleEnvelope:envelope plaintextData:plaintextData transaction:transaction]; [self try_handleEnvelope:envelope plaintextData:plaintextData transaction:transaction];
break; break;
case SSKProtoEnvelopeTypeReceipt: case SSKProtoEnvelopeTypeReceipt:
OWSAssertDebug(!plaintextData); OWSAssertDebug(!plaintextData);
@ -345,7 +345,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
- (void)handleEnvelope:(SSKProtoEnvelope *)envelope - (void)try_handleEnvelope:(SSKProtoEnvelope *)envelope
plaintextData:(NSData *)plaintextData plaintextData:(NSData *)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
@ -395,7 +395,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSLogInfo(@"handling content: <Content: %@>", [self descriptionForContent:contentProto]); OWSLogInfo(@"handling content: <Content: %@>", [self descriptionForContent:contentProto]);
if (contentProto.syncMessage) { if (contentProto.syncMessage) {
[self handleIncomingEnvelope:envelope withSyncMessage:contentProto.syncMessage transaction:transaction]; [self try_handleIncomingEnvelope:envelope withSyncMessage:contentProto.syncMessage transaction:transaction];
[[OWSDeviceManager sharedManager] setHasReceivedSyncMessage]; [[OWSDeviceManager sharedManager] setHasReceivedSyncMessage];
} else if (contentProto.dataMessage) { } else if (contentProto.dataMessage) {
@ -745,7 +745,7 @@ NS_ASSUME_NONNULL_BEGIN
}]; }];
} }
- (void)handleIncomingEnvelope:(SSKProtoEnvelope *)envelope - (void)try_handleIncomingEnvelope:(SSKProtoEnvelope *)envelope
withSyncMessage:(SSKProtoSyncMessage *)syncMessage withSyncMessage:(SSKProtoSyncMessage *)syncMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
@ -862,7 +862,7 @@ NS_ASSUME_NONNULL_BEGIN
transaction:transaction]; transaction:transaction];
} else if (syncMessage.verified) { } else if (syncMessage.verified) {
OWSLogInfo(@"Received verification state for %@", syncMessage.verified.destination); OWSLogInfo(@"Received verification state for %@", syncMessage.verified.destination);
[self.identityManager processIncomingSyncMessage:syncMessage.verified transaction:transaction]; [self.identityManager try_processIncomingSyncMessage:syncMessage.verified transaction:transaction];
} else { } else {
OWSLogWarn(@"Ignoring unsupported sync message."); OWSLogWarn(@"Ignoring unsupported sync message.");
} }

@ -888,7 +888,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return nil; return nil;
} }
NSData *newIdentityKey = [newIdentityKeyWithVersion removeKeyType]; NSData *newIdentityKey = [newIdentityKeyWithVersion try_removeKeyType];
[self.identityManager saveRemoteIdentity:newIdentityKey recipientId:recipient.recipientId]; [self.identityManager saveRemoteIdentity:newIdentityKey recipientId:recipient.recipientId];
return nil; return nil;

@ -32,8 +32,15 @@ public class SignalServiceProfile: NSObject {
guard identityKeyWithType.count == kIdentityKeyLength else { guard identityKeyWithType.count == kIdentityKeyLength else {
throw ValidationError.invalidIdentityKey(description: "malformed identity key \(identityKeyWithType.hexadecimalString) with decoded length: \(identityKeyWithType.count)") throw ValidationError.invalidIdentityKey(description: "malformed identity key \(identityKeyWithType.hexadecimalString) with decoded length: \(identityKeyWithType.count)")
} }
do {
// `removeKeyType` is an objc category method only on NSData, so temporarily cast. // `removeKeyType` is an objc category method only on NSData, so temporarily cast.
self.identityKey = (identityKeyWithType as NSData).removeKeyType() as Data self.identityKey = try (identityKeyWithType as NSData).removeKeyType() as Data
} catch {
// `removeKeyType` throws an SCKExceptionWrapperError, which, typically should
// be unwrapped by any objc code calling this method.
owsFailDebug("identify key had unexpected format")
throw ValidationError.invalidIdentityKey(description: "malformed identity key \(identityKeyWithType.hexadecimalString) with data: \(identityKeyWithType)")
}
self.profileNameEncrypted = try params.optionalBase64EncodedData(key: "name") self.profileNameEncrypted = try params.optionalBase64EncodedData(key: "name")

Loading…
Cancel
Save