/* Test basic add delete update copy matching stuff. */
static void tests(void)
{
    SecTrustRef trust;
	SecCertificateRef cert0, cert1;
	isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
		NULL, "create cert0");
	isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
		NULL, "create cert1");
	const void *v_certs[] = {
		cert0,
		cert1
	};
    SecPolicyRef policy = SecPolicyCreateSSL(false, CFSTR("store.apple.com"));
    CFArrayRef certs = CFArrayCreate(NULL, v_certs,
		array_size(v_certs), NULL);
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
	/* Jan 1st 2006. */
	CFDateRef date = CFDateCreate(NULL, 157680000.0);
    ok_status(SecTrustSetVerifyDate(trust, date), "set date");

	SecTrustResultType trustResult;
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");
    CFDataRef exceptions;
    ok(exceptions = SecTrustCopyExceptions(trust), "create an exceptions");
    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");

	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
    policy = SecPolicyCreateSSL(false, CFSTR("badstore.apple.com"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust with hostname mismatch");
    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
    ok(SecTrustSetExceptions(trust, exceptions), "set old exceptions");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
	CFReleaseSafe(exceptions);
    ok(exceptions = SecTrustCopyExceptions(trust), "create a new exceptions");
    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");

	CFReleaseSafe(trust);
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
    ok_status(SecTrustSetVerifyDate(trust, date), "set date");
    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
    CFArrayRef anchors = CFArrayCreate(kCFAllocatorDefault, NULL, 0, &kCFTypeArrayCallBacks);
    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set empty anchor list");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");

	ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultProceed, "trust is now kSecTrustResultProceed");

	ok_status(SecTrustSetAnchorCertificatesOnly(trust, true), "only trust passed in anchors (default)");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure again");

	CFReleaseSafe(exceptions);
    ok(exceptions = SecTrustCopyExceptions(trust), "create a new exceptions");
    ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
	CFReleaseSafe(date);
	date = CFDateCreate(NULL, 667680000.0);
    ok_status(SecTrustSetVerifyDate(trust, date), "set date to far future so certs are expired");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");

	CFReleaseSafe(anchors);
	CFReleaseSafe(exceptions);
	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
	CFReleaseSafe(certs);
	CFReleaseSafe(cert0);
	CFReleaseSafe(cert1);
	CFReleaseSafe(date);
}
/* Basic processing of input */
static void tests(void)
{
    CFArrayRef certs = NULL;
    CFDataRef message;

    // Premade message containing one certificate blob
    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
                                          certsOnlyMsg, sizeof(certsOnlyMsg), kCFAllocatorNull);
    ok(certs = SecCMSCertificatesOnlyMessageCopyCertificates(message),
       "SecCMSCertificatesOnlyMessageCopyCertificates");
    is(CFArrayGetCount(certs), 1, "certificate count is 1");
    CFReleaseNull(message);

    // Premade message containing one certificate blob
    message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
                                          gkIPACCG2DevCertClass87, sizeof(gkIPACCG2DevCertClass87), kCFAllocatorNull);
    ok(certs = SecCMSCertificatesOnlyMessageCopyCertificates(message),
       "SecCMSCertificatesOnlyMessageCopyCertificates");
    is(CFArrayGetCount(certs), 1, "certificate count is 1");
    CFReleaseNull(message);


    SecCertificateRef another_cert = NULL;

    // Process a single raw certificate and make it a message
    isnt(another_cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
         NULL, "create certificate");
    ok(message = SecCMSCreateCertificatesOnlyMessageIAP(another_cert), "create iAP specific cert only message (1cert)");
    ok(certs = SecCMSCertificatesOnlyMessageCopyCertificates(message),
       "SecCMSCertificatesOnlyMessageCopyCertificates");
    is(CFArrayGetCount(certs), 1, "certificate count is 1");

    // Process two raw certificates (concatenated DER blobs) and make it a message
    isnt(another_cert = SecCertificateCreateWithBytes(NULL, TestDoubleCerts, sizeof(TestDoubleCerts)),
         NULL, "create certificate");
    ok(message = SecCMSCreateCertificatesOnlyMessageIAP(another_cert), "create iAP specific cert only message (2certs)");
    ok(certs = SecCMSCertificatesOnlyMessageCopyCertificates(message),
       "SecCMSCertificatesOnlyMessageCopyCertificates");
    is(CFArrayGetCount(certs), 2, "certificate count is 2");

    // Clean up
    CFReleaseNull(another_cert);
    CFReleaseNull(message);

    CFReleaseNull(certs);
}
static void tests(void)
{
    SecTrustRef trust;
    SecCertificateRef leaf, wwdr_intermediate;
    SecPolicyRef policy;

    isnt(wwdr_intermediate = SecCertificateCreateWithBytes(kCFAllocatorDefault,
        wwdr_intermediate_cert, sizeof(wwdr_intermediate_cert)), NULL, "create WWDR intermediate");
    isnt(leaf = SecCertificateCreateWithBytes(kCFAllocatorDefault,
        codesigning_certificate, sizeof(codesigning_certificate)), NULL, "create leaf");

    const void *vcerts[] = { leaf, wwdr_intermediate };
    CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, vcerts, 2, NULL);

    isnt(policy = SecPolicyCreateiPhoneProfileApplicationSigning(), NULL,
        "create iPhoneProfileApplicationSigning policy instance");
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for leaf");
    CFDateRef verifyDate = CFDateCreate(kCFAllocatorDefault, 228244066);
    ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set verify date");
    CFReleaseNull(verifyDate);
    SecTrustResultType trustResult;
    CFArrayRef properties = NULL;
    properties = SecTrustCopyProperties(trust);
    is(properties, NULL, "no properties returned before eval");
    CFReleaseNull(properties);
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified");
    properties = SecTrustCopyProperties(trust);

    if (properties) {
        print_plist(properties);
        print_cert(leaf, true);
        print_cert(wwdr_intermediate, false);
    }

    CFReleaseNull(properties);
    CFReleaseNull(trust);
    CFReleaseNull(wwdr_intermediate);
    CFReleaseNull(leaf);
    CFReleaseNull(certs);
    CFReleaseNull(policy);
	CFReleaseNull(trust);
}
static void tests(void)
{
	CFDataRef attached_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, attached_signed_data_der, attached_signed_data_der_len, kCFAllocatorNull);
	CFDataRef detached_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, detached_signed_data_der, detached_signed_data_der_len, kCFAllocatorNull);
	CFDataRef attached_no_data_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, attached_no_data_signed_data_der, attached_no_data_signed_data_der_len, kCFAllocatorNull);
	CFDataRef detached_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, detached_content, detached_content_len, kCFAllocatorNull);
	CFDataRef no_data = CFDataCreate(kCFAllocatorDefault, NULL, 0);
	SecPolicyRef policy = SecPolicyCreateBasicX509();
	SecTrustRef trust = NULL;

	ok_status(SecCMSVerifyCopyDataAndAttributes(attached_signed_data, NULL, policy, &trust, NULL, NULL), "verify attached data");
	CFRelease(trust);
	ok_status(SecCMSVerifyCopyDataAndAttributes(detached_signed_data, detached_data, policy, &trust, NULL, NULL), "verify detached data");
	CFRelease(trust);
	ok_status(SecCMSVerifyCopyDataAndAttributes(attached_no_data_signed_data, NULL, policy, &trust, NULL, NULL), "verify attached no data");
	CFRelease(trust);
	ok_status(SecCMSVerifyCopyDataAndAttributes(attached_no_data_signed_data, no_data, policy, &trust, NULL, NULL), "verify attached no data");
	CFRelease(trust);


    SecCertificateRef cert = NULL;
    SecKeyRef privKey = NULL;
    SecIdentityRef identity = NULL;

    isnt(cert = SecCertificateCreateWithBytes(NULL, signer_der, signer_der_len), NULL, "create certificate");
    isnt(privKey = SecKeyCreateRSAPrivateKey(NULL, privkey_der, privkey_der_len, kSecKeyEncodingPkcs1), NULL, "create private key");
    isnt(identity = SecIdentityCreate(NULL, cert, privKey), NULL, "create identity");
    CFReleaseSafe(privKey);

	CFMutableDataRef cms_data = CFDataCreateMutable(kCFAllocatorDefault, 0);
	ok_status(SecCMSCreateSignedData(identity, detached_data, NULL, NULL, cms_data), "create attached data");
	//write_data("/var/tmp/attached", cms_data);
	CFDataSetLength(cms_data, 0);
	CFDictionaryRef detached_cms_dict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&kSecCMSSignDetached, (const void **)&kCFBooleanTrue, 1, NULL, NULL);
	ok_status(SecCMSCreateSignedData(identity, detached_data, detached_cms_dict, NULL, cms_data), "create attached data");
	CFRelease(detached_cms_dict);
	//write_data("/var/tmp/detached", cms_data);
	CFDataSetLength(cms_data, 0);
	ok_status(SecCMSCreateSignedData(identity, NULL, NULL, NULL, cms_data), "create attached data");
	//write_data("/var/tmp/empty_attached", cms_data);

	CFReleaseSafe(cms_data);
	CFReleaseSafe(cert);
	CFReleaseNull(identity);
	CFRelease(attached_signed_data);
	CFRelease(detached_signed_data);
	CFRelease(attached_no_data_signed_data);
	CFRelease(detached_data);
	CFRelease(no_data);
	CFRelease(policy);
}
/* Create and identity and try to retrieve it. */
static void AddIdentityToKeychain(void)
{
    SecCertificateRef cert = NULL;
    SecKeyRef privKey = NULL;
    //SecIdentityRef identity = NULL;

    isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
            NULL, "create certificate");

#if TARGET_OS_IPHONE
    privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
                                        kSecKeyEncodingPkcs1);
#else
#warning TODO
    privKey = NULL;
#endif

    isnt(privKey, NULL, "create private key");

    const void *certkeys[] = {
        kSecValueRef
    };
    const void *certvalues[] = {
        cert
    };
    CFDictionaryRef certDict = CFDictionaryCreate(NULL, certkeys, certvalues,
            array_size(certkeys), NULL, NULL);
    ok_status(SecItemAdd(certDict, NULL), "add certificate");
    CFReleaseNull(certDict);
    CFReleaseNull(cert);

    const void *privkeys[] = {
        kSecValueRef
    };
    const void *privvalues[] = {
        privKey
    };
    CFDictionaryRef privDict = CFDictionaryCreate(NULL, privkeys, privvalues,
            array_size(privkeys), NULL, NULL);
    ok_status(SecItemAdd(privDict, NULL), "add private key");
    CFReleaseNull(privDict);
    CFReleaseNull(privKey);
}
static void tests(void)
{
    CFErrorRef error = NULL;
    CFDataRef testData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)testbytes, testbytes_size, kCFAllocatorNull);

    SecCertificateRef cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, public_cert_der, sizeof(public_cert_der));
    CFArrayRef certInArray = CFArrayCreateForCFTypes(kCFAllocatorDefault, cert, NULL);

    SecKeyRef full_key = SecKeyCreateECPrivateKey(kCFAllocatorDefault, private_key_der, sizeof(private_key_der), kSecKeyEncodingPkcs1);

    SecTrustRef trust = NULL;
    SecPolicyRef basic = SecPolicyCreateBasicX509();
    OSStatus status = SecTrustCreateWithCertificates(cert, basic, &trust);
    ok_status(status, "created");
    CFReleaseNull(basic);
    status = SecTrustSetAnchorCertificates(trust, certInArray);
    ok_status(status, "Anchors");

    SecTrustResultType result;
    status = SecTrustEvaluate(trust, &result);
    ok_status(status, "Trust evaluation");
    is(result, (SecTrustResultType)kSecTrustResultUnspecified, "Trust result");

    CFDataRef encrypted = SecCopyEncryptedToServer(trust, testData, &error);
    ok(encrypted != NULL, "Encrypt to server (%@)", error);
    CFReleaseNull(error);

    ok(!CFEqualSafe(testData, encrypted), "encrypted different");

    CFDataRef decrypted = SecCopyDecryptedForServer(full_key, encrypted, &error);
    ok(decrypted != NULL, "Decrypt from server (%@)", error);
    ok(CFEqualSafe(testData, decrypted), "round trip");


    CFReleaseNull(cert);
    CFReleaseNull(certInArray);
    CFReleaseNull(trust);
    CFReleaseNull(testData);
    CFReleaseNull(encrypted);
    CFReleaseNull(decrypted);
}
static void tests(void)
{
	SecCertificateRef cert0;
	isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
		NULL, "create cert0");
    SecTrustStoreRef user_store;
    isnt(user_store = SecTrustStoreForDomain(kSecTrustStoreDomainUser),
        NULL, "get user trust settings store handle");
    ok(!SecTrustStoreContains(user_store, cert0),
        "cert0 is not yet present");
    ok_status(SecTrustStoreSetTrustSettings(user_store, cert0, NULL),
        "make cert0 trusted for anything");
    ok(SecTrustStoreContains(user_store, cert0),
        "cert0 is present");
    ok_status(SecTrustStoreSetTrustSettings(user_store, cert0, NULL),
        "make cert0 trusted for anything - again, should update now");
    ok(SecTrustStoreContains(user_store, cert0),
        "cert0 is still present");
    ok_status(SecTrustStoreRemoveCertificate(user_store, cert0),
        "removing cert0");
    ok(!SecTrustStoreContains(user_store, cert0),
        "cert0 is no longer present");

    /* Adding again...*/
    ok_status(SecTrustStoreSetTrustSettings(user_store, cert0, NULL),
        "make cert0 trusted for anything");
    ok(SecTrustStoreContains(user_store, cert0),
       "cert0 is present");

    /* Remove it */
    ok_status(SecTrustStoreRemoveCertificate(user_store, cert0),
              "removing cert0");
    ok(!SecTrustStoreContains(user_store, cert0),
       "cert0 is no longer present");

	CFReleaseSafe(cert0);
}
/* Create and identity and try to retrieve it. */
static void tests(void)
{
    SecCertificateRef cert = NULL;
    SecKeyRef privKey = NULL;
    SecIdentityRef identity = NULL;

    isnt(cert = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
            NULL, "create certificate");
    isnt(privKey = SecKeyCreateRSAPrivateKey(NULL, _k1, sizeof(_k1),
                kSecKeyEncodingPkcs1), NULL, "create private key");

    const void *certkeys[] = {
        kSecValueRef
    };
    const void *certvalues[] = {
        cert
    };
    CFDictionaryRef certDict = CFDictionaryCreate(NULL, certkeys, certvalues,
            array_size(certkeys), NULL, NULL);
    ok_status(SecItemAdd(certDict, NULL), "add certificate");
    CFReleaseNull(certDict);

    const void *privkeys[] = {
        kSecValueRef
    };
    const void *privvalues[] = {
        privKey
    };
    CFDictionaryRef privDict = CFDictionaryCreate(NULL, privkeys, privvalues,
            array_size(privkeys), NULL, NULL);
    ok_status(SecItemAdd(privDict, NULL), "add private key");
    CFReleaseNull(privDict);

    isnt(identity = SecIdentityCreate(NULL, cert, privKey), NULL, "create identity");

    /* Lookup the key and certificate using SecItemCopyMatching(). */
    CFDataRef pk_digest = CFDataCreate(NULL, _k1_digest, sizeof(_k1_digest));
    const void *q_keys[] = {
        kSecClass,
        kSecAttrApplicationLabel,
        kSecReturnRef
    };
    const void *q_values[] = {
        kSecClassKey,
        pk_digest,
        kCFBooleanTrue
    };
    CFDictionaryRef query = CFDictionaryCreate(NULL, q_keys, q_values,
            array_size(q_keys), NULL, NULL);
    CFTypeRef result_key;
    ok_status(SecItemCopyMatching(query, &result_key), "lookup key");

    isnt(CFEqual(privKey, result_key), 0, "keys match");
    CFReleaseNull(query);

    q_keys[1] = kSecAttrPublicKeyHash;
    q_values[0] = kSecClassCertificate;
    query = CFDictionaryCreate(NULL, q_keys, q_values,
            array_size(q_keys), NULL, NULL);
    CFTypeRef result_cert;
    ok_status(SecItemCopyMatching(query, &result_cert), "lookup certificate");
    isnt(CFEqual(cert, result_cert), 0, "certificates match");
    CFReleaseNull(query);

    /* Cleanup. */
    CFReleaseNull(result_key);
    CFReleaseNull(result_cert);

    /* identity lookup */
    const void *idnt_keys[] = {
        kSecClass,
        kSecAttrApplicationLabel,
        kSecReturnRef
    };
    const void *idnt_values[] = {
        kSecClassIdentity,
        pk_digest,
        kCFBooleanTrue
    };
    CFTypeRef result_idnt;
    SecCertificateRef result_cert2;
    query = CFDictionaryCreate(NULL, idnt_keys, idnt_values,
            array_size(idnt_keys), NULL, NULL);
    ok_status(SecItemCopyMatching(query, &result_idnt), "lookup identity");
    isnt(result_idnt, NULL, "found identity?");
    is(CFGetRetainCount(result_idnt), 1, "result_idnt rc = 1");
    isnt(CFEqual(identity, result_idnt), 0, "identities match");
    CFReleaseNull(identity);

    ok_status(SecIdentityCopyCertificate((SecIdentityRef)result_idnt, &result_cert2), "get cert from identity");
    isnt(CFEqual(cert, result_cert2), 0, "certificates match");
    CFRelease(query);
    CFRelease(pk_digest);
    CFReleaseNull(result_cert2);

    certDict = CFDictionaryCreate(NULL, certkeys, certvalues,
            array_size(certkeys), NULL, NULL);
    ok_status(SecItemDelete(certDict), "delete certificate via ref");
    is_status(errSecItemNotFound, SecItemCopyMatching(certDict, NULL), "verify certificate is gone");

    CFReleaseNull(certDict);

    privDict = CFDictionaryCreate(NULL, privkeys, privvalues,
            array_size(privkeys), NULL, NULL);
    ok_status(SecItemDelete(privDict), "delete key via ref");
    is_status(errSecItemNotFound, SecItemCopyMatching(privDict, NULL), "verify key is gone");
    CFReleaseNull(privDict);

    /* add certificate to offset cert row id from key row id */
    SecCertificateRef apple_ca_cert = NULL;
    isnt(apple_ca_cert = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
            NULL, "create apple ca certificate");
    CFDictionaryRef appleCertDict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&apple_ca_cert, 1, NULL, NULL);
    ok_status(SecItemAdd(appleCertDict, NULL), "add apple ca certificate to offset key and cert rowid");

    /* add identity, get persistent ref */
    const void *keys_identity[] = {     kSecValueRef,   kSecReturnPersistentRef };
    const void *values_identity[] = {   result_idnt,    kCFBooleanTrue };
    CFDictionaryRef identity_add = CFDictionaryCreate(NULL, keys_identity, values_identity,
        array_size(keys_identity), NULL, NULL);
    CFTypeRef persist = NULL;
    ok_status(SecItemAdd(identity_add, &persist), "add identity ref");
    ok(persist, "got back persistent ref");
    /* <rdar://problem/6537195> SecItemAdd returns success when it shouldn't */
    CFTypeRef persist_again = NULL;
    is_status(errSecDuplicateItem, SecItemAdd(identity_add, &persist_again),
        "fail to add identity ref again");
    ok(!persist_again, "no persistent ref this time");

    /* find by persistent ref */
    const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef };
    const void *values_persist[] = { kCFBooleanTrue, persist };
    CFDictionaryRef persist_find = CFDictionaryCreate(NULL, keys_persist, values_persist,
	(array_size(keys_persist)), NULL, NULL);
    CFTypeRef results2 = NULL;
    ok_status(SecItemCopyMatching(persist_find, &results2), "find identity by persistent ref");
    is(CFGetRetainCount(results2), 1, "results2 rc = 1");
    // not implemented ok(CFEqual(result_idnt, results2), "same item (attributes)");
    CFReleaseNull(results2);

    /* find identity, key and cert by ref and return persistent ref */
    const void *keys_ref_to_persist[] = { kSecReturnPersistentRef, kSecValueRef };
    const void *values_ref_to_persist[] = { kCFBooleanTrue, NULL };
    CFTypeRef items[] = { result_idnt, privKey, cert, NULL };
    CFTypeRef *item = items;
    while (*item) {
        values_ref_to_persist[1] = *item;
        CFDictionaryRef ref_to_persist_find = CFDictionaryCreate(NULL, keys_ref_to_persist, values_ref_to_persist,
            (array_size(keys_ref_to_persist)), NULL, NULL);
        results2 = NULL;
        ok_status(SecItemCopyMatching(ref_to_persist_find, &results2), "find persistent ref for identity ref");
        ok(NULL != results2, "good persistent ref");
        is(CFGetRetainCount(results2), 1, "results2 rc = 1");
        CFReleaseNull(results2);
        CFReleaseNull(ref_to_persist_find);
        item++;
    }

    /* delete identity by identity ref */
    ok_status(SecItemDelete(identity_add), "delete identity by identity ref");
    is(SecItemCopyMatching(persist_find, &results2), errSecItemNotFound,
        "make sure identity by persistent ref is no longer there");
    CFRelease(persist_find);
    CFReleaseNull(persist);
    ok_status(SecItemAdd(identity_add, &persist), "add identity ref back");
    CFRelease(identity_add);

    /* delete identity by persistent ref */
    CFDictionaryRef persist_delete = CFDictionaryCreate(NULL,
        &kSecValuePersistentRef, &persist, 1, NULL, NULL);
    ok_status(SecItemDelete(persist_delete),
        "delete identity by persistent ref");
    is(SecItemCopyMatching(persist_delete, &results2), errSecItemNotFound,
        "make sure identity by persistent ref is no longer there");
    CFRelease(persist_delete);
    CFReleaseNull(persist);

	/* add identity with a label set */
	CFStringRef zomg_label = CFSTR("zomg");
	CFMutableDictionaryRef lbl_idnt_query =
		CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
		&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	CFDictionarySetValue(lbl_idnt_query, kSecValueRef, result_idnt);
	CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
    ok_status(SecItemAdd(lbl_idnt_query, NULL), "add identity ref");

	/* find identity with label*/
	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
	CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
	ok_status(SecItemCopyMatching(lbl_idnt_query, NULL), "find identity by label");

	/* find certs with label */
	CFTypeRef zomg_cert;
	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassCertificate);
	CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
	CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
	ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_cert), "find cert by label");

	/* find keys with label */
	CFTypeRef zomg_key;
	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassKey);
	CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
	CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
	ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_key), "find key by label");

	/* update label on key */
	CFStringRef new_label_value = CFSTR("zzzomg");
	CFDictionaryRef new_label = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&kSecAttrLabel, (const void **)&new_label_value, 1, NULL, NULL);
	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecValueRef, zomg_key);
	ok_status(SecItemUpdate(lbl_idnt_query, new_label), "update label to zzzomg for key");

	CFTypeRef zomg_idnt = NULL;
	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
	CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
	CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
	ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "still finding zomg ident");
	CFReleaseNull(zomg_idnt);


	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecValueRef, zomg_cert);
	ok_status(SecItemUpdate(lbl_idnt_query, new_label), "update label to zzzomg for cert");
	CFReleaseNull(new_label);

	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
	CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, zomg_label);
	CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
	is_status(errSecItemNotFound, SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "no longer find identity by label");

	CFDictionaryRemoveAllValues(lbl_idnt_query);
	CFDictionarySetValue(lbl_idnt_query, kSecReturnRef, kCFBooleanTrue);
	CFDictionarySetValue(lbl_idnt_query, kSecAttrLabel, new_label_value);
	CFDictionarySetValue(lbl_idnt_query, kSecClass, kSecClassIdentity);
	ok_status(SecItemCopyMatching(lbl_idnt_query, &zomg_idnt), "finding ident with zzzomg label");

    /* Find zomg identity with canonical issuer */
    {
        unsigned char DN[] = {
            0x30, 0x32, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
            0x07, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x43, 0x41, 0x31, 0x1e, 0x30, 0x1c,
            0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x0c,
            0x0f, 0x70, 0x6c, 0x75, 0x74, 0x6f, 0x40, 0x70, 0x6c, 0x75, 0x74, 0x6f,
            0x2e, 0x63, 0x6f, 0x6d
        };
        unsigned int DN_len = 52;
        CFMutableDictionaryRef find_by_issuer = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
        CFDataRef issuer = SecCertificateGetNormalizedIssuerContent(cert);
        CFTypeRef found_by_issuer = NULL;
        CFDictionarySetValue(find_by_issuer, kSecAttrIssuer, issuer);
        CFDictionarySetValue(find_by_issuer, kSecClass, kSecClassIdentity);
        CFDictionarySetValue(find_by_issuer, kSecReturnRef, kCFBooleanTrue);
        ok_status(SecItemCopyMatching(find_by_issuer, &found_by_issuer), "find identity by cert issuer");
        ok(CFEqual(found_by_issuer, zomg_idnt), "should be same as zomg_idnt");
        CFReleaseNull(found_by_issuer);
        issuer = CFDataCreate(kCFAllocatorDefault, DN, DN_len);
        CFDictionarySetValue(find_by_issuer, kSecAttrIssuer, issuer);
        ok_status(SecItemCopyMatching(find_by_issuer, &found_by_issuer), "find identity by cert issuer");
        CFReleaseNull(issuer);
        ok(CFEqual(found_by_issuer, zomg_idnt), "should be same as zomg_idnt");
        CFReleaseNull(found_by_issuer);
        CFReleaseNull(find_by_issuer);
    }

    ok_status(SecItemDelete(lbl_idnt_query), "delete ident with zzzomg label");

    /* Delete the apple cert last */
    ok_status(SecItemDelete(appleCertDict), "delete apple ca certificate");
    CFReleaseNull(appleCertDict);
    CFReleaseNull(apple_ca_cert);

	CFRelease(zomg_key);
	CFRelease(zomg_cert);
	CFRelease(zomg_idnt);
	CFRelease(zomg_label);
	CFRelease(new_label_value);
	CFRelease(lbl_idnt_query);

    CFReleaseNull(result_idnt);
    CFReleaseNull(privKey);
    CFReleaseNull(cert);
}
static void tests(void)
{
	SecTrustRef trust;
	SecCertificateRef cert0, cert1;
	isnt(cert0 = SecCertificateCreateWithBytes(NULL, WWDR_NoRevInfo, sizeof(WWDR_NoRevInfo)),
			NULL, "create leaf");
	isnt(cert1 = SecCertificateCreateWithBytes(NULL, WWDR_CA, sizeof(WWDR_CA)),
			NULL, "create intermediate");
	CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
			&kCFTypeArrayCallBacks);
	CFArrayAppendValue(certs, cert0);
	CFArrayAppendValue(certs, cert1);

	/* at this point, we should have an OCSP responder for the WWDR-issued leaf cert,
	 * even though the leaf itself doesn't contain any revocation info.
	 */
	CFArrayRef ocspResponders = SecCertificateGetOCSPResponders(cert0);
	ok(ocspResponders != NULL, "synthesized OCSP responder successfully");

	SecPolicyRef signingPolicy = SecPolicyCreateCodeSigning();
	SecPolicyRef ocspPolicy = SecPolicyCreateRevocation();
	const void *v_policies[] = { signingPolicy, ocspPolicy };
	CFArrayRef policies = CFArrayCreate(NULL, v_policies,
			sizeof(v_policies) / sizeof(*v_policies), &kCFTypeArrayCallBacks);
	CFRelease(signingPolicy);
	CFRelease(ocspPolicy);
	ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
			"create trust");
	/* Aug 1st 2012. */
	CFGregorianDate g_date = { 2012, 8, 1, 12, 0, 0 }; // Aug 1 2012 12:00 PM
	CFDateRef date = CFDateCreate(kCFAllocatorDefault,
			CFGregorianDateGetAbsoluteTime(g_date, NULL));
#if 0
	/* will we trust the OCSP response for a verify date in the past?? */
	ok_status(SecTrustSetVerifyDate(trust, date), "set date");
#else
	ok_status(errSecSuccess, "using current date");
#endif

	SecTrustResultType trustResult;
	ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");

	/* The cert should either be reported as revoked (until Jan 13 2013),
	 * or as expired (after Jan 13 2013). That means its trust result value
     * should be 5 (kSecTrustResultRecoverableTrustFailure) or greater.
	 */
	ok(trustResult >= kSecTrustResultRecoverableTrustFailure,
       "trustResult must report a failure, cert is either expired or revoked");
#if 0
    fprintf(stderr, "=== trustResult %lu\n", trustResult);
    CFStringRef errStr = SecTrustCopyFailureDescription(trust);
    CFShow(errStr);
#endif

	CFReleaseSafe(trust);
	CFReleaseSafe(policies);
	CFReleaseSafe(certs);
	CFReleaseSafe(cert0);
	CFReleaseSafe(cert1);
	CFReleaseSafe(date);
}
/* Test basic add delete update copy matching stuff. */
static void tests(void)
{
    SecTrustRef trust;
	SecCertificateRef iAP1CA, iAP2CA, leaf0, leaf1;
	isnt(iAP1CA = SecCertificateCreateWithBytes(NULL, _iAP1CA, sizeof(_iAP1CA)),
		NULL, "create iAP1CA");
	isnt(iAP2CA = SecCertificateCreateWithBytes(NULL, _iAP2CA, sizeof(_iAP2CA)),
		NULL, "create iAP2CA");
	isnt(leaf0 = SecCertificateCreateWithBytes(NULL, _leaf0, sizeof(_leaf0)),
		NULL, "create leaf0");
	isnt(leaf1 = SecCertificateCreateWithBytes(NULL, _leaf1, sizeof(_leaf1)),
		NULL, "create leaf1");
    {
        // temporarily grab some stack space and fill it with 0xFF;
        // when we exit this scope, the stack pointer should shrink but leave the memory filled.
        // this tests for a stack overflow bug inside SecPolicyCreateiAP (rdar://16056248)
        char buf[2048];
        memset(buf, 0xFF, sizeof(buf));
    }
    SecPolicyRef policy = SecPolicyCreateiAP();
	const void *v_anchors[] = {
		iAP1CA,
		iAP2CA
	};
    CFArrayRef anchors = CFArrayCreate(NULL, v_anchors,
		array_size(v_anchors), NULL);
    CFArrayRef certs0 = CFArrayCreate(NULL, (const void **)&leaf0, 1, NULL);
    CFArrayRef certs1 = CFArrayCreate(NULL, (const void **)&leaf1, 1, NULL);
    ok_status(SecTrustCreateWithCertificates(certs0, policy, &trust), "create trust for leaf0");
	ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");

	/* Jan 1st 2008. */
	CFDateRef date = CFDateCreate(NULL, 220752000.0);
    ok_status(SecTrustSetVerifyDate(trust, date), "set date");

	SecTrustResultType trustResult;
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");

	is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");

	CFReleaseSafe(trust);
    ok_status(SecTrustCreateWithCertificates(certs1, policy, &trust), "create trust for leaf1");
	ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
	TODO:
	{
		todo("We need the actual iAP1 intermediate");
		is_status(trustResult, kSecTrustResultUnspecified,
			"trust is kSecTrustResultUnspecified");
	}

	CFReleaseSafe(anchors);
	CFReleaseSafe(certs1);
	CFReleaseSafe(certs0);
	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
	CFReleaseSafe(leaf0);
	CFReleaseSafe(leaf1);
	CFReleaseSafe(iAP1CA);
	CFReleaseSafe(iAP2CA);
	CFReleaseSafe(date);
}
/* Test basic add delete update copy matching stuff. */
static void tests(void)
{
	SecCertificateRef cert0, cert1, cert2, cert3, cert4, cert5, cert6;
	isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
		NULL, "create cert0");
	isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
		NULL, "create cert1");

    CFDataRef cert2Data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
        _c2, sizeof(_c2), kCFAllocatorNull);
	isnt(cert2 = SecCertificateCreateWithData(kCFAllocatorDefault, cert2Data),
		NULL, "create cert2");
    CFReleaseNull(cert2Data);

	isnt(cert3 = SecCertificateCreateWithBytes(NULL, _phased_c3, sizeof(_phased_c3)),
		NULL, "create cert3");

    CFDataRef cert4data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
        pem, sizeof(pem), kCFAllocatorNull);
    ok(cert4 = SecCertificateCreateWithPEM(NULL, cert4data), "create cert from pem");
    CFReleaseNull(cert4data);

	isnt(cert5 = SecCertificateCreateWithBytes(NULL, _elektron_v1_cert_der,
        sizeof(_elektron_v1_cert_der)), NULL, "create cert5");

	isnt(cert6 = SecCertificateCreateWithBytes(NULL, _wapi_as_der,
        sizeof(_wapi_as_der)), NULL, "create cert6");

    ok(SecCertificateIsSelfSignedCA(cert0), "cert0 is CA");
    ok(!SecCertificateIsSelfSignedCA(cert1), "cert1 is not CA");
    ok(SecCertificateIsSelfSignedCA(cert5), "cert5 is v1 CA");

    CFStringRef subjectSummary, issuerSummary;
    isnt(subjectSummary = SecCertificateCopySubjectSummary(cert1), NULL,
        "cert1 has a subject summary");
    isnt(issuerSummary = SecCertificateCopyIssuerSummary(cert1), NULL,
        "cert1 has an issuer summary");

    ok(subjectSummary && CFEqual(subjectSummary, CFSTR("www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.")),
        "subject summary is \"www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.\"");
    ok(issuerSummary && CFEqual(issuerSummary,
        CFSTR("Class 3 Public Primary Certification Authority")),
        "issuer summary is \"Class 3 Public Primary Certification Authority\"");

    CFArrayRef ntPrincipalNames;
    ok(ntPrincipalNames = SecCertificateCopyNTPrincipalNames(cert2),
        "SecCertificateCopyNTPrincipalNames");
    is(CFArrayGetCount(ntPrincipalNames), 1, "we got 1 princialname back");
    CFStringRef principal = (CFStringRef)CFArrayGetValueAtIndex(ntPrincipalNames, 0);
    ok(CFEqual(principal, CFSTR("*****@*****.**")),
        "first principal is [email protected]");
    CFReleaseSafe(ntPrincipalNames);

	CFReleaseSafe(subjectSummary);
	CFReleaseSafe(issuerSummary);

    isnt(subjectSummary = SecCertificateCopySubjectSummary(cert3), NULL,
        "cert3 has a subject summary");
	/* @@@ this causes a double free without an extra retain in obtainSummaryFromX501Name():
	       summary->description = string = copyDERThingDescription(kCFAllocatorDefault, value, true); */
	CFReleaseSafe(subjectSummary);

    isnt(subjectSummary = SecCertificateCopySubjectSummary(cert4), NULL,
        "cert4 has a subject summary");
    ok(subjectSummary && CFEqual(subjectSummary, CFSTR("S5L8900 Secure Boot")),
        "cert4 is S5L8900 Secure Boot");
	CFReleaseSafe(subjectSummary);

    CFStringRef desc = NULL;
    ok(desc = CFCopyDescription(cert4), "cert4 CFCopyDescription works");

	CFReleaseSafe(cert0);
	CFReleaseSafe(cert1);
	CFReleaseSafe(cert2);
	CFReleaseSafe(cert3);
	CFReleaseSafe(cert4);
	CFReleaseSafe(cert5);
	CFReleaseSafe(cert6);
	CFReleaseNull(desc);
}
/* Test basic add delete update copy matching stuff. */
static void tests(void)
{
    SecTrustRef trust;
	SecCertificateRef cert0, cert1;
	isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
		NULL, "create cert0");
	isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
		NULL, "create cert1");
	const void *v_certs[] = {
		cert0,
		cert1
	};
    SecPolicyRef policy = SecPolicyCreateSSL(false, NULL);
    CFArrayRef certs = CFArrayCreate(NULL, v_certs,
		array_size(v_certs), NULL);

    /* SecTrustCreateWithCertificates using single cert. */
    ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust),
        "create trust with single cert0");
    is(SecTrustGetCertificateCount(trust), 1, "cert count is 1");
    is(SecTrustGetCertificateAtIndex(trust, 0), cert0, "cert 0 is leaf");
    CFReleaseNull(trust);

    /* SecTrustCreateWithCertificates failures. */
    is_status(SecTrustCreateWithCertificates(kCFBooleanTrue, policy, &trust),
        errSecParam, "create trust with boolean instead of cert");
    is_status(SecTrustCreateWithCertificates(cert0, kCFBooleanTrue, &trust),
        errSecParam, "create trust with boolean instead of policy");

    /* SecTrustCreateWithCertificates using array of certs. */
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
    /* NOTE: prior to <rdar://11810677 SecTrustGetCertificateCount would return 1 at this point.
     * Now, however, we do an implicit SecTrustEvaluate to build the chain if it has not yet been
     * evaluated, so we now expect the full chain length.
     */
    is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
    is(SecTrustGetCertificateAtIndex(trust, 0), cert0, "cert 0 is leaf");

	/* Jan 1st 2006. */
	CFDateRef date = CFDateCreate(NULL, 157680000.0);
    ok_status(SecTrustSetVerifyDate(trust, date), "set date");

    is(SecTrustGetVerifyTime(trust), 157680000.0, "get date");

	SecTrustResultType trustResult;

SKIP: {
#ifdef NO_SERVER
    skip("Can't fail to connect to securityd in NO_SERVER mode", 4, false);
#endif
    // Test Restore OS environment
    SecServerSetMachServiceName("com.apple.security.doesn't-exist");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust without securityd running");
    is_status(trustResult, kSecTrustResultInvalid, "trustResult is kSecTrustResultInvalid");
	is(SecTrustGetCertificateCount(trust), 1, "cert count is 1 without securityd running");
    SecKeyRef pubKey = NULL;
    ok(pubKey = SecTrustCopyPublicKey(trust), "copy public key without securityd running");
    CFReleaseNull(pubKey);
    SecServerSetMachServiceName(NULL);
    // End of Restore OS environment tests
}

    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trustResult is kSecTrustResultUnspecified");

	is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");

	CFDataRef c0_serial = CFDataCreate(NULL, _c0_serial, sizeof(_c0_serial));
	CFDataRef serial;
	ok(serial = SecCertificateCopySerialNumber(cert0), "copy cert0 serial");
	ok(CFEqual(c0_serial, serial), "serial matches");

    CFArrayRef anchors = CFArrayCreate(NULL, (const void **)&cert1, 1, &kCFTypeArrayCallBacks);
    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");
	is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");

	CFReleaseSafe(anchors);
    anchors = CFArrayCreate(NULL, NULL, 0, NULL);
    ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set empty anchors list");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
		"trust is kSecTrustResultRecoverableTrustFailure");

	ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");

	ok_status(SecTrustSetAnchorCertificatesOnly(trust, true), "only trust passed in anchors (default)");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
		"trust is kSecTrustResultRecoverableTrustFailure");

    /* Test cert_1 intermididate from the keychain. */
    CFReleaseSafe(trust);
    ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust),
              "create trust with single cert0");
    ok_status(SecTrustSetVerifyDate(trust, date), "set date");

    // Add cert1
    CFDictionaryRef query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
        kSecClass, kSecClassCertificate, kSecValueRef, cert1, NULL);
    ok_status(SecItemAdd(query, NULL), "add cert1 to keychain");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
    // Cleanup added cert1.
    ok_status(SecItemDelete(query), "remove cert1 from keychain");
    CFReleaseSafe(query);
    is_status(trustResult, kSecTrustResultUnspecified,
              "trust is kSecTrustResultUnspecified");
	is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");

    /* Set certs to be the xedge2 leaf. */
	CFReleaseSafe(certs);
	const void *cert_xedge2;
	isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_certificate,
        sizeof(xedge2_certificate)), NULL, "create cert_xedge2");
    certs = CFArrayCreate(NULL, &cert_xedge2, 1, NULL);

	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
	CFReleaseSafe(date);
    bool server = true;
    policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
        "create trust for ssl server xedge2.apple.com");
    /* Jan 1st 2009. */
    date = CFDateCreate(NULL, 252288000.0);
    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");

	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
    server = false;
    policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
        "create trust for ssl client xedge2.apple.com");
    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
		"trust is kSecTrustResultRecoverableTrustFailure");

	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
    server = true;
    policy = SecPolicyCreateIPSec(server, CFSTR("xedge2.apple.com"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
        "create trust for ip server xedge2.apple.com");
    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
#if 0
    /* Although this shouldn't be a valid ipsec cert, since we no longer
       check for ekus in the ipsec policy it is. */
    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
		"trust is kSecTrustResultRecoverableTrustFailure");
#else
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");
#endif

	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
    server = true;
    policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
        "create trust for ssl server nowhere.com");
    SecPolicyRef replacementPolicy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
    SecTrustSetPolicies(trust, replacementPolicy);
    CFReleaseSafe(replacementPolicy);
    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");

	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
    server = true;
    policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
        "create trust for ssl server nowhere.com");
    SecPolicyRef replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
    CFArrayRef replacementPolicies = CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)&replacementPolicy2, 1, &kCFTypeArrayCallBacks);
    SecTrustSetPolicies(trust, replacementPolicies);
    CFReleaseSafe(replacementPolicy2);
    CFReleaseSafe(replacementPolicies);
    ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");

    /* Test self signed ssl cert with cert itself set as anchor. */
	CFReleaseSafe(trust);
	CFReleaseSafe(policy);
	CFReleaseSafe(certs);
	CFReleaseSafe(date);
	const void *garthc2;
    server = true;
	isnt(garthc2 = SecCertificateCreateWithBytes(NULL, garthc2_certificate,
        sizeof(garthc2_certificate)), NULL, "create garthc2");
    certs = CFArrayCreate(NULL, &garthc2, 1, NULL);
    policy = SecPolicyCreateSSL(server, CFSTR("garthc2.apple.com"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
        "create trust for ip server garthc2.apple.com");
    date = CFDateCreate(NULL, 269568000.0);
    ok_status(SecTrustSetVerifyDate(trust, date),
        "set garthc2 trust date to Aug 2009");
    ok_status(SecTrustSetAnchorCertificates(trust, certs),
        "set garthc2 as anchor");
    ok_status(SecTrustEvaluate(trust, &trustResult),
        "evaluate self signed cert with cert as anchor");
    is_status(trustResult, kSecTrustResultUnspecified,
		"trust is kSecTrustResultUnspecified");

	CFReleaseSafe(garthc2);
	CFReleaseSafe(cert_xedge2);
	CFReleaseSafe(anchors);
	CFReleaseSafe(trust);
	CFReleaseSafe(serial);
	CFReleaseSafe(c0_serial);
	CFReleaseSafe(policy);
	CFReleaseSafe(certs);
	CFReleaseSafe(cert0);
	CFReleaseSafe(cert1);
	CFReleaseSafe(date);
    
    /* Test prt_forest_fi */
    const void *prt_forest_fi;
    isnt(prt_forest_fi = SecCertificateCreateWithBytes(NULL, prt_forest_fi_certificate,
						 sizeof(prt_forest_fi_certificate)), NULL, "create prt_forest_fi");
    isnt(certs = CFArrayCreate(NULL, &prt_forest_fi, 1, NULL), NULL, "failed to create cert array");
    policy = SecPolicyCreateSSL(false, CFSTR("owa.prt-forest.fi"));
    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
	      "create trust for ip client owa.prt-forest.fi");
    date = CFDateCreate(NULL, 391578321.0);
    ok_status(SecTrustSetVerifyDate(trust, date),
	      "set owa.prt-forest.fi trust date to May 2013");
    
    SecKeyRef pubkey = SecTrustCopyPublicKey(trust);
    is(pubkey, NULL, "pubkey returned");
    
	CFReleaseSafe(certs);
    CFReleaseNull(prt_forest_fi);
    CFReleaseNull(policy);
    CFReleaseNull(trust);
    CFReleaseNull(pubkey);
    CFReleaseNull(date);

}