verifytest.c revision 1.3
1/*	$OpenBSD: verifytest.c,v 1.3 2015/02/22 15:14:32 jsing 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
25extern int tls_check_servername(struct tls *ctx, X509 *cert, const char *name);
26
27struct 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 servername[128];
33	int want;
34};
35
36struct verify_test verify_tests[] = {
37	{
38		.common_name = "www.openbsd.org",
39		.servername = "www.openbsd.org",
40		.want = 0,
41	},
42	{
43		.common_name = "www.openbsd.org",
44		.servername = "",
45		.want = -1,
46	},
47	{
48		.common_name = "*.openbsd.org",
49		.servername = "www.openbsd.org",
50		.want = 0,
51	},
52	{
53		.common_name = "www.openbsdfoundation.org",
54		.servername = "www.openbsd.org",
55		.want = -1,
56	},
57	{
58		.common_name = "w*.openbsd.org",
59		.servername = "www.openbsd.org",
60		.want = -1,
61	},
62	{
63		.common_name = "www.*.org",
64		.servername = "www.openbsd.org",
65		.want = -1,
66	},
67	{
68		.common_name = "www.openbsd.*",
69		.servername = "www.openbsd.org",
70		.want = -1,
71	},
72	{
73		.common_name = "*",
74		.servername = "www.openbsd.org",
75		.want = -1,
76	},
77	{
78		.common_name = "*.org",
79		.servername = "www.openbsd.org",
80		.want = -1,
81	},
82	{
83		.common_name = "*.org",
84		.servername = "openbsd.org",
85		.want = -1,
86	},
87	{
88		.common_name = "1.2.3.4",
89		.servername = "1.2.3.4",
90		.want = 0,
91	},
92	{
93		.common_name = "*.2.3.4",
94		.servername = "1.2.3.4",
95		.want = -1,
96	},
97	{
98		.common_name = "cafe::beef",
99		.servername = "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		.servername = "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		.servername = "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		.servername = "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		.servername = "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		.servername = "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		.servername = "cafe::beef",
151		.want = 0,
152	},
153};
154
155#define N_VERIFY_TESTS \
156    (sizeof(verify_tests) / sizeof(*verify_tests))
157
158static int
159do_verify_test(int test_no, struct verify_test *vt)
160{
161	STACK_OF(GENERAL_NAME) *alt_name_stack = NULL;
162	ASN1_STRING *alt_name_str;
163	GENERAL_NAME *alt_name;
164	X509_NAME *name;
165	X509 *cert;
166	struct tls *tls;
167
168	/* Build certificate structure. */
169	if ((cert = X509_new()) == NULL)
170		errx(1, "failed to malloc X509");
171	if ((name = X509_NAME_new()) == NULL)
172		errx(1, "failed to malloc X509_NAME");
173	if (X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC,
174	    (unsigned char *)vt->common_name, -1, -1, 0) == 0)
175		errx(1, "failed to add name entry");
176	if (X509_set_subject_name(cert, name) == 0)
177		errx(1, "failed to set subject name");
178	X509_NAME_free(name);
179	if ((tls = tls_client()) == NULL)
180		errx(1, "failed to malloc tls_client");
181
182	if (vt->alt_name_type != 0) {
183		if ((alt_name_stack = sk_GENERAL_NAME_new_null()) == NULL)
184			errx(1, "failed to malloc sk_GENERAL_NAME");
185		if ((alt_name = GENERAL_NAME_new()) == NULL)
186			errx(1, "failed to malloc GENERAL_NAME");
187		alt_name->type = vt->alt_name_type;
188
189		if ((alt_name_str = ASN1_STRING_new()) == NULL)
190			errx(1, "failed to malloc alt name");
191		if (ASN1_STRING_set(alt_name_str, vt->alt_name,
192		    vt->alt_name_len) == 0)
193			errx(1, "failed to set alt name");
194
195		switch (alt_name->type) {
196		case GEN_DNS:
197			alt_name->d.dNSName = alt_name_str;
198			break;
199
200		case GEN_IPADD:
201			alt_name->d.iPAddress = alt_name_str;
202			break;
203
204		default:
205			errx(1, "unknown alt name type (%i)", alt_name->type);
206		}
207
208		if (sk_GENERAL_NAME_push(alt_name_stack, alt_name) == 0)
209			errx(1, "failed to push alt_name");
210		if (X509_add1_ext_i2d(cert, NID_subject_alt_name,
211		    alt_name_stack, 0, 0) == 0)
212			errx(1, "failed to set subject alt name");
213		sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
214	}
215
216	if (tls_check_servername(tls, cert, vt->servername) != vt->want) {
217		fprintf(stderr, "FAIL: test %i failed with common name "
218		    "'%s', alt name '%s' and servername '%s'\n", test_no,
219		    vt->common_name, vt->alt_name, vt->servername);
220		return (1);
221	}
222
223	X509_free(cert);
224
225	return (0);
226}
227
228int
229main(int argc, char **argv)
230{
231	int failed = 0;
232	size_t i;
233
234	for (i = 0; i < N_VERIFY_TESTS; i++)
235		failed += do_verify_test(i, &verify_tests[i]);
236
237	return (failed);
238}
239