-#include <libDER/oidsPriv.h>
-#include <Security/oidscert.h>
-static bool isSoftwareUpdateDevelopment(SecTrustRef trust) {
- bool isPolicy = false, isEKU = false;
- CFArrayRef policies = NULL;
-
- /* Policy used to evaluate was SWUpdateSigning */
- SecTrustCopyPolicies(trust, &policies);
- if (policies) {
- SecPolicyRef swUpdatePolicy = SecPolicyCreateAppleSWUpdateSigning();
- if (swUpdatePolicy && CFArrayContainsValue(policies, CFRangeMake(0, CFArrayGetCount(policies)),
- swUpdatePolicy)) {
- isPolicy = true;
- }
- if (swUpdatePolicy) { CFRelease(swUpdatePolicy); }
- CFRelease(policies);
- }
- if (!isPolicy) {
- return false;
- }
-
- /* Only error was EKU on the leaf */
- CFArrayRef details = SecTrustCopyFilteredDetails(trust);
- CFIndex ix, count = CFArrayGetCount(details);
- bool hasDisqualifyingError = false;
- for (ix = 0; ix < count; ix++) {
- CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
- if (ix == 0) { // Leaf
- if (CFDictionaryGetCount(detail) != 1 || // One error
- CFDictionaryGetValue(detail, CFSTR("ExtendedKeyUsage")) != kCFBooleanFalse) { // kSecPolicyCheckExtendedKeyUsage
- hasDisqualifyingError = true;
- break;
- }
- } else {
- if (CFDictionaryGetCount(detail) > 0) { // No errors on other certs
- hasDisqualifyingError = true;
- break;
- }
- }
- }
- CFReleaseSafe(details);
- if (hasDisqualifyingError) {
- return false;
- }
-
- /* EKU on the leaf is the Apple Development Code Signing OID */
- SecCertificateRef leaf = SecTrustGetCertificateAtIndex(trust, 0);
- CSSM_DATA *fieldValue = NULL;
- if (errSecSuccess != SecCertificateCopyFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, &fieldValue)) {
- return false;
- }
- if (fieldValue && fieldValue->Data && fieldValue->Length == sizeof(CSSM_X509_EXTENSION)) {
- const CSSM_X509_EXTENSION *ext = (const CSSM_X509_EXTENSION *)fieldValue->Data;
- if (ext->format == CSSM_X509_DATAFORMAT_PARSED) {
- const CE_ExtendedKeyUsage *ekus = (const CE_ExtendedKeyUsage *)ext->value.parsedValue;
- if (ekus && (ekus->numPurposes == 1) && ekus->purposes[0].Data &&
- (ekus->purposes[0].Length == CSSMOID_APPLE_EKU_CODE_SIGNING_DEV.Length) &&
- (memcmp(ekus->purposes[0].Data, CSSMOID_APPLE_EKU_CODE_SIGNING_DEV.Data,
- ekus->purposes[0].Length) == 0)) {
- isEKU = true;
- }
- }
- }
- SecCertificateReleaseFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, fieldValue);
- return isEKU;
-}
-