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