2 * Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved.
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
12 #include <openssl/e_os2.h>
13 #include <openssl/x509.h>
14 #include <openssl/x509v3.h>
15 #include "internal/nelem.h"
18 static 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",
37 static 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]",
75 static int is_exception(const char *msg)
79 for (p = exceptions; *p; ++p)
80 if (strcmp(msg, *p) == 0)
85 static int set_cn(X509 *crt, ...)
100 nid = va_arg(ap, int);
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))
108 if (!X509_set_subject_name(crt, n))
118 int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
119 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
120 int nid, int crit, ASN1_OCTET_STRING *data);
121 int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
124 static int set_altname(X509 *crt, ...)
127 GENERAL_NAMES *gens = NULL;
128 GENERAL_NAME *gen = NULL;
129 ASN1_IA5STRING *ia5 = NULL;
132 gens = sk_GENERAL_NAME_new_null();
138 type = va_arg(ap, int);
141 name = va_arg(ap, const char *);
143 gen = GENERAL_NAME_new();
146 ia5 = ASN1_IA5STRING_new();
149 if (!ASN1_STRING_set(ia5, name, -1))
154 GENERAL_NAME_set0_value(gen, type, ia5);
160 sk_GENERAL_NAME_push(gens, gen);
163 if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
167 ASN1_IA5STRING_free(ia5);
168 GENERAL_NAME_free(gen);
169 GENERAL_NAMES_free(gens);
174 static int set_cn1(X509 *crt, const char *name)
176 return set_cn(crt, NID_commonName, name, 0);
179 static int set_cn_and_email(X509 *crt, const char *name)
181 return set_cn(crt, NID_commonName, name,
182 NID_pkcs9_emailAddress, "dummy@example.com", 0);
185 static int set_cn2(X509 *crt, const char *name)
187 return set_cn(crt, NID_commonName, "dummy value",
188 NID_commonName, name, 0);
191 static int set_cn3(X509 *crt, const char *name)
193 return set_cn(crt, NID_commonName, name,
194 NID_commonName, "dummy value", 0);
197 static int set_email1(X509 *crt, const char *name)
199 return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
202 static int set_email2(X509 *crt, const char *name)
204 return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
205 NID_pkcs9_emailAddress, name, 0);
208 static int set_email3(X509 *crt, const char *name)
210 return set_cn(crt, NID_pkcs9_emailAddress, name,
211 NID_pkcs9_emailAddress, "dummy@example.com", 0);
214 static int set_email_and_cn(X509 *crt, const char *name)
216 return set_cn(crt, NID_pkcs9_emailAddress, name,
217 NID_commonName, "www.example.org", 0);
220 static int set_altname_dns(X509 *crt, const char *name)
222 return set_altname(crt, GEN_DNS, name, 0);
225 static int set_altname_email(X509 *crt, const char *name)
227 return set_altname(crt, GEN_EMAIL, name, 0);
231 int (*fn) (X509 *, const char *);
237 static 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},
250 static X509 *make_cert(void)
254 if (!TEST_ptr(crt = X509_new()))
256 if (!TEST_true(X509_set_version(crt, X509_VERSION_3))) {
263 static int check_message(const struct set_name_fn *fn, const char *op,
264 const char *nameincert, int match, const char *name)
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))
275 TEST_error("%s", msg);
279 static int run_cert(X509 *crt, const char *nameincert,
280 const struct set_name_fn *fn)
282 const char *const *pname = names;
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);
291 memcpy(name, *pname, namelen + 1);
294 if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen, 0, NULL),
297 } else if (fn->host) {
298 if (ret == 1 && !samename)
300 if (ret == 0 && samename)
304 if (!TEST_true(check_message(fn, "host", nameincert, match, *pname)))
308 if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen,
309 X509_CHECK_FLAG_NO_WILDCARDS,
312 } else if (fn->host) {
313 if (ret == 1 && !samename)
315 if (ret == 0 && samename)
319 if (!TEST_true(check_message(fn, "host-no-wildcards",
320 nameincert, match, *pname)))
324 ret = X509_check_email(crt, name, namelen, 0);
326 if (ret && !samename)
328 if (!ret && samename && strchr(nameincert, '@') != NULL)
332 if (!TEST_true(check_message(fn, "email", nameincert, match, *pname)))
340 static int call_run_cert(int i)
343 const struct set_name_fn *pfn = &name_fns[i];
345 const char *const *pname;
347 TEST_info("%s", pfn->name);
348 for (pname = names; *pname != NULL; pname++) {
349 if (!TEST_ptr(crt = make_cert())
350 || !TEST_true(pfn->fn(crt, *pname))
351 || !run_cert(crt, *pname, pfn))
358 static struct gennamedata {
359 const unsigned char der[22];
365 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
372 0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
373 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x30, 0x00
379 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
386 0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
387 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x60, 0x00
393 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
400 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
401 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x61
407 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.2 }
414 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
415 0x01, 0x84, 0xb7, 0x09, 0x02, 0x02, 0xa0, 0x03, 0x0c, 0x01, 0x61
421 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
428 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
429 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x62
435 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
442 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
443 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0xff
449 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
456 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
457 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0x00
461 /* [1 PRIMITIVE] { "a" } */
467 /* [1 PRIMITIVE] { "b" } */
473 /* [2 PRIMITIVE] { "a" } */
479 /* [2 PRIMITIVE] { "b" } */
491 * OBJECT_IDENTIFIER { 2.5.4.3 }
499 0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
500 0x04, 0x03, 0x0c, 0x01, 0x61
510 * OBJECT_IDENTIFIER { 2.5.4.3 }
518 0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
519 0x04, 0x03, 0x0c, 0x01, 0x62
531 0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x61
543 0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x62
558 0xa5, 0x09, 0xa0, 0x02, 0x0c, 0x00, 0xa1, 0x03, 0x0c, 0x01, 0x61
573 0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x61, 0xa1, 0x03, 0x0c, 0x01,
589 0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x62, 0xa1, 0x03, 0x0c, 0x01,
594 /* [6 PRIMITIVE] { "a" } */
600 /* [6 PRIMITIVE] { "b" } */
606 /* [7 PRIMITIVE] { `11111111` } */
608 0x87, 0x04, 0x11, 0x11, 0x11, 0x11
612 /* [7 PRIMITIVE] { `22222222`} */
614 0x87, 0x04, 0x22, 0x22, 0x22, 0x22
618 /* [7 PRIMITIVE] { `11111111111111111111111111111111` } */
620 0x87, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
621 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
625 /* [7 PRIMITIVE] { `22222222222222222222222222222222` } */
627 0x87, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
628 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22
632 /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.1 } */
634 0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
635 0xb7, 0x09, 0x02, 0x01
639 /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.2 } */
641 0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
642 0xb7, 0x09, 0x02, 0x02
648 static int test_GENERAL_NAME_cmp(void)
651 GENERAL_NAME **namesa = OPENSSL_malloc(sizeof(*namesa)
652 * OSSL_NELEM(gennames));
653 GENERAL_NAME **namesb = OPENSSL_malloc(sizeof(*namesb)
654 * OSSL_NELEM(gennames));
657 if (!TEST_ptr(namesa) || !TEST_ptr(namesb))
660 for (i = 0; i < OSSL_NELEM(gennames); i++) {
661 const unsigned char *derp = gennames[i].der;
664 * We create two versions of each GENERAL_NAME so that we ensure when
665 * we compare them they are always different pointers.
667 namesa[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
668 derp = gennames[i].der;
669 namesb[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
670 if (!TEST_ptr(namesa[i]) || !TEST_ptr(namesb[i]))
674 /* Every name should be equal to itself and not equal to any others. */
675 for (i = 0; i < OSSL_NELEM(gennames); i++) {
676 for (j = 0; j < OSSL_NELEM(gennames); j++) {
678 if (!TEST_int_eq(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
681 if (!TEST_int_ne(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
689 for (i = 0; i < OSSL_NELEM(gennames); i++) {
691 GENERAL_NAME_free(namesa[i]);
693 GENERAL_NAME_free(namesb[i]);
695 OPENSSL_free(namesa);
696 OPENSSL_free(namesb);
701 int setup_tests(void)
703 ADD_ALL_TESTS(call_run_cert, OSSL_NELEM(name_fns));
704 ADD_TEST(test_GENERAL_NAME_cmp);