]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/crypto_cssm.c
3f0bbfa8f357b4788892367cc0ba025b339022b8
[apple/ipsec.git] / ipsec-tools / racoon / crypto_cssm.c
1
2 /*
3 * Copyright (c) 2001-2004 Apple Computer, Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * The contents of this file constitute Original Code as defined in and
8 * are subject to the Apple Public Source License Version 1.1 (the
9 * "License"). You may not use this file except in compliance with the
10 * License. Please obtain a copy of the License at
11 * http://www.apple.com/publicsource and read it before using this file.
12 *
13 * This 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 OR NON-INFRINGEMENT. Please see the
18 * License for the specific language governing rights and limitations
19 * under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 /*
26 * Racoon module for verifying and signing certificates through Security
27 * Framework and CSSM
28 */
29
30 #include <Security/SecCertificate.h>
31 #include <Security/SecPolicy.h>
32 #include <Security/SecTrust.h>
33 #include <Security/SecKey.h>
34 #include <Security/SecIdentity.h>
35 #include <Security/SecItem.h>
36 #include <TargetConditionals.h>
37 #if TARGET_OS_EMBEDDED
38 #include <Security/SecTrustPriv.h>
39 #include <Security/SecPolicyPriv.h>
40 #include <Security/SecCertificatePriv.h>
41 #else
42 #include <Security/SecBase.h>
43 #include <Security/SecIdentityPriv.h>
44 #include <Security/SecIdentitySearch.h>
45 #include <Security/SecKeychain.h>
46 #include <Security/SecKeychainItem.h>
47 #include <Security/SecKeychainItemPriv.h>
48
49 #include <Security/SecKeyPriv.h>
50 #include <Security/oidsalg.h>
51 #include <Security/cssmapi.h>
52 #include <Security/SecPolicySearch.h>
53 #endif
54
55 #include <CoreFoundation/CoreFoundation.h>
56 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
57 #include "plog.h"
58 #include "debug.h"
59 #include "misc.h"
60 #include "oakley.h"
61
62
63 #include "crypto_cssm.h"
64
65
66 static OSStatus EvaluateCert(SecCertificateRef evalCertArray[], CFIndex evalCertArrayNumValues, CFTypeRef policyRef, SecKeyRef *publicKeyRef);
67
68 #if !TARGET_OS_EMBEDDED
69 static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef);
70 static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef);
71 #endif
72
73 static SecPolicyRef
74 crypto_cssm_x509cert_get_SecPolicyRef (CFStringRef hostname)
75 {
76 SecPolicyRef policyRef = NULL;
77 #if !TARGET_OS_EMBEDDED
78 OSStatus status;
79 CSSM_OID ourPolicyOID = CSSMOID_APPLE_TP_IP_SEC;
80
81 // get our policy object
82 status = FindPolicy(&ourPolicyOID, &policyRef);
83 if (status != noErr && status != -1) {
84 plog(LLV_ERROR, LOCATION, NULL,
85 "error %d %s.\n", status, GetSecurityErrorString(status));
86 }
87 #else
88 if (hostname) {
89 policyRef = SecPolicyCreateIPSec(FALSE, hostname);
90 if (policyRef == NULL) {
91 plog(LLV_ERROR, LOCATION, NULL,
92 "unable to create a SSL policyRef.\n");
93 }
94 }
95 #endif
96 return policyRef;
97 }
98
99 SecCertificateRef
100 crypto_cssm_x509cert_get_SecCertificateRef (vchar_t *cert)
101 {
102 SecCertificateRef certRef = NULL;
103
104 CFDataRef cert_data = CFDataCreateWithBytesNoCopy(NULL, cert->v, cert->l, kCFAllocatorNull);
105 if (cert_data) {
106 certRef = SecCertificateCreateWithData(NULL, cert_data);
107 CFRelease(cert_data);
108 }
109
110 if (certRef == NULL) {
111 plog(LLV_ERROR, LOCATION, NULL,
112 "unable to create a certRef.\n");
113 }
114 return certRef;
115 }
116
117 static cert_status_t
118 crypto_cssm_check_x509cert_dates (SecCertificateRef certificateRef)
119 {
120 cert_status_t certStatus = CERT_STATUS_OK;
121 #if TARGET_OS_EMBEDDED
122 CFAbsoluteTime timeNow = 0;
123 CFAbsoluteTime notvalidbeforedate = 0;
124 CFAbsoluteTime notvalidafterdate = 0;
125 CFDateRef nowcfdatedata = NULL;
126 CFDateRef notvalidbeforedatedata = NULL;
127 CFDateRef notvalidafterdatedata = NULL;
128 CFArrayRef certProparray = NULL;
129 CFDictionaryRef propDict = NULL;
130 const void *datevalue = NULL;
131 const void *labelvalue = NULL;
132 CFGregorianDate gregoriandate;
133 CFIndex count;
134 CFIndex i;
135
136 if ((certProparray = SecCertificateCopyProperties(certificateRef))){
137 if ((count = CFArrayGetCount( certProparray ))){
138 for( i = 0; i < count; i++) {
139 if ((propDict = CFArrayGetValueAtIndex(certProparray, i))) {
140 if ( CFDictionaryGetValueIfPresent(propDict, kSecPropertyKeyValue, (const void**)&datevalue)){
141 /* get kSecPropertyKeyLabel */
142 if ( (datevalue) && (CFDictionaryGetValueIfPresent(propDict, kSecPropertyKeyLabel, (const void**)&labelvalue))){
143 if ( (labelvalue) && (CFStringCompare( (CFStringRef)labelvalue, CFSTR("Not Valid Before"), 0) == kCFCompareEqualTo)){
144 if ( notvalidbeforedate = CFDateGetAbsoluteTime(datevalue)) {
145 if (notvalidbeforedatedata) {
146 CFRelease(notvalidbeforedatedata);
147 }
148 notvalidbeforedatedata = CFDateCreate(NULL, notvalidbeforedate);
149 }
150 }else if ((labelvalue) && (CFStringCompare( (CFStringRef)labelvalue, CFSTR("Not Valid After"), 0 ) == kCFCompareEqualTo)){
151 if ( notvalidafterdate = CFDateGetAbsoluteTime(datevalue)) {
152 if (notvalidafterdatedata) {
153 CFRelease(notvalidafterdatedata);
154 }
155 notvalidafterdatedata = CFDateCreate(NULL, notvalidafterdate);
156 }
157 }
158 }
159 }
160 }
161 }
162 }
163 }
164
165 if ( (timeNow = CFAbsoluteTimeGetCurrent()) && (nowcfdatedata = CFDateCreate( NULL, timeNow))){
166 if ( notvalidbeforedatedata ){
167 gregoriandate = CFAbsoluteTimeGetGregorianDate(notvalidbeforedate, NULL);
168 plog(LLV_DEBUG, LOCATION, NULL,
169 "cert not valid before yr %d, mon %d, days %d, hours %d, min %d\n", gregoriandate.year, gregoriandate.month, gregoriandate.day, gregoriandate.hour, gregoriandate.minute);
170 gregoriandate = CFAbsoluteTimeGetGregorianDate(notvalidafterdate, NULL);
171 plog(LLV_DEBUG, LOCATION, NULL,
172 "cert not valid after yr %d, mon %d, days %d, hours %d, min %d\n", gregoriandate.year, gregoriandate.month, gregoriandate.day, gregoriandate.hour, gregoriandate.minute);
173 if ( CFDateCompare( nowcfdatedata, notvalidbeforedatedata, NULL ) == kCFCompareLessThan){
174 plog(LLV_ERROR, LOCATION, NULL,
175 "current time before valid time\n");
176 certStatus = CERT_STATUS_PREMATURE;
177 } else if (notvalidafterdatedata && (CFDateCompare( nowcfdatedata, notvalidafterdatedata, NULL ) == kCFCompareGreaterThan)){
178 plog(LLV_ERROR, LOCATION, NULL,
179 "current time after valid time\n");
180 certStatus = CERT_STATUS_EXPIRED;
181 }else {
182 plog(LLV_INFO, LOCATION, NULL, "certificate expiration date OK\n");
183 certStatus = CERT_STATUS_OK;
184 }
185 }
186 }
187
188 if (notvalidbeforedatedata)
189 CFRelease(notvalidbeforedatedata);
190 if (notvalidafterdatedata)
191 CFRelease(notvalidafterdatedata);
192 if (certProparray)
193 CFRelease(certProparray);
194 if (nowcfdatedata)
195 CFRelease(nowcfdatedata);
196 #endif
197 return certStatus;
198 }
199
200 /*
201 * Verify cert using security framework
202 */
203 int crypto_cssm_check_x509cert (cert_t *hostcert, cert_t *certchain, CFStringRef hostname, SecKeyRef *publicKeyRef)
204 {
205 cert_t *p;
206 cert_status_t certStatus = 0;
207 OSStatus status;
208 CFIndex certArrayRefNumValues = 0;
209 CFIndex n = 0;
210 int certArraySiz;
211 SecCertificateRef *certArrayRef = NULL;
212 SecPolicyRef policyRef = crypto_cssm_x509cert_get_SecPolicyRef(hostname);
213
214 if (!hostcert || !certchain) {
215 return -1;
216 }
217
218 // find the total number of certs
219 for (p = certchain; p; p = p->chain, n++);
220 if (n> 1) {
221 plog(LLV_DEBUG2, LOCATION, NULL,
222 "%s: checking chain of %d certificates.\n", __FUNCTION__, n);
223 }
224
225 certArraySiz = n * sizeof(CFTypeRef);
226 certArrayRef = CFAllocatorAllocate(NULL, certArraySiz, 0);
227 if (!certArrayRef) {
228 return -1;
229 }
230 bzero(certArrayRef, certArraySiz);
231 if ((certArrayRef[certArrayRefNumValues] = crypto_cssm_x509cert_get_SecCertificateRef(&hostcert->cert))) {
232 /* don't overwrite any pending status */
233 if (!hostcert->status) {
234 hostcert->status = crypto_cssm_check_x509cert_dates(certArrayRef[certArrayRefNumValues]);
235 if (hostcert->status) {
236 plog(LLV_ERROR, LOCATION, NULL,
237 "host certificate failed date verification: %d.\n", hostcert->status);
238 certStatus = hostcert->status;
239 }
240 }
241 certArrayRefNumValues++;
242 }
243 for (p = certchain; p && certArrayRefNumValues < n; p = p->chain) {
244 if (p != hostcert) {
245 if ((certArrayRef[certArrayRefNumValues] = crypto_cssm_x509cert_get_SecCertificateRef(&p->cert))) {
246 /* don't overwrite any pending status */
247 if (!p->status) {
248 p->status = crypto_cssm_check_x509cert_dates(certArrayRef[certArrayRefNumValues]);
249 if (p->status) {
250 plog(LLV_ERROR, LOCATION, NULL,
251 "other certificate in chain failed date verification: %d.\n", p->status);
252 if (!certStatus) {
253 certStatus = p->status;
254 }
255 }
256 }
257 certArrayRefNumValues++;
258 }
259 }
260 }
261
262 // evaluate cert
263 status = EvaluateCert(certArrayRef, certArrayRefNumValues, policyRef, publicKeyRef);
264
265 while (certArrayRefNumValues) {
266 CFRelease(certArrayRef[--certArrayRefNumValues]);
267 }
268 CFAllocatorDeallocate(NULL, certArrayRef);
269
270 if (policyRef)
271 CFRelease(policyRef);
272
273 if (status != noErr && status != -1) {
274 plog(LLV_ERROR, LOCATION, NULL,
275 "error %d %s.\n", status, GetSecurityErrorString(status));
276 status = -1;
277 } else if (certStatus == CERT_STATUS_PREMATURE || certStatus == CERT_STATUS_EXPIRED) {
278 status = -1;
279 }
280 return status;
281
282 }
283
284
285 int crypto_cssm_verify_x509sign(SecKeyRef publicKeyRef, vchar_t *hash, vchar_t *signature)
286 {
287 return SecKeyRawVerify(publicKeyRef, kSecPaddingPKCS1, hash->v, hash->l, signature->v, signature->l);
288 }
289
290 /*
291 * Encrypt a hash via CSSM using the private key in the keychain
292 * from an identity.
293 */
294 vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash)
295 {
296
297 OSStatus status = -1;
298 SecIdentityRef identityRef = NULL;
299 SecKeyRef privateKeyRef = NULL;
300 vchar_t *sig = NULL;
301
302
303 CFDictionaryRef persistFind = NULL;
304 const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef, kSecClass};
305 const void *values_persist[] = { kCFBooleanTrue, persistentCertRef, kSecClassIdentity};
306
307 #define SIG_BUF_SIZE 1024
308
309 /* find identity by persistent ref */
310 persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
311 (sizeof(keys_persist) / sizeof(*keys_persist)), NULL, NULL);
312 if (persistFind == NULL)
313 goto end;
314
315 status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
316 if (status != noErr)
317 goto end;
318
319 status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef);
320 if (status != noErr)
321 goto end;
322
323 // alloc buffer for result
324 sig = vmalloc(SIG_BUF_SIZE);
325 if (sig == NULL)
326 goto end;
327
328 status = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1, hash->v,
329 hash->l, sig->v, &sig->l);
330
331
332 end:
333 if (identityRef)
334 CFRelease(identityRef);
335 if (privateKeyRef)
336 CFRelease(privateKeyRef);
337
338 if (persistFind)
339 CFRelease(persistFind);
340
341 if (status != noErr) {
342 if (sig) {
343 vfree(sig);
344 sig = NULL;
345 }
346 }
347
348 if (status != noErr && status != -1) {
349 plog(LLV_ERROR, LOCATION, NULL,
350 "error %d %s.\n", status, GetSecurityErrorString(status));
351 status = -1;
352 }
353 return sig;
354
355 }
356
357
358 /*
359 * Retrieve a cert from the keychain
360 */
361 vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef,
362 cert_status_t *certStatus)
363 {
364
365 OSStatus status = -1;
366 vchar_t *cert = NULL;
367 SecIdentityRef identityRef = NULL;
368 SecCertificateRef certificateRef = NULL;
369
370 #if !TARGET_OS_EMBEDDED
371 CSSM_DATA cssmData;
372 SecIdentitySearchRef idSearchRef = NULL;
373 SecKeychainRef keychainRef = NULL;
374
375 // get cert ref
376 if (persistentCertRef) {
377 status = SecKeychainItemCopyFromPersistentReference(persistentCertRef, (SecKeychainItemRef*)&certificateRef);
378 if (status != noErr)
379 goto end;
380 } else {
381 // copy system keychain
382 status = CopySystemKeychain(&keychainRef);
383 if (status != noErr)
384 goto end;
385
386 // find first identity in system keychain
387 status = SecIdentitySearchCreate(keychainRef, CSSM_KEYUSE_SIGN, &idSearchRef);
388 if (status != noErr)
389 goto end;
390
391 status = SecIdentitySearchCopyNext(idSearchRef, &identityRef);
392 if (status != noErr)
393 goto end;
394
395 // get certificate from identity
396 status = SecIdentityCopyCertificate(identityRef, &certificateRef);
397 if (status != noErr)
398 goto end;
399
400 }
401
402 // get certificate data
403 cssmData.Length = 0;
404 cssmData.Data = NULL;
405 status = SecCertificateGetData(certificateRef, &cssmData);
406 if (status != noErr)
407 goto end;
408
409 if (cssmData.Length == 0)
410 goto end;
411
412 cert = vmalloc(cssmData.Length);
413 if (cert == NULL)
414 goto end;
415
416 // cssmData struct just points to the data
417 // data must be copied to be returned
418 memcpy(cert->v, cssmData.Data, cssmData.Length);
419
420 // verify expiry or missing fields
421 if (certStatus) {
422 *certStatus = CERT_STATUS_OK;
423 }
424 #else
425
426 CFDictionaryRef persistFind = NULL;
427 const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef };
428 const void *values_persist[] = { kCFBooleanTrue, persistentCertRef };
429 size_t dataLen;
430 CFDataRef certData = NULL;
431
432 /* find identity by persistent ref */
433 persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
434 (sizeof(keys_persist) / sizeof(*keys_persist)), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
435 if (persistFind == NULL)
436 goto end;
437
438 status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
439 if (status != noErr)
440 goto end;
441
442 status = SecIdentityCopyCertificate(identityRef, &certificateRef);
443 if (status != noErr)
444 goto end;
445
446 certData = SecCertificateCopyData(certificateRef);
447 if (certData == NULL)
448 goto end;
449
450 dataLen = CFDataGetLength(certData);
451 if (dataLen == 0)
452 goto end;
453
454 cert = vmalloc(dataLen);
455 if (cert == NULL)
456 goto end;
457
458 CFDataGetBytes(certData, CFRangeMake(0, dataLen), cert->v);
459
460 // verify expiry or missing fields
461 if (certStatus) {
462 *certStatus = crypto_cssm_check_x509cert_dates(certificateRef);
463 }
464
465 #endif
466
467 end:
468 if (certificateRef)
469 CFRelease(certificateRef);
470 if (identityRef)
471 CFRelease(identityRef);
472 #if !TARGET_OS_EMBEDDED
473 if (idSearchRef)
474 CFRelease(idSearchRef);
475 if (keychainRef)
476 CFRelease(keychainRef);
477 #else
478 if (persistFind)
479 CFRelease(persistFind);
480 if (certData)
481 CFRelease(certData);
482 #endif
483
484 if (status != noErr && status != -1) {
485 plog(LLV_ERROR, LOCATION, NULL,
486 "error %d %s.\n", status, GetSecurityErrorString(status));
487 status = -1;
488 }
489 return cert;
490
491 }
492
493 #if !TARGET_OS_EMBEDDED
494 /*
495 * Find a policy ref by OID
496 */
497 static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef)
498 {
499
500 OSStatus status;
501 SecPolicySearchRef searchRef = nil;
502
503 status = SecPolicySearchCreate(CSSM_CERT_X_509v3, policyOID, NULL, &searchRef);
504 if (status != noErr)
505 goto end;
506
507 status = SecPolicySearchCopyNext(searchRef, policyRef);
508
509 end:
510 if (searchRef)
511 CFRelease(searchRef);
512
513 if (status != noErr) {
514 plog(LLV_ERROR, LOCATION, NULL,
515 "error %d %s.\n", status, GetSecurityErrorString(status));
516 status = -1;
517 }
518 return status;
519 }
520 #endif
521
522 /*
523 * Evaluate the trust of a cert using the policy provided
524 */
525 static OSStatus EvaluateCert(SecCertificateRef evalCertArray[], CFIndex evalCertArrayNumValues, CFTypeRef policyRef, SecKeyRef *publicKeyRef)
526 {
527 OSStatus status;
528 SecTrustRef trustRef = 0;
529 SecTrustResultType evalResult;
530
531 CFArrayRef errorStrings;
532
533 CFArrayRef cfCertRef = CFArrayCreate((CFAllocatorRef) NULL, (void*)evalCertArray, evalCertArrayNumValues,
534 &kCFTypeArrayCallBacks);
535
536 if (!cfCertRef) {
537 plog(LLV_ERROR, LOCATION, NULL,
538 "unable to create CFArray.\n");
539 return -1;
540 }
541
542 status = SecTrustCreateWithCertificates(cfCertRef, policyRef, &trustRef);
543 if (status != noErr)
544 goto end;
545
546 status = SecTrustEvaluate(trustRef, &evalResult);
547 if (status != noErr)
548 goto end;
549
550 if (evalResult != kSecTrustResultProceed && evalResult != kSecTrustResultUnspecified) {
551 plog(LLV_ERROR, LOCATION, NULL, "Error evaluating certificate.\n");
552
553 switch (evalResult) {
554 case kSecTrustResultInvalid:
555 plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultInvalid.\n");
556 break;
557 case kSecTrustResultProceed:
558 plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultProceed.\n");
559 break;
560 case kSecTrustResultDeny:
561 plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultDeny.\n");
562 break;
563 case kSecTrustResultUnspecified:
564 plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultUnspecified.\n");
565 break;
566 case kSecTrustResultRecoverableTrustFailure:
567 plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultRecoverableTrustFailure.\n");
568 break;
569 case kSecTrustResultFatalTrustFailure:
570 plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultFatalTrustFailure.\n");
571 break;
572 case kSecTrustResultOtherError:
573 plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultOtherError.\n");
574 break;
575 default:
576 plog(LLV_DEBUG, LOCATION, NULL, "eval result unknown: value = %d.\n", (int)evalResult);
577 break;
578 }
579
580 errorStrings = SecTrustCopyProperties(trustRef);
581 if (errorStrings) {
582
583 CFDictionaryRef dict;
584 CFStringRef val;
585 const char *str;
586 CFIndex count, maxcount = CFArrayGetCount(errorStrings);
587
588 plog(LLV_ERROR, LOCATION, NULL, "---------------Returned error strings: ---------------.\n");
589 for (count = 0; count < maxcount; count++) {
590 dict = CFArrayGetValueAtIndex(errorStrings, count);
591 if (dict && (CFGetTypeID(dict) == CFDictionaryGetTypeID())) {
592 val = CFDictionaryGetValue(dict, kSecPropertyKeyType);
593 if (val && (CFGetTypeID(val) == CFStringGetTypeID())) {
594 str = CFStringGetCStringPtr(val, kCFStringEncodingMacRoman);
595 if (str)
596 plog(LLV_ERROR, LOCATION, NULL, "type = %s.\n", str);
597 }
598 val = CFDictionaryGetValue(dict, kSecPropertyKeyValue);
599 if (val && (CFGetTypeID(val) == CFStringGetTypeID())) {
600 str = CFStringGetCStringPtr(val, kCFStringEncodingMacRoman);
601 if (str)
602 plog(LLV_ERROR, LOCATION, NULL, "value = %s.\n", str);
603 }
604 }
605 }
606 plog(LLV_ERROR, LOCATION, NULL, "-----------------------------------------------------.\n");
607 CFRelease(errorStrings);
608 }
609
610 status = -1;
611 goto end;
612 }
613
614 /* get and return the public key */
615 *publicKeyRef = SecTrustCopyPublicKey(trustRef);
616
617 end:
618 if (cfCertRef)
619 CFRelease(cfCertRef);
620 if (trustRef)
621 CFRelease(trustRef);
622
623 if (status != noErr && status != -1) {
624 plog(LLV_ERROR, LOCATION, NULL,
625 "error %d %s.\n", status, GetSecurityErrorString(status));
626 status = -1;
627 }
628 return status;
629 }
630
631 #if !TARGET_OS_EMBEDDED
632 /*
633 * Copy the system keychain
634 */
635 static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef)
636 {
637
638 OSStatus status;
639
640 status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
641 if (status != noErr)
642 goto end;
643
644 status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, keychainRef);
645
646 end:
647
648 if (status != noErr) {
649 plog(LLV_ERROR, LOCATION, NULL,
650 "error %d %s.\n", status, GetSecurityErrorString(status));
651 status = -1;
652 }
653 return status;
654
655 }
656 #endif
657
658 /*
659 * Return string representation of Security-related OSStatus.
660 */
661 const char *
662 GetSecurityErrorString(OSStatus err)
663 {
664 switch(err) {
665 case noErr:
666 return "noErr";
667 case memFullErr:
668 return "memFullErr";
669 case paramErr:
670 return "paramErr";
671 case unimpErr:
672 return "unimpErr";
673
674 /* SecBase.h: */
675 case errSecNotAvailable:
676 return "errSecNotAvailable";
677 #if !TARGET_OS_EMBEDDED
678 case errSecReadOnly:
679 return "errSecReadOnly";
680 case errSecAuthFailed:
681 return "errSecAuthFailed";
682 case errSecNoSuchKeychain:
683 return "errSecNoSuchKeychain";
684 case errSecInvalidKeychain:
685 return "errSecInvalidKeychain";
686 case errSecDuplicateKeychain:
687 return "errSecDuplicateKeychain";
688 case errSecDuplicateCallback:
689 return "errSecDuplicateCallback";
690 case errSecInvalidCallback:
691 return "errSecInvalidCallback";
692 case errSecBufferTooSmall:
693 return "errSecBufferTooSmall";
694 case errSecDataTooLarge:
695 return "errSecDataTooLarge";
696 case errSecNoSuchAttr:
697 return "errSecNoSuchAttr";
698 case errSecInvalidItemRef:
699 return "errSecInvalidItemRef";
700 case errSecInvalidSearchRef:
701 return "errSecInvalidSearchRef";
702 case errSecNoSuchClass:
703 return "errSecNoSuchClass";
704 case errSecNoDefaultKeychain:
705 return "errSecNoDefaultKeychain";
706 case errSecInteractionNotAllowed:
707 return "errSecInteractionNotAllowed";
708 case errSecReadOnlyAttr:
709 return "errSecReadOnlyAttr";
710 case errSecWrongSecVersion:
711 return "errSecWrongSecVersion";
712 case errSecKeySizeNotAllowed:
713 return "errSecKeySizeNotAllowed";
714 case errSecNoStorageModule:
715 return "errSecNoStorageModule";
716 case errSecNoCertificateModule:
717 return "errSecNoCertificateModule";
718 case errSecNoPolicyModule:
719 return "errSecNoPolicyModule";
720 case errSecInteractionRequired:
721 return "errSecInteractionRequired";
722 case errSecDataNotAvailable:
723 return "errSecDataNotAvailable";
724 case errSecDataNotModifiable:
725 return "errSecDataNotModifiable";
726 case errSecCreateChainFailed:
727 return "errSecCreateChainFailed";
728 case errSecACLNotSimple:
729 return "errSecACLNotSimple";
730 case errSecPolicyNotFound:
731 return "errSecPolicyNotFound";
732 case errSecInvalidTrustSetting:
733 return "errSecInvalidTrustSetting";
734 case errSecNoAccessForItem:
735 return "errSecNoAccessForItem";
736 case errSecInvalidOwnerEdit:
737 return "errSecInvalidOwnerEdit";
738 #endif
739 case errSecDuplicateItem:
740 return "errSecDuplicateItem";
741 case errSecItemNotFound:
742 return "errSecItemNotFound";
743 default:
744 return "<unknown>";
745 }
746 }
747