/* 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);
}
Exemple #2
0
int32_t AppleCryptoNative_X509ChainEvaluate(SecTrustRef chain,
                                            CFDateRef cfEvaluationTime,
                                            bool allowNetwork,
                                            int32_t* pOSStatus)
{
    if (pOSStatus != NULL)
        *pOSStatus = noErr;

    if (chain == NULL || pOSStatus == NULL)
        return -1;

    *pOSStatus = SecTrustSetVerifyDate(chain, cfEvaluationTime);

    if (*pOSStatus != noErr)
    {
        return -2;
    }

    *pOSStatus = SecTrustSetNetworkFetchAllowed(chain, allowNetwork);

    if (*pOSStatus != noErr)
    {
        return -3;
    }

    SecTrustResultType trustResult;
    *pOSStatus = SecTrustEvaluate(chain, &trustResult);

    // If any error is reported from the function or the trust result value indicates that
    // otherwise was a failed chain build (vs an untrusted chain, etc) return failure and
    // we'll throw in the managed layer.  (but if we hit the "or" the message is "No error")
    if (*pOSStatus != noErr || trustResult == kSecTrustResultInvalid)
    {
        return 0;
    }

    // If: The chain was built with no errors (Unspecified)
    // Or: The chain was built and involved an explicitly trusted cert (Proceed)
    // Then: Success.
    if (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)
    {
        return 1;
    }

    // Should this be a different return code?
    return 1;
}
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);
}
/*
** OLD OBSOLETE FUNCTIONS with enum SECCertUsage - DO NOT USE FOR NEW CODE
** verify a certificate by checking validity times against a certain time,
** that we trust the issuer, and that the signature on the certificate is
** valid.
**	"cert" the certificate to verify
**	"checkSig" only check signatures if true
*/
SECStatus
CERT_VerifyCert(SecKeychainRef keychainOrArray, SecCertificateRef cert,
		const CSSM_DATA_PTR *otherCerts,    /* intermediates */
		CFTypeRef policies, CFAbsoluteTime stime, SecTrustRef *trustRef)
{
    CFMutableArrayRef certificates = NULL;
    SecTrustRef trust = NULL;
    OSStatus rv;
    int numOtherCerts = SecCmsArrayCount((void **)otherCerts);
    int dex;
    
    /* 
     * Certs to evaluate: first the leaf - our cert - then all the rest we know
     * about. It's OK for otherCerts to contain a copy of the leaf. 
     */
    certificates = CFArrayCreateMutable(NULL, numOtherCerts + 1, &kCFTypeArrayCallBacks);
    CFArrayAppendValue(certificates, cert);
    for(dex=0; dex<numOtherCerts; dex++) {
	SecCertificateRef intCert;
	
	rv = SecCertificateCreateFromData(otherCerts[dex], 
	    CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
	    &intCert);
	if(rv) {
	    goto loser;
	}
	CFArrayAppendValue(certificates, intCert);
	CFRelease(intCert);
    }
    rv = SecTrustCreateWithCertificates(certificates, policies, &trust);
    CFRelease(certificates);
    certificates = NULL;
    if (rv)
	goto loser;

    rv = SecTrustSetKeychains(trust, keychainOrArray);
    if (rv)
	goto loser;

    CFDateRef verifyDate = CFDateCreate(NULL, stime);
    rv = SecTrustSetVerifyDate(trust, verifyDate);
    CFRelease(verifyDate);
    if (rv)
	goto loser;

    if (trustRef)
    {
	*trustRef = trust;
    }
    else
    {
	SecTrustResultType result;
	/* The caller doesn't want a SecTrust object, so let's evaluate it for them. */
	rv = SecTrustEvaluate(trust, &result);
	if (rv)
	    goto loser;

	switch (result)
	{
	case kSecTrustResultProceed:
	case kSecTrustResultUnspecified:
	    /* TP Verification succeeded and there was either a UserTurst entry
	       telling us to procceed, or no user trust setting was specified. */
	    CFRelease(trust);
	    break;
	default:
	    PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
	    rv = SECFailure;
	    goto loser;
	    break;
	}
    }

    return SECSuccess;
loser:
    if (trust)
	CFRelease(trust);
    if(certificates) 
	CFRelease(certificates);
    return rv;
}
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)
{
    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);

}