Merge pull request #44 from matrix-org/manuroe/olmkit-backup

OLMKit: Add wrappers for export/import of inbound group sessions
This commit is contained in:
Richard van der Hoff 2017-01-17 15:16:16 +00:00 committed by GitHub
commit a45c3cc809
3 changed files with 116 additions and 1 deletions

View file

@ -22,9 +22,17 @@
- (instancetype)initInboundGroupSessionWithSessionKey:(NSString*)sessionKey error:(NSError**)error; - (instancetype)initInboundGroupSessionWithSessionKey:(NSString*)sessionKey error:(NSError**)error;
- (instancetype)initInboundGroupSessionWithImportedSession:(NSString*)sessionKey error:(NSError**)error;
- (NSString*)sessionIdentifier; - (NSString*)sessionIdentifier;
/** base64 ciphertext -> UTF-8 plaintext */ /** base64 ciphertext -> UTF-8 plaintext */
- (NSString*)decryptMessage:(NSString*)message messageIndex:(NSUInteger*)messageIndex error:(NSError**)error; - (NSString*)decryptMessage:(NSString*)message messageIndex:(NSUInteger*)messageIndex error:(NSError**)error;
- (NSUInteger)firstKnownIndex;
- (BOOL)isVerified;
- (NSString*)exportSessionAtMessageIndex:(NSUInteger*)messageIndex error:(NSError**)error;
@end @end

View file

@ -76,6 +76,33 @@
return self; 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 { - (NSString *)sessionIdentifier {
size_t length = olm_inbound_group_session_id_length(session); size_t length = olm_inbound_group_session_id_length(session);
NSMutableData *idData = [NSMutableData dataWithLength:length]; NSMutableData *idData = [NSMutableData dataWithLength:length];
@ -153,6 +180,34 @@
return plaintext; 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 #pragma mark OLMSerializable

View file

@ -91,4 +91,56 @@
XCTAssertEqualObjects(bobSession2.sessionIdentifier, aliceSession.sessionIdentifier); 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 @end