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