Upstream version 10.39.225.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/crypto.h>
59 #include <openssl/x509.h>
60 #include <openssl/x509v3.h>
61
62
63 static const char *const names[] =
64         {
65         "a", "b", ".", "*", "@",
66         ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
67         "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
68         "*@example.com", "test@*.example.com", "example.com", "www.example.com",
69         "test.www.example.com", "*.example.com", "*.www.example.com",
70         "test.*.example.com", "www.*.com",
71         ".www.example.com", "*www.example.com",
72         "example.net", "xn--rger-koa.example.com",
73         "a.example.com", "b.example.com",
74         "postmaster@example.com", "Postmaster@example.com",
75         "postmaster@EXAMPLE.COM",
76         NULL
77         };
78
79 static const char *const exceptions[] =
80         {
81         "set CN: host: [*.example.com] matches [a.example.com]",
82         "set CN: host: [*.example.com] matches [b.example.com]",
83         "set CN: host: [*.example.com] matches [www.example.com]",
84         "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
85         "set CN: host: [*.www.example.com] matches [test.www.example.com]",
86         "set CN: host: [*.www.example.com] matches [.www.example.com]",
87         "set CN: host: [*www.example.com] matches [www.example.com]",
88         "set CN: host: [test.www.example.com] matches [.www.example.com]",
89         "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
90         "set CN: host-no-wildcards: [test.www.example.com] matches [.www.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 emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
95         "set dnsName: host: [*.example.com] matches [www.example.com]",
96         "set dnsName: host: [*.example.com] matches [a.example.com]",
97         "set dnsName: host: [*.example.com] matches [b.example.com]",
98         "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
99         "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
100         "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
101         "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
102         "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
103         "set dnsName: host: [*www.example.com] matches [www.example.com]",
104         "set dnsName: host: [test.www.example.com] matches [.www.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         "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
109         NULL
110         };
111
112 static int is_exception(const char *msg)
113         {
114         const char *const *p;
115         for (p = exceptions; *p; ++p)
116                 if (strcmp(msg, *p) == 0)
117                         return 1;
118         return 0;
119         }
120
121 static int set_cn(X509 *crt, ...)
122         {
123         int ret = 0;
124         X509_NAME *n = NULL;
125         va_list ap;
126         va_start(ap, crt);
127         n = X509_NAME_new();
128         if (n == NULL)
129                 goto out;
130         while (1) {
131                 int nid;
132                 const char *name;
133                 nid = va_arg(ap, int);
134                 if (nid == 0)
135                         break;
136                 name = va_arg(ap, const char *);
137                 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
138                                                         (unsigned char *)name,
139                                                 -1, -1, 1))
140                         goto out;
141         }
142         if (!X509_set_subject_name(crt, n))
143                 goto out;
144         ret = 1;
145  out:
146         X509_NAME_free(n);
147         va_end(ap);
148         return ret;
149         }
150
151 /*
152 int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
153 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
154                         int nid, int crit, ASN1_OCTET_STRING *data);
155 int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
156 */
157
158 static int set_altname(X509 *crt, ...)
159         {
160         int ret = 0;
161         GENERAL_NAMES *gens = NULL;
162         GENERAL_NAME *gen = NULL;
163         ASN1_IA5STRING *ia5 = NULL;
164         va_list ap;
165         va_start(ap, crt);
166         gens = sk_GENERAL_NAME_new_null();
167         if (gens == NULL)
168                 goto out;
169         while (1) {
170                 int type;
171                 const char *name;
172                 type = va_arg(ap, int);
173                 if (type == 0)
174                         break;
175                 name = va_arg(ap, const char *);
176
177                 gen = GENERAL_NAME_new();
178                 if (gen == NULL)
179                         goto out;
180                 ia5 = ASN1_IA5STRING_new();
181                 if (ia5 == NULL)
182                         goto out;
183                 if (!ASN1_STRING_set(ia5, name, -1))
184                         goto out;
185                 switch (type)
186                         {
187                         case GEN_EMAIL:
188                         case GEN_DNS:
189                                 GENERAL_NAME_set0_value(gen, type, ia5);
190                                 ia5 = NULL;
191                                 break;
192                         default:
193                                 abort();
194                         }
195                 sk_GENERAL_NAME_push(gens, gen);
196                 gen = NULL;
197         }
198         if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
199                 goto out;
200         ret = 1;
201  out:
202         ASN1_IA5STRING_free(ia5);
203         GENERAL_NAME_free(gen);
204         GENERAL_NAMES_free(gens);
205         va_end(ap);
206         return ret;
207         }
208
209 static int set_cn1(X509 *crt, const char *name)
210         {
211         return set_cn(crt, NID_commonName, name, 0);
212         }
213
214
215 static int set_cn_and_email(X509 *crt, const char *name)
216         {
217         return set_cn(crt, NID_commonName, name,
218                       NID_pkcs9_emailAddress, "dummy@example.com", 0);
219         }
220
221 static int set_cn2(X509 *crt, const char *name)
222         {
223         return set_cn(crt, NID_commonName, "dummy value",
224                       NID_commonName, name, 0);
225         }
226
227 static int set_cn3(X509 *crt, const char *name)
228         {
229         return set_cn(crt, NID_commonName, name,
230                       NID_commonName, "dummy value", 0);
231         }
232
233 static int set_email1(X509 *crt, const char *name)
234         {
235         return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
236         }
237
238 static int set_email2(X509 *crt, const char *name)
239         {
240         return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
241                       NID_pkcs9_emailAddress, name, 0);
242         }
243
244 static int set_email3(X509 *crt, const char *name)
245         {
246         return set_cn(crt, NID_pkcs9_emailAddress, name,
247                       NID_pkcs9_emailAddress, "dummy@example.com", 0);
248         }
249
250 static int set_email_and_cn(X509 *crt, const char *name)
251         {
252         return set_cn(crt, NID_pkcs9_emailAddress, name,
253                       NID_commonName, "www.example.org", 0);
254         }
255
256 static int set_altname_dns(X509 *crt, const char *name)
257         {
258         return set_altname(crt, GEN_DNS, name, 0);
259         }
260
261 static int set_altname_email(X509 *crt, const char *name)
262         {
263         return set_altname(crt, GEN_EMAIL, name, 0);
264         }
265
266 struct set_name_fn
267         {
268         int (*fn)(X509 *, const char *);
269         const char *name;
270         int host;
271         int email;
272         };
273
274 static const struct set_name_fn name_fns[] =
275         {
276         {set_cn1, "set CN", 1, 0},
277         {set_cn2, "set CN", 1, 0},
278         {set_cn3, "set CN", 1, 0},
279         {set_cn_and_email, "set CN", 1, 0},
280         {set_email1, "set emailAddress", 0, 1},
281         {set_email2, "set emailAddress", 0, 1},
282         {set_email3, "set emailAddress", 0, 1},
283         {set_email_and_cn, "set emailAddress", 0, 1},
284         {set_altname_dns, "set dnsName", 1, 0},
285         {set_altname_email, "set rfc822Name", 0, 1},
286         {NULL, NULL, 0}
287         };
288
289 static X509 *make_cert(void)
290         {
291         X509 *ret = NULL;
292         X509 *crt = NULL;
293         X509_NAME *issuer = NULL;
294         crt = X509_new();
295         if (crt == NULL)
296                 goto out;
297         if (!X509_set_version(crt, 3))
298                 goto out;
299         ret = crt;
300         crt = NULL;
301  out:
302         X509_NAME_free(issuer);
303         return ret;
304         }
305
306 static int errors;
307
308 static void check_message(const struct set_name_fn *fn, const char *op,
309                           const char *nameincert, int match, const char *name)
310         {
311         char msg[1024];
312         if (match < 0)
313                 return;
314         BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
315                  fn->name, op, nameincert,
316                  match ? "matches" : "does not match", name);
317         if (is_exception(msg))
318                 return;
319         puts(msg);
320         ++errors;
321         }
322
323 static void run_cert(X509 *crt, const char *nameincert,
324                      const struct set_name_fn *fn)
325         {
326         const char *const *pname = names;
327         while (*pname)
328                 {
329                 int samename = strcasecmp(nameincert, *pname) == 0;
330                 size_t namelen = strlen(*pname);
331                 char *name = malloc(namelen);
332                 int match, ret;
333                 memcpy(name, *pname, namelen);
334
335                 ret = X509_check_host(crt, (const unsigned char *)name,
336                                       namelen, 0);
337                 match = -1;
338                 if (ret < 0)
339                         {
340                         fprintf(stderr, "internal error in X509_check_host");
341                         ++errors;
342                         }
343                 else if (fn->host)
344                         {
345                         if (ret == 1 && !samename)
346                                 match = 1;
347                         if (ret == 0 && samename)
348                                 match = 0;
349                         }
350                 else if (ret == 1)
351                         match = 1;
352                 check_message(fn, "host", nameincert, match, *pname);
353
354                 ret = X509_check_host(crt, (const unsigned char *)name,
355                                       namelen, X509_CHECK_FLAG_NO_WILDCARDS);
356                 match = -1;
357                 if (ret < 0)
358                         {
359                         fprintf(stderr, "internal error in X509_check_host");
360                         ++errors;
361                         }
362                 else if (fn->host)
363                         {
364                         if (ret == 1 && !samename)
365                                 match = 1;
366                         if (ret == 0 && samename)
367                                 match = 0;
368                         }
369                 else if (ret == 1)
370                         match = 1;
371                 check_message(fn, "host-no-wildcards",
372                               nameincert, match, *pname);
373
374                 ret = X509_check_email(crt, (const unsigned char *)name,
375                                        namelen, 0);
376                 match = -1;
377                 if (fn->email)
378                         {
379                         if (ret && !samename)
380                                 match = 1;
381                         if (!ret && samename && strchr(nameincert, '@') != NULL)
382                                 match = 0;
383                         }
384                 else if (ret)
385                         match = 1;
386                 check_message(fn, "email", nameincert, match, *pname);
387                 ++pname;
388                 free(name);
389                 }
390         }
391
392 int
393 main(void)
394         {
395         CRYPTO_library_init();
396
397         const struct set_name_fn *pfn = name_fns;
398         while (pfn->name) {
399                 const char *const *pname = names;
400                 while (*pname)
401                         {
402                         X509 *crt = make_cert();
403                         if (crt == NULL)
404                                 {
405                                 fprintf(stderr, "make_cert failed\n");
406                                 return 1;
407                                 }
408                         if (!pfn->fn(crt, *pname))
409                                 {
410                                 fprintf(stderr, "X509 name setting failed\n");
411                                 return 1;
412                                 }
413                         run_cert(crt, *pname, pfn);
414                         X509_free(crt);
415                         ++pname;
416                         }
417                 ++pfn;
418         }
419         if (errors == 0) {
420           printf("PASS\n");
421         }
422         return errors > 0 ? 1 : 0;
423         }