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