]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/lib/SecTrustSettings.cpp
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / SecTrustSettings.cpp
index a59873d64ec7d6fa04dc55eb9649b7184efc2a5a..c2a7e1334b2189377a107672ffa71cd3432faad8 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "SecBridge.h"
  */
 
 #include "SecBridge.h"
-#include "SecCertificatePriv.h"
-#include "SecTrustSettings.h"
-#include "SecTrustSettingsPriv.h"
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecTrustSettings.h>
+#include <Security/SecTrustSettingsPriv.h>
 #include "SecTrustSettingsCertificates.h"
 #include "SecCFRelease.h"
 #include "TrustSettingsUtils.h"
 #include "SecTrustSettingsCertificates.h"
 #include "SecCFRelease.h"
 #include "TrustSettingsUtils.h"
@@ -48,7 +48,7 @@
 #include <security_utilities/simpleprefs.h>
 #include <securityd_client/dictionary.h>
 #include <securityd_client/ssclient.h>
 #include <security_utilities/simpleprefs.h>
 #include <securityd_client/dictionary.h>
 #include <securityd_client/ssclient.h>
-#include <assert.h>
+#include <security_utilities/simulatecrash_assert.h>
 #include <dlfcn.h>
 #include <libproc.h>
 #include <syslog.h>
 #include <dlfcn.h>
 #include <libproc.h>
 #include <syslog.h>
@@ -108,7 +108,7 @@ static bool tsUserTrustSettingsDisabled()
        Dictionary* dictionary = Dictionary::CreateDictionary(kSecTrustSettingsPrefsDomain, Dictionary::US_System);
        if (dictionary)
        {
        Dictionary* dictionary = Dictionary::CreateDictionary(kSecTrustSettingsPrefsDomain, Dictionary::US_System);
        if (dictionary)
        {
-               auto_ptr<Dictionary> prefsDict(dictionary);
+               unique_ptr<Dictionary> prefsDict(dictionary);
                /* this returns false if the pref isn't there, just like we want */
                tsUserTrustDisable = prefsDict->getBoolValue(kSecTrustSettingsDisableUserTrustSettings);
        }
                /* 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();
 static void tsTrustSettingsChanged()
 {
        tsPurgeCache();
+    SecTrustSettingsPurgeUserAdminCertsCache();
 
        /* The only interesting data is our pid */
        NameValueDictionary nvd;
 
        /* The only interesting data is our pid */
        NameValueDictionary nvd;
@@ -347,7 +348,7 @@ static OSStatus tsCopyTrustSettings(
                return result;
        }
 
                return result;
        }
 
-       auto_ptr<TrustSettings>_(ts); // make sure this gets deleted just in case something throws underneath
+       unique_ptr<TrustSettings>_(ts); // make sure this gets deleted just in case something throws underneath
 
        if(trustSettings) {
                *trustSettings = ts->copyTrustSettings(cert);
 
        if(trustSettings) {
                *trustSettings = ts->copyTrustSettings(cert);
@@ -359,6 +360,59 @@ static OSStatus tsCopyTrustSettings(
        END_RCSAPI
 }
 
        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<Mutex>    _(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<Mutex>    _(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);
 
 /*
 static void tsAddConditionalCerts(CFMutableArrayRef certArray);
 
 /*
@@ -726,7 +780,7 @@ OSStatus SecTrustSettingsSetTrustSettingsExternal(
                return result;
        }
 
                return result;
        }
 
-       auto_ptr<TrustSettings>_(ts);
+       unique_ptr<TrustSettings>_(ts);
 
        if(certRef != NULL) {
                ts->setTrustSettings(certRef, trustSettingsDictOrArray);
 
        if(certRef != NULL) {
                ts->setTrustSettings(certRef, trustSettingsDictOrArray);
@@ -737,6 +791,25 @@ OSStatus SecTrustSettingsSetTrustSettingsExternal(
        END_RCSAPI
 }
 
        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(
 #pragma mark --- API functions ---
 
 OSStatus SecTrustSettingsCopyTrustSettings(
@@ -791,7 +864,7 @@ OSStatus SecTrustSettingsSetTrustSettings(
                return result;
        }
 
                return result;
        }
 
-       auto_ptr<TrustSettings>_(ts);
+       unique_ptr<TrustSettings>_(ts);
 
        ts->setTrustSettings(certRef, trustSettingsDictOrArray);
        ts->flushToDisk();
 
        ts->setTrustSettings(certRef, trustSettingsDictOrArray);
        ts->flushToDisk();
@@ -821,7 +894,7 @@ OSStatus SecTrustSettingsRemoveTrustSettings(
                return result;
        }
 
                return result;
        }
 
-       auto_ptr<TrustSettings>_(ts);
+       unique_ptr<TrustSettings>_(ts);
 
        /* deleteTrustSettings throws if record not found */
        trustSettingsDbg("SecTrustSettingsRemoveTrustSettings: deleting from domain %d",
 
        /* 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;
        OSStatus status;
        TrustSettings* ts;
        CFMutableArrayRef trustedCertArray = NULL;
+    SecTrustRef trust = NULL;
 
        status = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
        if (status != errSecSuccess) {
                return status;
        }
 
 
        status = TrustSettings::CreateTrustSettings(domain, CREATE_NO, TRIM_NO, ts);
        if (status != errSecSuccess) {
                return status;
        }
 
-       auto_ptr<TrustSettings>_(ts);
+       unique_ptr<TrustSettings>_(ts);
 
        CFMutableArrayRef outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
     
 
        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++) {
         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);
             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);
             }
             if (result != kSecTrustResultFatalTrustFailure) {
                 CFArrayAppendValue(trustedCertArray, certificate);
             }
+            CFReleaseNull(trust);
         }
                tsAddConditionalCerts(trustedCertArray);
         if (CFArrayGetCount(trustedCertArray) == 0) {
         }
                tsAddConditionalCerts(trustedCertArray);
         if (CFArrayGetCount(trustedCertArray) == 0) {
@@ -925,16 +999,17 @@ out:
         CFReleaseSafe(outArray);
                CFReleaseSafe(trustedCertArray);
      }
         CFReleaseSafe(outArray);
                CFReleaseSafe(trustedCertArray);
      }
+    CFReleaseNull(trust);
     return status;
        END_RCSAPI
 }
 
 static CFArrayRef gUserAdminCerts = NULL;
 static bool gUserAdminCertsCacheBuilt = false;
     return status;
        END_RCSAPI
 }
 
 static CFArrayRef gUserAdminCerts = NULL;
 static bool gUserAdminCertsCacheBuilt = false;
-static ReadWriteLock gUserAdminCertsLock;
+static ModuleNexus<ReadWriteLock> gUserAdminCertsLock;
 
 void SecTrustSettingsPurgeUserAdminCertsCache(void) {
 
 void SecTrustSettingsPurgeUserAdminCertsCache(void) {
-    StReadWriteLock _(gUserAdminCertsLock, StReadWriteLock::Write);
+    StReadWriteLock _(gUserAdminCertsLock(), StReadWriteLock::Write);
     CFReleaseNull(gUserAdminCerts);
     gUserAdminCertsCacheBuilt = false;
 }
     CFReleaseNull(gUserAdminCerts);
     gUserAdminCertsCacheBuilt = false;
 }
@@ -946,7 +1021,7 @@ OSStatus SecTrustSettingsCopyCertificatesForUserAdminDomains(
     OSStatus result = errSecSuccess;
 
     { /* Hold the read lock for the check */
     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);
         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) {
 
     /* 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;
         CFReleaseNull(gUserAdminCerts);
         gUserAdminCerts = (CFArrayRef)CFRetainSafe(outArray);
         gUserAdminCertsCacheBuilt = true;
@@ -1000,6 +1075,16 @@ OSStatus SecTrustSettingsCopyCertificatesForUserAdminDomains(
     return result;
 }
 
     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.
 /*
  * 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;
        }
 
                return result;
        }
 
-       auto_ptr<TrustSettings>_(ts);
+       unique_ptr<TrustSettings>_(ts);
 
        *trustSettings = ts->createExternal();
        return errSecSuccess;
 
        *trustSettings = ts->createExternal();
        return errSecSuccess;
@@ -1050,7 +1135,7 @@ OSStatus SecTrustSettingsImportExternalRepresentation(
                return result;
        }
 
                return result;
        }
 
-       auto_ptr<TrustSettings>_(ts);
+       unique_ptr<TrustSettings>_(ts);
 
        ts->flushToDisk();
        tsTrustSettingsChanged();
 
        ts->flushToDisk();
        tsTrustSettingsChanged();