1
2//
3//  si-70-sectrust-unified.c
4//  regressions
5//
6//  Created by Ken McLeod on 2/4/13.
7//
8//
9#include <CoreFoundation/CoreFoundation.h>
10#include <Security/Security.h>
11#include <Security/SecCertificatePriv.h>
12#include <Security/SecInternal.h>
13#include <utilities/array_size.h>
14
15#include "Security_regressions.h"
16#include <test/testcert.h>
17
18/* This is a minimal test case to ensure that the functionality of
19 * <rdar://problem/11736016> TLF: SecTrust Unification is present
20 * and working. Needs to be expanded and split up into separate
21 * test case files in the future.
22 */
23
24/* SecPolicy: new in 7.0 */
25//CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef)
26//OSStatus SecTrustSetPolicies(SecTrustRef trust, CFTypeRef policies) /* (this was SPI in 6.0) */
27//SecPolicyRef SecPolicyCreateRevocation(CFIndex revocationFlags)
28//SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, CFDictionaryRef properties)
29
30/* SecTrust new in 7.0 */
31//OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
32//OSStatus SecTrustSetNetworkFetchAllowed(SecTrustRef trust, Boolean allowFetch)
33//OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust, Boolean *allowFetch)
34//OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, CFArrayRef *anchors)
35//CFDictionaryRef SecTrustCopyResult(SecTrustRef trust)
36//OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData)
37
38
39/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Operations/CN=xedge2.apple.com
40   issuer :/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority */
41const uint8_t xedge2_cert[1385]={
420x30,0x82,0x05,0x65,0x30,0x82,0x04,0xCE,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x46,
430x9C,0xDF,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
440x05,0x00,0x30,0x81,0xC3,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
450x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x45,0x6E,0x74,
460x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x31,0x3B,0x30,0x39,0x06,0x03,0x55,0x04,
470x0B,0x13,0x32,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
480x65,0x74,0x2F,0x43,0x50,0x53,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,0x2E,0x20,0x62,
490x79,0x20,0x72,0x65,0x66,0x2E,0x20,0x28,0x6C,0x69,0x6D,0x69,0x74,0x73,0x20,0x6C,
500x69,0x61,0x62,0x2E,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x13,0x1C,
510x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,
520x2E,0x6E,0x65,0x74,0x20,0x4C,0x69,0x6D,0x69,0x74,0x65,0x64,0x31,0x3A,0x30,0x38,
530x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
540x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,
550x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,
560x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x38,0x30,0x31,
570x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x32,
580x38,0x31,0x39,0x30,0x33,0x31,0x32,0x5A,0x30,0x81,0x83,0x31,0x0B,0x30,0x09,0x06,
590x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
600x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,
610x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,
620x6F,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x13,0x09,0x41,0x70,0x70,0x6C,
630x65,0x20,0x49,0x6E,0x63,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x13,0x13,
640x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x4F,0x70,0x65,0x72,0x61,0x74,0x69,
650x6F,0x6E,0x73,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x78,0x65,
660x64,0x67,0x65,0x32,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81,
670x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
680x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC7,0xF3,0xA1,0x0E,0x0E,
690xA4,0xDF,0xC5,0x3F,0x24,0x87,0xC3,0x6E,0xE7,0xD0,0x7C,0x2B,0x5A,0x1C,0xF3,0x67,
700x6C,0x6B,0x56,0x0A,0x95,0xC9,0xE5,0x13,0x28,0x6E,0x16,0x9D,0x4F,0xB1,0x76,0xFB,
710x7D,0x42,0x5B,0x2A,0x7C,0xCC,0x97,0x75,0xAA,0xA6,0xA9,0xDE,0xB2,0xEC,0xEF,0xE2,
720xAB,0x40,0xAE,0x9A,0x23,0xF0,0x6A,0x10,0xB3,0x75,0x27,0xF0,0xF4,0x7D,0x08,0x67,
730x8F,0xCE,0x41,0x24,0x74,0xAA,0x37,0xB6,0xC1,0x32,0x61,0xCF,0x7D,0x1C,0x21,0xCD,
740xCF,0x7C,0x9E,0xE2,0x48,0x03,0x7E,0x78,0xB3,0x86,0x3D,0x06,0x6B,0x39,0xEC,0xC8,
750x73,0x68,0xDB,0xE7,0x5B,0x97,0xF4,0xF9,0xA3,0xE7,0xFB,0x81,0x2E,0x4D,0x0B,0x3F,
760xA9,0xCA,0xDE,0x32,0x26,0xF3,0xF0,0x97,0x72,0x65,0xAB,0x02,0x03,0x01,0x00,0x01,
770xA3,0x82,0x02,0xA2,0x30,0x82,0x02,0x9E,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,
780x04,0x03,0x02,0x05,0xA0,0x30,0x2B,0x06,0x03,0x55,0x1D,0x10,0x04,0x24,0x30,0x22,
790x80,0x0F,0x32,0x30,0x30,0x38,0x30,0x31,0x32,0x39,0x31,0x38,0x33,0x33,0x31,0x33,
800x5A,0x81,0x0F,0x32,0x30,0x31,0x30,0x30,0x31,0x32,0x38,0x31,0x39,0x30,0x33,0x31,
810x32,0x5A,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,
820x04,0x03,0x02,0x06,0x40,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,
830x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x82,0x01,0x68,0x06,0x03,
840x55,0x1D,0x20,0x04,0x82,0x01,0x5F,0x30,0x82,0x01,0x5B,0x30,0x82,0x01,0x57,0x06,
850x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x4B,0x02,0x30,0x82,0x01,0x48,0x30,0x26,
860x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1A,0x68,0x74,0x74,0x70,
870x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,
880x65,0x74,0x2F,0x63,0x70,0x73,0x30,0x82,0x01,0x1C,0x06,0x08,0x2B,0x06,0x01,0x05,
890x05,0x07,0x02,0x02,0x30,0x82,0x01,0x0E,0x1A,0x82,0x01,0x0A,0x54,0x68,0x65,0x20,
900x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x53,0x53,0x4C,0x20,0x57,0x65,0x62,0x20,
910x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
920x74,0x69,0x6F,0x6E,0x20,0x50,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20,0x53,0x74,
930x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x20,0x28,0x43,0x50,0x53,0x29,0x20,0x61,0x76,
940x61,0x69,0x6C,0x61,0x62,0x6C,0x65,0x20,0x61,0x74,0x20,0x77,0x77,0x77,0x2E,0x65,
950x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,0x63,0x70,0x73,0x20,0x20,
960x69,0x73,0x20,0x68,0x65,0x72,0x65,0x62,0x79,0x20,0x69,0x6E,0x63,0x6F,0x72,0x70,
970x6F,0x72,0x61,0x74,0x65,0x64,0x20,0x69,0x6E,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,
980x20,0x75,0x73,0x65,0x20,0x6F,0x72,0x20,0x72,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65,
990x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,
1000x63,0x61,0x74,0x65,0x2E,0x20,0x20,0x54,0x68,0x69,0x73,0x20,0x43,0x50,0x53,0x20,
1010x63,0x6F,0x6E,0x74,0x61,0x69,0x6E,0x73,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74,
1020x69,0x6F,0x6E,0x73,0x20,0x6F,0x6E,0x20,0x77,0x61,0x72,0x72,0x61,0x6E,0x74,0x69,
1030x65,0x73,0x20,0x61,0x6E,0x64,0x20,0x6C,0x69,0x61,0x62,0x69,0x6C,0x69,0x74,0x69,
1040x65,0x73,0x2E,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,
1050x29,0x20,0x32,0x30,0x30,0x32,0x20,0x45,0x6E,0x74,0x72,0x75,0x73,0x74,0x20,0x4C,
1060x69,0x6D,0x69,0x74,0x65,0x64,0x30,0x33,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2C,0x30,
1070x2A,0x30,0x28,0xA0,0x26,0xA0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
1080x63,0x72,0x6C,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,0x2F,
1090x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2E,0x63,0x72,0x6C,0x30,0x33,0x06,0x08,0x2B,
1100x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x27,0x30,0x25,0x30,0x23,0x06,0x08,0x2B,
1110x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x17,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,
1120x6F,0x63,0x73,0x70,0x2E,0x65,0x6E,0x74,0x72,0x75,0x73,0x74,0x2E,0x6E,0x65,0x74,
1130x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF0,0x17,0x62,
1140x13,0x55,0x3D,0xB3,0xFF,0x0A,0x00,0x6B,0xFB,0x50,0x84,0x97,0xF3,0xED,0x62,0xD0,
1150x1A,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2D,0xEF,0xD9,0xAF,
1160x1A,0x89,0x40,0x53,0x75,0x48,0x26,0x59,0x2F,0xEC,0x11,0x18,0xC0,0xD1,0x7A,0x34,
1170x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x19,0x06,0x09,0x2A,
1180x86,0x48,0x86,0xF6,0x7D,0x07,0x41,0x00,0x04,0x0C,0x30,0x0A,0x1B,0x04,0x56,0x37,
1190x2E,0x31,0x03,0x02,0x03,0x28,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,
1200x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x77,0x33,0x2A,0x69,0x45,0x5A,0xB2,
1210xF5,0x74,0xF7,0xDF,0xC7,0x08,0x85,0x86,0x88,0x98,0x41,0x7F,0x57,0x49,0x01,0xBA,
1220x13,0x21,0x40,0xD0,0x0A,0x5C,0xA7,0x37,0xDF,0xB3,0x7E,0xF8,0xED,0x04,0x63,0xC3,
1230xE8,0x0F,0xA0,0xE5,0xC4,0x4F,0x3A,0x90,0xE4,0x87,0x5F,0xEC,0xDB,0x65,0x8B,0x6E,
1240x88,0x6E,0x6E,0xE4,0xBC,0x6A,0x7E,0x37,0x47,0x04,0xFF,0x09,0xC6,0x70,0xE1,0x65,
1250x8F,0xE3,0xE9,0x60,0xEB,0xE8,0x8E,0x29,0xAE,0xF9,0x81,0xCA,0x9A,0x97,0x3C,0x6F,
1260x7C,0xFA,0xA8,0x49,0xB4,0x33,0x76,0x9C,0x65,0x92,0x12,0xF6,0x7F,0x6A,0x62,0x84,
1270x29,0x5F,0x14,0x26,0x6E,0x07,0x6F,0x5C,0xB5,0x7C,0x21,0x64,0x7C,0xD9,0x93,0xF4,
1280x9C,0xC8,0xE7,0xEC,0xC6,0xAC,0x13,0xC4,0xF0
129};
130
131
132static void tests(void)
133{
134	SecTrustResultType trustResult;
135	SecTrustRef trust = NULL;
136    SecPolicyRef policy = NULL;
137    CFArrayRef certs = NULL;
138	CFDateRef date = NULL;
139
140	const void *cert_xedge2;
141	isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_cert,
142        sizeof(xedge2_cert)), NULL, "create cert_xedge2");
143    certs = CFArrayCreate(NULL, &cert_xedge2, 1, NULL);
144
145    bool server = true;
146    policy = SecPolicyCreateSSL(server, CFSTR("xedge.apple.com")); // deliberate hostname mismatch
147    ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
148        "create trust for ssl server xedge.apple.com");
149    CFReleaseSafe(certs);
150    date = CFDateCreate(NULL, 252288000.0); /* Jan 1st 2009 */
151    ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to Jan 1st 2009");
152    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge trust");
153    is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
154		"trust is kSecTrustResultRecoverableTrustFailure (hostname mismatch)");
155
156	/* Test SecPolicyCreateRevocation */
157	{
158		/* FIXME need to do more than just call the function, but it's a start */
159		SecPolicyRef revocation = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
160		isnt(revocation, NULL, "create revocation policy");
161		CFReleaseSafe(revocation);
162	}
163
164	/* Test SecTrustCopyPolicies */
165	{
166		CFArrayRef policies = NULL;
167		ok_status(SecTrustCopyPolicies(trust, &policies), "copy policies");
168		is((policies && (CFArrayGetCount(policies) > 0)), true, "non-empty policies");
169		CFReleaseSafe(policies);
170	}
171
172	/* Test SecTrustSetNetworkFetchAllowed */
173	{
174		Boolean curAllow, allow;
175		ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow));
176		allow = !curAllow; /* flip it and see if the setting sticks */
177		ok_status(SecTrustSetNetworkFetchAllowed(trust, allow));
178		ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow));
179		is((allow == curAllow), true, "network fetch toggle");
180	}
181
182	/* Test setting OCSP response data */
183	{
184		CFDataRef resp = (CFDataRef) CFDataCreateMutable(NULL, 0);
185		/* FIXME: use actual OCSPResponse DER blob */
186		CFDataIncreaseLength((CFMutableDataRef)resp, 64); /* arbitrary length, zero-filled data */
187
188		is_status(SecTrustSetOCSPResponse(NULL, resp), errSecParam, "SecTrustSetOCSPResponse param 1 check OK");
189		is_status(SecTrustSetOCSPResponse(trust, NULL), errSecSuccess, "SecTrustSetOCSPResponse param 2 check OK");
190		is_status(SecTrustSetOCSPResponse(trust, resp), errSecSuccess, "SecTrustSetOCSPResponse OK");
191        CFReleaseSafe(resp);
192	}
193
194	/* Test creation of a policy via SecPolicyCreateWithProperties */
195	CFReleaseNull(policy);
196	{
197		const void *keys[] = { kSecPolicyName, kSecPolicyClient };
198		const void *values[] = { CFSTR("xedge2.apple.com"), kCFBooleanFalse };
199		CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values,
200				array_size(keys),
201				&kCFTypeDictionaryKeyCallBacks,
202				&kCFTypeDictionaryValueCallBacks);
203		policy = SecPolicyCreateWithProperties(kSecPolicyAppleSSL, properties);
204		isnt(policy, NULL, "SecPolicyCreateWithProperties");
205		CFReleaseSafe(properties);
206	}
207
208	/* Test introspection of a policy's properties via SecPolicyCopyProperties */
209	{
210		CFDictionaryRef properties = NULL;
211		isnt(properties = SecPolicyCopyProperties(policy), NULL, "copy policy properties");
212		CFTypeRef value = NULL;
213		is(CFDictionaryGetValueIfPresent(properties, kSecPolicyName, (const void **)&value) &&
214			kCFCompareEqualTo == CFStringCompare((CFStringRef)value, CFSTR("xedge2.apple.com"), 0),
215        	true, "has policy name");
216		is(CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value) &&
217			CFEqual(value, kSecPolicyAppleSSL) , true, "has SSL policy");
218        CFReleaseSafe(properties);
219	}
220	/* Test setting new policy on a trust via SecTrustSetPolicies */
221	ok_status(SecTrustSetPolicies(trust, policy));
222	/* Evaluation should now succeed, since our new policy has the correct hostname */
223    ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
224    is_status(trustResult, kSecTrustResultUnspecified,
225		"trust is kSecTrustResultUnspecified");
226
227	/* Make sure we can get the results */
228	{
229		CFDictionaryRef results = NULL;
230		SecTrustResultType anotherResult = kSecTrustResultInvalid;
231		ok_status(SecTrustGetTrustResult(trust, &anotherResult), "get trust result");
232		is_status(trustResult, anotherResult, "trust is kSecTrustResultUnspecified");
233
234		isnt(results = SecTrustCopyResult(trust), NULL, "copy trust results");
235		CFReleaseSafe(results);
236	}
237
238	CFReleaseSafe(trust);
239	CFReleaseSafe(policy);
240	CFReleaseSafe(date);
241	CFReleaseSafe(cert_xedge2);
242}
243
244int si_70_sectrust_unified(int argc, char *const *argv)
245{
246	plan_tests(25);
247	tests();
248
249	return 0;
250}
251