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