]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / SecTrustOSXEntryPoints.cpp
index 55c099397966b43cd93d20a0db60ab67b6e70c0c..49b9e3240a166ca0fd2b284a2250451411d8cc5f 100644 (file)
 
 #include "SecTrustOSXEntryPoints.h"
 
+#include <CoreFoundation/CoreFoundation.h>
+#include <dispatch/dispatch.h>
+#include <AssertMacros.h>
+#include <notify.h>
+#include <mach/mach_time.h>
+
 #include <Security/Security.h>
 #include <Security/cssmtype.h>
 #include <Security/SecKeychain.h>
 #include <Security/SecImportExport.h>
 #include <security_keychain/SecImportExportPem.h>
 #include <security_utilities/debugging.h>
+#include <Security/SecItemInternal.h>
 
 #include <security_ocspd/ocspdClient.h>
 #include <security_ocspd/ocspdUtils.h>
 
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFRunLoop.h>
-#include <dispatch/dispatch.h>
-#include <AssertMacros.h>
-#include <pthread.h>
-
-/*
- * MARK: CFRunloop
- */
-
-static OSStatus SecLegacySourceChanged(__unused SecKeychainEvent keychainEvent, __unused SecKeychainCallbackInfo *info, __unused void *context) {
-    // Purge keychain parent cache
-    SecItemParentCachePurge();
-    // Purge unrestricted roots cache
-    SecTrustSettingsPurgeUserAdminCertsCache();
-    return 0;
-}
-
-static void *SecTrustOSXCFRunloop(__unused void *unused) {
-    CFRunLoopTimerRef timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, (CFTimeInterval) UINT_MAX, 0, 0, 0, ^(__unused CFRunLoopTimerRef _timer) {
-        /* do nothing */
-    });
-
-    /* add a timer to force the runloop to stay running */
-    CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
-    /* add keychain callback before we initiate a runloop to avoid it exiting due to no sources */
-
-    SecKeychainEventMask trustdMask = (kSecAddEventMask | kSecDeleteEventMask | kSecUpdateEventMask |
-                                       kSecDefaultChangedEventMask | kSecKeychainListChangedMask |
-                                       kSecTrustSettingsChangedEventMask);
-    SecKeychainAddCallback(SecLegacySourceChanged, trustdMask, NULL);
-
-    try {
-        CFRunLoopRun();
-    }
-    catch (...) {
-        /* An exception was rethrown from the runloop. Since we can't reliably
-         * obtain info about changes to keychains or trust settings anymore,
-         * just exit and respawn the process when needed. */
-
-        secerror("Exception occurred in CFRunLoopRun; exiting");
-        exit(0);
-    }
-    CFRelease(timer);
-    return NULL;
-}
-
-void SecTrustLegacySourcesEventRunloopCreate(void) {
-    /* A runloop is currently necessary to receive notifications about changes in the
-     * legacy keychains and trust settings. */
-    static dispatch_once_t once;
-
-    dispatch_once(&once, ^{
-        pthread_attr_t attrs;
-        pthread_t thread;
 
-        pthread_attr_init(&attrs);
-        pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
+void SecTrustLegacySourcesListenForKeychainEvents(void) {
+    /* Register for CertificateTrustNotification */
+    int out_token = 0;
+    notify_register_dispatch(kSecServerCertificateTrustNotification, &out_token,
+                             dispatch_get_main_queue(),
+                             ^(int token __unused) {
+                                 // Purge keychain parent cache
+                                 SecItemParentCachePurge();
+                                 // Purge unrestricted roots cache
+                                 SecTrustSettingsPurgeUserAdminCertsCache();
 
-        /* we do this with traditional pthread to avoid impacting our 512 WQ thread limit since this is a parked thread */
-        pthread_create(&thread, &attrs, SecTrustOSXCFRunloop, NULL);
-    });
+                             });
 }
 
 /*
@@ -138,7 +96,7 @@ static OSStatus cssmReturnToOSStatus(CSSM_RETURN crtn) {
 }
 
 #define PEM_STRING_X509                "CERTIFICATE"
-static CFDataRef serializedPathToPemSequences(CFArrayRef certs) {
+static CFDataRef CF_RETURNS_RETAINED serializedPathToPemSequences(CFArrayRef certs) {
     CFMutableDataRef result = NULL;
     CFIndex certIX, certCount;
     require_quiet(certs, out);
@@ -166,7 +124,7 @@ OSStatus SecTrustLegacyCRLStatus(SecCertificateRef cert, CFArrayRef chain, CFURL
 
     /* serialNumber is a CSSM_DATA with the value from the TBS Certificate. */
     CSSM_DATA serialNumber = { 0, NULL };
-    serialData = SecCertificateCopySerialNumber(cert, NULL);
+    serialData = SecCertificateCopySerialNumberData(cert, NULL);
     if (serialData) {
         serialNumber.Data = (uint8_t *)CFDataGetBytePtr(serialData);
         serialNumber.Length = CFDataGetLength(serialData);
@@ -272,6 +230,7 @@ static void async_ocspd_complete(async_ocspd_t *ocspd) {
 bool SecTrustLegacyCRLFetch(async_ocspd_t *ocspd,
                        CFURLRef currCRLDP, CFAbsoluteTime verifyTime,
                        SecCertificateRef cert, CFArrayRef chain) {
+    ocspd->start_time = mach_absolute_time();
     dispatch_async(ocspd->queue, ^ {
         OSStatus status = fetchCRL(currCRLDP, verifyTime);
         switch (status) {