mirror of
https://github.com/samsonjs/arq_restore.git
synced 2026-03-25 09:25:53 +00:00
updated to support new encryptionv3.dat file
This commit is contained in:
parent
d9a0893024
commit
5a6beaebdc
3 changed files with 71 additions and 9 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue