X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/p12Reencode/p12Reencode.cpp diff --git a/SecurityTests/clxutils/p12Reencode/p12Reencode.cpp b/SecurityTests/clxutils/p12Reencode/p12Reencode.cpp new file mode 100644 index 00000000..8ec65e6f --- /dev/null +++ b/SecurityTests/clxutils/p12Reencode/p12Reencode.cpp @@ -0,0 +1,395 @@ +/* + * p12Reencode - take a p12 PFX, decode and reencode + */ +#include  +#include +#include +#include +#include +#include + +static void usage(char **argv) +{ + printf("Usage: %s pfx password keychain1 keychain2 [l=loops] [q(uiet)] " + "[v(erbose)]\n", argv[0]); + exit(1); +} + + +#define WRITE_BLOBS 0 +#if WRITE_BLOBS +static void writeBlobs(CFDataRef pfx1, CFDataRef pfx2) +{ + writeFile("pfx1.der", CFDataGetBytePtr(pfx1), CFDataGetLength(pfx1)); + writeFile("pfx2.der", CFDataGetBytePtr(pfx2), CFDataGetLength(pfx2)); + printf("...wrote %u bytes to pfx1.der, %u bytes to pfx2.der\n", + CFDataGetLength(pfx1), CFDataGetLength(pfx2)); +} +#else +#define writeBlobs(p1, p2) +#endif + +#if 0 +/* Not possible using import/export API */ +/* compare attrs, all of which are optional */ +static int compareAttrs( + CFStringRef refFriendlyName, + CFDataRef refLocalKeyId, + CFStringRef testFriendlyName, + CFDataRef testLocalKeyId, + char *itemType, + CSSM_BOOL quiet) +{ + if(refFriendlyName == NULL) { + if(testFriendlyName != NULL) { + printf("****s refFriendlyName NULL, testFriendlyName " + "non-NULL\n", itemType); + return testError(quiet); + } + } + else { + CFComparisonResult res = CFStringCompare(refFriendlyName, + testFriendlyName, 0); + if(res != kCFCompareEqualTo) { + printf("***%s friendlyName Miscompare\n", itemType); + return testError(quiet); + } + } + + if(refLocalKeyId == NULL) { + if(testLocalKeyId != NULL) { + printf("****s refLocalKeyId NULL, testLocalKeyId " + "non-NULL\n", itemType); + return testError(quiet); + } + } + else { + if(compareCfData(refLocalKeyId, testLocalKeyId)) { + printf("***%s localKeyId Miscompare\n", itemType); + return testError(quiet); + } + } + + /* release the attrs */ + if(refFriendlyName) { + CFRelease(refFriendlyName); + } + if(refLocalKeyId) { + CFRelease(refLocalKeyId); + } + if(testFriendlyName) { + CFRelease(testFriendlyName); + } + if(testLocalKeyId) { + CFRelease(testLocalKeyId); + } + return 0; +} +#endif + +static void setUpKeyParams( + SecKeyImportExportParameters &keyParams, + CFStringRef pwd) +{ + memset(&keyParams, 0, sizeof(keyParams)); + keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; + keyParams.passphrase = pwd; +} + +/* + * Basic import/export: convert between CFArray of keychain items and a CFDataRef + */ +static OSStatus p12Import( + CFDataRef pfx, + CFStringRef pwd, + SecKeychainRef kcRef, + CFArrayRef *outArray) +{ + SecKeyImportExportParameters keyParams; + setUpKeyParams(keyParams, pwd); + OSStatus ortn; + SecExternalFormat format = kSecFormatPKCS12; + + ortn = SecKeychainItemImport(pfx, NULL, &format, NULL, 0, &keyParams, + kcRef, outArray); + if(ortn) { + cssmPerror("SecKeychainItemImport", ortn); + } + return ortn; +} + +static OSStatus p12Export( + CFArrayRef inArray, + CFStringRef pwd, + CFDataRef *pfx) +{ + SecKeyImportExportParameters keyParams; + setUpKeyParams(keyParams, pwd); + OSStatus ortn; + + ortn = SecKeychainItemExport(inArray, kSecFormatPKCS12, 0, &keyParams, pfx); + if(ortn) { + cssmPerror("SecKeychainItemExport", ortn); + } + return ortn; +} + +/* + * Compare two CFArrayRefs containing various items, subsequent to decode. Returns + * nonzero if they differ. + * + * As of April 9 2004, we do NOT see CRLs so we don't compare them. I think + * we need a SecCRLRef... + */ +static int compareDecodedArrays( + CFArrayRef refArray, + CFArrayRef testArray, + CSSM_BOOL quiet) +{ + OSStatus ortn; + int ourRtn = 0; + + CFIndex numRefItems = CFArrayGetCount(refArray); + CFIndex numTestItems = CFArrayGetCount(testArray); + if(numRefItems != numTestItems) { + printf("***item count mismatch: ref %ld test %ld\n", + numRefItems, numTestItems); + return 1; + } + for(CFIndex dex=0; dexKeyHeader.LogicalKeySizeInBits != + testKey->KeyHeader.LogicalKeySizeInBits) { + printf("***Key size miscompare on Key %ld\n", dex); + ourRtn = testError(quiet); + if(ourRtn) { + return ourRtn; + } + } + if(refKey->KeyHeader.AlgorithmId != + testKey->KeyHeader.AlgorithmId) { + printf("***AlgorithmId miscompare on Key %ld\n", dex); + ourRtn = testError(quiet); + if(ourRtn) { + return ourRtn; + } + } + } + else { + /* this program may need work here. e.g. for SecCRLRefs */ + printf("***Unknown type ID (%ld)\n", theType); + ourRtn++; + } + } + + return ourRtn; +} + +int main(int argc, char **argv) +{ + unsigned char *pfx; + unsigned pfxLen; + SecKeychainRef kcRef1 = nil; // reference, 1st import destination + SecKeychainRef kcRef2 = nil; // subsequent import destination + + CSSM_BOOL quiet = CSSM_FALSE; + unsigned loops = 10; + bool verbose = false; + bool doPause = false; + char *kcName = NULL; + + int i; + + if(argc < 5) { + usage(argv); + } + + if(readFile(argv[1], &pfx, &pfxLen)) { + printf("***Error reading PFX from %s. Aborting.\n", argv[1]); + exit(1); + } + CFStringRef pwd = CFStringCreateWithCString(NULL, argv[2], + kCFStringEncodingASCII); + if(pwd == NULL) { + printf("Bad password (%s)\n", argv[2]); + exit(1); + } + kcName = argv[3]; + OSStatus ortn = SecKeychainOpen(kcName, &kcRef1); + if(ortn) { + cssmPerror("SecKeychainOpen", ortn); + exit(1); + } + kcName = argv[4]; + ortn = SecKeychainOpen(kcName, &kcRef2); + if(ortn) { + cssmPerror("SecKeychainOpen", ortn); + exit(1); + } + + for(i=5; i