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:
commit
a45c3cc809
3 changed files with 116 additions and 1 deletions
|
@ -20,11 +20,19 @@
|
||||||
|
|
||||||
@interface OLMInboundGroupSession : NSObject <OLMSerializable, NSSecureCoding>
|
@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;
|
- (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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue