]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_keychain/lib/SecPolicy.cpp
Security-57031.10.10.tar.gz
[apple/security.git] / Security / libsecurity_keychain / lib / SecPolicy.cpp
1 /*
2 * Copyright (c) 2002-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <CoreFoundation/CFString.h>
25 #include <CoreFoundation/CFNumber.h>
26 #include <CoreFoundation/CFArray.h>
27 #include <Security/SecItem.h>
28 #include <Security/SecPolicy.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <Security/SecCertificate.h>
31 #include <Security/SecCertificatePriv.h>
32 #include <security_keychain/Policies.h>
33 #include <security_keychain/PolicyCursor.h>
34 #include "SecBridge.h"
35 #include "utilities/SecCFRelease.h"
36
37
38 // String constant declarations
39
40 #define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
41
42 SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2");
43 SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3");
44 SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8");
45 SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9");
46 SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11");
47 SEC_CONST_DECL (kSecPolicyAppleiChat, "1.2.840.113635.100.1.12");
48 SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14");
49 SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15");
50 SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16");
51 SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17");
52 SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
53 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
54 SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
55 SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21");
56 SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22");
57 SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23");
58 SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24");
59 SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25");
60 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26");
61 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27");
62 #if TARGET_OS_IPHONE
63 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner, "1.2.840.113635.100.1.28");
64 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner, "1.2.840.113635.100.1.29");
65 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
66 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy, "1.2.840.113625.100.1.30");
67 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption, "1.2.840.113625.100.1.31");
68 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption, "1.2.840.113625.100.1.32");
69 #endif
70 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication, "1.2.840.113635.100.1.33");
71 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService, "1.2.840.113635.100.1.34");
72
73 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
74 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
75 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
76 SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
77 SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
78
79 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature");
80 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation");
81 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment, "CE_KU_KeyEncipherment");
82 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment, "CE_KU_DataEncipherment");
83 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement, "CE_KU_KeyAgreement");
84 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign, "CE_KU_KeyCertSign");
85 SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign");
86 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly");
87 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly");
88
89 // Private functions
90
91 SecPolicyRef SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr);
92 extern "C" { CFArrayRef SecPolicyCopyEscrowRootCertificates(void); }
93
94 //
95 // CF boilerplate
96 //
97 CFTypeID
98 SecPolicyGetTypeID(void)
99 {
100 BEGIN_SECAPI
101 return gTypes().Policy.typeID;
102 END_SECAPI1(_kCFRuntimeNotATypeID)
103 }
104
105
106 //
107 // Sec API bridge functions
108 //
109 OSStatus
110 SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
111 {
112 BEGIN_SECAPI
113 Required(oid) = Policy::required(policyRef)->oid();
114 END_SECAPI
115 }
116
117 OSStatus
118 SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
119 {
120 BEGIN_SECAPI
121 Required(value) = Policy::required(policyRef)->value();
122 END_SECAPI
123 }
124
125 CFDictionaryRef
126 SecPolicyCopyProperties(SecPolicyRef policyRef)
127 {
128 /* can't use SECAPI macros, since this function does not return OSStatus */
129 CFDictionaryRef result = NULL;
130 try {
131 result = Policy::required(policyRef)->properties();
132 }
133 catch (...) {
134 if (result) {
135 CFRelease(result);
136 result = NULL;
137 }
138 };
139 return result;
140 }
141
142 OSStatus
143 SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
144 {
145 BEGIN_SECAPI
146 Required(value);
147 const CssmData newValue(value->Data, value->Length);
148 Policy::required(policyRef)->setValue(newValue);
149 END_SECAPI
150 }
151
152 OSStatus
153 SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties)
154 {
155 BEGIN_SECAPI
156 Policy::required(policyRef)->setProperties(properties);
157 END_SECAPI
158 }
159
160 OSStatus
161 SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
162 {
163 BEGIN_SECAPI
164 Required(tpHandle) = Policy::required(policyRef)->tp()->handle();
165 END_SECAPI
166 }
167
168 OSStatus
169 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
170 {
171 BEGIN_SECAPI
172 Required(policies);
173 CFMutableArrayRef currPolicies = NULL;
174 currPolicies = CFArrayCreateMutable(NULL, 0, NULL);
175 if ( currPolicies )
176 {
177 SecPointer<PolicyCursor> cursor(new PolicyCursor(NULL, NULL));
178 SecPointer<Policy> policy;
179 while ( cursor->next(policy) ) /* copies the next policy */
180 {
181 CFArrayAppendValue(currPolicies, policy->handle()); /* 'SecPolicyRef' appended */
182 CFRelease(policy->handle()); /* refcount bumped up when appended to array */
183 }
184 *policies = CFArrayCreateCopy(NULL, currPolicies);
185 CFRelease(currPolicies);
186 CFRelease(cursor->handle());
187 }
188 END_SECAPI
189 }
190
191 OSStatus
192 SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
193 {
194 Required(policy);
195 Required(policyOID);
196
197 SecPolicySearchRef srchRef = NULL;
198 OSStatus ortn;
199
200 ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef);
201 if(ortn) {
202 return ortn;
203 }
204 ortn = SecPolicySearchCopyNext(srchRef, policy);
205 CFRelease(srchRef);
206 return ortn;
207 }
208
209 /* new in 10.6 */
210 SecPolicyRef
211 SecPolicyCreateBasicX509(void)
212 {
213 // return a SecPolicyRef object for the X.509 Basic policy
214 SecPolicyRef policy = nil;
215 SecPolicySearchRef policySearch = nil;
216 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch);
217 if (!status) {
218 status = SecPolicySearchCopyNext(policySearch, &policy);
219 }
220 if (policySearch) {
221 CFRelease(policySearch);
222 }
223 return policy;
224 }
225
226 /* new in 10.6 */
227 SecPolicyRef
228 SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
229 {
230 // return a SecPolicyRef object for the SSL policy, given hostname and client options
231 SecPolicyRef policy = nil;
232 SecPolicySearchRef policySearch = nil;
233 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch);
234 if (!status) {
235 status = SecPolicySearchCopyNext(policySearch, &policy);
236 }
237 if (!status && policy) {
238 // set options for client-side or server-side policy evaluation
239 char *strbuf = NULL;
240 const char *hostnamestr = NULL;
241 if (hostname) {
242 hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
243 if (hostnamestr == NULL) {
244 CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1;
245 strbuf = (char *)malloc(maxLen);
246 if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) {
247 hostnamestr = strbuf;
248 }
249 }
250 }
251 uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0;
252 uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0;
253 CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
254 CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
255 SecPolicySetValue(policy, &data);
256
257 if (strbuf) {
258 free(strbuf);
259 }
260 }
261 if (policySearch) {
262 CFRelease(policySearch);
263 }
264 return policy;
265 }
266
267 SecPolicyRef
268 SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr)
269 {
270 SecPolicyRef policy = NULL;
271 try {
272 SecPointer<Policy> policyObj;
273 PolicyCursor::policy(oidPtr, policyObj);
274 policy = policyObj->handle();
275 }
276 catch (...) {}
277
278 return policy;
279 }
280
281 /* new in 10.7 */
282 SecPolicyRef
283 SecPolicyCreateWithOID(CFTypeRef policyOID)
284 {
285 // for now, we only accept the policy constants that are defined in SecPolicy.h
286 CFStringRef oidStr = (CFStringRef)policyOID;
287 CSSM_OID *oidPtr = NULL;
288 SecPolicyRef policy = NULL;
289 if (!oidStr) {
290 return policy;
291 }
292 struct oidmap_entry_t {
293 const CFTypeRef oidstr;
294 const SecAsn1Oid *oidptr;
295 };
296 const oidmap_entry_t oidmap[] = {
297 { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC },
298 { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL },
299 { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME },
300 { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP },
301 { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC },
302 { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT },
303 { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT },
304 { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER },
305 { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING },
306 { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
307 { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING },
308 { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING },
309 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION },
310 { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
311 { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE },
312 { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE },
313 { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING },
314 { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
315 { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
316 { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
317 };
318 unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
319 for (i=0; i<oidmaplen; i++) {
320 CFStringRef str = (CFStringRef) oidmap[i].oidstr;
321 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
322 oidPtr = (CSSM_OID*)oidmap[i].oidptr;
323 break;
324 }
325 }
326 if (CFEqual(oidStr, kSecPolicyAppleServerAuthentication)) {
327 return SecPolicyCreateAppleSSLService(NULL);
328 }
329 if (oidPtr) {
330 SecPolicySearchRef policySearch = NULL;
331 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, oidPtr, NULL, &policySearch);
332 if (!status && policySearch) {
333 status = SecPolicySearchCopyNext(policySearch, &policy);
334 CFRelease(policySearch);
335 }
336 if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) {
337 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
338 }
339 if (!policy) {
340 policy = SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid*)oidPtr);
341 }
342 }
343 return policy;
344 }
345
346 /* new in 10.9 */
347 SecPolicyRef
348 SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, CFDictionaryRef properties)
349 {
350 SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier);
351 SecPolicySetProperties(policy, properties);
352
353 return policy;
354 }
355
356 /* new in 10.9 */
357 SecPolicyRef
358 SecPolicyCreateRevocation(CFOptionFlags revocationFlags)
359 {
360 // return a SecPolicyRef object for the unified revocation policy
361 SecAsn1Oid *oidPtr = (SecAsn1Oid*)&CSSMOID_APPLE_TP_REVOCATION;
362 SecPolicyRef policy = SecPolicyCreateWithSecAsn1Oid(oidPtr);
363 if (policy) {
364 CSSM_DATA policyData = { (CSSM_SIZE)sizeof(CFOptionFlags), (uint8*)&revocationFlags };
365 SecPolicySetValue(policy, &policyData);
366 }
367 return policy;
368 }
369
370 /* new in 10.9 ***FIXME*** TO BE REMOVED */
371 CFArrayRef SecPolicyCopyEscrowRootCertificates(void)
372 {
373 return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
374 }
375
376 SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname)
377 {
378 return SecPolicyCreateSSL(true, hostname);
379 }
380
381 SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname)
382 {
383 return SecPolicyCreateSSL(true, hostname);
384 }
385
386 SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname)
387 {
388 return SecPolicyCreateSSL(true, hostname);
389 }
390
391 SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname)
392 {
393 // SSL server, pinned to an Apple intermediate
394 SecPolicyRef policy = SecPolicyCreateSSL(true, hostname);
395 if (policy) {
396 // change options for policy evaluation
397 char *strbuf = NULL;
398 const char *hostnamestr = NULL;
399 if (hostname) {
400 hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
401 if (hostnamestr == NULL) {
402 CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1;
403 strbuf = (char *)malloc(maxLen);
404 if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) {
405 hostnamestr = strbuf;
406 }
407 }
408 }
409 uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0;
410 uint32 flags = 0x00000002; // 2nd-lowest bit set to require Apple intermediate pin
411 CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
412 CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
413 SecPolicySetValue(policy, &data);
414 }
415 return policy;
416 }
417 #include <security_utilities/cfutilities.h>
418 /* New in 10.10 */
419 // Takes the "context" policies to extract the revocation and apply it to timeStamp.
420 CFArrayRef
421 SecPolicyCreateAppleTimeStampingAndRevocationPolicies(CFTypeRef policyOrArray)
422 {
423 /* can't use SECAPI macros, since this function does not return OSStatus */
424 CFArrayRef resultPolicyArray=NULL;
425 try {
426 // Set default policy
427 CFRef<CFArrayRef> policyArray = cfArrayize(policyOrArray);
428 CFRef<SecPolicyRef> defaultPolicy = SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping);
429 CFRef<CFMutableArrayRef> appleTimeStampingPolicies = makeCFMutableArray(1,defaultPolicy.get());
430
431 // Parse the policy and add revocation related ones
432 CFIndex numPolicies = CFArrayGetCount(policyArray);
433 for(CFIndex dex=0; dex<numPolicies; dex++) {
434 SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policyArray, dex);
435 SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
436 const CssmOid &oid = pol->oid();
437 if ((oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION))
438 || (oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL))
439 || (oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP)))
440 {
441 CFArrayAppendValue(appleTimeStampingPolicies, secPol);
442 }
443 }
444 // Transfer of ownership
445 resultPolicyArray=appleTimeStampingPolicies.yield();
446 }
447 catch (...) {
448 CFReleaseNull(resultPolicyArray);
449 };
450 return resultPolicyArray;
451 }
452
453