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