#include "TrustSettings.h"
#include "TrustSettingsSchema.h"
-#include "SecTrustSettings.h"
+#include <Security/SecTrustSettings.h>
#include "TrustSettingsUtils.h"
#include "TrustKeychains.h"
#include "Certificate.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_ocspd/ocspdClient.h>
#include <CoreFoundation/CoreFoundation.h>
#include <assert.h>
-#include <Security/Authorization.h>
+#include <dispatch/dispatch.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"
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);
if (certPolicyStrNoNULL == NULL) {
/* I really don't see how this can happen either */
trustSettingsEvalDbg("tsCheckPolicyStr: policyStr string conversion error 2");
+ CFReleaseNull(cfPolicyStr);
return false;
}
/* 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 */
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;
+ unsigned int total=0, entries=0, qualified=0;
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));
- 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));
- #endif
/* do we have an entry for this cert? */
CFDictionaryRef certDict = findDictionaryForCert(certRef);
if(certDict == NULL) {
continue;
}
+ ++entries;
if(!findAll) {
/* qualify */
continue;
}
}
+ ++qualified;
/* see if we already have this one - get in CFData form */
CSSM_DATA certData;
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;
CFArrayAppendValue(certArray, certRef);
}
} while(found);
+
+ trustSettingsEvalDbg("findQualifiedCerts: examined %d certs, qualified %d of %d",
+ total, qualified, entries);
}
/*
/* 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);
&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<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) {
return NULL;
}
- return findDictionaryForCertHash(static_cast<CFStringRef>(certHashStr));
+ return findDictionaryForCertHash(static_cast<CFStringRef>(certHashStr.get()));
}
/*
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()) {
OSStatus ortn = errSecSuccess;
SecPolicyRef certPolicy;
SecTrustedApplicationRef certApp;
+ CFTypeRef oidData = NULL;
/* convert */
for(CFIndex dex=0; dex<numSpecs; dex++) {
- CFDataRef oidData = NULL;
+ CFStringRef policyName = NULL;
CFDataRef appData = NULL;
CFStringRef policyStr = NULL;
CFNumberRef allowedErr = NULL;
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;
}
- oidData = CFDataCreate(NULL, oid.Data, oid.Length);
+ policyName = SecPolicyGetName(certPolicy);
}
/* application - optional */
ortn = errSecParam;
break;
}
- result = resultNum;
+ result = (SecTrustSettingsResult) resultNum;
/* validate result later */
keyUsage = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage);
&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(allowedErr) {
CFDictionaryAddValue(outDict, kSecTrustSettingsAllowedError, allowedErr);
}
-#if SECTRUST_OSX
-#warning STU: temporarily unblocking build
+
ortn = errSecSuccess;
-#else
+
if(resultType) {
/* let's be really picky on this one */
switch(result) {
break;
}
}
-#endif
+
if(keyUsage) {
CFDictionaryAddValue(outDict, kSecTrustSettingsKeyUsage, keyUsage);
}
} /* for each usage constraint dictionary */
+ CFReleaseNull(oidData);
CFRelease(tmpInArray);
if(ortn) {
CFRelease(outArray);
CFDataRef *issuer, /* optional, RETURNED */
CFDataRef *serial) /* RETURNED */
{
-#if SECTRUST_OSX
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;