From 885b85f5167d2d3ddcbe3de41dc88e8586b01a57 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 17 Jan 2017 14:47:41 +0100 Subject: [PATCH] OLMKit: Add wrappers for export/import of inbound group sessions --- xcode/OLMKit/OLMInboundGroupSession.h | 10 ++++- xcode/OLMKit/OLMInboundGroupSession.m | 54 +++++++++++++++++++++++++++ xcode/OLMKitTests/OLMKitGroupTests.m | 52 ++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) 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 -- (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..3ef02e8 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,33 @@ 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]; + 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