/* 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);
}
Exemplo n.º 2
0
/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
OSStatus
SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
{
	/* bridge to support API functionality for legacy callers */
	OSStatus status = errSecSuccess;
	CFDataRef encodedExceptions = SecTrustCopyExceptions(trustRef);
	CFArrayRef exceptions = NULL,
            oldExceptions = SecTrustGetTrustExceptionsArray(trustRef);

	if (encodedExceptions) {
		exceptions = (CFArrayRef)CFPropertyListCreateWithData(kCFAllocatorDefault,
			encodedExceptions, kCFPropertyListImmutable, NULL, NULL);
		CFRelease(encodedExceptions);
		encodedExceptions = NULL;
	}

	if (exceptions && CFGetTypeID(exceptions) != CFArrayGetTypeID()) {
		CFRelease(exceptions);
		exceptions = NULL;
	}

	if (oldExceptions && exceptions &&
		CFArrayGetCount(oldExceptions) > CFArrayGetCount(exceptions)) {
		oldExceptions = NULL;
	}

	/* verify both exceptions are for the same leaf */
	if (oldExceptions && exceptions && CFArrayGetCount(oldExceptions) > 0) {
		CFDictionaryRef oldLeafExceptions = (CFDictionaryRef)CFArrayGetValueAtIndex(oldExceptions, 0);
		CFDictionaryRef leafExceptions = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, 0);
		CFDataRef oldDigest = (CFDataRef)CFDictionaryGetValue(oldLeafExceptions, CFSTR("SHA1Digest"));
		CFDataRef digest = (CFDataRef)CFDictionaryGetValue(leafExceptions, CFSTR("SHA1Digest"));
		if (!oldDigest || !digest || !CFEqual(oldDigest, digest)) {
			oldExceptions = NULL;
		}
	}

	/* add only those exceptions which are allowed by the supplied options */
	if (exceptions) {
		CFMutableArrayRef filteredExceptions = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
		CFIndex i, exceptionCount = (filteredExceptions) ? CFArrayGetCount(exceptions) : 0;

		for (i = 0; i < exceptionCount; ++i) {
			CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, i);
			CFDictionaryRef oldException = NULL;
			if (oldExceptions && i < CFArrayGetCount(oldExceptions)) {
				oldException = (CFDictionaryRef)CFArrayGetValueAtIndex(oldExceptions, i);
			}
			CFMutableDictionaryRef filteredException = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
																				 &kCFTypeDictionaryValueCallBacks);
			if (exception && filteredException) {
				SecExceptionFilterContext filterContext = { options, i, trustRef, filteredException, oldException };
				CFDictionaryApplyFunction(exception, filter_exception, &filterContext);
				CFArrayAppendValue(filteredExceptions, filteredException);
				CFRelease(filteredException);
			}
		}

		if (filteredExceptions) {
			CFIndex filteredCount = CFArrayGetCount(filteredExceptions);
			/* remove empty trailing entries to match iOS behavior */
			for (i = filteredCount; i-- > 1;) {
				CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(filteredExceptions, i);
				if (CFDictionaryGetCount(exception) == 0) {
					CFArrayRemoveValueAtIndex(filteredExceptions, i);
				} else {
					break;
				}
			}
			encodedExceptions = CFPropertyListCreateData(kCFAllocatorDefault,
				filteredExceptions, kCFPropertyListBinaryFormat_v1_0, 0, NULL);
			CFRelease(filteredExceptions);

			SecTrustSetExceptions(trustRef, encodedExceptions);
			CFRelease(encodedExceptions);
		}
		CFRelease(exceptions);
	}

#if SECTRUST_DEPRECATION_WARNINGS
	bool displayModifyMsg = false;
	bool displayNetworkMsg = false;
	bool displayPolicyMsg = false;
	const char *baseMsg = "WARNING: SecTrustSetOptions called with";
	const char *modifyMsg = "Use SecTrustSetExceptions and SecTrustCopyExceptions to modify default trust results.";
	const char *networkMsg = "Use SecTrustSetNetworkFetchAllowed to specify whether missing certificates can be fetched from the network.";
	const char *policyMsg = "Use SecPolicyCreateRevocation to specify revocation policy requirements.";

	if (options & kSecTrustOptionAllowExpired) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionAllowExpired");
		displayModifyMsg = true;
	}
	if (options & kSecTrustOptionAllowExpiredRoot) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionAllowExpiredRoot");
		displayModifyMsg = true;
	}
	if (options & kSecTrustOptionFetchIssuerFromNet) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionFetchIssuerFromNet");
		displayNetworkMsg = true;
	}
	if (options & kSecTrustOptionRequireRevPerCert) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionRequireRevPerCert");
		displayPolicyMsg = true;
	}
	if (displayModifyMsg || displayNetworkMsg || displayPolicyMsg) {
		syslog(LOG_ERR, "%s %s %s",
			(displayModifyMsg) ? modifyMsg : "",
			(displayNetworkMsg) ? networkMsg : "",
			(displayPolicyMsg) ? policyMsg : "");
	}
#endif

	return status;
}