2 * Copyright (c) 2015 Apple Inc. All Rights Reserved.
5 #include <Security/SecPolicyPriv.h>
6 #include <Security/SecTrust.h>
7 #include <Security/SecTrustPriv.h>
8 #include <Security/SecCertificatePriv.h>
9 #include <AssertMacros.h>
10 #include <utilities/SecCFWrappers.h>
12 #include "shared_regressions.h"
14 #include "si-85-sectrust-ssl-policy.h"
16 static void runTestForDictionary (const void *test_key
, const void *test_value
, void *context
) {
17 CFDictionaryRef test_info
= test_value
;
18 CFStringRef test_name
= test_key
, file
= NULL
, reason
= NULL
, expectedResult
= NULL
, failReason
= NULL
;
19 CFURLRef cert_file_url
= NULL
;
20 CFDataRef cert_data
= NULL
;
21 bool expectTrustSuccess
= false;
23 SecCertificateRef leaf
= NULL
, root
= NULL
;
24 CFStringRef hostname
= NULL
;
25 SecPolicyRef policy
= NULL
;
26 SecTrustRef trust
= NULL
;
27 CFArrayRef anchor_array
= NULL
;
28 CFDateRef date
= NULL
;
30 /* Note that this is built without many of the test convenience macros
31 * in order to ensure there's only one "test" per test.
34 /* get filename in test dictionary */
35 file
= CFDictionaryGetValue(test_info
, CFSTR("Filename"));
36 require_action_quiet(file
, cleanup
, fail("%@: Unable to load filename from plist", test_name
));
38 /* get leaf certificate from file */
39 cert_file_url
= CFBundleCopyResourceURL(CFBundleGetMainBundle(), file
, CFSTR("cer"), CFSTR("ssl-policy-certs"));
40 require_action_quiet(cert_file_url
, cleanup
, fail("%@: Unable to get url for cert file %@",
44 require_action_quiet(CFURLCreateDataAndPropertiesFromResource(NULL
, cert_file_url
, &cert_data
, NULL
, NULL
, &errorCode
),
46 fail("%@: Could not create cert data for %@ with error %d",
47 test_name
, file
, (int)errorCode
));
49 /* create certificates */
50 leaf
= SecCertificateCreateWithData(NULL
, cert_data
);
51 root
= SecCertificateCreateWithBytes(NULL
, _SSLTrustPolicyTestRootCA
, sizeof(_SSLTrustPolicyTestRootCA
));
53 require_action_quiet(leaf
&& root
, cleanup
, fail("%@: Unable to create certificates", test_name
));
56 hostname
= CFDictionaryGetValue(test_info
, CFSTR("Hostname"));
57 require_action_quiet(hostname
, cleanup
, fail("%@: Unable to load hostname from plist", test_name
));
59 policy
= SecPolicyCreateSSL(true, hostname
);
60 require_action_quiet(policy
, cleanup
, fail("%@: Unable to create SSL policy with hostname %@",
61 test_name
, hostname
));
63 /* create trust ref */
64 OSStatus err
= SecTrustCreateWithCertificates(leaf
, policy
, &trust
);
66 require_noerr_action(err
, cleanup
, ok_status(err
, "SecTrustCreateWithCertificates"));
68 /* set anchor in trust ref */
69 anchor_array
= CFArrayCreate(NULL
, (const void **)&root
, 1, &kCFTypeArrayCallBacks
);
70 require_action_quiet(anchor_array
, cleanup
, fail("%@: Unable to create anchor array", test_name
));
71 err
= SecTrustSetAnchorCertificates(trust
, anchor_array
);
72 require_noerr_action(err
, cleanup
, ok_status(err
, "SecTrustSetAnchorCertificates"));
74 /* set date in trust ref to 4 Sep 2015 */
75 date
= CFDateCreate(NULL
, 463079909.0);
76 require_action_quiet(date
, cleanup
, fail("%@: Unable to create verify date", test_name
));
77 err
= SecTrustSetVerifyDate(trust
, date
);
79 require_noerr_action(err
, cleanup
, ok_status(err
, "SecTrustSetVerifyDate"));
82 SecTrustResultType actualResult
= 0;
83 err
= SecTrustEvaluate(trust
, &actualResult
);
84 require_noerr_action(err
, cleanup
, ok_status(err
, "SecTrustEvaluate"));
85 bool is_valid
= (actualResult
== kSecTrustResultProceed
|| actualResult
== kSecTrustResultUnspecified
);
86 if (!is_valid
) failReason
= SecTrustCopyFailureDescription(trust
);
88 /* get expected result for test */
89 expectedResult
= CFDictionaryGetValue(test_info
, CFSTR("Result"));
90 require_action_quiet(expectedResult
, cleanup
, fail("%@: Unable to get expected result",test_name
));
91 if (!CFStringCompare(expectedResult
, CFSTR("kSecTrustResultUnspecified"), 0) ||
92 !CFStringCompare(expectedResult
, CFSTR("kSecTrustResultProceed"), 0)) {
93 expectTrustSuccess
= true;
97 if(!CFDictionaryGetValueIfPresent(test_info
, CFSTR("Reason"), (const void **)&reason
)) {
98 /* not a known failure */
99 ok(is_valid
== expectTrustSuccess
, "%s %@%@",
100 expectTrustSuccess
? "REGRESSION" : "SECURITY",
102 failReason
? failReason
: CFSTR(""));
106 todo(CFStringGetCStringPtr(reason
, kCFStringEncodingUTF8
));
107 ok(is_valid
== expectTrustSuccess
, "%@%@",
108 test_name
, expectTrustSuccess
? (failReason
? failReason
: CFSTR("")) : CFSTR(" valid"));
111 fail("%@: unable to get reason for known failure", test_name
);
115 CFReleaseNull(cert_file_url
);
118 CFReleaseNull(trust
);
119 CFReleaseNull(anchor_array
);
120 CFReleaseNull(failReason
);
123 static void tests(void)
125 CFDataRef plist_data
= NULL
;
126 CFArrayRef plist
= NULL
;
127 CFPropertyListRef tests_dictionary
= NULL
;
129 plist
= CFBundleCopyResourceURLsOfType(CFBundleGetMainBundle(), CFSTR("plist"), CFSTR("ssl-policy-certs"));
130 if (CFArrayGetCount(plist
) != 1) {
131 fail("Incorrect number of plists found in ssl-policy-certs");
136 if(!CFURLCreateDataAndPropertiesFromResource(NULL
, CFArrayGetValueAtIndex(plist
, 0), &plist_data
, NULL
, NULL
, &errorCode
)) {
137 fail("Could not create data from plist with error %d", (int)errorCode
);
142 tests_dictionary
= CFPropertyListCreateWithData(NULL
, plist_data
, kCFPropertyListImmutable
, NULL
, &err
);
143 if(!tests_dictionary
|| (CFGetTypeID(tests_dictionary
) != CFDictionaryGetTypeID())) {
144 fail("Failed to create tests dictionary from plist");
148 CFDictionaryApplyFunction(tests_dictionary
, runTestForDictionary
, NULL
);
151 CFReleaseNull(plist
);
152 CFReleaseNull(plist_data
);
153 CFReleaseNull(tests_dictionary
);
156 int si_85_sectrust_ssl_policy(int argc
, char *const *argv
)