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