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