]> git.saurik.com Git - apple/security.git/blob - libsecurity_keychain/lib/SecPolicy.cpp
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_keychain / lib / SecPolicy.cpp
1 /*
2 * Copyright (c) 2002-2013 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
36
37 // String constant declarations
38
39 #define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
40
41 SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2");
42 SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3");
43 SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8");
44 SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9");
45 SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11");
46 SEC_CONST_DECL (kSecPolicyAppleiChat, "1.2.840.113635.100.1.12");
47 SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14");
48 SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15");
49 SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16");
50 SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17");
51 SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
52 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
53 SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
54 SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21");
55 SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22");
56 SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23");
57 SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24");
58 SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25");
59 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26");
60 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27");
61
62
63 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
64 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
65 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
66 SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
67 SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
68
69 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature");
70 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation");
71 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment, "CE_KU_KeyEncipherment");
72 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment, "CE_KU_DataEncipherment");
73 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement, "CE_KU_KeyAgreement");
74 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign, "CE_KU_KeyCertSign");
75 SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign");
76 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly");
77 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly");
78
79 // Private functions
80
81 SecPolicyRef SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr);
82 extern "C" { CFArrayRef SecPolicyCopyEscrowRootCertificates(void); }
83
84 //
85 // CF boilerplate
86 //
87 CFTypeID
88 SecPolicyGetTypeID(void)
89 {
90 BEGIN_SECAPI
91 return gTypes().Policy.typeID;
92 END_SECAPI1(_kCFRuntimeNotATypeID)
93 }
94
95
96 //
97 // Sec API bridge functions
98 //
99 OSStatus
100 SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
101 {
102 BEGIN_SECAPI
103 Required(oid) = Policy::required(policyRef)->oid();
104 END_SECAPI
105 }
106
107 OSStatus
108 SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
109 {
110 BEGIN_SECAPI
111 Required(value) = Policy::required(policyRef)->value();
112 END_SECAPI
113 }
114
115 CFDictionaryRef
116 SecPolicyCopyProperties(SecPolicyRef policyRef)
117 {
118 /* can't use SECAPI macros, since this function does not return OSStatus */
119 CFDictionaryRef result = NULL;
120 try {
121 result = Policy::required(policyRef)->properties();
122 }
123 catch (...) {
124 if (result) {
125 CFRelease(result);
126 result = NULL;
127 }
128 };
129 return result;
130 }
131
132 OSStatus
133 SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
134 {
135 BEGIN_SECAPI
136 Required(value);
137 const CssmData newValue(value->Data, value->Length);
138 Policy::required(policyRef)->setValue(newValue);
139 END_SECAPI
140 }
141
142 OSStatus
143 SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties)
144 {
145 BEGIN_SECAPI
146 Policy::required(policyRef)->setProperties(properties);
147 END_SECAPI
148 }
149
150 OSStatus
151 SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
152 {
153 BEGIN_SECAPI
154 Required(tpHandle) = Policy::required(policyRef)->tp()->handle();
155 END_SECAPI
156 }
157
158 OSStatus
159 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
160 {
161 BEGIN_SECAPI
162 Required(policies);
163 CFMutableArrayRef currPolicies = NULL;
164 currPolicies = CFArrayCreateMutable(NULL, 0, NULL);
165 if ( currPolicies )
166 {
167 SecPointer<PolicyCursor> cursor(new PolicyCursor(NULL, NULL));
168 SecPointer<Policy> policy;
169 while ( cursor->next(policy) ) /* copies the next policy */
170 {
171 CFArrayAppendValue(currPolicies, policy->handle()); /* 'SecPolicyRef' appended */
172 CFRelease(policy->handle()); /* refcount bumped up when appended to array */
173 }
174 *policies = CFArrayCreateCopy(NULL, currPolicies);
175 CFRelease(currPolicies);
176 CFRelease(cursor->handle());
177 }
178 END_SECAPI
179 }
180
181 OSStatus
182 SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
183 {
184 Required(policy);
185 Required(policyOID);
186
187 SecPolicySearchRef srchRef = NULL;
188 OSStatus ortn;
189
190 ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef);
191 if(ortn) {
192 return ortn;
193 }
194 ortn = SecPolicySearchCopyNext(srchRef, policy);
195 CFRelease(srchRef);
196 return ortn;
197 }
198
199 /* new in 10.6 */
200 SecPolicyRef
201 SecPolicyCreateBasicX509(void)
202 {
203 // return a SecPolicyRef object for the X.509 Basic policy
204 SecPolicyRef policy = nil;
205 SecPolicySearchRef policySearch = nil;
206 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch);
207 if (!status) {
208 status = SecPolicySearchCopyNext(policySearch, &policy);
209 }
210 if (policySearch) {
211 CFRelease(policySearch);
212 }
213 return policy;
214 }
215
216 /* new in 10.6 */
217 SecPolicyRef
218 SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
219 {
220 // return a SecPolicyRef object for the SSL policy, given hostname and client options
221 SecPolicyRef policy = nil;
222 SecPolicySearchRef policySearch = nil;
223 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch);
224 if (!status) {
225 status = SecPolicySearchCopyNext(policySearch, &policy);
226 }
227 if (!status && policy) {
228 // set options for client-side or server-side policy evaluation
229 char *strbuf = NULL;
230 const char *hostnamestr = NULL;
231 if (hostname) {
232 hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
233 if (hostnamestr == NULL) {
234 CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1;
235 strbuf = (char *)malloc(maxLen);
236 if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) {
237 hostnamestr = strbuf;
238 }
239 }
240 }
241 uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0;
242 uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0;
243 CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
244 CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
245 SecPolicySetValue(policy, &data);
246
247 if (strbuf) {
248 free(strbuf);
249 }
250 }
251 if (policySearch) {
252 CFRelease(policySearch);
253 }
254 return policy;
255 }
256
257 SecPolicyRef
258 SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr)
259 {
260 SecPolicyRef policy = NULL;
261 try {
262 SecPointer<Policy> policyObj;
263 PolicyCursor::policy(oidPtr, policyObj);
264 policy = policyObj->handle();
265 }
266 catch (...) {}
267
268 return policy;
269 }
270
271 /* new in 10.7 */
272 SecPolicyRef
273 SecPolicyCreateWithOID(CFTypeRef policyOID)
274 {
275 // for now, we only accept the policy constants that are defined in SecPolicy.h
276 CFStringRef oidStr = (CFStringRef)policyOID;
277 CSSM_OID *oidPtr = NULL;
278 SecPolicyRef policy = NULL;
279 struct oidmap_entry_t {
280 const CFTypeRef oidstr;
281 const SecAsn1Oid *oidptr;
282 };
283 const oidmap_entry_t oidmap[] = {
284 { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC },
285 { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL },
286 { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME },
287 { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP },
288 { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC },
289 { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT },
290 { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT },
291 { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER },
292 { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING },
293 { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
294 { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING },
295 { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING },
296 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION },
297 { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
298 { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE },
299 { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE },
300 { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING },
301 { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
302 { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
303 };
304 unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
305 for (i=0; i<oidmaplen; i++) {
306 CFStringRef str = (CFStringRef) oidmap[i].oidstr;
307 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
308 oidPtr = (CSSM_OID*)oidmap[i].oidptr;
309 break;
310 }
311 }
312 if (oidPtr) {
313 SecPolicySearchRef policySearch = NULL;
314 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, oidPtr, NULL, &policySearch);
315 if (!status && policySearch) {
316 status = SecPolicySearchCopyNext(policySearch, &policy);
317 CFRelease(policySearch);
318 }
319 if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) {
320 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
321 }
322 if (!policy) {
323 policy = SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid*)oidPtr);
324 }
325 }
326 return policy;
327 }
328
329 /* new in 10.9 */
330 SecPolicyRef
331 SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, CFDictionaryRef properties)
332 {
333 SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier);
334 SecPolicySetProperties(policy, properties);
335
336 return policy;
337 }
338
339 /* new in 10.9 */
340 SecPolicyRef
341 SecPolicyCreateRevocation(CFOptionFlags revocationFlags)
342 {
343 // return a SecPolicyRef object for the unified revocation policy
344 SecAsn1Oid *oidPtr = (SecAsn1Oid*)&CSSMOID_APPLE_TP_REVOCATION;
345 SecPolicyRef policy = SecPolicyCreateWithSecAsn1Oid(oidPtr);
346 //%%% FIXME set policy value with revocationFlags
347
348 return policy;
349 }
350
351 /* new in 10.9 ***FIXME*** TO BE REMOVED */
352 CFArrayRef SecPolicyCopyEscrowRootCertificates(void)
353 {
354 return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
355 }
356