OLD | NEW |
| (Empty) |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 /* | |
5 * pkix_pl_date.c | |
6 * | |
7 * Date Object Definitions | |
8 * | |
9 */ | |
10 | |
11 #include "pkix_pl_date.h" | |
12 | |
13 /* --Private-Date-Functions------------------------------------- */ | |
14 /* | |
15 * FUNCTION: pkix_pl_Date_GetPRTime | |
16 * DESCRIPTION: | |
17 * | |
18 * Translates into a PRTime the Date embodied by the Date object pointed to | |
19 * by "date", and stores it at "pPRTime". | |
20 * | |
21 * PARAMETERS | |
22 * "date" | |
23 * Address of Date whose PRTime representation is desired. Must be | |
24 * non-NULL. | |
25 * "pPRTime" | |
26 * Address where PRTime value will be stored. Must be non-NULL. | |
27 * "plContext" - Platform-specific context pointer. | |
28 * THREAD SAFETY: | |
29 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
30 * RETURNS: | |
31 * Returns NULL if the function succeeds. | |
32 * Returns a Date Error if the function fails in a non-fatal way. | |
33 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
34 */ | |
35 PKIX_Error * | |
36 pkix_pl_Date_GetPRTime( | |
37 PKIX_PL_Date *date, | |
38 PRTime *pPRTime, | |
39 void *plContext) | |
40 { | |
41 PKIX_ENTER(DATE, "PKIX_PL_Date_GetPRTime"); | |
42 PKIX_NULLCHECK_TWO(date, pPRTime); | |
43 | |
44 *pPRTime = date->nssTime; | |
45 | |
46 PKIX_RETURN(DATE); | |
47 } | |
48 | |
49 /* | |
50 * FUNCTION: pkix_pl_Date_CreateFromPRTime | |
51 * DESCRIPTION: | |
52 * | |
53 * Creates a new Date from the PRTime whose value is "prtime", and stores the | |
54 * result at "pDate". | |
55 * | |
56 * PARAMETERS | |
57 * "prtime" | |
58 * The PRTime value to be embodied in the new Date object. | |
59 * "pDate" | |
60 * Address where object pointer will be stored. Must be non-NULL. | |
61 * "plContext" - Platform-specific context pointer. | |
62 * THREAD SAFETY: | |
63 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
64 * RETURNS: | |
65 * Returns NULL if the function succeeds. | |
66 * Returns a Date Error if the function fails in a non-fatal way. | |
67 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
68 */ | |
69 PKIX_Error * | |
70 pkix_pl_Date_CreateFromPRTime( | |
71 PRTime prtime, | |
72 PKIX_PL_Date **pDate, | |
73 void *plContext) | |
74 { | |
75 PKIX_PL_Date *date = NULL; | |
76 | |
77 PKIX_ENTER(DATE, "PKIX_PL_Date_CreateFromPRTime"); | |
78 PKIX_NULLCHECK_ONE(pDate); | |
79 | |
80 /* create a PKIX_PL_Date object */ | |
81 PKIX_CHECK(PKIX_PL_Object_Alloc | |
82 (PKIX_DATE_TYPE, | |
83 sizeof (PKIX_PL_Date), | |
84 (PKIX_PL_Object **)&date, | |
85 plContext), | |
86 PKIX_COULDNOTCREATEOBJECT); | |
87 /* populate the nssTime field */ | |
88 date->nssTime = prtime; | |
89 *pDate = date; | |
90 cleanup: | |
91 PKIX_RETURN(DATE); | |
92 } | |
93 | |
94 /* | |
95 * FUNCTION: pkix_pl_Date_ToString_Helper | |
96 * DESCRIPTION: | |
97 * | |
98 * Helper function that creates a string representation of the SECItem pointed | |
99 * to by "nssTime" (which represents a date) and stores it at "pString". | |
100 * | |
101 * PARAMETERS | |
102 * "nssTime" | |
103 * Address of SECItem whose string representation is desired. | |
104 * Must be non-NULL. | |
105 * "pString" | |
106 * Address where object pointer will be stored. Must be non-NULL. | |
107 * "plContext" - Platform-specific context pointer. | |
108 * THREAD SAFETY: | |
109 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
110 * RETURNS: | |
111 * Returns NULL if the function succeeds. | |
112 * Returns a Date Error if the function fails in a non-fatal way. | |
113 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
114 */ | |
115 PKIX_Error * | |
116 pkix_pl_Date_ToString_Helper( | |
117 SECItem *nssTime, | |
118 PKIX_PL_String **pString, | |
119 void *plContext) | |
120 { | |
121 char *asciiDate = NULL; | |
122 | |
123 PKIX_ENTER(DATE, "pkix_pl_Date_ToString_Helper"); | |
124 PKIX_NULLCHECK_TWO(nssTime, pString); | |
125 | |
126 switch (nssTime->type) { | |
127 case siUTCTime: | |
128 PKIX_PL_NSSCALLRV | |
129 (DATE, asciiDate, DER_UTCDayToAscii, (nssTime)); | |
130 if (!asciiDate){ | |
131 PKIX_ERROR(PKIX_DERUTCTIMETOASCIIFAILED); | |
132 } | |
133 break; | |
134 case siGeneralizedTime: | |
135 /* | |
136 * we don't currently have any way to create GeneralizedTime. | |
137 * this code is only here so that it will be in place when | |
138 * we do have the capability to create GeneralizedTime. | |
139 */ | |
140 PKIX_PL_NSSCALLRV | |
141 (DATE, asciiDate, DER_GeneralizedDayToAscii, (nssTime)); | |
142 if (!asciiDate){ | |
143 PKIX_ERROR(PKIX_DERGENERALIZEDDAYTOASCIIFAILED); | |
144 } | |
145 break; | |
146 default: | |
147 PKIX_ERROR(PKIX_UNRECOGNIZEDTIMETYPE); | |
148 } | |
149 | |
150 PKIX_CHECK(PKIX_PL_String_Create | |
151 (PKIX_ESCASCII, asciiDate, 0, pString, plContext), | |
152 PKIX_STRINGCREATEFAILED); | |
153 | |
154 cleanup: | |
155 PR_Free(asciiDate); | |
156 | |
157 PKIX_RETURN(DATE); | |
158 } | |
159 | |
160 | |
161 /* | |
162 * FUNCTION: pkix_pl_Date_Destroy | |
163 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
164 */ | |
165 static PKIX_Error * | |
166 pkix_pl_Date_Destroy( | |
167 PKIX_PL_Object *object, | |
168 void *plContext) | |
169 { | |
170 PKIX_ENTER(DATE, "pkix_pl_Date_Destroy"); | |
171 PKIX_NULLCHECK_ONE(object); | |
172 | |
173 PKIX_CHECK(pkix_CheckType(object, PKIX_DATE_TYPE, plContext), | |
174 PKIX_OBJECTNOTDATE); | |
175 cleanup: | |
176 PKIX_RETURN(DATE); | |
177 } | |
178 | |
179 /* | |
180 * FUNCTION: pkix_pl_Date_ToString | |
181 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) | |
182 */ | |
183 static PKIX_Error * | |
184 pkix_pl_Date_ToString( | |
185 PKIX_PL_Object *object, | |
186 PKIX_PL_String **pString, | |
187 void *plContext) | |
188 { | |
189 PKIX_PL_Date *date = NULL; | |
190 SECItem nssTime = {siBuffer, NULL, 0}; | |
191 SECStatus rv; | |
192 | |
193 PKIX_ENTER(DATE, "pkix_pl_Date_toString"); | |
194 PKIX_NULLCHECK_TWO(object, pString); | |
195 | |
196 PKIX_CHECK(pkix_CheckType(object, PKIX_DATE_TYPE, plContext), | |
197 PKIX_OBJECTNOTDATE); | |
198 | |
199 date = (PKIX_PL_Date *)object; | |
200 rv = DER_EncodeTimeChoice(NULL, &nssTime, date->nssTime); | |
201 if (rv == SECFailure) { | |
202 PKIX_ERROR(PKIX_DERENCODETIMECHOICEFAILED); | |
203 } | |
204 PKIX_CHECK(pkix_pl_Date_ToString_Helper | |
205 (&nssTime, pString, plContext), | |
206 PKIX_DATETOSTRINGHELPERFAILED); | |
207 cleanup: | |
208 if (nssTime.data) { | |
209 SECITEM_FreeItem(&nssTime, PR_FALSE); | |
210 } | |
211 | |
212 PKIX_RETURN(DATE); | |
213 } | |
214 | |
215 /* | |
216 * FUNCTION: pkix_pl_Date_Hashcode | |
217 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
218 */ | |
219 static PKIX_Error * | |
220 pkix_pl_Date_Hashcode( | |
221 PKIX_PL_Object *object, | |
222 PKIX_UInt32 *pHashcode, | |
223 void *plContext) | |
224 { | |
225 PKIX_PL_Date *date = NULL; | |
226 PKIX_UInt32 dateHash; | |
227 | |
228 PKIX_ENTER(DATE, "pkix_pl_Date_Hashcode"); | |
229 PKIX_NULLCHECK_TWO(object, pHashcode); | |
230 | |
231 PKIX_CHECK(pkix_CheckType(object, PKIX_DATE_TYPE, plContext), | |
232 PKIX_OBJECTNOTDATE); | |
233 | |
234 date = (PKIX_PL_Date *)object; | |
235 | |
236 PKIX_CHECK(pkix_hash | |
237 ((const unsigned char *)&date->nssTime, | |
238 sizeof(date->nssTime), | |
239 &dateHash, | |
240 plContext), | |
241 PKIX_HASHFAILED); | |
242 | |
243 *pHashcode = dateHash; | |
244 | |
245 cleanup: | |
246 | |
247 PKIX_RETURN(DATE); | |
248 | |
249 } | |
250 | |
251 /* | |
252 * FUNCTION: pkix_pl_Date_Comparator | |
253 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h) | |
254 */ | |
255 static PKIX_Error * | |
256 pkix_pl_Date_Comparator( | |
257 PKIX_PL_Object *firstObject, | |
258 PKIX_PL_Object *secondObject, | |
259 PKIX_Int32 *pResult, | |
260 void *plContext) | |
261 { | |
262 PRTime firstTime; | |
263 PRTime secondTime; | |
264 SECComparison cmpResult; | |
265 | |
266 PKIX_ENTER(DATE, "pkix_pl_Date_Comparator"); | |
267 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
268 | |
269 PKIX_CHECK(pkix_CheckTypes | |
270 (firstObject, secondObject, PKIX_DATE_TYPE, plContext), | |
271 PKIX_ARGUMENTSNOTDATES); | |
272 | |
273 firstTime = ((PKIX_PL_Date *)firstObject)->nssTime; | |
274 secondTime = ((PKIX_PL_Date *)secondObject)->nssTime; | |
275 | |
276 if (firstTime == secondTime) | |
277 cmpResult = SECEqual; | |
278 else if (firstTime < secondTime) | |
279 cmpResult = SECLessThan; | |
280 else | |
281 cmpResult = SECGreaterThan; | |
282 | |
283 *pResult = cmpResult; | |
284 | |
285 cleanup: | |
286 | |
287 PKIX_RETURN(DATE); | |
288 } | |
289 | |
290 /* | |
291 * FUNCTION: pkix_pl_Date_Equals | |
292 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) | |
293 */ | |
294 static PKIX_Error * | |
295 pkix_pl_Date_Equals( | |
296 PKIX_PL_Object *firstObject, | |
297 PKIX_PL_Object *secondObject, | |
298 PKIX_Boolean *pResult, | |
299 void *plContext) | |
300 { | |
301 PKIX_ENTER(DATE, "pkix_pl_Date_Equals"); | |
302 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
303 | |
304 /* test that firstObject is a Date */ | |
305 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_DATE_TYPE, plContext), | |
306 PKIX_FIRSTOBJECTNOTDATE); | |
307 | |
308 /* | |
309 * Since we know firstObject is a Date, if both references are | |
310 * identical, they must be equal | |
311 */ | |
312 if (firstObject == secondObject){ | |
313 *pResult = PKIX_TRUE; | |
314 goto cleanup; | |
315 } | |
316 | |
317 *pResult = PKIX_FALSE; | |
318 pkixErrorResult = | |
319 pkix_pl_Date_Comparator(firstObject, secondObject, | |
320 pResult, plContext); | |
321 if (pkixErrorResult) { | |
322 PKIX_DECREF(pkixErrorResult); | |
323 } | |
324 | |
325 cleanup: | |
326 | |
327 PKIX_RETURN(DATE); | |
328 } | |
329 | |
330 /* | |
331 * FUNCTION: pkix_pl_Date_RegisterSelf | |
332 * DESCRIPTION: | |
333 * Registers PKIX_DATE_TYPE and its related functions with systemClasses[] | |
334 * THREAD SAFETY: | |
335 * Not Thread Safe - for performance and complexity reasons | |
336 * | |
337 * Since this function is only called by PKIX_PL_Initialize, which should | |
338 * only be called once, it is acceptable that this function is not | |
339 * thread-safe. | |
340 */ | |
341 PKIX_Error * | |
342 pkix_pl_Date_RegisterSelf(void *plContext) | |
343 { | |
344 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
345 pkix_ClassTable_Entry* entry = &systemClasses[PKIX_DATE_TYPE]; | |
346 | |
347 PKIX_ENTER(CRLCHECKER, "pkix_CrlDp_RegisterSelf"); | |
348 | |
349 entry->description = "Date"; | |
350 entry->typeObjectSize = sizeof(PKIX_PL_Date); | |
351 entry->destructor = pkix_pl_Date_Destroy; | |
352 entry->equalsFunction = pkix_pl_Date_Equals; | |
353 entry->hashcodeFunction = pkix_pl_Date_Hashcode; | |
354 entry->toStringFunction = pkix_pl_Date_ToString; | |
355 entry->comparator = pkix_pl_Date_Comparator; | |
356 entry->duplicateFunction = pkix_duplicateImmutable; | |
357 | |
358 PKIX_RETURN(DATE); | |
359 } | |
360 | |
361 /* --Public-Functions------------------------------------------------------- */ | |
362 | |
363 /* | |
364 * FUNCTION: PKIX_PL_Date_Create_UTCTime (see comments in pkix_pl_pki.h) | |
365 */ | |
366 PKIX_Error * | |
367 PKIX_PL_Date_Create_UTCTime( | |
368 PKIX_PL_String *stringRep, | |
369 PKIX_PL_Date **pDate, | |
370 void *plContext) | |
371 { | |
372 PKIX_PL_Date *date = NULL; | |
373 char *asciiString = NULL; | |
374 PKIX_UInt32 escAsciiLength; | |
375 SECStatus rv; | |
376 PRTime time; | |
377 | |
378 PKIX_ENTER(DATE, "PKIX_PL_Date_Create_UTCTime"); | |
379 PKIX_NULLCHECK_ONE(pDate); | |
380 | |
381 if (stringRep == NULL){ | |
382 PKIX_DATE_DEBUG("\t\tCalling PR_Now).\n"); | |
383 time = PR_Now(); | |
384 } else { | |
385 /* convert the input PKIX_PL_String to PKIX_ESCASCII */ | |
386 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
387 (stringRep, | |
388 PKIX_ESCASCII, | |
389 (void **)&asciiString, | |
390 &escAsciiLength, | |
391 plContext), | |
392 PKIX_STRINGGETENCODEDFAILED); | |
393 | |
394 PKIX_DATE_DEBUG("\t\tCalling DER_AsciiToTime).\n"); | |
395 /* DER_AsciiToTime only supports UTCTime (2-digit years) */ | |
396 rv = DER_AsciiToTime(&time, asciiString); | |
397 if (rv != SECSuccess){ | |
398 PKIX_ERROR(PKIX_DERASCIITOTIMEFAILED); | |
399 } | |
400 } | |
401 | |
402 /* create a PKIX_PL_Date object */ | |
403 PKIX_CHECK(PKIX_PL_Object_Alloc | |
404 (PKIX_DATE_TYPE, | |
405 sizeof (PKIX_PL_Date), | |
406 (PKIX_PL_Object **)&date, | |
407 plContext), | |
408 PKIX_COULDNOTCREATEOBJECT); | |
409 | |
410 /* populate the nssTime field */ | |
411 date->nssTime = time; | |
412 *pDate = date; | |
413 | |
414 cleanup: | |
415 PKIX_FREE(asciiString); | |
416 | |
417 PKIX_RETURN(DATE); | |
418 } | |
419 | |
420 /* | |
421 * FUNCTION: PKIX_PL_Date_Create_CurrentOffBySeconds | |
422 * (see comments in pkix_pl_pki.h) | |
423 */ | |
424 PKIX_Error * | |
425 PKIX_PL_Date_Create_CurrentOffBySeconds( | |
426 PKIX_Int32 secondsOffset, | |
427 PKIX_PL_Date **pDate, | |
428 void *plContext) | |
429 { | |
430 PKIX_PL_Date *date = NULL; | |
431 PRTime time; | |
432 | |
433 PKIX_ENTER(DATE, "PKIX_PL_Date_Create_CurrentOffBySeconds"); | |
434 PKIX_NULLCHECK_ONE(pDate); | |
435 | |
436 time = PR_Now() + PR_SecondsToInterval(secondsOffset); | |
437 /* create a PKIX_PL_Date object */ | |
438 PKIX_CHECK(PKIX_PL_Object_Alloc | |
439 (PKIX_DATE_TYPE, | |
440 sizeof (PKIX_PL_Date), | |
441 (PKIX_PL_Object **)&date, | |
442 plContext), | |
443 PKIX_COULDNOTCREATEOBJECT); | |
444 | |
445 /* populate the nssTime field */ | |
446 date->nssTime = time; | |
447 *pDate = date; | |
448 | |
449 cleanup: | |
450 PKIX_RETURN(DATE); | |
451 } | |
452 | |
453 PKIX_Error * | |
454 PKIX_PL_Date_CreateFromPRTime( | |
455 PRTime prtime, | |
456 PKIX_PL_Date **pDate, | |
457 void *plContext) | |
458 { | |
459 PKIX_ENTER(DATE, "PKIX_PL_Date_CreateFromPRTime"); | |
460 PKIX_CHECK( | |
461 pkix_pl_Date_CreateFromPRTime(prtime, pDate, plContext), | |
462 PKIX_DATECREATEFROMPRTIMEFAILED); | |
463 | |
464 cleanup: | |
465 PKIX_RETURN(DATE); | |
466 } | |
OLD | NEW |