2 * Copyright 2012-2020 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 #ifdef OPENSSL_SYS_WINDOWS
19 # define strcasecmp _stricmp
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@example.com", "Postmaster@example.com",
37 "postmaster@EXAMPLE.COM",
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@example.com] does not match [Postmaster@example.com]",
56 "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
57 "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
58 "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@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@example.com] does not match [Postmaster@example.com]",
73 "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
74 "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
75 "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
79 static int is_exception(const char *msg)
83 for (p = exceptions; *p; ++p)
84 if (strcmp(msg, *p) == 0)
89 static int set_cn(X509 *crt, ...)
104 nid = va_arg(ap, int);
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))
112 if (!X509_set_subject_name(crt, n))
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);
128 static int set_altname(X509 *crt, ...)
131 GENERAL_NAMES *gens = NULL;
132 GENERAL_NAME *gen = NULL;
133 ASN1_IA5STRING *ia5 = NULL;
136 gens = sk_GENERAL_NAME_new_null();
142 type = va_arg(ap, int);
145 name = va_arg(ap, const char *);
147 gen = GENERAL_NAME_new();
150 ia5 = ASN1_IA5STRING_new();
153 if (!ASN1_STRING_set(ia5, name, -1))
158 GENERAL_NAME_set0_value(gen, type, ia5);
164 sk_GENERAL_NAME_push(gens, gen);
167 if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
171 ASN1_IA5STRING_free(ia5);
172 GENERAL_NAME_free(gen);
173 GENERAL_NAMES_free(gens);
178 static int set_cn1(X509 *crt, const char *name)
180 return set_cn(crt, NID_commonName, name, 0);
183 static int set_cn_and_email(X509 *crt, const char *name)
185 return set_cn(crt, NID_commonName, name,
186 NID_pkcs9_emailAddress, "dummy@example.com", 0);
189 static int set_cn2(X509 *crt, const char *name)
191 return set_cn(crt, NID_commonName, "dummy value",
192 NID_commonName, name, 0);
195 static int set_cn3(X509 *crt, const char *name)
197 return set_cn(crt, NID_commonName, name,
198 NID_commonName, "dummy value", 0);
201 static int set_email1(X509 *crt, const char *name)
203 return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
206 static int set_email2(X509 *crt, const char *name)
208 return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
209 NID_pkcs9_emailAddress, name, 0);
212 static int set_email3(X509 *crt, const char *name)
214 return set_cn(crt, NID_pkcs9_emailAddress, name,
215 NID_pkcs9_emailAddress, "dummy@example.com", 0);
218 static int set_email_and_cn(X509 *crt, const char *name)
220 return set_cn(crt, NID_pkcs9_emailAddress, name,
221 NID_commonName, "www.example.org", 0);
224 static int set_altname_dns(X509 *crt, const char *name)
226 return set_altname(crt, GEN_DNS, name, 0);
229 static int set_altname_email(X509 *crt, const char *name)
231 return set_altname(crt, GEN_EMAIL, name, 0);
235 int (*fn) (X509 *, const char *);
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},
254 static X509 *make_cert(void)
258 if (!TEST_ptr(crt = X509_new()))
260 if (!TEST_true(X509_set_version(crt, 2))) {
267 static int check_message(const struct set_name_fn *fn, const char *op,
268 const char *nameincert, int match, const char *name)
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))
279 TEST_error("%s", msg);
283 static int run_cert(X509 *crt, const char *nameincert,
284 const struct set_name_fn *fn)
286 const char *const *pname = names;
289 for (; *pname != NULL; ++pname) {
290 int samename = strcasecmp(nameincert, *pname) == 0;
291 size_t namelen = strlen(*pname);
292 char *name = OPENSSL_malloc(namelen + 1);
295 memcpy(name, *pname, namelen + 1);
298 if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen, 0, NULL),
301 } else if (fn->host) {
302 if (ret == 1 && !samename)
304 if (ret == 0 && samename)
308 if (!TEST_true(check_message(fn, "host", nameincert, match, *pname)))
312 if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen,
313 X509_CHECK_FLAG_NO_WILDCARDS,
316 } else if (fn->host) {
317 if (ret == 1 && !samename)
319 if (ret == 0 && samename)
323 if (!TEST_true(check_message(fn, "host-no-wildcards",
324 nameincert, match, *pname)))
328 ret = X509_check_email(crt, name, namelen, 0);
330 if (ret && !samename)
332 if (!ret && samename && strchr(nameincert, '@') != NULL)
336 if (!TEST_true(check_message(fn, "email", nameincert, match, *pname)))
344 static int call_run_cert(int i)
347 const struct set_name_fn *pfn = &name_fns[i];
349 const char *const *pname;
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))
362 static struct gennamedata {
363 const unsigned char der[22];
369 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
376 0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
377 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x30, 0x00
383 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
390 0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
391 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x60, 0x00
397 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
404 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
405 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x61
411 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.2 }
418 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
419 0x01, 0x84, 0xb7, 0x09, 0x02, 0x02, 0xa0, 0x03, 0x0c, 0x01, 0x61
425 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
432 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
433 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x62
439 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
446 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
447 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0xff
453 * OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
460 0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
461 0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0x00
465 /* [1 PRIMITIVE] { "a" } */
471 /* [1 PRIMITIVE] { "b" } */
477 /* [2 PRIMITIVE] { "a" } */
483 /* [2 PRIMITIVE] { "b" } */
495 * OBJECT_IDENTIFIER { 2.5.4.3 }
503 0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
504 0x04, 0x03, 0x0c, 0x01, 0x61
514 * OBJECT_IDENTIFIER { 2.5.4.3 }
522 0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
523 0x04, 0x03, 0x0c, 0x01, 0x62
535 0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x61
547 0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x62
562 0xa5, 0x09, 0xa0, 0x02, 0x0c, 0x00, 0xa1, 0x03, 0x0c, 0x01, 0x61
577 0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x61, 0xa1, 0x03, 0x0c, 0x01,
593 0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x62, 0xa1, 0x03, 0x0c, 0x01,
598 /* [6 PRIMITIVE] { "a" } */
604 /* [6 PRIMITIVE] { "b" } */
610 /* [7 PRIMITIVE] { `11111111` } */
612 0x87, 0x04, 0x11, 0x11, 0x11, 0x11
616 /* [7 PRIMITIVE] { `22222222`} */
618 0x87, 0x04, 0x22, 0x22, 0x22, 0x22
622 /* [7 PRIMITIVE] { `11111111111111111111111111111111` } */
624 0x87, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
625 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
629 /* [7 PRIMITIVE] { `22222222222222222222222222222222` } */
631 0x87, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
632 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22
636 /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.1 } */
638 0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
639 0xb7, 0x09, 0x02, 0x01
643 /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.2 } */
645 0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
646 0xb7, 0x09, 0x02, 0x02
652 static int test_GENERAL_NAME_cmp(void)
655 GENERAL_NAME **namesa = OPENSSL_malloc(sizeof(*namesa)
656 * OSSL_NELEM(gennames));
657 GENERAL_NAME **namesb = OPENSSL_malloc(sizeof(*namesb)
658 * OSSL_NELEM(gennames));
661 if (!TEST_ptr(namesa) || !TEST_ptr(namesb))
664 for (i = 0; i < OSSL_NELEM(gennames); i++) {
665 const unsigned char *derp = gennames[i].der;
668 * We create two versions of each GENERAL_NAME so that we ensure when
669 * we compare them they are always different pointers.
671 namesa[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
672 derp = gennames[i].der;
673 namesb[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
674 if (!TEST_ptr(namesa[i]) || !TEST_ptr(namesb[i]))
678 /* Every name should be equal to itself and not equal to any others. */
679 for (i = 0; i < OSSL_NELEM(gennames); i++) {
680 for (j = 0; j < OSSL_NELEM(gennames); j++) {
682 if (!TEST_int_eq(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
685 if (!TEST_int_ne(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
693 for (i = 0; i < OSSL_NELEM(gennames); i++) {
695 GENERAL_NAME_free(namesa[i]);
697 GENERAL_NAME_free(namesb[i]);
699 OPENSSL_free(namesa);
700 OPENSSL_free(namesb);
705 int setup_tests(void)
707 ADD_ALL_TESTS(call_run_cert, OSSL_NELEM(name_fns));
708 ADD_TEST(test_GENERAL_NAME_cmp);