]>
git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/clAppUtils/timeStr.cpp
6 #include <security_utilities/threading.h> /* for Mutex */
7 #include <utilLib/common.h>
10 * Given a string containing either a UTC-style or "generalized time"
11 * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on
14 int appTimeStringToTm(
25 if((str
== NULL
) || (len
== 0) || (tmp
== NULL
)) {
29 /* tolerate NULL terminated or not */
30 if(str
[len
- 1] == '\0') {
34 case UTC_TIME_STRLEN
: // 2-digit year, not Y2K compliant
37 case GENERALIZED_TIME_STRLEN
: // 4-digit year
40 default: // unknown format
46 /* check that all characters except last are digits */
47 for(i
=0; i
<(len
- 1); i
++) {
48 if ( !(isdigit(cp
[i
])) ) {
53 /* check last character is a 'Z' */
54 if(cp
[len
- 1] != 'Z' ) {
74 * 0 <= year < 50 : assume century 21
75 * 50 <= year < 70 : illegal per PKIX
76 * 70 < year <= 99 : assume century 20
89 /* by definition - tm_year is year - 1900 */
90 tmp
->tm_year
= x
- 1900;
97 /* in the string, months are from 1 to 12 */
98 if((x
> 12) || (x
<= 0)) {
101 /* in a tm, 0 to 11 */
109 /* 1..31 in both formats */
110 if((x
> 31) || (x
<= 0)) {
120 if((x
> 23) || (x
< 0)) {
130 if((x
> 59) || (x
< 0)) {
140 if((x
> 59) || (x
< 0)) {
147 /* common time routine used by utcAtNowPlus and genTimeAtNowPlus */
148 #define MAX_TIME_STR_LEN 30
150 static Mutex timeMutex
; // protects time(), gmtime()
152 char *appTimeAtNowPlus(int secFromNow
,
160 baseTime
= time(NULL
);
161 baseTime
+= (time_t)secFromNow
;
162 utc
= *gmtime(&baseTime
);
165 outStr
= (char *)CSSM_MALLOC(MAX_TIME_STR_LEN
);
169 /* UTC - 2 year digits - code which parses this assumes that
170 * (2-digit) years between 0 and 49 are in century 21 */
171 if(utc
.tm_year
>= 100) {
174 sprintf(outStr
, "%02d%02d%02d%02d%02d%02dZ",
175 utc
.tm_year
/* + 1900 */, utc
.tm_mon
+ 1,
176 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
179 sprintf(outStr
, "%04d%02d%02d%02d%02d%02dZ",
180 /* note year is relative to 1900, hopefully it'll have four valid
182 utc
.tm_year
+ 1900, utc
.tm_mon
+ 1,
183 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
186 sprintf(outStr
, "%04d%02d%02d%02d%02d%02d",
187 /* note year is relative to 1900, hopefully it'll have
188 * four valid digits! */
189 utc
.tm_year
+ 1900, utc
.tm_mon
+ 1,
190 utc
.tm_mday
, utc
.tm_hour
, utc
.tm_min
, utc
.tm_sec
);
197 * Malloc and return UTC (2-digit year) time string, for time with specified
198 * offset from present. This uses the stdlib gmtime(), which is not thread safe.
199 * Even though this function protects the call with a lock, the TP also uses
200 * gmtime. It also does the correct locking for its own calls to gmtime()Êbut
201 * the is no way to synchronize TP's calls to gmtime() with the calls to this
202 * one other than only using this one when no threads might be performing TP ops.
204 char *utcAtNowPlus(int secFromNow
)
206 return appTimeAtNowPlus(secFromNow
, TIME_UTC
);
210 * Same thing, generalized time (4-digit year).
212 char *genTimeAtNowPlus(int secFromNow
)
214 return appTimeAtNowPlus(secFromNow
, TIME_GEN
);
218 * Free the string obtained from the above.
220 void freeTimeString(char *timeStr
)
226 * Convert a CSSM_X509_TIME, which can be in any of three forms (UTC,
227 * generalized, or CSSM_TIMESTRING) into a CSSM_TIMESTRING. Caller
228 * must free() the result. Returns NULL if x509time is badly formed.
230 char *x509TimeToCssmTimestring(
231 const CSSM_X509_TIME
*x509Time
,
232 unsigned *rtnLen
) // for caller's convenience
234 int len
= x509Time
->time
.Length
;
235 const char *inStr
= (char *)x509Time
->time
.Data
; // not NULL terminated!
239 if((len
== 0) || (inStr
== NULL
)) {
242 rtn
= (char *)malloc(CSSM_TIME_STRLEN
+ 1);
245 case UTC_TIME_STRLEN
:
247 /* infer century and prepend to output */
256 * 0 <= year < 50 : assume century 21
257 * 50 <= year < 70 : illegal per PKIX
258 * 70 < year <= 99 : assume century 20
272 memmove(rtn
+ 2, inStr
, len
- 1); // don't copy the Z
275 case CSSM_TIME_STRLEN
:
276 memmove(rtn
, inStr
, len
); // trivial case
278 case GENERALIZED_TIME_STRLEN
:
279 memmove(rtn
, inStr
, len
- 1); // don't copy the Z
286 rtn
[CSSM_TIME_STRLEN
] = '\0';
287 *rtnLen
= CSSM_TIME_STRLEN
;