X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/ecaf5866106b8f08bdb7c1b4f489ef4dfd01278a..refs/heads/master:/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp diff --git a/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp b/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp index a59873d6..c2a7e133 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp +++ b/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp @@ -27,9 +27,9 @@ */ #include "SecBridge.h" -#include "SecCertificatePriv.h" -#include "SecTrustSettings.h" -#include "SecTrustSettingsPriv.h" +#include +#include +#include #include "SecTrustSettingsCertificates.h" #include "SecCFRelease.h" #include "TrustSettingsUtils.h" @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include #include @@ -108,7 +108,7 @@ static bool tsUserTrustSettingsDisabled() Dictionary* dictionary = Dictionary::CreateDictionary(kSecTrustSettingsPrefsDomain, Dictionary::US_System); if (dictionary) { - auto_ptr prefsDict(dictionary); + unique_ptr prefsDict(dictionary); /* this returns false if the pref isn't there, just like we want */ tsUserTrustDisable = prefsDict->getBoolValue(kSecTrustSettingsDisableUserTrustSettings); } @@ -303,6 +303,7 @@ static void tsRegisterCallback() static void tsTrustSettingsChanged() { tsPurgeCache(); + SecTrustSettingsPurgeUserAdminCertsCache(); /* The only interesting data is our pid */ NameValueDictionary nvd; @@ -347,7 +348,7 @@ static OSStatus tsCopyTrustSettings( return result; } - auto_ptr_(ts); // make sure this gets deleted just in case something throws underneath + unique_ptr_(ts); // make sure this gets deleted just in case something throws underneath if(trustSettings) { *trustSettings = ts->copyTrustSettings(cert); @@ -359,6 +360,59 @@ static OSStatus tsCopyTrustSettings( END_RCSAPI } +/* + * Common code for SecTrustSettingsCopyTrustSettings(), + * SecTrustSettingsCopyModificationDate(). + */ +static OSStatus tsCopyTrustSettings_cached( + SecCertificateRef cert, + SecTrustSettingsDomain domain, + CFArrayRef CF_RETURNS_RETAINED *trustSettings) +{ + BEGIN_RCSAPI + + TS_REQUIRED(cert) + + StLock _(sutCacheLock()); + TrustSettings* ts = tsGetGlobalTrustSettings(domain); + + // rather than throw these results, just return them because we are at the top level + if (ts == NULL) { + return errSecItemNotFound; + } + + if(trustSettings) { + *trustSettings = ts->copyTrustSettings(cert); + } + + END_RCSAPI +} + +static OSStatus tsContains( + SecCertificateRef cert, + SecTrustSettingsDomain domain) +{ + BEGIN_RCSAPI + + TS_REQUIRED(cert) + + StLock _(sutCacheLock()); + TrustSettings* ts = tsGetGlobalTrustSettings(domain); + + // rather than throw these results, just return them because we are at the top level + if (ts == NULL) { + return errSecItemNotFound; + } + + if (ts->contains(cert)) { + return errSecSuccess; + } else { + return errSecItemNotFound; + } + + END_RCSAPI +} + static void tsAddConditionalCerts(CFMutableArrayRef certArray); /* @@ -726,7 +780,7 @@ OSStatus SecTrustSettingsSetTrustSettingsExternal( return result; } - auto_ptr_(ts); + unique_ptr_(ts); if(certRef != NULL) { ts->setTrustSettings(certRef, trustSettingsDictOrArray); @@ -737,6 +791,25 @@ OSStatus SecTrustSettingsSetTrustSettingsExternal( END_RCSAPI } +void SecTrustSettingsPurgeCache(void) { + tsPurgeCache(); +} + +OSStatus SecTrustSettingsCopyTrustSettings_Cached( + SecCertificateRef certRef, + SecTrustSettingsDomain domain, + CFArrayRef CF_RETURNS_RETAINED *trustSettings) /* RETURNED */ +{ + TS_REQUIRED(certRef) + TS_REQUIRED(trustSettings) + + OSStatus result = tsCopyTrustSettings_cached(certRef, domain, trustSettings); + if (result == errSecSuccess && *trustSettings == NULL) { + result = errSecItemNotFound; /* documented result if no trust settings exist */ + } + return result; +} + #pragma mark --- API functions --- OSStatus SecTrustSettingsCopyTrustSettings( @@ -791,7 +864,7 @@ OSStatus SecTrustSettingsSetTrustSettings( return result; } - auto_ptr_(ts); + unique_ptr_(ts); ts->setTrustSettings(certRef, trustSettingsDictOrArray); ts->flushToDisk(); @@ -821,7 +894,7 @@ OSStatus SecTrustSettingsRemoveTrustSettings( return result; } - auto_ptr_(ts); + unique_ptr_(ts); /* deleteTrustSettings throws if record not found */ trustSettingsDbg("SecTrustSettingsRemoveTrustSettings: deleting from domain %d", @@ -846,13 +919,14 @@ OSStatus SecTrustSettingsCopyCertificates( OSStatus status; TrustSettings* ts; CFMutableArrayRef trustedCertArray = NULL; + SecTrustRef trust = NULL; status = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts); if (status != errSecSuccess) { return status; } - auto_ptr_(ts); + unique_ptr_(ts); CFMutableArrayRef outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -892,7 +966,6 @@ OSStatus SecTrustSettingsCopyCertificates( SecPolicyRef policy = SecPolicyCreateBasicX509(); trustedCertArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < count ; i++) { - SecTrustRef trust; SecTrustResultType result; SecCertificateRef certificate = (SecCertificateRef) CFArrayGetValueAtIndex(outArray, i); status = SecTrustCreateWithCertificates(certificate, policy, &trust); @@ -908,6 +981,7 @@ OSStatus SecTrustSettingsCopyCertificates( if (result != kSecTrustResultFatalTrustFailure) { CFArrayAppendValue(trustedCertArray, certificate); } + CFReleaseNull(trust); } tsAddConditionalCerts(trustedCertArray); if (CFArrayGetCount(trustedCertArray) == 0) { @@ -925,16 +999,17 @@ out: CFReleaseSafe(outArray); CFReleaseSafe(trustedCertArray); } + CFReleaseNull(trust); return status; END_RCSAPI } static CFArrayRef gUserAdminCerts = NULL; static bool gUserAdminCertsCacheBuilt = false; -static ReadWriteLock gUserAdminCertsLock; +static ModuleNexus gUserAdminCertsLock; void SecTrustSettingsPurgeUserAdminCertsCache(void) { - StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Write); + StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Write); CFReleaseNull(gUserAdminCerts); gUserAdminCertsCacheBuilt = false; } @@ -946,7 +1021,7 @@ OSStatus SecTrustSettingsCopyCertificatesForUserAdminDomains( OSStatus result = errSecSuccess; { /* Hold the read lock for the check */ - StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Read); + StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Read); if (gUserAdminCertsCacheBuilt) { if (gUserAdminCerts) { *certArray = (CFArrayRef)CFRetain(gUserAdminCerts); @@ -991,7 +1066,7 @@ OSStatus SecTrustSettingsCopyCertificatesForUserAdminDomains( /* For valid results, update the global cache */ if (result == errSecSuccess || result == errSecNoTrustSettings) { - StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Write); + StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Write); CFReleaseNull(gUserAdminCerts); gUserAdminCerts = (CFArrayRef)CFRetainSafe(outArray); gUserAdminCertsCacheBuilt = true; @@ -1000,6 +1075,16 @@ OSStatus SecTrustSettingsCopyCertificatesForUserAdminDomains( return result; } +bool SecTrustSettingsUserAdminDomainsContain(SecCertificateRef certRef) +{ + TS_REQUIRED(certRef) + if (tsContains(certRef, kSecTrustSettingsDomainAdmin) == errSecSuccess || + tsContains(certRef, kSecTrustSettingsDomainUser) == errSecSuccess) { + return true; + } + return false; +} + /* * Obtain an external, portable representation of the specified * domain's TrustSettings. Caller must CFRelease the returned data. @@ -1020,7 +1105,7 @@ OSStatus SecTrustSettingsCreateExternalRepresentation( return result; } - auto_ptr_(ts); + unique_ptr_(ts); *trustSettings = ts->createExternal(); return errSecSuccess; @@ -1050,7 +1135,7 @@ OSStatus SecTrustSettingsImportExternalRepresentation( return result; } - auto_ptr_(ts); + unique_ptr_(ts); ts->flushToDisk(); tsTrustSettingsChanged();