static EVP_PKEY * GenerateRSAPrivateKey(int bits) // IN { RSA *rsa; EVP_PKEY *pkey = NULL; rsa = GenerateRSAKeyPair(bits); if (!rsa) { goto exit; } pkey = EVP_PKEY_new(); if (!pkey) { Error("Failed to allocate a private key structure.\n"); goto exit; } EVP_PKEY_assign_RSA(pkey, rsa); rsa = NULL; exit: RSA_free(rsa); return pkey; }
static int testExtractable( SecKeychainRef keychain, Boolean extractable, Boolean explicit) { OSStatus status; SecKeyRef publicKeyRef = NULL; SecKeyRef privateKeyRef = NULL; CFStringRef label = (extractable) ? CFSTR("test-extractable-YES") : CFSTR("test-extractable-NO"); Boolean *extractablePtr = (explicit) ? &extractable : NULL; status = GenerateRSAKeyPair(keychain, label, 1024, // size extractablePtr, &publicKeyRef, &privateKeyRef); if (status != noErr) { //errx(EXIT_FAILURE, "Unable to get key pair (err = %d)", status); return status; } // check that the attributes of the generated private key are what we think they are const CSSM_KEY *cssmPrivKey; status = SecKeyGetCSSMKey(privateKeyRef, &cssmPrivKey); ok_status(status, "%s: SecKeyGetCSSMKey", testName); if (status != noErr) { //errx(EXIT_FAILURE, "Unable to get CSSM reference key (err = %d)", status); return status; } if (extractable) { ok(cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE, "%s: check private key marked as extractable (as requested)", testName); if (!(cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE)) { //errx(EXIT_FAILURE, "Oops! the private key was not marked as extractable!"); return 1; } } else { ok(!(cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE), "%s: check private key marked as non-extractable (as requested)", testName); if (cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE) { //errx(EXIT_FAILURE, "Oops! the private key was marked as extractable!"); return 1; } } SecKeyImportExportParameters keyParams; memset(&keyParams, 0, sizeof(keyParams)); keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; keyParams.passphrase = CFSTR("borken"); CFDataRef exportedData = NULL; status = SecKeychainItemExport(privateKeyRef, kSecFormatWrappedPKCS8, 0, &keyParams, &exportedData); if(extractable) { ok_status(status, "%s: SecKeychainItemExport (PKCS8) (and we expected it to succeed)", testName); } else { is(status, errSecDataNotAvailable, "%s: SecKeychainItemExport (PKCS8) (and we expected this to fail with errSecDataNotAvailable)", testName); } status = SecKeychainItemExport(privateKeyRef, kSecFormatPKCS12, 0, &keyParams, &exportedData); if(extractable) { ok_status(status, "%s: SecKeychainItemExport(and we expected it to succeed)", testName); } else { is(status, errSecDataNotAvailable, "%s: SecKeychainItemExport (PKCS12) (and we expected this to fail with errSecDataNotAvailable)", testName); } if (status != noErr) { if (extractable) { //errx(EXIT_FAILURE, "Unable to export extractable key! (err = %d)", status); return 1; } else { status = 0; // wasn't extractable, so this is the expected result } } else if (status == noErr && !extractable) { //errx(EXIT_FAILURE, "Was able to export non-extractable key! (err = %d)", status); return 1; } status = SecKeychainItemDelete((SecKeychainItemRef)publicKeyRef); ok_status(status, "%s: SecKeychainItemDelete", testName); if (status != noErr) { warnx("Unable to delete created public key from keychain (err = %d)", (int)status); } status = SecKeychainItemDelete((SecKeychainItemRef)privateKeyRef); ok_status(status, "%s: SecKeychainItemDelete", testName); if (status != noErr) { warnx("Unable to delete created private key from keychain (err = %d)", (int)status); } CFRelease(publicKeyRef); CFRelease(privateKeyRef); return 0; }