Merge branch 'mkirk/wrap-exceptions' into release/2.31.0

pull/1/head
Michael Kirk 7 years ago
commit e94e4d0a90

@ -246,22 +246,22 @@ EXTERNAL SOURCES:
CHECKOUT OPTIONS: CHECKOUT OPTIONS:
AxolotlKit: AxolotlKit:
:commit: f43a65b456c43d1f5cad621ef108b4e18a70c17f :commit: 66b38e23b4e980cbddc94980f5bd0d1211d9184a
:git: https://github.com/signalapp/SignalProtocolKit.git :git: https://github.com/signalapp/SignalProtocolKit.git
Curve25519Kit: Curve25519Kit:
:commit: 14effe344be35f5d9f5597a2fd56824f78a4067d :commit: 9e5663baf4c2c7cb68ac4c0beb0423383c19a7fe
:git: https://github.com/signalapp/Curve25519Kit :git: https://github.com/signalapp/Curve25519Kit
GRKOpenSSLFramework: GRKOpenSSLFramework:
:commit: b799c27e7927e5304ec1e4ad53c6d33c6fd1cae7 :commit: b799c27e7927e5304ec1e4ad53c6d33c6fd1cae7
:git: https://github.com/signalapp/GRKOpenSSLFramework :git: https://github.com/signalapp/GRKOpenSSLFramework
HKDFKit: HKDFKit:
:commit: 8b8326cd50bc488663a3d3743f1a92b90f4d85b4 :commit: 3e0c2371d125f2d3db26daa498d5d436961b1795
:git: https://github.com/signalapp/HKDFKit.git :git: https://github.com/signalapp/HKDFKit.git
SignalCoreKit: SignalCoreKit:
:commit: ff0b95770520133b83a4bd7b26bc2c90b51abc4d :commit: b60dc7d58dfc93ca6eafbb3ea5300c6d67ebc69a
:git: https://github.com/signalapp/SignalCoreKit.git :git: https://github.com/signalapp/SignalCoreKit.git
SignalMetadataKit: SignalMetadataKit:
:commit: 90f3dee7122ff13061770c496001135ba90b71e3 :commit: d6b0186cc5b15019e85c375bce3bf78e7a7fc162
:git: https://github.com/signalapp/SignalMetadataKit :git: https://github.com/signalapp/SignalMetadataKit
SocketRocket: SocketRocket:
:commit: 9f9563a83cd8960503074aa8de72206f83fb7a69 :commit: 9f9563a83cd8960503074aa8de72206f83fb7a69
@ -277,7 +277,7 @@ SPEC CHECKSUMS:
AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057 AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057
AxolotlKit: bb02741a93400b915df1be3365ad13d3768b0103 AxolotlKit: bb02741a93400b915df1be3365ad13d3768b0103
CocoaLumberjack: db7cc9e464771f12054c22ff6947c5a58d43a0fd CocoaLumberjack: db7cc9e464771f12054c22ff6947c5a58d43a0fd
Curve25519Kit: 2b2e55cfa2a72f1152d2733a3058d94cc87f37c3 Curve25519Kit: b3e77b7152ebe95fee2b3fb6c955449492bc14f7
GRKOpenSSLFramework: 8a3735ad41e7dc1daff460467bccd32ca5d6ae3e GRKOpenSSLFramework: 8a3735ad41e7dc1daff460467bccd32ca5d6ae3e
HKDFKit: 3b6dbbb9d59c221cc6c52c3aa915700cbf24e376 HKDFKit: 3b6dbbb9d59c221cc6c52c3aa915700cbf24e376
libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa

@ -1 +1 @@
Subproject commit 3b101143e57b34fbef613c365c9ee2e29bd25d16 Subproject commit 5821eb8e9fd9f76fbdbedd3402892c185e65c48e

@ -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] throws_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 messages in over a year.
[errorMessage throws_acceptNewIdentityKey];
} }
}]; }];
[actionSheetController addAction:acceptSafetyNumberAction]; [actionSheetController addAction:acceptSafetyNumberAction];

@ -40,7 +40,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSString *)migrationId + (NSString *)migrationId
{ {
OWSRaiseException(NSInternalInconsistencyException, @"Must override %@ in subclass", NSStringFromSelector(_cmd)); OWSAbstractMethod();
return @"";
} }
+ (NSString *)collection + (NSString *)collection
@ -51,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSRaiseException(NSInternalInconsistencyException, @"Must override %@ in subclass", NSStringFromSelector(_cmd)); OWSAbstractMethod();
} }
- (void)runUpWithCompletion:(OWSDatabaseMigrationCompletion)completion - (void)runUpWithCompletion:(OWSDatabaseMigrationCompletion)completion

@ -631,13 +631,17 @@ NS_ASSUME_NONNULL_BEGIN
continue; continue;
} }
NSData *_Nullable newIdentityKey = safetyNumberChange.newIdentityKey; @try {
if (newIdentityKey == nil) { NSData *_Nullable newIdentityKey = [safetyNumberChange throws_newIdentityKey];
OWSFailDebug(@"Safety number change was missing it's new identity key."); if (newIdentityKey == nil) {
continue; OWSFailDebug(@"Safety number change was missing it's new identity key.");
} 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

@ -159,7 +159,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa
NSString *phoneNumber = self.phoneNumberAwaitingVerification; NSString *phoneNumber = self.phoneNumberAwaitingVerification;
if (!phoneNumber) { if (!phoneNumber) {
OWSRaiseException(@"RegistrationFail", @"Internal Corrupted State"); OWSFail(@"phoneNumber was unexpectedly nil");
} }
[self storeLocalNumber:phoneNumber]; [self storeLocalNumber:phoneNumber];

@ -213,8 +213,7 @@ NS_ASSUME_NONNULL_BEGIN
// We need to use an Intel certificate as the anchor for IAS verification. // We need to use an Intel certificate as the anchor for IAS verification.
NSData *_Nullable anchorCertificate = [self certificateDataForService:@"ias-root"]; NSData *_Nullable anchorCertificate = [self certificateDataForService:@"ias-root"];
if (!anchorCertificate) { if (!anchorCertificate) {
OWSFailDebug(@"could not load anchor certificate."); OWSFail(@"could not load anchor certificate.");
OWSRaiseException(@"OWSSignalService_CouldNotLoadCertificate", @"%s", __PRETTY_FUNCTION__);
} else { } else {
anchorCertificates = @[ anchorCertificate ]; anchorCertificates = @[ anchorCertificate ];
} }

@ -83,9 +83,9 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont
NSData *ephemeralToStatic; NSData *ephemeralToStatic;
@try { @try {
ephemeralToEphemeral = ephemeralToEphemeral =
[Curve25519 generateSharedSecretFromPublicKey:self.serverEphemeralPublic andKeyPair:self.keyPair]; [Curve25519 throws_generateSharedSecretFromPublicKey:self.serverEphemeralPublic andKeyPair:self.keyPair];
ephemeralToStatic = ephemeralToStatic =
[Curve25519 generateSharedSecretFromPublicKey:self.serverStaticPublic andKeyPair:self.keyPair]; [Curve25519 throws_generateSharedSecretFromPublicKey:self.serverStaticPublic andKeyPair:self.keyPair];
} @catch (NSException *exception) { } @catch (NSException *exception) {
OWSFailDebug(@"could not generate shared secrets: %@", exception); OWSFailDebug(@"could not generate shared secrets: %@", exception);
return NO; return NO;
@ -101,7 +101,7 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont
NSData *_Nullable derivedMaterial; NSData *_Nullable derivedMaterial;
@try { @try {
derivedMaterial = derivedMaterial =
[HKDFKit deriveKey:masterSecret info:nil salt:publicKeys outputSize:(int)kAES256_KeyByteLength * 2]; [HKDFKit throws_deriveKey:masterSecret info:nil salt:publicKeys outputSize:(int)kAES256_KeyByteLength * 2];
} @catch (NSException *exception) { } @catch (NSException *exception) {
OWSFailDebug(@"could not derive service key: %@", exception); OWSFailDebug(@"could not derive service key: %@", exception);
return NO; return NO;

@ -248,8 +248,12 @@ 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 {
[errorMessages addObject:(TSInvalidIdentityKeyReceivingErrorMessage *)interaction]; if ([[error throws_newIdentityKey] isEqualToData:key]) {
[errorMessages addObject:(TSInvalidIdentityKeyReceivingErrorMessage *)interaction];
}
} @catch (NSException *exception) {
OWSFailDebug(@"exception: %@", exception);
} }
} }
}]; }];

@ -54,11 +54,7 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable NSData *)encrypt:(NSData *)dataToEncrypt - (nullable NSData *)encrypt:(NSData *)dataToEncrypt
{ {
@try { @try {
// Exceptions can be thrown in a number of places in encryptUnsafe, e.g.: return [self throws_encryptWithData:dataToEncrypt];
//
// * Curve25519's generateSharedSecretFromPublicKey.
// * [HKDFKit deriveKey].
return [self encryptUnsafe:dataToEncrypt];
} @catch (NSException *exception) { } @catch (NSException *exception) {
OWSFailDebug(@"exception: %@ of type: %@ with reason: %@, user info: %@.", OWSFailDebug(@"exception: %@ of type: %@ with reason: %@, user info: %@.",
exception.description, exception.description,
@ -69,14 +65,14 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
- (nullable NSData *)encryptUnsafe:(NSData *)dataToEncrypt - (nullable NSData *)throws_encryptWithData:(NSData *)dataToEncrypt
{ {
NSData *sharedSecret = NSData *sharedSecret =
[Curve25519 generateSharedSecretFromPublicKey:self.theirPublicKey andKeyPair:self.ourKeyPair]; [Curve25519 throws_generateSharedSecretFromPublicKey:self.theirPublicKey andKeyPair:self.ourKeyPair];
NSData *infoData = [@"TextSecure Provisioning Message" dataUsingEncoding:NSASCIIStringEncoding]; NSData *infoData = [@"TextSecure Provisioning Message" dataUsingEncoding:NSASCIIStringEncoding];
NSData *nullSalt = [[NSMutableData dataWithLength:32] copy]; NSData *nullSalt = [[NSMutableData dataWithLength:32] copy];
NSData *derivedSecret = [HKDFKit deriveKey:sharedSecret info:infoData salt:nullSalt outputSize:64]; NSData *derivedSecret = [HKDFKit throws_deriveKey:sharedSecret info:infoData salt:nullSalt outputSize:64];
NSData *cipherKey = [derivedSecret subdataWithRange:NSMakeRange(0, 32)]; NSData *cipherKey = [derivedSecret subdataWithRange:NSMakeRange(0, 32)];
NSData *macKey = [derivedSecret subdataWithRange:NSMakeRange(32, 32)]; NSData *macKey = [derivedSecret subdataWithRange:NSMakeRange(32, 32)];
if (cipherKey.length != 32) { if (cipherKey.length != 32) {

@ -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)throws_acceptNewIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (nullable NSData *)newIdentityKey; - (nullable NSData *)throws_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)throws_acceptNewIdentityKey
{ {
OWSAbstractMethod(); OWSAbstractMethod();
} }
- (nullable NSData *)newIdentityKey - (nullable NSData *)throws_newIdentityKey
{ {
OWSAbstractMethod(); OWSAbstractMethod();
return nil; return nil;

@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN
return _envelope; return _envelope;
} }
- (void)acceptNewIdentityKey - (void)throws_acceptNewIdentityKey
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
@ -90,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
return; return;
} }
NSData *_Nullable newKey = [self newIdentityKey]; NSData *_Nullable newKey = [self throws_newIdentityKey];
if (!newKey) { if (!newKey) {
OWSFailDebug(@"Couldn't extract identity key to accept"); OWSFailDebug(@"Couldn't extract identity key to accept");
return; return;
@ -112,7 +112,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
- (nullable NSData *)newIdentityKey - (nullable NSData *)throws_newIdentityKey
{ {
if (!self.envelope) { if (!self.envelope) {
OWSLogError(@"Error message had no envelope data to extract key from"); OWSLogError(@"Error message had no envelope data to extract key from");
@ -130,8 +130,8 @@ NS_ASSUME_NONNULL_BEGIN
return nil; return nil;
} }
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:pkwmData]; PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] init_throws_withData:pkwmData];
return [message.identityKey removeKeyType]; return [message.identityKey throws_removeKeyType];
} }
- (NSString *)theirSignalId - (NSString *)theirSignalId

@ -45,13 +45,13 @@ NSString *TSInvalidRecipientKey = @"TSInvalidRecipientKey";
return self; return self;
} }
- (void)acceptNewIdentityKey - (void)throws_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 throws_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 *)throws_newIdentityKey
{ {
return [self.preKeyBundle.identityKey removeKeyType]; return [self.preKeyBundle.identityKey throws_removeKeyType];
} }
- (NSString *)theirSignalId - (NSString *)theirSignalId

@ -403,9 +403,9 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
if (!envelope) { if (!envelope) {
reportFailure(transaction); reportFailure(transaction);
} else { } else {
[self.messageManager processEnvelope:envelope [self.messageManager throws_processEnvelope:envelope
plaintextData:job.plaintextData plaintextData:job.plaintextData
transaction:transaction]; transaction:transaction];
} }
} @catch (NSException *exception) { } @catch (NSException *exception) {
OWSFailDebug(@"Received an invalid envelope: %@", exception.debugDescription); OWSFailDebug(@"Received an invalid envelope: %@", exception.debugDescription);

@ -60,8 +60,8 @@ 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)throws_processIncomingSyncMessage:(SSKProtoVerified *)verified
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (BOOL)saveRemoteIdentity:(NSData *)identityKey recipientId:(NSString *)recipientId; - (BOOL)saveRemoteIdentity:(NSData *)identityKey recipientId:(NSString *)recipientId;

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

@ -26,6 +26,7 @@
#import <AxolotlKit/SessionCipher.h> #import <AxolotlKit/SessionCipher.h>
#import <SignalCoreKit/NSData+OWS.h> #import <SignalCoreKit/NSData+OWS.h>
#import <SignalCoreKit/Randomness.h> #import <SignalCoreKit/Randomness.h>
#import <SignalCoreKit/SCKExceptionWrapper.h>
#import <SignalMetadataKit/SignalMetadataKit-Swift.h> #import <SignalMetadataKit/SignalMetadataKit-Swift.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h> #import <SignalServiceKit/SignalServiceKit-Swift.h>
@ -211,7 +212,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
switch (envelope.type) { switch (envelope.type) {
case SSKProtoEnvelopeTypeCiphertext: { case SSKProtoEnvelopeTypeCiphertext: {
[self decryptSecureMessage:envelope [self throws_decryptSecureMessage:envelope
envelopeData:envelopeData envelopeData:envelopeData
successBlock:^(OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) { successBlock:^(OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) {
OWSLogDebug(@"decrypted secure message."); OWSLogDebug(@"decrypted secure message.");
@ -228,7 +229,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
return; return;
} }
case SSKProtoEnvelopeTypePrekeyBundle: { case SSKProtoEnvelopeTypePrekeyBundle: {
[self decryptPreKeyBundle:envelope [self throws_decryptPreKeyBundle:envelope
envelopeData:envelopeData envelopeData:envelopeData
successBlock:^(OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) { successBlock:^(OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) {
OWSLogDebug(@"decrypted pre-key whisper message"); OWSLogDebug(@"decrypted pre-key whisper message");
@ -297,10 +298,10 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
failureBlock(); failureBlock();
} }
- (void)decryptSecureMessage:(SSKProtoEnvelope *)envelope - (void)throws_decryptSecureMessage:(SSKProtoEnvelope *)envelope
envelopeData:(NSData *)envelopeData envelopeData:(NSData *)envelopeData
successBlock:(DecryptSuccessBlock)successBlock successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(void (^)(NSError *_Nullable error))failureBlock failureBlock:(void (^)(NSError *_Nullable error))failureBlock
{ {
OWSAssertDebug(envelope); OWSAssertDebug(envelope);
OWSAssertDebug(envelopeData); OWSAssertDebug(envelopeData);
@ -311,16 +312,16 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
envelopeData:envelopeData envelopeData:envelopeData
cipherTypeName:@"Secure Message" cipherTypeName:@"Secure Message"
cipherMessageBlock:^(NSData *encryptedData) { cipherMessageBlock:^(NSData *encryptedData) {
return [[WhisperMessage alloc] initWithData:encryptedData]; return [[WhisperMessage alloc] init_throws_withData:encryptedData];
} }
successBlock:successBlock successBlock:successBlock
failureBlock:failureBlock]; failureBlock:failureBlock];
} }
- (void)decryptPreKeyBundle:(SSKProtoEnvelope *)envelope - (void)throws_decryptPreKeyBundle:(SSKProtoEnvelope *)envelope
envelopeData:(NSData *)envelopeData envelopeData:(NSData *)envelopeData
successBlock:(DecryptSuccessBlock)successBlock successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(void (^)(NSError *_Nullable error))failureBlock failureBlock:(void (^)(NSError *_Nullable error))failureBlock
{ {
OWSAssertDebug(envelope); OWSAssertDebug(envelope);
OWSAssertDebug(envelopeData); OWSAssertDebug(envelopeData);
@ -334,7 +335,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
envelopeData:envelopeData envelopeData:envelopeData
cipherTypeName:@"PreKey Bundle" cipherTypeName:@"PreKey Bundle"
cipherMessageBlock:^(NSData *encryptedData) { cipherMessageBlock:^(NSData *encryptedData) {
return [[PreKeyWhisperMessage alloc] initWithData:encryptedData]; return [[PreKeyWhisperMessage alloc] init_throws_withData:encryptedData];
} }
successBlock:successBlock successBlock:successBlock
failureBlock:failureBlock]; failureBlock:failureBlock];
@ -378,7 +379,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
// plaintextData may be nil for some envelope types. // plaintextData may be nil for some envelope types.
NSData *_Nullable plaintextData = NSData *_Nullable plaintextData =
[[cipher decrypt:cipherMessage protocolContext:transaction] removePadding]; [[cipher throws_decrypt:cipherMessage protocolContext:transaction] removePadding];
OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData
plaintextData:plaintextData plaintextData:plaintextData
source:envelope.source source:envelope.source
@ -448,13 +449,15 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
} }
SMKDecryptResult *_Nullable decryptResult = SMKDecryptResult *_Nullable decryptResult =
[cipher decryptMessageWithCertificateValidator:certificateValidator [cipher throwswrapped_decryptMessageWithCertificateValidator:certificateValidator
cipherTextData:encryptedData cipherTextData:encryptedData
timestamp:serverTimestamp timestamp:serverTimestamp
localRecipientId:localRecipientId localRecipientId:localRecipientId
localDeviceId:localDeviceId localDeviceId:localDeviceId
protocolContext:transaction protocolContext:transaction
error:&error]; error:&error];
SCKRaiseIfExceptionWrapperError(error);
if (error || !decryptResult) { if (error || !decryptResult) {
if ([error.domain isEqualToString:@"SignalMetadataKit.SMKSecretSessionCipherError"] if ([error.domain isEqualToString:@"SignalMetadataKit.SMKSecretSessionCipherError"]
&& error.code == SMKSecretSessionCipherErrorSelfSentMessage) { && error.code == SMKSecretSessionCipherErrorSelfSentMessage) {

@ -19,9 +19,9 @@ 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)throws_processEnvelope:(SSKProtoEnvelope *)envelope
plaintextData:(NSData *_Nullable)plaintextData plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
// This should be invoked by the main app when the app is ready. // This should be invoked by the main app when the app is ready.
- (void)startObserving; - (void)startObserving;

@ -212,9 +212,9 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - message handling #pragma mark - message handling
- (void)processEnvelope:(SSKProtoEnvelope *)envelope - (void)throws_processEnvelope:(SSKProtoEnvelope *)envelope
plaintextData:(NSData *_Nullable)plaintextData plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
if (!envelope) { if (!envelope) {
OWSFailDebug(@"Missing envelope."); OWSFailDebug(@"Missing envelope.");
@ -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 throws_handleEnvelope:envelope plaintextData:plaintextData transaction:transaction];
break; break;
case SSKProtoEnvelopeTypeReceipt: case SSKProtoEnvelopeTypeReceipt:
OWSAssertDebug(!plaintextData); OWSAssertDebug(!plaintextData);
@ -345,9 +345,9 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
- (void)handleEnvelope:(SSKProtoEnvelope *)envelope - (void)throws_handleEnvelope:(SSKProtoEnvelope *)envelope
plaintextData:(NSData *)plaintextData plaintextData:(NSData *)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
if (!envelope) { if (!envelope) {
OWSFailDebug(@"Missing envelope."); OWSFailDebug(@"Missing envelope.");
@ -395,7 +395,9 @@ 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 throws_handleIncomingEnvelope:envelope
withSyncMessage:contentProto.syncMessage
transaction:transaction];
[[OWSDeviceManager sharedManager] setHasReceivedSyncMessage]; [[OWSDeviceManager sharedManager] setHasReceivedSyncMessage];
} else if (contentProto.dataMessage) { } else if (contentProto.dataMessage) {
@ -745,9 +747,9 @@ NS_ASSUME_NONNULL_BEGIN
}]; }];
} }
- (void)handleIncomingEnvelope:(SSKProtoEnvelope *)envelope - (void)throws_handleIncomingEnvelope:(SSKProtoEnvelope *)envelope
withSyncMessage:(SSKProtoSyncMessage *)syncMessage withSyncMessage:(SSKProtoSyncMessage *)syncMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
if (!envelope) { if (!envelope) {
OWSFailDebug(@"Missing envelope."); OWSFailDebug(@"Missing envelope.");
@ -862,7 +864,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 throws_processIncomingSyncMessage:syncMessage.verified transaction:transaction];
} else { } else {
OWSLogWarn(@"Ignoring unsupported sync message."); OWSLogWarn(@"Ignoring unsupported sync message.");
} }

@ -50,6 +50,7 @@
#import <PromiseKit/AnyPromise.h> #import <PromiseKit/AnyPromise.h>
#import <SignalCoreKit/NSData+OWS.h> #import <SignalCoreKit/NSData+OWS.h>
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalCoreKit/SCKExceptionWrapper.h>
#import <SignalCoreKit/Threading.h> #import <SignalCoreKit/Threading.h>
#import <SignalMetadataKit/SignalMetadataKit-Swift.h> #import <SignalMetadataKit/SignalMetadataKit-Swift.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h> #import <SignalServiceKit/SignalServiceKit-Swift.h>
@ -478,7 +479,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
failure:(RetryableFailureHandler)failure failure:(RetryableFailureHandler)failure
{ {
[self.udManager [self.udManager
ensureSenderCertificateObjCWithSuccess:^(SMKSenderCertificate *senderCertificate) { ensureSenderCertificateWithSuccess:^(SMKSenderCertificate *senderCertificate) {
dispatch_async([OWSDispatch sendingQueue], ^{ dispatch_async([OWSDispatch sendingQueue], ^{
[self sendMessageToService:message senderCertificate:senderCertificate success:success failure:failure]; [self sendMessageToService:message senderCertificate:senderCertificate success:success failure:failure];
}); });
@ -838,7 +839,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
NSArray<NSDictionary *> *deviceMessages; NSArray<NSDictionary *> *deviceMessages;
@try { @try {
deviceMessages = [self deviceMessagesForMessageSendUnsafe:messageSend]; deviceMessages = [self throws_deviceMessagesForMessageSendUnsafe:messageSend];
} @catch (NSException *exception) { } @catch (NSException *exception) {
if ([exception.name isEqualToString:UntrustedIdentityKeyException]) { if ([exception.name isEqualToString:UntrustedIdentityKeyException]) {
// This *can* happen under normal usage, but it should happen relatively rarely. // This *can* happen under normal usage, but it should happen relatively rarely.
@ -887,7 +888,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return nil; return nil;
} }
NSData *newIdentityKey = [newIdentityKeyWithVersion removeKeyType]; NSData *newIdentityKey = [newIdentityKeyWithVersion throws_removeKeyType];
[self.identityManager saveRemoteIdentity:newIdentityKey recipientId:recipient.recipientId]; [self.identityManager saveRemoteIdentity:newIdentityKey recipientId:recipient.recipientId];
return nil; return nil;
@ -1406,8 +1407,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[self sendMessageToRecipient:messageSend]; [self sendMessageToRecipient:messageSend];
} }
// NOTE: This method uses exceptions for control flow. - (NSArray<NSDictionary *> *)throws_deviceMessagesForMessageSendUnsafe:(OWSMessageSend *)messageSend
- (NSArray<NSDictionary *> *)deviceMessagesForMessageSendUnsafe:(OWSMessageSend *)messageSend
{ {
OWSAssertDebug(messageSend.message); OWSAssertDebug(messageSend.message);
OWSAssertDebug(messageSend.recipient); OWSAssertDebug(messageSend.recipient);
@ -1443,17 +1443,17 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
@try { @try {
// This may involve blocking network requests, so we do it _before_ // This may involve blocking network requests, so we do it _before_
// we open a transaction. // we open a transaction.
[self ensureRecipientHasSessionForMessageSend:messageSend deviceId:deviceId]; [self throws_ensureRecipientHasSessionForMessageSend:messageSend deviceId:deviceId];
__block NSDictionary *messageDict; __block NSDictionary *messageDict;
__block NSException *encryptionException; __block NSException *encryptionException;
[self.dbConnection [self.dbConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
@try { @try {
messageDict = [self encryptedMessageForMessageSend:messageSend messageDict = [self throws_encryptedMessageForMessageSend:messageSend
deviceId:deviceId deviceId:deviceId
plainText:plainText plainText:plainText
transaction:transaction]; transaction:transaction];
} @catch (NSException *exception) { } @catch (NSException *exception) {
encryptionException = exception; encryptionException = exception;
} }
@ -1485,9 +1485,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return [messagesArray copy]; return [messagesArray copy];
} }
// NOTE: This method uses exceptions for control flow. - (void)throws_ensureRecipientHasSessionForMessageSend:(OWSMessageSend *)messageSend deviceId:(NSNumber *)deviceId
- (void)ensureRecipientHasSessionForMessageSend:(OWSMessageSend *)messageSend
deviceId:(NSNumber *)deviceId
{ {
OWSAssertDebug(messageSend); OWSAssertDebug(messageSend);
OWSAssertDebug(deviceId); OWSAssertDebug(deviceId);
@ -1546,7 +1544,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
deviceId:[deviceId intValue]]; deviceId:[deviceId intValue]];
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
@try { @try {
[builder processPrekeyBundle:bundle protocolContext:transaction]; [builder throws_processPrekeyBundle:bundle protocolContext:transaction];
} @catch (NSException *caughtException) { } @catch (NSException *caughtException) {
exception = caughtException; exception = caughtException;
} }
@ -1611,11 +1609,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
}) retainUntilComplete]; }) retainUntilComplete];
} }
// NOTE: This method uses exceptions for control flow. - (NSDictionary *)throws_encryptedMessageForMessageSend:(OWSMessageSend *)messageSend
- (NSDictionary *)encryptedMessageForMessageSend:(OWSMessageSend *)messageSend deviceId:(NSNumber *)deviceId
deviceId:(NSNumber *)deviceId plainText:(NSData *)plainText
plainText:(NSData *)plainText transaction:(YapDatabaseReadWriteTransaction *)transaction
transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(messageSend); OWSAssertDebug(messageSend);
OWSAssertDebug(deviceId); OWSAssertDebug(deviceId);
@ -1658,17 +1655,18 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
OWSRaiseException(@"SecretSessionCipherFailure", @"Can't create secret session cipher."); OWSRaiseException(@"SecretSessionCipherFailure", @"Can't create secret session cipher.");
} }
serializedMessage = [secretCipher encryptMessageWithRecipientId:recipientId serializedMessage = [secretCipher throwswrapped_encryptMessageWithRecipientId:recipientId
deviceId:deviceId.intValue deviceId:deviceId.intValue
paddedPlaintext:[plainText paddedMessageBody] paddedPlaintext:[plainText paddedMessageBody]
senderCertificate:messageSend.senderCertificate senderCertificate:messageSend.senderCertificate
protocolContext:transaction protocolContext:transaction
error:&error]; error:&error];
SCKRaiseIfExceptionWrapperError(error);
messageType = TSUnidentifiedSenderMessageType; messageType = TSUnidentifiedSenderMessageType;
} else { } else {
// This may throw an exception. // This may throw an exception.
id<CipherMessage> encryptedMessage = id<CipherMessage> encryptedMessage =
[cipher encryptMessage:[plainText paddedMessageBody] protocolContext:transaction]; [cipher throws_encryptMessage:[plainText paddedMessageBody] protocolContext:transaction];
serializedMessage = encryptedMessage.serialized; serializedMessage = encryptedMessage.serialized;
messageType = [self messageTypeForCipherMessage:encryptedMessage]; messageType = [self messageTypeForCipherMessage:encryptedMessage];
} }
@ -1680,7 +1678,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
device:[deviceId intValue] device:[deviceId intValue]
content:serializedMessage content:serializedMessage
isSilent:isSilent isSilent:isSilent
registrationId:[cipher remoteRegistrationId:transaction]]; registrationId:[cipher throws_remoteRegistrationId:transaction]];
NSError *error; NSError *error;
NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error];

@ -65,8 +65,8 @@ private func string(forUnidentifiedAccessMode mode: UnidentifiedAccessMode) -> S
// We use completion handlers instead of a promise so that message sending // We use completion handlers instead of a promise so that message sending
// logic can access the strongly typed certificate data. // logic can access the strongly typed certificate data.
@objc @objc
func ensureSenderCertificateObjC(success:@escaping (SMKSenderCertificate) -> Void, func ensureSenderCertificate(success:@escaping (SMKSenderCertificate) -> Void,
failure:@escaping (Error) -> Void) failure:@escaping (Error) -> Void)
// MARK: Unrestricted Access // MARK: Unrestricted Access
@ -109,6 +109,8 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
guard TSAccountManager.isRegistered() else { guard TSAccountManager.isRegistered() else {
return return
} }
// Any error is silently ignored on startup.
self.ensureSenderCertificate().retainUntilComplete() self.ensureSenderCertificate().retainUntilComplete()
} }
NotificationCenter.default.addObserver(self, NotificationCenter.default.addObserver(self,
@ -121,6 +123,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
func registrationStateDidChange() { func registrationStateDidChange() {
AssertIsOnMainThread() AssertIsOnMainThread()
// Any error is silently ignored
ensureSenderCertificate().retainUntilComplete() ensureSenderCertificate().retainUntilComplete()
} }
@ -297,8 +300,8 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
} }
@objc @objc
public func ensureSenderCertificateObjC(success:@escaping (SMKSenderCertificate) -> Void, public func ensureSenderCertificate(success:@escaping (SMKSenderCertificate) -> Void,
failure:@escaping (Error) -> Void) { failure:@escaping (Error) -> Void) {
firstly { firstly {
ensureSenderCertificate() ensureSenderCertificate()
}.map { certificate in }.map { certificate in
@ -348,7 +351,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
let anHourFromNowMs = nowMs + kHourInMs let anHourFromNowMs = nowMs + kHourInMs
do { do {
try certificateValidator.validate(senderCertificate: certificate, validationTime: anHourFromNowMs) try certificateValidator.throwswrapped_validate(senderCertificate: certificate, validationTime: anHourFromNowMs)
return true return true
} catch { } catch {
OWSLogger.error("Invalid certificate") OWSLogger.error("Invalid certificate")

@ -30,7 +30,7 @@
- (instancetype)init - (instancetype)init
{ {
OWSRaiseException(NSInternalInconsistencyException, @"You must use the initWithURL: method"); OWSFail(@"You must use the initWithURL: method");
return nil; return nil;
} }
@ -41,7 +41,7 @@
cachePolicy:(NSURLRequestCachePolicy)cachePolicy cachePolicy:(NSURLRequestCachePolicy)cachePolicy
timeoutInterval:(NSTimeInterval)timeoutInterval timeoutInterval:(NSTimeInterval)timeoutInterval
{ {
OWSRaiseException(NSInternalInconsistencyException, @"You must use the initWithURL method"); OWSFail(@"You must use the initWithURL: method");
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)")
} }
// `removeKeyType` is an objc category method only on NSData, so temporarily cast. do {
self.identityKey = (identityKeyWithType as NSData).removeKeyType() as Data // `removeKeyType` is an objc category method only on NSData, so temporarily cast.
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")

@ -152,13 +152,11 @@ NSString *const OWSCensorshipConfiguration_DefaultFrontingHost = OWSCensorshipCo
NSError *error; NSError *error;
NSData *certData = [self certificateDataWithName:certName error:&error]; NSData *certData = [self certificateDataWithName:certName error:&error];
if (error) { if (error) {
OWSLogError(@"reading data for certificate: %@ failed with error: %@", certName, error); OWSFail(@"reading data for certificate: %@ failed with error: %@", certName, error);
OWSRaiseException(@"OWSSignalService_UnableToReadCertificate", @"%@", error.description);
} }
if (!certData) { if (!certData) {
OWSLogError(@"No data for certificate: %@", certName); OWSFail(@"reading data for certificate: %@ failed with error: %@", certName, error);
OWSRaiseException(@"OWSSignalService_UnableToReadCertificate", @"%@", error.description);
} }
[certificates addObject:certData]; [certificates addObject:certData];
} }

@ -43,7 +43,7 @@
NSString *path = [bundle pathForResource:service ofType:@"cer"]; NSString *path = [bundle pathForResource:service ofType:@"cer"];
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
OWSRaiseException(@"Missing server certificate", @"Missing signing certificate for service %@", service); OWSFail(@"Missing signing certificate for service %@", service);
} }
NSData *certificateData = [NSData dataWithContentsOfFile:path]; NSData *certificateData = [NSData dataWithContentsOfFile:path];

@ -49,7 +49,7 @@
} }
} }
- (PreKeyRecord *)loadPreKey:(int)preKeyId - (PreKeyRecord *)throws_loadPreKey:(int)preKeyId
{ {
PreKeyRecord *preKeyRecord = [self.dbReadConnection preKeyRecordForKey:[self keyFromInt:preKeyId] PreKeyRecord *preKeyRecord = [self.dbReadConnection preKeyRecordForKey:[self keyFromInt:preKeyId]
inCollection:OWSPrimaryStoragePreKeyStoreCollection]; inCollection:OWSPrimaryStoragePreKeyStoreCollection];

@ -29,14 +29,23 @@ NSString *const OWSPrimaryStorageKeyPrekeyCurrentSignedPrekeyId = @"currentSigne
// Signed prekey ids must be > 0. // Signed prekey ids must be > 0.
int preKeyId = 1 + arc4random_uniform(INT32_MAX - 1); int preKeyId = 1 + arc4random_uniform(INT32_MAX - 1);
ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair]; ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair];
return [[SignedPreKeyRecord alloc] OWSAssert(identityKeyPair);
initWithId:preKeyId
keyPair:keyPair @try {
signature:[Ed25519 sign:keyPair.publicKey.prependKeyType withKeyPair:identityKeyPair] NSData *signature = [Ed25519 throws_sign:keyPair.publicKey.prependKeyType withKeyPair:identityKeyPair];
generatedAt:[NSDate date]]; return [[SignedPreKeyRecord alloc] initWithId:preKeyId
keyPair:keyPair
signature:signature
generatedAt:[NSDate date]];
} @catch (NSException *exception) {
// throws_sign only throws when the data to sign is empty or `keyPair` is nil.
// Neither of which should happen.
OWSFail(@"exception: %@", exception);
return nil;
}
} }
- (SignedPreKeyRecord *)loadSignedPrekey:(int)signedPreKeyId - (SignedPreKeyRecord *)throws_loadSignedPrekey:(int)signedPreKeyId
{ {
SignedPreKeyRecord *preKeyRecord = SignedPreKeyRecord *preKeyRecord =
[self.dbReadConnection signedPreKeyRecordForKey:[self keyFromInt:signedPreKeyId] [self.dbReadConnection signedPreKeyRecordForKey:[self keyFromInt:signedPreKeyId]

@ -28,8 +28,6 @@ NSString *const OWSUIDatabaseConnectionWillUpdateExternallyNotification = @"OWSU
NSString *const OWSUIDatabaseConnectionDidUpdateExternallyNotification = @"OWSUIDatabaseConnectionDidUpdateExternallyNotification"; NSString *const OWSUIDatabaseConnectionDidUpdateExternallyNotification = @"OWSUIDatabaseConnectionDidUpdateExternallyNotification";
NSString *const OWSUIDatabaseConnectionNotificationsKey = @"OWSUIDatabaseConnectionNotificationsKey"; NSString *const OWSUIDatabaseConnectionNotificationsKey = @"OWSUIDatabaseConnectionNotificationsKey";
NSString *const OWSPrimaryStorageExceptionName_CouldNotCreateDatabaseDirectory
= @"TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory";
void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage) void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage)
{ {
@ -252,8 +250,7 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage)
NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"]; NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"];
if (![OWSFileSystem ensureDirectoryExists:databaseDirPath]) { if (![OWSFileSystem ensureDirectoryExists:databaseDirPath]) {
OWSRaiseException( OWSFail(@"Could not create new database directory");
OWSPrimaryStorageExceptionName_CouldNotCreateDatabaseDirectory, @"Could not create new database directory");
} }
return databaseDirPath; return databaseDirPath;
} }

@ -26,12 +26,6 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
NSString *const StorageIsReadyNotification = @"StorageIsReadyNotification"; NSString *const StorageIsReadyNotification = @"StorageIsReadyNotification";
NSString *const OWSStorageExceptionName_DatabasePasswordInaccessibleWhileBackgrounded
= @"OWSStorageExceptionName_DatabasePasswordInaccessibleWhileBackgrounded";
NSString *const OWSStorageExceptionName_DatabasePasswordUnwritable
= @"OWSStorageExceptionName_DatabasePasswordUnwritable";
NSString *const OWSStorageExceptionName_NoDatabase = @"OWSStorageExceptionName_NoDatabase";
NSString *const OWSResetStorageNotification = @"OWSResetStorageNotification"; NSString *const OWSResetStorageNotification = @"OWSResetStorageNotification";
static NSString *keychainService = @"TSKeyChainService"; static NSString *keychainService = @"TSKeyChainService";
@ -330,7 +324,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// Sleep to give analytics events time to be delivered. // Sleep to give analytics events time to be delivered.
[NSThread sleepForTimeInterval:15.0f]; [NSThread sleepForTimeInterval:15.0f];
OWSRaiseException(OWSStorageExceptionName_NoDatabase, @"Failed to initialize database."); OWSFail(@"Failed to initialize database.");
} }
} }
} }
@ -503,8 +497,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
{ {
YapDatabaseConnection *dbConnection = self.database.newConnection; YapDatabaseConnection *dbConnection = self.database.newConnection;
if (!dbConnection) { if (!dbConnection) {
OWSRaiseException( OWSFail(@"Storage could not open new database connection.");
@"OWSStorageExceptionName_CouldNotOpenConnection", @"Storage could not open new database connection.");
} }
return dbConnection; return dbConnection;
} }
@ -862,7 +855,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// Presumably this happened in response to a push notification. It's possible that the keychain is corrupted // Presumably this happened in response to a push notification. It's possible that the keychain is corrupted
// but it could also just be that the user hasn't yet unlocked their device since our password is // but it could also just be that the user hasn't yet unlocked their device since our password is
// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly // kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
OWSRaiseException(OWSStorageExceptionName_DatabasePasswordInaccessibleWhileBackgrounded, @"%@", errorDescription); OWSFail(@"%@", errorDescription);
} }
+ (void)deleteDBKeys + (void)deleteDBKeys
@ -925,8 +918,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// Sleep to give analytics events time to be delivered. // Sleep to give analytics events time to be delivered.
[NSThread sleepForTimeInterval:15.0f]; [NSThread sleepForTimeInterval:15.0f];
OWSRaiseException( OWSFail(@"Setting keychain value failed with error: %@", error);
OWSStorageExceptionName_DatabasePasswordUnwritable, @"Setting keychain value failed with error: %@", error);
} else { } else {
OWSLogWarn(@"Successfully set new keychain value."); OWSLogWarn(@"Successfully set new keychain value.");
} }

@ -138,7 +138,8 @@
break; break;
default: default:
OWSRaiseException(NSInternalInconsistencyException, @"Invalid image orientation"); OWSFailDebug(@"Invalid image orientation");
return nil;
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

@ -35,10 +35,10 @@
PreKeyRecord *lastPreKeyRecord = [generatedKeys lastObject]; PreKeyRecord *lastPreKeyRecord = [generatedKeys lastObject];
PreKeyRecord *firstPreKeyRecord = [generatedKeys firstObject]; PreKeyRecord *firstPreKeyRecord = [generatedKeys firstObject];
XCTAssert([[[OWSPrimaryStorage sharedManager] loadPreKey:lastPreKeyRecord.Id].keyPair.publicKey XCTAssert([[[OWSPrimaryStorage sharedManager] throws_loadPreKey:lastPreKeyRecord.Id].keyPair.publicKey
isEqualToData:lastPreKeyRecord.keyPair.publicKey]); isEqualToData:lastPreKeyRecord.keyPair.publicKey]);
XCTAssert([[[OWSPrimaryStorage sharedManager] loadPreKey:firstPreKeyRecord.Id].keyPair.publicKey XCTAssert([[[OWSPrimaryStorage sharedManager] throws_loadPreKey:firstPreKeyRecord.Id].keyPair.publicKey
isEqualToData:firstPreKeyRecord.keyPair.publicKey]); isEqualToData:firstPreKeyRecord.keyPair.publicKey]);
} }
@ -56,8 +56,8 @@
[[OWSPrimaryStorage sharedManager] removePreKey:lastPreKeyRecord.Id]; [[OWSPrimaryStorage sharedManager] removePreKey:lastPreKeyRecord.Id];
XCTAssertThrows([[OWSPrimaryStorage sharedManager] loadPreKey:lastPreKeyRecord.Id]); XCTAssertThrows([[OWSPrimaryStorage sharedManager] throws_loadPreKey:lastPreKeyRecord.Id]);
XCTAssertNoThrow([[OWSPrimaryStorage sharedManager] loadPreKey:firstPreKeyRecord.Id]); XCTAssertNoThrow([[OWSPrimaryStorage sharedManager] throws_loadPreKey:firstPreKeyRecord.Id]);
} }
@end @end

Loading…
Cancel
Save