4be395397cd38e2e20d7310cf1ab7d30e95367b7
[openssl.git] / crypto / x509 / v3_utl.c
1 /*
2  * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /* X509 v3 extension utilities */
11
12 #include "e_os.h"
13 #include "internal/cryptlib.h"
14 #include <stdio.h>
15 #include "crypto/ctype.h"
16 #include <openssl/conf.h>
17 #include <openssl/crypto.h>
18 #include <openssl/x509v3.h>
19 #include "crypto/x509.h"
20 #include <openssl/bn.h>
21 #include "ext_dat.h"
22
23 DEFINE_STACK_OF(CONF_VALUE)
24 DEFINE_STACK_OF(GENERAL_NAME)
25 DEFINE_STACK_OF(ACCESS_DESCRIPTION)
26 DEFINE_STACK_OF(X509_EXTENSION)
27 DEFINE_STACK_OF_STRING()
28
29 static char *strip_spaces(char *name);
30 static int sk_strcmp(const char *const *a, const char *const *b);
31 static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name,
32                                            GENERAL_NAMES *gens);
33 static void str_free(OPENSSL_STRING str);
34 static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email);
35
36 static int ipv4_from_asc(unsigned char *v4, const char *in);
37 static int ipv6_from_asc(unsigned char *v6, const char *in);
38 static int ipv6_cb(const char *elem, int len, void *usr);
39 static int ipv6_hex(unsigned char *out, const char *in, int inlen);
40
41 /* Add a CONF_VALUE name value pair to stack */
42
43 int X509V3_add_value(const char *name, const char *value,
44                      STACK_OF(CONF_VALUE) **extlist)
45 {
46     CONF_VALUE *vtmp = NULL;
47     char *tname = NULL, *tvalue = NULL;
48     int sk_allocated = (*extlist == NULL);
49
50     if (name && (tname = OPENSSL_strdup(name)) == NULL)
51         goto err;
52     if (value && (tvalue = OPENSSL_strdup(value)) == NULL)
53         goto err;
54     if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL)
55         goto err;
56     if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL)
57         goto err;
58     vtmp->section = NULL;
59     vtmp->name = tname;
60     vtmp->value = tvalue;
61     if (!sk_CONF_VALUE_push(*extlist, vtmp))
62         goto err;
63     return 1;
64  err:
65     X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE);
66     if (sk_allocated) {
67         sk_CONF_VALUE_free(*extlist);
68         *extlist = NULL;
69     }
70     OPENSSL_free(vtmp);
71     OPENSSL_free(tname);
72     OPENSSL_free(tvalue);
73     return 0;
74 }
75
76 int X509V3_add_value_uchar(const char *name, const unsigned char *value,
77                            STACK_OF(CONF_VALUE) **extlist)
78 {
79     return X509V3_add_value(name, (const char *)value, extlist);
80 }
81
82 /* Free function for STACK_OF(CONF_VALUE) */
83
84 void X509V3_conf_free(CONF_VALUE *conf)
85 {
86     if (!conf)
87         return;
88     OPENSSL_free(conf->name);
89     OPENSSL_free(conf->value);
90     OPENSSL_free(conf->section);
91     OPENSSL_free(conf);
92 }
93
94 int X509V3_add_value_bool(const char *name, int asn1_bool,
95                           STACK_OF(CONF_VALUE) **extlist)
96 {
97     if (asn1_bool)
98         return X509V3_add_value(name, "TRUE", extlist);
99     return X509V3_add_value(name, "FALSE", extlist);
100 }
101
102 int X509V3_add_value_bool_nf(const char *name, int asn1_bool,
103                              STACK_OF(CONF_VALUE) **extlist)
104 {
105     if (asn1_bool)
106         return X509V3_add_value(name, "TRUE", extlist);
107     return 1;
108 }
109
110 static char *bignum_to_string(const BIGNUM *bn)
111 {
112     char *tmp, *ret;
113     size_t len;
114
115     /*
116      * Display large numbers in hex and small numbers in decimal. Converting to
117      * decimal takes quadratic time and is no more useful than hex for large
118      * numbers.
119      */
120     if (BN_num_bits(bn) < 128)
121         return BN_bn2dec(bn);
122
123     tmp = BN_bn2hex(bn);
124     if (tmp == NULL)
125         return NULL;
126
127     len = strlen(tmp) + 3;
128     ret = OPENSSL_malloc(len);
129     if (ret == NULL) {
130         X509V3err(X509V3_F_BIGNUM_TO_STRING, ERR_R_MALLOC_FAILURE);
131         OPENSSL_free(tmp);
132         return NULL;
133     }
134
135     /* Prepend "0x", but place it after the "-" if negative. */
136     if (tmp[0] == '-') {
137         OPENSSL_strlcpy(ret, "-0x", len);
138         OPENSSL_strlcat(ret, tmp + 1, len);
139     } else {
140         OPENSSL_strlcpy(ret, "0x", len);
141         OPENSSL_strlcat(ret, tmp, len);
142     }
143     OPENSSL_free(tmp);
144     return ret;
145 }
146
147 char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a)
148 {
149     BIGNUM *bntmp = NULL;
150     char *strtmp = NULL;
151
152     if (!a)
153         return NULL;
154     if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL
155         || (strtmp = bignum_to_string(bntmp)) == NULL)
156         X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
157     BN_free(bntmp);
158     return strtmp;
159 }
160
161 char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a)
162 {
163     BIGNUM *bntmp = NULL;
164     char *strtmp = NULL;
165
166     if (!a)
167         return NULL;
168     if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL
169         || (strtmp = bignum_to_string(bntmp)) == NULL)
170         X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
171     BN_free(bntmp);
172     return strtmp;
173 }
174
175 ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value)
176 {
177     BIGNUM *bn = NULL;
178     ASN1_INTEGER *aint;
179     int isneg, ishex;
180     int ret;
181     if (value == NULL) {
182         X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
183         return NULL;
184     }
185     bn = BN_new();
186     if (bn == NULL) {
187         X509V3err(X509V3_F_S2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
188         return NULL;
189     }
190     if (value[0] == '-') {
191         value++;
192         isneg = 1;
193     } else
194         isneg = 0;
195
196     if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
197         value += 2;
198         ishex = 1;
199     } else
200         ishex = 0;
201
202     if (ishex)
203         ret = BN_hex2bn(&bn, value);
204     else
205         ret = BN_dec2bn(&bn, value);
206
207     if (!ret || value[ret]) {
208         BN_free(bn);
209         X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
210         return NULL;
211     }
212
213     if (isneg && BN_is_zero(bn))
214         isneg = 0;
215
216     aint = BN_to_ASN1_INTEGER(bn, NULL);
217     BN_free(bn);
218     if (!aint) {
219         X509V3err(X509V3_F_S2I_ASN1_INTEGER,
220                   X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
221         return NULL;
222     }
223     if (isneg)
224         aint->type |= V_ASN1_NEG;
225     return aint;
226 }
227
228 int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint,
229                          STACK_OF(CONF_VALUE) **extlist)
230 {
231     char *strtmp;
232     int ret;
233
234     if (!aint)
235         return 1;
236     if ((strtmp = i2s_ASN1_INTEGER(NULL, aint)) == NULL)
237         return 0;
238     ret = X509V3_add_value(name, strtmp, extlist);
239     OPENSSL_free(strtmp);
240     return ret;
241 }
242
243 int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool)
244 {
245     const char *btmp;
246
247     if ((btmp = value->value) == NULL)
248         goto err;
249     if (strcmp(btmp, "TRUE") == 0
250         || strcmp(btmp, "true") == 0
251         || strcmp(btmp, "Y") == 0
252         || strcmp(btmp, "y") == 0
253         || strcmp(btmp, "YES") == 0
254         || strcmp(btmp, "yes") == 0) {
255         *asn1_bool = 0xff;
256         return 1;
257     }
258     if (strcmp(btmp, "FALSE") == 0
259         || strcmp(btmp, "false") == 0
260         || strcmp(btmp, "N") == 0
261         || strcmp(btmp, "n") == 0
262         || strcmp(btmp, "NO") == 0
263         || strcmp(btmp, "no") == 0) {
264         *asn1_bool = 0;
265         return 1;
266     }
267  err:
268     X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,
269               X509V3_R_INVALID_BOOLEAN_STRING);
270     X509V3_conf_err(value);
271     return 0;
272 }
273
274 int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint)
275 {
276     ASN1_INTEGER *itmp;
277
278     if ((itmp = s2i_ASN1_INTEGER(NULL, value->value)) == NULL) {
279         X509V3_conf_err(value);
280         return 0;
281     }
282     *aint = itmp;
283     return 1;
284 }
285
286 #define HDR_NAME        1
287 #define HDR_VALUE       2
288
289 /*
290  * #define DEBUG
291  */
292
293 STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
294 {
295     char *p, *q, c;
296     char *ntmp, *vtmp;
297     STACK_OF(CONF_VALUE) *values = NULL;
298     char *linebuf;
299     int state;
300     /* We are going to modify the line so copy it first */
301     linebuf = OPENSSL_strdup(line);
302     if (linebuf == NULL) {
303         X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE);
304         goto err;
305     }
306     state = HDR_NAME;
307     ntmp = NULL;
308     /* Go through all characters */
309     for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
310          p++) {
311
312         switch (state) {
313         case HDR_NAME:
314             if (c == ':') {
315                 state = HDR_VALUE;
316                 *p = 0;
317                 ntmp = strip_spaces(q);
318                 if (!ntmp) {
319                     X509V3err(X509V3_F_X509V3_PARSE_LIST,
320                               X509V3_R_INVALID_NULL_NAME);
321                     goto err;
322                 }
323                 q = p + 1;
324             } else if (c == ',') {
325                 *p = 0;
326                 ntmp = strip_spaces(q);
327                 q = p + 1;
328                 if (!ntmp) {
329                     X509V3err(X509V3_F_X509V3_PARSE_LIST,
330                               X509V3_R_INVALID_NULL_NAME);
331                     goto err;
332                 }
333                 X509V3_add_value(ntmp, NULL, &values);
334             }
335             break;
336
337         case HDR_VALUE:
338             if (c == ',') {
339                 state = HDR_NAME;
340                 *p = 0;
341                 vtmp = strip_spaces(q);
342                 if (!vtmp) {
343                     X509V3err(X509V3_F_X509V3_PARSE_LIST,
344                               X509V3_R_INVALID_NULL_VALUE);
345                     goto err;
346                 }
347                 X509V3_add_value(ntmp, vtmp, &values);
348                 ntmp = NULL;
349                 q = p + 1;
350             }
351
352         }
353     }
354
355     if (state == HDR_VALUE) {
356         vtmp = strip_spaces(q);
357         if (!vtmp) {
358             X509V3err(X509V3_F_X509V3_PARSE_LIST,
359                       X509V3_R_INVALID_NULL_VALUE);
360             goto err;
361         }
362         X509V3_add_value(ntmp, vtmp, &values);
363     } else {
364         ntmp = strip_spaces(q);
365         if (!ntmp) {
366             X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
367             goto err;
368         }
369         X509V3_add_value(ntmp, NULL, &values);
370     }
371     OPENSSL_free(linebuf);
372     return values;
373
374  err:
375     OPENSSL_free(linebuf);
376     sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
377     return NULL;
378
379 }
380
381 /* Delete leading and trailing spaces from a string */
382 static char *strip_spaces(char *name)
383 {
384     char *p, *q;
385     /* Skip over leading spaces */
386     p = name;
387     while (*p && ossl_isspace(*p))
388         p++;
389     if (*p == '\0')
390         return NULL;
391     q = p + strlen(p) - 1;
392     while ((q != p) && ossl_isspace(*q))
393         q--;
394     if (p != q)
395         q[1] = 0;
396     if (*p == '\0')
397         return NULL;
398     return p;
399 }
400
401
402 /*
403  * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
404  */
405
406 int v3_name_cmp(const char *name, const char *cmp)
407 {
408     int len, ret;
409     char c;
410     len = strlen(cmp);
411     if ((ret = strncmp(name, cmp, len)))
412         return ret;
413     c = name[len];
414     if (!c || (c == '.'))
415         return 0;
416     return 1;
417 }
418
419 static int sk_strcmp(const char *const *a, const char *const *b)
420 {
421     return strcmp(*a, *b);
422 }
423
424 STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
425 {
426     GENERAL_NAMES *gens;
427     STACK_OF(OPENSSL_STRING) *ret;
428
429     gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
430     ret = get_email(X509_get_subject_name(x), gens);
431     sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
432     return ret;
433 }
434
435 STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
436 {
437     AUTHORITY_INFO_ACCESS *info;
438     STACK_OF(OPENSSL_STRING) *ret = NULL;
439     int i;
440
441     info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
442     if (!info)
443         return NULL;
444     for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
445         ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
446         if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
447             if (ad->location->type == GEN_URI) {
448                 if (!append_ia5
449                     (&ret, ad->location->d.uniformResourceIdentifier))
450                     break;
451             }
452         }
453     }
454     AUTHORITY_INFO_ACCESS_free(info);
455     return ret;
456 }
457
458 STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
459 {
460     GENERAL_NAMES *gens;
461     STACK_OF(X509_EXTENSION) *exts;
462     STACK_OF(OPENSSL_STRING) *ret;
463
464     exts = X509_REQ_get_extensions(x);
465     gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
466     ret = get_email(X509_REQ_get_subject_name(x), gens);
467     sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
468     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
469     return ret;
470 }
471
472 static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name,
473                                            GENERAL_NAMES *gens)
474 {
475     STACK_OF(OPENSSL_STRING) *ret = NULL;
476     X509_NAME_ENTRY *ne;
477     const ASN1_IA5STRING *email;
478     GENERAL_NAME *gen;
479     int i = -1;
480
481     /* Now add any email address(es) to STACK */
482     /* First supplied X509_NAME */
483     while ((i = X509_NAME_get_index_by_NID(name,
484                                            NID_pkcs9_emailAddress, i)) >= 0) {
485         ne = X509_NAME_get_entry(name, i);
486         email = X509_NAME_ENTRY_get_data(ne);
487         if (!append_ia5(&ret, email))
488             return NULL;
489     }
490     for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
491         gen = sk_GENERAL_NAME_value(gens, i);
492         if (gen->type != GEN_EMAIL)
493             continue;
494         if (!append_ia5(&ret, gen->d.ia5))
495             return NULL;
496     }
497     return ret;
498 }
499
500 static void str_free(OPENSSL_STRING str)
501 {
502     OPENSSL_free(str);
503 }
504
505 static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email)
506 {
507     char *emtmp;
508     /* First some sanity checks */
509     if (email->type != V_ASN1_IA5STRING)
510         return 1;
511     if (!email->data || !email->length)
512         return 1;
513     if (*sk == NULL)
514         *sk = sk_OPENSSL_STRING_new(sk_strcmp);
515     if (*sk == NULL)
516         return 0;
517     /* Don't add duplicates */
518     if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1)
519         return 1;
520     emtmp = OPENSSL_strdup((char *)email->data);
521     if (emtmp == NULL || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
522         OPENSSL_free(emtmp);    /* free on push failure */
523         X509_email_free(*sk);
524         *sk = NULL;
525         return 0;
526     }
527     return 1;
528 }
529
530 void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
531 {
532     sk_OPENSSL_STRING_pop_free(sk, str_free);
533 }
534
535 typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
536                          const unsigned char *subject, size_t subject_len,
537                          unsigned int flags);
538
539 /* Skip pattern prefix to match "wildcard" subject */
540 static void skip_prefix(const unsigned char **p, size_t *plen,
541                         size_t subject_len,
542                         unsigned int flags)
543 {
544     const unsigned char *pattern = *p;
545     size_t pattern_len = *plen;
546
547     /*
548      * If subject starts with a leading '.' followed by more octets, and
549      * pattern is longer, compare just an equal-length suffix with the
550      * full subject (starting at the '.'), provided the prefix contains
551      * no NULs.
552      */
553     if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
554         return;
555
556     while (pattern_len > subject_len && *pattern) {
557         if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
558             *pattern == '.')
559             break;
560         ++pattern;
561         --pattern_len;
562     }
563
564     /* Skip if entire prefix acceptable */
565     if (pattern_len == subject_len) {
566         *p = pattern;
567         *plen = pattern_len;
568     }
569 }
570
571 /* Compare while ASCII ignoring case. */
572 static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
573                         const unsigned char *subject, size_t subject_len,
574                         unsigned int flags)
575 {
576     skip_prefix(&pattern, &pattern_len, subject_len, flags);
577     if (pattern_len != subject_len)
578         return 0;
579     while (pattern_len) {
580         unsigned char l = *pattern;
581         unsigned char r = *subject;
582         /* The pattern must not contain NUL characters. */
583         if (l == 0)
584             return 0;
585         if (l != r) {
586             if ('A' <= l && l <= 'Z')
587                 l = (l - 'A') + 'a';
588             if ('A' <= r && r <= 'Z')
589                 r = (r - 'A') + 'a';
590             if (l != r)
591                 return 0;
592         }
593         ++pattern;
594         ++subject;
595         --pattern_len;
596     }
597     return 1;
598 }
599
600 /* Compare using memcmp. */
601 static int equal_case(const unsigned char *pattern, size_t pattern_len,
602                       const unsigned char *subject, size_t subject_len,
603                       unsigned int flags)
604 {
605     skip_prefix(&pattern, &pattern_len, subject_len, flags);
606     if (pattern_len != subject_len)
607         return 0;
608     return !memcmp(pattern, subject, pattern_len);
609 }
610
611 /*
612  * RFC 5280, section 7.5, requires that only the domain is compared in a
613  * case-insensitive manner.
614  */
615 static int equal_email(const unsigned char *a, size_t a_len,
616                        const unsigned char *b, size_t b_len,
617                        unsigned int unused_flags)
618 {
619     size_t i = a_len;
620     if (a_len != b_len)
621         return 0;
622     /*
623      * We search backwards for the '@' character, so that we do not have to
624      * deal with quoted local-parts.  The domain part is compared in a
625      * case-insensitive manner.
626      */
627     while (i > 0) {
628         --i;
629         if (a[i] == '@' || b[i] == '@') {
630             if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
631                 return 0;
632             break;
633         }
634     }
635     if (i == 0)
636         i = a_len;
637     return equal_case(a, i, b, i, 0);
638 }
639
640 /*
641  * Compare the prefix and suffix with the subject, and check that the
642  * characters in-between are valid.
643  */
644 static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
645                           const unsigned char *suffix, size_t suffix_len,
646                           const unsigned char *subject, size_t subject_len,
647                           unsigned int flags)
648 {
649     const unsigned char *wildcard_start;
650     const unsigned char *wildcard_end;
651     const unsigned char *p;
652     int allow_multi = 0;
653     int allow_idna = 0;
654
655     if (subject_len < prefix_len + suffix_len)
656         return 0;
657     if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
658         return 0;
659     wildcard_start = subject + prefix_len;
660     wildcard_end = subject + (subject_len - suffix_len);
661     if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
662         return 0;
663     /*
664      * If the wildcard makes up the entire first label, it must match at
665      * least one character.
666      */
667     if (prefix_len == 0 && *suffix == '.') {
668         if (wildcard_start == wildcard_end)
669             return 0;
670         allow_idna = 1;
671         if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
672             allow_multi = 1;
673     }
674     /* IDNA labels cannot match partial wildcards */
675     if (!allow_idna &&
676         subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0)
677         return 0;
678     /* The wildcard may match a literal '*' */
679     if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
680         return 1;
681     /*
682      * Check that the part matched by the wildcard contains only
683      * permitted characters and only matches a single label unless
684      * allow_multi is set.
685      */
686     for (p = wildcard_start; p != wildcard_end; ++p)
687         if (!(('0' <= *p && *p <= '9') ||
688               ('A' <= *p && *p <= 'Z') ||
689               ('a' <= *p && *p <= 'z') ||
690               *p == '-' || (allow_multi && *p == '.')))
691             return 0;
692     return 1;
693 }
694
695 #define LABEL_START     (1 << 0)
696 #define LABEL_END       (1 << 1)
697 #define LABEL_HYPHEN    (1 << 2)
698 #define LABEL_IDNA      (1 << 3)
699
700 static const unsigned char *valid_star(const unsigned char *p, size_t len,
701                                        unsigned int flags)
702 {
703     const unsigned char *star = 0;
704     size_t i;
705     int state = LABEL_START;
706     int dots = 0;
707     for (i = 0; i < len; ++i) {
708         /*
709          * Locate first and only legal wildcard, either at the start
710          * or end of a non-IDNA first and not final label.
711          */
712         if (p[i] == '*') {
713             int atstart = (state & LABEL_START);
714             int atend = (i == len - 1 || p[i + 1] == '.');
715             /*-
716              * At most one wildcard per pattern.
717              * No wildcards in IDNA labels.
718              * No wildcards after the first label.
719              */
720             if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
721                 return NULL;
722             /* Only full-label '*.example.com' wildcards? */
723             if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
724                 && (!atstart || !atend))
725                 return NULL;
726             /* No 'foo*bar' wildcards */
727             if (!atstart && !atend)
728                 return NULL;
729             star = &p[i];
730             state &= ~LABEL_START;
731         } else if (('a' <= p[i] && p[i] <= 'z')
732                    || ('A' <= p[i] && p[i] <= 'Z')
733                    || ('0' <= p[i] && p[i] <= '9')) {
734             if ((state & LABEL_START) != 0
735                 && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0)
736                 state |= LABEL_IDNA;
737             state &= ~(LABEL_HYPHEN | LABEL_START);
738         } else if (p[i] == '.') {
739             if ((state & (LABEL_HYPHEN | LABEL_START)) != 0)
740                 return NULL;
741             state = LABEL_START;
742             ++dots;
743         } else if (p[i] == '-') {
744             /* no domain/subdomain starts with '-' */
745             if ((state & LABEL_START) != 0)
746                 return NULL;
747             state |= LABEL_HYPHEN;
748         } else
749             return NULL;
750     }
751
752     /*
753      * The final label must not end in a hyphen or ".", and
754      * there must be at least two dots after the star.
755      */
756     if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
757         return NULL;
758     return star;
759 }
760
761 /* Compare using wildcards. */
762 static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
763                           const unsigned char *subject, size_t subject_len,
764                           unsigned int flags)
765 {
766     const unsigned char *star = NULL;
767
768     /*
769      * Subject names starting with '.' can only match a wildcard pattern
770      * via a subject sub-domain pattern suffix match.
771      */
772     if (!(subject_len > 1 && subject[0] == '.'))
773         star = valid_star(pattern, pattern_len, flags);
774     if (star == NULL)
775         return equal_nocase(pattern, pattern_len,
776                             subject, subject_len, flags);
777     return wildcard_match(pattern, star - pattern,
778                           star + 1, (pattern + pattern_len) - star - 1,
779                           subject, subject_len, flags);
780 }
781
782 /*
783  * Compare an ASN1_STRING to a supplied string. If they match return 1. If
784  * cmp_type > 0 only compare if string matches the type, otherwise convert it
785  * to UTF8.
786  */
787
788 static int do_check_string(const ASN1_STRING *a, int cmp_type, equal_fn equal,
789                            unsigned int flags, const char *b, size_t blen,
790                            char **peername)
791 {
792     int rv = 0;
793
794     if (!a->data || !a->length)
795         return 0;
796     if (cmp_type > 0) {
797         if (cmp_type != a->type)
798             return 0;
799         if (cmp_type == V_ASN1_IA5STRING)
800             rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
801         else if (a->length == (int)blen && !memcmp(a->data, b, blen))
802             rv = 1;
803         if (rv > 0 && peername)
804             *peername = OPENSSL_strndup((char *)a->data, a->length);
805     } else {
806         int astrlen;
807         unsigned char *astr;
808         astrlen = ASN1_STRING_to_UTF8(&astr, a);
809         if (astrlen < 0) {
810             /*
811              * -1 could be an internal malloc failure or a decoding error from
812              * malformed input; we can't distinguish.
813              */
814             return -1;
815         }
816         rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
817         if (rv > 0 && peername)
818             *peername = OPENSSL_strndup((char *)astr, astrlen);
819         OPENSSL_free(astr);
820     }
821     return rv;
822 }
823
824 static int do_x509_check(X509 *x, const char *chk, size_t chklen,
825                          unsigned int flags, int check_type, char **peername)
826 {
827     GENERAL_NAMES *gens = NULL;
828     const X509_NAME *name = NULL;
829     int i;
830     int cnid = NID_undef;
831     int alt_type;
832     int san_present = 0;
833     int rv = 0;
834     equal_fn equal;
835
836     /* See below, this flag is internal-only */
837     flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
838     if (check_type == GEN_EMAIL) {
839         cnid = NID_pkcs9_emailAddress;
840         alt_type = V_ASN1_IA5STRING;
841         equal = equal_email;
842     } else if (check_type == GEN_DNS) {
843         cnid = NID_commonName;
844         /* Implicit client-side DNS sub-domain pattern */
845         if (chklen > 1 && chk[0] == '.')
846             flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
847         alt_type = V_ASN1_IA5STRING;
848         if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
849             equal = equal_nocase;
850         else
851             equal = equal_wildcard;
852     } else {
853         alt_type = V_ASN1_OCTET_STRING;
854         equal = equal_case;
855     }
856
857     if (chklen == 0)
858         chklen = strlen(chk);
859
860     gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
861     if (gens) {
862         for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
863             GENERAL_NAME *gen;
864             ASN1_STRING *cstr;
865             gen = sk_GENERAL_NAME_value(gens, i);
866             if (gen->type != check_type)
867                 continue;
868             san_present = 1;
869             if (check_type == GEN_EMAIL)
870                 cstr = gen->d.rfc822Name;
871             else if (check_type == GEN_DNS)
872                 cstr = gen->d.dNSName;
873             else
874                 cstr = gen->d.iPAddress;
875             /* Positive on success, negative on error! */
876             if ((rv = do_check_string(cstr, alt_type, equal, flags,
877                                       chk, chklen, peername)) != 0)
878                 break;
879         }
880         GENERAL_NAMES_free(gens);
881         if (rv != 0)
882             return rv;
883         if (san_present && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))
884             return 0;
885     }
886
887     /* We're done if CN-ID is not pertinent */
888     if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT))
889         return 0;
890
891     i = -1;
892     name = X509_get_subject_name(x);
893     while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
894         const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i);
895         const ASN1_STRING *str = X509_NAME_ENTRY_get_data(ne);
896
897         /* Positive on success, negative on error! */
898         if ((rv = do_check_string(str, -1, equal, flags,
899                                   chk, chklen, peername)) != 0)
900             return rv;
901     }
902     return 0;
903 }
904
905 int X509_check_host(X509 *x, const char *chk, size_t chklen,
906                     unsigned int flags, char **peername)
907 {
908     if (chk == NULL)
909         return -2;
910     /*
911      * Embedded NULs are disallowed, except as the last character of a
912      * string of length 2 or more (tolerate caller including terminating
913      * NUL in string length).
914      */
915     if (chklen == 0)
916         chklen = strlen(chk);
917     else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
918         return -2;
919     if (chklen > 1 && chk[chklen - 1] == '\0')
920         --chklen;
921     return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
922 }
923
924 int X509_check_email(X509 *x, const char *chk, size_t chklen,
925                      unsigned int flags)
926 {
927     if (chk == NULL)
928         return -2;
929     /*
930      * Embedded NULs are disallowed, except as the last character of a
931      * string of length 2 or more (tolerate caller including terminating
932      * NUL in string length).
933      */
934     if (chklen == 0)
935         chklen = strlen((char *)chk);
936     else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
937         return -2;
938     if (chklen > 1 && chk[chklen - 1] == '\0')
939         --chklen;
940     return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
941 }
942
943 int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
944                   unsigned int flags)
945 {
946     if (chk == NULL)
947         return -2;
948     return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
949 }
950
951 int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
952 {
953     unsigned char ipout[16];
954     size_t iplen;
955
956     if (ipasc == NULL)
957         return -2;
958     iplen = (size_t)a2i_ipadd(ipout, ipasc);
959     if (iplen == 0)
960         return -2;
961     return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
962 }
963
964 /*
965  * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
966  * with RFC3280.
967  */
968
969 ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
970 {
971     unsigned char ipout[16];
972     ASN1_OCTET_STRING *ret;
973     int iplen;
974
975     /* If string contains a ':' assume IPv6 */
976
977     iplen = a2i_ipadd(ipout, ipasc);
978
979     if (!iplen)
980         return NULL;
981
982     ret = ASN1_OCTET_STRING_new();
983     if (ret == NULL)
984         return NULL;
985     if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
986         ASN1_OCTET_STRING_free(ret);
987         return NULL;
988     }
989     return ret;
990 }
991
992 ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
993 {
994     ASN1_OCTET_STRING *ret = NULL;
995     unsigned char ipout[32];
996     char *iptmp = NULL, *p;
997     int iplen1, iplen2;
998
999     p = strchr(ipasc, '/');
1000     if (p == NULL)
1001         return NULL;
1002     iptmp = OPENSSL_strdup(ipasc);
1003     if (iptmp == NULL)
1004         return NULL;
1005     p = iptmp + (p - ipasc);
1006     *p++ = 0;
1007
1008     iplen1 = a2i_ipadd(ipout, iptmp);
1009
1010     if (!iplen1)
1011         goto err;
1012
1013     iplen2 = a2i_ipadd(ipout + iplen1, p);
1014
1015     OPENSSL_free(iptmp);
1016     iptmp = NULL;
1017
1018     if (!iplen2 || (iplen1 != iplen2))
1019         goto err;
1020
1021     ret = ASN1_OCTET_STRING_new();
1022     if (ret == NULL)
1023         goto err;
1024     if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
1025         goto err;
1026
1027     return ret;
1028
1029  err:
1030     OPENSSL_free(iptmp);
1031     ASN1_OCTET_STRING_free(ret);
1032     return NULL;
1033 }
1034
1035 int a2i_ipadd(unsigned char *ipout, const char *ipasc)
1036 {
1037     /* If string contains a ':' assume IPv6 */
1038
1039     if (strchr(ipasc, ':')) {
1040         if (!ipv6_from_asc(ipout, ipasc))
1041             return 0;
1042         return 16;
1043     } else {
1044         if (!ipv4_from_asc(ipout, ipasc))
1045             return 0;
1046         return 4;
1047     }
1048 }
1049
1050 static int ipv4_from_asc(unsigned char *v4, const char *in)
1051 {
1052     int a0, a1, a2, a3;
1053     if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
1054         return 0;
1055     if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
1056         || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
1057         return 0;
1058     v4[0] = a0;
1059     v4[1] = a1;
1060     v4[2] = a2;
1061     v4[3] = a3;
1062     return 1;
1063 }
1064
1065 typedef struct {
1066     /* Temporary store for IPV6 output */
1067     unsigned char tmp[16];
1068     /* Total number of bytes in tmp */
1069     int total;
1070     /* The position of a zero (corresponding to '::') */
1071     int zero_pos;
1072     /* Number of zeroes */
1073     int zero_cnt;
1074 } IPV6_STAT;
1075
1076 static int ipv6_from_asc(unsigned char *v6, const char *in)
1077 {
1078     IPV6_STAT v6stat;
1079     v6stat.total = 0;
1080     v6stat.zero_pos = -1;
1081     v6stat.zero_cnt = 0;
1082     /*
1083      * Treat the IPv6 representation as a list of values separated by ':'.
1084      * The presence of a '::' will parse as one, two or three zero length
1085      * elements.
1086      */
1087     if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
1088         return 0;
1089
1090     /* Now for some sanity checks */
1091
1092     if (v6stat.zero_pos == -1) {
1093         /* If no '::' must have exactly 16 bytes */
1094         if (v6stat.total != 16)
1095             return 0;
1096     } else {
1097         /* If '::' must have less than 16 bytes */
1098         if (v6stat.total == 16)
1099             return 0;
1100         /* More than three zeroes is an error */
1101         if (v6stat.zero_cnt > 3)
1102             return 0;
1103         /* Can only have three zeroes if nothing else present */
1104         else if (v6stat.zero_cnt == 3) {
1105             if (v6stat.total > 0)
1106                 return 0;
1107         }
1108         /* Can only have two zeroes if at start or end */
1109         else if (v6stat.zero_cnt == 2) {
1110             if ((v6stat.zero_pos != 0)
1111                 && (v6stat.zero_pos != v6stat.total))
1112                 return 0;
1113         } else
1114             /* Can only have one zero if *not* start or end */
1115         {
1116             if ((v6stat.zero_pos == 0)
1117                 || (v6stat.zero_pos == v6stat.total))
1118                 return 0;
1119         }
1120     }
1121
1122     /* Format result */
1123
1124     if (v6stat.zero_pos >= 0) {
1125         /* Copy initial part */
1126         memcpy(v6, v6stat.tmp, v6stat.zero_pos);
1127         /* Zero middle */
1128         memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
1129         /* Copy final part */
1130         if (v6stat.total != v6stat.zero_pos)
1131             memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
1132                    v6stat.tmp + v6stat.zero_pos,
1133                    v6stat.total - v6stat.zero_pos);
1134     } else
1135         memcpy(v6, v6stat.tmp, 16);
1136
1137     return 1;
1138 }
1139
1140 static int ipv6_cb(const char *elem, int len, void *usr)
1141 {
1142     IPV6_STAT *s = usr;
1143     /* Error if 16 bytes written */
1144     if (s->total == 16)
1145         return 0;
1146     if (len == 0) {
1147         /* Zero length element, corresponds to '::' */
1148         if (s->zero_pos == -1)
1149             s->zero_pos = s->total;
1150         /* If we've already got a :: its an error */
1151         else if (s->zero_pos != s->total)
1152             return 0;
1153         s->zero_cnt++;
1154     } else {
1155         /* If more than 4 characters could be final a.b.c.d form */
1156         if (len > 4) {
1157             /* Need at least 4 bytes left */
1158             if (s->total > 12)
1159                 return 0;
1160             /* Must be end of string */
1161             if (elem[len])
1162                 return 0;
1163             if (!ipv4_from_asc(s->tmp + s->total, elem))
1164                 return 0;
1165             s->total += 4;
1166         } else {
1167             if (!ipv6_hex(s->tmp + s->total, elem, len))
1168                 return 0;
1169             s->total += 2;
1170         }
1171     }
1172     return 1;
1173 }
1174
1175 /*
1176  * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
1177  */
1178
1179 static int ipv6_hex(unsigned char *out, const char *in, int inlen)
1180 {
1181     unsigned char c;
1182     unsigned int num = 0;
1183     int x;
1184
1185     if (inlen > 4)
1186         return 0;
1187     while (inlen--) {
1188         c = *in++;
1189         num <<= 4;
1190         x = OPENSSL_hexchar2int(c);
1191         if (x < 0)
1192             return 0;
1193         num |= (char)x;
1194     }
1195     out[0] = num >> 8;
1196     out[1] = num & 0xff;
1197     return 1;
1198 }
1199
1200 int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
1201                              unsigned long chtype)
1202 {
1203     CONF_VALUE *v;
1204     int i, mval, spec_char, plus_char;
1205     char *p, *type;
1206     if (!nm)
1207         return 0;
1208
1209     for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1210         v = sk_CONF_VALUE_value(dn_sk, i);
1211         type = v->name;
1212         /*
1213          * Skip past any leading X. X: X, etc to allow for multiple instances
1214          */
1215         for (p = type; *p; p++) {
1216 #ifndef CHARSET_EBCDIC
1217             spec_char = ((*p == ':') || (*p == ',') || (*p == '.'));
1218 #else
1219             spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[','])
1220                     || (*p == os_toascii['.']));
1221 #endif
1222             if (spec_char) {
1223                 p++;
1224                 if (*p)
1225                     type = p;
1226                 break;
1227             }
1228         }
1229 #ifndef CHARSET_EBCDIC
1230         plus_char = (*type == '+');
1231 #else
1232         plus_char = (*type == os_toascii['+']);
1233 #endif
1234         if (plus_char) {
1235             mval = -1;
1236             type++;
1237         } else
1238             mval = 0;
1239         if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
1240                                         (unsigned char *)v->value, -1, -1,
1241                                         mval))
1242             return 0;
1243
1244     }
1245     return 1;
1246 }