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