forked from ChatSecure/SignalProtocol-ObjC
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix ChatSecure#4: Add encryption for group messaging
Co-Authored-By: Matthew Di Pasquale <[email protected]>
- Loading branch information
1 parent
6c85308
commit 41879ac
Showing
17 changed files
with
418 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
@import Foundation; | ||
#import "SignalContext.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalSenderKeyDistributionMessage : NSObject | ||
|
||
- (nullable instancetype)initWithData:(NSData *)data | ||
context:(SignalContext *)context | ||
error:(NSError **)error; | ||
|
||
- (NSData *)serializedData; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#import "SignalSenderKeyDistributionMessage_Internal.h" | ||
#import "SignalContext_Internal.h" | ||
#import "SignalError.h" | ||
|
||
@implementation SignalSenderKeyDistributionMessage | ||
|
||
- (void)dealloc { | ||
if (_sender_key_distribution_message) { | ||
SIGNAL_UNREF(_sender_key_distribution_message); | ||
} | ||
} | ||
|
||
- (instancetype)initWithSenderKeyDistributionMessage:(sender_key_distribution_message *)sender_key_distribution_message { | ||
NSParameterAssert(sender_key_distribution_message); | ||
if (!sender_key_distribution_message) { return nil; } | ||
if (self = [super init]) { | ||
_sender_key_distribution_message = sender_key_distribution_message; | ||
} | ||
return self; | ||
} | ||
|
||
- (instancetype)initWithData:(NSData *)data | ||
context:(SignalContext *)context | ||
error:(NSError **)error { | ||
NSParameterAssert(data); | ||
NSParameterAssert(context); | ||
if (!data || !context) { | ||
if (error) { | ||
*error = ErrorFromSignalError(SignalErrorInvalidArgument); | ||
} | ||
return nil; | ||
} | ||
if (self = [super init]) { | ||
int result = sender_key_distribution_message_deserialize(&_sender_key_distribution_message, data.bytes, data.length, context.context); | ||
if (result < 0 || !_sender_key_distribution_message) { | ||
if (error) { | ||
*error = ErrorFromSignalError(SignalErrorFromCode(result)); | ||
} | ||
return nil; | ||
} | ||
} | ||
return self; | ||
} | ||
|
||
- (NSData *)serializedData { | ||
ciphertext_message *message = (ciphertext_message *)_sender_key_distribution_message; | ||
signal_buffer *serialized = ciphertext_message_get_serialized(message); | ||
return [NSData dataWithBytes:signal_buffer_data(serialized) length:signal_buffer_len(serialized)]; | ||
} | ||
|
||
@end |
14 changes: 14 additions & 0 deletions
14
Classes/Models/SignalSenderKeyDistributionMessage_Internal.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#import "SignalSenderKeyDistributionMessage.h" | ||
@import SignalProtocolC; | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalSenderKeyDistributionMessage () | ||
|
||
@property (readonly, nonatomic) sender_key_distribution_message *sender_key_distribution_message; | ||
|
||
- (instancetype)initWithSenderKeyDistributionMessage:(sender_key_distribution_message *)sender_key_distribution_message; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
@import Foundation; | ||
#import "SignalContext.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalSenderKeyMessage : NSObject | ||
|
||
- (nullable instancetype)initWithData:(NSData *)data | ||
context:(SignalContext *)context | ||
error:(NSError **)error; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#import "SignalSenderKeyMessage_Internal.h" | ||
#import "SignalContext_Internal.h" | ||
#import "SignalError.h" | ||
|
||
@implementation SignalSenderKeyMessage | ||
|
||
- (void)dealloc { | ||
if (_sender_key_message) { | ||
SIGNAL_UNREF(_sender_key_message); | ||
} | ||
} | ||
|
||
- (instancetype)initWithData:(NSData *)data | ||
context:(SignalContext *)context | ||
error:(NSError **)error { | ||
NSParameterAssert(data); | ||
NSParameterAssert(context); | ||
if (!data || !context) { | ||
if (error) { | ||
*error = ErrorFromSignalError(SignalErrorInvalidArgument); | ||
} | ||
return nil; | ||
} | ||
if (self = [super init]) { | ||
int result = sender_key_message_deserialize(&_sender_key_message, data.bytes, data.length, context.context); | ||
if (result < 0 || !_sender_key_message) { | ||
if (error) { | ||
*error = ErrorFromSignalError(SignalErrorFromCode(result)); | ||
} | ||
return nil; | ||
} | ||
} | ||
return self; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#import "SignalSenderKeyMessage.h" | ||
@import SignalProtocolC; | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalSenderKeyMessage () | ||
|
||
@property (readonly, nonatomic) sender_key_message *sender_key_message; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#import "SignalAddress.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalSenderKeyName : NSObject | ||
|
||
@property (readonly, copy, nonatomic) NSString *groupId; | ||
@property (readonly, nonatomic) SignalAddress *address; | ||
|
||
- (instancetype)initWithGroupId:(NSString *)groupId address:(SignalAddress *)address; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#import "SignalSenderKeyName_Internal.h" | ||
#import "SignalAddress_Internal.h" | ||
|
||
@implementation SignalSenderKeyName | ||
|
||
- (void)dealloc { | ||
if (_sender_key_name) { | ||
free((void *)_sender_key_name->group_id); | ||
free(_sender_key_name); | ||
} | ||
} | ||
|
||
- (instancetype)initWithGroupId:(NSString *)groupId address:(SignalAddress *)address { | ||
NSParameterAssert(groupId); | ||
NSParameterAssert(address); | ||
if (!groupId || !address) { return nil; } | ||
if (self = [super init]) { | ||
_groupId = [groupId copy]; | ||
_address = address; | ||
_sender_key_name = malloc(sizeof(signal_protocol_sender_key_name)); | ||
_sender_key_name->group_id = strdup([groupId UTF8String]); | ||
_sender_key_name->group_id_len = [groupId lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; | ||
_sender_key_name->sender = *(address.address); | ||
} | ||
return self; | ||
} | ||
|
||
- (instancetype)initWithSenderKeyName:(const signal_protocol_sender_key_name *)sender_key_name { | ||
NSParameterAssert(sender_key_name); | ||
NSParameterAssert(sender_key_name->group_id); | ||
if (!sender_key_name || !sender_key_name->group_id) { return nil; } | ||
NSString *groupId = [NSString stringWithUTF8String:sender_key_name->group_id]; | ||
SignalAddress *address = [[SignalAddress alloc] initWithAddress:&sender_key_name->sender]; | ||
if (self = [self initWithGroupId:groupId address:address]) { | ||
} | ||
return self; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#import "SignalSenderKeyName.h" | ||
@import SignalProtocolC; | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalSenderKeyName () | ||
|
||
@property (readonly, nonatomic) signal_protocol_sender_key_name *sender_key_name; | ||
|
||
- (nullable instancetype)initWithSenderKeyName:(const signal_protocol_sender_key_name *)sender_key_name; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
@import Foundation; | ||
#import "SignalCiphertext.h" | ||
#import "SignalContext.h" | ||
#import "SignalSenderKeyName.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalGroupCipher : NSObject | ||
|
||
@property (readonly, nonatomic) SignalContext *context; | ||
|
||
- (instancetype)initWithSenderKeyName:(SignalSenderKeyName *)senderKeyName | ||
context:(SignalContext *)context; | ||
|
||
- (nullable SignalCiphertext *)encryptData:(NSData *)data error:(NSError **)error; | ||
- (nullable NSData *)decryptCiphertext:(SignalCiphertext *)ciphertext error:(NSError **)error; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#import "SignalGroupCipher.h" | ||
#import "SignalContext_Internal.h" | ||
#import "SignalError.h" | ||
#import "SignalSenderKeyMessage_Internal.h" | ||
#import "SignalSenderKeyName_Internal.h" | ||
#import "SignalStorage_Internal.h" | ||
|
||
@interface SignalGroupCipher () | ||
@property (readonly, nonatomic) group_cipher *cipher; | ||
@end | ||
|
||
@implementation SignalGroupCipher | ||
|
||
- (instancetype)initWithSenderKeyName:(SignalSenderKeyName *)senderKeyName | ||
context:(SignalContext *)context { | ||
NSParameterAssert(senderKeyName); | ||
NSParameterAssert(context); | ||
if (!senderKeyName || !context) { return nil; } | ||
if (self = [super init]) { | ||
_context = context; | ||
int result = group_cipher_create(&_cipher, context.storage.storeContext, senderKeyName.sender_key_name, context.context); | ||
NSAssert(result >= 0 && _cipher, @"couldn't create cipher"); | ||
if (result < 0 || !_cipher) { | ||
return nil; | ||
} | ||
} | ||
return self; | ||
} | ||
|
||
- (SignalCiphertext *)encryptData:(NSData *)data error:(NSError **)error { | ||
NSParameterAssert(data); | ||
if (!data) { | ||
if (error) { | ||
*error = ErrorFromSignalError(SignalErrorInvalidArgument); | ||
} | ||
return nil; | ||
} | ||
ciphertext_message *message = NULL; | ||
int result = group_cipher_encrypt(_cipher, data.bytes, data.length, &message); | ||
if (result < 0 || !message) { | ||
*error = ErrorFromSignalError(SignalErrorFromCode(result)); | ||
return nil; | ||
} | ||
signal_buffer *serialized = ciphertext_message_get_serialized(message); | ||
NSData *outData = [NSData dataWithBytes:signal_buffer_data(serialized) length:signal_buffer_len(serialized)]; | ||
SignalCiphertextType outType = SignalCiphertextTypeSenderKeyMessage; | ||
SignalCiphertext *encrypted = [[SignalCiphertext alloc] initWithData:outData type:outType]; | ||
SIGNAL_UNREF(message); | ||
return encrypted; | ||
} | ||
|
||
- (nullable NSData *)decryptCiphertext:(SignalCiphertext *)ciphertext error:(NSError **)error { | ||
NSParameterAssert(ciphertext && ciphertext.data); | ||
if (!ciphertext || !ciphertext.data) { | ||
if (error) { | ||
*error = ErrorFromSignalError(SignalErrorInvalidArgument); | ||
} | ||
return nil; | ||
} | ||
SignalSenderKeyMessage *message = [[SignalSenderKeyMessage alloc] initWithData:ciphertext.data context:_context error:error]; | ||
if (!message) { return nil; } | ||
signal_buffer *buffer = NULL; | ||
int result = SG_ERR_UNKNOWN; | ||
result = group_cipher_decrypt(_cipher, message.sender_key_message, NULL, &buffer); | ||
if (result < 0 || !buffer) { | ||
if (error) { | ||
*error = ErrorFromSignalError(SignalErrorFromCode(result)); | ||
} | ||
return nil; | ||
} | ||
NSData *outData = [NSData dataWithBytes:signal_buffer_data(buffer) length:signal_buffer_len(buffer)]; | ||
signal_buffer_free(buffer); | ||
return outData; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
@import Foundation; | ||
#import "SignalContext.h" | ||
#import "SignalSenderKeyDistributionMessage.h" | ||
#import "SignalSenderKeyName.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface SignalGroupSessionBuilder : NSObject | ||
|
||
@property (readonly, nonatomic) SignalContext *context; | ||
|
||
- (instancetype)initWithContext:(SignalContext *)context; | ||
|
||
- (BOOL)processSessionWithSenderKeyName:(SignalSenderKeyName *)senderKeyName | ||
senderKeyDistributionMessage:(SignalSenderKeyDistributionMessage *)senderKeyDistributionMessage | ||
error:(NSError **)error; | ||
- (nullable SignalSenderKeyDistributionMessage *)createSessionWithSenderKeyName:(SignalSenderKeyName *)senderKeyName | ||
error:(NSError **)error; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
Oops, something went wrong.