diff options
author | Richard van der Hoff <github@rvanderhoff.org.uk> | 2017-01-17 15:16:16 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-17 15:16:16 +0000 |
commit | a45c3cc80957d61065626089eee4ce664ad1615f (patch) | |
tree | c467aafb4df13fc31576e49a7909cc2fe2088328 /xcode | |
parent | c14f4b28b985a3ca8f8ff4218c7a2a74cf65a580 (diff) | |
parent | ded15597c6736d33bac74d34251c8527e5fa360f (diff) |
Merge pull request #44 from matrix-org/manuroe/olmkit-backup
OLMKit: Add wrappers for export/import of inbound group sessions
Diffstat (limited to 'xcode')
-rw-r--r-- | xcode/OLMKit/OLMInboundGroupSession.h | 10 | ||||
-rw-r--r-- | xcode/OLMKit/OLMInboundGroupSession.m | 55 | ||||
-rw-r--r-- | xcode/OLMKitTests/OLMKitGroupTests.m | 52 |
3 files changed, 116 insertions, 1 deletions
diff --git a/xcode/OLMKit/OLMInboundGroupSession.h b/xcode/OLMKit/OLMInboundGroupSession.h index ede68e3..e0cd961 100644 --- a/xcode/OLMKit/OLMInboundGroupSession.h +++ b/xcode/OLMKit/OLMInboundGroupSession.h @@ -20,11 +20,19 @@ @interface OLMInboundGroupSession : NSObject <OLMSerializable, NSSecureCoding> -- (instancetype) initInboundGroupSessionWithSessionKey:(NSString*)sessionKey error:(NSError**)error; +- (instancetype)initInboundGroupSessionWithSessionKey:(NSString*)sessionKey error:(NSError**)error; + +- (instancetype)initInboundGroupSessionWithImportedSession:(NSString*)sessionKey error:(NSError**)error; - (NSString*)sessionIdentifier; /** base64 ciphertext -> UTF-8 plaintext */ - (NSString*)decryptMessage:(NSString*)message messageIndex:(NSUInteger*)messageIndex error:(NSError**)error; +- (NSUInteger)firstKnownIndex; + +- (BOOL)isVerified; + +- (NSString*)exportSessionAtMessageIndex:(NSUInteger*)messageIndex error:(NSError**)error; + @end diff --git a/xcode/OLMKit/OLMInboundGroupSession.m b/xcode/OLMKit/OLMInboundGroupSession.m index 6ef51c3..08459ca 100644 --- a/xcode/OLMKit/OLMInboundGroupSession.m +++ b/xcode/OLMKit/OLMInboundGroupSession.m @@ -76,6 +76,33 @@ return self; } +- (instancetype)initInboundGroupSessionWithImportedSession:(NSString *)sessionKey error:(NSError *__autoreleasing *)error +{ + self = [self init]; + if (self) { + NSData *sessionKeyData = [sessionKey dataUsingEncoding:NSUTF8StringEncoding]; + size_t result = olm_import_inbound_group_session(session, sessionKeyData.bytes, sessionKeyData.length); + if (result == olm_error()) { + const char *olm_error = olm_inbound_group_session_last_error(session); + + NSString *errorString = [NSString stringWithUTF8String:olm_error]; + NSLog(@"olm_import_inbound_group_session error: %@", errorString); + + if (error && olm_error && errorString) { + *error = [NSError errorWithDomain:OLMErrorDomain + code:0 + userInfo:@{ + NSLocalizedDescriptionKey: errorString, + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_import_inbound_group_session error: %@", errorString] + }]; + } + + return nil; + } + } + return self; +} + - (NSString *)sessionIdentifier { size_t length = olm_inbound_group_session_id_length(session); NSMutableData *idData = [NSMutableData dataWithLength:length]; @@ -153,6 +180,34 @@ return plaintext; } +- (NSUInteger)firstKnownIndex +{ + return olm_inbound_group_session_first_known_index(session); +} + +- (BOOL)isVerified +{ + return (0 != olm_inbound_group_session_is_verified(session)); +} + +- (NSString*)exportSessionAtMessageIndex:(NSUInteger*)messageIndex error:(NSError**)error; +{ + size_t length = olm_export_inbound_group_session_length(session); + NSMutableData *key = [NSMutableData dataWithLength:length]; + size_t result = olm_export_inbound_group_session(session, key.mutableBytes, key.length, messageIndex); + if (result == olm_error()) { + const char *olm_error = olm_inbound_group_session_last_error(session); + NSString *errorString = [NSString stringWithUTF8String:olm_error]; + if (error && errorString) { + *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; + } + return nil; + } + NSString *keyString = [[NSString alloc] initWithData:key encoding:NSUTF8StringEncoding]; + [key resetBytesInRange:NSMakeRange(0, key.length)]; + return keyString; +} + #pragma mark OLMSerializable diff --git a/xcode/OLMKitTests/OLMKitGroupTests.m b/xcode/OLMKitTests/OLMKitGroupTests.m index ea82295..39ad400 100644 --- a/xcode/OLMKitTests/OLMKitGroupTests.m +++ b/xcode/OLMKitTests/OLMKitGroupTests.m @@ -91,4 +91,56 @@ XCTAssertEqualObjects(bobSession2.sessionIdentifier, aliceSession.sessionIdentifier); } +- (void)testInboundGroupSessionImportExport { + + NSError *error; + + NSString *sessionKey = @"AgAAAAAwMTIzNDU2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMzQ1Njc4OUFCREVGM" \ + "DEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkRFRjAxMjM0NTY3ODlBQkNERUYwMTIzND" \ + "U2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMw0bdg1BDq4Px/slBow06q8n/B9WBfw" \ + "WYyNOB8DlUmXGGwrFmaSb9bR/eY8xgERrxmP07hFmD9uqA2p8PMHdnV5ysmgufE6oLZ5+" \ + "8/mWQOW3VVTnDIlnwd8oHUYRuk8TCQ"; + + NSString *message = @"AwgAEhAcbh6UpbByoyZxufQ+h2B+8XHMjhR69G8F4+qjMaFlnIXusJZX3r8LnRORG9T3D" \ + "XFdbVuvIWrLyRfm4i8QRbe8VPwGRFG57B1CtmxanuP8bHtnnYqlwPsD"; + + // init first inbound group session, and decrypt */ + OLMInboundGroupSession *session1 = [[OLMInboundGroupSession alloc] initInboundGroupSessionWithSessionKey:sessionKey error:&error]; + + XCTAssertNil(error); + XCTAssertTrue(session1.isVerified); + + // decrypt the message + NSUInteger messageIndex; + NSString *plaintext = [session1 decryptMessage:message messageIndex:&messageIndex error:&error]; + + XCTAssertNil(error); + XCTAssertEqualObjects(plaintext, @"Message"); + XCTAssertEqual(messageIndex, 0); + + // export the keys + NSString *export = [session1 exportSessionAtMessageIndex:0 error:&error]; + + XCTAssertNil(error); + XCTAssertGreaterThan(export.length, 0); + + // free the old session to check there is no shared data + session1 = nil; + + // import the keys into another inbound group session + OLMInboundGroupSession *session2 = [[OLMInboundGroupSession alloc] initInboundGroupSessionWithImportedSession:export error:&error]; + + XCTAssertNil(error); + XCTAssert(session2); + XCTAssertFalse(session2.isVerified); + + // decrypt the message with the new session + NSString *plaintext2 = [session2 decryptMessage:message messageIndex:&messageIndex error:&error]; + + XCTAssertNil(error); + XCTAssertEqualObjects(plaintext2, @"Message"); + XCTAssertEqual(messageIndex, 0); + XCTAssertTrue(session2.isVerified); +} + @end |