]> git.saurik.com Git - apple/security.git/blob - sec/Security/SecTrustStore.c
Security-55471.14.18.tar.gz
[apple/security.git] / sec / Security / SecTrustStore.c
1 /*
2 * Copyright (c) 2007-2009 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 /*
25 * SecTrustStore.c - CertificateSource API to a system root certificate store
26 */
27 #include <Security/SecTrustStore.h>
28
29 #include <Security/SecCertificateInternal.h>
30 #include <Security/SecInternal.h>
31 #include <CoreFoundation/CFString.h>
32 #include <AssertMacros.h>
33 #include "securityd_client.h"
34 #include "SecuritydXPC.h"
35 #include "SecFramework.h"
36 #include <sys/stat.h>
37 #include <stdio.h>
38 #include <dirent.h>
39 #include "SecTrustPriv.h"
40 #include <utilities/SecCFError.h>
41 #include "utilities/SecDb.h"
42
43 static CFStringRef kSecTrustStoreUserName = CFSTR("user");
44
45 SecTrustStoreRef SecTrustStoreForDomain(SecTrustStoreDomain domain) {
46 CFStringRef domainName;
47 if (domain == kSecTrustStoreDomainUser) {
48 domainName = kSecTrustStoreUserName;
49 } else {
50 return NULL;
51 }
52
53 if (gSecurityd) {
54 return gSecurityd->sec_trust_store_for_domain(domainName, NULL);
55 } else {
56 return (SecTrustStoreRef)domainName;
57 }
58 }
59
60 static bool string_data_to_bool_error(enum SecXPCOperation op, SecTrustStoreRef ts, CFDataRef digest, CFErrorRef *error)
61 {
62 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
63 return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, error) &&
64 SecXPCDictionarySetData(message, kSecXPCKeyDigest, digest, error);
65 }, NULL);
66 }
67
68 static bool string_data_to_bool_bool_error(enum SecXPCOperation op, SecTrustStoreRef ts, CFDataRef digest, bool *result, CFErrorRef *error)
69 {
70 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
71 return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, error) &&
72 SecXPCDictionarySetData(message, kSecXPCKeyDigest, digest, error);
73 }, ^bool(xpc_object_t response, CFErrorRef *error) {
74 if (result)
75 *result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
76 return true;
77 });
78 }
79
80 Boolean SecTrustStoreContains(SecTrustStoreRef ts,
81 SecCertificateRef certificate) {
82 CFDataRef digest;
83 bool ok = false;
84 __block bool contains = false;
85
86 require(ts, errOut);
87 require(digest = SecCertificateGetSHA1Digest(certificate), errOut);
88 ok = (SecOSStatusWith(^bool (CFErrorRef *error) {
89 return SECURITYD_XPC(sec_trust_store_contains, string_data_to_bool_bool_error, ts, digest, &contains, error);
90 }) == errSecSuccess);
91
92 errOut:
93 return ok && contains;
94 }
95
96 static bool SecXPCDictionarySetCertificate(xpc_object_t message, const char *key, SecCertificateRef certificate, CFErrorRef *error) {
97 if (certificate) {
98 xpc_dictionary_set_data(message, key, SecCertificateGetBytePtr(certificate),
99 SecCertificateGetLength(certificate));
100 return true;
101 }
102 return SecError(errSecParam, error, CFSTR("NULL certificate"));
103 }
104
105
106 static bool string_cert_cftype_to_error(enum SecXPCOperation op, SecTrustStoreRef ts, SecCertificateRef certificate, CFTypeRef trustSettingsDictOrArray, CFErrorRef *error)
107 {
108 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
109 bool ok = false;
110 ok = SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, error) &&
111 SecXPCDictionarySetCertificate(message, kSecXPCKeyCertificate, certificate, error) &&
112 (!trustSettingsDictOrArray || SecXPCDictionarySetPList(message, kSecXPCKeySettings, trustSettingsDictOrArray, error));
113 return ok;
114 }, NULL);
115 }
116
117 OSStatus SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
118 SecCertificateRef certificate,
119 CFTypeRef trustSettingsDictOrArray) {
120 return SecOSStatusWith(^bool (CFErrorRef *error) {
121 return SECURITYD_XPC(sec_trust_store_set_trust_settings, string_cert_cftype_to_error, ts, certificate, trustSettingsDictOrArray, error);
122 });
123 }
124
125 OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts,
126 SecCertificateRef certificate)
127 {
128 CFDataRef digest;
129 OSStatus status = errSecParam;
130
131 require(ts, errOut);
132 require(digest = SecCertificateGetSHA1Digest(certificate), errOut);
133 require(gSecurityd || ts == (SecTrustStoreRef)kSecTrustStoreUserName, errOut);
134 status = SecOSStatusWith(^bool (CFErrorRef *error) {
135 return SECURITYD_XPC(sec_trust_store_remove_certificate, string_data_to_bool_error, ts, digest, error);
136 });
137
138 errOut:
139 return status;
140 }
141
142
143 static CFIndex GetOTAAssetVersionNumber()
144 {
145 CFIndex result = 0;
146 int version = 0;
147
148 if (errSecSuccess == SecTrustGetOTAPKIAssetVersionNumber(&version))
149 {
150 result = version;
151 }
152
153 return result;
154 }
155
156
157
158 OSStatus SecTrustStoreGetSettingsVersionNumber(SecTrustSettingsVersionNumber* p_settings_version_number)
159 {
160 OSStatus status = errSecParam;
161 if (NULL == p_settings_version_number)
162 {
163 return status;
164 }
165
166 CFIndex versionNumber = GetOTAAssetVersionNumber();
167 *p_settings_version_number = (SecTrustSettingsVersionNumber)versionNumber;
168
169 return errSecSuccess;
170 }