2017-06-06 23:43:41 +02:00
|
|
|
//
|
2018-06-07 17:52:39 +02:00
|
|
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
2017-06-06 23:43:41 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
#import "OWSVerificationStateSyncMessage.h"
|
2017-06-17 19:34:26 +02:00
|
|
|
#import "Cryptography.h"
|
2017-06-19 17:05:06 +02:00
|
|
|
#import "OWSIdentityManager.h"
|
2018-08-01 23:13:01 +02:00
|
|
|
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
2017-06-06 23:43:41 +02:00
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
2017-06-07 17:27:33 +02:00
|
|
|
#pragma mark -
|
|
|
|
|
2017-06-06 23:43:41 +02:00
|
|
|
@interface OWSVerificationStateSyncMessage ()
|
|
|
|
|
2017-06-22 02:19:23 +02:00
|
|
|
@property (nonatomic, readonly) OWSVerificationState verificationState;
|
|
|
|
@property (nonatomic, readonly) NSData *identityKey;
|
2017-06-06 23:43:41 +02:00
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
@implementation OWSVerificationStateSyncMessage
|
|
|
|
|
2017-06-22 02:19:23 +02:00
|
|
|
- (instancetype)initWithVerificationState:(OWSVerificationState)verificationState
|
|
|
|
identityKey:(NSData *)identityKey
|
|
|
|
verificationForRecipientId:(NSString *)verificationForRecipientId
|
2017-06-06 23:43:41 +02:00
|
|
|
{
|
2017-06-22 02:19:23 +02:00
|
|
|
OWSAssert(identityKey.length == kIdentityKeyLength);
|
|
|
|
OWSAssert(verificationForRecipientId.length > 0);
|
2017-06-22 20:32:06 +02:00
|
|
|
|
2017-06-22 02:19:23 +02:00
|
|
|
// we only sync user's marking as un/verified. Never sync the conflicted state, the sibling device
|
|
|
|
// will figure that out on it's own.
|
|
|
|
OWSAssert(verificationState != OWSVerificationStateNoLongerVerified);
|
|
|
|
|
2017-06-06 23:43:41 +02:00
|
|
|
self = [super init];
|
|
|
|
if (!self) {
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2017-06-22 02:19:23 +02:00
|
|
|
_verificationState = verificationState;
|
|
|
|
_identityKey = identityKey;
|
|
|
|
_verificationForRecipientId = verificationForRecipientId;
|
2017-06-22 18:12:24 +02:00
|
|
|
|
2017-06-22 19:05:28 +02:00
|
|
|
// This sync message should be 1-512 bytes longer than the corresponding NullMessage
|
|
|
|
// we store this values so the corresponding NullMessage can subtract it from the total length.
|
2017-06-22 18:12:24 +02:00
|
|
|
_paddingBytesLength = arc4random_uniform(512) + 1;
|
2017-06-22 02:19:23 +02:00
|
|
|
|
|
|
|
return self;
|
2017-06-06 23:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-06-07 17:52:39 +02:00
|
|
|
- (nullable instancetype)initWithCoder:(NSCoder *)coder
|
|
|
|
{
|
|
|
|
return [super initWithCoder:coder];
|
|
|
|
}
|
|
|
|
|
2018-08-02 00:00:58 +02:00
|
|
|
- (nullable SSKProtoSyncMessageBuilder *)syncMessageBuilder
|
2017-06-06 23:43:41 +02:00
|
|
|
{
|
2017-06-22 20:32:06 +02:00
|
|
|
OWSAssert(self.identityKey.length == kIdentityKeyLength);
|
|
|
|
OWSAssert(self.verificationForRecipientId.length > 0);
|
|
|
|
|
|
|
|
// we only sync user's marking as un/verified. Never sync the conflicted state, the sibling device
|
|
|
|
// will figure that out on it's own.
|
|
|
|
OWSAssert(self.verificationState != OWSVerificationStateNoLongerVerified);
|
|
|
|
|
2018-08-01 23:13:01 +02:00
|
|
|
SSKProtoVerifiedBuilder *verifiedBuilder = [SSKProtoVerifiedBuilder new];
|
2017-06-22 02:19:23 +02:00
|
|
|
verifiedBuilder.destination = self.verificationForRecipientId;
|
|
|
|
verifiedBuilder.identityKey = self.identityKey;
|
2017-06-22 19:36:40 +02:00
|
|
|
verifiedBuilder.state = OWSVerificationStateToProtoState(self.verificationState);
|
|
|
|
|
2017-06-22 18:12:24 +02:00
|
|
|
OWSAssert(self.paddingBytesLength != 0);
|
2017-06-22 21:13:34 +02:00
|
|
|
|
|
|
|
// We add the same amount of padding in the VerificationStateSync message and it's coresponding NullMessage so that
|
|
|
|
// the sync message is indistinguishable from an outgoing Sent transcript corresponding to the NullMessage. We pad
|
|
|
|
// the NullMessage so as to obscure it's content. The sync message (like all sync messages) will be *additionally*
|
|
|
|
// padded by the superclass while being sent. The end result is we send a NullMessage of a non-distinct size, and a
|
|
|
|
// verification sync which is ~1-512 bytes larger then that.
|
2017-06-22 19:05:28 +02:00
|
|
|
verifiedBuilder.nullMessage = [Cryptography generateRandomBytes:self.paddingBytesLength];
|
2018-08-02 00:00:58 +02:00
|
|
|
|
|
|
|
NSError *error;
|
|
|
|
SSKProtoVerified *_Nullable verifiedProto = [verifiedBuilder buildAndReturnError:&error];
|
|
|
|
if (error || !verifiedProto) {
|
|
|
|
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
SSKProtoSyncMessageBuilder *syncMessageBuilder = [SSKProtoSyncMessageBuilder new];
|
|
|
|
[syncMessageBuilder setVerified:verifiedProto];
|
2017-06-22 19:05:28 +02:00
|
|
|
return syncMessageBuilder;
|
2017-06-06 23:43:41 +02:00
|
|
|
}
|
|
|
|
|
2017-06-22 20:32:06 +02:00
|
|
|
- (size_t)unpaddedVerifiedLength
|
|
|
|
{
|
|
|
|
OWSAssert(self.identityKey.length == kIdentityKeyLength);
|
|
|
|
OWSAssert(self.verificationForRecipientId.length > 0);
|
|
|
|
|
|
|
|
// we only sync user's marking as un/verified. Never sync the conflicted state, the sibling device
|
|
|
|
// will figure that out on it's own.
|
|
|
|
OWSAssert(self.verificationState != OWSVerificationStateNoLongerVerified);
|
|
|
|
|
2018-08-01 23:13:01 +02:00
|
|
|
SSKProtoVerifiedBuilder *verifiedBuilder = [SSKProtoVerifiedBuilder new];
|
2017-06-22 20:32:06 +02:00
|
|
|
verifiedBuilder.destination = self.verificationForRecipientId;
|
|
|
|
verifiedBuilder.identityKey = self.identityKey;
|
|
|
|
verifiedBuilder.state = OWSVerificationStateToProtoState(self.verificationState);
|
|
|
|
|
|
|
|
return [verifiedBuilder build].data.length;
|
|
|
|
}
|
|
|
|
|
2017-06-06 23:43:41 +02:00
|
|
|
@end
|
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_END
|