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