Home | History | Annotate | Line # | Download | only in test
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos /* Tests for X509 time functions */
     11      1.1  christos 
     12      1.1  christos #include <string.h>
     13      1.1  christos #include <time.h>
     14      1.1  christos 
     15      1.1  christos #include <openssl/asn1.h>
     16      1.1  christos #include <openssl/x509.h>
     17      1.1  christos #include "testutil.h"
     18      1.1  christos #include "internal/nelem.h"
     19      1.1  christos 
     20      1.1  christos typedef struct {
     21      1.1  christos     const char *data;
     22      1.1  christos     int type;
     23      1.1  christos     time_t cmp_time;
     24      1.1  christos     /* -1 if asn1_time <= cmp_time, 1 if asn1_time > cmp_time, 0 if error. */
     25      1.1  christos     int expected;
     26      1.1  christos } TESTDATA;
     27      1.1  christos 
     28      1.1  christos typedef struct {
     29      1.1  christos     const char *data;
     30      1.1  christos     /* 0 for check-only mode, 1 for set-string mode */
     31      1.1  christos     int set_string;
     32      1.1  christos     /* 0 for error, 1 if succeed */
     33      1.1  christos     int expected;
     34      1.1  christos     /*
     35      1.1  christos      * The following 2 fields are ignored if set_string field is set to '0'
     36      1.1  christos      * (in check only mode).
     37      1.1  christos      *
     38      1.1  christos      * But they can still be ignored explicitly in set-string mode by:
     39      1.1  christos      * setting -1 to expected_type and setting NULL to expected_string.
     40      1.1  christos      *
     41      1.1  christos      * It's useful in a case of set-string mode but the expected result
     42      1.1  christos      * is a 'parsing error'.
     43      1.1  christos      */
     44      1.1  christos     int expected_type;
     45      1.1  christos     const char *expected_string;
     46      1.1  christos } TESTDATA_FORMAT;
     47      1.1  christos 
     48      1.1  christos /*
     49      1.1  christos  * Actually, the "loose" mode has been tested in
     50      1.1  christos  * those time-compare-cases, so we may not test it again.
     51      1.1  christos  */
     52      1.1  christos static TESTDATA_FORMAT x509_format_tests[] = {
     53      1.1  christos     /* GeneralizedTime */
     54      1.1  christos     {
     55      1.1  christos         /* good format, check only */
     56  1.1.1.2  christos         "20170217180105Z",
     57  1.1.1.2  christos         0,
     58  1.1.1.2  christos         1,
     59  1.1.1.2  christos         -1,
     60  1.1.1.2  christos         NULL,
     61      1.1  christos     },
     62      1.1  christos     {
     63      1.1  christos         /* not leap year, check only */
     64  1.1.1.2  christos         "20170229180105Z",
     65  1.1.1.2  christos         0,
     66  1.1.1.2  christos         0,
     67  1.1.1.2  christos         -1,
     68  1.1.1.2  christos         NULL,
     69      1.1  christos     },
     70      1.1  christos     {
     71      1.1  christos         /* leap year, check only */
     72  1.1.1.2  christos         "20160229180105Z",
     73  1.1.1.2  christos         0,
     74  1.1.1.2  christos         1,
     75  1.1.1.2  christos         -1,
     76  1.1.1.2  christos         NULL,
     77      1.1  christos     },
     78      1.1  christos     {
     79      1.1  christos         /* SS is missing, check only */
     80  1.1.1.2  christos         "201702171801Z",
     81  1.1.1.2  christos         0,
     82  1.1.1.2  christos         0,
     83  1.1.1.2  christos         -1,
     84  1.1.1.2  christos         NULL,
     85      1.1  christos     },
     86      1.1  christos     {
     87      1.1  christos         /* fractional seconds, check only */
     88  1.1.1.2  christos         "20170217180105.001Z",
     89  1.1.1.2  christos         0,
     90  1.1.1.2  christos         0,
     91  1.1.1.2  christos         -1,
     92  1.1.1.2  christos         NULL,
     93      1.1  christos     },
     94      1.1  christos     {
     95      1.1  christos         /* timezone, check only */
     96  1.1.1.2  christos         "20170217180105+0800",
     97  1.1.1.2  christos         0,
     98  1.1.1.2  christos         0,
     99  1.1.1.2  christos         -1,
    100  1.1.1.2  christos         NULL,
    101      1.1  christos     },
    102      1.1  christos     {
    103      1.1  christos         /* SS is missing, set string */
    104  1.1.1.2  christos         "201702171801Z",
    105  1.1.1.2  christos         1,
    106  1.1.1.2  christos         0,
    107  1.1.1.2  christos         -1,
    108  1.1.1.2  christos         NULL,
    109      1.1  christos     },
    110      1.1  christos     {
    111      1.1  christos         /* fractional seconds, set string */
    112  1.1.1.2  christos         "20170217180105.001Z",
    113  1.1.1.2  christos         1,
    114  1.1.1.2  christos         0,
    115  1.1.1.2  christos         -1,
    116  1.1.1.2  christos         NULL,
    117      1.1  christos     },
    118      1.1  christos     {
    119      1.1  christos         /* timezone, set string */
    120  1.1.1.2  christos         "20170217180105+0800",
    121  1.1.1.2  christos         1,
    122  1.1.1.2  christos         0,
    123  1.1.1.2  christos         -1,
    124  1.1.1.2  christos         NULL,
    125      1.1  christos     },
    126      1.1  christos     {
    127      1.1  christos         /* good format, check returned 'turned' string */
    128  1.1.1.2  christos         "20170217180154Z",
    129  1.1.1.2  christos         1,
    130  1.1.1.2  christos         1,
    131  1.1.1.2  christos         V_ASN1_UTCTIME,
    132  1.1.1.2  christos         "170217180154Z",
    133      1.1  christos     },
    134      1.1  christos     {
    135      1.1  christos         /* good format, check returned string */
    136  1.1.1.2  christos         "20510217180154Z",
    137  1.1.1.2  christos         1,
    138  1.1.1.2  christos         1,
    139  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    140  1.1.1.2  christos         "20510217180154Z",
    141      1.1  christos     },
    142      1.1  christos     {
    143      1.1  christos         /* good format but out of UTC range, check returned string */
    144  1.1.1.2  christos         "19230419180154Z",
    145  1.1.1.2  christos         1,
    146  1.1.1.2  christos         1,
    147  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    148  1.1.1.2  christos         "19230419180154Z",
    149      1.1  christos     },
    150      1.1  christos     /* UTC */
    151      1.1  christos     {
    152      1.1  christos         /* SS is missing, check only */
    153  1.1.1.2  christos         "1702171801Z",
    154  1.1.1.2  christos         0,
    155  1.1.1.2  christos         0,
    156  1.1.1.2  christos         -1,
    157  1.1.1.2  christos         NULL,
    158      1.1  christos     },
    159      1.1  christos     {
    160      1.1  christos         /* not leap year, check only */
    161  1.1.1.2  christos         "050229180101Z",
    162  1.1.1.2  christos         0,
    163  1.1.1.2  christos         0,
    164  1.1.1.2  christos         -1,
    165  1.1.1.2  christos         NULL,
    166      1.1  christos     },
    167      1.1  christos     {
    168      1.1  christos         /* leap year, check only */
    169  1.1.1.2  christos         "040229180101Z",
    170  1.1.1.2  christos         0,
    171  1.1.1.2  christos         1,
    172  1.1.1.2  christos         -1,
    173  1.1.1.2  christos         NULL,
    174      1.1  christos     },
    175      1.1  christos     {
    176      1.1  christos         /* timezone, check only */
    177  1.1.1.2  christos         "170217180154+0800",
    178  1.1.1.2  christos         0,
    179  1.1.1.2  christos         0,
    180  1.1.1.2  christos         -1,
    181  1.1.1.2  christos         NULL,
    182      1.1  christos     },
    183      1.1  christos     {
    184      1.1  christos         /* SS is missing, set string */
    185  1.1.1.2  christos         "1702171801Z",
    186  1.1.1.2  christos         1,
    187  1.1.1.2  christos         0,
    188  1.1.1.2  christos         -1,
    189  1.1.1.2  christos         NULL,
    190      1.1  christos     },
    191      1.1  christos     {
    192      1.1  christos         /* timezone, set string */
    193  1.1.1.2  christos         "170217180154+0800",
    194  1.1.1.2  christos         1,
    195  1.1.1.2  christos         0,
    196  1.1.1.2  christos         -1,
    197  1.1.1.2  christos         NULL,
    198      1.1  christos     },
    199      1.1  christos     {
    200      1.1  christos         /* 2017, good format, check returned string */
    201  1.1.1.2  christos         "170217180154Z",
    202  1.1.1.2  christos         1,
    203  1.1.1.2  christos         1,
    204  1.1.1.2  christos         V_ASN1_UTCTIME,
    205  1.1.1.2  christos         "170217180154Z",
    206      1.1  christos     },
    207      1.1  christos     {
    208      1.1  christos         /* 1998, good format, check returned string */
    209  1.1.1.2  christos         "981223180154Z",
    210  1.1.1.2  christos         1,
    211  1.1.1.2  christos         1,
    212  1.1.1.2  christos         V_ASN1_UTCTIME,
    213  1.1.1.2  christos         "981223180154Z",
    214      1.1  christos     },
    215      1.1  christos };
    216      1.1  christos 
    217      1.1  christos static TESTDATA x509_cmp_tests[] = {
    218      1.1  christos     {
    219  1.1.1.2  christos         "20170217180154Z",
    220  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    221      1.1  christos         /* The same in seconds since epoch. */
    222  1.1.1.2  christos         1487354514,
    223  1.1.1.2  christos         -1,
    224      1.1  christos     },
    225      1.1  christos     {
    226  1.1.1.2  christos         "20170217180154Z",
    227  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    228      1.1  christos         /* One second more. */
    229  1.1.1.2  christos         1487354515,
    230  1.1.1.2  christos         -1,
    231      1.1  christos     },
    232      1.1  christos     {
    233  1.1.1.2  christos         "20170217180154Z",
    234  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    235      1.1  christos         /* One second less. */
    236  1.1.1.2  christos         1487354513,
    237  1.1.1.2  christos         1,
    238      1.1  christos     },
    239      1.1  christos     /* Same as UTC time. */
    240      1.1  christos     {
    241  1.1.1.2  christos         "170217180154Z",
    242  1.1.1.2  christos         V_ASN1_UTCTIME,
    243      1.1  christos         /* The same in seconds since epoch. */
    244  1.1.1.2  christos         1487354514,
    245  1.1.1.2  christos         -1,
    246      1.1  christos     },
    247      1.1  christos     {
    248  1.1.1.2  christos         "170217180154Z",
    249  1.1.1.2  christos         V_ASN1_UTCTIME,
    250      1.1  christos         /* One second more. */
    251  1.1.1.2  christos         1487354515,
    252  1.1.1.2  christos         -1,
    253      1.1  christos     },
    254      1.1  christos     {
    255  1.1.1.2  christos         "170217180154Z",
    256  1.1.1.2  christos         V_ASN1_UTCTIME,
    257      1.1  christos         /* One second less. */
    258  1.1.1.2  christos         1487354513,
    259  1.1.1.2  christos         1,
    260      1.1  christos     },
    261      1.1  christos     /* UTCTime from the 20th century. */
    262      1.1  christos     {
    263  1.1.1.2  christos         "990217180154Z",
    264  1.1.1.2  christos         V_ASN1_UTCTIME,
    265      1.1  christos         /* The same in seconds since epoch. */
    266  1.1.1.2  christos         919274514,
    267  1.1.1.2  christos         -1,
    268      1.1  christos     },
    269      1.1  christos     {
    270  1.1.1.2  christos         "990217180154Z",
    271  1.1.1.2  christos         V_ASN1_UTCTIME,
    272      1.1  christos         /* One second more. */
    273  1.1.1.2  christos         919274515,
    274  1.1.1.2  christos         -1,
    275      1.1  christos     },
    276      1.1  christos     {
    277  1.1.1.2  christos         "990217180154Z",
    278  1.1.1.2  christos         V_ASN1_UTCTIME,
    279      1.1  christos         /* One second less. */
    280  1.1.1.2  christos         919274513,
    281  1.1.1.2  christos         1,
    282      1.1  christos     },
    283      1.1  christos     /* Various invalid formats. */
    284      1.1  christos     {
    285      1.1  christos         /* No trailing Z. */
    286  1.1.1.2  christos         "20170217180154",
    287  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    288  1.1.1.2  christos         0,
    289  1.1.1.2  christos         0,
    290      1.1  christos     },
    291      1.1  christos     {
    292      1.1  christos         /* No trailing Z, UTCTime. */
    293  1.1.1.2  christos         "170217180154",
    294  1.1.1.2  christos         V_ASN1_UTCTIME,
    295  1.1.1.2  christos         0,
    296  1.1.1.2  christos         0,
    297      1.1  christos     },
    298      1.1  christos     {
    299      1.1  christos         /* No seconds. */
    300  1.1.1.2  christos         "201702171801Z",
    301  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    302  1.1.1.2  christos         0,
    303  1.1.1.2  christos         0,
    304      1.1  christos     },
    305      1.1  christos     {
    306      1.1  christos         /* No seconds, UTCTime. */
    307  1.1.1.2  christos         "1702171801Z",
    308  1.1.1.2  christos         V_ASN1_UTCTIME,
    309  1.1.1.2  christos         0,
    310  1.1.1.2  christos         0,
    311      1.1  christos     },
    312      1.1  christos     {
    313      1.1  christos         /* Fractional seconds. */
    314  1.1.1.2  christos         "20170217180154.001Z",
    315  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    316  1.1.1.2  christos         0,
    317  1.1.1.2  christos         0,
    318      1.1  christos     },
    319      1.1  christos     {
    320      1.1  christos         /* Fractional seconds, UTCTime. */
    321  1.1.1.2  christos         "170217180154.001Z",
    322  1.1.1.2  christos         V_ASN1_UTCTIME,
    323  1.1.1.2  christos         0,
    324  1.1.1.2  christos         0,
    325      1.1  christos     },
    326      1.1  christos     {
    327      1.1  christos         /* Timezone offset. */
    328  1.1.1.2  christos         "20170217180154+0100",
    329  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    330  1.1.1.2  christos         0,
    331  1.1.1.2  christos         0,
    332      1.1  christos     },
    333      1.1  christos     {
    334      1.1  christos         /* Timezone offset, UTCTime. */
    335  1.1.1.2  christos         "170217180154+0100",
    336  1.1.1.2  christos         V_ASN1_UTCTIME,
    337  1.1.1.2  christos         0,
    338  1.1.1.2  christos         0,
    339      1.1  christos     },
    340      1.1  christos     {
    341      1.1  christos         /* Extra digits. */
    342  1.1.1.2  christos         "2017021718015400Z",
    343  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    344  1.1.1.2  christos         0,
    345  1.1.1.2  christos         0,
    346      1.1  christos     },
    347      1.1  christos     {
    348      1.1  christos         /* Extra digits, UTCTime. */
    349  1.1.1.2  christos         "17021718015400Z",
    350  1.1.1.2  christos         V_ASN1_UTCTIME,
    351  1.1.1.2  christos         0,
    352  1.1.1.2  christos         0,
    353      1.1  christos     },
    354      1.1  christos     {
    355      1.1  christos         /* Non-digits. */
    356  1.1.1.2  christos         "2017021718015aZ",
    357  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    358  1.1.1.2  christos         0,
    359  1.1.1.2  christos         0,
    360      1.1  christos     },
    361      1.1  christos     {
    362      1.1  christos         /* Non-digits, UTCTime. */
    363  1.1.1.2  christos         "17021718015aZ",
    364  1.1.1.2  christos         V_ASN1_UTCTIME,
    365  1.1.1.2  christos         0,
    366  1.1.1.2  christos         0,
    367      1.1  christos     },
    368      1.1  christos     {
    369      1.1  christos         /* Trailing garbage. */
    370  1.1.1.2  christos         "20170217180154Zlongtrailinggarbage",
    371  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    372  1.1.1.2  christos         0,
    373  1.1.1.2  christos         0,
    374      1.1  christos     },
    375      1.1  christos     {
    376      1.1  christos         /* Trailing garbage, UTCTime. */
    377  1.1.1.2  christos         "170217180154Zlongtrailinggarbage",
    378  1.1.1.2  christos         V_ASN1_UTCTIME,
    379  1.1.1.2  christos         0,
    380  1.1.1.2  christos         0,
    381      1.1  christos     },
    382      1.1  christos     {
    383  1.1.1.2  christos         /* Swapped type. */
    384  1.1.1.2  christos         "20170217180154Z",
    385  1.1.1.2  christos         V_ASN1_UTCTIME,
    386  1.1.1.2  christos         0,
    387  1.1.1.2  christos         0,
    388      1.1  christos     },
    389      1.1  christos     {
    390      1.1  christos         /* Swapped type. */
    391  1.1.1.2  christos         "170217180154Z",
    392  1.1.1.2  christos         V_ASN1_GENERALIZEDTIME,
    393  1.1.1.2  christos         0,
    394  1.1.1.2  christos         0,
    395      1.1  christos     },
    396      1.1  christos     {
    397      1.1  christos         /* Bad type. */
    398  1.1.1.2  christos         "20170217180154Z",
    399  1.1.1.2  christos         V_ASN1_OCTET_STRING,
    400  1.1.1.2  christos         0,
    401  1.1.1.2  christos         0,
    402      1.1  christos     },
    403      1.1  christos };
    404      1.1  christos 
    405      1.1  christos static int test_x509_cmp_time(int idx)
    406      1.1  christos {
    407      1.1  christos     ASN1_TIME t;
    408      1.1  christos     int result;
    409      1.1  christos 
    410      1.1  christos     memset(&t, 0, sizeof(t));
    411      1.1  christos     t.type = x509_cmp_tests[idx].type;
    412  1.1.1.2  christos     t.data = (unsigned char *)(x509_cmp_tests[idx].data);
    413      1.1  christos     t.length = strlen(x509_cmp_tests[idx].data);
    414      1.1  christos     t.flags = 0;
    415      1.1  christos 
    416      1.1  christos     result = X509_cmp_time(&t, &x509_cmp_tests[idx].cmp_time);
    417      1.1  christos     if (!TEST_int_eq(result, x509_cmp_tests[idx].expected)) {
    418      1.1  christos         TEST_info("test_x509_cmp_time(%d) failed: expected %d, got %d\n",
    419  1.1.1.2  christos             idx, x509_cmp_tests[idx].expected, result);
    420      1.1  christos         return 0;
    421      1.1  christos     }
    422      1.1  christos     return 1;
    423      1.1  christos }
    424      1.1  christos 
    425      1.1  christos static int test_x509_cmp_time_current(void)
    426      1.1  christos {
    427      1.1  christos     time_t now = time(NULL);
    428      1.1  christos     /* Pick a day earlier and later, relative to any system clock. */
    429      1.1  christos     ASN1_TIME *asn1_before = NULL, *asn1_after = NULL;
    430      1.1  christos     int cmp_result, failed = 0;
    431      1.1  christos 
    432      1.1  christos     asn1_before = ASN1_TIME_adj(NULL, now, -1, 0);
    433      1.1  christos     asn1_after = ASN1_TIME_adj(NULL, now, 1, 0);
    434      1.1  christos 
    435  1.1.1.2  christos     cmp_result = X509_cmp_time(asn1_before, NULL);
    436      1.1  christos     if (!TEST_int_eq(cmp_result, -1))
    437      1.1  christos         failed = 1;
    438      1.1  christos 
    439      1.1  christos     cmp_result = X509_cmp_time(asn1_after, NULL);
    440      1.1  christos     if (!TEST_int_eq(cmp_result, 1))
    441      1.1  christos         failed = 1;
    442      1.1  christos 
    443      1.1  christos     ASN1_TIME_free(asn1_before);
    444      1.1  christos     ASN1_TIME_free(asn1_after);
    445      1.1  christos 
    446      1.1  christos     return failed == 0;
    447      1.1  christos }
    448      1.1  christos 
    449      1.1  christos static int test_X509_cmp_timeframe_vpm(const X509_VERIFY_PARAM *vpm,
    450  1.1.1.2  christos     ASN1_TIME *asn1_before,
    451  1.1.1.2  christos     ASN1_TIME *asn1_mid,
    452  1.1.1.2  christos     ASN1_TIME *asn1_after)
    453      1.1  christos {
    454      1.1  christos     int always_0 = vpm != NULL
    455      1.1  christos         && (X509_VERIFY_PARAM_get_flags(vpm) & X509_V_FLAG_USE_CHECK_TIME) == 0
    456      1.1  christos         && (X509_VERIFY_PARAM_get_flags(vpm) & X509_V_FLAG_NO_CHECK_TIME) != 0;
    457      1.1  christos 
    458      1.1  christos     return asn1_before != NULL && asn1_mid != NULL && asn1_after != NULL
    459      1.1  christos         && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, asn1_after), 0)
    460      1.1  christos         && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, NULL), 0)
    461      1.1  christos         && TEST_int_eq(X509_cmp_timeframe(vpm, NULL, asn1_after), 0)
    462      1.1  christos         && TEST_int_eq(X509_cmp_timeframe(vpm, NULL, NULL), 0)
    463      1.1  christos         && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_after, asn1_after),
    464  1.1.1.2  christos             always_0 ? 0 : -1)
    465      1.1  christos         && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, asn1_before),
    466  1.1.1.2  christos             always_0 ? 0 : 1)
    467      1.1  christos         && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_after, asn1_before),
    468  1.1.1.2  christos             always_0 ? 0 : 1);
    469      1.1  christos }
    470      1.1  christos 
    471      1.1  christos static int test_X509_cmp_timeframe(void)
    472      1.1  christos {
    473      1.1  christos     time_t now = time(NULL);
    474      1.1  christos     ASN1_TIME *asn1_mid = ASN1_TIME_adj(NULL, now, 0, 0);
    475      1.1  christos     /* Pick a day earlier and later, relative to any system clock. */
    476      1.1  christos     ASN1_TIME *asn1_before = ASN1_TIME_adj(NULL, now, -1, 0);
    477      1.1  christos     ASN1_TIME *asn1_after = ASN1_TIME_adj(NULL, now, 1, 0);
    478      1.1  christos     X509_VERIFY_PARAM *vpm = X509_VERIFY_PARAM_new();
    479      1.1  christos     int res = 0;
    480      1.1  christos 
    481      1.1  christos     if (vpm == NULL)
    482      1.1  christos         goto finish;
    483      1.1  christos     res = test_X509_cmp_timeframe_vpm(NULL, asn1_before, asn1_mid, asn1_after)
    484      1.1  christos         && test_X509_cmp_timeframe_vpm(vpm, asn1_before, asn1_mid, asn1_after);
    485      1.1  christos 
    486      1.1  christos     X509_VERIFY_PARAM_set_time(vpm, now);
    487      1.1  christos     res = res
    488      1.1  christos         && test_X509_cmp_timeframe_vpm(vpm, asn1_before, asn1_mid, asn1_after)
    489      1.1  christos         && X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME)
    490      1.1  christos         && test_X509_cmp_timeframe_vpm(vpm, asn1_before, asn1_mid, asn1_after);
    491      1.1  christos 
    492      1.1  christos     X509_VERIFY_PARAM_free(vpm);
    493      1.1  christos finish:
    494      1.1  christos     ASN1_TIME_free(asn1_mid);
    495      1.1  christos     ASN1_TIME_free(asn1_before);
    496      1.1  christos     ASN1_TIME_free(asn1_after);
    497      1.1  christos 
    498      1.1  christos     return res;
    499      1.1  christos }
    500      1.1  christos 
    501      1.1  christos static int test_x509_time(int idx)
    502      1.1  christos {
    503      1.1  christos     ASN1_TIME *t = NULL;
    504      1.1  christos     int result, rv = 0;
    505      1.1  christos 
    506      1.1  christos     if (x509_format_tests[idx].set_string) {
    507      1.1  christos         /* set-string mode */
    508      1.1  christos         t = ASN1_TIME_new();
    509      1.1  christos         if (t == NULL) {
    510      1.1  christos             TEST_info("test_x509_time(%d) failed: internal error\n", idx);
    511      1.1  christos             return 0;
    512      1.1  christos         }
    513      1.1  christos     }
    514      1.1  christos 
    515      1.1  christos     result = ASN1_TIME_set_string_X509(t, x509_format_tests[idx].data);
    516      1.1  christos     /* time string parsing result is always checked against what's expected */
    517      1.1  christos     if (!TEST_int_eq(result, x509_format_tests[idx].expected)) {
    518      1.1  christos         TEST_info("test_x509_time(%d) failed: expected %d, got %d\n",
    519  1.1.1.2  christos             idx, x509_format_tests[idx].expected, result);
    520      1.1  christos         goto out;
    521      1.1  christos     }
    522      1.1  christos 
    523      1.1  christos     /* if t is not NULL but expected_type is ignored(-1), it is an 'OK' case */
    524      1.1  christos     if (t != NULL && x509_format_tests[idx].expected_type != -1) {
    525      1.1  christos         if (!TEST_int_eq(t->type, x509_format_tests[idx].expected_type)) {
    526      1.1  christos             TEST_info("test_x509_time(%d) failed: expected_type %d, got %d\n",
    527  1.1.1.2  christos                 idx, x509_format_tests[idx].expected_type, t->type);
    528      1.1  christos             goto out;
    529      1.1  christos         }
    530      1.1  christos     }
    531      1.1  christos 
    532      1.1  christos     /* if t is not NULL but expected_string is NULL, it is an 'OK' case too */
    533      1.1  christos     if (t != NULL && x509_format_tests[idx].expected_string) {
    534      1.1  christos         if (!TEST_mem_eq((const char *)t->data, t->length,
    535  1.1.1.2  christos                 x509_format_tests[idx].expected_string,
    536  1.1.1.2  christos                 strlen(x509_format_tests[idx].expected_string))) {
    537      1.1  christos             TEST_info("test_x509_time(%d) failed: expected_string %s, got %.*s\n",
    538  1.1.1.2  christos                 idx, x509_format_tests[idx].expected_string, t->length,
    539  1.1.1.2  christos                 t->data);
    540      1.1  christos             goto out;
    541      1.1  christos         }
    542      1.1  christos     }
    543      1.1  christos 
    544      1.1  christos     rv = 1;
    545      1.1  christos out:
    546      1.1  christos     if (t != NULL)
    547      1.1  christos         ASN1_TIME_free(t);
    548      1.1  christos     return rv;
    549      1.1  christos }
    550      1.1  christos 
    551      1.1  christos static const struct {
    552      1.1  christos     int y, m, d;
    553      1.1  christos     int yd, wd;
    554      1.1  christos } day_of_week_tests[] = {
    555      1.1  christos     /*YYYY  MM  DD  DoY  DoW */
    556  1.1.1.2  christos     { 1900, 1, 1, 0, 1 },
    557  1.1.1.2  christos     { 1900, 2, 28, 58, 3 },
    558  1.1.1.2  christos     { 1900, 3, 1, 59, 4 },
    559      1.1  christos     { 1900, 12, 31, 364, 1 },
    560  1.1.1.2  christos     { 1901, 1, 1, 0, 2 },
    561  1.1.1.2  christos     { 1970, 1, 1, 0, 4 },
    562  1.1.1.2  christos     { 1999, 1, 10, 9, 0 },
    563      1.1  christos     { 1999, 12, 31, 364, 5 },
    564  1.1.1.2  christos     { 2000, 1, 1, 0, 6 },
    565  1.1.1.2  christos     { 2000, 2, 28, 58, 1 },
    566  1.1.1.2  christos     { 2000, 2, 29, 59, 2 },
    567  1.1.1.2  christos     { 2000, 3, 1, 60, 3 },
    568      1.1  christos     { 2000, 12, 31, 365, 0 },
    569  1.1.1.2  christos     { 2001, 1, 1, 0, 1 },
    570  1.1.1.2  christos     { 2008, 1, 1, 0, 2 },
    571  1.1.1.2  christos     { 2008, 2, 28, 58, 4 },
    572  1.1.1.2  christos     { 2008, 2, 29, 59, 5 },
    573  1.1.1.2  christos     { 2008, 3, 1, 60, 6 },
    574      1.1  christos     { 2008, 12, 31, 365, 3 },
    575  1.1.1.2  christos     { 2009, 1, 1, 0, 4 },
    576  1.1.1.2  christos     { 2011, 1, 1, 0, 6 },
    577  1.1.1.2  christos     { 2011, 2, 28, 58, 1 },
    578  1.1.1.2  christos     { 2011, 3, 1, 59, 2 },
    579      1.1  christos     { 2011, 12, 31, 364, 6 },
    580  1.1.1.2  christos     { 2012, 1, 1, 0, 0 },
    581  1.1.1.2  christos     { 2019, 1, 2, 1, 3 },
    582  1.1.1.2  christos     { 2019, 2, 2, 32, 6 },
    583  1.1.1.2  christos     { 2019, 3, 2, 60, 6 },
    584  1.1.1.2  christos     { 2019, 4, 2, 91, 2 },
    585  1.1.1.2  christos     { 2019, 5, 2, 121, 4 },
    586  1.1.1.2  christos     { 2019, 6, 2, 152, 0 },
    587  1.1.1.2  christos     { 2019, 7, 2, 182, 2 },
    588  1.1.1.2  christos     { 2019, 8, 2, 213, 5 },
    589  1.1.1.2  christos     { 2019, 9, 2, 244, 1 },
    590  1.1.1.2  christos     { 2019, 10, 2, 274, 3 },
    591  1.1.1.2  christos     { 2019, 11, 2, 305, 6 },
    592  1.1.1.2  christos     { 2019, 12, 2, 335, 1 },
    593  1.1.1.2  christos     { 2020, 1, 2, 1, 4 },
    594  1.1.1.2  christos     { 2020, 2, 2, 32, 0 },
    595  1.1.1.2  christos     { 2020, 3, 2, 61, 1 },
    596  1.1.1.2  christos     { 2020, 4, 2, 92, 4 },
    597  1.1.1.2  christos     { 2020, 5, 2, 122, 6 },
    598  1.1.1.2  christos     { 2020, 6, 2, 153, 2 },
    599  1.1.1.2  christos     { 2020, 7, 2, 183, 4 },
    600  1.1.1.2  christos     { 2020, 8, 2, 214, 0 },
    601  1.1.1.2  christos     { 2020, 9, 2, 245, 3 },
    602  1.1.1.2  christos     { 2020, 10, 2, 275, 5 },
    603  1.1.1.2  christos     { 2020, 11, 2, 306, 1 },
    604  1.1.1.2  christos     { 2020, 12, 2, 336, 3 }
    605      1.1  christos };
    606      1.1  christos 
    607      1.1  christos static int test_days(int n)
    608      1.1  christos {
    609      1.1  christos     char d[16];
    610      1.1  christos     ASN1_TIME *a = NULL;
    611      1.1  christos     struct tm t;
    612      1.1  christos     int r;
    613      1.1  christos 
    614      1.1  christos     BIO_snprintf(d, sizeof(d), "%04d%02d%02d050505Z",
    615  1.1.1.2  christos         day_of_week_tests[n].y, day_of_week_tests[n].m,
    616  1.1.1.2  christos         day_of_week_tests[n].d);
    617      1.1  christos 
    618      1.1  christos     if (!TEST_ptr(a = ASN1_TIME_new()))
    619      1.1  christos         return 0;
    620      1.1  christos 
    621      1.1  christos     r = TEST_true(ASN1_TIME_set_string(a, d))
    622      1.1  christos         && TEST_true(ASN1_TIME_to_tm(a, &t))
    623      1.1  christos         && TEST_int_eq(t.tm_yday, day_of_week_tests[n].yd)
    624      1.1  christos         && TEST_int_eq(t.tm_wday, day_of_week_tests[n].wd);
    625      1.1  christos 
    626      1.1  christos     ASN1_TIME_free(a);
    627      1.1  christos     return r;
    628      1.1  christos }
    629      1.1  christos 
    630      1.1  christos #define construct_asn1_time(s, t, e) \
    631  1.1.1.2  christos     { { sizeof(s) - 1, t, (unsigned char *)s, 0 }, e }
    632      1.1  christos 
    633      1.1  christos static const struct {
    634      1.1  christos     ASN1_TIME asn1;
    635      1.1  christos     const char *readable;
    636  1.1.1.2  christos } x509_print_tests_rfc_822[] = {
    637      1.1  christos     /* Generalized Time */
    638      1.1  christos     construct_asn1_time("20170731222050Z", V_ASN1_GENERALIZEDTIME,
    639  1.1.1.2  christos         "Jul 31 22:20:50 2017 GMT"),
    640      1.1  christos     /* Generalized Time, no seconds */
    641      1.1  christos     construct_asn1_time("201707312220Z", V_ASN1_GENERALIZEDTIME,
    642  1.1.1.2  christos         "Bad time value"),
    643      1.1  christos     /* Generalized Time, fractional seconds (3 digits) */
    644      1.1  christos     construct_asn1_time("20170731222050.123Z", V_ASN1_GENERALIZEDTIME,
    645  1.1.1.2  christos         "Jul 31 22:20:50.123 2017 GMT"),
    646      1.1  christos     /* Generalized Time, fractional seconds (1 digit) */
    647      1.1  christos     construct_asn1_time("20170731222050.1Z", V_ASN1_GENERALIZEDTIME,
    648  1.1.1.2  christos         "Jul 31 22:20:50.1 2017 GMT"),
    649      1.1  christos     /* Generalized Time, fractional seconds (0 digit) */
    650      1.1  christos     construct_asn1_time("20170731222050.Z", V_ASN1_GENERALIZEDTIME,
    651  1.1.1.2  christos         "Bad time value"),
    652      1.1  christos     /* UTC Time */
    653      1.1  christos     construct_asn1_time("170731222050Z", V_ASN1_UTCTIME,
    654  1.1.1.2  christos         "Jul 31 22:20:50 2017 GMT"),
    655      1.1  christos     /* UTC Time, no seconds */
    656      1.1  christos     construct_asn1_time("1707312220Z", V_ASN1_UTCTIME,
    657  1.1.1.2  christos         "Bad time value"),
    658      1.1  christos };
    659      1.1  christos 
    660      1.1  christos static const struct {
    661      1.1  christos     ASN1_TIME asn1;
    662      1.1  christos     const char *readable;
    663  1.1.1.2  christos } x509_print_tests_iso_8601[] = {
    664      1.1  christos     /* Generalized Time */
    665      1.1  christos     construct_asn1_time("20170731222050Z", V_ASN1_GENERALIZEDTIME,
    666  1.1.1.2  christos         "2017-07-31 22:20:50Z"),
    667      1.1  christos     /* Generalized Time, no seconds */
    668      1.1  christos     construct_asn1_time("201707312220Z", V_ASN1_GENERALIZEDTIME,
    669  1.1.1.2  christos         "Bad time value"),
    670      1.1  christos     /* Generalized Time, fractional seconds (3 digits) */
    671      1.1  christos     construct_asn1_time("20170731222050.123Z", V_ASN1_GENERALIZEDTIME,
    672  1.1.1.2  christos         "2017-07-31 22:20:50.123Z"),
    673      1.1  christos     /* Generalized Time, fractional seconds (1 digit) */
    674      1.1  christos     construct_asn1_time("20170731222050.1Z", V_ASN1_GENERALIZEDTIME,
    675  1.1.1.2  christos         "2017-07-31 22:20:50.1Z"),
    676      1.1  christos     /* Generalized Time, fractional seconds (0 digit) */
    677      1.1  christos     construct_asn1_time("20170731222050.Z", V_ASN1_GENERALIZEDTIME,
    678  1.1.1.2  christos         "Bad time value"),
    679      1.1  christos     /* UTC Time */
    680      1.1  christos     construct_asn1_time("170731222050Z", V_ASN1_UTCTIME,
    681  1.1.1.2  christos         "2017-07-31 22:20:50Z"),
    682      1.1  christos     /* UTC Time, no seconds */
    683      1.1  christos     construct_asn1_time("1707312220Z", V_ASN1_UTCTIME,
    684  1.1.1.2  christos         "Bad time value"),
    685      1.1  christos };
    686      1.1  christos 
    687      1.1  christos static int test_x509_time_print_rfc_822(int idx)
    688      1.1  christos {
    689      1.1  christos     BIO *m;
    690      1.1  christos     int ret = 0, rv;
    691      1.1  christos     char *pp;
    692      1.1  christos     const char *readable;
    693      1.1  christos 
    694      1.1  christos     if (!TEST_ptr(m = BIO_new(BIO_s_mem())))
    695      1.1  christos         goto err;
    696      1.1  christos 
    697      1.1  christos     rv = ASN1_TIME_print_ex(m, &x509_print_tests_rfc_822[idx].asn1, ASN1_DTFLGS_RFC822);
    698      1.1  christos     readable = x509_print_tests_rfc_822[idx].readable;
    699      1.1  christos 
    700      1.1  christos     if (rv == 0 && !TEST_str_eq(readable, "Bad time value")) {
    701      1.1  christos         /* only if the test case intends to fail... */
    702      1.1  christos         goto err;
    703      1.1  christos     }
    704      1.1  christos     if (!TEST_int_ne(rv = BIO_get_mem_data(m, &pp), 0)
    705      1.1  christos         || !TEST_int_eq(rv, (int)strlen(readable))
    706      1.1  christos         || !TEST_strn_eq(pp, readable, rv))
    707      1.1  christos         goto err;
    708      1.1  christos 
    709      1.1  christos     ret = 1;
    710  1.1.1.2  christos err:
    711      1.1  christos     BIO_free(m);
    712      1.1  christos     return ret;
    713      1.1  christos }
    714      1.1  christos 
    715      1.1  christos static int test_x509_time_print_iso_8601(int idx)
    716      1.1  christos {
    717      1.1  christos     BIO *m;
    718      1.1  christos     int ret = 0, rv;
    719      1.1  christos     char *pp;
    720      1.1  christos     const char *readable;
    721      1.1  christos 
    722      1.1  christos     if (!TEST_ptr(m = BIO_new(BIO_s_mem())))
    723      1.1  christos         goto err;
    724      1.1  christos 
    725      1.1  christos     rv = ASN1_TIME_print_ex(m, &x509_print_tests_iso_8601[idx].asn1, ASN1_DTFLGS_ISO8601);
    726      1.1  christos     readable = x509_print_tests_iso_8601[idx].readable;
    727      1.1  christos 
    728      1.1  christos     if (rv == 0 && !TEST_str_eq(readable, "Bad time value")) {
    729      1.1  christos         /* only if the test case intends to fail... */
    730      1.1  christos         goto err;
    731      1.1  christos     }
    732      1.1  christos     if (!TEST_int_ne(rv = BIO_get_mem_data(m, &pp), 0)
    733      1.1  christos         || !TEST_int_eq(rv, (int)strlen(readable))
    734      1.1  christos         || !TEST_strn_eq(pp, readable, rv))
    735      1.1  christos         goto err;
    736      1.1  christos 
    737      1.1  christos     ret = 1;
    738  1.1.1.2  christos err:
    739      1.1  christos     BIO_free(m);
    740      1.1  christos     return ret;
    741      1.1  christos }
    742      1.1  christos 
    743      1.1  christos int setup_tests(void)
    744      1.1  christos {
    745      1.1  christos     ADD_TEST(test_x509_cmp_time_current);
    746      1.1  christos     ADD_TEST(test_X509_cmp_timeframe);
    747      1.1  christos     ADD_ALL_TESTS(test_x509_cmp_time, OSSL_NELEM(x509_cmp_tests));
    748      1.1  christos     ADD_ALL_TESTS(test_x509_time, OSSL_NELEM(x509_format_tests));
    749      1.1  christos     ADD_ALL_TESTS(test_days, OSSL_NELEM(day_of_week_tests));
    750      1.1  christos     ADD_ALL_TESTS(test_x509_time_print_rfc_822, OSSL_NELEM(x509_print_tests_rfc_822));
    751      1.1  christos     ADD_ALL_TESTS(test_x509_time_print_iso_8601, OSSL_NELEM(x509_print_tests_iso_8601));
    752      1.1  christos     return 1;
    753      1.1  christos }
    754