X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/cspxutils/clearPubKeyTest/clearPubKeyTest.cpp diff --git a/SecurityTests/cspxutils/clearPubKeyTest/clearPubKeyTest.cpp b/SecurityTests/cspxutils/clearPubKeyTest/clearPubKeyTest.cpp deleted file mode 100644 index 81c73e4a..00000000 --- a/SecurityTests/cspxutils/clearPubKeyTest/clearPubKeyTest.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* - * clearPubKeyTest.cpp - * - * Test CSSM_KEYATTR_PUBLIC_KEY_ENCRYPT. This cannot be run on a handsoff environment; - * it forces Keychain unlock dialogs. - */ - -#include -#include -#include -#include -#include -#include "cspwrap.h" -#include "common.h" - -#define KEYCHAIN_NAME "/tmp/clearPubKey.keychain" -#define KEYCHAIN_PWD "pwd" -#define KEY_ALG CSSM_ALGID_RSA -#define KEYSIZE 1024 -#define ENCRALG CSSM_ALGID_RSA - -static void usage(char **argv) -{ - printf("usage: %s -v(erbose)\n", argv[0]); - exit(1); -} - -static void printNoDialog() -{ - printf("*** If you get a keychain unlock dialog here the test is failing ***\n"); -} - -static void printExpectDialog() -{ - printf("*** You MUST get a keychain unlock dialog here (password = '%s') ***\n", - KEYCHAIN_PWD); -} - -static bool didGetDialog() -{ - fpurge(stdin); - printf("Enter 'y' if you just got a keychain unlock dialog: "); - if(getchar() == 'y') { - return 1; - } - printf("***Well, you really should have. Test failed.\n"); - return 0; -} - -static void verboseDisp(bool verbose, const char *str) -{ - if(verbose) { - printf("...%s\n", str); - } -} - -/* generate key pair, optionally storing the public key in encrypted form */ -static int genKeyPair( - bool pubKeyIsEncrypted, - SecKeychainRef kcRef, - SecKeyRef *pubKeyRef, - SecKeyRef *privKeyRef) -{ - /* gather keygen args */ - CSSM_ALGORITHMS keyAlg = KEY_ALG; - uint32 keySizeInBits = KEYSIZE; - CSSM_KEYUSE pubKeyUsage = CSSM_KEYUSE_ANY; - uint32 pubKeyAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT; - if(pubKeyIsEncrypted) { - pubKeyAttr |= CSSM_KEYATTR_PUBLIC_KEY_ENCRYPT; - } - CSSM_KEYUSE privKeyUsage = CSSM_KEYUSE_ANY; - uint32 privKeyAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | - CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE; - - OSStatus ortn = SecKeyCreatePair(kcRef, keyAlg, keySizeInBits, 0, - pubKeyUsage, pubKeyAttr, - privKeyUsage, privKeyAttr, - NULL, // default initial access for now - pubKeyRef, privKeyRef); - if(ortn) { - cssmPerror("SecKeyCreatePair", ortn); - return 1; - } - return 0; -} - -/* encrypt something with a public key */ -static int pubKeyEncrypt( - SecKeyRef pubKeyRef) -{ - const CSSM_KEY *cssmKey; - OSStatus ortn; - CSSM_CSP_HANDLE cspHand; - - ortn = SecKeyGetCSSMKey(pubKeyRef, &cssmKey); - if(ortn) { - cssmPerror("SecKeyGetCSSMKey", ortn); - return -1; - } - ortn = SecKeyGetCSPHandle(pubKeyRef, &cspHand); - if(ortn) { - cssmPerror("SecKeyGetCSPHandle", ortn); - return -1; - } - - char *ptext = "something to encrypt"; - CSSM_DATA ptextData = {strlen(ptext), (uint8 *)ptext}; - CSSM_DATA ctextData = { 0, NULL }; - CSSM_RETURN crtn; - - crtn = cspEncrypt(cspHand, CSSM_ALGID_RSA, - 0, CSSM_PADDING_PKCS1, // mode/pad - cssmKey, NULL, - 0, 0, // effect/rounds - NULL, // IV - &ptextData, &ctextData, CSSM_FALSE); - if(crtn) { - return -1; - } - /* slighyly hazardous, allocated by CSPDL's allocator */ - free(ctextData.Data); - return 0; -} - -int main(int argc, char **argv) -{ - bool verbose = false; - - int arg; - while ((arg = getopt(argc, argv, "vh")) != -1) { - switch (arg) { - case 'v': - verbose = true; - break; - case 'h': - usage(argv); - } - } - if(optind != argc) { - usage(argv); - } - - printNoDialog(); - - /* initial setup */ - verboseDisp(verbose, "deleting keychain"); - unlink(KEYCHAIN_NAME); - - verboseDisp(verbose, "creating keychain"); - SecKeychainRef kcRef = NULL; - OSStatus ortn = SecKeychainCreate(KEYCHAIN_NAME, - strlen(KEYCHAIN_PWD), KEYCHAIN_PWD, - false, NULL, &kcRef); - if(ortn) { - cssmPerror("SecKeychainCreate", ortn); - exit(1); - } - - /* - * 1. Generate key pair with cleartext public key. - * Ensure we can use the public key when keychain is locked with no - * user interaction. - */ - - /* generate key pair, cleartext public key */ - verboseDisp(verbose, "creating key pair, cleartext public key"); - SecKeyRef pubKeyRef = NULL; - SecKeyRef privKeyRef = NULL; - if(genKeyPair(false, kcRef, &pubKeyRef, &privKeyRef)) { - exit(1); - } - - /* Use generated cleartext public key with locked keychain */ - verboseDisp(verbose, "locking keychain, exporting public key"); - SecKeychainLock(kcRef); - CFDataRef exportData = NULL; - ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData); - if(ortn) { - cssmPerror("SecKeychainCreate", ortn); - exit(1); - } - CFRelease(exportData); - - verboseDisp(verbose, "locking keychain, encrypting with public key"); - SecKeychainLock(kcRef); - if(pubKeyEncrypt(pubKeyRef)) { - exit(1); - } - - /* reset */ - verboseDisp(verbose, "deleting keys"); - ortn = SecKeychainItemDelete((SecKeychainItemRef)pubKeyRef); - if(ortn) { - cssmPerror("SecKeychainItemDelete", ortn); - exit(1); - } - ortn = SecKeychainItemDelete((SecKeychainItemRef)privKeyRef); - if(ortn) { - cssmPerror("SecKeychainItemDelete", ortn); - exit(1); - } - CFRelease(pubKeyRef); - CFRelease(privKeyRef); - - /* - * 2. Generate key pair with encrypted public key. - * Ensure that user interaction is required when we use the public key - * when keychain is locked. - */ - - verboseDisp(verbose, "programmatically unlocking keychain"); - ortn = SecKeychainUnlock(kcRef, strlen(KEYCHAIN_PWD), KEYCHAIN_PWD, TRUE); - if(ortn) { - cssmPerror("SecKeychainItemDelete", ortn); - exit(1); - } - - /* generate key pair, encrypted public key */ - verboseDisp(verbose, "creating key pair, encrypted public key"); - if(genKeyPair(true, kcRef, &pubKeyRef, &privKeyRef)) { - exit(1); - } - - /* Use generated encrypted public key with locked keychain */ - verboseDisp(verbose, "locking keychain, exporting public key"); - SecKeychainLock(kcRef); - printExpectDialog(); - ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData); - if(ortn) { - cssmPerror("SecKeychainCreate", ortn); - exit(1); - } - /* we'll use that exported blob later to test import */ - if(!didGetDialog()) { - exit(1); - } - - verboseDisp(verbose, "locking keychain, encrypting with public key"); - SecKeychainLock(kcRef); - printExpectDialog(); - if(pubKeyEncrypt(pubKeyRef)) { - exit(1); - } - if(!didGetDialog()) { - exit(1); - } - - /* reset */ - printNoDialog(); - verboseDisp(verbose, "locking keychain"); - SecKeychainLock(kcRef); - verboseDisp(verbose, "deleting keys"); - ortn = SecKeychainItemDelete((SecKeychainItemRef)pubKeyRef); - if(ortn) { - cssmPerror("SecKeychainItemDelete", ortn); - exit(1); - } - ortn = SecKeychainItemDelete((SecKeychainItemRef)privKeyRef); - if(ortn) { - cssmPerror("SecKeychainItemDelete", ortn); - exit(1); - } - CFRelease(pubKeyRef); - CFRelease(privKeyRef); - - /* - * 3. Import public key, storing in cleartext. Ensure that the import - * doesn't require unlock, and ensure we can use the public key - * when keychain is locked with no user interaction. - */ - - printNoDialog(); - verboseDisp(verbose, "locking keychain"); - SecKeychainLock(kcRef); - - /* import public key - default is in the clear */ - verboseDisp(verbose, "importing public key, store in the clear (default)"); - CFArrayRef outArray = NULL; - SecExternalFormat format = kSecFormatOpenSSL; - SecExternalItemType type = kSecItemTypePublicKey; - ortn = SecKeychainItemImport(exportData, - NULL, &format, &type, - 0, NULL, - kcRef, &outArray); - if(ortn) { - cssmPerror("SecKeychainItemImport", ortn); - exit(1); - } - CFRelease(exportData); - if(CFArrayGetCount(outArray) != 1) { - printf("***Unexpected outArray size (%ld) after import\n", - (long)CFArrayGetCount(outArray)); - exit(1); - } - pubKeyRef = (SecKeyRef)CFArrayGetValueAtIndex(outArray, 0); - if(CFGetTypeID(pubKeyRef) != SecKeyGetTypeID()) { - printf("***Unexpected item type after import\n"); - exit(1); - } - - /* Use imported cleartext public key with locked keychain */ - verboseDisp(verbose, "locking keychain, exporting public key"); - SecKeychainLock(kcRef); - exportData = NULL; - ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData); - if(ortn) { - cssmPerror("SecKeychainItemExport", ortn); - exit(1); - } - /* we'll use exportData again */ - - verboseDisp(verbose, "locking keychain, encrypting with public key"); - SecKeychainLock(kcRef); - if(pubKeyEncrypt(pubKeyRef)) { - exit(1); - } - - /* reset */ - verboseDisp(verbose, "deleting key"); - ortn = SecKeychainItemDelete((SecKeychainItemRef)pubKeyRef); - if(ortn) { - cssmPerror("SecKeychainItemDelete", ortn); - exit(1); - } - CFRelease(pubKeyRef); - - /* - * Import public key, storing in encrypted form. - * Ensure that user interaction is required when we use the public key - * when keychain is locked. - */ - - /* import public key, encrypted in the keychain */ - SecKeyImportExportParameters impExpParams; - memset(&impExpParams, 0, sizeof(impExpParams)); - impExpParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - impExpParams.keyAttributes = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | - CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_PUBLIC_KEY_ENCRYPT; - verboseDisp(verbose, "importing public key, store encrypted"); - printExpectDialog(); - outArray = NULL; - format = kSecFormatOpenSSL; - type = kSecItemTypePublicKey; - ortn = SecKeychainItemImport(exportData, - NULL, &format, &type, - 0, &impExpParams, - kcRef, &outArray); - if(ortn) { - cssmPerror("SecKeychainItemImport", ortn); - exit(1); - } - if(!didGetDialog()) { - exit(1); - } - CFRelease(exportData); - if(CFArrayGetCount(outArray) != 1) { - printf("***Unexpected outArray size (%ld) after import\n", - (long)CFArrayGetCount(outArray)); - exit(1); - } - pubKeyRef = (SecKeyRef)CFArrayGetValueAtIndex(outArray, 0); - if(CFGetTypeID(pubKeyRef) != SecKeyGetTypeID()) { - printf("***Unexpected item type after import\n"); - exit(1); - } - - /* Use imported encrypted public key with locked keychain */ - verboseDisp(verbose, "locking keychain, exporting public key"); - SecKeychainLock(kcRef); - printExpectDialog(); - ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData); - if(ortn) { - cssmPerror("SecKeychainItemExport", ortn); - exit(1); - } - if(!didGetDialog()) { - exit(1); - } - CFRelease(exportData); - - verboseDisp(verbose, "locking keychain, encrypting with public key"); - SecKeychainLock(kcRef); - printExpectDialog(); - if(pubKeyEncrypt(pubKeyRef)) { - exit(1); - } - if(!didGetDialog()) { - exit(1); - } - - SecKeychainDelete(kcRef); - printf("...test succeeded.\n"); - return 0; -}