aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormanuroe <manu@matrix.org>2017-01-17 14:47:41 +0100
committermanuroe <manu@matrix.org>2017-01-17 14:47:41 +0100
commit885b85f5167d2d3ddcbe3de41dc88e8586b01a57 (patch)
treed9d05e75aa7fcf49584cb608ea284899c0eb2cd9
parent860740a91ee0efcf3c594ece23ef0a38ddda394e (diff)
OLMKit: Add wrappers for export/import of inbound group sessions
-rw-r--r--xcode/OLMKit/OLMInboundGroupSession.h10
-rw-r--r--xcode/OLMKit/OLMInboundGroupSession.m54
-rw-r--r--xcode/OLMKitTests/OLMKitGroupTests.m52
3 files changed, 115 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..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