kc-12-item-create-keypair.c   [plain text]


#include <Security/SecKey.h>
#include <Security/SecKeychain.h>
#include <Security/SecKeychainSearch.h>
#include <stdlib.h>
#include <unistd.h>

#include "keychain_regressions.h"
#include "kc-helpers.h"

static void tests(void)
{
    SecKeychainRef keychain = createNewKeychain("test", "test");
	SecKeyRef pub_crypt = NULL, prv_crypt = NULL;
	ok_status(SecKeyCreatePair(keychain, CSSM_ALGID_RSA, 256,
		0 /* contextHandle */,
		CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_WRAP,
		CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE,
		CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_UNWRAP,
		CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE |
			CSSM_KEYATTR_SENSITIVE,
		NULL /* initialAccess */, &pub_crypt, &prv_crypt),
		"generate encryption keypair");

	SecKeyRef pub_sign = NULL, prv_sign = NULL;
	ok_status(SecKeyCreatePair(keychain, CSSM_ALGID_RSA, 256,
		0 /* contextHandle */,
		CSSM_KEYUSE_VERIFY,
		CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE,
		CSSM_KEYUSE_SIGN,
		CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE |
			CSSM_KEYATTR_SENSITIVE,
		NULL /* initialAccess */, &pub_sign, &prv_sign),
		"generate signing keypair");

	uint32 btrue = 1;
	uint32 bfalse = 0;
	/* uint32 prv_class = CSSM_KEYCLASS_PRIVATE_KEY; */
	SecKeychainAttribute attrs[] = 
	{
		{ kSecKeyDecrypt, sizeof(uint32), &btrue },
		{ kSecKeyEncrypt, sizeof(uint32), &bfalse },
		/* { kSecKeyKeyClass, sizeof(uint32), &prv_class } */
	};
	SecKeychainAttributeList attrList = { sizeof(attrs) / sizeof(*attrs), attrs };
	SecKeychainSearchRef search;
	OSStatus result;
	SecKeychainItemRef item;
	
	ok_status((result = SecKeychainSearchCreateFromAttributes(keychain,
		CSSM_DL_DB_RECORD_PRIVATE_KEY, &attrList, &search)), "create key search");
	if (result == noErr)
	{
		ok_status(SecKeychainSearchCopyNext(search, &item), "get first key");
		cmp_ok((intptr_t)prv_crypt, ==, (intptr_t)item, "is key found the right one?");
		CFRelease(item);
		item = NULL;
		is_status(SecKeychainSearchCopyNext(search, &item),
			errSecItemNotFound, "get next key");
		is((intptr_t)item, 0, "no item returned");
		CFRelease(search);
	}
	
	SecKeychainAttribute attrs2[] = { { kSecKeySign, sizeof(btrue), &btrue } };
	SecKeychainAttributeList attrList2 = { sizeof(attrs2) / sizeof(*attrs2), attrs2 };
	ok_status((result = SecKeychainSearchCreateFromAttributes(keychain,
		CSSM_DL_DB_RECORD_PRIVATE_KEY, &attrList2, &search)), "create private signing key search");
	
	if (result == noErr)
	{
		ok_status(SecKeychainSearchCopyNext(search, &item), "get first key");
		cmp_ok((intptr_t)prv_sign, ==, (intptr_t)item, "is key found the right one?");
		CFRelease(item);
		is_status(SecKeychainSearchCopyNext(search, &item),
			errSecItemNotFound, "get next key");
		CFRelease(search);
	}
	
	CFRelease(pub_crypt);
	CFRelease(prv_crypt);
	CFRelease(pub_sign);
	CFRelease(prv_sign);

    ok_status(SecKeychainDelete(keychain), "%s: SecKeychainDelete", testName);
	CFRelease(keychain);
}

int kc_17_item_find_key(int argc, char *const *argv)
{
	plan_tests(13);

	tests();

    deleteTestFiles();
	return 0;
}