-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Encrypt rooms' last messages #1718
Changes from 12 commits
e4e7b2b
9b8b629
056afdd
1e1c243
e032582
9c2a2ce
10d4a6c
54aa4d9
7bc3e2e
6a5f3b9
e03289a
e6a0aee
3117c9c
a3a5ea9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
|
||
#import <Security/Security.h> | ||
#import <CommonCrypto/CommonCryptor.h> | ||
#import <Foundation/Foundation.h> | ||
|
||
NSString *const MXRoomLastMessageDataType = @"org.matrix.sdk.keychain.MXRoomLastMessage"; | ||
|
||
|
@@ -58,6 +59,27 @@ - (instancetype)initWithEvent:(MXEvent *)event | |
return self; | ||
} | ||
|
||
- (nullable NSData*)sensitiveData; | ||
{ | ||
NSError* error; | ||
NSData* archived = [NSKeyedArchiver archivedDataWithRootObject:[self sensitiveDataDictionary] | ||
requiringSecureCoding:NO | ||
error:&error]; | ||
|
||
if (error) { | ||
MXLogDebug(@"[MXRoomLastMessage] did fail to archive sensitiveDataDictionary. Error: %@", error.description); | ||
} | ||
|
||
if (archived && self.isEncrypted) | ||
{ | ||
return [self encrypt:archived]; | ||
} | ||
else | ||
{ | ||
return archived; | ||
} | ||
} | ||
|
||
- (NSComparisonResult)compareOriginServerTs:(MXRoomLastMessage *)otherMessage | ||
{ | ||
NSComparisonResult result = NSOrderedAscending; | ||
|
@@ -87,16 +109,39 @@ - (instancetype)initWithManagedObject:(MXRoomLastMessageMO *)model | |
_originServerTs = model.s_originServerTs; | ||
_isEncrypted = model.s_isEncrypted; | ||
_sender = model.s_sender; | ||
_text = model.s_text; | ||
if (model.s_attributedText) | ||
|
||
NSData* archivedSensitiveData; | ||
if (model.s_sensitiveData && model.s_isEncrypted) | ||
{ | ||
archivedSensitiveData = [self decrypt:model.s_sensitiveData]; | ||
} | ||
else | ||
{ | ||
_attributedText = [NSKeyedUnarchiver unarchiveObjectWithData:model.s_attributedText]; | ||
archivedSensitiveData = model.s_sensitiveData; | ||
} | ||
if (model.s_others) | ||
|
||
if (archivedSensitiveData) | ||
{ | ||
_others = [NSKeyedUnarchiver unarchiveObjectWithData:model.s_others]; | ||
NSDictionary* sensitiveDataDictionary = [NSKeyedUnarchiver unarchiveObjectWithData:archivedSensitiveData]; | ||
|
||
_text = sensitiveDataDictionary[kCodingKeyText]; | ||
_attributedText = sensitiveDataDictionary[kCodingKeyAttributedText]; | ||
_others = sensitiveDataDictionary[kCodingKeyOthers]; | ||
} | ||
else // fallback logic for old database versions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can completely avoid having to deal with old versions by incrementing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically I didn't change the |
||
{ | ||
_text = model.s_text; | ||
|
||
if (model.s_attributedText) { | ||
_attributedText = [NSKeyedUnarchiver unarchiveObjectWithData:model.s_attributedText]; | ||
} | ||
|
||
if (model.s_others) { | ||
_others = [NSKeyedUnarchiver unarchiveObjectWithData:model.s_others]; | ||
} | ||
} | ||
} | ||
|
||
return self; | ||
} | ||
|
||
|
@@ -142,20 +187,7 @@ - (void)encodeWithCoder:(NSCoder *)coder | |
[coder encodeObject:_sender forKey:kCodingKeySender]; | ||
|
||
// Build last message sensitive data | ||
NSMutableDictionary *lastMessageDictionary = [NSMutableDictionary dictionary]; | ||
if (_text) | ||
{ | ||
lastMessageDictionary[kCodingKeyText] = _text; | ||
} | ||
if (_attributedText) | ||
{ | ||
lastMessageDictionary[kCodingKeyAttributedText] = _attributedText; | ||
} | ||
if (_others) | ||
{ | ||
lastMessageDictionary[kCodingKeyOthers] = _others; | ||
} | ||
|
||
NSDictionary *lastMessageDictionary = [self sensitiveDataDictionary]; | ||
// And encrypt it if necessary | ||
if (_isEncrypted) | ||
{ | ||
|
@@ -173,6 +205,26 @@ - (void)encodeWithCoder:(NSCoder *)coder | |
} | ||
} | ||
|
||
- (NSDictionary*)sensitiveDataDictionary | ||
{ | ||
NSMutableDictionary *lastMessageDictionary = [NSMutableDictionary dictionary]; | ||
|
||
if (_text) | ||
{ | ||
lastMessageDictionary[kCodingKeyText] = _text; | ||
} | ||
if (_attributedText) | ||
{ | ||
lastMessageDictionary[kCodingKeyAttributedText] = _attributedText; | ||
} | ||
if (_others) | ||
{ | ||
lastMessageDictionary[kCodingKeyOthers] = _others; | ||
} | ||
|
||
return lastMessageDictionary; | ||
} | ||
|
||
#pragma mark - Data encryption | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Encryption: add encryption to rooms' last messages. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For future reference: errors are best logged via
MXLogErrorDetails
which will also send them to Sentry (if enabled), or evenMXLogFailureDetails
if we do not expect this error to ever occur