2 * Copyright (c) 2007-2009,2012-2015 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecTrustStore.c - CertificateSource API to a system root certificate store
27 #include <Security/SecTrustStore.h>
29 #include <Security/SecCertificateInternal.h>
30 #include <Security/SecInternal.h>
31 #include <Security/SecuritydXPC.h>
32 #include <CoreFoundation/CFString.h>
33 #include <AssertMacros.h>
34 #include <ipc/securityd_client.h>
35 #include "SecFramework.h"
38 #include <os/activity.h>
40 #include "SecTrustPriv.h"
41 #include <utilities/SecCFError.h>
42 #include "utilities/SecDb.h"
44 static CFStringRef kSecTrustStoreUserName
= CFSTR("user");
46 SecTrustStoreRef
SecTrustStoreForDomain(SecTrustStoreDomain domain
) {
47 CFStringRef domainName
;
48 if (domain
== kSecTrustStoreDomainUser
) {
49 domainName
= kSecTrustStoreUserName
;
55 return gSecurityd
->sec_trust_store_for_domain(domainName
, NULL
);
57 return (SecTrustStoreRef
)domainName
;
61 static bool string_data_to_bool_error(enum SecXPCOperation op
, SecTrustStoreRef ts
, CFDataRef digest
, CFErrorRef
*error
)
63 return securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
64 return SecXPCDictionarySetString(message
, kSecXPCKeyDomain
, (CFStringRef
)ts
, error
) &&
65 SecXPCDictionarySetData(message
, kSecXPCKeyDigest
, digest
, error
);
69 static bool string_data_to_bool_bool_error(enum SecXPCOperation op
, SecTrustStoreRef ts
, CFDataRef digest
, bool *result
, CFErrorRef
*error
)
71 return securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
72 return SecXPCDictionarySetString(message
, kSecXPCKeyDomain
, (CFStringRef
)ts
, error
) &&
73 SecXPCDictionarySetData(message
, kSecXPCKeyDigest
, digest
, error
);
74 }, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
76 *result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
81 Boolean
SecTrustStoreContains(SecTrustStoreRef ts
,
82 SecCertificateRef certificate
) {
85 __block
bool contains
= false;
87 os_activity_t trace_activity
= os_activity_start("SecTrustStoreContains", OS_ACTIVITY_FLAG_DEFAULT
);
89 require(digest
= SecCertificateGetSHA1Digest(certificate
), errOut
);
92 ok
= (SecOSStatusWith(^bool (CFErrorRef
*error
) {
93 return SECURITYD_XPC(sec_trust_store_contains
, string_data_to_bool_bool_error
, ts
, digest
, &contains
, error
);
97 os_activity_end(trace_activity
);
98 return ok
&& contains
;
101 static bool SecXPCDictionarySetCertificate(xpc_object_t message
, const char *key
, SecCertificateRef certificate
, CFErrorRef
*error
) {
103 xpc_dictionary_set_data(message
, key
, SecCertificateGetBytePtr(certificate
),
104 SecCertificateGetLength(certificate
));
107 return SecError(errSecParam
, error
, CFSTR("NULL certificate"));
111 static bool string_cert_cftype_to_error(enum SecXPCOperation op
, SecTrustStoreRef ts
, SecCertificateRef certificate
, CFTypeRef trustSettingsDictOrArray
, CFErrorRef
*error
)
113 return securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
115 ok
= SecXPCDictionarySetString(message
, kSecXPCKeyDomain
, (CFStringRef
)ts
, error
) &&
116 SecXPCDictionarySetCertificate(message
, kSecXPCKeyCertificate
, certificate
, error
) &&
117 (!trustSettingsDictOrArray
|| SecXPCDictionarySetPList(message
, kSecXPCKeySettings
, trustSettingsDictOrArray
, error
));
122 OSStatus
SecTrustStoreSetTrustSettings(SecTrustStoreRef ts
,
123 SecCertificateRef certificate
,
124 CFTypeRef trustSettingsDictOrArray
) {
125 __block OSStatus result
;
127 os_activity_initiate("SecTrustStoreSetTrustSettings", OS_ACTIVITY_FLAG_DEFAULT
, ^{
128 result
= SecOSStatusWith(^bool (CFErrorRef
*error
) {
129 return SECURITYD_XPC(sec_trust_store_set_trust_settings
, string_cert_cftype_to_error
, ts
, certificate
, trustSettingsDictOrArray
, error
);
136 OSStatus
SecTrustStoreRemoveCertificate(SecTrustStoreRef ts
,
137 SecCertificateRef certificate
)
140 __block OSStatus status
= errSecParam
;
142 os_activity_t trace_activity
= os_activity_start("SecTrustStoreRemoveCertificate", OS_ACTIVITY_FLAG_DEFAULT
);
144 require(digest
= SecCertificateGetSHA1Digest(certificate
), errOut
);
145 require(gSecurityd
|| ts
== (SecTrustStoreRef
)kSecTrustStoreUserName
, errOut
);
147 status
= SecOSStatusWith(^bool (CFErrorRef
*error
) {
148 return SECURITYD_XPC(sec_trust_store_remove_certificate
, string_data_to_bool_error
, ts
, digest
, error
);
152 os_activity_end(trace_activity
);
157 static CFIndex
GetOTAAssetVersionNumber()
162 if (errSecSuccess
== SecTrustGetOTAPKIAssetVersionNumber(&version
))
172 OSStatus
SecTrustStoreGetSettingsVersionNumber(SecTrustSettingsVersionNumber
* p_settings_version_number
)
174 OSStatus status
= errSecParam
;
175 if (NULL
== p_settings_version_number
)
180 CFIndex versionNumber
= GetOTAAssetVersionNumber();
181 *p_settings_version_number
= (SecTrustSettingsVersionNumber
)versionNumber
;
183 return errSecSuccess
;