diff --git a/README.md b/README.md index 1ad3d66..e3f53fe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Keychain Dumper +Added feature to display protection classes. + ## Usage All that should be needed to use keychain_dumper is the binary that is checked in to the Keychain-Dumper Git repository. This binary has been signed with a self-signed certificate with a "wildcard" entitlement that should grant keychain_dumper access to all Keychain items that would have been granted had the tool been signed with each individual entitlement. If you either don't trust this binary or are having trouble dumping Keychain items using the below steps, you may can build the tool from source and manually sign the appropriate entitlments into your build of the keychain_dumper binary. diff --git a/keychain_dumper b/keychain_dumper index 73c75d7..e697fb0 100755 Binary files a/keychain_dumper and b/keychain_dumper differ diff --git a/main.m b/main.m index a991dc4..f33d99e 100644 --- a/main.m +++ b/main.m @@ -195,6 +195,29 @@ void printGenericPassword(NSDictionary *passwordItem) { printToStdOut(@"Account: %@\n", [passwordItem objectForKey:(id)kSecAttrAccount]); printToStdOut(@"Entitlement Group: %@\n", [passwordItem objectForKey:(id)kSecAttrAccessGroup]); printToStdOut(@"Label: %@\n", [passwordItem objectForKey:(id)kSecAttrLabel]); + + if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ck"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlock\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ak"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlocked\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dk"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlways\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"aku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlockedThisDeviceOnly\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"cku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlwaysThisDeviceOnly\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"akpu"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly\n"); + } + printToStdOut(@"Generic Field: %@\n", [[passwordItem objectForKey:(id)kSecAttrGeneric] description]); NSData* passwordData = [passwordItem objectForKey:(id)kSecValueData]; printToStdOut(@"Keychain Data: %@\n\n", [[NSString alloc] initWithData:passwordData encoding:NSUTF8StringEncoding]); @@ -207,6 +230,31 @@ void printInternetPassword(NSDictionary *passwordItem) { printToStdOut(@"Account: %@\n", [passwordItem objectForKey:(id)kSecAttrAccount]); printToStdOut(@"Entitlement Group: %@\n", [passwordItem objectForKey:(id)kSecAttrAccessGroup]); printToStdOut(@"Label: %@\n", [passwordItem objectForKey:(id)kSecAttrLabel]); + + + if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ck"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlock\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ak"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlocked\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dk"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlways\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"aku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlockedThisDeviceOnly\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"cku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlwaysThisDeviceOnly\n"); + } + else if ([[passwordItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"akpu"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly\n"); + } + + NSData* passwordData = [passwordItem objectForKey:(id)kSecValueData]; printToStdOut(@"Keychain Data: %@\n\n", [[NSString alloc] initWithData:passwordData encoding:NSUTF8StringEncoding]); } @@ -223,6 +271,31 @@ void printCertificate(NSDictionary *certificateItem) { CFRelease(summary); printToStdOut(@"Entitlement Group: %@\n", [certificateItem objectForKey:(id)kSecAttrAccessGroup]); printToStdOut(@"Label: %@\n", [certificateItem objectForKey:(id)kSecAttrLabel]); + + + if ([[certificateItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ck"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlock\n"); + } + else if ([[certificateItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ak"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlocked\n"); + } + else if ([[certificateItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dk"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlways\n"); + } + else if ([[certificateItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"aku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlockedThisDeviceOnly\n"); + } + else if ([[certificateItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"cku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly\n"); + } + else if ([[certificateItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlwaysThisDeviceOnly\n"); + } + else if ([[certificateItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"akpu"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly\n"); + } + + printToStdOut(@"Serial Number: %@\n", [certificateItem objectForKey:(id)kSecAttrSerialNumber]); printToStdOut(@"Subject Key ID: %@\n", [certificateItem objectForKey:(id)kSecAttrSubjectKeyID]); printToStdOut(@"Subject Key Hash: %@\n\n", [certificateItem objectForKey:(id)kSecAttrPublicKeyHash]); @@ -247,6 +320,31 @@ void printKey(NSDictionary *keyItem) { printToStdOut(@"---\n"); printToStdOut(@"Entitlement Group: %@\n", [keyItem objectForKey:(id)kSecAttrAccessGroup]); printToStdOut(@"Label: %@\n", [keyItem objectForKey:(id)kSecAttrLabel]); + + + if ([[keyItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ck"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlock\n"); + } + else if ([[keyItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"ak"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlocked\n"); + } + else if ([[keyItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dk"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlways\n"); + } + else if ([[keyItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"aku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenUnlockedThisDeviceOnly\n"); + } + else if ([[keyItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"cku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly\n"); + } + else if ([[keyItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"dku"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleAlwaysThisDeviceOnly\n"); + } + else if ([[keyItem objectForKey:(id)kSecAttrAccessible] isEqualToString:@"akpu"]) { + printToStdOut(@"Keychain protection class: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly\n"); + } + + printToStdOut(@"Application Label: %@\n", [keyItem objectForKey:(id)kSecAttrApplicationLabel]); printToStdOut(@"Key Class: %@\n", keyClass); printToStdOut(@"Permanent Key: %@\n", CFBooleanGetValue((CFBooleanRef)[keyItem objectForKey:(id)kSecAttrIsPermanent]) == true ? @"True" : @"False");