Security-54.1.9.tar.gz
[apple/security.git] / CertTool / cdsaUtils / timeStr.cpp
CommitLineData
29654253
A
1#include "timeStr.h"
2#include <string.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <ctype.h>
6
7/*
8 * Given a string containing either a UTC-style or "generalized time"
9 * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on
10 * error.
11 */
12int appTimeStringToTm(
13 const char *str,
14 unsigned len,
15 struct tm *tmp)
16{
17 char szTemp[5];
18 unsigned isUtc;
19 unsigned x;
20 unsigned i;
21 char *cp;
22
23 if((str == NULL) || (len == 0) || (tmp == NULL)) {
24 return 1;
25 }
26
27 /* tolerate NULL terminated or not */
28 if(str[len - 1] == '\0') {
29 len--;
30 }
31 switch(len) {
32 case UTC_TIME_STRLEN: // 2-digit year, not Y2K compliant
33 isUtc = 1;
34 break;
35 case GENERALIZED_TIME_STRLEN: // 4-digit year
36 isUtc = 0;
37 break;
38 default: // unknown format
39 return 1;
40 }
41
42 cp = (char *)str;
43
44 /* check that all characters except last are digits */
45 for(i=0; i<(len - 1); i++) {
46 if ( !(isdigit(cp[i])) ) {
47 return 1;
48 }
49 }
50
51 /* check last character is a 'Z' */
52 if(cp[len - 1] != 'Z' ) {
53 return 1;
54 }
55
56 /* YEAR */
57 szTemp[0] = *cp++;
58 szTemp[1] = *cp++;
59 if(!isUtc) {
60 /* two more digits */
61 szTemp[2] = *cp++;
62 szTemp[3] = *cp++;
63 szTemp[4] = '\0';
64 }
65 else {
66 szTemp[2] = '\0';
67 }
68 x = atoi( szTemp );
69 if(isUtc) {
70 /*
71 * 2-digit year.
72 * 0 <= year < 50 : assume century 21
73 * 50 <= year < 70 : illegal per PKIX
74 * 70 < year <= 99 : assume century 20
75 */
76 if(x < 50) {
77 x += 2000;
78 }
79 else if(x < 70) {
80 return 1;
81 }
82 else {
83 /* century 20 */
84 x += 1900;
85 }
86 }
87 /* by definition - tm_year is year - 1900 */
88 tmp->tm_year = x - 1900;
89
90 /* MONTH */
91 szTemp[0] = *cp++;
92 szTemp[1] = *cp++;
93 szTemp[2] = '\0';
94 x = atoi( szTemp );
95 /* in the string, months are from 1 to 12 */
96 if((x > 12) || (x <= 0)) {
97 return 1;
98 }
99 /* in a tm, 0 to 11 */
100 tmp->tm_mon = x - 1;
101
102 /* DAY */
103 szTemp[0] = *cp++;
104 szTemp[1] = *cp++;
105 szTemp[2] = '\0';
106 x = atoi( szTemp );
107 /* 1..31 in both formats */
108 if((x > 31) || (x <= 0)) {
109 return 1;
110 }
111 tmp->tm_mday = x;
112
113 /* HOUR */
114 szTemp[0] = *cp++;
115 szTemp[1] = *cp++;
116 szTemp[2] = '\0';
117 x = atoi( szTemp );
118 if((x > 23) || (x < 0)) {
119 return 1;
120 }
121 tmp->tm_hour = x;
122
123 /* MINUTE */
124 szTemp[0] = *cp++;
125 szTemp[1] = *cp++;
126 szTemp[2] = '\0';
127 x = atoi( szTemp );
128 if((x > 59) || (x < 0)) {
129 return 1;
130 }
131 tmp->tm_min = x;
132
133 /* SECOND */
134 szTemp[0] = *cp++;
135 szTemp[1] = *cp++;
136 szTemp[2] = '\0';
137 x = atoi( szTemp );
138 if((x > 59) || (x < 0)) {
139 return 1;
140 }
141 tmp->tm_sec = x;
142 return 0;
143}
144