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