xref: /src/crypto/openssl/test/asn1_time_test.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
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, &gtime, &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