updated to support new encryptionv3.dat file

This commit is contained in:
Stefan Reitshamer 2017-07-10 06:18:28 -04:00
parent d9a0893024
commit 5a6beaebdc
3 changed files with 71 additions and 9 deletions

View file

@ -68,12 +68,24 @@
error:(NSError **)error { error:(NSError **)error {
NSError *myError = nil; NSError *myError = nil;
// Try to read local v2 file. // Try to read local v3 file.
EncryptionDatFile *datFile = [[[EncryptionDatFile alloc] initFromLocalCacheWithEncryptionPassword:theEncryptionPassword EncryptionDatFile *datFile = [[[EncryptionDatFile alloc] initFromLocalCacheWithEncryptionPassword:theEncryptionPassword
target:theTarget target:theTarget
computerUUID:theComputerUUID computerUUID:theComputerUUID
encryptionVersion:2 encryptionVersion:3
error:&myError] autorelease]; error:&myError] autorelease];
if (datFile == nil) {
if ([myError code] != ERROR_NOT_FOUND) {
SETERRORFROMMYERROR;
return nil;
}
// Try to read local v2 file.
datFile = [[[EncryptionDatFile alloc] initFromLocalCacheWithEncryptionPassword:theEncryptionPassword
target:theTarget
computerUUID:theComputerUUID
encryptionVersion:2
error:&myError] autorelease];
}
if (datFile == nil) { if (datFile == nil) {
if ([myError code] != ERROR_NOT_FOUND) { if ([myError code] != ERROR_NOT_FOUND) {
SETERRORFROMMYERROR; SETERRORFROMMYERROR;
@ -86,6 +98,25 @@
encryptionVersion:1 encryptionVersion:1
error:&myError] autorelease]; error:&myError] autorelease];
} }
if (datFile == nil) {
if ([myError code] != ERROR_NOT_FOUND) {
SETERRORFROMMYERROR;
return nil;
}
// Try to read v3 file from target.
datFile = [[[EncryptionDatFile alloc] initFromTargetWithEncryptionPassword:theEncryptionPassword
target:theTarget
computerUUID:theComputerUUID
encryptionVersion:3
targetConnectionDelegate:theTCD
error:&myError] autorelease];
if (datFile != nil) {
NSError *cacheError = nil;
if (![datFile saveToLocalCache:&cacheError]) {
HSLogError(@"failed to save encryption dat file to local cache: %@", cacheError);
}
}
}
if (datFile == nil) { if (datFile == nil) {
if ([myError code] != ERROR_NOT_FOUND) { if ([myError code] != ERROR_NOT_FOUND) {
SETERRORFROMMYERROR; SETERRORFROMMYERROR;
@ -300,7 +331,8 @@
} }
// Decrypt master keys. // Decrypt master keys.
size_t theMasterKeysLen = kCCKeySizeAES256 * 2 + kCCBlockSizeAES128; NSUInteger expectedKeysLen = (encryptionVersion == 3) ? (kCCKeySizeAES256 * 3) : (kCCKeySizeAES256 * 2);
size_t theMasterKeysLen = expectedKeysLen + kCCBlockSizeAES128;
NSMutableData *theMasterKeys = [NSMutableData dataWithLength:theMasterKeysLen]; NSMutableData *theMasterKeys = [NSMutableData dataWithLength:theMasterKeysLen];
size_t theMasterKeysActualLen = 0; size_t theMasterKeysActualLen = 0;
const unsigned char *encryptedMasterKeys = bytes + strlen(HEADER) + SALT_LENGTH + CC_SHA256_DIGEST_LENGTH + IV_LENGTH; const unsigned char *encryptedMasterKeys = bytes + strlen(HEADER) + SALT_LENGTH + CC_SHA256_DIGEST_LENGTH + IV_LENGTH;
@ -327,6 +359,12 @@
[masterKeys release]; [masterKeys release];
masterKeys = [theMasterKeys copy]; masterKeys = [theMasterKeys copy];
if ([masterKeys length] != expectedKeysLen && encryptionVersion != 1) {
SETNSERROR([EncryptionDatFile errorDomain], -1, @"unexpected master keys length %ld (expected %ld)", [masterKeys length], expectedKeysLen);
return NO;
}
return YES; return YES;
} }

View file

@ -40,13 +40,14 @@
@interface ObjectEncryptorV2 : NSObject <ObjectEncryptorImpl> { @interface ObjectEncryptorV2 : NSObject <ObjectEncryptorImpl> {
Target *target; Target *target;
NSString *computerUUID; NSString *computerUUID;
NSData *computerUUIDData; NSData *blobKeySaltData;
NSData *masterKeys; NSData *masterKeys;
const void *masterKey; const void *masterKey;
const void *hmacKey; const void *hmacKey;
unsigned char *symmetricKey; unsigned char *symmetricKey;
NSLock *symmetricKeyLock; NSLock *symmetricKeyLock;
int encryptCount; int encryptCount;
int encryptionVersion;
} }
- (id)initWithTarget:(Target *)theTarget - (id)initWithTarget:(Target *)theTarget

View file

@ -50,8 +50,9 @@
#define SYMMETRIC_KEY_LEN kCCKeySizeAES256 #define SYMMETRIC_KEY_LEN kCCKeySizeAES256
#define DATA_IV_AND_SYMMETRIC_KEY_LEN (IV_LEN + SYMMETRIC_KEY_LEN) #define DATA_IV_AND_SYMMETRIC_KEY_LEN (IV_LEN + SYMMETRIC_KEY_LEN)
#define ENCRYPTED_DATA_IV_AND_SYMMETRIC_KEY_LEN (DATA_IV_AND_SYMMETRIC_KEY_LEN + kCCBlockSizeAES128) #define ENCRYPTED_DATA_IV_AND_SYMMETRIC_KEY_LEN (DATA_IV_AND_SYMMETRIC_KEY_LEN + kCCBlockSizeAES128)
#define ENCRYPTION_VERSION (2)
#define MAX_ENCRYPTIONS_PER_SYMMETRIC_KEY (256) #define MAX_ENCRYPTIONS_PER_SYMMETRIC_KEY (256)
#define V3_MASTER_KEYS_LEN (kCCKeySizeAES256 * 3)
#define V2_MASTER_KEYS_LEN (kCCKeySizeAES256 * 2)
@implementation ObjectEncryptorV2 @implementation ObjectEncryptorV2
@ -63,7 +64,6 @@
if (self = [super init]) { if (self = [super init]) {
target = [theTarget retain]; target = [theTarget retain];
computerUUID = [theComputerUUID retain]; computerUUID = [theComputerUUID retain];
computerUUIDData = [[computerUUID dataUsingEncoding:NSUTF8StringEncoding] retain];
symmetricKey = (unsigned char *)malloc(SYMMETRIC_KEY_LEN); symmetricKey = (unsigned char *)malloc(SYMMETRIC_KEY_LEN);
@ -71,6 +71,28 @@
masterKey = [masterKeys bytes]; masterKey = [masterKeys bytes];
hmacKey = (unsigned char *)masterKey + kCCKeySizeAES256; hmacKey = (unsigned char *)masterKey + kCCKeySizeAES256;
encryptionVersion = [theEDF encryptionVersion];
if ([theEDF encryptionVersion] == 3) {
if ([masterKeys length] != V3_MASTER_KEYS_LEN) {
SETNSERROR([ObjectEncryptor errorDomain], -1, @"master keys data is not %d bytes", V3_MASTER_KEYS_LEN);
[self release];
return nil;
}
blobKeySaltData = [[NSData alloc] initWithBytes:(hmacKey + kCCKeySizeAES256) length:kCCKeySizeAES256];
} else if ([theEDF encryptionVersion] == 2) {
if ([masterKeys length] != V2_MASTER_KEYS_LEN) {
SETNSERROR([ObjectEncryptor errorDomain], -1, @"master keys data is not %d bytes", V2_MASTER_KEYS_LEN);
[self release];
return nil;
}
blobKeySaltData = [[computerUUID dataUsingEncoding:NSUTF8StringEncoding] retain];
} else {
SETNSERROR([ObjectEncryptor errorDomain], -1, @"unexpected encryption version: %d", [theEDF encryptionVersion]);
[self release];
return nil;
}
[self resetSymmetricKey]; [self resetSymmetricKey];
symmetricKeyLock = [[NSLock alloc] init]; symmetricKeyLock = [[NSLock alloc] init];
[symmetricKeyLock setName:@"symmetric key lock"]; [symmetricKeyLock setName:@"symmetric key lock"];
@ -81,6 +103,7 @@
- (void)dealloc { - (void)dealloc {
[target release]; [target release];
[computerUUID release]; [computerUUID release];
[blobKeySaltData release];
[masterKeys release]; [masterKeys release];
free(symmetricKey); free(symmetricKey);
[symmetricKeyLock release]; [symmetricKeyLock release];
@ -91,14 +114,14 @@
#pragma ObjectEncryptorImpl #pragma ObjectEncryptorImpl
- (BOOL)ensureDatFileExistsAtTargetWithEncryptionPassword:(NSString *)theEncryptionPassword targetConnectionDelegate:(id<TargetConnectionDelegate>)theTCD error:(NSError **)error { - (BOOL)ensureDatFileExistsAtTargetWithEncryptionPassword:(NSString *)theEncryptionPassword targetConnectionDelegate:(id<TargetConnectionDelegate>)theTCD error:(NSError **)error {
NSError *myError = nil; NSError *myError = nil;
EncryptionDatFile *encryptionDatFile = [[[EncryptionDatFile alloc] initFromTargetWithEncryptionPassword:theEncryptionPassword target:target computerUUID:computerUUID encryptionVersion:ENCRYPTION_VERSION targetConnectionDelegate:theTCD error:&myError] autorelease]; EncryptionDatFile *encryptionDatFile = [[[EncryptionDatFile alloc] initFromTargetWithEncryptionPassword:theEncryptionPassword target:target computerUUID:computerUUID encryptionVersion:encryptionVersion targetConnectionDelegate:theTCD error:&myError] autorelease];
if (encryptionDatFile == nil) { if (encryptionDatFile == nil) {
if ([myError code] != ERROR_NOT_FOUND) { if ([myError code] != ERROR_NOT_FOUND) {
SETERRORFROMMYERROR; SETERRORFROMMYERROR;
return NO; return NO;
} }
encryptionDatFile = [[[EncryptionDatFile alloc] initFromLocalCacheWithEncryptionPassword:theEncryptionPassword target:target computerUUID:computerUUID encryptionVersion:ENCRYPTION_VERSION error:error] autorelease]; encryptionDatFile = [[[EncryptionDatFile alloc] initFromLocalCacheWithEncryptionPassword:theEncryptionPassword target:target computerUUID:computerUUID encryptionVersion:encryptionVersion error:error] autorelease];
if (encryptionDatFile == nil) { if (encryptionDatFile == nil) {
SETERRORFROMMYERROR; SETERRORFROMMYERROR;
return NO; return NO;
@ -122,7 +145,7 @@
unsigned char digest[CC_SHA1_DIGEST_LENGTH]; unsigned char digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1_CTX ctx; CC_SHA1_CTX ctx;
CC_SHA1_Init(&ctx); CC_SHA1_Init(&ctx);
CC_SHA1_Update(&ctx, [computerUUIDData bytes], (CC_LONG)[computerUUIDData length]); CC_SHA1_Update(&ctx, [blobKeySaltData bytes], (CC_LONG)[blobKeySaltData length]);
CC_SHA1_Update(&ctx, [theData bytes], (CC_LONG)[theData length]); CC_SHA1_Update(&ctx, [theData bytes], (CC_LONG)[theData length]);
CC_SHA1_Final(digest, &ctx); CC_SHA1_Final(digest, &ctx);
return [NSString hexStringWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; return [NSString hexStringWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];