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