1/* 2 * Copyright (c) 2002-2013 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#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/SecCertificate.h> 31#include <Security/SecCertificatePriv.h> 32#include <security_keychain/Policies.h> 33#include <security_keychain/PolicyCursor.h> 34#include "SecBridge.h" 35 36 37// String constant declarations 38 39#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v)); 40 41SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2"); 42SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3"); 43SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8"); 44SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9"); 45SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11"); 46SEC_CONST_DECL (kSecPolicyAppleiChat, "1.2.840.113635.100.1.12"); 47SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14"); 48SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15"); 49SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16"); 50SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17"); 51SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18"); 52SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19"); 53SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20"); 54SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21"); 55SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22"); 56SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23"); 57SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24"); 58SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25"); 59SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26"); 60SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27"); 61 62 63SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid"); 64SEC_CONST_DECL (kSecPolicyName, "SecPolicyName"); 65SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient"); 66SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags"); 67SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier"); 68 69SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature"); 70SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation"); 71SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment, "CE_KU_KeyEncipherment"); 72SEC_CONST_DECL (kSecPolicyKU_DataEncipherment, "CE_KU_DataEncipherment"); 73SEC_CONST_DECL (kSecPolicyKU_KeyAgreement, "CE_KU_KeyAgreement"); 74SEC_CONST_DECL (kSecPolicyKU_KeyCertSign, "CE_KU_KeyCertSign"); 75SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign"); 76SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly"); 77SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly"); 78 79// Private functions 80 81SecPolicyRef SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr); 82extern "C" { CFArrayRef SecPolicyCopyEscrowRootCertificates(void); } 83 84// 85// CF boilerplate 86// 87CFTypeID 88SecPolicyGetTypeID(void) 89{ 90 BEGIN_SECAPI 91 return gTypes().Policy.typeID; 92 END_SECAPI1(_kCFRuntimeNotATypeID) 93} 94 95 96// 97// Sec API bridge functions 98// 99OSStatus 100SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid) 101{ 102 BEGIN_SECAPI 103 Required(oid) = Policy::required(policyRef)->oid(); 104 END_SECAPI 105} 106 107OSStatus 108SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value) 109{ 110 BEGIN_SECAPI 111 Required(value) = Policy::required(policyRef)->value(); 112 END_SECAPI 113} 114 115CFDictionaryRef 116SecPolicyCopyProperties(SecPolicyRef policyRef) 117{ 118 /* can't use SECAPI macros, since this function does not return OSStatus */ 119 CFDictionaryRef result = NULL; 120 try { 121 result = Policy::required(policyRef)->properties(); 122 } 123 catch (...) { 124 if (result) { 125 CFRelease(result); 126 result = NULL; 127 } 128 }; 129 return result; 130} 131 132OSStatus 133SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value) 134{ 135 BEGIN_SECAPI 136 Required(value); 137 const CssmData newValue(value->Data, value->Length); 138 Policy::required(policyRef)->setValue(newValue); 139 END_SECAPI 140} 141 142OSStatus 143SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties) 144{ 145 BEGIN_SECAPI 146 Policy::required(policyRef)->setProperties(properties); 147 END_SECAPI 148} 149 150OSStatus 151SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle) 152{ 153 BEGIN_SECAPI 154 Required(tpHandle) = Policy::required(policyRef)->tp()->handle(); 155 END_SECAPI 156} 157 158OSStatus 159SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies) 160{ 161 BEGIN_SECAPI 162 Required(policies); 163 CFMutableArrayRef currPolicies = NULL; 164 currPolicies = CFArrayCreateMutable(NULL, 0, NULL); 165 if ( currPolicies ) 166 { 167 SecPointer<PolicyCursor> cursor(new PolicyCursor(NULL, NULL)); 168 SecPointer<Policy> policy; 169 while ( cursor->next(policy) ) /* copies the next policy */ 170 { 171 CFArrayAppendValue(currPolicies, policy->handle()); /* 'SecPolicyRef' appended */ 172 CFRelease(policy->handle()); /* refcount bumped up when appended to array */ 173 } 174 *policies = CFArrayCreateCopy(NULL, currPolicies); 175 CFRelease(currPolicies); 176 CFRelease(cursor->handle()); 177 } 178 END_SECAPI 179} 180 181OSStatus 182SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy) 183{ 184 Required(policy); 185 Required(policyOID); 186 187 SecPolicySearchRef srchRef = NULL; 188 OSStatus ortn; 189 190 ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef); 191 if(ortn) { 192 return ortn; 193 } 194 ortn = SecPolicySearchCopyNext(srchRef, policy); 195 CFRelease(srchRef); 196 return ortn; 197} 198 199/* new in 10.6 */ 200SecPolicyRef 201SecPolicyCreateBasicX509(void) 202{ 203 // return a SecPolicyRef object for the X.509 Basic policy 204 SecPolicyRef policy = nil; 205 SecPolicySearchRef policySearch = nil; 206 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch); 207 if (!status) { 208 status = SecPolicySearchCopyNext(policySearch, &policy); 209 } 210 if (policySearch) { 211 CFRelease(policySearch); 212 } 213 return policy; 214} 215 216/* new in 10.6 */ 217SecPolicyRef 218SecPolicyCreateSSL(Boolean server, CFStringRef hostname) 219{ 220 // return a SecPolicyRef object for the SSL policy, given hostname and client options 221 SecPolicyRef policy = nil; 222 SecPolicySearchRef policySearch = nil; 223 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch); 224 if (!status) { 225 status = SecPolicySearchCopyNext(policySearch, &policy); 226 } 227 if (!status && policy) { 228 // set options for client-side or server-side policy evaluation 229 char *strbuf = NULL; 230 const char *hostnamestr = NULL; 231 if (hostname) { 232 hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8); 233 if (hostnamestr == NULL) { 234 CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1; 235 strbuf = (char *)malloc(maxLen); 236 if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) { 237 hostnamestr = strbuf; 238 } 239 } 240 } 241 uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0; 242 uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0; 243 CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags}; 244 CSSM_DATA data = {sizeof(opts), (uint8*)&opts}; 245 SecPolicySetValue(policy, &data); 246 247 if (strbuf) { 248 free(strbuf); 249 } 250 } 251 if (policySearch) { 252 CFRelease(policySearch); 253 } 254 return policy; 255} 256 257SecPolicyRef 258SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr) 259{ 260 SecPolicyRef policy = NULL; 261 try { 262 SecPointer<Policy> policyObj; 263 PolicyCursor::policy(oidPtr, policyObj); 264 policy = policyObj->handle(); 265 } 266 catch (...) {} 267 268 return policy; 269} 270 271/* new in 10.7 */ 272SecPolicyRef 273SecPolicyCreateWithOID(CFTypeRef policyOID) 274{ 275 // for now, we only accept the policy constants that are defined in SecPolicy.h 276 CFStringRef oidStr = (CFStringRef)policyOID; 277 CSSM_OID *oidPtr = NULL; 278 SecPolicyRef policy = NULL; 279 struct oidmap_entry_t { 280 const CFTypeRef oidstr; 281 const SecAsn1Oid *oidptr; 282 }; 283 const oidmap_entry_t oidmap[] = { 284 { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC }, 285 { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL }, 286 { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME }, 287 { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP }, 288 { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC }, 289 { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT }, 290 { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT }, 291 { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER }, 292 { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING }, 293 { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT }, 294 { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING }, 295 { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING }, 296 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION }, 297 { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING }, 298 { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE }, 299 { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE }, 300 { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING }, 301 { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING }, 302 { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE }, 303 }; 304 unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t); 305 for (i=0; i<oidmaplen; i++) { 306 CFStringRef str = (CFStringRef) oidmap[i].oidstr; 307 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) { 308 oidPtr = (CSSM_OID*)oidmap[i].oidptr; 309 break; 310 } 311 } 312 if (oidPtr) { 313 SecPolicySearchRef policySearch = NULL; 314 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, oidPtr, NULL, &policySearch); 315 if (!status && policySearch) { 316 status = SecPolicySearchCopyNext(policySearch, &policy); 317 CFRelease(policySearch); 318 } 319 if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) { 320 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); 321 } 322 if (!policy) { 323 policy = SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid*)oidPtr); 324 } 325 } 326 return policy; 327} 328 329/* new in 10.9 */ 330SecPolicyRef 331SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, CFDictionaryRef properties) 332{ 333 SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier); 334 SecPolicySetProperties(policy, properties); 335 336 return policy; 337} 338 339/* new in 10.9 */ 340SecPolicyRef 341SecPolicyCreateRevocation(CFOptionFlags revocationFlags) 342{ 343 // return a SecPolicyRef object for the unified revocation policy 344 SecAsn1Oid *oidPtr = (SecAsn1Oid*)&CSSMOID_APPLE_TP_REVOCATION; 345 SecPolicyRef policy = SecPolicyCreateWithSecAsn1Oid(oidPtr); 346 //%%% FIXME set policy value with revocationFlags 347 348 return policy; 349} 350 351/* new in 10.9 ***FIXME*** TO BE REMOVED */ 352CFArrayRef SecPolicyCopyEscrowRootCertificates(void) 353{ 354 return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot); 355} 356 357