1// 2// si-14-dateparse.c 3// regressions 4// 5// Created by Michael Brouwer on 5/5/11. 6// Copyright 2011 Apple Inc. All rights reserved. 7// 8 9#include <stdio.h> 10 11#include <CoreFoundation/CoreFoundation.h> 12#include <Security/SecCertificateInternal.h> 13#include <Security/SecInternal.h> 14#include <libDER/asn1Types.h> 15#include <stdlib.h> 16#include <unistd.h> 17 18#include "Security_regressions.h" 19 20#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); } 21 22#define dateparse(TTYPE, DATE) SecAbsoluteTimeFromDateContent(ASN1_ ## TTYPE ## _TIME, (const uint8_t *)DATE, sizeof(DATE) - 1); \ 23 24#define dateequals(TTYPE, DATE, EXPECTED) do { \ 25 UInt8 string[64]; \ 26 CFIndex string_len = 63; \ 27 CFAbsoluteTime at = dateparse(TTYPE, DATE); \ 28 if (at == NULL_TIME) { \ 29 eq_string("NULL_TIME", EXPECTED, "input: " DATE); \ 30 break; \ 31 } \ 32 ds = CFDateFormatterCreateStringWithAbsoluteTime(NULL, df, at); \ 33 CFStringGetBytes(ds, CFRangeMake(0, CFStringGetLength(ds)), kCFStringEncodingASCII, ' ', false, string, 63, &string_len); \ 34 string[string_len] = 0; \ 35 eq_string((const char *)string, EXPECTED, "input: " DATE); \ 36 CFReleaseSafe(ds); \ 37} while(0) 38 39/* Test SecAbsoluteTimeFromDateContent. */ 40static void tests(void) 41{ 42 CFLocaleRef ls = CFLocaleGetSystem(); 43 CFDateFormatterRef df = CFDateFormatterCreate(NULL, ls, kCFDateFormatterMediumStyle, kCFDateFormatterLongStyle); 44 CFStringRef ds = NULL; 45 CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(NULL, 0.0); 46 if (tz) { 47 CFDateFormatterSetProperty(df, kCFDateFormatterTimeZone, tz); 48 CFRelease(tz); 49 } 50 CFDateFormatterSetFormat(df, CFSTR("yyyyMMddHHmmss")); 51 52 dateequals(UTC, "1101010000Z", "20110101000000"); 53 dateequals(UTC, "010101000001Z", "20010101000001"); 54 dateequals(GENERALIZED, "201101010000Z", "NULL_TIME"); // Invalid date 55 dateequals(GENERALIZED, "20010101000001Z", "20010101000001"); 56 57 dateequals(GENERALIZED, "20000101000000Z", "20000101000000"); 58 dateequals(UTC, "990101000000Z", "19990101000000"); 59 dateequals(UTC, "710101000000Z", "19710101000000"); 60 61 dateequals(UTC, "020101000000+0000", "20020101000000"); 62 dateequals(UTC, "020101000000-0800", "20020101080000"); 63 dateequals(UTC, "020101000000+0800", "20011231160000"); 64 dateequals(UTC, "020101000000-0420", "20020101042000"); 65 dateequals(UTC, "020101000013+0430", "20011231193013"); 66 67 dateequals(UTC, "0201010000+0000", "NULL_TIME"); 68 69 dateequals(GENERALIZED, "20020101000000+0000", "20020101000000"); 70 dateequals(GENERALIZED, "20020101000000-0800", "20020101080000"); 71 dateequals(GENERALIZED, "20020101000000+0800", "20011231160000"); 72 dateequals(GENERALIZED, "20020101000000-0420", "20020101042000"); 73 dateequals(GENERALIZED, "20020101000013+0430", "20011231193013"); 74 75 dateequals(GENERALIZED, "20060101000013+0900", "20051231150013"); 76 dateequals(GENERALIZED, "20090101000013+0900", "20081231150013"); 77 dateequals(GENERALIZED, "20110101000013+0900", "20101231150013"); 78 79 /* I'd expect these to be off by one second but since they aren't it 80 seems we don't support leap seconds. */ 81 dateequals(GENERALIZED, "20051231200013-0900", "20060101050013"); 82 dateequals(GENERALIZED, "20081231200013-0900", "20090101050013"); 83 dateequals(GENERALIZED, "20101231200013-0900", "20110101050013"); 84 85 dateequals(GENERALIZED, "20051231200013+0900", "20051231110013"); 86 dateequals(GENERALIZED, "20081231200013+0900", "20081231110013"); 87 dateequals(GENERALIZED, "20101231200013+0900", "20101231110013"); 88 89 dateequals(GENERALIZED, "19001231200013Z", "19001231200013"); 90 dateequals(GENERALIZED, "19811231200013Z", "19811231200013"); 91 dateequals(GENERALIZED, "19840229000001Z", "19840229000001"); 92 dateequals(GENERALIZED, "19810229000002Z", "NULL_TIME"); // Feb 29 in a non leap-year 93 dateequals(GENERALIZED, "20000001000000Z", "NULL_TIME"); // Month 0 94 dateequals(GENERALIZED, "20000100000000Z", "NULL_TIME"); // Day 0 95 dateequals(GENERALIZED, "20000131000000Z", "20000131000000"); // Day 1/31 96 dateequals(GENERALIZED, "20000132000000Z", "NULL_TIME"); // Day 1/31 97 dateequals(GENERALIZED, "20000229000000Z", "20000229000000"); // Day 2/29 98 dateequals(GENERALIZED, "20000230000000Z", "NULL_TIME"); // Day 2/30 99 dateequals(GENERALIZED, "20010331000000Z", "20010331000000"); 100 dateequals(GENERALIZED, "20010332000000Z", "NULL_TIME"); 101 dateequals(GENERALIZED, "20010430000000Z", "20010430000000"); 102 dateequals(GENERALIZED, "20010431000000Z", "NULL_TIME"); 103 dateequals(GENERALIZED, "20010531000000Z", "20010531000000"); 104 dateequals(GENERALIZED, "20010532000000Z", "NULL_TIME"); 105 dateequals(GENERALIZED, "20010630000000Z", "20010630000000"); 106 dateequals(GENERALIZED, "20010631000000Z", "NULL_TIME"); 107 dateequals(GENERALIZED, "20010731000000Z", "20010731000000"); 108 dateequals(GENERALIZED, "20010732000000Z", "NULL_TIME"); 109 dateequals(GENERALIZED, "20010831000000Z", "20010831000000"); 110 dateequals(GENERALIZED, "20010832000000Z", "NULL_TIME"); 111 dateequals(GENERALIZED, "20010930000000Z", "20010930000000"); 112 dateequals(GENERALIZED, "20010931000000Z", "NULL_TIME"); 113 dateequals(GENERALIZED, "20011031000000Z", "20011031000000"); 114 dateequals(GENERALIZED, "20011032000000Z", "NULL_TIME"); 115 dateequals(GENERALIZED, "20011130000000Z", "20011130000000"); 116 dateequals(GENERALIZED, "20011131000000Z", "NULL_TIME"); 117 dateequals(GENERALIZED, "20011231000000Z", "20011231000000"); 118 dateequals(GENERALIZED, "20011232000000Z", "NULL_TIME"); 119 dateequals(GENERALIZED, "20011301000000Z", "NULL_TIME"); 120 121 dateequals(GENERALIZED, "21000301120000Z", "21000301120000"); 122 dateequals(GENERALIZED, "23000301120000Z", "23000301120000"); 123 dateequals(GENERALIZED, "24000301120000Z", "24000301120000"); 124 dateequals(GENERALIZED, "30000301120000Z", "30000301120000"); 125 dateequals(GENERALIZED, "60000228120000Z", "60000228120000"); 126 dateequals(GENERALIZED, "60800301120000Z", "60800301120000"); 127 128 CFReleaseSafe(df); 129} 130 131int si_14_dateparse(int argc, char *const *argv) 132{ 133 plan_tests(64); 134 135 tests(); 136 137 return 0; 138} 139