]> git.saurik.com Git - apple/security.git/blame - Security/libsecurity_keychain/lib/SecPolicy.cpp
Security-57031.30.12.tar.gz
[apple/security.git] / Security / libsecurity_keychain / lib / SecPolicy.cpp
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2002-2014 Apple Inc. All Rights Reserved.
427c49bc 3 *
b1ab9ed8 4 * @APPLE_LICENSE_HEADER_START@
d8f41ccd 5 *
b1ab9ed8
A
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.
d8f41ccd 12 *
b1ab9ed8
A
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.
d8f41ccd 20 *
b1ab9ed8
A
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>
427c49bc
A
30#include <Security/SecCertificate.h>
31#include <Security/SecCertificatePriv.h>
b1ab9ed8
A
32#include <security_keychain/Policies.h>
33#include <security_keychain/PolicyCursor.h>
34#include "SecBridge.h"
d8f41ccd 35#include "utilities/SecCFRelease.h"
b1ab9ed8
A
36
37
38// String constant declarations
39
40#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
41
42SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2");
43SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3");
44SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8");
45SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9");
46SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11");
47SEC_CONST_DECL (kSecPolicyAppleiChat, "1.2.840.113635.100.1.12");
48SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14");
49SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15");
50SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16");
51SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17");
52SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
53SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
54SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
427c49bc
A
55SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21");
56SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22");
57SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23");
58SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24");
59SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25");
60SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26");
61SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27");
d8f41ccd
A
62#if TARGET_OS_IPHONE
63SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner, "1.2.840.113635.100.1.28");
64SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner, "1.2.840.113635.100.1.29");
65/* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
66SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy, "1.2.840.113625.100.1.30");
67SEC_CONST_DECL (kSecPolicyAppleSMPEncryption, "1.2.840.113625.100.1.31");
68SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption, "1.2.840.113625.100.1.32");
69#endif
70SEC_CONST_DECL (kSecPolicyAppleServerAuthentication, "1.2.840.113635.100.1.33");
71SEC_CONST_DECL (kSecPolicyApplePCSEscrowService, "1.2.840.113635.100.1.34");
b1ab9ed8
A
72
73SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
74SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
75SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
427c49bc
A
76SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
77SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
b1ab9ed8
A
78
79SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature");
80SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation");
81SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment, "CE_KU_KeyEncipherment");
82SEC_CONST_DECL (kSecPolicyKU_DataEncipherment, "CE_KU_DataEncipherment");
83SEC_CONST_DECL (kSecPolicyKU_KeyAgreement, "CE_KU_KeyAgreement");
84SEC_CONST_DECL (kSecPolicyKU_KeyCertSign, "CE_KU_KeyCertSign");
85SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign");
86SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly");
87SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly");
88
427c49bc
A
89// Private functions
90
91SecPolicyRef SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr);
92extern "C" { CFArrayRef SecPolicyCopyEscrowRootCertificates(void); }
93
b1ab9ed8
A
94//
95// CF boilerplate
96//
97CFTypeID
98SecPolicyGetTypeID(void)
99{
100 BEGIN_SECAPI
101 return gTypes().Policy.typeID;
102 END_SECAPI1(_kCFRuntimeNotATypeID)
103}
104
105
106//
107// Sec API bridge functions
108//
109OSStatus
110SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
111{
427c49bc
A
112 BEGIN_SECAPI
113 Required(oid) = Policy::required(policyRef)->oid();
b1ab9ed8
A
114 END_SECAPI
115}
116
117OSStatus
118SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
119{
427c49bc
A
120 BEGIN_SECAPI
121 Required(value) = Policy::required(policyRef)->value();
b1ab9ed8
A
122 END_SECAPI
123}
124
125CFDictionaryRef
126SecPolicyCopyProperties(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
142OSStatus
143SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
144{
145 BEGIN_SECAPI
427c49bc
A
146 Required(value);
147 const CssmData newValue(value->Data, value->Length);
b1ab9ed8
A
148 Policy::required(policyRef)->setValue(newValue);
149 END_SECAPI
150}
151
152OSStatus
153SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties)
154{
155 BEGIN_SECAPI
156 Policy::required(policyRef)->setProperties(properties);
157 END_SECAPI
158}
159
160OSStatus
161SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
162{
427c49bc
A
163 BEGIN_SECAPI
164 Required(tpHandle) = Policy::required(policyRef)->tp()->handle();
b1ab9ed8
A
165 END_SECAPI
166}
167
168OSStatus
169SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
170{
427c49bc 171 BEGIN_SECAPI
b1ab9ed8
A
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
191OSStatus
192SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
193{
194 Required(policy);
195 Required(policyOID);
427c49bc 196
b1ab9ed8
A
197 SecPolicySearchRef srchRef = NULL;
198 OSStatus ortn;
427c49bc 199
b1ab9ed8
A
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 */
210SecPolicyRef
211SecPolicyCreateBasicX509(void)
212{
427c49bc
A
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 }
b1ab9ed8
A
220 if (policySearch) {
221 CFRelease(policySearch);
222 }
427c49bc 223 return policy;
b1ab9ed8
A
224}
225
226/* new in 10.6 */
227SecPolicyRef
228SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
229{
427c49bc
A
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
b1ab9ed8
A
239 char *strbuf = NULL;
240 const char *hostnamestr = NULL;
241 if (hostname) {
b1ab9ed8
A
242 hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
243 if (hostnamestr == NULL) {
427c49bc
A
244 CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1;
245 strbuf = (char *)malloc(maxLen);
246 if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) {
b1ab9ed8
A
247 hostnamestr = strbuf;
248 }
249 }
250 }
427c49bc 251 uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0;
b1ab9ed8
A
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);
427c49bc 256
b1ab9ed8
A
257 if (strbuf) {
258 free(strbuf);
259 }
260 }
261 if (policySearch) {
262 CFRelease(policySearch);
263 }
427c49bc
A
264 return policy;
265}
266
267SecPolicyRef
268SecPolicyCreateWithSecAsn1Oid(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;
b1ab9ed8
A
279}
280
281/* new in 10.7 */
282SecPolicyRef
283SecPolicyCreateWithOID(CFTypeRef policyOID)
284{
b1ab9ed8
A
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;
d8f41ccd
A
289 if (!oidStr) {
290 return policy;
291 }
427c49bc
A
292 struct oidmap_entry_t {
293 const CFTypeRef oidstr;
294 const SecAsn1Oid *oidptr;
b1ab9ed8 295 };
427c49bc
A
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 },
d8f41ccd 316 { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
427c49bc
A
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;
b1ab9ed8 321 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
427c49bc 322 oidPtr = (CSSM_OID*)oidmap[i].oidptr;
b1ab9ed8
A
323 break;
324 }
325 }
d8f41ccd
A
326 if (CFEqual(oidStr, kSecPolicyAppleServerAuthentication)) {
327 return SecPolicyCreateAppleSSLService(NULL);
328 }
b1ab9ed8
A
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 }
427c49bc
A
336 if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) {
337 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
338 }
339 if (!policy) {
340 policy = SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid*)oidPtr);
341 }
b1ab9ed8
A
342 }
343 return policy;
344}
427c49bc
A
345
346/* new in 10.9 */
347SecPolicyRef
348SecPolicyCreateWithProperties(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 */
357SecPolicyRef
358SecPolicyCreateRevocation(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);
d8f41ccd
A
363 if (policy) {
364 CSSM_DATA policyData = { (CSSM_SIZE)sizeof(CFOptionFlags), (uint8*)&revocationFlags };
365 SecPolicySetValue(policy, &policyData);
366 }
427c49bc
A
367 return policy;
368}
369
370/* new in 10.9 ***FIXME*** TO BE REMOVED */
371CFArrayRef SecPolicyCopyEscrowRootCertificates(void)
372{
373 return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
374}
375
d8f41ccd
A
376SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname)
377{
378 return SecPolicyCreateSSL(true, hostname);
379}
380
381SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname)
382{
383 return SecPolicyCreateSSL(true, hostname);
384}
385
386SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname)
387{
388 return SecPolicyCreateSSL(true, hostname);
389}
390
391SecPolicyRef 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.
420CFArrayRef
421SecPolicyCreateAppleTimeStampingAndRevocationPolicies(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