]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/x509v3/v3nametest.c
PR: 2909
[thirdparty/openssl.git] / crypto / x509v3 / v3nametest.c
CommitLineData
d88926f1
DSH
1#include <openssl/x509.h>
2#include <openssl/x509v3.h>
3#include <string.h>
4
5static const char *const names[] =
6 {
7 "a", "b", ".", "*", "@",
8 ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
9 "@@", "**",
10 "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
11 "*@example.com", "test@*.example.com",
12 "example.com", "www.example.com", "test.www.example.com",
13 "*.example.com", "*.www.example.com", "test.*.example.com", "www.*.com",
14 "example.net", "xn--rger-koa.example.com",
15 "a.example.com", "b.example.com",
16 "postmaster@example.com", "Postmaster@example.com",
17 "postmaster@EXAMPLE.COM",
18 NULL
19 };
20
21static const char *const exceptions[] =
22 {
23 "set CN: host: [*.example.com] does not match [*.example.com]",
24 "set CN: host: [*.example.com] matches [a.example.com]",
25 "set CN: host: [*.example.com] matches [b.example.com]",
26 "set CN: host: [*.example.com] matches [www.example.com]",
27 "set CN: host: [test.*.example.com] does not match [test.*.example.com]",
28 "set CN: host: [test.*.example.com] matches [test.www.example.com]",
29 "set CN: host: [*.www.example.com] does not match [*.www.example.com]",
30 "set CN: host: [*.www.example.com] matches [test.www.example.com]",
31 "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
32 "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
33 "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
34 "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
35 "set dnsName: host: [*.example.com] matches [www.example.com]",
36 "set dnsName: host: [*.example.com] does not match [*.example.com]",
37 "set dnsName: host: [*.example.com] matches [a.example.com]",
38 "set dnsName: host: [*.example.com] matches [b.example.com]",
39 "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
40 "set dnsName: host: [*.www.example.com] does not match [*.www.example.com]",
41 "set dnsName: host: [test.*.example.com] matches [test.www.example.com]",
42 "set dnsName: host: [test.*.example.com] does not match [test.*.example.com]",
43 "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
44 "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
45 "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
46 "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
47 NULL
48 };
49
50static int is_exception(const char *msg)
51 {
52 const char *const *p;
53 for (p = exceptions; *p; ++p)
54 if (strcmp(msg, *p) == 0)
55 return 1;
56 return 0;
57 }
58
59static int set_cn(X509 *crt, ...)
60 {
61 int ret = 0;
62 X509_NAME *n = NULL;
63 va_list ap;
64 va_start(ap, crt);
65 n = X509_NAME_new();
66 if (n == NULL)
67 goto out;
68 while (1) {
69 int nid;
70 const char *name;
71 nid = va_arg(ap, int);
72 if (nid == 0)
73 break;
74 name = va_arg(ap, const char *);
75 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
76 (unsigned char *)name,
77 -1, -1, 1))
78 goto out;
79 }
80 if (!X509_set_subject_name(crt, n))
81 goto out;
82 ret = 1;
83 out:
84 X509_NAME_free(n);
85 va_end(ap);
86 return ret;
87 }
88
89/*
90int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
91X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
92 int nid, int crit, ASN1_OCTET_STRING *data);
93int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
94*/
95
96static int set_altname(X509 *crt, ...)
97 {
98 int ret = 0;
99 GENERAL_NAMES *gens = NULL;
100 GENERAL_NAME *gen = NULL;
101 ASN1_IA5STRING *ia5 = NULL;
102 va_list ap;
103 va_start(ap, crt);
104 gens = sk_GENERAL_NAME_new_null();
105 if (gens == NULL)
106 goto out;
107 while (1) {
108 int type;
109 const char *name;
110 type = va_arg(ap, int);
111 if (type == 0)
112 break;
113 name = va_arg(ap, const char *);
114
115 gen = GENERAL_NAME_new();
116 if (gen == NULL)
117 goto out;
118 ia5 = ASN1_IA5STRING_new();
119 if (ia5 == NULL)
120 goto out;
121 if (!ASN1_STRING_set(ia5, name, -1))
122 goto out;
123 switch (type)
124 {
125 case GEN_EMAIL:
126 case GEN_DNS:
127 GENERAL_NAME_set0_value(gen, type, ia5);
128 ia5 = NULL;
129 break;
130 default:
131 abort();
132 }
133 sk_GENERAL_NAME_push(gens, gen);
134 gen = NULL;
135 }
136 if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
137 goto out;
138 ret = 1;
139 out:
140 ASN1_IA5STRING_free(ia5);
141 GENERAL_NAME_free(gen);
142 GENERAL_NAMES_free(gens);
143 va_end(ap);
144 return ret;
145 }
146
147static int set_cn1(X509 *crt, const char *name)
148 {
149 return set_cn(crt, NID_commonName, name, 0);
150 }
151
152
153static int set_cn_and_email(X509 *crt, const char *name)
154 {
155 return set_cn(crt, NID_commonName, name,
156 NID_pkcs9_emailAddress, "dummy@example.com", 0);
157 }
158
159static int set_cn2(X509 *crt, const char *name)
160 {
161 return set_cn(crt, NID_commonName, "dummy value",
162 NID_commonName, name, 0);
163 }
164
165static int set_cn3(X509 *crt, const char *name)
166 {
167 return set_cn(crt, NID_commonName, name,
168 NID_commonName, "dummy value", 0);
169 }
170
171static int set_email1(X509 *crt, const char *name)
172 {
173 return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
174 }
175
176static int set_email2(X509 *crt, const char *name)
177 {
178 return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
179 NID_pkcs9_emailAddress, name, 0);
180 }
181
182static int set_email3(X509 *crt, const char *name)
183 {
184 return set_cn(crt, NID_pkcs9_emailAddress, name,
185 NID_pkcs9_emailAddress, "dummy@example.com", 0);
186 }
187
188static int set_email_and_cn(X509 *crt, const char *name)
189 {
190 return set_cn(crt, NID_pkcs9_emailAddress, name,
191 NID_commonName, "www.example.org", 0);
192 }
193
194static int set_altname_dns(X509 *crt, const char *name)
195 {
196 return set_altname(crt, GEN_DNS, name, 0);
197 }
198
199static int set_altname_email(X509 *crt, const char *name)
200 {
201 return set_altname(crt, GEN_EMAIL, name, 0);
202 }
203
204struct set_name_fn
205 {
206 int (*fn)(X509 *, const char *);
207 const char *name;
208 int host;
209 int email;
210 };
211
212static const struct set_name_fn name_fns[] =
213 {
214 {set_cn1, "set CN", 1, 0},
215 {set_cn2, "set CN", 1, 0},
216 {set_cn3, "set CN", 1, 0},
217 {set_cn_and_email, "set CN", 1, 0},
218 {set_email1, "set emailAddress", 0, 1},
219 {set_email2, "set emailAddress", 0, 1},
220 {set_email3, "set emailAddress", 0, 1},
221 {set_email_and_cn, "set emailAddress", 0, 1},
222 {set_altname_dns, "set dnsName", 1, 0},
223 {set_altname_email, "set rfc822Name", 0, 1},
224 {NULL, NULL, 0}
225 };
226
227static X509 *make_cert()
228 {
229 X509 *ret = NULL;
230 X509 *crt = NULL;
231 X509_NAME *issuer = NULL;
232 crt = X509_new();
233 if (crt == NULL)
234 goto out;
235 if (!X509_set_version(crt, 3))
236 goto out;
237 ret = crt;
238 crt = NULL;
239 out:
240 X509_NAME_free(issuer);
241 return ret;
242 }
243
244static int errors;
245
246static void check_message(const struct set_name_fn *fn, const char *op,
247 const char *nameincert, int match, const char *name)
248 {
249 char msg[1024];
250 if (match < 0)
251 return;
252 snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
253 fn->name, op, nameincert,
254 match ? "matches" : "does not match", name);
255 if (is_exception(msg))
256 return;
257 puts(msg);
258 ++errors;
259 }
260
261static void run_cert(X509 *crt, const char *nameincert,
262 const struct set_name_fn *fn)
263 {
264 const char *const *pname = names;
265 while (*pname)
266 {
267 int samename = strcasecmp(nameincert, *pname) == 0;
268 size_t namelen = strlen(*pname);
269 char *name = malloc(namelen);
270 int match, ret;
271 memcpy(name, *pname, namelen);
272
273 ret = X509_check_host(crt, (const unsigned char *)name,
274 namelen, 0);
275 match = -1;
276 if (fn->host)
277 {
278 if (ret && !samename)
279 match = 1;
280 if (!ret && samename)
281 match = 0;
282 }
283 else if (ret)
284 match = 1;
285 check_message(fn, "host", nameincert, match, *pname);
286
287 ret = X509_check_host(crt, (const unsigned char *)name,
288 namelen, X509_CHECK_FLAG_NO_WILDCARDS);
289 match = -1;
290 if (fn->host)
291 {
292 if (ret && !samename)
293 match = 1;
294 if (!ret && samename)
295 match = 0;
296 }
297 else if (ret)
298 match = 1;
299 check_message(fn, "host-no-wildcards",
300 nameincert, match, *pname);
301
302 ret = X509_check_email(crt, (const unsigned char *)name,
303 namelen, 0);
304 match = -1;
305 if (fn->email)
306 {
307 if (ret && !samename)
308 match = 1;
309 if (!ret && samename && strchr(nameincert, '@') != NULL)
310 match = 0;
311 }
312 else if (ret)
313 match = 1;
314 check_message(fn, "email", nameincert, match, *pname);
315 ++pname;
316 free(name);
317 }
318 }
319
320int
321main(void)
322 {
323 const struct set_name_fn *pfn = name_fns;
324 while (pfn->name) {
325 const char *const *pname = names;
326 while (*pname)
327 {
328 X509 *crt = make_cert();
329 if (crt == NULL)
330 {
331 fprintf(stderr, "make_cert failed\n");
332 return 1;
333 }
334 if (!pfn->fn(crt, *pname))
335 {
336 fprintf(stderr, "X509 name setting failed\n");
337 return 1;
338 }
339 run_cert(crt, *pname, pfn);
340 X509_free(crt);
341 ++pname;
342 }
343 ++pfn;
344 }
345 return errors > 0 ? 1 : 0;
346 }