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