SecTrustStatusCodes.c [plain text]
#include <Security/SecTrustPriv.h>
#include <Security/SecInternal.h>
#include <Security/SecTrustStatusCodes.h>
#include <CoreFoundation/CoreFoundation.h>
struct resultmap_entry_s {
const CFStringRef checkstr;
const int32_t resultcode;
};
typedef struct resultmap_entry_s resultmap_entry_t;
const resultmap_entry_t resultmap[] = {
#undef POLICYCHECKMACRO
#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
{ CFSTR(#NAME), CSSMERR },
#include "SecPolicyChecks.list"
};
SInt32 *SecTrustCopyStatusCodes(SecTrustRef trust,
CFIndex index, CFIndex *numStatusCodes)
{
if (!trust || !numStatusCodes) {
return NULL;
}
*numStatusCodes = 0;
CFArrayRef details = SecTrustCopyFilteredDetails(trust);
CFIndex chainLength = (details) ? CFArrayGetCount(details) : 0;
if (!(index < chainLength)) {
CFReleaseSafe(details);
return NULL;
}
CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, index);
CFIndex ix, detailCount = CFDictionaryGetCount(detail);
*numStatusCodes = (unsigned int)detailCount;
SInt32 *statusCodes = (SInt32*)malloc((detailCount+1) * sizeof(SInt32));
statusCodes[*numStatusCodes] = 0;
const unsigned int resultmaplen = sizeof(resultmap) / sizeof(resultmap_entry_t);
const void *keys[detailCount];
CFDictionaryGetKeysAndValues(detail, &keys[0], NULL);
for (ix = 0; ix < detailCount; ix++) {
CFStringRef key = (CFStringRef)keys[ix];
SInt32 statusCode = 0;
for (unsigned int mapix = 0; mapix < resultmaplen; mapix++) {
CFStringRef str = (CFStringRef) resultmap[mapix].checkstr;
if (CFStringCompare(str, key, 0) == kCFCompareEqualTo) {
statusCode = (SInt32) resultmap[mapix].resultcode;
break;
}
}
if (statusCode == (SInt32)0x8001210C) {
SInt32 reason;
CFNumberRef number = (CFNumberRef)CFDictionaryGetValue(detail, key);
if (number && CFNumberGetValue(number, kCFNumberSInt32Type, &reason)) {
statusCodes[*numStatusCodes] = (SInt32)reason;
}
}
statusCodes[ix] = statusCode;
}
CFReleaseSafe(details);
return statusCodes;
}