]> git.saurik.com Git - apple/security.git/blame - AppleX509TP/tpTime.c
Security-28.tar.gz
[apple/security.git] / AppleX509TP / tpTime.c
CommitLineData
bac41a7b
A
1/*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19/*
20 * tpTime.c - cert related time functions
21 *
22 * Written 10/10/2000 by Doug Mitchell.
23 */
24
25#include "tpTime.h"
26#include <string.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <ctype.h>
30
31#define UTC_TIME_STRLEN 13
32#define GENERALIZED_TIME_STRLEN 15
33
34/*
35 * Given a string containing either a UTC-style or "generalized time"
36 * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on
37 * error.
38 */
39int timeStringToTm(
40 const char *str,
41 unsigned len,
42 struct tm *tmp)
43{
44 char szTemp[5];
45 unsigned isUtc;
46 unsigned x;
47 unsigned i;
48 char *cp;
49
50 if((str == NULL) || (len == 0) || (tmp == NULL)) {
51 return 1;
52 }
53
54 /* tolerate NULL terminated or not */
55 if(str[len - 1] == '\0') {
56 len--;
57 }
58 switch(len) {
59 case UTC_TIME_STRLEN: // 2-digit year, not Y2K compliant
60 isUtc = 1;
61 break;
62 case GENERALIZED_TIME_STRLEN: // 4-digit year
63 isUtc = 0;
64 break;
65 default: // unknown format
66 return 1;
67 }
68
69 cp = (char *)str;
70
71 /* check that all characters except last are digits */
72 for(i=0; i<(len - 1); i++) {
73 if ( !(isdigit(cp[i])) ) {
74 return 1;
75 }
76 }
77
78 /* check last character is a 'Z' */
79 if(cp[len - 1] != 'Z' ) {
80 return 1;
81 }
82
83 /* YEAR */
84 szTemp[0] = *cp++;
85 szTemp[1] = *cp++;
86 if(!isUtc) {
87 /* two more digits */
88 szTemp[2] = *cp++;
89 szTemp[3] = *cp++;
90 szTemp[4] = '\0';
91 }
92 else {
93 szTemp[2] = '\0';
94 }
95 x = atoi( szTemp );
96 if(isUtc) {
97 /*
98 * 2-digit year.
99 * 0 <= year < 50 : assume century 21
100 * 50 <= year < 70 : illegal per PKIX
101 * 70 < year <= 99 : assume century 20
102 */
103 if(x < 50) {
104 x += 2000;
105 }
106 else if(x < 70) {
107 return 1;
108 }
109 else {
110 /* century 20 */
111 x += 1900;
112 }
113 }
114 /* by definition - tm_year is year - 1900 */
115 tmp->tm_year = x - 1900;
116
117 /* MONTH */
118 szTemp[0] = *cp++;
119 szTemp[1] = *cp++;
120 szTemp[2] = '\0';
121 x = atoi( szTemp );
122 /* in the string, months are from 1 to 12 */
123 if((x > 12) || (x <= 0)) {
124 return 1;
125 }
126 /* in a tm, 0 to 11 */
127 tmp->tm_mon = x - 1;
128
129 /* DAY */
130 szTemp[0] = *cp++;
131 szTemp[1] = *cp++;
132 szTemp[2] = '\0';
133 x = atoi( szTemp );
134 /* 1..31 in both formats */
135 if((x > 31) || (x <= 0)) {
136 return 1;
137 }
138 tmp->tm_mday = x;
139
140 /* HOUR */
141 szTemp[0] = *cp++;
142 szTemp[1] = *cp++;
143 szTemp[2] = '\0';
144 x = atoi( szTemp );
145 if((x > 23) || (x < 0)) {
146 return 1;
147 }
148 tmp->tm_hour = x;
149
150 /* MINUTE */
151 szTemp[0] = *cp++;
152 szTemp[1] = *cp++;
153 szTemp[2] = '\0';
154 x = atoi( szTemp );
155 if((x > 59) || (x < 0)) {
156 return 1;
157 }
158 tmp->tm_min = x;
159
160 /* SECOND */
161 szTemp[0] = *cp++;
162 szTemp[1] = *cp++;
163 szTemp[2] = '\0';
164 x = atoi( szTemp );
165 if((x > 59) || (x < 0)) {
166 return 1;
167 }
168 tmp->tm_sec = x;
169 return 0;
170}
171
172/* return current GMT time as a struct tm */
173void nowTime(
174 struct tm *now)
175{
176 time_t nowTime = time(NULL);
177 *now = *gmtime(&nowTime);
178}
179
180/*
181 * Compare two times. Assumes they're both in GMT. Returns:
182 * -1 if t1 < t2
183 * 0 if t1 == t2
184 * 1 if t1 > t2
185 */
186int compareTimes(
187 const struct tm *t1,
188 const struct tm *t2)
189{
190 if(t1->tm_year > t2->tm_year) {
191 return 1;
192 }
193 else if(t1->tm_year < t2->tm_year) {
194 return -1;
195 }
196 /* year equal */
197 else if(t1->tm_mon > t2->tm_mon) {
198 return 1;
199 }
200 else if(t1->tm_mon < t2->tm_mon) {
201 return -1;
202 }
203 /* month equal */
204 else if(t1->tm_mday > t2->tm_mday) {
205 return 1;
206 }
207 else if(t1->tm_mday < t2->tm_mday) {
208 return -1;
209 }
210 /* day of month equal */
211 else if(t1->tm_hour > t2->tm_hour) {
212 return 1;
213 }
214 else if(t1->tm_hour < t2->tm_hour) {
215 return -1;
216 }
217 /* hour equal */
218 else if(t1->tm_min > t2->tm_min) {
219 return 1;
220 }
221 else if(t1->tm_min < t2->tm_min) {
222 return -1;
223 }
224 /* minute equal */
225 else if(t1->tm_sec > t2->tm_sec) {
226 return 1;
227 }
228 else if(t1->tm_sec < t2->tm_sec) {
229 return -1;
230 }
231 /* equal */
232 return 0;
233}
234