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