]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/lib/TrustSettings.cpp
Security-59306.61.1.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / TrustSettings.cpp
index bcd2d033cf9575a738c68e6d1ad7725a688c409e..7474aca6e1aca1f6d36ee67a0fd906291609c2cb 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "TrustSettings.h"
 #include "TrustSettingsSchema.h"
 
 #include "TrustSettings.h"
 #include "TrustSettingsSchema.h"
-#include "SecTrustSettings.h"
+#include <Security/SecTrustSettings.h>
 #include "TrustSettingsUtils.h"
 #include "TrustKeychains.h"
 #include "Certificate.h"
 #include "TrustSettingsUtils.h"
 #include "TrustKeychains.h"
 #include "Certificate.h"
@@ -40,6 +40,9 @@
 #include <security_utilities/logging.h>
 #include <security_utilities/cfutilities.h>
 #include <security_utilities/alloc.h>
 #include <security_utilities/logging.h>
 #include <security_utilities/cfutilities.h>
 #include <security_utilities/alloc.h>
+#include <security_utilities/casts.h>
+#include <utilities/SecCFRelease.h>
+#include <Security/Authorization.h>
 #include <Security/cssmapplePriv.h>
 #include <Security/oidscert.h>
 #include <Security/SecCertificatePriv.h>
 #include <Security/cssmapplePriv.h>
 #include <Security/oidscert.h>
 #include <Security/SecCertificatePriv.h>
 #include <security_ocspd/ocspdClient.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <assert.h>
 #include <security_ocspd/ocspdClient.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <assert.h>
-#include <Security/Authorization.h>
+#include <dispatch/dispatch.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
+#include <syslog.h>
 
 
-#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"
 
 /*
  * Common error return for "malformed TrustSettings record"
@@ -108,7 +117,7 @@ static bool tsCheckApp(
                OSStatus ortn;
                ortn = SecTrustedApplicationCreateWithExternalRepresentation(certApp, &appRef);
                if(ortn) {
                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);
                        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");
                if (certPolicyStrNoNULL == NULL) {
                        /* I really don't see how this can happen either */
                        trustSettingsEvalDbg("tsCheckPolicyStr: policyStr string conversion error 2");
+            CFReleaseNull(cfPolicyStr);
                        return false;
                }
 
                        return false;
                }
 
@@ -621,10 +631,6 @@ bool TrustSettings::evaluateCert(
 
        /* get trust settings dictionary for this cert */
        CFDictionaryRef certDict = findDictionaryForCertHash(certHashStr);
 
        /* 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 */
 #if CERT_HASH_DEBUG
        /* @@@ debug only @@@ */
        /* print certificate hash and found dictionary reference */
@@ -800,32 +806,36 @@ void TrustSettings::findQualifiedCerts(
        CFRef<CFMutableSetRef> certSet(CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks));
 
        /* search: all certs, no attributes */
        CFRef<CFMutableSetRef> 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;
        Item certItem;
        bool found;
+       unsigned int total=0, entries=0, qualified=0;
        do {
                found = cursor->next(certItem);
                if(!found) {
                        break;
                }
        do {
                found = cursor->next(certItem);
                if(!found) {
                        break;
                }
-       #if !SECTRUST_OSX
-               CFRef<SecCertificateRef> certRef((SecCertificateRef)certItem->handle());
-       #else
+               ++total;
+
                /* must convert to unified SecCertificateRef */
                SecPointer<Certificate> certificate(static_cast<Certificate *>(&*certItem));
                /* must convert to unified SecCertificateRef */
                SecPointer<Certificate> certificate(static_cast<Certificate *>(&*certItem));
-               CssmData certCssmData = certificate->data();
+        CssmData certCssmData;
+        try {
+            certCssmData = certificate->data();
+        }
+        catch (...) {}
                if (!(certCssmData.Data && certCssmData.Length)) {
                        continue;
                }
                CFRef<CFDataRef> cfDataRef(CFDataCreate(NULL, certCssmData.Data, certCssmData.Length));
                CFRef<SecCertificateRef> certRef(SecCertificateCreateWithData(NULL, cfDataRef));
                if (!(certCssmData.Data && certCssmData.Length)) {
                        continue;
                }
                CFRef<CFDataRef> cfDataRef(CFDataCreate(NULL, certCssmData.Data, certCssmData.Length));
                CFRef<SecCertificateRef> certRef(SecCertificateCreateWithData(NULL, cfDataRef));
-       #endif
 
                /* do we have an entry for this cert? */
                CFDictionaryRef certDict = findDictionaryForCert(certRef);
                if(certDict == NULL) {
                        continue;
                }
 
                /* do we have an entry for this cert? */
                CFDictionaryRef certDict = findDictionaryForCert(certRef);
                if(certDict == NULL) {
                        continue;
                }
+               ++entries;
 
                if(!findAll) {
                        /* qualify */
 
                if(!findAll) {
                        /* qualify */
@@ -834,6 +844,7 @@ void TrustSettings::findQualifiedCerts(
                                continue;
                        }
                }
                                continue;
                        }
                }
+               ++qualified;
 
                /* see if we already have this one - get in CFData form */
                CSSM_DATA certData;
 
                /* see if we already have this one - get in CFData form */
                CSSM_DATA certData;
@@ -843,7 +854,7 @@ void TrustSettings::findQualifiedCerts(
                        continue;
                }
                CFRef<CFDataRef> cfData(CFDataCreate(NULL, certData.Data, certData.Length));
                        continue;
                }
                CFRef<CFDataRef> cfData(CFDataCreate(NULL, certData.Data, certData.Length));
-               CFDataRef cfd = cfData;
+               CFDataRef cfd = cfData.get();
                if(CFSetContainsValue(certSet, cfd)) {
                        trustSettingsEvalDbg("findQualifiedCerts: dup cert");
                        continue;
                if(CFSetContainsValue(certSet, cfd)) {
                        trustSettingsEvalDbg("findQualifiedCerts: dup cert");
                        continue;
@@ -855,6 +866,9 @@ void TrustSettings::findQualifiedCerts(
                        CFArrayAppendValue(certArray, certRef);
                }
        } while(found);
                        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());
 
                /* 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);
                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) {
                        &kCFTypeDictionaryValueCallBacks));
 
                if(certPolicy != NULL) {
-                       /* convert OID as CFDataRef to SecPolicyRef */
                        SecPolicyRef policyRef = NULL;
                        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<CFIndex, CSSM_SIZE>(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) {
                }
 
                if(certApp != NULL) {
@@ -1135,7 +1166,7 @@ CFDictionaryRef TrustSettings::findDictionaryForCert(
                return NULL;
        }
 
                return NULL;
        }
 
-       return findDictionaryForCertHash(static_cast<CFStringRef>(certHashStr));
+       return findDictionaryForCertHash(static_cast<CFStringRef>(certHashStr.get()));
 }
 
 /*
 }
 
 /*
@@ -1163,15 +1194,11 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
        CFArrayRef tmpInArray = NULL;
 
        if(trustSettingsDictOrArray == NULL) {
        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);
                }
                /* 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()) {
                return CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
        }
        else if(CFGetTypeID(trustSettingsDictOrArray) == CFDictionaryGetTypeID()) {
@@ -1195,10 +1222,11 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
        OSStatus ortn = errSecSuccess;
        SecPolicyRef certPolicy;
        SecTrustedApplicationRef certApp;
        OSStatus ortn = errSecSuccess;
        SecPolicyRef certPolicy;
        SecTrustedApplicationRef certApp;
+       CFTypeRef oidData = NULL;
 
        /* convert */
        for(CFIndex dex=0; dex<numSpecs; dex++) {
 
        /* convert */
        for(CFIndex dex=0; dex<numSpecs; dex++) {
-               CFDataRef   oidData = NULL;
+               CFStringRef policyName = NULL;
                CFDataRef   appData = NULL;
                CFStringRef policyStr = NULL;
                CFNumberRef allowedErr = NULL;
                CFDataRef   appData = NULL;
                CFStringRef policyStr = NULL;
                CFNumberRef allowedErr = NULL;
@@ -1224,11 +1252,18 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                                break;
                        }
                        ortn = SecPolicyGetOID(certPolicy, &oid);
                                break;
                        }
                        ortn = SecPolicyGetOID(certPolicy, &oid);
-                       if(ortn) {
+                       if (ortn) {
+                               /* newer policies don't have CSSM OIDs but they do have string OIDs */
+                               oidData = CFRetain(SecPolicyGetOidString(certPolicy));
+                       } else {
+                               oidData = CFDataCreate(NULL, oid.Data, oid.Length);
+                       }
+
+                       if (!oidData) {
                                trustSettingsDbg("validateAppPolicyArray: SecPolicyGetOID error");
                                break;
                        }
                                trustSettingsDbg("validateAppPolicyArray: SecPolicyGetOID error");
                                break;
                        }
-                       oidData = CFDataCreate(NULL, oid.Data, oid.Length);
+                       policyName = SecPolicyGetName(certPolicy);
                }
 
                /* application - optional */
                }
 
                /* application - optional */
@@ -1267,7 +1302,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                        ortn = errSecParam;
                        break;
                }
                        ortn = errSecParam;
                        break;
                }
-               result = resultNum;
+               result = (SecTrustSettingsResult) resultNum;
                /* validate result later */
 
                keyUsage   = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage);
                /* validate result later */
 
                keyUsage   = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage);
@@ -1290,7 +1325,11 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                        &kCFTypeDictionaryValueCallBacks);
                if(oidData) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsPolicy, oidData);
                        &kCFTypeDictionaryValueCallBacks);
                if(oidData) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsPolicy, oidData);
-                       CFRelease(oidData);                     // owned by dictionary
+                       CFReleaseNull(oidData);                 // owned by dictionary
+               }
+               if(policyName) {
+                       CFDictionaryAddValue(outDict, kSecTrustSettingsPolicyName, policyName);
+                       /* still owned by ucDict */
                }
                if(appData) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsApplication, appData);
                }
                if(appData) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsApplication, appData);
@@ -1303,10 +1342,9 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                if(allowedErr) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsAllowedError, allowedErr);
                }
                if(allowedErr) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsAllowedError, allowedErr);
                }
-#if SECTRUST_OSX
-#warning STU: temporarily unblocking build
+
                ortn = errSecSuccess;
                ortn = errSecSuccess;
-#else
+
                if(resultType) {
                        /* let's be really picky on this one */
                        switch(result) {
                if(resultType) {
                        /* let's be really picky on this one */
                        switch(result) {
@@ -1346,7 +1384,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
                                break;
                        }
                }
                                break;
                        }
                }
-#endif
+
                if(keyUsage) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsKeyUsage, keyUsage);
                }
                if(keyUsage) {
                        CFDictionaryAddValue(outDict, kSecTrustSettingsKeyUsage, keyUsage);
                }
@@ -1358,6 +1396,7 @@ CFArrayRef TrustSettings::validateApiTrustSettings(
 
        }       /* for each usage constraint dictionary */
 
 
        }       /* for each usage constraint dictionary */
 
+       CFReleaseNull(oidData);
        CFRelease(tmpInArray);
        if(ortn) {
                CFRelease(outArray);
        CFRelease(tmpInArray);
        if(ortn) {
                CFRelease(outArray);
@@ -1555,11 +1594,7 @@ void TrustSettings::copyIssuerAndSerial(
        CFDataRef                       *issuer,                /* optional, RETURNED */
        CFDataRef                       *serial)                /* RETURNED */
 {
        CFDataRef                       *issuer,                /* optional, RETURNED */
        CFDataRef                       *serial)                /* RETURNED */
 {
-#if SECTRUST_OSX
        CFRef<SecCertificateRef> certificate = SecCertificateCreateItemImplInstance(certRef);
        CFRef<SecCertificateRef> certificate = SecCertificateCreateItemImplInstance(certRef);
-#else
-       CFRef<SecCertificateRef> certificate = (SecCertificateRef) ((certRef) ? CFRetain(certRef) : NULL);
-#endif
 
        SecPointer<Certificate> cert = Certificate::required(certificate);
        CSSM_DATA_PTR fieldVal;
 
        SecPointer<Certificate> cert = Certificate::required(certificate);
        CSSM_DATA_PTR fieldVal;