session-ios/SignalServiceKit/src/Messages/PreKeyBundle+jsonDict.m

111 lines
4 KiB
Mathematica
Raw Normal View History

2015-12-07 03:31:43 +01:00
//
2017-02-10 01:35:10 +01:00
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
2015-12-07 03:31:43 +01:00
//
#import "NSData+Base64.h"
#import "PreKeyBundle+jsonDict.h"
@implementation PreKeyBundle (jsonDict)
+ (PreKeyBundle *)preKeyBundleFromDictionary:(NSDictionary *)dictionary forDeviceNumber:(NSNumber *)number {
PreKeyBundle *bundle = nil;
NSString *identityKeyString = [dictionary objectForKey:@"identityKey"];
NSArray *devicesArray = [dictionary objectForKey:@"devices"];
if (!(identityKeyString && [devicesArray isKindOfClass:[NSArray class]])) {
DDLogError(@"Failed to get identity key or messages array from server request");
return nil;
}
NSData *identityKey = [NSData dataFromBase64StringNoPadding:identityKeyString];
for (NSDictionary *deviceDict in devicesArray) {
NSNumber *registrationIdString = [deviceDict objectForKey:@"registrationId"];
NSNumber *deviceIdString = [deviceDict objectForKey:@"deviceId"];
if (!(registrationIdString && deviceIdString)) {
DDLogError(@"Failed to get the registration id and device id");
return nil;
}
if (![deviceIdString isEqualToNumber:number]) {
DDLogWarn(@"Got a keyid for another device");
return nil;
}
int registrationId = [registrationIdString intValue];
int deviceId = [deviceIdString intValue];
2017-02-10 01:35:10 +01:00
NSDictionary *_Nullable preKeyDict;
id optionalPreKeyDict = [deviceDict objectForKey:@"preKey"];
// JSON parsing might give us NSNull, so we can't simply check for non-nil.
if ([optionalPreKeyDict isKindOfClass:[NSDictionary class]]) {
preKeyDict = (NSDictionary *)optionalPreKeyDict;
}
2015-12-07 03:31:43 +01:00
int prekeyId;
2017-02-10 01:35:10 +01:00
NSData *_Nullable preKeyPublic;
2015-12-07 03:31:43 +01:00
2017-02-10 01:35:10 +01:00
if (!preKeyDict) {
DDLogInfo(@"%@ No one-time prekey included in the bundle.", self.tag);
2015-12-07 03:31:43 +01:00
prekeyId = -1;
} else {
2017-02-10 01:35:10 +01:00
prekeyId = [[preKeyDict objectForKey:@"keyId"] intValue];
NSString *preKeyPublicString = [preKeyDict objectForKey:@"publicKey"];
2015-12-07 03:31:43 +01:00
preKeyPublic = [NSData dataFromBase64StringNoPadding:preKeyPublicString];
}
NSDictionary *signedPrekey = [deviceDict objectForKey:@"signedPreKey"];
if (![signedPrekey isKindOfClass:[NSDictionary class]]) {
DDLogError(@"Device doesn't have signed prekeys registered");
return nil;
}
NSNumber *signedKeyIdNumber = [signedPrekey objectForKey:@"keyId"];
NSString *signedSignatureString = [signedPrekey objectForKey:@"signature"];
NSString *signedPublicKeyString = [signedPrekey objectForKey:@"publicKey"];
if (!(signedKeyIdNumber && signedPublicKeyString && signedSignatureString)) {
DDLogError(@"Missing signed key material");
return nil;
}
NSData *signedPrekeyPublic = [NSData dataFromBase64StringNoPadding:signedPublicKeyString];
NSData *signedPreKeySignature = [NSData dataFromBase64StringNoPadding:signedSignatureString];
if (!(signedPrekeyPublic && signedPreKeySignature)) {
DDLogError(@"Failed to parse signed keying material");
return nil;
}
int signedPreKeyId = [signedKeyIdNumber intValue];
bundle = [[self alloc] initWithRegistrationId:registrationId
deviceId:deviceId
preKeyId:prekeyId
preKeyPublic:preKeyPublic
signedPreKeyPublic:signedPrekeyPublic
signedPreKeyId:signedPreKeyId
signedPreKeySignature:signedPreKeySignature
identityKey:identityKey];
}
return bundle;
}
2017-02-10 01:35:10 +01:00
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
2015-12-07 03:31:43 +01:00
@end