2
0

Fix internal bugs.

Pass masterKey data safely by ensuring the NSData holder is owned.

nameOfType: threw an unrecougnized-type error always, including for
recougnized types.

Swizzling broke when triggered on multiple levels of the hierarchy.
This commit is contained in:
Maarten Billemont 2020-01-14 15:21:56 -05:00
parent 91b89aaf39
commit ec6625b800
6 changed files with 20 additions and 18 deletions

@ -1 +1 @@
Subproject commit 4eb904f9b4c318da36b5071d57d137b63f8ef144 Subproject commit a0b8d6fe4ef563579c97c70905fe0b6806e8d787

View File

@ -49,7 +49,7 @@ NSString *NSStringFromTimeToCrack(TimeToCrack timeToCrack);
- (BOOL)tryMigrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc; - (BOOL)tryMigrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc;
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit; - (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit;
- (NSData *)keyIDForKey:(MPMasterKey)masterKey; - (NSData *)keyIDForKey:(NSData *)masterKey;
- (NSData *)keyDataForFullName:(NSString *)fullName withMasterPassword:(NSString *)masterPassword; - (NSData *)keyDataForFullName:(NSString *)fullName withMasterPassword:(NSString *)masterPassword;
- (NSString *)nameOfType:(MPResultType)type; - (NSString *)nameOfType:(MPResultType)type;

View File

@ -132,7 +132,7 @@ static NSOperationQueue *_mpwQueue = nil;
if (masterKey) { if (masterKey) {
keyData = [NSData dataWithBytes:masterKey length:MPMasterKeySize]; keyData = [NSData dataWithBytes:masterKey length:MPMasterKeySize];
trc( @"User: %@, password: %@ derives to key ID: %@ (took %0.2fs)", // trc( @"User: %@, password: %@ derives to key ID: %@ (took %0.2fs)", //
fullName, masterPassword, [self keyIDForKey:masterKey], -[start timeIntervalSinceNow] ); fullName, masterPassword, [self keyIDForKey:keyData], -[start timeIntervalSinceNow] );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
} }
}]; }];
@ -140,9 +140,9 @@ static NSOperationQueue *_mpwQueue = nil;
return keyData; return keyData;
} }
- (NSData *)keyIDForKey:(MPMasterKey)masterKey { - (NSData *)keyIDForKey:(NSData *)masterKey {
return [[NSData dataWithBytesNoCopy:(void *)masterKey length:MPMasterKeySize] hashWith:PearlHashSHA256]; return [masterKey hashWith:PearlHashSHA256];
} }
- (NSString *)nameOfType:(MPResultType)type { - (NSString *)nameOfType:(MPResultType)type {
@ -364,8 +364,9 @@ static NSOperationQueue *_mpwQueue = nil;
__block NSString *result = nil; __block NSString *result = nil;
[self mpw_perform:^{ [self mpw_perform:^{
char const *resultBytes = mpw_siteResult( [key keyForAlgorithm:self], NSData *masterKey = [key keyForAlgorithm:self];
name.UTF8String, counter, purpose, context.UTF8String, type, parameter.UTF8String, [self version] ); char const *resultBytes = mpw_siteResult( masterKey.bytes, name.UTF8String,
counter, purpose, context.UTF8String, type, parameter.UTF8String, [self version] );
if (resultBytes) { if (resultBytes) {
result = [NSString stringWithCString:resultBytes encoding:NSUTF8StringEncoding]; result = [NSString stringWithCString:resultBytes encoding:NSUTF8StringEncoding];
mpw_free_string( &resultBytes ); mpw_free_string( &resultBytes );
@ -392,7 +393,8 @@ static NSOperationQueue *_mpwQueue = nil;
__block NSData *state = nil; __block NSData *state = nil;
if (plainText) if (plainText)
[self mpw_perform:^{ [self mpw_perform:^{
char const *stateBytes = mpw_siteState( [key keyForAlgorithm:self], site.name.UTF8String, NSData *masterKey = [key keyForAlgorithm:self];
char const *stateBytes = mpw_siteState( masterKey.bytes, site.name.UTF8String,
MPCounterValueInitial, MPKeyPurposeAuthentication, NULL, site.type, plainText.UTF8String, [self version] ); MPCounterValueInitial, MPKeyPurposeAuthentication, NULL, site.type, plainText.UTF8String, [self version] );
if (stateBytes) { if (stateBytes) {
state = [[NSString stringWithCString:stateBytes encoding:NSUTF8StringEncoding] decodeBase64]; state = [[NSString stringWithCString:stateBytes encoding:NSUTF8StringEncoding] decodeBase64];
@ -499,7 +501,7 @@ static NSOperationQueue *_mpwQueue = nil;
if (![site isKindOfClass:[MPGeneratedSiteEntity class]]) { if (![site isKindOfClass:[MPGeneratedSiteEntity class]]) {
wrn( @"Site with generated type %lu is not an MPGeneratedSiteEntity, but a %@.", wrn( @"Site with generated type %lu is not an MPGeneratedSiteEntity, but a %@.",
(long)site.type, [site class] ); (long)site.type, [site class] );
break; return;
} }
MPCounterValue counter = ((MPGeneratedSiteEntity *)site).counter; MPCounterValue counter = ((MPGeneratedSiteEntity *)site).counter;
@ -507,7 +509,7 @@ static NSOperationQueue *_mpwQueue = nil;
PearlNotMainQueue( ^{ PearlNotMainQueue( ^{
resultBlock( [algorithm mpwTemplateForSiteNamed:name ofType:type withCounter:counter usingKey:key] ); resultBlock( [algorithm mpwTemplateForSiteNamed:name ofType:type withCounter:counter usingKey:key] );
} ); } );
break; return;
} }
case MPResultTypeStatefulPersonal: case MPResultTypeStatefulPersonal:
@ -515,7 +517,7 @@ static NSOperationQueue *_mpwQueue = nil;
if (![site isKindOfClass:[MPStoredSiteEntity class]]) { if (![site isKindOfClass:[MPStoredSiteEntity class]]) {
wrn( @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.", wrn( @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.",
(long)site.type, [site class] ); (long)site.type, [site class] );
break; return;
} }
NSDictionary *siteQuery = [self queryForSite:site]; NSDictionary *siteQuery = [self queryForSite:site];
@ -527,11 +529,11 @@ static NSOperationQueue *_mpwQueue = nil;
withCounter:MPCounterValueInitial variant:MPKeyPurposeAuthentication context:nil withCounter:MPCounterValueInitial variant:MPKeyPurposeAuthentication context:nil
usingKey:key] ); usingKey:key] );
} ); } );
break; return;
} }
case MPResultTypeDeriveKey: case MPResultTypeDeriveKey:
break; return;
} }
Throw( @"Type not supported: %lu", (long)type ); Throw( @"Type not supported: %lu", (long)type );

View File

@ -95,13 +95,13 @@
- (void)storeSavedKeyFor:(MPUserEntity *)user { - (void)storeSavedKeyFor:(MPUserEntity *)user {
if (user.saveKey) { if (user.saveKey) {
MPMasterKey masterKey = [self.key keyForAlgorithm:user.algorithm]; NSData *masterKey = [self.key keyForAlgorithm:user.algorithm];
if (masterKey) { if (masterKey) {
[self forgetSavedKeyFor:user]; [self forgetSavedKeyFor:user];
inf( @"Saving key in keychain for user: %@", user.userID ); inf( @"Saving key in keychain for user: %@", user.userID );
[PearlKeyChain addOrUpdateItemForQuery:[self createKeyQueryforUser:user origin:nil] withAttributes:@{ [PearlKeyChain addOrUpdateItemForQuery:[self createKeyQueryforUser:user origin:nil] withAttributes:@{
(__bridge id)kSecValueData: [NSData dataWithBytesNoCopy:(void *)masterKey length:MPMasterKeySize] (__bridge id)kSecValueData: masterKey
}]; }];
} }
} }

View File

@ -38,7 +38,7 @@ typedef NS_ENUM( NSUInteger, MPKeyOrigin ) {
keyOrigin:(MPKeyOrigin)origin; keyOrigin:(MPKeyOrigin)origin;
- (NSData *)keyIDForAlgorithm:(id<MPAlgorithm>)algorithm; - (NSData *)keyIDForAlgorithm:(id<MPAlgorithm>)algorithm;
- (MPMasterKey)keyForAlgorithm:(id<MPAlgorithm>)algorithm; - (NSData *)keyForAlgorithm:(id<MPAlgorithm>)algorithm;
- (BOOL)isEqualToKey:(MPKey *)key; - (BOOL)isEqualToKey:(MPKey *)key;

View File

@ -56,7 +56,7 @@
return [algorithm keyIDForKey:[self keyForAlgorithm:algorithm]]; return [algorithm keyIDForKey:[self keyForAlgorithm:algorithm]];
} }
- (MPMasterKey)keyForAlgorithm:(id<MPAlgorithm>)algorithm { - (NSData *)keyForAlgorithm:(id<MPAlgorithm>)algorithm {
@synchronized (self) { @synchronized (self) {
NSData *keyData = [self.keyCache objectForKey:algorithm]; NSData *keyData = [self.keyCache objectForKey:algorithm];
@ -66,7 +66,7 @@
[self.keyCache setObject:keyData forKey:algorithm]; [self.keyCache setObject:keyData forKey:algorithm];
} }
return keyData.length == MPMasterKeySize? keyData.bytes: NULL; return keyData.length == MPMasterKeySize? keyData: NULL;
} }
} }