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