/* * Ensure that the policy being evaluated is accessible via * SecPolicySearch*(). Not really part of the test, but a handy place * to catch this common error before checking in TP changes. */ static int verifySecPolicy( const CSSM_OID *oid) { SecPolicySearchRef srchRef = NULL; OSStatus ortn; ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3, oid, NULL, &srchRef); if(ortn) { cssmPerror("SecPolicySearchCreate", ortn); return -1; } SecPolicyRef policyRef = NULL; ortn = SecPolicySearchCopyNext(srchRef, &policyRef); if(ortn) { cssmPerror("SecPolicySearchCopyNext", ortn); printf("***The TP policy used in this test is not accessible via SecPolicySearchCopyNext().\n"); printf(" You probably forgot to add the policy to the theOidList table in PolicyCursor.cpp\n"); printf(" in the libsecurity_keychain project.\n"); } CFRelease(srchRef); if(policyRef) { CFRelease(policyRef); } return ortn; }
CFTypeRef CERT_PolicyForCertUsage(SECCertUsage certUsage) { SecPolicySearchRef search = NULL; SecPolicyRef policy = NULL; const CSSM_OID *policyOID; OSStatus rv; switch (certUsage) { case certUsageSSLServerWithStepUp: case certUsageSSLCA: case certUsageVerifyCA: case certUsageAnyCA: goto loser; break; case certUsageSSLClient: case certUsageSSLServer: policyOID = &CSSMOID_APPLE_TP_SSL; break; case certUsageUserCertImport: policyOID = &CSSMOID_APPLE_TP_CSR_GEN; break; case certUsageStatusResponder: policyOID = &CSSMOID_APPLE_TP_REVOCATION_OCSP; break; case certUsageObjectSigner: case certUsageProtectedObjectSigner: policyOID = &CSSMOID_APPLE_ISIGN; break; case certUsageEmailSigner: case certUsageEmailRecipient: policyOID = &CSSMOID_APPLE_X509_BASIC; break; default: goto loser; } rv = SecPolicySearchCreate(CSSM_CERT_X_509v3, policyOID, NULL, &search); if (rv) goto loser; rv = SecPolicySearchCopyNext(search, &policy); if (rv) goto loser; loser: if(search) CFRelease(search); return policy; }
/* new in 10.6 */ SecPolicyRef SecPolicyCreateBasicX509(void) { // return a SecPolicyRef object for the X.509 Basic policy SecPolicyRef policy = nil; SecPolicySearchRef policySearch = nil; OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch); if (!status) { status = SecPolicySearchCopyNext(policySearch, &policy); } if (policySearch) { CFRelease(policySearch); } return policy; }
OSStatus SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy) { Required(policy); Required(policyOID); SecPolicySearchRef srchRef = NULL; OSStatus ortn; ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef); if(ortn) { return ortn; } ortn = SecPolicySearchCopyNext(srchRef, policy); CFRelease(srchRef); return ortn; }
/* new in 10.6 */ SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname) { // return a SecPolicyRef object for the SSL policy, given hostname and client options SecPolicyRef policy = nil; SecPolicySearchRef policySearch = nil; OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch); if (!status) { status = SecPolicySearchCopyNext(policySearch, &policy); } if (!status && policy) { // set options for client-side or server-side policy evaluation char *strbuf = NULL; const char *hostnamestr = NULL; if (hostname) { CFIndex strbuflen = 0; hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8); if (hostnamestr == NULL) { strbuflen = CFStringGetLength(hostname)*6; strbuf = (char *)malloc(strbuflen+1); if (CFStringGetCString(hostname, strbuf, strbuflen, kCFStringEncodingUTF8)) { hostnamestr = strbuf; } } } uint32 hostnamelen = (hostnamestr) ? strlen(hostnamestr) : 0; uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0; CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags}; CSSM_DATA data = {sizeof(opts), (uint8*)&opts}; SecPolicySetValue(policy, &data); if (strbuf) { free(strbuf); } } if (policySearch) { CFRelease(policySearch); } return policy; }
/* new in 10.7 */ SecPolicyRef SecPolicyCreateWithOID(CFTypeRef policyOID) { //%%% FIXME: allow policyOID to be a CFDataRef or a CFStringRef for an arbitrary OID // for now, we only accept the policy constants that are defined in SecPolicy.h CFStringRef oidStr = (CFStringRef)policyOID; CSSM_OID *oidPtr = NULL; SecPolicyRef policy = NULL; const void* oidmap[] = { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC, kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL, kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME, kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP, kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC, kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT, kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT, kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER, kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING, kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT, kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING }; unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap[0]); for (i=0; i<oidmaplen*2; i+=2) { CFStringRef str = (CFStringRef)oidmap[i]; if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) { oidPtr = (CSSM_OID*)oidmap[i+1]; break; } } if (oidPtr) { SecPolicySearchRef policySearch = NULL; OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, oidPtr, NULL, &policySearch); if (!status && policySearch) { status = SecPolicySearchCopyNext(policySearch, &policy); CFRelease(policySearch); } } return policy; }
SecPolicyRef Download::GetPolicy () { SecPolicySearchRef search; SecPolicyRef policy; OSStatus result; // get the policy for resource signing result = SecPolicySearchCreate (CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_RESOURCE_SIGN, NULL, &search); if (result != noErr) { MacOSError::throwMe (result); } result = SecPolicySearchCopyNext (search, &policy); if (result != noErr) { MacOSError::throwMe (result); } CFRelease (search); return policy; }
/* * Parse a ContentInfo as best we can. All return fields are optional. * If signer_cert_status is NULL on entry, NO signature or cert evaluation * will be performed. */ krb5_error_code krb5int_pkinit_parse_cms_msg( const krb5_data *content_info, krb5_pkinit_cert_db_t cert_db, /* may be required for SignedData */ krb5_boolean is_client_msg, /* TRUE : msg is from client */ krb5_boolean *is_signed, /* RETURNED */ krb5_boolean *is_encrypted, /* RETURNED */ krb5_data *raw_data, /* RETURNED */ krb5int_cms_content_type *inner_content_type,/* Returned, ContentType of */ /* EncapsulatedData */ krb5_data *signer_cert, /* RETURNED */ krb5int_cert_sig_status *signer_cert_status,/* RETURNED */ unsigned *num_all_certs, /* size of *all_certs RETURNED */ krb5_data **all_certs) /* entire cert chain RETURNED */ { SecPolicySearchRef policy_search = NULL; SecPolicyRef policy = NULL; OSStatus ortn; krb5_error_code krtn = 0; CMSDecoderRef decoder = NULL; size_t num_signers; CMSSignerStatus signer_status; OSStatus cert_verify_status; CFArrayRef cf_all_certs = NULL; int msg_is_signed = 0; if(content_info == NULL) { pkiDebug("krb5int_pkinit_parse_cms_msg: no ContentInfo\n"); return KRB5_CRYPTO_INTERNAL; } ortn = CMSDecoderCreate(&decoder); if(ortn) { return ENOMEM; } ortn = CMSDecoderUpdateMessage(decoder, content_info->data, content_info->length); if(ortn) { /* no verify yet, must be bad message */ krtn = KRB5_PARSE_MALFORMED; goto errOut; } ortn = CMSDecoderFinalizeMessage(decoder); if(ortn) { pkiCssmErr("CMSDecoderFinalizeMessage", ortn); krtn = KRB5_PARSE_MALFORMED; goto errOut; } /* expect zero or one signers */ ortn = CMSDecoderGetNumSigners(decoder, &num_signers); switch(num_signers) { case 0: msg_is_signed = 0; break; case 1: msg_is_signed = 1; break; default: krtn = KRB5_PARSE_MALFORMED; goto errOut; } /* * We need a cert verify policy even if we're not actually evaluating * the cert due to requirements in libsecurity_smime. */ ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3, is_client_msg ? &CSSMOID_APPLE_TP_PKINIT_CLIENT : &CSSMOID_APPLE_TP_PKINIT_SERVER, NULL, &policy_search); if(ortn) { pkiCssmErr("SecPolicySearchCreate", ortn); krtn = KRB5_CRYPTO_INTERNAL; goto errOut; } ortn = SecPolicySearchCopyNext(policy_search, &policy); if(ortn) { pkiCssmErr("SecPolicySearchCopyNext", ortn); krtn = KRB5_CRYPTO_INTERNAL; goto errOut; } /* get some basic status that doesn't need heavyweight evaluation */ if(msg_is_signed) { if(is_signed) { *is_signed = TRUE; } if(inner_content_type) { CSSM_OID ec_oid = {0, NULL}; CFDataRef ec_data = NULL; krb5int_cms_content_type ctype; ortn = CMSDecoderCopyEncapsulatedContentType(decoder, &ec_data); if(ortn || (ec_data == NULL)) { pkiCssmErr("CMSDecoderCopyEncapsulatedContentType", ortn); krtn = KRB5_CRYPTO_INTERNAL; goto errOut; } ec_oid.Data = (uint8 *)CFDataGetBytePtr(ec_data); ec_oid.Length = CFDataGetLength(ec_data); if(pkiCompareCssmData(&ec_oid, &CSSMOID_PKCS7_Data)) { ctype = ECT_Data; } else if(pkiCompareCssmData(&ec_oid, &CSSMOID_PKCS7_SignedData)) { ctype = ECT_SignedData; } else if(pkiCompareCssmData(&ec_oid, &CSSMOID_PKCS7_EnvelopedData)) { ctype = ECT_EnvelopedData; } else if(pkiCompareCssmData(&ec_oid, &CSSMOID_PKCS7_EncryptedData)) { ctype = ECT_EncryptedData; } else if(pkiCompareCssmData(&ec_oid, &_CSSMOID_PKINIT_AUTH_DATA)) { ctype = ECT_PkAuthData; } else if(pkiCompareCssmData(&ec_oid, &_CSSMOID_PKINIT_RKEY_DATA)) { ctype = ECT_PkReplyKeyKata; } else { ctype = ECT_Other; } *inner_content_type = ctype; CFRelease(ec_data); } /* * Get SignedData's certs if the caller wants them */ if(all_certs) { ortn = CMSDecoderCopyAllCerts(decoder, &cf_all_certs); if(ortn) { pkiCssmErr("CMSDecoderCopyAllCerts", ortn); krtn = KRB5_CRYPTO_INTERNAL; goto errOut; } krtn = pkiCertArrayToKrb5Data(cf_all_certs, num_all_certs, all_certs); if(krtn) { goto errOut; } } /* optional signer cert */ if(signer_cert) { SecCertificateRef sec_signer_cert = NULL; CSSM_DATA cert_data; ortn = CMSDecoderCopySignerCert(decoder, 0, &sec_signer_cert); if(ortn) { /* should never happen if it's signed */ pkiCssmErr("CMSDecoderCopySignerStatus", ortn); krtn = KRB5_CRYPTO_INTERNAL; goto errOut; } ortn = SecCertificateGetData(sec_signer_cert, &cert_data); if(ortn) { pkiCssmErr("SecCertificateGetData", ortn); CFRelease(sec_signer_cert); krtn = KRB5_CRYPTO_INTERNAL; goto errOut; } krtn = pkiDataToKrb5Data(cert_data.Data, cert_data.Length, signer_cert); CFRelease(sec_signer_cert); if(krtn) { goto errOut; } } } else { /* not signed */ if(is_signed) { *is_signed = FALSE; } if(inner_content_type) { *inner_content_type = ECT_Other; } if(signer_cert) { signer_cert->data = NULL; signer_cert->length = 0; } if(signer_cert_status) { *signer_cert_status = pki_not_signed; } if(num_all_certs) { *num_all_certs = 0; } if(all_certs) { *all_certs = NULL; } } if(is_encrypted) { Boolean bencr; ortn = CMSDecoderIsContentEncrypted(decoder, &bencr); if(ortn) { pkiCssmErr("CMSDecoderCopySignerStatus", ortn); krtn = KRB5_CRYPTO_INTERNAL; goto errOut; } *is_encrypted = bencr ? TRUE : FALSE; } /* * Verify signature and cert. The actual verify operation is optional, * per our signer_cert_status argument, but we do this anyway if we need * to get the signer cert. */ if((signer_cert_status != NULL) || (signer_cert != NULL)) { ortn = CMSDecoderCopySignerStatus(decoder, 0, /* signerIndex */ policy, signer_cert_status ? TRUE : FALSE, /* evaluateSecTrust */ &signer_status, NULL, /* secTrust - not needed */ &cert_verify_status); if(ortn) { /* gross error - subsequent processing impossible */ pkiCssmErr("CMSDecoderCopySignerStatus", ortn); krtn = KRB5_PARSE_MALFORMED; goto errOut; } } /* obtain & return status */ if(signer_cert_status) { *signer_cert_status = pkiInferSigStatus(signer_status, cert_verify_status); } /* finally, the payload */ if(raw_data) { CFDataRef cf_content = NULL; ortn = CMSDecoderCopyContent(decoder, &cf_content); if(ortn) { pkiCssmErr("CMSDecoderCopyContent", ortn); krtn = KRB5_PARSE_MALFORMED; goto errOut; } krtn = pkiCfDataToKrb5Data(cf_content, raw_data); CFRELEASE(cf_content); } errOut: CFRELEASE(policy_search); CFRELEASE(policy); CFRELEASE(cf_all_certs); CFRELEASE(decoder); return krtn; }
/* * Given a SecIdentityRef, do our best to construct a complete, ordered, and * verified cert chain, returning the result in a CFArrayRef. The result is * suitable for use when calling SSLSetCertificate(). */ OSStatus sslCompleteCertChain( SecIdentityRef identity, SecCertificateRef trustedAnchor, // optional additional trusted anchor bool includeRoot, // include the root in outArray CFArrayRef *outArray) // created and RETURNED { CFMutableArrayRef certArray; SecTrustRef secTrust = NULL; SecPolicyRef policy = NULL; SecPolicySearchRef policySearch = NULL; SecTrustResultType secTrustResult; CSSM_TP_APPLE_EVIDENCE_INFO *dummyEv; // not used CFArrayRef certChain = NULL; // constructed chain CFIndex numResCerts; certArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(certArray, identity); /* * Case 1: identity is a root; we're done. Note that this case * overrides the includeRoot argument. */ SecCertificateRef certRef; OSStatus ortn = SecIdentityCopyCertificate(identity, &certRef); if(ortn) { /* should never happen */ cssmPerror("SecIdentityCopyCertificate", ortn); return ortn; } bool isRoot = isCertRefRoot(certRef); if(isRoot) { *outArray = certArray; CFRelease(certRef); return errSecSuccess; } /* * Now use SecTrust to get a complete cert chain, using all of the * user's keychains to look for intermediate certs. * NOTE this does NOT handle root certs which are not in the system * root cert DB. (The above case, where the identity is a root cert, does.) */ CFMutableArrayRef subjCerts = CFArrayCreateMutable(NULL, 1, &kCFTypeArrayCallBacks); CFArraySetValueAtIndex(subjCerts, 0, certRef); /* the array owns the subject cert ref now */ CFRelease(certRef); /* Get a SecPolicyRef for generic X509 cert chain verification */ ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, // value &policySearch); if(ortn) { cssmPerror("SecPolicySearchCreate", ortn); goto errOut; } ortn = SecPolicySearchCopyNext(policySearch, &policy); if(ortn) { cssmPerror("SecPolicySearchCopyNext", ortn); goto errOut; } /* build a SecTrustRef for specified policy and certs */ ortn = SecTrustCreateWithCertificates(subjCerts, policy, &secTrust); if(ortn) { cssmPerror("SecTrustCreateWithCertificates", ortn); goto errOut; } if(trustedAnchor) { /* * Tell SecTrust to trust this one in addition to the current * trusted system-wide anchors. */ CFMutableArrayRef newAnchors; CFArrayRef currAnchors; ortn = SecTrustCopyAnchorCertificates(&currAnchors); if(ortn) { /* should never happen */ cssmPerror("SecTrustCopyAnchorCertificates", ortn); goto errOut; } newAnchors = CFArrayCreateMutableCopy(NULL, CFArrayGetCount(currAnchors) + 1, currAnchors); CFRelease(currAnchors); CFArrayAppendValue(newAnchors, trustedAnchor); ortn = SecTrustSetAnchorCertificates(secTrust, newAnchors); CFRelease(newAnchors); if(ortn) { cssmPerror("SecTrustSetAnchorCertificates", ortn); goto errOut; } } /* evaluate: GO */ ortn = SecTrustEvaluate(secTrust, &secTrustResult); if(ortn) { cssmPerror("SecTrustEvaluate", ortn); goto errOut; } switch(secTrustResult) { case kSecTrustResultUnspecified: /* cert chain valid, no special UserTrust assignments */ case kSecTrustResultProceed: /* cert chain valid AND user explicitly trusts this */ break; default: /* * Cert chain construction failed. * Just go with the single subject cert we were given. */ printf("***Warning: could not construct completed cert chain\n"); ortn = errSecSuccess; goto errOut; } /* get resulting constructed cert chain */ ortn = SecTrustGetResult(secTrust, &secTrustResult, &certChain, &dummyEv); if(ortn) { cssmPerror("SecTrustEvaluate", ortn); goto errOut; } /* * Copy certs from constructed chain to our result array, skipping * the leaf (which is already there, as a SecIdentityRef) and possibly * a root. */ numResCerts = CFArrayGetCount(certChain); if(numResCerts < 2) { /* * Can't happen: if subject was a root, we'd already have returned. * If chain doesn't verify to a root, we'd have bailed after * SecTrustEvaluate(). */ printf("***sslCompleteCertChain screwup: numResCerts %d\n", (int)numResCerts); ortn = errSecSuccess; goto errOut; } if(!includeRoot) { /* skip the last (root) cert) */ numResCerts--; } for(CFIndex dex=1; dex<numResCerts; dex++) { certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certChain, dex); CFArrayAppendValue(certArray, certRef); } errOut: /* clean up */ if(secTrust) { CFRelease(secTrust); } if(subjCerts) { CFRelease(subjCerts); } if(policy) { CFRelease(policy); } if(policySearch) { CFRelease(policySearch); } *outArray = certArray; return ortn; }
CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot) { SecPolicySearchRef searchRef = NULL; SecPolicyRef policy = NULL; CFArrayRef wrappedCert = NULL; SecTrustRef trust = NULL; CFArrayRef certChain = NULL; CSSM_TP_APPLE_EVIDENCE_INFO *statusChain; CFDataRef actionData = NULL; OSStatus status = 0; if (!cert) goto loser; status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &searchRef); if (status) goto loser; status = SecPolicySearchCopyNext(searchRef, &policy); if (status) goto loser; wrappedCert = CERT_CertListFromCert(cert); status = SecTrustCreateWithCertificates(wrappedCert, policy, &trust); if (status) goto loser; /* Tell SecTrust that we don't care if any certs in the chain have expired, nor do we want to stop when encountering a cert with a trust setting; we always want to build the full chain. */ CSSM_APPLE_TP_ACTION_DATA localActionData = { CSSM_APPLE_TP_ACTION_VERSION, CSSM_TP_ACTION_ALLOW_EXPIRED | CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT }; actionData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)&localActionData, sizeof(localActionData), kCFAllocatorNull); if (!actionData) goto loser; status = SecTrustSetParameters(trust, CSSM_TP_ACTION_DEFAULT, actionData); if (status) goto loser; status = SecTrustEvaluate(trust, NULL); if (status) goto loser; status = SecTrustGetResult(trust, NULL, &certChain, &statusChain); if (status) goto loser; /* We don't drop the root if there is only 1 (self signed) certificate in the chain. */ if (!includeRoot && CFArrayGetCount(certChain) > 1) { CFMutableArrayRef subChain = CFArrayCreateMutableCopy(NULL, 0, certChain); CFRelease(certChain); certChain = subChain; if (subChain) CFArrayRemoveValueAtIndex(subChain, CFArrayGetCount(subChain) - 1); } loser: if (searchRef) CFRelease(searchRef); if (policy) CFRelease(policy); if (wrappedCert) CFRelease(wrappedCert); if (trust) CFRelease(trust); if (actionData) CFRelease(actionData); if (certChain && status) { CFRelease(certChain); certChain = NULL; } return certChain; }
/* new in 10.7 */ SecPolicyRef SecPolicyCreateWithOID(CFTypeRef policyOID) { // for now, we only accept the policy constants that are defined in SecPolicy.h CFStringRef oidStr = (CFStringRef)policyOID; CSSM_OID *oidPtr = NULL; SecPolicyRef policy = NULL; if (!oidStr) { return policy; } struct oidmap_entry_t { const CFTypeRef oidstr; const SecAsn1Oid *oidptr; }; const oidmap_entry_t oidmap[] = { { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC }, { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL }, { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME }, { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP }, { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC }, { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT }, { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT }, { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER }, { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING }, { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT }, { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING }, { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING }, { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION }, { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING }, { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE }, { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE }, { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING }, { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING }, { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE }, { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE }, }; unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t); for (i=0; i<oidmaplen; i++) { CFStringRef str = (CFStringRef) oidmap[i].oidstr; if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) { oidPtr = (CSSM_OID*)oidmap[i].oidptr; break; } } if (CFEqual(oidStr, kSecPolicyAppleServerAuthentication)) { return SecPolicyCreateAppleSSLService(NULL); } if (oidPtr) { SecPolicySearchRef policySearch = NULL; OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, oidPtr, NULL, &policySearch); if (!status && policySearch) { status = SecPolicySearchCopyNext(policySearch, &policy); CFRelease(policySearch); } if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) { policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); } if (!policy) { policy = SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid*)oidPtr); } } return policy; }