2 * Copyright (c) 2007-2009 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 <CoreFoundation/CFString.h>
32 #include <AssertMacros.h>
33 #include "securityd_client.h"
34 #include "SecuritydXPC.h"
35 #include "SecFramework.h"
39 #include "SecTrustPriv.h"
40 #include <utilities/SecCFError.h>
41 #include "utilities/SecDb.h"
43 static CFStringRef kSecTrustStoreUserName
= CFSTR("user");
45 SecTrustStoreRef
SecTrustStoreForDomain(SecTrustStoreDomain domain
) {
46 CFStringRef domainName
;
47 if (domain
== kSecTrustStoreDomainUser
) {
48 domainName
= kSecTrustStoreUserName
;
54 return gSecurityd
->sec_trust_store_for_domain(domainName
, NULL
);
56 return (SecTrustStoreRef
)domainName
;
60 static bool string_data_to_bool_error(enum SecXPCOperation op
, SecTrustStoreRef ts
, CFDataRef digest
, CFErrorRef
*error
)
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
);
68 static bool string_data_to_bool_bool_error(enum SecXPCOperation op
, SecTrustStoreRef ts
, CFDataRef digest
, bool *result
, CFErrorRef
*error
)
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
) {
75 *result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
80 Boolean
SecTrustStoreContains(SecTrustStoreRef ts
,
81 SecCertificateRef certificate
) {
84 __block
bool contains
= false;
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
);
93 return ok
&& contains
;
96 static bool SecXPCDictionarySetCertificate(xpc_object_t message
, const char *key
, SecCertificateRef certificate
, CFErrorRef
*error
) {
98 xpc_dictionary_set_data(message
, key
, SecCertificateGetBytePtr(certificate
),
99 SecCertificateGetLength(certificate
));
102 return SecError(errSecParam
, error
, CFSTR("NULL certificate"));
106 static bool string_cert_cftype_to_error(enum SecXPCOperation op
, SecTrustStoreRef ts
, SecCertificateRef certificate
, CFTypeRef trustSettingsDictOrArray
, CFErrorRef
*error
)
108 return securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
110 ok
= SecXPCDictionarySetString(message
, kSecXPCKeyDomain
, (CFStringRef
)ts
, error
) &&
111 SecXPCDictionarySetCertificate(message
, kSecXPCKeyCertificate
, certificate
, error
) &&
112 (!trustSettingsDictOrArray
|| SecXPCDictionarySetPList(message
, kSecXPCKeySettings
, trustSettingsDictOrArray
, error
));
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
);
125 OSStatus
SecTrustStoreRemoveCertificate(SecTrustStoreRef ts
,
126 SecCertificateRef certificate
)
129 OSStatus status
= errSecParam
;
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
);
143 static CFIndex
GetOTAAssetVersionNumber()
148 if (errSecSuccess
== SecTrustGetOTAPKIAssetVersionNumber(&version
))
158 OSStatus
SecTrustStoreGetSettingsVersionNumber(SecTrustSettingsVersionNumber
* p_settings_version_number
)
160 OSStatus status
= errSecParam
;
161 if (NULL
== p_settings_version_number
)
166 CFIndex versionNumber
= GetOTAAssetVersionNumber();
167 *p_settings_version_number
= (SecTrustSettingsVersionNumber
)versionNumber
;
169 return errSecSuccess
;