X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/extendAttrTest/extendAttrTest.cpp?ds=sidebyside diff --git a/SecurityTests/clxutils/extendAttrTest/extendAttrTest.cpp b/SecurityTests/clxutils/extendAttrTest/extendAttrTest.cpp new file mode 100644 index 00000000..ee4fc2dd --- /dev/null +++ b/SecurityTests/clxutils/extendAttrTest/extendAttrTest.cpp @@ -0,0 +1,526 @@ +/* + * extendAttrTest.cpp + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_KC_NAME "extendAttr.keychain" + +static void usage(char **argv) +{ + printf("usage: %s [options]\n", argv[0]); + printf("Options:\n"); + printf(" -k keychain -- default is %s\n", DEFAULT_KC_NAME); + printf(" -n -- don't delete attributes or keychain\n"); + printf(" -q -- quiet\n"); + exit(1); +} + +/* RSA keys, both in OpenSSL format */ +#define PUB_KEY "rsakey_pub.der" +#define PRIV_KEY "rsakey_priv.der" +#define CERT_FILE "amazon_v3.100.cer" +#define PWD_SERVICE "some service" +#define PWD_ACCOUNT "some account" +#define PWD_PWD "some password" + +/* set up unique extended attributes for each tested item */ +typedef struct { + CFStringRef attr1Name; + const char *attr1Value; + CFStringRef attr2Name; + const char *attr2Value; +} ItemAttrs; + +static const ItemAttrs pubKeyAttrs = { + CFSTR("one pub key Attribute"), + "some pub key value", + CFSTR("another pub key Attribute"), + "another pub key value" +}; + +static const ItemAttrs privKeyAttrs = { + CFSTR("one priv key Attribute"), + "some priv key value", + CFSTR("another priv key Attribute"), + "another priv key value" +}; + +static const ItemAttrs certAttrs = { + CFSTR("one cert Attribute"), + "some cert value", + CFSTR("another cert Attribute"), + "another cert value" +}; + +static const ItemAttrs pwdAttrs = { + CFSTR("one pwd Attribute"), + "some pwd value", + CFSTR("another pwd Attribute"), + "another pwd value" +}; + +#define CFRELEASE(cf) if(cf) { CFRelease(cf); } + +/* import file as key into specified keychain */ +static int doImportKey( + const char *fileName, + SecExternalFormat format, + SecExternalItemType itemType, + SecKeychainRef kcRef, + SecKeyRef *keyRef) // RETURNED +{ + unsigned char *item = NULL; + unsigned itemLen = 0; + + if(readFile(fileName, &item, &itemLen)) { + printf("***Error reading %s. \n", fileName); + } + CFDataRef cfd = CFDataCreate(NULL, (const UInt8 *)item, itemLen); + free(item); + SecKeyImportExportParameters params; + memset(¶ms, 0, sizeof(params)); + params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; + params.keyUsage = CSSM_KEYUSE_ANY; + params.keyAttributes = CSSM_KEYATTR_PERMANENT; + if(itemType == kSecItemTypePrivateKey) { + params.keyAttributes |= CSSM_KEYATTR_SENSITIVE; + } + CFArrayRef outArray = NULL; + OSStatus ortn; + ortn = SecKeychainItemImport(cfd, NULL, &format, &itemType, 0, ¶ms, kcRef, &outArray); + if(ortn) { + cssmPerror("SecKeychainItemImport", ortn); + } + CFRelease(cfd); + if(ortn) { + return -1; + } + if((outArray == NULL) || (CFArrayGetCount(outArray) == 0)) { + printf("SecKeychainItemImport succeeded, but no returned items\n"); + return -1; + } + *keyRef = (SecKeyRef)CFArrayGetValueAtIndex(outArray, 0); + if(CFGetTypeID(*keyRef) != SecKeyGetTypeID()) { + printf("***Unknown type returned after import\n"); + return -1; + } + CFRetain(*keyRef); + CFRelease(outArray); + return 0; +} + +/* import file as cert into specified keychain */ +static int doImportCert( + const char *fileName, + SecKeychainRef kcRef, + SecCertificateRef *certRef) // RETURNED +{ + unsigned char *item = NULL; + unsigned itemLen = 0; + + if(readFile(fileName, &item, &itemLen)) { + printf("***Error reading %s. \n", fileName); + return -1; + } + CSSM_DATA certData = {itemLen, (uint8 *)item}; + OSStatus ortn = SecCertificateCreateFromData(&certData, + CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, certRef); + if(ortn) { + cssmPerror("SecCertificateCreateFromData", ortn); + return -1; + } + ortn = SecCertificateAddToKeychain(*certRef, kcRef); + if(ortn) { + cssmPerror("SecCertificateAddToKeychain", ortn); + return -1; + } + return 0; +} + +/* + * Verify specified attr does not exist + * set it + * make sure we get it back + */ +int testOneAttr( + SecKeychainItemRef itemRef, + CFStringRef attrName, + CFDataRef attrVal, + bool quiet) +{ + OSStatus ortn; + CFDataRef fetchedVal = NULL; + int ourRtn = 0; + + if(!quiet) { + printf(" ...verifying attribute doesn't exist\n"); + } + ortn = SecKeychainItemCopyExtendedAttribute(itemRef, attrName, &fetchedVal); + if(ortn != errSecNoSuchAttr) { + printf("***First SecKeychainItemCopyExtendedAttribute returned %d, expected %d\n", + (int)ortn, (int)errSecNoSuchAttr); + ourRtn = -1; + goto errOut; + } + if(!quiet) { + printf(" ...setting attribute\n"); + } + ortn = SecKeychainItemSetExtendedAttribute(itemRef, attrName, attrVal); + if(ortn) { + cssmPerror("SecKeychainItemSetExtendedAttribute", ortn); + ourRtn = -1; + goto errOut; + } + if(!quiet) { + printf(" ...verify attribute\n"); + } + ortn = SecKeychainItemCopyExtendedAttribute(itemRef, attrName, &fetchedVal); + if(ortn) { + cssmPerror("SecKeychainItemCopyExtendedAttribute", ortn); + ourRtn = -1; + goto errOut; + } + if(!CFEqual(fetchedVal, attrVal)) { + printf("***Mismatch in set and fetched attribute\n"); + ourRtn = -1; + } +errOut: + CFRELEASE(fetchedVal); + return ourRtn; +} + +/* + * Set two distinct extended attributes; + * Ensure that each comes back via SecKeychainItemCopyExtendedAttribute(); + * Ensure that both come back via SecKeychainItemCopyAllExtendedAttributes(); + */ +int doTest(SecKeychainItemRef itemRef, + const ItemAttrs &itemAttrs, + bool quiet) +{ + CFDataRef attrVal1 = CFDataCreate(NULL, + (const UInt8 *)itemAttrs.attr1Value, strlen(itemAttrs.attr1Value)); + if(testOneAttr(itemRef, itemAttrs.attr1Name, attrVal1, quiet)) { + return -1; + } + CFDataRef attrVal2 = CFDataCreate(NULL, + (const UInt8 *)itemAttrs.attr2Value, strlen(itemAttrs.attr2Value)); + if(testOneAttr(itemRef, itemAttrs.attr2Name, attrVal2, quiet)) { + return -1; + } + + if(!quiet) { + printf(" ...verify both attributes via CopyAllExtendedAttributes()\n"); + } + /* make sure they both come back in SecKeychainItemCopyAllExtendedAttributes */ + CFArrayRef attrNames = NULL; + CFArrayRef attrValues = NULL; + OSStatus ortn = SecKeychainItemCopyAllExtendedAttributes(itemRef, &attrNames, &attrValues); + if(ortn) { + cssmPerror("SecKeychainItemCopyAllExtendedAttributes", ortn); + return -1; + } + CFIndex numNames = CFArrayGetCount(attrNames); + CFIndex numValues = CFArrayGetCount(attrValues); + if((numNames != 2) || (numValues != 2)) { + printf("***Bad array count after SecKeychainItemCopyAllExtendedAttributes\n"); + printf(" numNames %ld numValues %ld; expected 2 for both\n", + (long)numNames, (long)numValues); + return -1; + } + bool found1 = false; + bool found2 = false; + for(CFIndex dex=0; dex