]>
git.saurik.com Git - apple/security.git/blob - AppleX509TP/tpTime.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 * tpTime.c - cert related time functions
22 * Written 10/10/2000 by Doug Mitchell.
33 * Given a string containing either a UTC-style or "generalized time"
34 * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on
43 bool isUtc
= false; // 2-digit year
44 bool isCssmTime
= false; // no trailing 'Z'
49 if((str
== NULL
) || (len
== 0) || (tmp
== NULL
)) {
53 /* tolerate NULL terminated or not */
54 if(str
[len
- 1] == '\0') {
58 case UTC_TIME_STRLEN
: // 2-digit year, not Y2K compliant
61 case CSSM_TIME_STRLEN
:
64 case GENERALIZED_TIME_STRLEN
: // 4-digit year
66 default: // unknown format
72 /* check that all characters except last are digits */
73 for(i
=0; i
<(len
- 1); i
++) {
74 if ( !(isdigit(cp
[i
])) ) {
79 /* check last character is a 'Z' or digit as appropriate */
81 if(!isdigit(cp
[len
- 1])) {
86 if(cp
[len
- 1] != 'Z' ) {
107 * 0 <= year < 50 : assume century 21
108 * 50 <= year < 70 : illegal per PKIX
109 * ...though we allow this as of 10/10/02...dmitch
110 * 70 < year <= 99 : assume century 20
125 /* by definition - tm_year is year - 1900 */
126 tmp
->tm_year
= x
- 1900;
133 /* in the string, months are from 1 to 12 */
134 if((x
> 12) || (x
<= 0)) {
137 /* in a tm, 0 to 11 */
145 /* 1..31 in both formats */
146 if((x
> 31) || (x
<= 0)) {
156 if((x
> 23) || (x
< 0)) {
166 if((x
> 59) || (x
< 0)) {
176 if((x
> 59) || (x
< 0)) {
184 * Return current GMT time as a struct tm.
185 * Caller must hold tpTimeLock.
190 time_t nowTime
= time(NULL
);
191 *now
= *gmtime(&nowTime
);
195 * Compare two times. Assumes they're both in GMT. Returns:
204 if(t1
->tm_year
> t2
->tm_year
) {
207 else if(t1
->tm_year
< t2
->tm_year
) {
211 else if(t1
->tm_mon
> t2
->tm_mon
) {
214 else if(t1
->tm_mon
< t2
->tm_mon
) {
218 else if(t1
->tm_mday
> t2
->tm_mday
) {
221 else if(t1
->tm_mday
< t2
->tm_mday
) {
224 /* day of month equal */
225 else if(t1
->tm_hour
> t2
->tm_hour
) {
228 else if(t1
->tm_hour
< t2
->tm_hour
) {
232 else if(t1
->tm_min
> t2
->tm_min
) {
235 else if(t1
->tm_min
< t2
->tm_min
) {
239 else if(t1
->tm_sec
> t2
->tm_sec
) {
242 else if(t1
->tm_sec
< t2
->tm_sec
) {
250 * Create a time string, in either UTC (2-digit) or or Generalized (4-digit)
251 * year format. Caller mallocs the output string whose length is at least
252 * (UTC_TIME_STRLEN+1), (GENERALIZED_TIME_STRLEN+1), or (CSSM_TIME_STRLEN+1)
253 * respectively. Caller must hold tpTimeLock.
255 void timeAtNowPlus(unsigned secFromNow
,
262 baseTime
= time(NULL
);
263 baseTime
+= (time_t)secFromNow
;
264 utc
= *gmtime(&baseTime
);
268 /* UTC - 2 year digits - code which parses this assumes that
269 * (2-digit) years between 0 and 49 are in century 21 */
270 if(utc
.tm_year
>= 100) {
273 sprintf(outStr
, "%02d%02d%02d%02d%02d%02dZ",
274 utc
.tm_year
/* + 1900 */, utc
.tm_mon
+ 1,
275 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
278 sprintf(outStr
, "%04d%02d%02d%02d%02d%02dZ",
279 /* note year is relative to 1900, hopefully it'll have
280 * four valid digits! */
281 utc
.tm_year
+ 1900, utc
.tm_mon
+ 1,
282 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
285 sprintf(outStr
, "%04d%02d%02d%02d%02d%02d",
286 /* note year is relative to 1900, hopefully it'll have
287 * four valid digits! */
288 utc
.tm_year
+ 1900, utc
.tm_mon
+ 1,
289 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
295 * Convert a time string, which can be in any of three forms (UTC,
296 * generalized, or CSSM_TIMESTRING) into a CSSM_TIMESTRING. Caller
297 * mallocs the result, which must be at least (CSSM_TIME_STRLEN+1) bytes.
298 * Returns nonzero if incoming time string is badly formed.
300 int tpTimeToCssmTimestring(
301 const char *inStr
, // not necessarily NULL terminated
302 unsigned inStrLen
, // not including possible NULL
305 if((inStrLen
== 0) || (inStr
== NULL
)) {
310 case UTC_TIME_STRLEN
:
312 /* infer century and prepend to output */
321 * 0 <= year < 50 : assume century 21
322 * 50 <= year < 70 : illegal per PKIX
323 * 70 < year <= 99 : assume century 20
327 strcpy(outTime
, "20");
334 strcpy(outTime
, "19");
336 memmove(outTime
+ 2, inStr
, inStrLen
- 1); // don't copy the Z
339 case CSSM_TIME_STRLEN
:
340 memmove(outTime
, inStr
, inStrLen
); // trivial case
342 case GENERALIZED_TIME_STRLEN
:
343 memmove(outTime
, inStr
, inStrLen
- 1); // don't copy the Z
349 outTime
[CSSM_TIME_STRLEN
] = '\0';