]>
git.saurik.com Git - apple/security.git/blob - CdsaUtils/cuTimeStr.cpp
2 * Copyright (c) 2002 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.
19 * cuTimeStr.cpp - time string routines
21 #include "cuTimeStr.h"
22 #include "cuCdsaUtils.h"
27 #include <Security/threading.h>
30 * Given a string containing either a UTC-style or "generalized time"
31 * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on
45 if((str
== NULL
) || (len
== 0) || (tmp
== NULL
)) {
49 /* tolerate NULL terminated or not */
50 if(str
[len
- 1] == '\0') {
54 case UTC_TIME_STRLEN
: // 2-digit year, not Y2K compliant
57 case GENERALIZED_TIME_STRLEN
: // 4-digit year
60 default: // unknown format
66 /* check that all characters except last are digits */
67 for(i
=0; i
<(len
- 1); i
++) {
68 if ( !(isdigit(cp
[i
])) ) {
73 /* check last character is a 'Z' */
74 if(cp
[len
- 1] != 'Z' ) {
94 * 0 <= year < 50 : assume century 21
95 * 50 <= year < 70 : illegal per PKIX, though we tolerate
96 * 70 < year <= 99 : assume century 20
111 /* by definition - tm_year is year - 1900 */
112 tmp
->tm_year
= x
- 1900;
119 /* in the string, months are from 1 to 12 */
120 if((x
> 12) || (x
<= 0)) {
123 /* in a tm, 0 to 11 */
131 /* 1..31 in both formats */
132 if((x
> 31) || (x
<= 0)) {
142 if((x
> 23) || (x
< 0)) {
152 if((x
> 59) || (x
< 0)) {
162 if((x
> 59) || (x
< 0)) {
169 #define MAX_TIME_STR_LEN 30
171 static Mutex timeMutex
; // protects time(), gmtime()
173 char *cuTimeAtNowPlus(int secFromNow
,
181 baseTime
= time(NULL
);
182 baseTime
+= (time_t)secFromNow
;
183 utc
= *gmtime(&baseTime
);
186 outStr
= (char *)APP_MALLOC(MAX_TIME_STR_LEN
);
190 /* UTC - 2 year digits - code which parses this assumes that
191 * (2-digit) years between 0 and 49 are in century 21 */
192 if(utc
.tm_year
>= 100) {
195 sprintf(outStr
, "%02d%02d%02d%02d%02d%02dZ",
196 utc
.tm_year
/* + 1900 */, utc
.tm_mon
+ 1,
197 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
200 sprintf(outStr
, "%04d%02d%02d%02d%02d%02dZ",
201 /* note year is relative to 1900, hopefully it'll
202 * have four valid digits! */
203 utc
.tm_year
+ 1900, utc
.tm_mon
+ 1,
204 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
207 sprintf(outStr
, "%04d%02d%02d%02d%02d%02d",
208 /* note year is relative to 1900, hopefully it'll have
209 * four valid digits! */
210 utc
.tm_year
+ 1900, utc
.tm_mon
+ 1,
211 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
218 * Convert a CSSM_X509_TIME, which can be in any of three forms (UTC,
219 * generalized, or CSSM_TIMESTRING) into a CSSM_TIMESTRING. Caller
220 * must free() the result. Returns NULL if x509time is badly formed.
222 char *cuX509TimeToCssmTimestring(
223 const CSSM_X509_TIME
*x509Time
,
224 unsigned *rtnLen
) // for caller's convenience
226 int len
= x509Time
->time
.Length
;
227 const char *inStr
= (char *)x509Time
->time
.Data
;
228 // not NULL terminated!
232 if((len
== 0) || (inStr
== NULL
)) {
235 rtn
= (char *)malloc(CSSM_TIME_STRLEN
+ 1);
238 case UTC_TIME_STRLEN
:
240 /* infer century and prepend to output */
249 * 0 <= year < 50 : assume century 21
250 * 50 <= year < 70 : illegal per PKIX
251 * 70 < year <= 99 : assume century 20
265 memmove(rtn
+ 2, inStr
, len
- 1); // don't copy the Z
268 case CSSM_TIME_STRLEN
:
269 memmove(rtn
, inStr
, len
); // trivial case
271 case GENERALIZED_TIME_STRLEN
:
272 memmove(rtn
, inStr
, len
- 1); // don't copy the Z
279 rtn
[CSSM_TIME_STRLEN
] = '\0';
280 *rtnLen
= CSSM_TIME_STRLEN
;