1 /*
2 * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 /* Time tests for the asn1 module */
11
12 #include <limits.h>
13 #include <stdio.h>
14 #include <string.h>
15
16 #include <crypto/asn1.h>
17 #include <openssl/asn1.h>
18 #include <openssl/evp.h>
19 #include <openssl/objects.h>
20 #include "testutil.h"
21 #include "internal/nelem.h"
22
23 struct testdata {
24 char *data; /* TIME string value */
25 int type; /* GENERALIZED OR UTC */
26 int expected_type; /* expected type after set/set_string_gmt */
27 int check_result; /* check result */
28 time_t t; /* expected time_t*/
29 int cmp_result; /* comparison to baseline result */
30 int convert_result; /* conversion result */
31 };
32
33 struct TESTDATA_asn1_to_utc {
34 char *input;
35 time_t expected;
36 };
37
38 static const struct TESTDATA_asn1_to_utc asn1_to_utc[] = {
39 {
40 /*
41 * last second of standard time in central Europe in 2021
42 * specified in GMT
43 */
44 "210328005959Z",
45 1616893199,
46 },
47 {
48 /*
49 * first second of daylight saving time in central Europe in 2021
50 * specified in GMT
51 */
52 "210328010000Z",
53 1616893200,
54 },
55 {
56 /*
57 * last second of standard time in central Europe in 2021
58 * specified in offset to GMT
59 */
60 "20210328015959+0100",
61 1616893199,
62 },
63 {
64 /*
65 * first second of daylight saving time in central Europe in 2021
66 * specified in offset to GMT
67 */
68 "20210328030000+0200",
69 1616893200,
70 },
71 {
72 /*
73 * Invalid strings should get -1 as a result
74 */
75 "INVALID",
76 -1,
77 },
78 };
79
80 static struct testdata tbl_testdata_pos[] = {
81 {
82 "0",
83 V_ASN1_GENERALIZEDTIME,
84 V_ASN1_GENERALIZEDTIME,
85 0,
86 0,
87 0,
88 0,
89 }, /* Bad time */
90 {
91 "ABCD",
92 V_ASN1_GENERALIZEDTIME,
93 V_ASN1_GENERALIZEDTIME,
94 0,
95 0,
96 0,
97 0,
98 },
99 {
100 "0ABCD",
101 V_ASN1_GENERALIZEDTIME,
102 V_ASN1_GENERALIZEDTIME,
103 0,
104 0,
105 0,
106 0,
107 },
108 {
109 "1-700101000000Z",
110 V_ASN1_GENERALIZEDTIME,
111 V_ASN1_GENERALIZEDTIME,
112 0,
113 0,
114 0,
115 0,
116 },
117 {
118 "`9700101000000Z",
119 V_ASN1_GENERALIZEDTIME,
120 V_ASN1_GENERALIZEDTIME,
121 0,
122 0,
123 0,
124 0,
125 },
126 {
127 "19700101000000Z",
128 V_ASN1_UTCTIME,
129 V_ASN1_UTCTIME,
130 0,
131 0,
132 0,
133 0,
134 },
135 {
136 "A00101000000Z",
137 V_ASN1_UTCTIME,
138 V_ASN1_UTCTIME,
139 0,
140 0,
141 0,
142 0,
143 },
144 {
145 "A9700101000000Z",
146 V_ASN1_GENERALIZEDTIME,
147 V_ASN1_GENERALIZEDTIME,
148 0,
149 0,
150 0,
151 0,
152 },
153 {
154 "1A700101000000Z",
155 V_ASN1_GENERALIZEDTIME,
156 V_ASN1_GENERALIZEDTIME,
157 0,
158 0,
159 0,
160 0,
161 },
162 {
163 "19A00101000000Z",
164 V_ASN1_GENERALIZEDTIME,
165 V_ASN1_GENERALIZEDTIME,
166 0,
167 0,
168 0,
169 0,
170 },
171 {
172 "197A0101000000Z",
173 V_ASN1_GENERALIZEDTIME,
174 V_ASN1_GENERALIZEDTIME,
175 0,
176 0,
177 0,
178 0,
179 },
180 {
181 "1970A101000000Z",
182 V_ASN1_GENERALIZEDTIME,
183 V_ASN1_GENERALIZEDTIME,
184 0,
185 0,
186 0,
187 0,
188 },
189 {
190 "19700A01000000Z",
191 V_ASN1_GENERALIZEDTIME,
192 V_ASN1_GENERALIZEDTIME,
193 0,
194 0,
195 0,
196 0,
197 },
198 {
199 "197001A1000000Z",
200 V_ASN1_GENERALIZEDTIME,
201 V_ASN1_GENERALIZEDTIME,
202 0,
203 0,
204 0,
205 0,
206 },
207 {
208 "1970010A000000Z",
209 V_ASN1_GENERALIZEDTIME,
210 V_ASN1_GENERALIZEDTIME,
211 0,
212 0,
213 0,
214 0,
215 },
216 {
217 "19700101A00000Z",
218 V_ASN1_GENERALIZEDTIME,
219 V_ASN1_GENERALIZEDTIME,
220 0,
221 0,
222 0,
223 0,
224 },
225 {
226 "197001010A0000Z",
227 V_ASN1_GENERALIZEDTIME,
228 V_ASN1_GENERALIZEDTIME,
229 0,
230 0,
231 0,
232 0,
233 },
234 {
235 "1970010100A000Z",
236 V_ASN1_GENERALIZEDTIME,
237 V_ASN1_GENERALIZEDTIME,
238 0,
239 0,
240 0,
241 0,
242 },
243 {
244 "19700101000A00Z",
245 V_ASN1_GENERALIZEDTIME,
246 V_ASN1_GENERALIZEDTIME,
247 0,
248 0,
249 0,
250 0,
251 },
252 {
253 "197001010000A0Z",
254 V_ASN1_GENERALIZEDTIME,
255 V_ASN1_GENERALIZEDTIME,
256 0,
257 0,
258 0,
259 0,
260 },
261 {
262 "1970010100000AZ",
263 V_ASN1_GENERALIZEDTIME,
264 V_ASN1_GENERALIZEDTIME,
265 0,
266 0,
267 0,
268 0,
269 },
270 {
271 "700101000000X",
272 V_ASN1_UTCTIME,
273 V_ASN1_UTCTIME,
274 0,
275 0,
276 0,
277 0,
278 },
279 {
280 "19700101000000X",
281 V_ASN1_GENERALIZEDTIME,
282 V_ASN1_GENERALIZEDTIME,
283 0,
284 0,
285 0,
286 0,
287 },
288 {
289 "209912312359Z",
290 V_ASN1_GENERALIZEDTIME,
291 V_ASN1_GENERALIZEDTIME,
292 0,
293 0,
294 0,
295 0,
296 },
297 {
298 "199912310000Z",
299 V_ASN1_GENERALIZEDTIME,
300 V_ASN1_GENERALIZEDTIME,
301 0,
302 0,
303 0,
304 0,
305 },
306 {
307 "9912312359Z",
308 V_ASN1_UTCTIME,
309 V_ASN1_UTCTIME,
310 0,
311 0,
312 0,
313 0,
314 },
315 {
316 "9912310000Z",
317 V_ASN1_UTCTIME,
318 V_ASN1_UTCTIME,
319 0,
320 0,
321 0,
322 0,
323 },
324 {
325 "19700101000000Z",
326 V_ASN1_GENERALIZEDTIME,
327 V_ASN1_UTCTIME,
328 1,
329 0,
330 -1,
331 1,
332 }, /* Epoch begins */
333 {
334 "700101000000Z",
335 V_ASN1_UTCTIME,
336 V_ASN1_UTCTIME,
337 1,
338 0,
339 -1,
340 1,
341 }, /* ditto */
342 {
343 "20380119031407Z",
344 V_ASN1_GENERALIZEDTIME,
345 V_ASN1_UTCTIME,
346 1,
347 0x7FFFFFFF,
348 1,
349 1,
350 }, /* Max 32bit time_t */
351 {
352 "380119031407Z",
353 V_ASN1_UTCTIME,
354 V_ASN1_UTCTIME,
355 1,
356 0x7FFFFFFF,
357 1,
358 1,
359 },
360 {
361 "20371231235959Z",
362 V_ASN1_GENERALIZEDTIME,
363 V_ASN1_UTCTIME,
364 1,
365 2145916799,
366 1,
367 1,
368 }, /* Just before 2038 */
369 {
370 "20371231235959Z",
371 V_ASN1_UTCTIME,
372 V_ASN1_UTCTIME,
373 0,
374 0,
375 0,
376 1,
377 }, /* Bad UTC time */
378 {
379 "371231235959Z",
380 V_ASN1_UTCTIME,
381 V_ASN1_UTCTIME,
382 1,
383 2145916799,
384 1,
385 1,
386 },
387 {
388 "19701006121456Z",
389 V_ASN1_GENERALIZEDTIME,
390 V_ASN1_UTCTIME,
391 1,
392 24063296,
393 -1,
394 1,
395 },
396 {
397 "701006121456Z",
398 V_ASN1_UTCTIME,
399 V_ASN1_UTCTIME,
400 1,
401 24063296,
402 -1,
403 1,
404 },
405 {
406 "19991231000000Z",
407 V_ASN1_GENERALIZEDTIME,
408 V_ASN1_UTCTIME,
409 1,
410 946598400,
411 0,
412 1,
413 }, /* Match baseline */
414 {
415 "991231000000Z",
416 V_ASN1_UTCTIME,
417 V_ASN1_UTCTIME,
418 1,
419 946598400,
420 0,
421 1,
422 },
423 {
424 "9912310000+0000",
425 V_ASN1_UTCTIME,
426 V_ASN1_UTCTIME,
427 1,
428 946598400,
429 0,
430 1,
431 },
432 {
433 "199912310000+0000",
434 V_ASN1_GENERALIZEDTIME,
435 V_ASN1_UTCTIME,
436 1,
437 946598400,
438 0,
439 1,
440 },
441 {
442 "9912310000-0000",
443 V_ASN1_UTCTIME,
444 V_ASN1_UTCTIME,
445 1,
446 946598400,
447 0,
448 1,
449 },
450 {
451 "199912310000-0000",
452 V_ASN1_GENERALIZEDTIME,
453 V_ASN1_UTCTIME,
454 1,
455 946598400,
456 0,
457 1,
458 },
459 {
460 "199912310100+0100",
461 V_ASN1_GENERALIZEDTIME,
462 V_ASN1_UTCTIME,
463 1,
464 946598400,
465 0,
466 1,
467 },
468 {
469 "199912302300-0100",
470 V_ASN1_GENERALIZEDTIME,
471 V_ASN1_UTCTIME,
472 1,
473 946598400,
474 0,
475 1,
476 },
477 {
478 "199912302300-A000",
479 V_ASN1_GENERALIZEDTIME,
480 V_ASN1_UTCTIME,
481 0,
482 946598400,
483 0,
484 1,
485 },
486 {
487 "199912302300-0A00",
488 V_ASN1_GENERALIZEDTIME,
489 V_ASN1_UTCTIME,
490 0,
491 946598400,
492 0,
493 1,
494 },
495 {
496 "9912310100+0100",
497 V_ASN1_UTCTIME,
498 V_ASN1_UTCTIME,
499 1,
500 946598400,
501 0,
502 1,
503 },
504 {
505 "9912302300-0100",
506 V_ASN1_UTCTIME,
507 V_ASN1_UTCTIME,
508 1,
509 946598400,
510 0,
511 1,
512 },
513 };
514
515 /* ASSUMES SIGNED TIME_T */
516 static struct testdata tbl_testdata_neg[] = {
517 {
518 "19011213204552Z",
519 V_ASN1_GENERALIZEDTIME,
520 V_ASN1_GENERALIZEDTIME,
521 1,
522 INT_MIN,
523 -1,
524 0,
525 },
526 {
527 "691006121456Z",
528 V_ASN1_UTCTIME,
529 V_ASN1_UTCTIME,
530 1,
531 -7472704,
532 -1,
533 1,
534 },
535 {
536 "19691006121456Z",
537 V_ASN1_GENERALIZEDTIME,
538 V_ASN1_UTCTIME,
539 1,
540 -7472704,
541 -1,
542 1,
543 },
544 };
545
546 /* explicit casts to time_t short warnings on systems with 32-bit time_t */
547 static struct testdata tbl_testdata_pos_64bit[] = {
548 {
549 "20380119031408Z",
550 V_ASN1_GENERALIZEDTIME,
551 V_ASN1_UTCTIME,
552 1,
553 (time_t)0x80000000,
554 1,
555 1,
556 },
557 {
558 "20380119031409Z",
559 V_ASN1_GENERALIZEDTIME,
560 V_ASN1_UTCTIME,
561 1,
562 (time_t)0x80000001,
563 1,
564 1,
565 },
566 {
567 "380119031408Z",
568 V_ASN1_UTCTIME,
569 V_ASN1_UTCTIME,
570 1,
571 (time_t)0x80000000,
572 1,
573 1,
574 },
575 {
576 "20500101120000Z",
577 V_ASN1_GENERALIZEDTIME,
578 V_ASN1_GENERALIZEDTIME,
579 1,
580 (time_t)0x967b1ec0,
581 1,
582 0,
583 },
584 };
585
586 /* ASSUMES SIGNED TIME_T */
587 static struct testdata tbl_testdata_neg_64bit[] = {
588 {
589 "19011213204551Z",
590 V_ASN1_GENERALIZEDTIME,
591 V_ASN1_GENERALIZEDTIME,
592 1,
593 (time_t)-2147483649LL,
594 -1,
595 0,
596 },
597 {
598 "19000101120000Z",
599 V_ASN1_GENERALIZEDTIME,
600 V_ASN1_GENERALIZEDTIME,
601 1,
602 (time_t)-2208945600LL,
603 -1,
604 0,
605 },
606 };
607
608 /* A baseline time to compare to */
609 static ASN1_TIME gtime = {
610 15,
611 V_ASN1_GENERALIZEDTIME,
612 (unsigned char *)"19991231000000Z",
613 0
614 };
615 static time_t gtime_t = 946598400;
616
test_table(struct testdata * tbl,int idx)617 static int test_table(struct testdata *tbl, int idx)
618 {
619 int error = 0;
620 ASN1_TIME atime;
621 ASN1_TIME *ptime;
622 struct testdata *td = &tbl[idx];
623 int day, sec;
624
625 atime.data = (unsigned char *)td->data;
626 atime.length = strlen((char *)atime.data);
627 atime.type = td->type;
628 atime.flags = 0;
629
630 if (!TEST_int_eq(ASN1_TIME_check(&atime), td->check_result)) {
631 TEST_info("ASN1_TIME_check(%s) unexpected result", atime.data);
632 error = 1;
633 }
634 if (td->check_result == 0)
635 return 1;
636
637 if (!TEST_int_eq(ASN1_TIME_cmp_time_t(&atime, td->t), 0)) {
638 TEST_info("ASN1_TIME_cmp_time_t(%s vs %ld) compare failed", atime.data, (long)td->t);
639 error = 1;
640 }
641
642 if (!TEST_true(ASN1_TIME_diff(&day, &sec, &atime, &atime))) {
643 TEST_info("ASN1_TIME_diff(%s) to self failed", atime.data);
644 error = 1;
645 }
646 if (!TEST_int_eq(day, 0) || !TEST_int_eq(sec, 0)) {
647 TEST_info("ASN1_TIME_diff(%s) to self not equal", atime.data);
648 error = 1;
649 }
650
651 if (!TEST_true(ASN1_TIME_diff(&day, &sec, >ime, &atime))) {
652 TEST_info("ASN1_TIME_diff(%s) to baseline failed", atime.data);
653 error = 1;
654 } else if (!((td->cmp_result == 0 && TEST_true((day == 0 && sec == 0))) || (td->cmp_result == -1 && TEST_true((day < 0 || sec < 0))) || (td->cmp_result == 1 && TEST_true((day > 0 || sec > 0))))) {
655 TEST_info("ASN1_TIME_diff(%s) to baseline bad comparison", atime.data);
656 error = 1;
657 }
658
659 if (!TEST_int_eq(ASN1_TIME_cmp_time_t(&atime, gtime_t), td->cmp_result)) {
660 TEST_info("ASN1_TIME_cmp_time_t(%s) to baseline bad comparison", atime.data);
661 error = 1;
662 }
663
664 ptime = ASN1_TIME_set(NULL, td->t);
665 if (!TEST_ptr(ptime)) {
666 TEST_info("ASN1_TIME_set(%ld) failed", (long)td->t);
667 error = 1;
668 } else {
669 int local_error = 0;
670 if (!TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, td->t), 0)) {
671 TEST_info("ASN1_TIME_set(%ld) compare failed (%s->%s)",
672 (long)td->t, td->data, ptime->data);
673 local_error = error = 1;
674 }
675 if (!TEST_int_eq(ptime->type, td->expected_type)) {
676 TEST_info("ASN1_TIME_set(%ld) unexpected type", (long)td->t);
677 local_error = error = 1;
678 }
679 if (local_error)
680 TEST_info("ASN1_TIME_set() = %*s", ptime->length, ptime->data);
681 ASN1_TIME_free(ptime);
682 }
683
684 ptime = ASN1_TIME_new();
685 if (!TEST_ptr(ptime)) {
686 TEST_info("ASN1_TIME_new() failed");
687 error = 1;
688 } else {
689 int local_error = 0;
690 if (!TEST_int_eq(ASN1_TIME_set_string(ptime, td->data), td->check_result)) {
691 TEST_info("ASN1_TIME_set_string_gmt(%s) failed", td->data);
692 local_error = error = 1;
693 }
694 if (!TEST_int_eq(ASN1_TIME_normalize(ptime), td->check_result)) {
695 TEST_info("ASN1_TIME_normalize(%s) failed", td->data);
696 local_error = error = 1;
697 }
698 if (!TEST_int_eq(ptime->type, td->expected_type)) {
699 TEST_info("ASN1_TIME_set_string_gmt(%s) unexpected type", td->data);
700 local_error = error = 1;
701 }
702 day = sec = 0;
703 if (!TEST_true(ASN1_TIME_diff(&day, &sec, ptime, &atime)) || !TEST_int_eq(day, 0) || !TEST_int_eq(sec, 0)) {
704 TEST_info("ASN1_TIME_diff(day=%d, sec=%d, %s) after ASN1_TIME_set_string_gmt() failed", day, sec, td->data);
705 local_error = error = 1;
706 }
707 if (!TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, gtime_t), td->cmp_result)) {
708 TEST_info("ASN1_TIME_cmp_time_t(%s) after ASN1_TIME_set_string_gnt() to baseline bad comparison", td->data);
709 local_error = error = 1;
710 }
711 if (local_error)
712 TEST_info("ASN1_TIME_set_string_gmt() = %*s", ptime->length, ptime->data);
713 ASN1_TIME_free(ptime);
714 }
715
716 ptime = ASN1_TIME_new();
717 if (!TEST_ptr(ptime)) {
718 TEST_info("ASN1_TIME_new() failed");
719 error = 1;
720 } else {
721 int local_error = 0;
722 if (!TEST_int_eq(ASN1_TIME_set_string(ptime, td->data), td->check_result)) {
723 TEST_info("ASN1_TIME_set_string(%s) failed", td->data);
724 local_error = error = 1;
725 }
726 day = sec = 0;
727 if (!TEST_true(ASN1_TIME_diff(&day, &sec, ptime, &atime)) || !TEST_int_eq(day, 0) || !TEST_int_eq(sec, 0)) {
728 TEST_info("ASN1_TIME_diff(day=%d, sec=%d, %s) after ASN1_TIME_set_string() failed", day, sec, td->data);
729 local_error = error = 1;
730 }
731 if (!TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, gtime_t), td->cmp_result)) {
732 TEST_info("ASN1_TIME_cmp_time_t(%s) after ASN1_TIME_set_string() to baseline bad comparison", td->data);
733 local_error = error = 1;
734 }
735 if (local_error)
736 TEST_info("ASN1_TIME_set_string() = %*s", ptime->length, ptime->data);
737 ASN1_TIME_free(ptime);
738 }
739
740 if (td->type == V_ASN1_UTCTIME) {
741 ptime = ASN1_TIME_to_generalizedtime(&atime, NULL);
742 if (td->convert_result == 1 && !TEST_ptr(ptime)) {
743 TEST_info("ASN1_TIME_to_generalizedtime(%s) failed", atime.data);
744 error = 1;
745 } else if (td->convert_result == 0 && !TEST_ptr_null(ptime)) {
746 TEST_info("ASN1_TIME_to_generalizedtime(%s) should have failed", atime.data);
747 error = 1;
748 }
749 if (ptime != NULL && !TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, td->t), 0)) {
750 TEST_info("ASN1_TIME_to_generalizedtime(%s->%s) bad result", atime.data, ptime->data);
751 error = 1;
752 }
753 ASN1_TIME_free(ptime);
754 }
755 /* else cannot simply convert GENERALIZEDTIME to UTCTIME */
756
757 if (error)
758 TEST_error("atime=%s", atime.data);
759
760 return !error;
761 }
762
test_table_pos(int idx)763 static int test_table_pos(int idx)
764 {
765 return test_table(tbl_testdata_pos, idx);
766 }
767
test_table_neg(int idx)768 static int test_table_neg(int idx)
769 {
770 return test_table(tbl_testdata_neg, idx);
771 }
772
test_table_pos_64bit(int idx)773 static int test_table_pos_64bit(int idx)
774 {
775 return test_table(tbl_testdata_pos_64bit, idx);
776 }
777
test_table_neg_64bit(int idx)778 static int test_table_neg_64bit(int idx)
779 {
780 return test_table(tbl_testdata_neg_64bit, idx);
781 }
782
783 struct compare_testdata {
784 ASN1_TIME t1;
785 ASN1_TIME t2;
786 int result;
787 };
788
789 static unsigned char TODAY_GEN_STR[] = "20170825000000Z";
790 static unsigned char TOMORROW_GEN_STR[] = "20170826000000Z";
791 static unsigned char TODAY_UTC_STR[] = "170825000000Z";
792 static unsigned char TOMORROW_UTC_STR[] = "170826000000Z";
793
794 #define TODAY_GEN { sizeof(TODAY_GEN_STR) - 1, V_ASN1_GENERALIZEDTIME, TODAY_GEN_STR, 0 }
795 #define TOMORROW_GEN { sizeof(TOMORROW_GEN_STR) - 1, V_ASN1_GENERALIZEDTIME, TOMORROW_GEN_STR, 0 }
796 #define TODAY_UTC { sizeof(TODAY_UTC_STR) - 1, V_ASN1_UTCTIME, TODAY_UTC_STR, 0 }
797 #define TOMORROW_UTC { sizeof(TOMORROW_UTC_STR) - 1, V_ASN1_UTCTIME, TOMORROW_UTC_STR, 0 }
798
799 static struct compare_testdata tbl_compare_testdata[] = {
800 { TODAY_GEN, TODAY_GEN, 0 },
801 { TODAY_GEN, TODAY_UTC, 0 },
802 { TODAY_GEN, TOMORROW_GEN, -1 },
803 { TODAY_GEN, TOMORROW_UTC, -1 },
804
805 { TODAY_UTC, TODAY_GEN, 0 },
806 { TODAY_UTC, TODAY_UTC, 0 },
807 { TODAY_UTC, TOMORROW_GEN, -1 },
808 { TODAY_UTC, TOMORROW_UTC, -1 },
809
810 { TOMORROW_GEN, TODAY_GEN, 1 },
811 { TOMORROW_GEN, TODAY_UTC, 1 },
812 { TOMORROW_GEN, TOMORROW_GEN, 0 },
813 { TOMORROW_GEN, TOMORROW_UTC, 0 },
814
815 { TOMORROW_UTC, TODAY_GEN, 1 },
816 { TOMORROW_UTC, TODAY_UTC, 1 },
817 { TOMORROW_UTC, TOMORROW_GEN, 0 },
818 { TOMORROW_UTC, TOMORROW_UTC, 0 }
819 };
820
test_table_compare(int idx)821 static int test_table_compare(int idx)
822 {
823 struct compare_testdata *td = &tbl_compare_testdata[idx];
824
825 return TEST_int_eq(ASN1_TIME_compare(&td->t1, &td->t2), td->result);
826 }
827
test_time_dup(void)828 static int test_time_dup(void)
829 {
830 int ret = 0;
831 ASN1_TIME *asn1_time = NULL;
832 ASN1_TIME *asn1_time_dup = NULL;
833 ASN1_TIME *asn1_gentime = NULL;
834
835 asn1_time = ASN1_TIME_adj(NULL, time(NULL), 0, 0);
836 if (asn1_time == NULL) {
837 TEST_info("Internal error.");
838 goto err;
839 }
840
841 asn1_gentime = ASN1_TIME_to_generalizedtime(asn1_time, NULL);
842 if (asn1_gentime == NULL) {
843 TEST_info("Internal error.");
844 goto err;
845 }
846
847 asn1_time_dup = ASN1_TIME_dup(asn1_time);
848 if (!TEST_ptr_ne(asn1_time_dup, NULL)) {
849 TEST_info("ASN1_TIME_dup() failed.");
850 goto err;
851 }
852 if (!TEST_int_eq(ASN1_TIME_compare(asn1_time, asn1_time_dup), 0)) {
853 TEST_info("ASN1_TIME_dup() duplicated non-identical value.");
854 goto err;
855 }
856 ASN1_STRING_free(asn1_time_dup);
857
858 asn1_time_dup = ASN1_UTCTIME_dup(asn1_time);
859 if (!TEST_ptr_ne(asn1_time_dup, NULL)) {
860 TEST_info("ASN1_UTCTIME_dup() failed.");
861 goto err;
862 }
863 if (!TEST_int_eq(ASN1_TIME_compare(asn1_time, asn1_time_dup), 0)) {
864 TEST_info("ASN1_UTCTIME_dup() duplicated non-identical UTCTIME value.");
865 goto err;
866 }
867 ASN1_STRING_free(asn1_time_dup);
868
869 asn1_time_dup = ASN1_GENERALIZEDTIME_dup(asn1_gentime);
870 if (!TEST_ptr_ne(asn1_time_dup, NULL)) {
871 TEST_info("ASN1_GENERALIZEDTIME_dup() failed.");
872 goto err;
873 }
874 if (!TEST_int_eq(ASN1_TIME_compare(asn1_gentime, asn1_time_dup), 0)) {
875 TEST_info("ASN1_GENERALIZEDTIME_dup() dup'ed non-identical value.");
876 goto err;
877 }
878
879 ret = 1;
880 err:
881 ASN1_STRING_free(asn1_time);
882 ASN1_STRING_free(asn1_gentime);
883 ASN1_STRING_free(asn1_time_dup);
884 return ret;
885 }
886
convert_asn1_to_time_t(int idx)887 static int convert_asn1_to_time_t(int idx)
888 {
889 time_t testdateutc;
890
891 testdateutc = test_asn1_string_to_time_t(asn1_to_utc[idx].input);
892
893 if (!TEST_time_t_eq(testdateutc, asn1_to_utc[idx].expected)) {
894 TEST_info("test_asn1_string_to_time_t (%s) failed: expected %lli, got %lli\n",
895 asn1_to_utc[idx].input,
896 (long long int)asn1_to_utc[idx].expected,
897 (long long int)testdateutc);
898 return 0;
899 }
900 return 1;
901 }
902
903 /*
904 * this test is here to exercise ossl_asn1_time_from_tm
905 * with an integer year close to INT_MAX.
906 */
convert_tm_to_asn1_time(void)907 static int convert_tm_to_asn1_time(void)
908 {
909 /* we need 64 bit time_t */
910 #if ((ULONG_MAX >> 31) >> 31) >= 1
911 time_t t;
912 ASN1_TIME *at;
913
914 if (sizeof(time_t) * CHAR_BIT >= 64) {
915 t = 67768011791126057ULL;
916 at = ASN1_TIME_set(NULL, t);
917 /*
918 * If ASN1_TIME_set returns NULL, it means it could not handle the input
919 * which is fine for this edge case.
920 */
921 ASN1_STRING_free(at);
922 }
923 #endif
924 return 1;
925 }
926
setup_tests(void)927 int setup_tests(void)
928 {
929 /*
930 * On platforms where |time_t| is an unsigned integer, t will be a
931 * positive number.
932 *
933 * We check if we're on a platform with a signed |time_t| with '!(t > 0)'
934 * because some compilers are picky if you do 't < 0', or even 't <= 0'
935 * if |t| is unsigned.
936 */
937 time_t t = -1;
938 /*
939 * On some platforms, |time_t| is signed, but a negative value is an
940 * error, and using it with gmtime() or localtime() generates a NULL.
941 * If that is the case, we can't perform tests on negative values.
942 */
943 struct tm *ptm = localtime(&t);
944
945 ADD_ALL_TESTS(test_table_pos, OSSL_NELEM(tbl_testdata_pos));
946 if (!(t > 0) && ptm != NULL) {
947 TEST_info("Adding negative-sign time_t tests");
948 ADD_ALL_TESTS(test_table_neg, OSSL_NELEM(tbl_testdata_neg));
949 }
950 if (sizeof(time_t) > sizeof(uint32_t)) {
951 TEST_info("Adding 64-bit time_t tests");
952 ADD_ALL_TESTS(test_table_pos_64bit, OSSL_NELEM(tbl_testdata_pos_64bit));
953 #ifndef __hpux
954 if (!(t > 0) && ptm != NULL) {
955 TEST_info("Adding negative-sign 64-bit time_t tests");
956 ADD_ALL_TESTS(test_table_neg_64bit, OSSL_NELEM(tbl_testdata_neg_64bit));
957 }
958 #endif
959 }
960 ADD_ALL_TESTS(test_table_compare, OSSL_NELEM(tbl_compare_testdata));
961 ADD_TEST(test_time_dup);
962 ADD_ALL_TESTS(convert_asn1_to_time_t, OSSL_NELEM(asn1_to_utc));
963 ADD_TEST(convert_tm_to_asn1_time);
964 return 1;
965 }
966