xref: /openbsd-src/regress/lib/libtls/verify/verifytest.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: verifytest.c,v 1.5 2015/09/11 13:10:42 beck Exp $	*/
2 /*
3  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <err.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include <openssl/x509v3.h>
23 #include <tls.h>
24 
25 extern int tls_check_name(struct tls *ctx, X509 *cert, const char *name);
26 
27 struct verify_test {
28 	const char common_name[128];
29 	const char alt_name[128];
30 	int alt_name_len;
31 	int alt_name_type;
32 	const char name[128];
33 	int want;
34 };
35 
36 struct verify_test verify_tests[] = {
37 	{
38 		.common_name = "www.openbsd.org",
39 		.name = "www.openbsd.org",
40 		.want = 0,
41 	},
42 	{
43 		.common_name = "www.openbsd.org",
44 		.name = "",
45 		.want = -1,
46 	},
47 	{
48 		.common_name = "*.openbsd.org",
49 		.name = "www.openbsd.org",
50 		.want = 0,
51 	},
52 	{
53 		.common_name = "www.openbsdfoundation.org",
54 		.name = "www.openbsd.org",
55 		.want = -1,
56 	},
57 	{
58 		.common_name = "w*.openbsd.org",
59 		.name = "www.openbsd.org",
60 		.want = -1,
61 	},
62 	{
63 		.common_name = "www.*.org",
64 		.name = "www.openbsd.org",
65 		.want = -1,
66 	},
67 	{
68 		.common_name = "www.openbsd.*",
69 		.name = "www.openbsd.org",
70 		.want = -1,
71 	},
72 	{
73 		.common_name = "*",
74 		.name = "www.openbsd.org",
75 		.want = -1,
76 	},
77 	{
78 		.common_name = "*.org",
79 		.name = "www.openbsd.org",
80 		.want = -1,
81 	},
82 	{
83 		.common_name = "*.org",
84 		.name = "openbsd.org",
85 		.want = -1,
86 	},
87 	{
88 		.common_name = "1.2.3.4",
89 		.name = "1.2.3.4",
90 		.want = 0,
91 	},
92 	{
93 		.common_name = "*.2.3.4",
94 		.name = "1.2.3.4",
95 		.want = -1,
96 	},
97 	{
98 		.common_name = "cafe::beef",
99 		.name = "cafe::beef",
100 		.want = 0,
101 	},
102 	{
103 		.common_name = "www.openbsd.org",
104 		.alt_name = "ftp.openbsd.org",
105 		.alt_name_len = -1,
106 		.alt_name_type = GEN_DNS,
107 		.name = "ftp.openbsd.org",
108 		.want = 0,
109 	},
110 	{
111 		.common_name = "www.openbsdfoundation.org",
112 		.alt_name = "*.openbsd.org",
113 		.alt_name_len = -1,
114 		.alt_name_type = GEN_DNS,
115 		.name = "www.openbsd.org",
116 		.want = 0,
117 	},
118 	{
119 		.common_name = "www.openbsdfoundation.org",
120 		.alt_name = "*.org",
121 		.alt_name_len = -1,
122 		.alt_name_type = GEN_DNS,
123 		.name = "www.openbsd.org",
124 		.want = -1,
125 	},
126 	{
127 		.common_name = "www.openbsd.org",
128 		.alt_name = "1.2.3.4",
129 		.alt_name_len = -1,
130 		.alt_name_type = GEN_DNS,
131 		.name = "1.2.3.4",
132 		.want = -1,
133 	},
134 	{
135 		.common_name = "www.openbsd.org",
136 		.alt_name = {0x1, 0x2, 0x3, 0x4},
137 		.alt_name_len = 4,
138 		.alt_name_type = GEN_IPADD,
139 		.name = "1.2.3.4",
140 		.want = 0,
141 	},
142 	{
143 		.common_name = "www.openbsd.org",
144 		.alt_name = {
145 			0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xef,
147 		},
148 		.alt_name_len = 16,
149 		.alt_name_type = GEN_IPADD,
150 		.name = "cafe::beef",
151 		.want = 0,
152 	},
153 	{
154 		.common_name = "*.openbsd.org",
155 		.name = ".openbsd.org",
156 		.want = -1,
157 	},
158 };
159 
160 #define N_VERIFY_TESTS \
161     (sizeof(verify_tests) / sizeof(*verify_tests))
162 
163 static int
164 do_verify_test(int test_no, struct verify_test *vt)
165 {
166 	STACK_OF(GENERAL_NAME) *alt_name_stack = NULL;
167 	ASN1_STRING *alt_name_str;
168 	GENERAL_NAME *alt_name;
169 	X509_NAME *name;
170 	X509 *cert;
171 	struct tls *tls;
172 
173 	/* Build certificate structure. */
174 	if ((cert = X509_new()) == NULL)
175 		errx(1, "failed to malloc X509");
176 	if ((name = X509_NAME_new()) == NULL)
177 		errx(1, "failed to malloc X509_NAME");
178 	if (X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC,
179 	    (unsigned char *)vt->common_name, -1, -1, 0) == 0)
180 		errx(1, "failed to add name entry");
181 	if (X509_set_subject_name(cert, name) == 0)
182 		errx(1, "failed to set subject name");
183 	X509_NAME_free(name);
184 	if ((tls = tls_client()) == NULL)
185 		errx(1, "failed to malloc tls_client");
186 
187 	if (vt->alt_name_type != 0) {
188 		if ((alt_name_stack = sk_GENERAL_NAME_new_null()) == NULL)
189 			errx(1, "failed to malloc sk_GENERAL_NAME");
190 		if ((alt_name = GENERAL_NAME_new()) == NULL)
191 			errx(1, "failed to malloc GENERAL_NAME");
192 		alt_name->type = vt->alt_name_type;
193 
194 		if ((alt_name_str = ASN1_STRING_new()) == NULL)
195 			errx(1, "failed to malloc alt name");
196 		if (ASN1_STRING_set(alt_name_str, vt->alt_name,
197 		    vt->alt_name_len) == 0)
198 			errx(1, "failed to set alt name");
199 
200 		switch (alt_name->type) {
201 		case GEN_DNS:
202 			alt_name->d.dNSName = alt_name_str;
203 			break;
204 
205 		case GEN_IPADD:
206 			alt_name->d.iPAddress = alt_name_str;
207 			break;
208 
209 		default:
210 			errx(1, "unknown alt name type (%i)", alt_name->type);
211 		}
212 
213 		if (sk_GENERAL_NAME_push(alt_name_stack, alt_name) == 0)
214 			errx(1, "failed to push alt_name");
215 		if (X509_add1_ext_i2d(cert, NID_subject_alt_name,
216 		    alt_name_stack, 0, 0) == 0)
217 			errx(1, "failed to set subject alt name");
218 		sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
219 	}
220 
221 	if (tls_check_name(tls, cert, vt->name) != vt->want) {
222 		fprintf(stderr, "FAIL: test %i failed with common name "
223 		    "'%s', alt name '%s' and name '%s'\n", test_no,
224 		    vt->common_name, vt->alt_name, vt->name);
225 		return (1);
226 	}
227 
228 	X509_free(cert);
229 
230 	return (0);
231 }
232 
233 int
234 main(int argc, char **argv)
235 {
236 	int failed = 0;
237 	size_t i;
238 
239 	for (i = 0; i < N_VERIFY_TESTS; i++)
240 		failed += do_verify_test(i, &verify_tests[i]);
241 
242 	return (failed);
243 }
244