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