]> git.saurik.com Git - apple/security.git/blob - libsecurity_keychain/lib/SecTrust.cpp
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_keychain / lib / SecTrust.cpp
1 /*
2 * Copyright (c) 2002-2010 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 "SecTrust.h"
25 #include "SecTrustPriv.h"
26 #include "Trust.h"
27 #include <security_keychain/SecTrustSettingsPriv.h>
28 #include "SecBridge.h"
29 #include "SecTrustSettings.h"
30 #include "SecCertificatePriv.h"
31 #include <security_utilities/cfutilities.h>
32 #include <CoreFoundation/CoreFoundation.h>
33
34
35 //
36 // CF boilerplate
37 //
38 CFTypeID SecTrustGetTypeID(void)
39 {
40 BEGIN_SECAPI
41
42 return gTypes().Trust.typeID;
43
44 END_SECAPI1(_kCFRuntimeNotATypeID)
45 }
46
47
48 //
49 // Sec* API bridge functions
50 //
51 OSStatus SecTrustCreateWithCertificates(
52 CFArrayRef certificates,
53 CFTypeRef policies,
54 SecTrustRef *trustRef)
55 {
56 BEGIN_SECAPI
57 Required(trustRef);
58 *trustRef = (new Trust(certificates, policies))->handle();
59 END_SECAPI
60 }
61
62 OSStatus
63 SecTrustSetPolicies(SecTrustRef trustRef, CFTypeRef policies)
64 {
65 BEGIN_SECAPI
66 Trust::required(trustRef)->policies(policies);
67 END_SECAPI
68 }
69
70 OSStatus
71 SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
72 {
73 BEGIN_SECAPI
74 CSSM_APPLE_TP_ACTION_DATA actionData = {
75 CSSM_APPLE_TP_ACTION_VERSION,
76 (CSSM_APPLE_TP_ACTION_FLAGS)options
77 };
78 Trust *trust = Trust::required(trustRef);
79 CFDataRef actionDataRef = CFDataCreate(NULL,
80 (const UInt8 *)&actionData,
81 (CFIndex)sizeof(CSSM_APPLE_TP_ACTION_DATA));
82 trust->action(CSSM_TP_ACTION_DEFAULT);
83 trust->actionData(actionDataRef);
84 if (actionDataRef) CFRelease(actionDataRef);
85 END_SECAPI
86 }
87
88 OSStatus SecTrustSetParameters(
89 SecTrustRef trustRef,
90 CSSM_TP_ACTION action,
91 CFDataRef actionData)
92 {
93 BEGIN_SECAPI
94 Trust *trust = Trust::required(trustRef);
95 trust->action(action);
96 trust->actionData(actionData);
97 END_SECAPI
98 }
99
100
101 OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust, CFArrayRef anchorCertificates)
102 {
103 BEGIN_SECAPI
104 Trust::required(trust)->anchors(anchorCertificates);
105 END_SECAPI
106 }
107
108 OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust, Boolean anchorCertificatesOnly)
109 {
110 BEGIN_SECAPI
111 Trust::AnchorPolicy policy = (anchorCertificatesOnly) ? Trust::useAnchorsOnly : Trust::useAnchorsAndBuiltIns;
112 Trust::required(trust)->anchorPolicy(policy);
113 END_SECAPI
114 }
115
116 OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
117 {
118 BEGIN_SECAPI
119 StorageManager::KeychainList keychains;
120 // avoid unnecessary global initializations if an empty array is passed in
121 if (!( (keychainOrArray != NULL) &&
122 (CFGetTypeID(keychainOrArray) == CFArrayGetTypeID()) &&
123 (CFArrayGetCount((CFArrayRef)keychainOrArray) == 0) )) {
124 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
125 }
126 Trust::required(trust)->searchLibs(keychains);
127 END_SECAPI
128 }
129
130
131 OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate)
132 {
133 BEGIN_SECAPI
134 Trust::required(trust)->time(verifyDate);
135 END_SECAPI
136 }
137
138
139 CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
140 {
141 CFAbsoluteTime verifyTime = 0;
142 OSStatus __secapiresult;
143 try {
144 CFRef<CFDateRef> verifyDate = Trust::required(trust)->time();
145 verifyTime = CFDateGetAbsoluteTime(verifyDate);
146
147 __secapiresult=noErr;
148 }
149 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
150 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
151 catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
152 catch (...) { __secapiresult=internalComponentErr; }
153 return verifyTime;
154 }
155
156 OSStatus SecTrustEvaluate(SecTrustRef trustRef, SecTrustResultType *resultP)
157 {
158 BEGIN_SECAPI
159 Trust *trust = Trust::required(trustRef);
160 trust->evaluate();
161 if (resultP) {
162 *resultP = trust->result();
163 secdebug("SecTrustEvaluate", "SecTrustEvaluate trust result = %d", (int)*resultP);
164 }
165 END_SECAPI
166 }
167
168 OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
169 dispatch_queue_t queue, SecTrustCallback result)
170 {
171 BEGIN_SECAPI
172 dispatch_async(queue, ^{
173 try {
174 Trust *trustObj = Trust::required(trust);
175 trustObj->evaluate();
176 result(trust, trustObj->result());
177 }
178 catch (...) {
179 result(trust, kSecTrustResultInvalid);
180 };
181 });
182 END_SECAPI
183 }
184
185 //
186 // Construct the "official" result evidence and return it
187 //
188 OSStatus SecTrustGetResult(
189 SecTrustRef trustRef,
190 SecTrustResultType *result,
191 CFArrayRef *certChain, CSSM_TP_APPLE_EVIDENCE_INFO **statusChain)
192 {
193 BEGIN_SECAPI
194 Trust *trust = Trust::required(trustRef);
195 if (result)
196 *result = trust->result();
197 if (certChain && statusChain)
198 trust->buildEvidence(*certChain, TPEvidenceInfo::overlayVar(*statusChain));
199 END_SECAPI
200 }
201
202 //
203 // Retrieve result of trust evaluation only
204 //
205 OSStatus SecTrustGetTrustResult(SecTrustRef trustRef,
206 SecTrustResultType *result)
207 {
208 BEGIN_SECAPI
209 Trust *trust = Trust::required(trustRef);
210 if (result) *result = trust->result();
211 END_SECAPI
212 }
213
214 //
215 // Retrieve extended validation trust results
216 //
217 OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result)
218 {
219 BEGIN_SECAPI
220 Trust *trustObj = Trust::required(trust);
221 if (result == nil)
222 return paramErr;
223 trustObj->extendedResult(*result);
224 END_SECAPI
225 }
226
227 //
228 // Retrieve CSSM-level information for those who want to dig down
229 //
230 OSStatus SecTrustGetCssmResult(SecTrustRef trust, CSSM_TP_VERIFY_CONTEXT_RESULT_PTR *result)
231 {
232 BEGIN_SECAPI
233 Required(result) = Trust::required(trust)->cssmResult();
234 END_SECAPI
235 }
236
237 //
238 // Retrieve CSSM_LEVEL TP return code
239 //
240 OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result)
241 {
242 BEGIN_SECAPI
243 Trust *trust = Trust::required(trustRef);
244 if (trust->result() == kSecTrustResultInvalid)
245 return paramErr;
246 else
247 Required(result) = trust->cssmResultCode();
248 END_SECAPI
249 }
250
251 OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
252 {
253 BEGIN_SECAPI
254 Required(handle) = Trust::required(trust)->getTPHandle();
255 END_SECAPI
256 }
257
258 OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
259 {
260 BEGIN_SECAPI
261 CFArrayRef currentPolicies = Trust::required(trust)->policies();
262 if (currentPolicies != NULL)
263 {
264 CFRetain(currentPolicies);
265 }
266
267 Required(policies) = currentPolicies;
268 END_SECAPI
269 }
270
271 OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, CFArrayRef *anchorCertificates)
272 {
273 BEGIN_SECAPI
274 CFRef<CFArrayRef> customAnchors(Trust::required(trust)->anchors());
275 Required(anchorCertificates) = (customAnchors) ?
276 (const CFArrayRef)CFRetain(customAnchors) : (const CFArrayRef)NULL;
277 END_SECAPI
278 }
279
280 //
281 // Get the user's default anchor certificate set
282 //
283 OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchorCertificates)
284 {
285 BEGIN_SECAPI
286
287 return SecTrustSettingsCopyUnrestrictedRoots(
288 true, true, true, /* all domains */
289 anchorCertificates);
290
291 END_SECAPI
292 }
293
294 /* new in 10.6 */
295 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
296 {
297 SecKeyRef pubKey = NULL;
298 CFArrayRef certChain = NULL;
299 CFArrayRef evidenceChain = NULL;
300 CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
301 OSStatus __secapiresult;
302 try {
303 Trust *trustObj = Trust::required(trust);
304 if (trustObj->result() == kSecTrustResultInvalid)
305 MacOSError::throwMe(errSecTrustNotAvailable);
306 if (trustObj->evidence() == nil)
307 trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
308 evidenceChain = trustObj->evidence();
309 __secapiresult=noErr;
310 }
311 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
312 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
313 catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
314 catch (...) { __secapiresult=internalComponentErr; }
315
316 if (certChain)
317 CFRelease(certChain);
318
319 if (evidenceChain) {
320 if (CFArrayGetCount(evidenceChain) > 0) {
321 SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(evidenceChain, 0);
322 __secapiresult = SecCertificateCopyPublicKey(cert, &pubKey);
323 }
324 // do not release evidenceChain, as it is owned by the trust object.
325 }
326 return pubKey;
327 }
328
329 /* new in 10.6 */
330 CFIndex SecTrustGetCertificateCount(SecTrustRef trust)
331 {
332 CFIndex chainLen = 0;
333 CFArrayRef certChain = NULL;
334 CFArrayRef evidenceChain = NULL;
335 CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
336 OSStatus __secapiresult;
337 try {
338 Trust *trustObj = Trust::required(trust);
339 if (trustObj->result() == kSecTrustResultInvalid)
340 MacOSError::throwMe(errSecTrustNotAvailable);
341 if (trustObj->evidence() == nil)
342 trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
343 evidenceChain = trustObj->evidence();
344 __secapiresult=noErr;
345 }
346 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
347 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
348 catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
349 catch (...) { __secapiresult=internalComponentErr; }
350
351 if (certChain)
352 CFRelease(certChain);
353
354 if (evidenceChain)
355 chainLen = CFArrayGetCount(evidenceChain); // don't release, trust object owns it.
356
357 return chainLen;
358 }
359
360 /* new in 10.6 */
361 SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
362 {
363 SecCertificateRef certificate = NULL;
364 CFArrayRef certChain = NULL;
365 CFArrayRef evidenceChain = NULL;
366 CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
367 OSStatus __secapiresult;
368 try {
369 Trust *trustObj = Trust::required(trust);
370 if (trustObj->result() == kSecTrustResultInvalid)
371 MacOSError::throwMe(errSecTrustNotAvailable);
372 if (trustObj->evidence() == nil)
373 trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
374 evidenceChain = trustObj->evidence();
375 __secapiresult=noErr;
376 }
377 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
378 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
379 catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
380 catch (...) { __secapiresult=internalComponentErr; }
381
382 if (certChain)
383 CFRelease(certChain);
384
385 if (evidenceChain) {
386 if (ix < CFArrayGetCount(evidenceChain)) {
387 certificate = (SecCertificateRef) CFArrayGetValueAtIndex(evidenceChain, ix);
388 // note: we do not retain this certificate. The assumption here is
389 // that the certificate is retained by the trust object, so it is
390 // valid unil the trust is released (or until re-evaluated.)
391 // also note: we do not release the evidenceChain, as it is owned
392 // by the trust object.
393 }
394 }
395 return certificate;
396 }
397
398 /* new in 10.7 */
399 CFArrayRef
400 SecTrustCopyProperties(SecTrustRef trust)
401 {
402 /* can't use SECAPI macros, since this function does not return OSStatus */
403 CFArrayRef result = NULL;
404 try {
405 result = Trust::required(trust)->properties();
406 }
407 catch (...) {
408 if (result) {
409 CFRelease(result);
410 result = NULL;
411 }
412 };
413 return result;
414 }
415
416
417 /* deprecated in 10.5 */
418 OSStatus SecTrustGetCSSMAnchorCertificates(const CSSM_DATA **cssmAnchors,
419 uint32 *cssmAnchorCount)
420 {
421 BEGIN_SECAPI
422 CertGroup certs;
423 Trust::gStore().getCssmRootCertificates(certs);
424 Required(cssmAnchors) = certs.blobCerts();
425 Required(cssmAnchorCount) = certs.count();
426 END_SECAPI
427 }
428
429
430 //
431 // Get and set user trust settings. Deprecated in 10.5.
432 // User Trust getter, deprecated, works as it always has.
433 //
434 OSStatus SecTrustGetUserTrust(SecCertificateRef certificate,
435 SecPolicyRef policy, SecTrustUserSetting *trustSetting)
436 {
437 BEGIN_SECAPI
438 StorageManager::KeychainList searchList;
439 globals().storageManager.getSearchList(searchList);
440 Required(trustSetting) = Trust::gStore().find(
441 Certificate::required(certificate),
442 Policy::required(policy),
443 searchList);
444 END_SECAPI
445 }
446
447 //
448 // The public setter, also deprecated; it maps to the appropriate
449 // Trust Settings call if possible, else throws unimpErr.
450 //
451 OSStatus SecTrustSetUserTrust(SecCertificateRef certificate,
452 SecPolicyRef policy, SecTrustUserSetting trustSetting)
453 {
454 SecTrustSettingsResult tsResult = kSecTrustSettingsResultInvalid;
455 OSStatus ortn;
456 Boolean isRoot;
457
458 Policy::required(policy);
459 switch(trustSetting) {
460 case kSecTrustResultProceed:
461 /* different SecTrustSettingsResult depending in root-ness */
462 ortn = SecCertificateIsSelfSigned(certificate, &isRoot);
463 if(ortn) {
464 return ortn;
465 }
466 if(isRoot) {
467 tsResult = kSecTrustSettingsResultTrustRoot;
468 }
469 else {
470 tsResult = kSecTrustSettingsResultTrustAsRoot;
471 }
472 break;
473 case kSecTrustResultDeny:
474 tsResult = kSecTrustSettingsResultDeny;
475 break;
476 default:
477 return unimpErr;
478 }
479
480 /* make a usage constraints dictionary */
481 CFRef<CFMutableDictionaryRef> usageDict(CFDictionaryCreateMutable(NULL,
482 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
483 CFDictionaryAddValue(usageDict, kSecTrustSettingsPolicy, policy);
484 if(tsResult != kSecTrustSettingsResultTrustRoot) {
485 /* skip if we're specifying the default */
486 SInt32 result = tsResult;
487 CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &result);
488 CFDictionarySetValue(usageDict, kSecTrustSettingsResult, cfNum);
489 CFRelease(cfNum);
490 }
491 return SecTrustSettingsSetTrustSettings(certificate, kSecTrustSettingsDomainUser,
492 usageDict);
493 }
494
495 //
496 // This one is the now-private version of what SecTrustSetUserTrust() used to
497 // be. The public API can no longer manipulate User Trust settings, only
498 // view them.
499 //
500 OSStatus SecTrustSetUserTrustLegacy(SecCertificateRef certificate,
501 SecPolicyRef policy, SecTrustUserSetting trustSetting)
502 {
503 BEGIN_SECAPI
504 switch (trustSetting) {
505 case kSecTrustResultProceed:
506 case kSecTrustResultConfirm:
507 case kSecTrustResultDeny:
508 case kSecTrustResultUnspecified:
509 break;
510 default:
511 MacOSError::throwMe(errSecInvalidTrustSetting);
512 }
513 Trust::gStore().assign(
514 Certificate::required(certificate),
515 Policy::required(policy),
516 trustSetting);
517 END_SECAPI
518 }
519
520 /* SecGetAppleTPHandle - @@@NOT EXPORTED YET; copied from SecurityInterface,
521 but could be useful in the future.
522 */
523 /*
524 CSSM_TP_HANDLE
525 SecGetAppleTPHandle()
526 {
527 BEGIN_SECAPI
528 return TP(gGuidAppleX509TP)->handle();
529 END_SECAPI1(NULL);
530 }
531 */
532
533