X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..07691282a056c4efea71e1e505527601e8cc166b:/OSX/libsecurity_keychain/lib/TrustSettings.cpp diff --git a/OSX/libsecurity_keychain/lib/TrustSettings.cpp b/OSX/libsecurity_keychain/lib/TrustSettings.cpp index bcd2d033..ceafbb01 100644 --- a/OSX/libsecurity_keychain/lib/TrustSettings.cpp +++ b/OSX/libsecurity_keychain/lib/TrustSettings.cpp @@ -40,6 +40,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -48,11 +51,17 @@ #include #include #include -#include +#include #include +#include -#define trustSettingsDbg(args...) secdebug("trustSettings", ## args) -#define trustSettingsEvalDbg(args...) secdebug("trustSettingsEval", ## args) +#if 0 +#define trustSettingsDbg(args...) syslog(LOG_ERR, ## args) +#define trustSettingsEvalDbg(args...) syslog(LOG_ERR, ## args) +#else +#define trustSettingsDbg(args...) secinfo("trustSettings", ## args) +#define trustSettingsEvalDbg(args...) secinfo("trustSettingsEval", ## args) +#endif /* * Common error return for "malformed TrustSettings record" @@ -108,7 +117,7 @@ static bool tsCheckApp( OSStatus ortn; ortn = SecTrustedApplicationCreateWithExternalRepresentation(certApp, &appRef); if(ortn) { - trustSettingsDbg("tsCheckApp: bad trustedApp data\n"); + trustSettingsDbg("tsCheckApp: bad trustedApp data"); return false; } ortn = SecTrustedApplicationValidateWithPath(appRef, NULL); @@ -172,6 +181,7 @@ static bool tsCheckPolicyStr( if (certPolicyStrNoNULL == NULL) { /* I really don't see how this can happen either */ trustSettingsEvalDbg("tsCheckPolicyStr: policyStr string conversion error 2"); + CFReleaseNull(cfPolicyStr); return false; } @@ -621,10 +631,6 @@ bool TrustSettings::evaluateCert( /* get trust settings dictionary for this cert */ CFDictionaryRef certDict = findDictionaryForCertHash(certHashStr); - if((certDict == NULL) && isRootCert) { - /* No? How about default root setting for this domain? */ - certDict = findDictionaryForCertHash(kSecTrustRecordDefaultRootCert); - } #if CERT_HASH_DEBUG /* @@@ debug only @@@ */ /* print certificate hash and found dictionary reference */ @@ -800,32 +806,36 @@ void TrustSettings::findQualifiedCerts( CFRef certSet(CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks)); /* search: all certs, no attributes */ - KCCursor cursor(keychains, CSSM_DL_DB_RECORD_X509_CERTIFICATE, NULL); + KCCursor cursor(keychains, (SecItemClass) CSSM_DL_DB_RECORD_X509_CERTIFICATE, NULL); Item certItem; bool found; + unsigned int total=0, entries=0, qualified=0; do { found = cursor->next(certItem); if(!found) { break; } - #if !SECTRUST_OSX - CFRef certRef((SecCertificateRef)certItem->handle()); - #else + ++total; + /* must convert to unified SecCertificateRef */ SecPointer certificate(static_cast(&*certItem)); - CssmData certCssmData = certificate->data(); + CssmData certCssmData; + try { + certCssmData = certificate->data(); + } + catch (...) {} if (!(certCssmData.Data && certCssmData.Length)) { continue; } CFRef cfDataRef(CFDataCreate(NULL, certCssmData.Data, certCssmData.Length)); CFRef certRef(SecCertificateCreateWithData(NULL, cfDataRef)); - #endif /* do we have an entry for this cert? */ CFDictionaryRef certDict = findDictionaryForCert(certRef); if(certDict == NULL) { continue; } + ++entries; if(!findAll) { /* qualify */ @@ -834,6 +844,7 @@ void TrustSettings::findQualifiedCerts( continue; } } + ++qualified; /* see if we already have this one - get in CFData form */ CSSM_DATA certData; @@ -843,7 +854,7 @@ void TrustSettings::findQualifiedCerts( continue; } CFRef cfData(CFDataCreate(NULL, certData.Data, certData.Length)); - CFDataRef cfd = cfData; + CFDataRef cfd = cfData.get(); if(CFSetContainsValue(certSet, cfd)) { trustSettingsEvalDbg("findQualifiedCerts: dup cert"); continue; @@ -855,6 +866,9 @@ void TrustSettings::findQualifiedCerts( CFArrayAppendValue(certArray, certRef); } } while(found); + + trustSettingsEvalDbg("findQualifiedCerts: examined %d certs, qualified %d of %d", + total, qualified, entries); } /* @@ -893,7 +907,8 @@ CFArrayRef TrustSettings::copyTrustSettings( /* already validated... */ assert(CFGetTypeID(diskTsDict) == CFDictionaryGetTypeID()); - CFDataRef certPolicy = (CFDataRef) CFDictionaryGetValue(diskTsDict, kSecTrustSettingsPolicy); + CFTypeRef certPolicy = (CFTypeRef) CFDictionaryGetValue(diskTsDict, kSecTrustSettingsPolicy); + CFStringRef policyName = (CFStringRef)CFDictionaryGetValue(diskTsDict, kSecTrustSettingsPolicyName); CFDataRef certApp = (CFDataRef) CFDictionaryGetValue(diskTsDict, kSecTrustSettingsApplication); CFStringRef policyStr = (CFStringRef)CFDictionaryGetValue(diskTsDict, kSecTrustSettingsPolicyString); CFNumberRef allowedErr = (CFNumberRef)CFDictionaryGetValue(diskTsDict, kSecTrustSettingsAllowedError); @@ -915,17 +930,33 @@ CFArrayRef TrustSettings::copyTrustSettings( &kCFTypeDictionaryValueCallBacks)); if(certPolicy != NULL) { - /* convert OID as CFDataRef to SecPolicyRef */ SecPolicyRef policyRef = NULL; - CSSM_OID policyOid = { CFDataGetLength(certPolicy), - (uint8 *)CFDataGetBytePtr(certPolicy) }; - OSStatus ortn = SecPolicyCopy(CSSM_CERT_X_509v3, &policyOid, &policyRef); - if(ortn) { - trustSettingsDbg("copyTrustSettings: OID conversion error"); - abort("Bad Policy OID in trusted root list", errSecInvalidTrustedRootRecord); + if (CFDataGetTypeID() == CFGetTypeID(certPolicy)) { + /* convert OID as CFDataRef to SecPolicyRef */ + CSSM_OID policyOid = { int_cast(CFDataGetLength((CFDataRef)certPolicy)), + (uint8 *)CFDataGetBytePtr((CFDataRef)certPolicy) }; + OSStatus ortn = SecPolicyCopy(CSSM_CERT_X_509v3, &policyOid, &policyRef); + if(ortn) { + trustSettingsDbg("copyTrustSettings: OID conversion error"); + abort("Bad Policy OID in trusted root list", errSecInvalidTrustedRootRecord); + } + } else if (CFStringGetTypeID() == CFGetTypeID(certPolicy)) { + policyRef = SecPolicyCreateWithProperties(certPolicy, NULL); + } + if (policyRef) { + CFDictionaryAddValue(outTsDict, kSecTrustSettingsPolicy, policyRef); + CFRelease(policyRef); // owned by dictionary } - CFDictionaryAddValue(outTsDict, kSecTrustSettingsPolicy, policyRef); - CFRelease(policyRef); // owned by dictionary + } + + if (policyName != NULL) { + /* + * copy, since policyName is in our mutable dictionary and could change out from + * under the caller + */ + CFStringRef str = CFStringCreateCopy(NULL, policyName); + CFDictionaryAddValue(outTsDict, kSecTrustSettingsPolicyName, str); + CFRelease(str); // owned by dictionary } if(certApp != NULL) { @@ -1135,7 +1166,7 @@ CFDictionaryRef TrustSettings::findDictionaryForCert( return NULL; } - return findDictionaryForCertHash(static_cast(certHashStr)); + return findDictionaryForCertHash(static_cast(certHashStr.get())); } /* @@ -1163,15 +1194,11 @@ CFArrayRef TrustSettings::validateApiTrustSettings( CFArrayRef tmpInArray = NULL; if(trustSettingsDictOrArray == NULL) { -#if SECTRUST_OSX -#warning STU: temporarily unblocking build -#else /* trivial case, only valid for roots */ if(!isSelfSigned) { trustSettingsDbg("validateApiUsageConstraints: !isSelfSigned, no settings"); MacOSError::throwMe(errSecParam); } -#endif return CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); } else if(CFGetTypeID(trustSettingsDictOrArray) == CFDictionaryGetTypeID()) { @@ -1198,7 +1225,8 @@ CFArrayRef TrustSettings::validateApiTrustSettings( /* convert */ for(CFIndex dex=0; dex certificate = SecCertificateCreateItemImplInstance(certRef); -#else - CFRef certificate = (SecCertificateRef) ((certRef) ? CFRetain(certRef) : NULL); -#endif SecPointer cert = Certificate::required(certificate); CSSM_DATA_PTR fieldVal;