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