• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/openssl/crypto/x509v3/
1#include <openssl/x509.h>
2#include <openssl/x509v3.h>
3#include "../e_os.h"
4#include <string.h>
5
6static const char *const names[] = {
7    "a", "b", ".", "*", "@",
8    ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
9    "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
10    "*@example.com", "test@*.example.com", "example.com", "www.example.com",
11    "test.www.example.com", "*.example.com", "*.www.example.com",
12    "test.*.example.com", "www.*.com",
13    ".www.example.com", "*www.example.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    "set CN: host: [*.example.com] matches [a.example.com]",
23    "set CN: host: [*.example.com] matches [b.example.com]",
24    "set CN: host: [*.example.com] matches [www.example.com]",
25    "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
26    "set CN: host: [*.www.example.com] matches [test.www.example.com]",
27    "set CN: host: [*.www.example.com] matches [.www.example.com]",
28    "set CN: host: [*www.example.com] matches [www.example.com]",
29    "set CN: host: [test.www.example.com] matches [.www.example.com]",
30    "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
31    "set CN: host-no-wildcards: [test.www.example.com] matches [.www.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 emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
36    "set dnsName: host: [*.example.com] matches [www.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: [*.example.com] matches [xn--rger-koa.example.com]",
40    "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
41    "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
42    "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
43    "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
44    "set dnsName: host: [*www.example.com] matches [www.example.com]",
45    "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
46    "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
47    "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
48    "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
49    "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
50    NULL
51};
52
53static int is_exception(const char *msg)
54{
55    const char *const *p;
56    for (p = exceptions; *p; ++p)
57        if (strcmp(msg, *p) == 0)
58            return 1;
59    return 0;
60}
61
62static int set_cn(X509 *crt, ...)
63{
64    int ret = 0;
65    X509_NAME *n = NULL;
66    va_list ap;
67    va_start(ap, crt);
68    n = X509_NAME_new();
69    if (n == NULL)
70        goto out;
71    while (1) {
72        int nid;
73        const char *name;
74        nid = va_arg(ap, int);
75        if (nid == 0)
76            break;
77        name = va_arg(ap, const char *);
78        if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
79                                        (unsigned char *)name, -1, -1, 1))
80            goto out;
81    }
82    if (!X509_set_subject_name(crt, n))
83        goto out;
84    ret = 1;
85 out:
86    X509_NAME_free(n);
87    va_end(ap);
88    return ret;
89}
90
91/*-
92int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
93X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
94                        int nid, int crit, ASN1_OCTET_STRING *data);
95int             X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
96*/
97
98static int set_altname(X509 *crt, ...)
99{
100    int ret = 0;
101    GENERAL_NAMES *gens = NULL;
102    GENERAL_NAME *gen = NULL;
103    ASN1_IA5STRING *ia5 = NULL;
104    va_list ap;
105    va_start(ap, crt);
106    gens = sk_GENERAL_NAME_new_null();
107    if (gens == NULL)
108        goto out;
109    while (1) {
110        int type;
111        const char *name;
112        type = va_arg(ap, int);
113        if (type == 0)
114            break;
115        name = va_arg(ap, const char *);
116
117        gen = GENERAL_NAME_new();
118        if (gen == NULL)
119            goto out;
120        ia5 = ASN1_IA5STRING_new();
121        if (ia5 == NULL)
122            goto out;
123        if (!ASN1_STRING_set(ia5, name, -1))
124            goto out;
125        switch (type) {
126        case GEN_EMAIL:
127        case GEN_DNS:
128            GENERAL_NAME_set0_value(gen, type, ia5);
129            ia5 = NULL;
130            break;
131        default:
132            abort();
133        }
134        sk_GENERAL_NAME_push(gens, gen);
135        gen = NULL;
136    }
137    if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
138        goto out;
139    ret = 1;
140 out:
141    ASN1_IA5STRING_free(ia5);
142    GENERAL_NAME_free(gen);
143    GENERAL_NAMES_free(gens);
144    va_end(ap);
145    return ret;
146}
147
148static int set_cn1(X509 *crt, const char *name)
149{
150    return set_cn(crt, NID_commonName, name, 0);
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    int (*fn) (X509 *, const char *);
206    const char *name;
207    int host;
208    int email;
209};
210
211static const struct set_name_fn name_fns[] = {
212    {set_cn1, "set CN", 1, 0},
213    {set_cn2, "set CN", 1, 0},
214    {set_cn3, "set CN", 1, 0},
215    {set_cn_and_email, "set CN", 1, 0},
216    {set_email1, "set emailAddress", 0, 1},
217    {set_email2, "set emailAddress", 0, 1},
218    {set_email3, "set emailAddress", 0, 1},
219    {set_email_and_cn, "set emailAddress", 0, 1},
220    {set_altname_dns, "set dnsName", 1, 0},
221    {set_altname_email, "set rfc822Name", 0, 1},
222    {NULL, NULL, 0}
223};
224
225static X509 *make_cert()
226{
227    X509 *ret = NULL;
228    X509 *crt = NULL;
229    X509_NAME *issuer = NULL;
230    crt = X509_new();
231    if (crt == NULL)
232        goto out;
233    if (!X509_set_version(crt, 3))
234        goto out;
235    ret = crt;
236    crt = NULL;
237 out:
238    X509_NAME_free(issuer);
239    return ret;
240}
241
242static int errors;
243
244static void check_message(const struct set_name_fn *fn, const char *op,
245                          const char *nameincert, int match, const char *name)
246{
247    char msg[1024];
248    if (match < 0)
249        return;
250    BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
251                 fn->name, op, nameincert,
252                 match ? "matches" : "does not match", name);
253    if (is_exception(msg))
254        return;
255    puts(msg);
256    ++errors;
257}
258
259static void run_cert(X509 *crt, const char *nameincert,
260                     const struct set_name_fn *fn)
261{
262    const char *const *pname = names;
263    while (*pname) {
264        int samename = strcasecmp(nameincert, *pname) == 0;
265        size_t namelen = strlen(*pname);
266        char *name = malloc(namelen);
267        int match, ret;
268        memcpy(name, *pname, namelen);
269
270        ret = X509_check_host(crt, name, namelen, 0, NULL);
271        match = -1;
272        if (ret < 0) {
273            fprintf(stderr, "internal error in X509_check_host");
274            ++errors;
275        } else if (fn->host) {
276            if (ret == 1 && !samename)
277                match = 1;
278            if (ret == 0 && samename)
279                match = 0;
280        } else if (ret == 1)
281            match = 1;
282        check_message(fn, "host", nameincert, match, *pname);
283
284        ret = X509_check_host(crt, name, namelen,
285                              X509_CHECK_FLAG_NO_WILDCARDS, NULL);
286        match = -1;
287        if (ret < 0) {
288            fprintf(stderr, "internal error in X509_check_host");
289            ++errors;
290        } else if (fn->host) {
291            if (ret == 1 && !samename)
292                match = 1;
293            if (ret == 0 && samename)
294                match = 0;
295        } else if (ret == 1)
296            match = 1;
297        check_message(fn, "host-no-wildcards", nameincert, match, *pname);
298
299        ret = X509_check_email(crt, name, namelen, 0);
300        match = -1;
301        if (fn->email) {
302            if (ret && !samename)
303                match = 1;
304            if (!ret && samename && strchr(nameincert, '@') != NULL)
305                match = 0;
306        } else if (ret)
307            match = 1;
308        check_message(fn, "email", nameincert, match, *pname);
309        ++pname;
310        free(name);
311    }
312}
313
314int main(void)
315{
316    const struct set_name_fn *pfn = name_fns;
317    while (pfn->name) {
318        const char *const *pname = names;
319        while (*pname) {
320            X509 *crt = make_cert();
321            if (crt == NULL) {
322                fprintf(stderr, "make_cert failed\n");
323                return 1;
324            }
325            if (!pfn->fn(crt, *pname)) {
326                fprintf(stderr, "X509 name setting failed\n");
327                return 1;
328            }
329            run_cert(crt, *pname, pfn);
330            X509_free(crt);
331            ++pname;
332        }
333        ++pfn;
334    }
335    return errors > 0 ? 1 : 0;
336}
337