Home | History | Annotate | Line # | Download | only in test
      1 /*
      2  * Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the OpenSSL license (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 #include <string.h>
     11 
     12 #include <openssl/e_os2.h>
     13 #include <openssl/x509.h>
     14 #include <openssl/x509v3.h>
     15 #include "internal/nelem.h"
     16 #include "testutil.h"
     17 
     18 #ifdef OPENSSL_SYS_WINDOWS
     19 # define strcasecmp _stricmp
     20 #endif
     21 
     22 static const char *const names[] = {
     23     "a", "b", ".", "*", "@",
     24     ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
     25     "-example.com", "example-.com",
     26     "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
     27     "*@example.com", "test@*.example.com", "example.com", "www.example.com",
     28     "test.www.example.com", "*.example.com", "*.www.example.com",
     29     "test.*.example.com", "www.*.com",
     30     ".www.example.com", "*www.example.com",
     31     "example.net", "xn--rger-koa.example.com",
     32     "*.xn--rger-koa.example.com", "www.xn--rger-koa.example.com",
     33     "*.good--example.com", "www.good--example.com",
     34     "*.xn--bar.com", "xn--foo.xn--bar.com",
     35     "a.example.com", "b.example.com",
     36     "postmaster (at) example.com", "Postmaster (at) example.com",
     37     "postmaster (at) EXAMPLE.COM",
     38     NULL
     39 };
     40 
     41 static const char *const exceptions[] = {
     42     "set CN: host: [*.example.com] matches [a.example.com]",
     43     "set CN: host: [*.example.com] matches [b.example.com]",
     44     "set CN: host: [*.example.com] matches [www.example.com]",
     45     "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
     46     "set CN: host: [*.www.example.com] matches [test.www.example.com]",
     47     "set CN: host: [*.www.example.com] matches [.www.example.com]",
     48     "set CN: host: [*www.example.com] matches [www.example.com]",
     49     "set CN: host: [test.www.example.com] matches [.www.example.com]",
     50     "set CN: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
     51     "set CN: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
     52     "set CN: host: [*.good--example.com] matches [www.good--example.com]",
     53     "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
     54     "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
     55     "set emailAddress: email: [postmaster (at) example.com] does not match [Postmaster (at) example.com]",
     56     "set emailAddress: email: [postmaster (at) EXAMPLE.COM] does not match [Postmaster (at) example.com]",
     57     "set emailAddress: email: [Postmaster (at) example.com] does not match [postmaster (at) example.com]",
     58     "set emailAddress: email: [Postmaster (at) example.com] does not match [postmaster (at) EXAMPLE.COM]",
     59     "set dnsName: host: [*.example.com] matches [www.example.com]",
     60     "set dnsName: host: [*.example.com] matches [a.example.com]",
     61     "set dnsName: host: [*.example.com] matches [b.example.com]",
     62     "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
     63     "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
     64     "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
     65     "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
     66     "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
     67     "set dnsName: host: [*www.example.com] matches [www.example.com]",
     68     "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
     69     "set dnsName: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
     70     "set dnsName: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
     71     "set dnsName: host: [*.good--example.com] matches [www.good--example.com]",
     72     "set rfc822Name: email: [postmaster (at) example.com] does not match [Postmaster (at) example.com]",
     73     "set rfc822Name: email: [Postmaster (at) example.com] does not match [postmaster (at) example.com]",
     74     "set rfc822Name: email: [Postmaster (at) example.com] does not match [postmaster (at) EXAMPLE.COM]",
     75     "set rfc822Name: email: [postmaster (at) EXAMPLE.COM] does not match [Postmaster (at) example.com]",
     76     NULL
     77 };
     78 
     79 static int is_exception(const char *msg)
     80 {
     81     const char *const *p;
     82 
     83     for (p = exceptions; *p; ++p)
     84         if (strcmp(msg, *p) == 0)
     85             return 1;
     86     return 0;
     87 }
     88 
     89 static int set_cn(X509 *crt, ...)
     90 {
     91     int ret = 0;
     92     X509_NAME *n = NULL;
     93     va_list ap;
     94 
     95     va_start(ap, crt);
     96     n = X509_NAME_new();
     97     if (n == NULL)
     98         goto out;
     99 
    100     while (1) {
    101         int nid;
    102         const char *name;
    103 
    104         nid = va_arg(ap, int);
    105         if (nid == 0)
    106             break;
    107         name = va_arg(ap, const char *);
    108         if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
    109                                         (unsigned char *)name, -1, -1, 1))
    110             goto out;
    111     }
    112     if (!X509_set_subject_name(crt, n))
    113         goto out;
    114     ret = 1;
    115  out:
    116     X509_NAME_free(n);
    117     va_end(ap);
    118     return ret;
    119 }
    120 
    121 /*-
    122 int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
    123 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
    124                         int nid, int crit, ASN1_OCTET_STRING *data);
    125 int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
    126 */
    127 
    128 static int set_altname(X509 *crt, ...)
    129 {
    130     int ret = 0;
    131     GENERAL_NAMES *gens = NULL;
    132     GENERAL_NAME *gen = NULL;
    133     ASN1_IA5STRING *ia5 = NULL;
    134     va_list ap;
    135     va_start(ap, crt);
    136     gens = sk_GENERAL_NAME_new_null();
    137     if (gens == NULL)
    138         goto out;
    139     while (1) {
    140         int type;
    141         const char *name;
    142         type = va_arg(ap, int);
    143         if (type == 0)
    144             break;
    145         name = va_arg(ap, const char *);
    146 
    147         gen = GENERAL_NAME_new();
    148         if (gen == NULL)
    149             goto out;
    150         ia5 = ASN1_IA5STRING_new();
    151         if (ia5 == NULL)
    152             goto out;
    153         if (!ASN1_STRING_set(ia5, name, -1))
    154             goto out;
    155         switch (type) {
    156         case GEN_EMAIL:
    157         case GEN_DNS:
    158             GENERAL_NAME_set0_value(gen, type, ia5);
    159             ia5 = NULL;
    160             break;
    161         default:
    162             abort();
    163         }
    164         sk_GENERAL_NAME_push(gens, gen);
    165         gen = NULL;
    166     }
    167     if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
    168         goto out;
    169     ret = 1;
    170  out:
    171     ASN1_IA5STRING_free(ia5);
    172     GENERAL_NAME_free(gen);
    173     GENERAL_NAMES_free(gens);
    174     va_end(ap);
    175     return ret;
    176 }
    177 
    178 static int set_cn1(X509 *crt, const char *name)
    179 {
    180     return set_cn(crt, NID_commonName, name, 0);
    181 }
    182 
    183 static int set_cn_and_email(X509 *crt, const char *name)
    184 {
    185     return set_cn(crt, NID_commonName, name,
    186                   NID_pkcs9_emailAddress, "dummy (at) example.com", 0);
    187 }
    188 
    189 static int set_cn2(X509 *crt, const char *name)
    190 {
    191     return set_cn(crt, NID_commonName, "dummy value",
    192                   NID_commonName, name, 0);
    193 }
    194 
    195 static int set_cn3(X509 *crt, const char *name)
    196 {
    197     return set_cn(crt, NID_commonName, name,
    198                   NID_commonName, "dummy value", 0);
    199 }
    200 
    201 static int set_email1(X509 *crt, const char *name)
    202 {
    203     return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
    204 }
    205 
    206 static int set_email2(X509 *crt, const char *name)
    207 {
    208     return set_cn(crt, NID_pkcs9_emailAddress, "dummy (at) example.com",
    209                   NID_pkcs9_emailAddress, name, 0);
    210 }
    211 
    212 static int set_email3(X509 *crt, const char *name)
    213 {
    214     return set_cn(crt, NID_pkcs9_emailAddress, name,
    215                   NID_pkcs9_emailAddress, "dummy (at) example.com", 0);
    216 }
    217 
    218 static int set_email_and_cn(X509 *crt, const char *name)
    219 {
    220     return set_cn(crt, NID_pkcs9_emailAddress, name,
    221                   NID_commonName, "www.example.org", 0);
    222 }
    223 
    224 static int set_altname_dns(X509 *crt, const char *name)
    225 {
    226     return set_altname(crt, GEN_DNS, name, 0);
    227 }
    228 
    229 static int set_altname_email(X509 *crt, const char *name)
    230 {
    231     return set_altname(crt, GEN_EMAIL, name, 0);
    232 }
    233 
    234 struct set_name_fn {
    235     int (*fn) (X509 *, const char *);
    236     const char *name;
    237     int host;
    238     int email;
    239 };
    240 
    241 static const struct set_name_fn name_fns[] = {
    242     {set_cn1, "set CN", 1, 0},
    243     {set_cn2, "set CN", 1, 0},
    244     {set_cn3, "set CN", 1, 0},
    245     {set_cn_and_email, "set CN", 1, 0},
    246     {set_email1, "set emailAddress", 0, 1},
    247     {set_email2, "set emailAddress", 0, 1},
    248     {set_email3, "set emailAddress", 0, 1},
    249     {set_email_and_cn, "set emailAddress", 0, 1},
    250     {set_altname_dns, "set dnsName", 1, 0},
    251     {set_altname_email, "set rfc822Name", 0, 1},
    252 };
    253 
    254 static X509 *make_cert(void)
    255 {
    256     X509 *crt = NULL;
    257 
    258     if (!TEST_ptr(crt = X509_new()))
    259         return NULL;
    260     if (!TEST_true(X509_set_version(crt, 2))) {
    261         X509_free(crt);
    262         return NULL;
    263     }
    264     return crt;
    265 }
    266 
    267 static int check_message(const struct set_name_fn *fn, const char *op,
    268                          const char *nameincert, int match, const char *name)
    269 {
    270     char msg[1024];
    271 
    272     if (match < 0)
    273         return 1;
    274     BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
    275                  fn->name, op, nameincert,
    276                  match ? "matches" : "does not match", name);
    277     if (is_exception(msg))
    278         return 1;
    279     TEST_error("%s", msg);
    280     return 0;
    281 }
    282 
    283 static int run_cert(X509 *crt, const char *nameincert,
    284                      const struct set_name_fn *fn)
    285 {
    286     const char *const *pname = names;
    287     int failed = 0;
    288 
    289     for (; *pname != NULL; ++pname) {
    290         int samename = strcasecmp(nameincert, *pname) == 0;
    291         size_t namelen = strlen(*pname);
    292         char *name = OPENSSL_malloc(namelen);
    293         int match, ret;
    294 
    295         memcpy(name, *pname, namelen);
    296 
    297         match = -1;
    298         if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen, 0, NULL),
    299                          0)) {
    300             failed = 1;
    301         } else if (fn->host) {
    302             if (ret == 1 && !samename)
    303                 match = 1;
    304             if (ret == 0 && samename)
    305                 match = 0;
    306         } else if (ret == 1)
    307             match = 1;
    308         if (!TEST_true(check_message(fn, "host", nameincert, match, *pname)))
    309             failed = 1;
    310 
    311         match = -1;
    312         if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen,
    313                                                X509_CHECK_FLAG_NO_WILDCARDS,
    314                                                NULL), 0)) {
    315             failed = 1;
    316         } else if (fn->host) {
    317             if (ret == 1 && !samename)
    318                 match = 1;
    319             if (ret == 0 && samename)
    320                 match = 0;
    321         } else if (ret == 1)
    322             match = 1;
    323         if (!TEST_true(check_message(fn, "host-no-wildcards",
    324                                      nameincert, match, *pname)))
    325             failed = 1;
    326 
    327         match = -1;
    328         ret = X509_check_email(crt, name, namelen, 0);
    329         if (fn->email) {
    330             if (ret && !samename)
    331                 match = 1;
    332             if (!ret && samename && strchr(nameincert, '@') != NULL)
    333                 match = 0;
    334         } else if (ret)
    335             match = 1;
    336         if (!TEST_true(check_message(fn, "email", nameincert, match, *pname)))
    337             failed = 1;
    338         OPENSSL_free(name);
    339     }
    340 
    341     return failed == 0;
    342 }
    343 
    344 static int call_run_cert(int i)
    345 {
    346     int failed = 0;
    347     const struct set_name_fn *pfn = &name_fns[i];
    348     X509 *crt;
    349     const char *const *pname;
    350 
    351     TEST_info("%s", pfn->name);
    352     for (pname = names; *pname != NULL; pname++) {
    353         if (!TEST_ptr(crt = make_cert())
    354              || !TEST_true(pfn->fn(crt, *pname))
    355              || !run_cert(crt, *pname, pfn))
    356             failed = 1;
    357         X509_free(crt);
    358     }
    359     return failed == 0;
    360 }
    361 
    362 static struct gennamedata {
    363     const unsigned char der[22];
    364     size_t derlen;
    365 } gennames[] = {
    366     {
    367         /*
    368         * [0] {
    369         *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
    370         *   [0] {
    371         *     SEQUENCE {}
    372         *   }
    373         * }
    374         */
    375         {
    376             0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
    377             0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x30, 0x00
    378         },
    379         21
    380     }, {
    381         /*
    382         * [0] {
    383         *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
    384         *   [0] {
    385         *     [APPLICATION 0] {}
    386         *   }
    387         * }
    388         */
    389         {
    390             0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
    391             0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x60, 0x00
    392         },
    393         21
    394     }, {
    395         /*
    396         * [0] {
    397         *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
    398         *   [0] {
    399         *     UTF8String { "a" }
    400         *   }
    401         * }
    402         */
    403         {
    404             0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
    405             0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x61
    406         },
    407         22
    408     }, {
    409         /*
    410         * [0] {
    411         *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.2 }
    412         *   [0] {
    413         *     UTF8String { "a" }
    414         *   }
    415         * }
    416         */
    417         {
    418             0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
    419             0x01, 0x84, 0xb7, 0x09, 0x02, 0x02, 0xa0, 0x03, 0x0c, 0x01, 0x61
    420         },
    421         22
    422     }, {
    423         /*
    424         * [0] {
    425         *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
    426         *   [0] {
    427         *     UTF8String { "b" }
    428         *   }
    429         * }
    430         */
    431         {
    432             0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
    433             0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x62
    434         },
    435         22
    436     }, {
    437         /*
    438         * [0] {
    439         *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
    440         *   [0] {
    441         *     BOOLEAN { TRUE }
    442         *   }
    443         * }
    444         */
    445         {
    446             0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
    447             0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0xff
    448         },
    449         22
    450     }, {
    451         /*
    452         * [0] {
    453         *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
    454         *   [0] {
    455         *     BOOLEAN { FALSE }
    456         *   }
    457         * }
    458         */
    459         {
    460             0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
    461             0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0x00
    462         },
    463         22
    464     }, {
    465         /* [1 PRIMITIVE] { "a" } */
    466         {
    467             0x81, 0x01, 0x61
    468         },
    469         3
    470     }, {
    471         /* [1 PRIMITIVE] { "b" } */
    472         {
    473             0x81, 0x01, 0x62
    474         },
    475         3
    476     }, {
    477         /* [2 PRIMITIVE] { "a" } */
    478         {
    479             0x82, 0x01, 0x61
    480         },
    481         3
    482     }, {
    483         /* [2 PRIMITIVE] { "b" } */
    484         {
    485             0x82, 0x01, 0x62
    486         },
    487         3
    488     }, {
    489         /*
    490         * [4] {
    491         *   SEQUENCE {
    492         *     SET {
    493         *       SEQUENCE {
    494         *         # commonName
    495         *         OBJECT_IDENTIFIER { 2.5.4.3 }
    496         *         UTF8String { "a" }
    497         *       }
    498         *     }
    499         *   }
    500         * }
    501         */
    502         {
    503             0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
    504             0x04, 0x03, 0x0c, 0x01, 0x61
    505         },
    506         16
    507     }, {
    508         /*
    509         * [4] {
    510         *   SEQUENCE {
    511         *     SET {
    512         *       SEQUENCE {
    513         *         # commonName
    514         *         OBJECT_IDENTIFIER { 2.5.4.3 }
    515         *         UTF8String { "b" }
    516         *       }
    517         *     }
    518         *   }
    519         * }
    520         */
    521         {
    522             0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
    523             0x04, 0x03, 0x0c, 0x01, 0x62
    524         },
    525         16
    526     }, {
    527         /*
    528         * [5] {
    529         *   [1] {
    530         *     UTF8String { "a" }
    531         *   }
    532         * }
    533         */
    534         {
    535             0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x61
    536         },
    537         7
    538     }, {
    539         /*
    540         * [5] {
    541         *   [1] {
    542         *     UTF8String { "b" }
    543         *   }
    544         * }
    545         */
    546         {
    547             0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x62
    548         },
    549         7
    550     }, {
    551         /*
    552         * [5] {
    553         *   [0] {
    554         *     UTF8String {}
    555         *   }
    556         *   [1] {
    557         *     UTF8String { "a" }
    558         *   }
    559         * }
    560         */
    561         {
    562             0xa5, 0x09, 0xa0, 0x02, 0x0c, 0x00, 0xa1, 0x03, 0x0c, 0x01, 0x61
    563         },
    564         11
    565     }, {
    566         /*
    567         * [5] {
    568         *   [0] {
    569         *     UTF8String { "a" }
    570         *   }
    571         *   [1] {
    572         *     UTF8String { "a" }
    573         *   }
    574         * }
    575         */
    576         {
    577             0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x61, 0xa1, 0x03, 0x0c, 0x01,
    578             0x61
    579         },
    580         12
    581     }, {
    582         /*
    583         * [5] {
    584         *   [0] {
    585         *     UTF8String { "b" }
    586         *   }
    587         *   [1] {
    588         *     UTF8String { "a" }
    589         *   }
    590         * }
    591         */
    592         {
    593             0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x62, 0xa1, 0x03, 0x0c, 0x01,
    594             0x61
    595         },
    596         12
    597     }, {
    598         /* [6 PRIMITIVE] { "a" } */
    599         {
    600             0x86, 0x01, 0x61
    601         },
    602         3
    603     }, {
    604         /* [6 PRIMITIVE] { "b" } */
    605         {
    606             0x86, 0x01, 0x62
    607         },
    608         3
    609     }, {
    610         /* [7 PRIMITIVE] { `11111111` } */
    611         {
    612             0x87, 0x04, 0x11, 0x11, 0x11, 0x11
    613         },
    614         6
    615     }, {
    616         /* [7 PRIMITIVE] { `22222222`} */
    617         {
    618             0x87, 0x04, 0x22, 0x22, 0x22, 0x22
    619         },
    620         6
    621     }, {
    622         /* [7 PRIMITIVE] { `11111111111111111111111111111111` } */
    623         {
    624             0x87, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
    625             0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
    626         },
    627         18
    628     }, {
    629         /* [7 PRIMITIVE] { `22222222222222222222222222222222` } */
    630         {
    631             0x87, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
    632             0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22
    633         },
    634         18
    635     }, {
    636         /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.1 } */
    637         {
    638             0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
    639             0xb7, 0x09, 0x02, 0x01
    640         },
    641         15
    642     }, {
    643         /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.2 } */
    644         {
    645             0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
    646             0xb7, 0x09, 0x02, 0x02
    647         },
    648         15
    649     }, {
    650         /*
    651          * Regression test for CVE-2023-0286.
    652          */
    653         {
    654             0xa3, 0x00
    655         },
    656         2
    657     }
    658 };
    659 
    660 static int test_GENERAL_NAME_cmp(void)
    661 {
    662     size_t i, j;
    663     GENERAL_NAME **namesa = OPENSSL_malloc(sizeof(*namesa)
    664                                            * OSSL_NELEM(gennames));
    665     GENERAL_NAME **namesb = OPENSSL_malloc(sizeof(*namesb)
    666                                            * OSSL_NELEM(gennames));
    667     int testresult = 0;
    668 
    669     if (!TEST_ptr(namesa) || !TEST_ptr(namesb))
    670         goto end;
    671 
    672     for (i = 0; i < OSSL_NELEM(gennames); i++) {
    673         const unsigned char *derp = gennames[i].der;
    674 
    675         /*
    676          * We create two versions of each GENERAL_NAME so that we ensure when
    677          * we compare them they are always different pointers.
    678          */
    679         namesa[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
    680         derp = gennames[i].der;
    681         namesb[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
    682         if (!TEST_ptr(namesa[i]) || !TEST_ptr(namesb[i]))
    683             goto end;
    684     }
    685 
    686     /* Every name should be equal to itself and not equal to any others. */
    687     for (i = 0; i < OSSL_NELEM(gennames); i++) {
    688         for (j = 0; j < OSSL_NELEM(gennames); j++) {
    689             if (i == j) {
    690                 if (!TEST_int_eq(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
    691                     goto end;
    692             } else {
    693                 if (!TEST_int_ne(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
    694                     goto end;
    695             }
    696         }
    697     }
    698     testresult = 1;
    699 
    700  end:
    701     for (i = 0; i < OSSL_NELEM(gennames); i++) {
    702         if (namesa != NULL)
    703             GENERAL_NAME_free(namesa[i]);
    704         if (namesb != NULL)
    705             GENERAL_NAME_free(namesb[i]);
    706     }
    707     OPENSSL_free(namesa);
    708     OPENSSL_free(namesb);
    709 
    710     return testresult;
    711 }
    712 
    713 int setup_tests(void)
    714 {
    715     ADD_ALL_TESTS(call_run_cert, OSSL_NELEM(name_fns));
    716     ADD_TEST(test_GENERAL_NAME_cmp);
    717     return 1;
    718 }
    719