X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/clxutils/p12/p12ImportExport.cpp?ds=inline diff --git a/SecurityTests/clxutils/p12/p12ImportExport.cpp b/SecurityTests/clxutils/p12/p12ImportExport.cpp deleted file mode 100644 index 13c52af5..00000000 --- a/SecurityTests/clxutils/p12/p12ImportExport.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* - * p12ImportExport.cpp - high-level libnsspkcs12 exerciser - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "p12GetPassKey.h" - -static void printOsError( - const char *op, - OSStatus ortn) -{ - char *errStr = NULL; - switch(ortn) { - case CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA: - errStr = "CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA"; break; - case CSSMERR_DL_DATASTORE_DOESNOT_EXIST: - errStr = "CSSMERR_DL_DATASTORE_DOESNOT_EXIST"; break; - case errSecDuplicateItem: - errStr = "errSecDuplicateItem"; break; - case errSecNotAvailable: - errStr = "errSecNotAvailable"; break; - case errSecAuthFailed: - errStr = "errSecAuthFailed"; break; - case errSecItemNotFound: - errStr = "errSecItemNotFound"; break; - case errSecInvalidItemRef: - errStr = "errSecInvalidItemRef"; break; - default: - break; - } - if(errStr) { - printf("%s returned %s\n", op, errStr); - } - else { - printf("%s returned %d\n", op, (int)ortn); - } -} - -/* - * For now we assume "import everything" - */ -int p12Import( - const char *pfxFile, - const char *kcName, - CFStringRef pwd, // explicit passphrase, mutually exclusive with... - bool usePassKey, // use SECURE_PASSPHRASE key - const char *kcPwd) // optional -{ - OSStatus ortn; - unsigned char *pfx; - unsigned pfxLen; - CSSM_KEY passKey; - - /* get the PFX */ - if(readFile(pfxFile, &pfx, &pfxLen)) { - printf("***Error reading pfx from %s. Aborting.\n", pfxFile); - return 1; - } - CFDataRef cfd = CFDataCreate(NULL, pfx, pfxLen); - - /* import to keychain specified by kcName */ - SecKeychainRef kcRef = NULL; - ortn = SecKeychainOpen(kcName, &kcRef); - if(ortn) { - printOsError("SecKeychainOpen", ortn); - return ortn; - } - - if(kcPwd) { - ortn = SecKeychainUnlock(kcRef, strlen(kcPwd), (void *)kcPwd, true); - if(ortn) { - printOsError("SecKeychainUnlock", ortn); - } - } - - /* set up a pkcs12 coder for import */ - SecPkcs12CoderRef coder; - ortn = SecPkcs12CoderCreate(&coder); - if(ortn) { - printOsError("SecPkcs12CoderCreate", ortn); - return ortn; - } - - ortn = SecPkcs12SetKeychain(coder, kcRef); - if(ortn) { - printOsError("SecPkcs12SetKeychain", ortn); - return ortn; - } - - if(usePassKey) { - CSSM_CSP_HANDLE cspHand; - ortn = SecKeychainGetCSPHandle(kcRef, &cspHand); - if(ortn) { - printOsError("SecPkcs12SetKeychain", ortn); - return ortn; - } - ortn = p12GetPassKey(cspHand, GPK_Decode, false, &passKey); - if(ortn) { - return ortn; - } - ortn = SecPkcs12SetMACPassKey(coder, &passKey); - if(ortn) { - printOsError("SecPkcs12SetMACPassKey", ortn); - return ortn; - } - } - else { - ortn = SecPkcs12SetMACPassphrase(coder, pwd); - if(ortn) { - printOsError("SecPkcs12SetMACPassphrase", ortn); - return ortn; - } - } - - /* - * For now we assume "import everything" - */ - ortn = SecPkcs12SetImportToKeychain(coder, - kSecImportCertificates | - kSecImportCRLs | - kSecImportKeys); - if(ortn) { - printOsError("SecPkcs12SetImportFromKeychain", ortn); - return ortn; - } - - /* Go! */ - ortn = SecPkcs12Decode(coder, cfd); - if(ortn) { - printOsError("SecPkcs12Decode", ortn); - return ortn; - } - - /* report how many of each item got imported */ - CFIndex num; - SecPkcs12CertificateCount(coder, &num); - printf("...%d certs imported\n", (int)num); - SecPkcs12CrlCount(coder, &num); - printf("...%d CRLs imported\n", (int)num); - SecPkcs12PrivateKeyCount(coder, &num); - printf("...%d private keys imported\n", (int)num); - - SecPkcs12CoderRelease(coder); - CFRelease(cfd); - free(pfx); // mallocd by readFile() - return 0; -} - -/* - * Use the kludge from hell to get the name-as-int form of a specified - * "known" name-as-string for the Key Schema. - */ -OSStatus attrNameToInt( - const char *name, - uint32 *attrInt) -{ - const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *attrList = - KeySchema::KeySchemaAttributeList; - unsigned numAttrs = KeySchema::KeySchemaAttributeCount; - for(unsigned dex=0; dexAttributeName)) { - *attrInt = info->AttributeId; - return noErr; - } - } - return paramErr; -} - -static int p12AddExportedItem( - SecKeychainItemRef item, - CFMutableArrayRef itemArray, - bool noPrompt) -{ - if(noPrompt) { - CFArrayAppendValue(itemArray, item); - return 1; - } - - CFTypeID itemId = CFGetTypeID(item); - OSStatus ortn; - - /* the printable name attr */ - UInt32 nameAttr = 0; - char *itemClass = ""; - if(itemId == SecCertificateGetTypeID()) { - itemClass = "Certificate"; - nameAttr = kSecLabelItemAttr; - } - else if(itemId == SecKeyGetTypeID()) { - itemClass = "Private Key"; - ortn = attrNameToInt("PrintName", &nameAttr); - if(ortn) { - /* out of sync with Sec layer? With KeySchema? */ - printf("warning: attrNameToInt failure\n"); - return 0; - } - } - else { - /* we don't know how to deal with this */ - printf("p12AddExportedItem: internal screwup\n"); - return 0; - } - - /* get the printable name attr */ - SecKeychainAttributeInfo attrInfo; - attrInfo.count = 1; - attrInfo.tag = &nameAttr; - attrInfo.format = NULL; // ??? - - /* FIXME header says this is an IN/OUT param, but it's not */ - SecKeychainAttributeList *attrList = NULL; - - ortn = SecKeychainItemCopyAttributesAndData( - item, - &attrInfo, - NULL, // itemClass - &attrList, - NULL, // don't need the data - NULL); - if(ortn) { - printOsError("SecKeychainItemCopyAttributesAndData", ortn); - return 0; - } - if(attrList->count != 1) { - printf("***Unexpected attribute count (%u) for %s\n", - (unsigned)attrList->count, itemClass); - return 0; - } - SecKeychainAttribute *attr = attrList->attr; - - /* it's a UTF8 string: use CFString to convert to C ASCII string */ - CFStringRef cfStr = CFStringCreateWithBytes(NULL, - (UInt8 *)attr->data, attr->length, - kCFStringEncodingUTF8, false); - SecKeychainItemFreeAttributesAndData(attrList, NULL); - if(cfStr == NULL) { - printf("***Error converting %s name to UTF CFSTring.\n", - itemClass); - return 0; - } - - CFIndex strLen = CFStringGetLength(cfStr); - char *printName = (char *)malloc(strLen + 1); - if(!CFStringGetCString(cfStr, printName, strLen + 1, kCFStringEncodingASCII)) { - printf("***Error converting %s name to ASCII\n", itemClass); - return 0; - } - CFRelease(cfStr); - - char *aliasCStr = NULL; - if((itemId == SecCertificateGetTypeID())) { - /* the alias attr, for cert email */ - CFStringRef aliasCFStr = NULL; - nameAttr = kSecAlias; - attrInfo.count = 1; - attrInfo.tag = &nameAttr; - attrInfo.format = NULL; // ??? - attrList = NULL; - - ortn = SecKeychainItemCopyAttributesAndData( - item, - &attrInfo, - NULL, // itemClass - &attrList, - NULL, // don't need the data - NULL); - if(ortn) { - printOsError("SecKeychainItemCopyAttributesAndData", ortn); - return 0; - } - if(attrList->count != 1) { - printf("***Unexpected attribute count (%u) for Alias\n", - (unsigned)attrList->count); - return 0; - } - attr = attrList->attr; - - /* it's a UTF8 string: use CFString to convert to C ASCII string */ - aliasCFStr = CFStringCreateWithBytes(NULL, - (UInt8 *)attr->data, attr->length, - kCFStringEncodingUTF8, false); - if(aliasCFStr == NULL) { - printf("***Error converting Alias name to UTF CFSTring.\n"); - return 0; - } - - strLen = CFStringGetLength(aliasCFStr); - aliasCStr = (char *)malloc(strLen + 1); - if(!CFStringGetCString(aliasCFStr, aliasCStr, strLen + 1, - kCFStringEncodingASCII)) { - printf("***Error converting Alias name to ASCII\n"); - return 0; - } - CFRelease(aliasCFStr); - } - - int ourRtn = 0; - fpurge(stdin); - printf("Found %s\n", itemClass); - printf(" printable name : %s\n", printName); - if(aliasCStr != NULL) { - printf(" alias : %s\n", aliasCStr); - } - printf("Export (y/anything)? "); - char c = getchar(); - if(c == 'y') { - CFArrayAppendValue(itemArray, item); - ourRtn = 1; - } - free(printName); - if(aliasCStr) { - free(aliasCStr); - } - return ourRtn; -} - -int p12Export( - const char *pfxFile, - const char *kcName, - CFStringRef pwd, // explicit passphrase, mutually exclusive with... - bool usePassKey, // use SECURE_PASSPHRASE key - const char *kcPwd, // optional - bool noPrompt) // true --> export all -{ - OSStatus ortn; - CSSM_KEY passKey; - - /* set up a pkcs12 coder for export */ - SecPkcs12CoderRef coder; - ortn = SecPkcs12CoderCreate(&coder); - if(ortn) { - printOsError("SecPkcs12CoderCreate", ortn); - return ortn; - } - - /* - Ê* Since we're not providing the SecPkcs12CoderRef with a - * keychain, we have to provide the CSPDL handle - */ - CSSM_CSP_HANDLE cspHand = cuCspStartup(CSSM_FALSE); - if(cspHand == 0) { - printf("***Error attaching to CSPDL. Aborting.\n"); - return 1; - } - - if(usePassKey) { - ortn = p12GetPassKey(cspHand, GPK_Encode, false, &passKey); - if(ortn) { - return ortn; - } - ortn = SecPkcs12SetMACPassKey(coder, &passKey); - if(ortn) { - printOsError("SecPkcs12SetMACPassKey", ortn); - return ortn; - } - } - else { - ortn = SecPkcs12SetMACPassphrase(coder, pwd); - if(ortn) { - printOsError("SecPkcs12SetMACPassphrase", ortn); - return ortn; - } - } - - ortn = SecPkcs12SetCspHandle(coder, cspHand); - if(ortn) { - printOsError("SecPkcs12SetCspHandle", ortn); - return ortn; - } - - /* the array of things we want to export */ - CFMutableArrayRef items = CFArrayCreateMutable(NULL, 0, NULL); - - /* export from keychain specified by kcName */ - SecKeychainRef kcRef = NULL; - ortn = SecKeychainOpen(kcName, &kcRef); - if(ortn) { - printOsError("SecKeychainOpen", ortn); - return ortn; - } - - if(kcPwd) { - ortn = SecKeychainUnlock(kcRef, strlen(kcPwd), (void *)kcPwd, true); - if(ortn) { - printOsError("SecKeychainUnlock", ortn); - } - } - - /* - * Prompt user for each known item - it would be nice if we - * could search for anything, eh? - * Certs first... - */ - SecKeychainSearchRef srchRef; - ortn = SecKeychainSearchCreateFromAttributes(kcRef, - kSecCertificateItemClass, - NULL, // no attrs - &srchRef); - if(ortn) { - printOsError("SecKeychainSearchCreateFromAttributes", ortn); - return ortn; - } - int exported = 0; - for(;;) { - SecKeychainItemRef certRef; - ortn = SecKeychainSearchCopyNext(srchRef, &certRef); - if(ortn) { - break; - } - exported += p12AddExportedItem(certRef, items, noPrompt); - } - CFRelease(srchRef); - - /* now private keys */ - ortn = SecKeychainSearchCreateFromAttributes(kcRef, - CSSM_DL_DB_RECORD_PRIVATE_KEY, // undocumented - NULL, // no attrs - &srchRef); - if(ortn) { - printOsError("SecKeychainSearchCreateFromAttributes", ortn); - return ortn; - } - for(;;) { - SecKeychainItemRef keyRef; - ortn = SecKeychainSearchCopyNext(srchRef, &keyRef); - if(ortn) { - break; - } - exported += p12AddExportedItem(keyRef, items, noPrompt); - } - - if(exported == 0) { - printf("...Hmmm, no items to export. Done.\n"); - return 0; - } - ortn = SecPkcs12ExportKeychainItems(coder, items); - if(ortn) { - printOsError("SecPkcs12ExportKeychainItems", ortn); - return ortn; - } - - /* go */ - CFDataRef pfx; - ortn = SecPkcs12Encode(coder, &pfx); - if(ortn) { - printOsError("SecPkcs12ExportKeychainItems", ortn); - return ortn; - } - - if(writeFile(pfxFile, CFDataGetBytePtr(pfx), - CFDataGetLength(pfx))) { - printf("***Error writing pfx to %s\n", pfxFile); - return 1; - } - printf("...%u items exported; %ld bytes written to %s\n", - exported, CFDataGetLength(pfx), pfxFile); - - /* cleanup */ - SecPkcs12CoderRelease(coder); - CFRelease(pfx); - CFRelease(srchRef); - CFRelease(kcRef); - return 0; -}