Swift protos for Envelope

This commit is contained in:
Michael Kirk 2018-06-06 23:57:59 -06:00 committed by Michael Kirk
parent e77b798aa7
commit b860dce7f9
32 changed files with 4612 additions and 261 deletions

View File

@ -60,6 +60,7 @@ PODS:
- Reachability
- SAMKeychain
- SocketRocket
- SwiftProtobuf
- YapDatabase/SQLCipher
- SocketRocket (0.5.1)
- SQLCipher (3.4.2):
@ -68,6 +69,7 @@ PODS:
- SQLCipher/standard (3.4.2):
- SQLCipher/common
- SSZipArchive (2.1.2)
- SwiftProtobuf (1.0.3)
- YapDatabase/SQLCipher (3.0.2):
- YapDatabase/SQLCipher/Core (= 3.0.2)
- YapDatabase/SQLCipher/Extensions (= 3.0.2)
@ -161,6 +163,7 @@ SPEC REPOS:
- Reachability
- SAMKeychain
- SSZipArchive
- SwiftProtobuf
- YYImage
EXTERNAL SOURCES:
@ -223,10 +226,11 @@ SPEC CHECKSUMS:
PureLayout: 4d550abe49a94f24c2808b9b95db9131685fe4cd
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SignalServiceKit: eaaf6404e61fc05c71f91246327e2d487e0e1833
SignalServiceKit: a16410721705f896905c65ad718424fa20728e7d
SocketRocket: dbb1554b8fc288ef8ef370d6285aeca7361be31e
SQLCipher: f9fcf29b2e59ced7defc2a2bdd0ebe79b40d4990
SSZipArchive: d4009d2ce5520a421f231fd97028cc0e2667eed8
SwiftProtobuf: 5ccc0e4054e37c75800e5744acb2aa80bb72b39c
YapDatabase: 299a32de9d350d37a9ac5b0532609d87d5d2a5de
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54

2
Pods

@ -1 +1 @@
Subproject commit 4ede6c138ce6b5fd7279c9dcbbcece4018b03d57
Subproject commit 2474b814b3108d9684effcdfe460c5ff42d3cbbe

View File

@ -2998,6 +2998,7 @@
"${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework",
"${BUILT_PRODUCTS_DIR}/SignalServiceKit/SignalServiceKit.framework",
"${BUILT_PRODUCTS_DIR}/SocketRocket/SocketRocket.framework",
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
"${BUILT_PRODUCTS_DIR}/libPhoneNumber-iOS/libPhoneNumber_iOS.framework",
@ -3021,6 +3022,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalServiceKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SocketRocket.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libPhoneNumber_iOS.framework",
@ -3070,6 +3072,7 @@
"${BUILT_PRODUCTS_DIR}/SQLCipher/SQLCipher.framework",
"${BUILT_PRODUCTS_DIR}/SignalServiceKit/SignalServiceKit.framework",
"${BUILT_PRODUCTS_DIR}/SocketRocket/SocketRocket.framework",
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
"${BUILT_PRODUCTS_DIR}/libPhoneNumber-iOS/libPhoneNumber_iOS.framework",
@ -3091,6 +3094,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SQLCipher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalServiceKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SocketRocket.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libPhoneNumber_iOS.framework",

View File

@ -38,10 +38,15 @@ public class MessageFetcherJob: NSObject {
Logger.info("\(self.logTag) fetching messages via REST.")
let promise = self.fetchUndeliveredMessages().then { (envelopes: [OWSSignalServiceProtosEnvelope], more: Bool) -> Promise<Void> in
let promise = self.fetchUndeliveredMessages().then { (envelopes: [SSKEnvelope], more: Bool) -> Promise<Void> in
for envelope in envelopes {
Logger.info("\(self.logTag) received envelope.")
self.messageReceiver.handleReceivedEnvelope(envelope)
do {
let envelopeData = try envelope.serializedData()
self.messageReceiver.handleReceivedEnvelopeData(envelopeData)
} catch {
owsFail("\(self.logTag) in \(#function) failed to serialize envelope")
}
self.acknowledgeDelivery(envelope: envelope)
}
@ -80,7 +85,7 @@ public class MessageFetcherJob: NSObject {
timer = nil
}
private func parseMessagesResponse(responseObject: Any?) -> (envelopes: [OWSSignalServiceProtosEnvelope], more: Bool)? {
private func parseMessagesResponse(responseObject: Any?) -> (envelopes: [SSKEnvelope], more: Bool)? {
guard let responseObject = responseObject else {
Logger.error("\(self.logTag) response object was surpringly nil")
return nil
@ -113,56 +118,57 @@ public class MessageFetcherJob: NSObject {
)
}
private func buildEnvelope(messageDict: [String: Any]) -> OWSSignalServiceProtosEnvelope? {
let builder = OWSSignalServiceProtosEnvelopeBuilder()
private func buildEnvelope(messageDict: [String: Any]) -> SSKEnvelope? {
guard let typeInt = messageDict["type"] as? Int32 else {
Logger.error("\(self.logTag) message body didn't have type")
return nil
}
guard let type = OWSSignalServiceProtosEnvelopeType(rawValue: typeInt) else {
guard let type: SSKEnvelope.SSKEnvelopeType = SSKEnvelope.SSKEnvelopeType(rawValue: typeInt) else {
Logger.error("\(self.logTag) message body type was invalid")
return nil
}
builder.setType(type)
guard let timestamp = messageDict["timestamp"] as? UInt64 else {
Logger.error("\(self.logTag) message body didn't have timestamp")
return nil
}
builder.setTimestamp(timestamp)
guard let source = messageDict["source"] as? String else {
Logger.error("\(self.logTag) message body didn't have source")
return nil
}
builder.setSource(source)
guard let sourceDevice = messageDict["sourceDevice"] as? UInt32 else {
Logger.error("\(self.logTag) message body didn't have sourceDevice")
return nil
}
builder.setSourceDevice(sourceDevice)
if let encodedLegacyMessage = messageDict["message"] as? String {
Logger.debug("\(self.logTag) message body had legacyMessage")
if let legacyMessage = Data(base64Encoded: encodedLegacyMessage) {
builder.setLegacyMessage(legacyMessage)
let legacyMessage: Data? = {
if let encodedLegacyMessage = messageDict["message"] as? String {
Logger.debug("\(self.logTag) message body had legacyMessage")
if let legacyMessage = Data(base64Encoded: encodedLegacyMessage) {
return legacyMessage
}
}
}
return nil
}()
if let encodedContent = messageDict["content"] as? String {
Logger.debug("\(self.logTag) message body had content")
if let content = Data(base64Encoded: encodedContent) {
builder.setContent(content)
let content: Data? = {
if let encodedContent = messageDict["content"] as? String {
Logger.debug("\(self.logTag) message body had content")
if let content = Data(base64Encoded: encodedContent) {
return content
}
}
}
return nil
}()
return builder.build()
return SSKEnvelope(timestamp: timestamp, source: source, sourceDevice: sourceDevice, type: type, content: content, legacyMessage: legacyMessage)
}
private func fetchUndeliveredMessages() -> Promise<(envelopes: [OWSSignalServiceProtosEnvelope], more: Bool)> {
private func fetchUndeliveredMessages() -> Promise<(envelopes: [SSKEnvelope], more: Bool)> {
return Promise { fulfill, reject in
let request = OWSRequestFactory.getMessagesRequest()
self.networkManager.makeRequest(
@ -186,7 +192,7 @@ public class MessageFetcherJob: NSObject {
}
}
private func acknowledgeDelivery(envelope: OWSSignalServiceProtosEnvelope) {
private func acknowledgeDelivery(envelope: SSKEnvelope) {
let request = OWSRequestFactory.acknowledgeMessageDeliveryRequest(withSource: envelope.source, timestamp: envelope.timestamp)
self.networkManager.makeRequest(request,
success: { (_: URLSessionDataTask?, _: Any?) -> Void in

View File

@ -3372,23 +3372,32 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac
completion:nil];
}
+ (OWSSignalServiceProtosEnvelope *)createEnvelopeForThread:(TSThread *)thread
+ (SSKEnvelope *)createEnvelopeForThread:(TSThread *)thread
{
OWSAssert(thread);
OWSSignalServiceProtosEnvelopeBuilder *builder = [OWSSignalServiceProtosEnvelopeBuilder new];
uint64_t timestamp = [NSDate ows_millisecondTimeStamp];
NSString *source = ^{
if ([thread isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *gThread = (TSGroupThread *)thread;
return gThread.groupModel.groupMemberIds[0];
} else if ([thread isKindOfClass:[TSContactThread class]]) {
TSContactThread *contactThread = (TSContactThread *)thread;
return contactThread.contactIdentifier;
} else {
OWSFail(@"%@ failure: unknown thread type", self.logTag);
return @"unknown-source-id";
}
}();
[builder setTimestamp:[NSDate ows_millisecondTimeStamp]];
SSKEnvelope *envelope = [[SSKEnvelope alloc] initWithTimestamp:timestamp
source:source
sourceDevice:1
type:SSKEnvelopeTypeCiphertext
content:nil
legacyMessage:nil];
if ([thread isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *gThread = (TSGroupThread *)thread;
[builder setSource:gThread.groupModel.groupMemberIds[0]];
} else if ([thread isKindOfClass:[TSContactThread class]]) {
TSContactThread *contactThread = (TSContactThread *)thread;
[builder setSource:contactThread.contactIdentifier];
}
return [builder build];
return envelope;
}
+ (NSArray<TSInteraction *> *)unsavedSystemMessagesInThread:(TSThread *)thread
@ -3542,9 +3551,6 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac
withTransaction:transaction]];
[result addObject:[TSErrorMessage invalidVersionWithEnvelope:[self createEnvelopeForThread:thread]
withTransaction:transaction]];
[result addObject:[TSInvalidIdentityKeyReceivingErrorMessage
untrustedKeyWithEnvelope:[self createEnvelopeForThread:thread]
withTransaction:transaction]];
[result addObject:[TSErrorMessage corruptedMessageWithEnvelope:[self createEnvelopeForThread:thread]
withTransaction:transaction]];
@ -3871,15 +3877,22 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac
recipientId = @"+12345678901";
}
OWSSignalServiceProtosEnvelopeBuilder *envelopeBuilder = [OWSSignalServiceProtosEnvelopeBuilder new];
[envelopeBuilder setType:OWSSignalServiceProtosEnvelopeTypeCiphertext];
[envelopeBuilder setSource:recipientId];
[envelopeBuilder setSourceDevice:1];
[envelopeBuilder setTimestamp:[NSDate ows_millisecondTimeStamp]];
[envelopeBuilder setContent:plaintextData];
uint64_t timestamp = [NSDate ows_millisecondTimeStamp];
NSString *source = recipientId;
uint32_t sourceDevice = 1;
SSKEnvelopeType envelopeType = SSKEnvelopeTypeCiphertext;
NSData *content = plaintextData;
NSData *envelopeData = [envelopeBuilder build].data;
OWSAssert(envelopeData);
SSKEnvelope *envelope = [[SSKEnvelope alloc] initWithTimestamp:timestamp
source:source
sourceDevice:sourceDevice
type:envelopeType
content:content
legacyMessage:nil];
NSError *error;
NSData *_Nullable envelopeData = [envelope serializedDataAndReturnError:&error];
OWSAssert(!error && envelopeData);
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[[OWSBatchMessageProcessor sharedInstance] enqueueEnvelopeData:envelopeData

View File

@ -49,11 +49,12 @@ An Objective-C library for communicating with the Signal messaging service.
s.dependency 'GRKOpenSSLFramework'
s.dependency 'SAMKeychain'
s.dependency 'Reachability'
s.dependency 'SwiftProtobuf'
# Avoid PromiseKit 5/6 for now.
# From the maintainer:
# > PromiseKit 5 has been released, but is not yet fully documented,
# > so we advise sticking with version 4 for the time being.
# Avoid PromiseKit 5/6 for now.
# From the maintainer:
# > PromiseKit 5 has been released, but is not yet fully documented,
# > so we advise sticking with version 4 for the time being.
s.dependency 'PromiseKit', "~> 4.0"
end

View File

@ -1,25 +1,22 @@
# See README.md in this dir for prerequisite setup.
PROTOC=protoc \
--plugin=/usr/local/bin/protoc-gen-objc \
--proto_path="${HOME}/src/signal/protobuf-objc/src/compiler/" \
--proto_path="${HOME}/src/signal/protobuf-objc/src/compiler/google/protobuf/" \
--proto_path='./'
all: signal_service_proto provisioning_protos fingerprint_protos websocket_protos
signal_service_proto: OWSSignalServiceProtos.proto
$(PROTOC) --objc_out=../src/Messages/ \
$(PROTOC) --swift_out=../src/Protos/ \
OWSSignalServiceProtos.proto
provisioning_protos: OWSProvisioningProtos.proto
$(PROTOC) --objc_out=../src/Devices/ \
$(PROTOC) --swift_out=../src/Protos/ \
OWSProvisioningProtos.proto
fingerprint_protos: OWSFingerprintProtos.proto
$(PROTOC) --objc_out=../src/Security/ \
$(PROTOC) --swift_out=../src/Protos/ \
OWSFingerprintProtos.proto
websocket_protos: WebSocketResources.proto
$(PROTOC) --objc_out=../src/Network/WebSockets/ \
$(PROTOC) --swift_out=../src/Protos/ \
WebSocketResources.proto

View File

@ -1,11 +1,12 @@
// iOS - since we use a modern proto-compiler, we must specify
// the legacy proto format.
syntax = "proto2";
package textsecure;
option java_package = "org.whispersystems.libsignal.fingerprint";
option java_outer_classname = "FingerprintProtos";
import "objectivec-descriptor.proto";
option (google.protobuf.objectivec_file_options).class_prefix = "OWSFingerprintProtos";
message LogicalFingerprint {
optional bytes identityData = 1;
// optional bytes identifier = 2;

View File

@ -4,14 +4,15 @@
* Licensed according to the LICENSE file in this repository.
*/
// iOS - since we use a modern proto-compiler, we must specify
// the legacy proto format.
syntax = "proto2";
package signalservice;
option java_package = "org.whispersystems.signalservice.internal.push";
option java_outer_classname = "ProvisioningProtos";
import "objectivec-descriptor.proto";
option (google.protobuf.objectivec_file_options).class_prefix = "OWSProvisioningProtos";
message ProvisionEnvelope {
optional bytes publicKey = 1;
optional bytes body = 2; // Encrypted ProvisionMessage

View File

@ -4,15 +4,15 @@
* Licensed according to the LICENSE file in this repository.
*/
package signalservice;
// iOS - since we use a modern proto-compiler, we must specify
// the legacy proto format.
syntax = "proto2";
package SignalService;
option java_package = "org.whispersystems.signalservice.internal.push";
option java_outer_classname = "SignalServiceProtos";
// Signal-iOS
import "objectivec-descriptor.proto";
option (google.protobuf.objectivec_file_options).class_prefix = "OWSSignalServiceProtos";
message Envelope {
enum Type {
UNKNOWN = 0;

View File

@ -4,11 +4,11 @@
* Licensed according to the LICENSE file in this repository.
*/
package signalios;
// iOS - since we use a modern proto-compiler, we must specify
// the legacy proto format.
syntax = "proto2";
// Signal-iOS
import "objectivec-descriptor.proto";
option (google.protobuf.objectivec_file_options).class_prefix = "OWSSignaliOSProtos";
package signalios;
message BackupSnapshot
{
@ -26,4 +26,4 @@ message BackupSnapshot
}
repeated BackupEntity entity = 1;
}
}

View File

@ -1,38 +1,22 @@
# SignalServiceKit Protobufs
These protobuf definitions are copied from Signal-Android, but modified
to include a conventional ObjC classnames.
e.g.
import "objectivec-descriptor.proto";
option (google.protobuf.objectivec_file_options).class_prefix = "OWSFingerprintProtos";
to match some iOS conventions.
## Prequisites
Install protobuf 2.6, the objc plugin doesn't currently work with
protobuf 3.0
Install Apple's `swift-protobuf` (*not* the similarly named `protobuf-swift`)
brew install protobuf@2.6
# Beware if you are depending on protobuf 3.0 elsewhere
brew link --force protobuf@2.6
brew install swift-protobuf
Install the objc plugin to $SignalServiceKitRoot/..
This should install an up to date protobuf package as a dependency. Note that
since we use the legacy proto2 format, we need to specify this in our .proto
files.
e.g. I have SignalServiceKit installed to ~/src/WhisperSystems/SignalServiceKit
So I run
cd ~/src/WhisperSystems
git clone https://github.com/alexeyxo/protobuf-objc
Follow the install instructions at https://github.com/alexeyxo/protobuf-objc
syntax = "proto2";
## Building Protobuf
After changes are made to any proto, generate the ObjC classes by
running:
cd ~/src/WhisperSystems/SignalServiceKit/protobuf
make

View File

@ -4,15 +4,15 @@
* Licensed according to the LICENSE file in this repository.
*/
// iOS - since we use a modern proto-compiler, we must specify
// the legacy proto format.
syntax = "proto2";
package signalservice;
option java_package = "org.whispersystems.signalservice.internal.websocket";
option java_outer_classname = "WebSocketProtos";
// Signal-iOS
import "objectivec-descriptor.proto";
option (google.protobuf.objectivec_file_options).class_prefix = "WebSocketResources";
message WebSocketRequestMessage
{
optional string verb = 1;
@ -42,4 +42,4 @@ message WebSocketMessage
optional Type type = 1;
optional WebSocketRequestMessage request = 2;
optional WebSocketResponseMessage response = 3;
}
}

View File

@ -3,11 +3,12 @@
//
#import "OWSReadTracking.h"
#import "OWSSignalServiceProtos.pb.h"
#import "TSMessage.h"
NS_ASSUME_NONNULL_BEGIN
@class SSKEnvelope;
typedef NS_ENUM(int32_t, TSErrorMessageType) {
TSErrorMessageNoSession,
// DEPRECATED: We no longer create TSErrorMessageWrongTrustedIdentityKey, but
@ -54,18 +55,18 @@ typedef NS_ENUM(int32_t, TSErrorMessageType) {
inThread:(nullable TSThread *)thread
failedMessageType:(TSErrorMessageType)errorMessageType;
+ (instancetype)corruptedMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)corruptedMessageWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (instancetype)corruptedMessageInUnknownThread;
+ (instancetype)invalidVersionWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)invalidVersionWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (instancetype)invalidKeyExceptionWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)invalidKeyExceptionWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (instancetype)missingSessionWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)missingSessionWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (instancetype)nonblockingIdentityChangeInThread:(TSThread *)thread recipientId:(NSString *)recipientId;

View File

@ -9,6 +9,7 @@
#import "TSContactThread.h"
#import "TSErrorMessage_privateConstructor.h"
#import "TextSecureKitEnv.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabaseConnection.h>
NS_ASSUME_NONNULL_BEGIN
@ -83,7 +84,7 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
return [self initWithTimestamp:timestamp inThread:thread failedMessageType:errorMessageType recipientId:nil];
}
- (instancetype)initWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (instancetype)initWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
failedMessageType:(TSErrorMessageType)errorMessageType
{
@ -145,7 +146,7 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
}
}
+ (instancetype)corruptedMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)corruptedMessageWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
return [[self alloc] initWithEnvelope:envelope
@ -158,7 +159,7 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
return [[self alloc] initWithFailedMessageType:TSErrorMessageInvalidMessage];
}
+ (instancetype)invalidVersionWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)invalidVersionWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
return [[self alloc] initWithEnvelope:envelope
@ -166,7 +167,7 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
failedMessageType:TSErrorMessageInvalidVersion];
}
+ (instancetype)invalidKeyExceptionWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)invalidKeyExceptionWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
return [[self alloc] initWithEnvelope:envelope
@ -174,7 +175,7 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
failedMessageType:TSErrorMessageInvalidKeyException];
}
+ (instancetype)missingSessionWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
+ (instancetype)missingSessionWithEnvelope:(SSKEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
return

View File

@ -1,9 +1,5 @@
//
// TSErrorMessage_privateConstructor.h
// Signal
//
// Created by Frederic Jacobs on 31/12/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSErrorMessage.h"
@ -14,7 +10,7 @@
inThread:(TSThread *)thread
failedMessageType:(TSErrorMessageType)errorMessageType NS_DESIGNATED_INITIALIZER;
@property NSData *envelopeData;
@property (atomic, nullable) NSData *envelopeData;
@property NSDictionary *pendingOutgoingMessage;

View File

@ -8,7 +8,6 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosDataMessage;
@class OWSSignalServiceProtosEnvelope;
@class TSAttachment;
@class TSAttachmentStream;
@class TSQuotedMessage;

View File

@ -1,20 +1,15 @@
//
// TSInvalidIdentityKeyErrorMessage.h
// Signal
//
// Created by Frederic Jacobs on 31/12/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSInvalidIdentityKeyErrorMessage.h"
NS_ASSUME_NONNULL_BEGIN
// DEPRECATED - we no longer create new instances of this class (as of mid-2017); However, existing instances may
// exist, so we should keep this class around to honor their old behavior.
@interface TSInvalidIdentityKeyReceivingErrorMessage : TSInvalidIdentityKeyErrorMessage
+ (instancetype)untrustedKeyWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
@end
NS_ASSUME_NONNULL_END

View File

@ -14,6 +14,7 @@
#import "TSErrorMessage_privateConstructor.h"
#import <AxolotlKit/NSData+keyVersionByte.h>
#import <AxolotlKit/PreKeyWhisperMessage.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabaseTransaction.h>
NS_ASSUME_NONNULL_BEGIN
@ -27,46 +28,20 @@ NS_ASSUME_NONNULL_BEGIN
@implementation TSInvalidIdentityKeyReceivingErrorMessage {
// Not using a property declaration in order to exclude from DB serialization
OWSSignalServiceProtosEnvelope *_envelope;
SSKEnvelope *_Nullable _envelope;
}
@synthesize envelopeData = _envelopeData;
+ (instancetype)untrustedKeyWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
TSContactThread *contactThread =
[TSContactThread getOrCreateThreadWithContactId:envelope.source transaction:transaction];
TSInvalidIdentityKeyReceivingErrorMessage *errorMessage =
[[self alloc] initForUnknownIdentityKeyWithTimestamp:envelope.timestamp
inThread:contactThread
incomingEnvelope:envelope];
return errorMessage;
}
- (instancetype)initForUnknownIdentityKeyWithTimestamp:(uint64_t)timestamp
inThread:(TSThread *)thread
incomingEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
{
self = [self initWithTimestamp:timestamp inThread:thread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
if (!self) {
return self;
}
_envelopeData = envelope.data;
_authorId = envelope.source;
return self;
}
- (OWSSignalServiceProtosEnvelope *)envelope
- (nullable SSKEnvelope *)envelope
{
if (!_envelope) {
@try {
_envelope = [OWSSignalServiceProtosEnvelope parseFromData:self.envelopeData];
} @catch (NSException *exception) {
OWSProdLogAndFail(@"%@ Could not parse proto: %@", self.logTag, exception.debugDescription);
// TODO: Add analytics.
NSError *error;
SSKEnvelope *_Nullable envelope = [[SSKEnvelope alloc] initWithSerializedData:self.envelopeData error:&error];
if (error || envelope == nil) {
OWSProdLogAndFail(@"%@ Could not parse proto: %@", self.logTag, error);
} else {
_envelope = envelope;
}
}
return _envelope;
@ -94,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
[self.thread receivedMessagesForInvalidKey:newKey];
for (TSInvalidIdentityKeyReceivingErrorMessage *errorMessage in messagesToDecrypt) {
[[OWSMessageReceiver sharedInstance] handleReceivedEnvelope:errorMessage.envelope];
[[OWSMessageReceiver sharedInstance] handleReceivedEnvelopeData:errorMessage.envelopeData];
// Here we remove the existing error message because handleReceivedEnvelope will either
// 1.) succeed and create a new successful message in the thread or...
@ -110,13 +85,12 @@ NS_ASSUME_NONNULL_BEGIN
return nil;
}
if (self.envelope.type != OWSSignalServiceProtosEnvelopeTypePrekeyBundle) {
if (self.envelope.type != SSKEnvelopeTypePrekeyBundle) {
DDLogError(@"Refusing to attempt key extraction from an envelope which isn't a prekey bundle");
return nil;
}
// DEPRECATED - Remove after all clients have been upgraded.
NSData *pkwmData = self.envelope.hasContent ? self.envelope.content : self.envelope.legacyMessage;
NSData *pkwmData = self.envelope.content;
if (!pkwmData) {
DDLogError(@"Ignoring acceptNewIdentityKey for empty message");
return nil;

View File

@ -4,8 +4,8 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class OWSStorage;
@class SSKEnvelope;
@class YapDatabaseReadWriteTransaction;
// This class is used to write incoming (decrypted, unprocessed)

View File

@ -19,6 +19,7 @@
#import "TSYapDatabaseObject.h"
#import "TextSecureKitEnv.h"
#import "Threading.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabaseAutoView.h>
#import <YapDatabase/YapDatabaseConnection.h>
#import <YapDatabase/YapDatabaseTransaction.h>
@ -28,8 +29,6 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Persisted data model
@class OWSSignalServiceProtosEnvelope;
@interface OWSMessageContentJob : TSYapDatabaseObject
@property (nonatomic, readonly) NSDate *createdAt;
@ -40,7 +39,8 @@ NS_ASSUME_NONNULL_BEGIN
plaintextData:(NSData *_Nullable)plaintextData NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithUniqueId:(NSString *_Nullable)uniqueId NS_UNAVAILABLE;
- (OWSSignalServiceProtosEnvelope *)envelopeProto;
@property (nonatomic, readonly, nullable) SSKEnvelope *envelope;
@end
@ -74,9 +74,17 @@ NS_ASSUME_NONNULL_BEGIN
return [super initWithCoder:coder];
}
- (OWSSignalServiceProtosEnvelope *)envelopeProto
- (nullable SSKEnvelope *)envelope
{
return [OWSSignalServiceProtosEnvelope parseFromData:self.envelopeData];
NSError *error;
SSKEnvelope *_Nullable result = [[SSKEnvelope alloc] initWithSerializedData:self.envelopeData error:&error];
if (error) {
OWSProdLogAndFail(@"%@ paring SSKEnvelope failed with error: %@", self.logTag, error);
return nil;
}
return result;
}
@end
@ -378,16 +386,27 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
NSMutableArray<OWSMessageContentJob *> *processedJobs = [NSMutableArray new];
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (OWSMessageContentJob *job in jobs) {
@try {
[self.messagesManager processEnvelope:job.envelopeProto
plaintextData:job.plaintextData
transaction:transaction];
} @catch (NSException *exception) {
OWSProdLogAndFail(@"%@ Received an invalid envelope: %@", self.logTag, exception.debugDescription);
void (^reportFailure)(YapDatabaseReadWriteTransaction *transaction) = ^(
YapDatabaseReadWriteTransaction *transaction) {
// TODO: Add analytics.
TSErrorMessage *errorMessage = [TSErrorMessage corruptedMessageInUnknownThread];
[[TextSecureKitEnv sharedEnv].notificationsManager notifyUserForThreadlessErrorMessage:errorMessage
transaction:transaction];
};
@try {
SSKEnvelope *_Nullable envelope = job.envelope;
if (!envelope) {
reportFailure(transaction);
} else {
[self.messagesManager processEnvelope:envelope
plaintextData:job.plaintextData
transaction:transaction];
}
} @catch (NSException *exception) {
OWSProdLogAndFail(@"%@ Received an invalid envelope: %@", self.logTag, exception.debugDescription);
reportFailure(transaction);
}
[processedJobs addObject:job];

View File

@ -6,7 +6,7 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class SSKEnvelope;
@class YapDatabaseReadWriteTransaction;
typedef void (^DecryptSuccessBlock)(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction);
@ -22,7 +22,7 @@ typedef void (^DecryptFailureBlock)(void);
//
// Exactly one of successBlock & failureBlock will be called,
// once.
- (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)decryptEnvelope:(SSKEnvelope *)envelope
successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(DecryptFailureBlock)failureBlock;

View File

@ -22,6 +22,7 @@
#import "TextSecureKitEnv.h"
#import <AxolotlKit/AxolotlExceptions.h>
#import <AxolotlKit/SessionCipher.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
@ -80,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Blocking
- (BOOL)isEnvelopeBlocked:(OWSSignalServiceProtosEnvelope *)envelope
- (BOOL)isEnvelopeBlocked:(SSKEnvelope *)envelope
{
OWSAssert(envelope);
@ -89,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Decryption
- (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)decryptEnvelope:(SSKEnvelope *)envelope
successBlock:(DecryptSuccessBlock)successBlockParameter
failureBlock:(DecryptFailureBlock)failureBlockParameter
{
@ -128,7 +129,7 @@ NS_ASSUME_NONNULL_BEGIN
}
switch (envelope.type) {
case OWSSignalServiceProtosEnvelopeTypeCiphertext: {
case SSKEnvelopeTypeCiphertext: {
[self decryptSecureMessage:envelope
successBlock:^(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
DDLogDebug(@"%@ decrypted secure message.", self.logTag);
@ -145,7 +146,7 @@ NS_ASSUME_NONNULL_BEGIN
// Return to avoid double-acknowledging.
return;
}
case OWSSignalServiceProtosEnvelopeTypePrekeyBundle: {
case SSKEnvelopeTypePrekeyBundle: {
[self decryptPreKeyBundle:envelope
successBlock:^(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
DDLogDebug(@"%@ decrypted pre-key whisper message", self.logTag);
@ -164,9 +165,9 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
// These message types don't have a payload to decrypt.
case OWSSignalServiceProtosEnvelopeTypeReceipt:
case OWSSignalServiceProtosEnvelopeTypeKeyExchange:
case OWSSignalServiceProtosEnvelopeTypeUnknown: {
case SSKEnvelopeTypeReceipt:
case SSKEnvelopeTypeKeyExchange:
case SSKEnvelopeTypeUnknown: {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
successBlock(nil, transaction);
}];
@ -192,7 +193,7 @@ NS_ASSUME_NONNULL_BEGIN
failureBlock();
}
- (void)decryptSecureMessage:(OWSSignalServiceProtosEnvelope *)envelope
- (void)decryptSecureMessage:(SSKEnvelope *)envelope
successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(void (^)(NSError *_Nullable error))failureBlock
{
@ -209,7 +210,7 @@ NS_ASSUME_NONNULL_BEGIN
failureBlock:failureBlock];
}
- (void)decryptPreKeyBundle:(OWSSignalServiceProtosEnvelope *)envelope
- (void)decryptPreKeyBundle:(SSKEnvelope *)envelope
successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(void (^)(NSError *_Nullable error))failureBlock
{
@ -229,7 +230,7 @@ NS_ASSUME_NONNULL_BEGIN
failureBlock:failureBlock];
}
- (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)decryptEnvelope:(SSKEnvelope *)envelope
cipherTypeName:(NSString *)cipherTypeName
cipherMessageBlock:(id<CipherMessage> (^_Nonnull)(NSData *))cipherMessageBlock
successBlock:(DecryptSuccessBlock)successBlock
@ -245,8 +246,8 @@ NS_ASSUME_NONNULL_BEGIN
NSString *recipientId = envelope.source;
int deviceId = envelope.sourceDevice;
// DEPRECATED - Remove after all clients have been upgraded.
NSData *encryptedData = envelope.hasContent ? envelope.content : envelope.legacyMessage;
// DEPRECATED - Remove `legacyMessage` after all clients have been upgraded.
NSData *encryptedData = envelope.content ?: envelope.legacyMessage;
if (!encryptedData) {
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
failureBlock(nil);
@ -278,7 +279,7 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
- (void)processException:(NSException *)exception envelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)processException:(NSException *)exception envelope:(SSKEnvelope *)envelope
{
DDLogError(@"%@ Got exception: %@ of type: %@ with reason: %@",
self.logTag,
@ -325,7 +326,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)notifyUserForErrorMessage:(TSErrorMessage *)errorMessage
envelope:(OWSSignalServiceProtosEnvelope *)envelope
envelope:(SSKEnvelope *)envelope
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
TSThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:envelope.source transaction:transaction];

View File

@ -1,19 +1,19 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosContent;
@class OWSSignalServiceProtosDataMessage;
@class OWSSignalServiceProtosEnvelope;
@class SSKEnvelope;
NSString *envelopeAddress(OWSSignalServiceProtosEnvelope *envelope);
NSString *envelopeAddress(SSKEnvelope *envelope);
@interface OWSMessageHandler : NSObject
- (NSString *)descriptionForEnvelopeType:(OWSSignalServiceProtosEnvelope *)envelope;
- (NSString *)descriptionForEnvelope:(OWSSignalServiceProtosEnvelope *)envelope;
- (NSString *)descriptionForEnvelopeType:(SSKEnvelope *)envelope;
- (NSString *)descriptionForEnvelope:(SSKEnvelope *)envelope;
- (NSString *)descriptionForContent:(OWSSignalServiceProtosContent *)content;
- (NSString *)descriptionForDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage;

View File

@ -4,35 +4,36 @@
#import "OWSMessageHandler.h"
#import "OWSSignalServiceProtos.pb.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
// used in log formatting
NSString *envelopeAddress(OWSSignalServiceProtosEnvelope *envelope)
NSString *envelopeAddress(SSKEnvelope *envelope)
{
return [NSString stringWithFormat:@"%@.%d", envelope.source, (unsigned int)envelope.sourceDevice];
}
@implementation OWSMessageHandler
- (NSString *)descriptionForEnvelopeType:(OWSSignalServiceProtosEnvelope *)envelope
- (NSString *)descriptionForEnvelopeType:(SSKEnvelope *)envelope
{
OWSAssert(envelope != nil);
switch (envelope.type) {
case OWSSignalServiceProtosEnvelopeTypeReceipt:
case SSKEnvelopeTypeReceipt:
return @"DeliveryReceipt";
case OWSSignalServiceProtosEnvelopeTypeUnknown:
case SSKEnvelopeTypeUnknown:
// Shouldn't happen
OWSProdFail([OWSAnalyticsEvents messageManagerErrorEnvelopeTypeUnknown]);
return @"Unknown";
case OWSSignalServiceProtosEnvelopeTypeCiphertext:
case SSKEnvelopeTypeCiphertext:
return @"SignalEncryptedMessage";
case OWSSignalServiceProtosEnvelopeTypeKeyExchange:
case SSKEnvelopeTypeKeyExchange:
// Unsupported
OWSProdFail([OWSAnalyticsEvents messageManagerErrorEnvelopeTypeKeyExchange]);
return @"KeyExchange";
case OWSSignalServiceProtosEnvelopeTypePrekeyBundle:
case SSKEnvelopeTypePrekeyBundle:
return @"PreKeyEncryptedMessage";
default:
// Shouldn't happen
@ -41,7 +42,7 @@ NSString *envelopeAddress(OWSSignalServiceProtosEnvelope *envelope)
}
}
- (NSString *)descriptionForEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (NSString *)descriptionForEnvelope:(SSKEnvelope *)envelope
{
OWSAssert(envelope != nil);

View File

@ -6,7 +6,7 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class SSKEnvelope;
@class TSThread;
@class YapDatabaseReadWriteTransaction;
@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)sharedManager;
// processEnvelope: can be called from any thread.
- (void)processEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)processEnvelope:(SSKEnvelope *)envelope
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction;

View File

@ -47,6 +47,7 @@
#import "TSOutgoingMessage.h"
#import "TSQuotedMessage.h"
#import "TextSecureKitEnv.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabase.h>
NS_ASSUME_NONNULL_BEGIN
@ -157,7 +158,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Blocking
- (BOOL)isEnvelopeBlocked:(OWSSignalServiceProtosEnvelope *)envelope
- (BOOL)isEnvelopeBlocked:(SSKEnvelope *)envelope
{
OWSAssert(envelope);
@ -166,7 +167,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - message handling
- (void)processEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)processEnvelope:(SSKEnvelope *)envelope
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -188,8 +189,8 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(![self isEnvelopeBlocked:envelope]);
switch (envelope.type) {
case OWSSignalServiceProtosEnvelopeTypeCiphertext:
case OWSSignalServiceProtosEnvelopeTypePrekeyBundle:
case SSKEnvelopeTypeCiphertext:
case SSKEnvelopeTypePrekeyBundle:
if (plaintextData) {
[self handleEnvelope:envelope plaintextData:plaintextData transaction:transaction];
} else {
@ -197,15 +198,15 @@ NS_ASSUME_NONNULL_BEGIN
@"%@ missing decrypted data for envelope: %@", self.logTag, [self descriptionForEnvelope:envelope]);
}
break;
case OWSSignalServiceProtosEnvelopeTypeReceipt:
case SSKEnvelopeTypeReceipt:
OWSAssert(!plaintextData);
[self handleDeliveryReceipt:envelope transaction:transaction];
break;
// Other messages are just dismissed for now.
case OWSSignalServiceProtosEnvelopeTypeKeyExchange:
case SSKEnvelopeTypeKeyExchange:
DDLogWarn(@"Received Key Exchange Message, not supported");
break;
case OWSSignalServiceProtosEnvelopeTypeUnknown:
case SSKEnvelopeTypeUnknown:
DDLogWarn(@"Received an unknown message type");
break;
default:
@ -214,7 +215,7 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)handleDeliveryReceipt:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleDeliveryReceipt:(SSKEnvelope *)envelope
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(envelope);
@ -271,16 +272,16 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)handleEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleEnvelope:(SSKEnvelope *)envelope
plaintextData:(NSData *)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(envelope);
OWSAssert(plaintextData);
OWSAssert(transaction);
OWSAssert(envelope.hasTimestamp && envelope.timestamp > 0);
OWSAssert(envelope.hasSource && envelope.source.length > 0);
OWSAssert(envelope.hasSourceDevice && envelope.sourceDevice > 0);
OWSAssert(envelope.timestamp > 0);
OWSAssert(envelope.source.length > 0);
OWSAssert(envelope.sourceDevice > 0);
BOOL duplicateEnvelope = [self.incomingMessageFinder existsMessageWithTimestamp:envelope.timestamp
sourceId:envelope.source
@ -294,7 +295,7 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
if (envelope.hasContent) {
if (envelope.content != nil) {
OWSSignalServiceProtosContent *content = [OWSSignalServiceProtosContent parseFromData:plaintextData];
DDLogInfo(@"%@ handling content: <Content: %@>", self.logTag, [self descriptionForContent:content]);
@ -313,7 +314,7 @@ NS_ASSUME_NONNULL_BEGIN
} else {
DDLogWarn(@"%@ Ignoring envelope. Content with no known payload", self.logTag);
}
} else if (envelope.hasLegacyMessage) { // DEPRECATED - Remove after all clients have been upgraded.
} else if (envelope.legacyMessage != nil) { // DEPRECATED - Remove after all clients have been upgraded.
OWSSignalServiceProtosDataMessage *dataMessage =
[OWSSignalServiceProtosDataMessage parseFromData:plaintextData];
DDLogInfo(
@ -321,11 +322,11 @@ NS_ASSUME_NONNULL_BEGIN
[self handleIncomingEnvelope:envelope withDataMessage:dataMessage transaction:transaction];
} else {
OWSProdInfoWEnvelope([OWSAnalyticsEvents messageManagerErrorEnvelopeNoActionablePayload], envelope);
DDLogWarn(@"%@ Ignoring envelope with neither Content nor LegacyMessage", self.logTag);
}
}
- (void)handleIncomingEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleIncomingEnvelope:(SSKEnvelope *)envelope
withDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -394,7 +395,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)sendGroupInfoRequest:(NSData *)groupId
envelope:(OWSSignalServiceProtosEnvelope *)envelope
envelope:(SSKEnvelope *)envelope
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(groupId.length > 0);
@ -428,7 +429,7 @@ NS_ASSUME_NONNULL_BEGIN
return [TextSecureKitEnv sharedEnv].profileManager;
}
- (void)handleIncomingEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleIncomingEnvelope:(SSKEnvelope *)envelope
withReceiptMessage:(OWSSignalServiceProtosReceiptMessage *)receiptMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -463,7 +464,7 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)handleIncomingEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleIncomingEnvelope:(SSKEnvelope *)envelope
withCallMessage:(OWSSignalServiceProtosCallMessage *)callMessage
{
OWSAssert(envelope);
@ -498,7 +499,7 @@ NS_ASSUME_NONNULL_BEGIN
});
}
- (void)handleReceivedGroupAvatarUpdateWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleReceivedGroupAvatarUpdateWithEnvelope:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -536,7 +537,7 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
- (void)handleReceivedMediaWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleReceivedMediaWithEnvelope:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -584,7 +585,7 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
- (void)handleIncomingEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleIncomingEnvelope:(SSKEnvelope *)envelope
withSyncMessage:(OWSSignalServiceProtosSyncMessage *)syncMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -719,7 +720,7 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)handleEndSessionMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleEndSessionMessageWithEnvelope:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -736,7 +737,7 @@ NS_ASSUME_NONNULL_BEGIN
[self.primaryStorage deleteAllSessionsForContact:envelope.source protocolContext:transaction];
}
- (void)handleExpirationTimerUpdateMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleExpirationTimerUpdateMessageWithEnvelope:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -779,7 +780,7 @@ NS_ASSUME_NONNULL_BEGIN
[message saveWithTransaction:transaction];
}
- (void)handleProfileKeyMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleProfileKeyMessageWithEnvelope:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
{
OWSAssert(envelope);
@ -804,7 +805,7 @@ NS_ASSUME_NONNULL_BEGIN
[profileManager setProfileKeyData:profileKey forRecipientId:recipientId];
}
- (void)handleReceivedTextMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleReceivedTextMessageWithEnvelope:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -845,7 +846,7 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)handleGroupInfoRequest:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleGroupInfoRequest:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
@ -901,7 +902,7 @@ NS_ASSUME_NONNULL_BEGIN
[self sendGroupUpdateForThread:gThread message:message];
}
- (TSIncomingMessage *_Nullable)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (TSIncomingMessage *_Nullable)handleReceivedEnvelope:(SSKEnvelope *)envelope
withDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
attachmentIds:(NSArray<NSString *> *)attachmentIds
transaction:(YapDatabaseReadWriteTransaction *)transaction
@ -1083,7 +1084,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)finalizeIncomingMessage:(TSIncomingMessage *)incomingMessage
thread:(TSThread *)thread
envelope:(OWSSignalServiceProtosEnvelope *)envelope
envelope:(SSKEnvelope *)envelope
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(thread);
@ -1203,7 +1204,7 @@ NS_ASSUME_NONNULL_BEGIN
* Group or Contact thread for message, creating a new contact thread if necessary,
* but never creating a new group thread.
*/
- (nullable TSThread *)threadForEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (nullable TSThread *)threadForEnvelope:(SSKEnvelope *)envelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{

View File

@ -4,7 +4,6 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class OWSStorage;
// This class is used to write incoming (encrypted, unprocessed)
@ -18,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSString *)databaseExtensionName;
+ (void)asyncRegisterDatabaseExtension:(OWSStorage *)storage;
- (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope;
- (void)handleReceivedEnvelopeData:(NSData *)envelopeData;
- (void)handleAnyUnprocessedEnvelopesAsync;
@end

View File

@ -19,6 +19,7 @@
#import "TSYapDatabaseObject.h"
#import "TextSecureKitEnv.h"
#import "Threading.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabaseAutoView.h>
#import <YapDatabase/YapDatabaseConnection.h>
#import <YapDatabase/YapDatabaseTransaction.h>
@ -30,11 +31,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) NSDate *createdAt;
@property (nonatomic, readonly) NSData *envelopeData;
@property (nonatomic, readonly, nullable) SSKEnvelope *envelopeProto;
- (instancetype)initWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithEnvelopeData:(NSData *)envelopeData NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithUniqueId:(NSString *_Nullable)uniqueId NS_UNAVAILABLE;
- (OWSSignalServiceProtosEnvelope *)envelopeProto;
@end
@ -47,16 +48,16 @@ NS_ASSUME_NONNULL_BEGIN
return @"OWSMessageProcessingJob";
}
- (instancetype)initWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (instancetype)initWithEnvelopeData:(NSData *)envelopeData
{
OWSAssert(envelope);
OWSAssert(envelopeData);
self = [super initWithUniqueId:[NSUUID new].UUIDString];
if (!self) {
return self;
}
_envelopeData = envelope.data;
_envelopeData = envelopeData;
_createdAt = [NSDate new];
return self;
@ -67,9 +68,16 @@ NS_ASSUME_NONNULL_BEGIN
return [super initWithCoder:coder];
}
- (OWSSignalServiceProtosEnvelope *)envelopeProto
- (nullable SSKEnvelope *)envelopeProto
{
return [OWSSignalServiceProtosEnvelope parseFromData:self.envelopeData];
NSError *error;
SSKEnvelope *_Nullable envelope = [[SSKEnvelope alloc] initWithSerializedData:self.envelopeData error:&error];
if (error || envelope == nil) {
OWSFail(@"%@ failed to parase envelope with error: %@", self.logTag, error);
return nil;
}
return envelope;
}
@end
@ -123,10 +131,10 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
return job;
}
- (void)addJobForEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)addJobForEnvelopeData:(NSData *)envelopeData
{
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
OWSMessageDecryptJob *job = [[OWSMessageDecryptJob alloc] initWithEnvelope:envelope];
OWSMessageDecryptJob *job = [[OWSMessageDecryptJob alloc] initWithEnvelopeData:envelopeData];
[job saveWithTransaction:transaction];
}];
}
@ -265,9 +273,9 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
return queue;
}
- (void)enqueueEnvelopeForProcessing:(OWSSignalServiceProtosEnvelope *)envelope
- (void)enqueueEnvelopeData:(NSData *)envelopeData
{
[self.finder addJobForEnvelope:envelope];
[self.finder addJobForEnvelopeData:envelopeData];
}
- (void)drainQueue
@ -319,7 +327,7 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
AssertOnDispatchQueue(self.serialQueue);
OWSAssert(job);
OWSSignalServiceProtosEnvelope *_Nullable envelope = nil;
SSKEnvelope *_Nullable envelope = nil;
@try {
envelope = job.envelopeProto;
} @catch (NSException *exception) {
@ -441,11 +449,11 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
[self.processingQueue drainQueue];
}
- (void)handleReceivedEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)handleReceivedEnvelopeData:(NSData *)envelopeData
{
// Drop any too-large messages on the floor. Well behaving clients should never send them.
NSUInteger kMaxEnvelopeByteCount = 250 * 1024;
if (envelope.serializedSize > kMaxEnvelopeByteCount) {
if (envelopeData.length > kMaxEnvelopeByteCount) {
OWSProdError([OWSAnalyticsEvents messageReceiverErrorOversizeMessage]);
return;
}
@ -453,11 +461,11 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
// Take note of any messages larger than we expect, but still process them.
// This likely indicates a misbehaving sending client.
NSUInteger kLargeEnvelopeWarningByteCount = 25 * 1024;
if (envelope.serializedSize > kLargeEnvelopeWarningByteCount) {
if (envelopeData.length > kLargeEnvelopeWarningByteCount) {
OWSProdError([OWSAnalyticsEvents messageReceiverErrorLargeMessage]);
}
[self.processingQueue enqueueEnvelopeForProcessing:envelope];
[self.processingQueue enqueueEnvelopeData:envelopeData];
[self.processingQueue drainQueue];
}

View File

@ -747,10 +747,7 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
return;
}
OWSSignalServiceProtosEnvelope *envelope =
[OWSSignalServiceProtosEnvelope parseFromData:decryptedPayload];
[self.messageReceiver handleReceivedEnvelope:envelope];
[self.messageReceiver handleReceivedEnvelopeData:decryptedPayload];
} @catch (NSException *exception) {
OWSProdLogAndFail(@"%@ Received an invalid envelope: %@", self.logTag, exception.debugDescription);
// TODO: Add analytics.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
@objc
public class SSKEnvelope: NSObject {
enum EnvelopeError: Error {
case invalidProtobuf(description: String)
}
@objc
public enum SSKEnvelopeType: Int32 {
case unknown = 0
case ciphertext = 1
case keyExchange = 2
case prekeyBundle = 3
case receipt = 5
}
@objc
public let timestamp: UInt64
@objc
public let source: String
@objc
public let sourceDevice: UInt32
@objc
public let type: SSKEnvelopeType
@objc
public let relay: String?
@objc
public let content: Data?
@objc
public let legacyMessage: Data?
@objc
public init(timestamp: UInt64, source: String, sourceDevice: UInt32, type: SSKEnvelopeType, content: Data?, legacyMessage: Data?) {
self.source = source
self.type = type
self.timestamp = timestamp
self.sourceDevice = sourceDevice
self.relay = nil
self.content = content
self.legacyMessage = legacyMessage
}
@objc
public init(serializedData: Data) throws {
let proto: SignalService_Envelope = try SignalService_Envelope(serializedData: serializedData)
guard proto.hasSource else {
throw EnvelopeError.invalidProtobuf(description: "missing required field: source")
}
self.source = proto.source
guard proto.hasType else {
throw EnvelopeError.invalidProtobuf(description: "missing required field: type")
}
self.type = {
switch proto.type {
case .unknown:
return .unknown
case .ciphertext:
return .ciphertext
case .keyExchange:
return .keyExchange
case .prekeyBundle:
return .prekeyBundle
case .receipt:
return .receipt
}
}()
guard proto.hasTimestamp else {
throw EnvelopeError.invalidProtobuf(description: "missing required field: timestamp")
}
self.timestamp = proto.timestamp
guard proto.hasSourceDevice else {
throw EnvelopeError.invalidProtobuf(description: "missing required field: sourceDevice")
}
self.sourceDevice = proto.sourceDevice
if proto.hasContent {
self.content = proto.content
} else {
self.content = nil
}
if proto.hasLegacyMessage {
self.legacyMessage = proto.legacyMessage
} else {
self.legacyMessage = nil
}
if proto.relay.count > 0 {
self.relay = proto.relay
} else {
relay = nil
}
}
@objc
public func serializedData() throws -> Data {
return try self.asProtobuf.serializedData()
}
private var asProtobuf: SignalService_Envelope {
var proto = SignalService_Envelope()
proto.source = self.source
proto.type = {
switch self.type {
case .unknown:
return .unknown
case .ciphertext:
return .ciphertext
case .keyExchange:
return .keyExchange
case .prekeyBundle:
return .prekeyBundle
case .receipt:
return .receipt
}
}()
proto.timestamp = self.timestamp
proto.sourceDevice = self.sourceDevice
if let relay = self.relay {
proto.relay = relay
}
if let content = self.content {
proto.content = content
}
return proto
}
}