]> git.saurik.com Git - apple/security.git/blob - utilities/src/SecCFError.c
Security-55471.14.tar.gz
[apple/security.git] / utilities / src / SecCFError.c
1 //
2 // SecCFError.c
3 // utilities
4 //
5 // Created by Mitch Adler on 7/18/12.
6 // Copyright (c) 2012 Apple Inc. All rights reserved.
7 //
8
9 #include <Security/SecBase.h>
10 #include <utilities/SecCFError.h>
11 #include <utilities/SecCFRelease.h>
12 #include <utilities/debugging.h>
13
14 bool SecKernError(kern_return_t result, CFErrorRef *error, CFStringRef format, ...) {
15 if (!result) return true;
16 if (error) {
17 va_list args;
18 CFIndex code = result;
19 CFErrorRef previousError = *error;
20
21 *error = NULL;
22 va_start(args, format);
23 SecCFCreateErrorWithFormatAndArguments(code, kSecKernDomain, previousError, error, NULL, format, args);
24 va_end(args);
25 }
26 return false;
27 }
28
29 bool SecCheckErrno(int result, CFErrorRef *error, CFStringRef format, ...) {
30 if (result == 0) return true;
31 if (error) {
32 va_list args;
33 int errnum = errno;
34 CFIndex code = errnum;
35 CFErrorRef previousError = *error;
36
37 *error = NULL;
38 va_start(args, format);
39 CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
40 va_end(args);
41 SecCFCreateErrorWithFormat(code, kSecErrnoDomain, previousError, error, NULL, CFSTR("%@: [%d] %s"), message, errnum, strerror(errnum));
42 CFReleaseSafe(message);
43 }
44 return false;
45 }
46
47 bool SecError(OSStatus status, CFErrorRef *error, CFStringRef format, ...) {
48 if (status == errSecSuccess) return true;
49 if (error) {
50 va_list args;
51 CFIndex code = status;
52 CFErrorRef previousError = *error;
53
54 *error = NULL;
55 va_start(args, format);
56 SecCFCreateErrorWithFormatAndArguments(code, kSecErrorDomain, previousError, error, NULL, format, args);
57 va_end(args);
58 }
59 return false;
60 }
61
62
63 void SecCFCreateError(CFIndex errorCode, CFStringRef domain, CFStringRef descriptionString,
64 CFErrorRef previousError, CFErrorRef *newError)
65 {
66 #pragma clang diagnostic push
67 #pragma GCC diagnostic ignored "-Wformat-security"
68 SecCFCreateErrorWithFormat(errorCode, domain, previousError, newError, NULL, descriptionString);
69 #pragma clang diagnostic pop
70 }
71
72 void SecCFCreateErrorWithFormat(CFIndex errorCode, CFStringRef domain, CFErrorRef previousError, CFErrorRef *newError,
73 CFDictionaryRef formatoptions, CFStringRef format, ...)
74 {
75 va_list args;
76 va_start(args, format);
77
78 SecCFCreateErrorWithFormatAndArguments(errorCode, domain, previousError, newError, formatoptions, format, args);
79
80 va_end(args);
81 }
82
83 void SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode, CFStringRef domain,
84 CFErrorRef previousError, CFErrorRef *newError,
85 CFDictionaryRef formatoptions, CFStringRef format, va_list args)
86 {
87 if (newError && !(*newError)) {
88 CFStringRef formattedString = CFStringCreateWithFormatAndArguments(NULL, formatoptions, format, args);
89
90 const void* keys[2] = { kCFErrorDescriptionKey, kCFErrorUnderlyingErrorKey};
91 const void* values[2] = { formattedString, previousError };
92 const CFIndex numEntriesToUse = (previousError != NULL) ? 2 : 1;
93
94 *newError = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, domain, errorCode,
95 keys, values, numEntriesToUse);
96
97 CFReleaseNull(formattedString);
98 if (previousError)
99 secnotice("error", "encapsulated %@ with new error: %@", previousError, *newError);
100 } else {
101 if (previousError && newError && (previousError != *newError)) {
102 secnotice("error", "dropping %@", previousError);
103 CFRelease(previousError);
104 }
105 }
106 }