Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / crypto / x509v3 / v3nametest.c
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 1999. */
3 /* ====================================================================
4  * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * 3. All advertising materials mentioning features or use of this
19  *    software must display the following acknowledgment:
20  *    "This product includes software developed by the OpenSSL Project
21  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
22  *
23  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24  *    endorse or promote products derived from this software without
25  *    prior written permission. For written permission, please contact
26  *    licensing@OpenSSL.org.
27  *
28  * 5. Products derived from this software may not be called "OpenSSL"
29  *    nor may "OpenSSL" appear in their names without prior written
30  *    permission of the OpenSSL Project.
31  *
32  * 6. Redistributions of any form whatsoever must retain the following
33  *    acknowledgment:
34  *    "This product includes software developed by the OpenSSL Project
35  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48  * OF THE POSSIBILITY OF SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This product includes cryptographic software written by Eric Young
52  * (eay@cryptsoft.com).  This product includes software written by Tim
53  * Hudson (tjh@cryptsoft.com). */
54
55 #include <string.h>
56 #include <strings.h>
57
58 #include <openssl/x509.h>
59 #include <openssl/x509v3.h>
60
61
62 static const char *const names[] =
63         {
64         "a", "b", ".", "*", "@",
65         ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
66         "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
67         "*@example.com", "test@*.example.com", "example.com", "www.example.com",
68         "test.www.example.com", "*.example.com", "*.www.example.com",
69         "test.*.example.com", "www.*.com",
70         ".www.example.com", "*www.example.com",
71         "example.net", "xn--rger-koa.example.com",
72         "a.example.com", "b.example.com",
73         "postmaster@example.com", "Postmaster@example.com",
74         "postmaster@EXAMPLE.COM",
75         NULL
76         };
77
78 static const char *const exceptions[] =
79         {
80         "set CN: host: [*.example.com] matches [a.example.com]",
81         "set CN: host: [*.example.com] matches [b.example.com]",
82         "set CN: host: [*.example.com] matches [www.example.com]",
83         "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
84         "set CN: host: [*.www.example.com] matches [test.www.example.com]",
85         "set CN: host: [*.www.example.com] matches [.www.example.com]",
86         "set CN: host: [*www.example.com] matches [www.example.com]",
87         "set CN: host: [test.www.example.com] matches [.www.example.com]",
88         "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
89         "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
90         "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
91         "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
92         "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
93         "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
94         "set dnsName: host: [*.example.com] matches [www.example.com]",
95         "set dnsName: host: [*.example.com] matches [a.example.com]",
96         "set dnsName: host: [*.example.com] matches [b.example.com]",
97         "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
98         "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
99         "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
100         "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
101         "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
102         "set dnsName: host: [*www.example.com] matches [www.example.com]",
103         "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
104         "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
105         "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
106         "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
107         "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
108         NULL
109         };
110
111 static int is_exception(const char *msg)
112         {
113         const char *const *p;
114         for (p = exceptions; *p; ++p)
115                 if (strcmp(msg, *p) == 0)
116                         return 1;
117         return 0;
118         }
119
120 static int set_cn(X509 *crt, ...)
121         {
122         int ret = 0;
123         X509_NAME *n = NULL;
124         va_list ap;
125         va_start(ap, crt);
126         n = X509_NAME_new();
127         if (n == NULL)
128                 goto out;
129         while (1) {
130                 int nid;
131                 const char *name;
132                 nid = va_arg(ap, int);
133                 if (nid == 0)
134                         break;
135                 name = va_arg(ap, const char *);
136                 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
137                                                         (unsigned char *)name,
138                                                 -1, -1, 1))
139                         goto out;
140         }
141         if (!X509_set_subject_name(crt, n))
142                 goto out;
143         ret = 1;
144  out:
145         X509_NAME_free(n);
146         va_end(ap);
147         return ret;
148         }
149
150 /*
151 int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
152 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
153                         int nid, int crit, ASN1_OCTET_STRING *data);
154 int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
155 */
156
157 static int set_altname(X509 *crt, ...)
158         {
159         int ret = 0;
160         GENERAL_NAMES *gens = NULL;
161         GENERAL_NAME *gen = NULL;
162         ASN1_IA5STRING *ia5 = NULL;
163         va_list ap;
164         va_start(ap, crt);
165         gens = sk_GENERAL_NAME_new_null();
166         if (gens == NULL)
167                 goto out;
168         while (1) {
169                 int type;
170                 const char *name;
171                 type = va_arg(ap, int);
172                 if (type == 0)
173                         break;
174                 name = va_arg(ap, const char *);
175
176                 gen = GENERAL_NAME_new();
177                 if (gen == NULL)
178                         goto out;
179                 ia5 = ASN1_IA5STRING_new();
180                 if (ia5 == NULL)
181                         goto out;
182                 if (!ASN1_STRING_set(ia5, name, -1))
183                         goto out;
184                 switch (type)
185                         {
186                         case GEN_EMAIL:
187                         case GEN_DNS:
188                                 GENERAL_NAME_set0_value(gen, type, ia5);
189                                 ia5 = NULL;
190                                 break;
191                         default:
192                                 abort();
193                         }
194                 sk_GENERAL_NAME_push(gens, gen);
195                 gen = NULL;
196         }
197         if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
198                 goto out;
199         ret = 1;
200  out:
201         ASN1_IA5STRING_free(ia5);
202         GENERAL_NAME_free(gen);
203         GENERAL_NAMES_free(gens);
204         va_end(ap);
205         return ret;
206         }
207
208 static int set_cn1(X509 *crt, const char *name)
209         {
210         return set_cn(crt, NID_commonName, name, 0);
211         }
212
213
214 static int set_cn_and_email(X509 *crt, const char *name)
215         {
216         return set_cn(crt, NID_commonName, name,
217                       NID_pkcs9_emailAddress, "dummy@example.com", 0);
218         }
219
220 static int set_cn2(X509 *crt, const char *name)
221         {
222         return set_cn(crt, NID_commonName, "dummy value",
223                       NID_commonName, name, 0);
224         }
225
226 static int set_cn3(X509 *crt, const char *name)
227         {
228         return set_cn(crt, NID_commonName, name,
229                       NID_commonName, "dummy value", 0);
230         }
231
232 static int set_email1(X509 *crt, const char *name)
233         {
234         return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
235         }
236
237 static int set_email2(X509 *crt, const char *name)
238         {
239         return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
240                       NID_pkcs9_emailAddress, name, 0);
241         }
242
243 static int set_email3(X509 *crt, const char *name)
244         {
245         return set_cn(crt, NID_pkcs9_emailAddress, name,
246                       NID_pkcs9_emailAddress, "dummy@example.com", 0);
247         }
248
249 static int set_email_and_cn(X509 *crt, const char *name)
250         {
251         return set_cn(crt, NID_pkcs9_emailAddress, name,
252                       NID_commonName, "www.example.org", 0);
253         }
254
255 static int set_altname_dns(X509 *crt, const char *name)
256         {
257         return set_altname(crt, GEN_DNS, name, 0);
258         }
259
260 static int set_altname_email(X509 *crt, const char *name)
261         {
262         return set_altname(crt, GEN_EMAIL, name, 0);
263         }
264
265 struct set_name_fn
266         {
267         int (*fn)(X509 *, const char *);
268         const char *name;
269         int host;
270         int email;
271         };
272
273 static const struct set_name_fn name_fns[] =
274         {
275         {set_cn1, "set CN", 1, 0},
276         {set_cn2, "set CN", 1, 0},
277         {set_cn3, "set CN", 1, 0},
278         {set_cn_and_email, "set CN", 1, 0},
279         {set_email1, "set emailAddress", 0, 1},
280         {set_email2, "set emailAddress", 0, 1},
281         {set_email3, "set emailAddress", 0, 1},
282         {set_email_and_cn, "set emailAddress", 0, 1},
283         {set_altname_dns, "set dnsName", 1, 0},
284         {set_altname_email, "set rfc822Name", 0, 1},
285         {NULL, NULL, 0}
286         };
287
288 static X509 *make_cert()
289         {
290         X509 *ret = NULL;
291         X509 *crt = NULL;
292         X509_NAME *issuer = NULL;
293         crt = X509_new();
294         if (crt == NULL)
295                 goto out;
296         if (!X509_set_version(crt, 3))
297                 goto out;
298         ret = crt;
299         crt = NULL;
300  out:
301         X509_NAME_free(issuer);
302         return ret;
303         }
304
305 static int errors;
306
307 static void check_message(const struct set_name_fn *fn, const char *op,
308                           const char *nameincert, int match, const char *name)
309         {
310         char msg[1024];
311         if (match < 0)
312                 return;
313         BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
314                  fn->name, op, nameincert,
315                  match ? "matches" : "does not match", name);
316         if (is_exception(msg))
317                 return;
318         puts(msg);
319         ++errors;
320         }
321
322 static void run_cert(X509 *crt, const char *nameincert,
323                      const struct set_name_fn *fn)
324         {
325         const char *const *pname = names;
326         while (*pname)
327                 {
328                 int samename = strcasecmp(nameincert, *pname) == 0;
329                 size_t namelen = strlen(*pname);
330                 char *name = malloc(namelen);
331                 int match, ret;
332                 memcpy(name, *pname, namelen);
333
334                 ret = X509_check_host(crt, (const unsigned char *)name,
335                                       namelen, 0);
336                 match = -1;
337                 if (ret < 0)
338                         {
339                         fprintf(stderr, "internal error in X509_check_host");
340                         ++errors;
341                         }
342                 else if (fn->host)
343                         {
344                         if (ret == 1 && !samename)
345                                 match = 1;
346                         if (ret == 0 && samename)
347                                 match = 0;
348                         }
349                 else if (ret == 1)
350                         match = 1;
351                 check_message(fn, "host", nameincert, match, *pname);
352
353                 ret = X509_check_host(crt, (const unsigned char *)name,
354                                       namelen, X509_CHECK_FLAG_NO_WILDCARDS);
355                 match = -1;
356                 if (ret < 0)
357                         {
358                         fprintf(stderr, "internal error in X509_check_host");
359                         ++errors;
360                         }
361                 else if (fn->host)
362                         {
363                         if (ret == 1 && !samename)
364                                 match = 1;
365                         if (ret == 0 && samename)
366                                 match = 0;
367                         }
368                 else if (ret == 1)
369                         match = 1;
370                 check_message(fn, "host-no-wildcards",
371                               nameincert, match, *pname);
372
373                 ret = X509_check_email(crt, (const unsigned char *)name,
374                                        namelen, 0);
375                 match = -1;
376                 if (fn->email)
377                         {
378                         if (ret && !samename)
379                                 match = 1;
380                         if (!ret && samename && strchr(nameincert, '@') != NULL)
381                                 match = 0;
382                         }
383                 else if (ret)
384                         match = 1;
385                 check_message(fn, "email", nameincert, match, *pname);
386                 ++pname;
387                 free(name);
388                 }
389         }
390
391 int
392 main(void)
393         {
394         const struct set_name_fn *pfn = name_fns;
395         while (pfn->name) {
396                 const char *const *pname = names;
397                 while (*pname)
398                         {
399                         X509 *crt = make_cert();
400                         if (crt == NULL)
401                                 {
402                                 fprintf(stderr, "make_cert failed\n");
403                                 return 1;
404                                 }
405                         if (!pfn->fn(crt, *pname))
406                                 {
407                                 fprintf(stderr, "X509 name setting failed\n");
408                                 return 1;
409                                 }
410                         run_cert(crt, *pname, pfn);
411                         X509_free(crt);
412                         ++pname;
413                         }
414                 ++pfn;
415         }
416         if (errors == 0) {
417           printf("PASS\n");
418         }
419         return errors > 0 ? 1 : 0;
420         }