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