static bool SecAbsoluteTimeGetGregorianDate(CFTimeInterval at, int *year, int *month, int *day, int *hour, int *minute, int *second, CFErrorRef *error) { // TODO: Remove CFCalendarDecomposeAbsoluteTime dependancy because CFTimeZoneCreateWithTimeIntervalFromGMT is expensive and requires filesystem access to timezone files when we are only doing zulu time anyway if (!CFCalendarDecomposeAbsoluteTime(SecCFCalendarGetZulu(), at, "yMdHms", year, month, day, hour, minute, second)) { SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Failed to encode date."), 0, error); return false; } return true; }
static OSStatus DER_CFDateToUTCTime(CFAbsoluteTime date, SecAsn1Item * utcTime) { unsigned char *d; utcTime->Length = 13; utcTime->Data = d = PORT_Alloc(13); if (!utcTime->Data) return SECFailure; __block int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0; __block bool result; SecCFCalendarDoWithZuluCalendar(^(CFCalendarRef zuluCalendar) { result = CFCalendarDecomposeAbsoluteTime(zuluCalendar, date, "yMdHms", &year, &month, &day, &hour, &minute, &second); });
CFStringRef _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions) { #ifdef ENABLE_SC_FORMATTING CFMutableDictionaryRef nFormatOptions; CFStringRef prefix1; CFStringRef prefix2; CFTypeID type = CFGetTypeID(cf); if (!formatOptions || !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX1"), (const void **)&prefix1)) { prefix1 = CFSTR(""); } if (type == CFStringGetTypeID()) { return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%@"), prefix1, cf); } if (type == CFBooleanGetTypeID()) { return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%s"), prefix1, CFBooleanGetValue(cf) ? "TRUE" : "FALSE"); } if (type == CFDataGetTypeID()) { const uint8_t *data; CFIndex dataLen; CFIndex i; CFMutableStringRef str; str = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(str, formatOptions, CFSTR("%@<data> 0x"), prefix1); data = CFDataGetBytePtr(cf); dataLen = CFDataGetLength(cf); for (i = 0; i < dataLen; i++) { CFStringAppendFormat(str, NULL, CFSTR("%02x"), data[i]); } return str; } if (type == CFNumberGetTypeID()) { return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%@"), prefix1, cf); } if (type == CFDateGetTypeID()) { CFCalendarRef calendar; CFStringRef str; CFTimeZoneRef tz; int MM, DD, YYYY, hh, mm, ss; calendar = CFCalendarCreateWithIdentifier(NULL, kCFGregorianCalendar); tz = CFTimeZoneCopySystem(); CFCalendarSetTimeZone(calendar, tz); CFRelease(tz); CFCalendarDecomposeAbsoluteTime(calendar, CFDateGetAbsoluteTime(cf), "MdyHms", &MM, &DD, &YYYY, &hh, &mm, &ss); CFRelease(calendar); str = CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%02d/%02d/%04d %02d:%02d:%02d"), prefix1, MM, DD, YYYY, hh, mm, ss); return str; } if ((formatOptions == NULL) || !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX2"), (const void **)&prefix2)) { prefix2 = prefix1; } if (formatOptions != NULL) { nFormatOptions = CFDictionaryCreateMutableCopy(NULL, 0, formatOptions); } else { nFormatOptions = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } assert(nFormatOptions != NULL); #define N_QUICK 32 if (type == CFArrayGetTypeID()) { const void * elements_q[N_QUICK]; const void ** elements = elements_q; CFIndex i; CFIndex nElements; CFMutableStringRef str; str = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(str, formatOptions, CFSTR("%@<array> {"), prefix1); nElements = CFArrayGetCount(cf); if (nElements > 0) { if (nElements > (CFIndex)(sizeof(elements_q)/sizeof(CFTypeRef))) elements = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0); CFArrayGetValues(cf, CFRangeMake(0, nElements), elements); for (i = 0; i < nElements; i++) { CFMutableStringRef nPrefix1; CFMutableStringRef nPrefix2; CFStringRef nStr; CFStringRef vStr; nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), i); nPrefix1 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix1, formatOptions, CFSTR("%@ %@ : "), prefix2, nStr); nPrefix2 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix2, formatOptions, CFSTR("%@ "), prefix2); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2); CFRelease(nPrefix1); CFRelease(nPrefix2); CFRelease(nStr); vStr = _SCCopyDescription((CFTypeRef)elements[i], nFormatOptions); CFStringAppendFormat(str, formatOptions, CFSTR("\n%@"), vStr); CFRelease(vStr); } if (elements != elements_q) CFAllocatorDeallocate(NULL, elements); } CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2); CFRelease(nFormatOptions); return str; } if (type == CFDictionaryGetTypeID()) { const void * keys_q[N_QUICK]; const void ** keys = keys_q; CFIndex i; CFIndex nElements; CFMutableStringRef nPrefix1; CFMutableStringRef nPrefix2; CFMutableStringRef str; str = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(str, formatOptions, CFSTR("%@<dictionary> {"), prefix1); nElements = CFDictionaryGetCount(cf); if (nElements > 0) { CFComparatorFunction compFunc = NULL; CFMutableArrayRef sortedKeys; if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) { keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0); } CFDictionaryGetKeysAndValues(cf, keys, NULL); sortedKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < nElements; i++) { CFArrayAppendValue(sortedKeys, (CFStringRef)keys[i]); } if (isA_CFString(keys[0])) { compFunc = (CFComparatorFunction)CFStringCompare; } else if (isA_CFNumber(keys[0])) { compFunc = (CFComparatorFunction)CFNumberCompare; } else if (isA_CFDate(keys[0])) { compFunc = (CFComparatorFunction)CFDateCompare; } if (compFunc != NULL) { CFArraySortValues(sortedKeys, CFRangeMake(0, nElements), compFunc, NULL); } for (i = 0; i < nElements; i++) { CFStringRef key; CFStringRef kStr; CFTypeRef val; CFStringRef vStr; key = CFArrayGetValueAtIndex(sortedKeys, i); kStr = _SCCopyDescription((CFTypeRef)key, NULL); nPrefix1 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix1, formatOptions, CFSTR("%@ %@ : "), prefix2, kStr); nPrefix2 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix2, formatOptions, CFSTR("%@ "), prefix2); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2); CFRelease(nPrefix1); CFRelease(nPrefix2); CFRelease(kStr); val = CFDictionaryGetValue(cf, key); vStr = _SCCopyDescription((CFTypeRef)val, nFormatOptions); CFStringAppendFormat(str, formatOptions, CFSTR("\n%@"), vStr); CFRelease(vStr); } CFRelease(sortedKeys); if (keys != keys_q) { CFAllocatorDeallocate(NULL, keys); } } CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2); CFRelease(nFormatOptions); return str; } CFRelease(nFormatOptions); #endif /* ENABLE_SC_FORMATTING */ return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%@"), prefix1, cf); }