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>
|
||||
|
||||
- (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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue