OLMKit: New pickle version using a pickle key provided externally

Improve ObjC wrappers so that they can use a pickle key provided by the olm lib user.

This new behavior is optional to not break existing usage.

It is retro compatible and use pickle versioning already in place. 
Existing key will be unpickled with pickle v1 and pickled with pickle v2 if an external pickle key is provided.
This commit is contained in:
manuroe 2021-02-18 14:57:43 +01:00
parent c01164f001
commit b69b56d0bb
6 changed files with 122 additions and 20 deletions

View file

@ -21,6 +21,7 @@
#import "OLMSession.h" #import "OLMSession.h"
#import "OLMSession_Private.h" #import "OLMSession_Private.h"
#import "OLMUtility.h" #import "OLMUtility.h"
#import "OLMKit.h"
@import Security; @import Security;
@ -243,6 +244,13 @@
self = [self initWithSerializedData:pickle key:key error:&error]; self = [self initWithSerializedData:pickle key:key error:&error];
} }
else if ([version isEqualToString:@"2"]) {
NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"];
NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
NSParameterAssert(key);
self = [self initWithSerializedData:pickle key:key error:&error];
}
NSParameterAssert(error == nil); NSParameterAssert(error == nil);
NSParameterAssert(self != nil); NSParameterAssert(self != nil);
@ -254,14 +262,23 @@
} }
- (void)encodeWithCoder:(NSCoder *)encoder { - (void)encodeWithCoder:(NSCoder *)encoder {
NSData *key = [OLMUtility randomBytesOfLength:32]; NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
if (key)
{
[encoder encodeObject:@"2" forKey:@"version"];
}
else
{
key = [OLMUtility randomBytesOfLength:32];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
}
NSError *error = nil; NSError *error = nil;
NSString *pickle = [self serializeDataWithKey:key error:&error]; NSString *pickle = [self serializeDataWithKey:key error:&error];
NSParameterAssert(pickle.length > 0 && error == nil); NSParameterAssert(pickle.length > 0 && error == nil);
[encoder encodeObject:pickle forKey:@"pickle"]; [encoder encodeObject:pickle forKey:@"pickle"];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
} }

View file

@ -19,6 +19,7 @@
#import "OLMUtility.h" #import "OLMUtility.h"
#include "olm/olm.h" #include "olm/olm.h"
#import "OLMKit.h"
@interface OLMInboundGroupSession () @interface OLMInboundGroupSession ()
{ {
@ -277,7 +278,14 @@
self = [self initWithSerializedData:pickle key:key error:&error]; self = [self initWithSerializedData:pickle key:key error:&error];
} }
else if ([version isEqualToString:@"2"]) {
NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"];
NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
NSParameterAssert(key);
self = [self initWithSerializedData:pickle key:key error:&error];
}
NSParameterAssert(error == nil); NSParameterAssert(error == nil);
NSParameterAssert(self != nil); NSParameterAssert(self != nil);
if (!self) { if (!self) {
@ -288,14 +296,23 @@
} }
- (void)encodeWithCoder:(NSCoder *)encoder { - (void)encodeWithCoder:(NSCoder *)encoder {
NSData *key = [OLMUtility randomBytesOfLength:32]; NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
if (key)
{
[encoder encodeObject:@"2" forKey:@"version"];
}
else
{
key = [OLMUtility randomBytesOfLength:32];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
}
NSError *error = nil; NSError *error = nil;
NSString *pickle = [self serializeDataWithKey:key error:&error]; NSString *pickle = [self serializeDataWithKey:key error:&error];
NSParameterAssert(pickle.length > 0 && error == nil); NSParameterAssert(pickle.length > 0 && error == nil);
[encoder encodeObject:pickle forKey:@"pickle"]; [encoder encodeObject:pickle forKey:@"pickle"];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
} }
@end @end

View file

@ -31,9 +31,31 @@
#import <OLMKit/OLMPkSigning.h> #import <OLMKit/OLMPkSigning.h>
#import <OLMKit/OLMSAS.h> #import <OLMKit/OLMSAS.h>
@interface OLMKit : NSObject
//! Project version string for OLMKit, the same as libolm. NS_ASSUME_NONNULL_BEGIN
+ (NSString*)versionString;
/**
`OLMKitPickleKeyDelegate` provides the key to use for every pickle operation.
*/
@protocol OLMKitPickleKeyDelegate <NSObject>
- (NSData*)pickleKey;
@end @end
@interface OLMKit : NSObject
/// Project version string for OLMKit, the same as libolm.
+ (NSString*)versionString;
/// The optional delegate that provides the pickle key.
/// If not provided, OLMKit will use default pickle keys.
@property (nonatomic, weak, nullable) id<OLMKitPickleKeyDelegate> pickleKeyDelegate;
/// The singleton instance.
+ (instancetype)sharedInstance;
@end
NS_ASSUME_NONNULL_END

View file

@ -30,4 +30,15 @@
return [NSString stringWithFormat:@"%tu.%tu.%tu", major, minor, patch]; return [NSString stringWithFormat:@"%tu.%tu.%tu", major, minor, patch];
} }
+ (instancetype)sharedInstance
{
static OLMKit *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
@end @end

View file

@ -20,6 +20,8 @@
#import "OLMUtility.h" #import "OLMUtility.h"
#include "olm/olm.h" #include "olm/olm.h"
#import "OLMKit.h"
@interface OLMOutboundGroupSession () @interface OLMOutboundGroupSession ()
{ {
OlmOutboundGroupSession *session; OlmOutboundGroupSession *session;
@ -198,6 +200,14 @@
self = [self initWithSerializedData:pickle key:key error:&error]; self = [self initWithSerializedData:pickle key:key error:&error];
} }
else if ([version isEqualToString:@"2"]) {
NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"];
NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
NSParameterAssert(key);
self = [self initWithSerializedData:pickle key:key error:&error];
}
NSParameterAssert(error == nil); NSParameterAssert(error == nil);
NSParameterAssert(self != nil); NSParameterAssert(self != nil);
@ -209,14 +219,23 @@
} }
- (void)encodeWithCoder:(NSCoder *)encoder { - (void)encodeWithCoder:(NSCoder *)encoder {
NSData *key = [OLMUtility randomBytesOfLength:32]; NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
if (key)
{
[encoder encodeObject:@"2" forKey:@"version"];
}
else
{
key = [OLMUtility randomBytesOfLength:32];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
}
NSError *error = nil; NSError *error = nil;
NSString *pickle = [self serializeDataWithKey:key error:&error]; NSString *pickle = [self serializeDataWithKey:key error:&error];
NSParameterAssert(pickle.length > 0 && error == nil); NSParameterAssert(pickle.length > 0 && error == nil);
[encoder encodeObject:pickle forKey:@"pickle"]; [encoder encodeObject:pickle forKey:@"pickle"];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
} }
@end @end

View file

@ -19,6 +19,7 @@
#include "olm/olm.h" #include "olm/olm.h"
#include "olm/pk.h" #include "olm/pk.h"
#include "OLMUtility.h" #include "OLMUtility.h"
#import "OLMKit.h"
@interface OLMPkDecryption () @interface OLMPkDecryption ()
{ {
@ -274,7 +275,14 @@
self = [self initWithSerializedData:pickle key:key error:&error]; self = [self initWithSerializedData:pickle key:key error:&error];
} }
else if ([version isEqualToString:@"2"]) {
NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"];
NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
NSParameterAssert(key);
self = [self initWithSerializedData:pickle key:key error:&error];
}
NSParameterAssert(error == nil); NSParameterAssert(error == nil);
NSParameterAssert(self != nil); NSParameterAssert(self != nil);
if (!self) { if (!self) {
@ -285,15 +293,23 @@
} }
- (void)encodeWithCoder:(NSCoder *)encoder { - (void)encodeWithCoder:(NSCoder *)encoder {
NSData *key = [OLMUtility randomBytesOfLength:32]; NSData *key = OLMKit.sharedInstance.pickleKeyDelegate.pickleKey;
NSError *error = nil; if (key)
{
[encoder encodeObject:@"2" forKey:@"version"];
}
else
{
key = [OLMUtility randomBytesOfLength:32];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
}
NSError *error = nil;
NSString *pickle = [self serializeDataWithKey:key error:&error]; NSString *pickle = [self serializeDataWithKey:key error:&error];
NSParameterAssert(pickle.length > 0 && error == nil); NSParameterAssert(pickle.length > 0 && error == nil);
[encoder encodeObject:pickle forKey:@"pickle"]; [encoder encodeObject:pickle forKey:@"pickle"];
[encoder encodeObject:key forKey:@"key"];
[encoder encodeObject:@"1" forKey:@"version"];
} }
@end @end