Example #1
0
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;
}