Skip to content

Commit

Permalink
element-hq/element-ios/issues/4255 - Added fallback keys to the dehyd…
Browse files Browse the repository at this point in the history
…rated device. Removed unused dehydration key.
  • Loading branch information
stefanceriu committed Sep 17, 2021
1 parent 175c34c commit 596370e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 25 deletions.
3 changes: 0 additions & 3 deletions MatrixSDK/Crypto/Dehydration/MXDehydrationService.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@

NS_ASSUME_NONNULL_BEGIN

/// MXKeyProvider identifier for a 32 bytes long key used to pickle / unpickle the account of the dehydrated device.
FOUNDATION_EXPORT NSString *const MXDehydrationServiceKeyDataType;

/// Error domain for this class.
FOUNDATION_EXPORT NSString *const MXDehydrationServiceErrorDomain;

Expand Down
60 changes: 39 additions & 21 deletions MatrixSDK/Crypto/Dehydration/MXDehydrationService.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#import "MXKey.h"

NSString *const MXDehydrationAlgorithm = @"org.matrix.msc2697.v1.olm.libolm_pickle";
NSString *const MXDehydrationServiceKeyDataType = @"org.matrix.sdk.dehydration.service.key";
NSString *const MXDehydrationServiceErrorDomain = @"org.matrix.sdk.dehydration.service";

@interface MXDehydrationService ()
Expand Down Expand Up @@ -62,8 +61,8 @@ - (void)dehydrateDeviceWithMatrixRestClient:(MXRestClient*)restClient

NSUInteger maxKeys = [account maxOneTimeKeys];
[account generateOneTimeKeys:maxKeys / 2];

// TODO: [account generateFallbackKey];
[account generateFallbackKey];

MXLogDebug(@"[MXDehydrationService] dehydrateDevice: Account created %@", account.identityKeys);

Expand Down Expand Up @@ -210,27 +209,20 @@ - (void)uploadDeviceInfo:(MXDeviceInfo*)deviceInfo
{
MXLogDebug(@"[MXDehydrationService] uploadDeviceInfo: preparing one time keys");

NSDictionary *oneTimeKeys = account.oneTimeKeys;
NSMutableDictionary *oneTimeJson = [NSMutableDictionary dictionary];
NSDictionary *oneTimeKeys = [self signKeys:account.oneTimeKeys
withAccount:account
userId:restClient.credentials.userId
deviceId:deviceInfo.deviceId];

for (NSString *keyId in oneTimeKeys[kMXKeyCurve25519Type])
{
// Sign each one-time key
NSMutableDictionary *key = [NSMutableDictionary dictionary];
key[@"key"] = oneTimeKeys[kMXKeyCurve25519Type][keyId];

NSString *signature = [account signMessage:[MXCryptoTools canonicalJSONDataForJSON:key]];
key[@"signatures"] = @{
restClient.credentials.userId: @{
[NSString stringWithFormat:@"%@:%@", kMXKeyEd25519Type, deviceInfo.deviceId]: signature
}
};

oneTimeJson[[NSString stringWithFormat:@"signed_curve25519:%@", keyId]] = key;
}
MXLogDebug(@"[MXDehydrationService] uploadDeviceInfo: preparing fallback keys");

NSDictionary *fallbackKeys = [self signKeys:account.fallbackKey
withAccount:account
userId:restClient.credentials.userId
deviceId:deviceInfo.deviceId];

MXWeakify(self);
[restClient uploadKeys:deviceInfo.JSONDictionary oneTimeKeys:oneTimeJson fallbackKeys:nil forDeviceWithId:deviceInfo.deviceId success:^(MXKeysUploadResponse *keysUploadResponse) {
[restClient uploadKeys:deviceInfo.JSONDictionary oneTimeKeys:oneTimeKeys fallbackKeys:fallbackKeys forDeviceWithId:deviceInfo.deviceId success:^(MXKeysUploadResponse *keysUploadResponse) {
[account markOneTimeKeysAsPublished];
MXLogDebug(@"[MXDehydrationService] uploadDeviceInfo: dehydration done successfully with device ID: %@ ed25519: %@ curve25519: %@", deviceInfo.deviceId, account.identityKeys[kMXKeyEd25519Type], account.identityKeys[kMXKeyCurve25519Type]);
MXStrongifyAndReturnIfNil(self);
Expand All @@ -251,4 +243,30 @@ - (void)stopProgress
self.inProgress = NO;
}

- (NSDictionary *)signKeys:(NSDictionary *)keys
withAccount:(OLMAccount *)account
userId:(NSString *)userId
deviceId:(NSString *)deviceId

{
NSMutableDictionary *signedKeys = [NSMutableDictionary dictionary];

for (NSString *keyId in keys[kMXKeyCurve25519Type])
{
NSMutableDictionary *key = [NSMutableDictionary dictionary];
key[@"key"] = keys[kMXKeyCurve25519Type][keyId];

NSString *signature = [account signMessage:[MXCryptoTools canonicalJSONDataForJSON:key]];
key[@"signatures"] = @{
userId: @{
[NSString stringWithFormat:@"%@:%@", kMXKeyEd25519Type, deviceId]: signature
}
};

signedKeys[[NSString stringWithFormat:@"%@:%@", kMXKeySignedCurve25519Type, keyId]] = key;
}

return signedKeys;
}

@end
11 changes: 11 additions & 0 deletions MatrixSDKTests/MXDehydrationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,12 @@ -(void)testDataPickling
OLMAccount *account = [[OLMAccount alloc] initNewAccount];
NSDictionary *e2eKeys = [account identityKeys];

[account generateOneTimeKeys:50];
NSDictionary *oneTimeKeys = [account oneTimeKeys];

[account generateFallbackKey];
NSDictionary *fallbackKey = [account fallbackKey];

// - pickle the OLM account
NSData *key = [@"6fXK17pQFUrFqOnxt3wrqz8RHkQUT9vQ" dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
Expand All @@ -473,11 +479,16 @@ -(void)testDataPickling
// - unpickle the pickled account
OLMAccount *deserializedAccount = [[OLMAccount alloc] initWithSerializedData:serializedAccount key:key error:&error];
NSDictionary *deserializedE2eKeys = [deserializedAccount identityKeys];
NSDictionary *deserializedOneTimeKeys = [deserializedAccount oneTimeKeys];
NSDictionary *deserializedFallbackKey = [deserializedAccount fallbackKey];

// -> identity keys must be the same
XCTAssertNil(error, "initWithSerializedData failed due to error %@", error);
XCTAssert([e2eKeys[@"ed25519"] isEqual:deserializedE2eKeys[@"ed25519"]], @"wrong deserialized ed25519 key %@ != %@", e2eKeys[@"ed25519"], deserializedE2eKeys[@"ed25519"]);
XCTAssert([e2eKeys[@"curve25519"] isEqual:deserializedE2eKeys[@"curve25519"]], @"wrong deserialized curve25519 key %@ != %@", e2eKeys[@"curve25519"], deserializedE2eKeys[@"curve25519"]);

XCTAssert([oneTimeKeys isEqualToDictionary:deserializedOneTimeKeys]);
XCTAssert([fallbackKey isEqualToDictionary:deserializedFallbackKey]);
}

#pragma mark - Private methods
Expand Down
2 changes: 1 addition & 1 deletion changelog.d/4255.change
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Sign dehydrated device info with the MSK.
Add fallback keys to the dehydrated device info and sign it with the MSK.

0 comments on commit 596370e

Please sign in to comment.