2 * Copyright (c) 2002-2010 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@
24 #include <CoreFoundation/CFString.h>
25 #include <CoreFoundation/CFNumber.h>
26 #include <CoreFoundation/CFArray.h>
27 #include <Security/SecItem.h>
28 #include <Security/SecPolicy.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <security_keychain/Policies.h>
31 #include <security_keychain/PolicyCursor.h>
32 #include "SecBridge.h"
35 // String constant declarations
37 #define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
39 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
40 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
41 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
42 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
43 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
44 SEC_CONST_DECL (kSecPolicyAppleiChat
, "1.2.840.113635.100.1.12");
45 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
46 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
47 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
48 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
49 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
50 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
51 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
53 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
54 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
55 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
57 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
58 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
59 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
60 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
61 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
62 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
63 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
64 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
65 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
71 SecPolicyGetTypeID(void)
74 return gTypes().Policy
.typeID
;
75 END_SECAPI1(_kCFRuntimeNotATypeID
)
80 // Sec API bridge functions
83 SecPolicyGetOID(SecPolicyRef policyRef
, CSSM_OID
* oid
)
86 Required(oid
) = Policy::required(policyRef
)->oid();
91 SecPolicyGetValue(SecPolicyRef policyRef
, CSSM_DATA
* value
)
94 Required(value
) = Policy::required(policyRef
)->value();
99 SecPolicyCopyProperties(SecPolicyRef policyRef
)
101 /* can't use SECAPI macros, since this function does not return OSStatus */
102 CFDictionaryRef result
= NULL
;
104 result
= Policy::required(policyRef
)->properties();
116 SecPolicySetValue(SecPolicyRef policyRef
, const CSSM_DATA
*value
)
120 const CssmData
newValue(value
->Data
, value
->Length
);
121 Policy::required(policyRef
)->setValue(newValue
);
126 SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
)
129 Policy::required(policyRef
)->setProperties(properties
);
134 SecPolicyGetTPHandle(SecPolicyRef policyRef
, CSSM_TP_HANDLE
* tpHandle
)
137 Required(tpHandle
) = Policy::required(policyRef
)->tp()->handle();
142 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType
, CFArrayRef
* policies
)
146 CFMutableArrayRef currPolicies
= NULL
;
147 currPolicies
= CFArrayCreateMutable(NULL
, 0, NULL
);
150 SecPointer
<PolicyCursor
> cursor(new PolicyCursor(NULL
, NULL
));
151 SecPointer
<Policy
> policy
;
152 while ( cursor
->next(policy
) ) /* copies the next policy */
154 CFArrayAppendValue(currPolicies
, policy
->handle()); /* 'SecPolicyRef' appended */
155 CFRelease(policy
->handle()); /* refcount bumped up when appended to array */
157 *policies
= CFArrayCreateCopy(NULL
, currPolicies
);
158 CFRelease(currPolicies
);
159 CFRelease(cursor
->handle());
165 SecPolicyCopy(CSSM_CERT_TYPE certificateType
, const CSSM_OID
*policyOID
, SecPolicyRef
* policy
)
170 SecPolicySearchRef srchRef
= NULL
;
173 ortn
= SecPolicySearchCreate(certificateType
, policyOID
, NULL
, &srchRef
);
177 ortn
= SecPolicySearchCopyNext(srchRef
, policy
);
184 SecPolicyCreateBasicX509(void)
186 // return a SecPolicyRef object for the X.509 Basic policy
187 SecPolicyRef policy
= nil
;
188 SecPolicySearchRef policySearch
= nil
;
189 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_X509_BASIC
, NULL
, &policySearch
);
191 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
194 CFRelease(policySearch
);
201 SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
)
203 // return a SecPolicyRef object for the SSL policy, given hostname and client options
204 SecPolicyRef policy
= nil
;
205 SecPolicySearchRef policySearch
= nil
;
206 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_TP_SSL
, NULL
, &policySearch
);
208 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
210 if (!status
&& policy
) {
211 // set options for client-side or server-side policy evaluation
213 const char *hostnamestr
= NULL
;
215 CFIndex strbuflen
= 0;
216 hostnamestr
= CFStringGetCStringPtr(hostname
, kCFStringEncodingUTF8
);
217 if (hostnamestr
== NULL
) {
218 strbuflen
= CFStringGetLength(hostname
)*6;
219 strbuf
= (char *)malloc(strbuflen
+1);
220 if (CFStringGetCString(hostname
, strbuf
, strbuflen
, kCFStringEncodingUTF8
)) {
221 hostnamestr
= strbuf
;
225 uint32 hostnamelen
= (hostnamestr
) ? strlen(hostnamestr
) : 0;
226 uint32 flags
= (!server
) ? CSSM_APPLE_TP_SSL_CLIENT
: 0;
227 CSSM_APPLE_TP_SSL_OPTIONS opts
= {CSSM_APPLE_TP_SSL_OPTS_VERSION
, hostnamelen
, hostnamestr
, flags
};
228 CSSM_DATA data
= {sizeof(opts
), (uint8
*)&opts
};
229 SecPolicySetValue(policy
, &data
);
236 CFRelease(policySearch
);
243 SecPolicyCreateWithOID(CFTypeRef policyOID
)
245 //%%% FIXME: allow policyOID to be a CFDataRef or a CFStringRef for an arbitrary OID
246 // for now, we only accept the policy constants that are defined in SecPolicy.h
247 CFStringRef oidStr
= (CFStringRef
)policyOID
;
248 CSSM_OID
*oidPtr
= NULL
;
249 SecPolicyRef policy
= NULL
;
250 const void* oidmap
[] = {
251 kSecPolicyAppleX509Basic
, &CSSMOID_APPLE_X509_BASIC
,
252 kSecPolicyAppleSSL
, &CSSMOID_APPLE_TP_SSL
,
253 kSecPolicyAppleSMIME
, &CSSMOID_APPLE_TP_SMIME
,
254 kSecPolicyAppleEAP
, &CSSMOID_APPLE_TP_EAP
,
255 kSecPolicyAppleIPsec
, &CSSMOID_APPLE_TP_IP_SEC
,
256 kSecPolicyAppleiChat
, &CSSMOID_APPLE_TP_ICHAT
,
257 kSecPolicyApplePKINITClient
, &CSSMOID_APPLE_TP_PKINIT_CLIENT
,
258 kSecPolicyApplePKINITServer
, &CSSMOID_APPLE_TP_PKINIT_SERVER
,
259 kSecPolicyAppleCodeSigning
, &CSSMOID_APPLE_TP_CODE_SIGNING
,
260 kSecPolicyMacAppStoreReceipt
, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
,
261 kSecPolicyAppleIDValidation
, &CSSMOID_APPLE_TP_APPLEID_SHARING
,
262 kSecPolicyAppleTimeStamping
, &CSSMOID_APPLE_TP_TIMESTAMPING
264 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap
[0]);
265 for (i
=0; i
<oidmaplen
*2; i
+=2) {
266 CFStringRef str
= (CFStringRef
)oidmap
[i
];
267 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
268 oidPtr
= (CSSM_OID
*)oidmap
[i
+1];
273 SecPolicySearchRef policySearch
= NULL
;
274 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, oidPtr
, NULL
, &policySearch
);
275 if (!status
&& policySearch
) {
276 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
277 CFRelease(policySearch
);