1 /* $OpenBSD: x509_vpm.c,v 1.26 2021/04/24 18:10:12 tb Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2004. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2004 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@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@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <stdio.h> 60 #include <string.h> 61 62 #include <openssl/buffer.h> 63 #include <openssl/crypto.h> 64 #include <openssl/lhash.h> 65 #include <openssl/stack.h> 66 #include <openssl/x509.h> 67 #include <openssl/x509v3.h> 68 69 #include "vpm_int.h" 70 71 /* X509_VERIFY_PARAM functions */ 72 73 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, 74 size_t emaillen); 75 int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, 76 size_t iplen); 77 78 #define SET_HOST 0 79 #define ADD_HOST 1 80 81 static void 82 str_free(char *s) 83 { 84 free(s); 85 } 86 87 #define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) 88 89 90 /* 91 * Post 1.0.1 sk function "deep_copy". For the moment we simply make 92 * these take void * and use them directly without a glorious blob of 93 * obfuscating macros of dubious value in front of them. All this in 94 * preparation for a rototilling of safestack.h (likely inspired by 95 * this). 96 */ 97 static void * 98 sk_deep_copy(void *sk_void, void *copy_func_void, void *free_func_void) 99 { 100 _STACK *sk = sk_void; 101 void *(*copy_func)(void *) = copy_func_void; 102 void (*free_func)(void *) = free_func_void; 103 _STACK *ret = sk_dup(sk); 104 size_t i; 105 106 if (ret == NULL) 107 return NULL; 108 109 for (i = 0; i < ret->num; i++) { 110 if (ret->data[i] == NULL) 111 continue; 112 ret->data[i] = copy_func(ret->data[i]); 113 if (ret->data[i] == NULL) { 114 size_t j; 115 for (j = 0; j < i; j++) { 116 if (ret->data[j] != NULL) 117 free_func(ret->data[j]); 118 } 119 sk_free(ret); 120 return NULL; 121 } 122 } 123 124 return ret; 125 } 126 127 static int 128 x509_param_set_hosts_internal(X509_VERIFY_PARAM_ID *id, int mode, 129 const char *name, size_t namelen) 130 { 131 char *copy; 132 133 if (name != NULL && namelen == 0) 134 namelen = strlen(name); 135 /* 136 * Refuse names with embedded NUL bytes. 137 */ 138 if (name && memchr(name, '\0', namelen)) 139 return 0; 140 141 if (mode == SET_HOST && id->hosts) { 142 string_stack_free(id->hosts); 143 id->hosts = NULL; 144 } 145 if (name == NULL || namelen == 0) 146 return 1; 147 copy = strndup(name, namelen); 148 if (copy == NULL) 149 return 0; 150 151 if (id->hosts == NULL && 152 (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { 153 free(copy); 154 return 0; 155 } 156 157 if (!sk_OPENSSL_STRING_push(id->hosts, copy)) { 158 free(copy); 159 if (sk_OPENSSL_STRING_num(id->hosts) == 0) { 160 sk_OPENSSL_STRING_free(id->hosts); 161 id->hosts = NULL; 162 } 163 return 0; 164 } 165 166 return 1; 167 } 168 169 static void 170 x509_verify_param_zero(X509_VERIFY_PARAM *param) 171 { 172 X509_VERIFY_PARAM_ID *paramid; 173 if (!param) 174 return; 175 free(param->name); 176 param->name = NULL; 177 param->purpose = 0; 178 param->trust = 0; 179 /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/ 180 param->inh_flags = 0; 181 param->flags = 0; 182 param->depth = -1; 183 if (param->policies) { 184 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); 185 param->policies = NULL; 186 } 187 paramid = param->id; 188 if (paramid->hosts) { 189 string_stack_free(paramid->hosts); 190 paramid->hosts = NULL; 191 } 192 free(paramid->peername); 193 paramid->peername = NULL; 194 free(paramid->email); 195 paramid->email = NULL; 196 paramid->emaillen = 0; 197 free(paramid->ip); 198 paramid->ip = NULL; 199 paramid->iplen = 0; 200 paramid->poisoned = 0; 201 } 202 203 X509_VERIFY_PARAM * 204 X509_VERIFY_PARAM_new(void) 205 { 206 X509_VERIFY_PARAM *param; 207 X509_VERIFY_PARAM_ID *paramid; 208 param = calloc(1, sizeof(X509_VERIFY_PARAM)); 209 if (param == NULL) 210 return NULL; 211 paramid = calloc(1, sizeof(X509_VERIFY_PARAM_ID)); 212 if (paramid == NULL) { 213 free(param); 214 return NULL; 215 } 216 param->id = paramid; 217 x509_verify_param_zero(param); 218 return param; 219 } 220 221 void 222 X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) 223 { 224 if (param == NULL) 225 return; 226 x509_verify_param_zero(param); 227 free(param->id); 228 free(param); 229 } 230 231 /* 232 * This function determines how parameters are "inherited" from one structure 233 * to another. There are several different ways this can happen. 234 * 235 * 1. If a child structure needs to have its values initialized from a parent 236 * they are simply copied across. For example SSL_CTX copied to SSL. 237 * 2. If the structure should take on values only if they are currently unset. 238 * For example the values in an SSL structure will take appropriate value 239 * for SSL servers or clients but only if the application has not set new 240 * ones. 241 * 242 * The "inh_flags" field determines how this function behaves. 243 * 244 * Normally any values which are set in the default are not copied from the 245 * destination and verify flags are ORed together. 246 * 247 * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied 248 * to the destination. Effectively the values in "to" become default values 249 * which will be used only if nothing new is set in "from". 250 * 251 * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether 252 * they are set or not. Flags is still Ored though. 253 * 254 * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead 255 * of ORed. 256 * 257 * If X509_VP_FLAG_LOCKED is set then no values are copied. 258 * 259 * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed 260 * after the next call. 261 */ 262 263 /* Macro to test if a field should be copied from src to dest */ 264 265 #define test_x509_verify_param_copy(field, def) \ 266 (to_overwrite || \ 267 ((src->field != def) && (to_default || (dest->field == def)))) 268 269 /* As above but for ID fields */ 270 271 #define test_x509_verify_param_copy_id(idf, def) \ 272 test_x509_verify_param_copy(id->idf, def) 273 274 /* Macro to test and copy a field if necessary */ 275 276 #define x509_verify_param_copy(field, def) \ 277 if (test_x509_verify_param_copy(field, def)) \ 278 dest->field = src->field 279 280 int 281 X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) 282 { 283 unsigned long inh_flags; 284 int to_default, to_overwrite; 285 X509_VERIFY_PARAM_ID *id; 286 287 if (!src) 288 return 1; 289 id = src->id; 290 inh_flags = dest->inh_flags | src->inh_flags; 291 292 if (inh_flags & X509_VP_FLAG_ONCE) 293 dest->inh_flags = 0; 294 295 if (inh_flags & X509_VP_FLAG_LOCKED) 296 return 1; 297 298 if (inh_flags & X509_VP_FLAG_DEFAULT) 299 to_default = 1; 300 else 301 to_default = 0; 302 303 if (inh_flags & X509_VP_FLAG_OVERWRITE) 304 to_overwrite = 1; 305 else 306 to_overwrite = 0; 307 308 x509_verify_param_copy(purpose, 0); 309 x509_verify_param_copy(trust, 0); 310 x509_verify_param_copy(depth, -1); 311 312 /* If overwrite or check time not set, copy across */ 313 314 if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { 315 dest->check_time = src->check_time; 316 dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; 317 /* Don't need to copy flag: that is done below */ 318 } 319 320 if (inh_flags & X509_VP_FLAG_RESET_FLAGS) 321 dest->flags = 0; 322 323 dest->flags |= src->flags; 324 325 if (test_x509_verify_param_copy(policies, NULL)) { 326 if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) 327 return 0; 328 } 329 330 /* Copy the host flags if and only if we're copying the host list */ 331 if (test_x509_verify_param_copy_id(hosts, NULL)) { 332 if (dest->id->hosts) { 333 string_stack_free(dest->id->hosts); 334 dest->id->hosts = NULL; 335 } 336 if (id->hosts) { 337 dest->id->hosts = 338 sk_deep_copy(id->hosts, strdup, str_free); 339 if (dest->id->hosts == NULL) 340 return 0; 341 dest->id->hostflags = id->hostflags; 342 } 343 } 344 345 if (test_x509_verify_param_copy_id(email, NULL)) { 346 if (!X509_VERIFY_PARAM_set1_email(dest, id->email, 347 id->emaillen)) 348 return 0; 349 } 350 351 if (test_x509_verify_param_copy_id(ip, NULL)) { 352 if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen)) 353 return 0; 354 } 355 356 return 1; 357 } 358 359 int 360 X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) 361 { 362 unsigned long save_flags = to->inh_flags; 363 int ret; 364 365 to->inh_flags |= X509_VP_FLAG_DEFAULT; 366 ret = X509_VERIFY_PARAM_inherit(to, from); 367 to->inh_flags = save_flags; 368 return ret; 369 } 370 371 static int 372 x509_param_set1_internal(char **pdest, size_t *pdestlen, const char *src, 373 size_t srclen, int nonul) 374 { 375 char *tmp; 376 377 if (src == NULL) 378 return 0; 379 380 if (srclen == 0) { 381 srclen = strlen(src); 382 if (srclen == 0) 383 return 0; 384 if ((tmp = strdup(src)) == NULL) 385 return 0; 386 } else { 387 if (nonul && memchr(src, '\0', srclen)) 388 return 0; 389 if ((tmp = malloc(srclen)) == NULL) 390 return 0; 391 memcpy(tmp, src, srclen); 392 } 393 394 if (*pdest) 395 free(*pdest); 396 *pdest = tmp; 397 if (pdestlen) 398 *pdestlen = srclen; 399 return 1; 400 } 401 402 int 403 X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) 404 { 405 free(param->name); 406 param->name = NULL; 407 if (name == NULL) 408 return 1; 409 param->name = strdup(name); 410 if (param->name) 411 return 1; 412 return 0; 413 } 414 415 int 416 X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) 417 { 418 param->flags |= flags; 419 if (flags & X509_V_FLAG_POLICY_MASK) 420 param->flags |= X509_V_FLAG_POLICY_CHECK; 421 return 1; 422 } 423 424 int 425 X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags) 426 { 427 param->flags &= ~flags; 428 return 1; 429 } 430 431 unsigned long 432 X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) 433 { 434 return param->flags; 435 } 436 437 int 438 X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) 439 { 440 return X509_PURPOSE_set(¶m->purpose, purpose); 441 } 442 443 int 444 X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) 445 { 446 return X509_TRUST_set(¶m->trust, trust); 447 } 448 449 void 450 X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) 451 { 452 param->depth = depth; 453 } 454 455 void 456 X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) 457 { 458 param->check_time = t; 459 param->flags |= X509_V_FLAG_USE_CHECK_TIME; 460 } 461 462 int 463 X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) 464 { 465 if (!param->policies) { 466 param->policies = sk_ASN1_OBJECT_new_null(); 467 if (!param->policies) 468 return 0; 469 } 470 if (!sk_ASN1_OBJECT_push(param->policies, policy)) 471 return 0; 472 return 1; 473 } 474 475 int 476 X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 477 STACK_OF(ASN1_OBJECT) *policies) 478 { 479 int i; 480 ASN1_OBJECT *oid, *doid; 481 482 if (!param) 483 return 0; 484 if (param->policies) 485 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); 486 487 if (!policies) { 488 param->policies = NULL; 489 return 1; 490 } 491 492 param->policies = sk_ASN1_OBJECT_new_null(); 493 if (!param->policies) 494 return 0; 495 496 for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { 497 oid = sk_ASN1_OBJECT_value(policies, i); 498 doid = OBJ_dup(oid); 499 if (!doid) 500 return 0; 501 if (!sk_ASN1_OBJECT_push(param->policies, doid)) { 502 ASN1_OBJECT_free(doid); 503 return 0; 504 } 505 } 506 param->flags |= X509_V_FLAG_POLICY_CHECK; 507 return 1; 508 } 509 510 int 511 X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, 512 const char *name, size_t namelen) 513 { 514 if (x509_param_set_hosts_internal(param->id, SET_HOST, name, namelen)) 515 return 1; 516 param->id->poisoned = 1; 517 return 0; 518 } 519 520 int 521 X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, 522 const char *name, size_t namelen) 523 { 524 if (x509_param_set_hosts_internal(param->id, ADD_HOST, name, namelen)) 525 return 1; 526 param->id->poisoned = 1; 527 return 0; 528 } 529 530 void 531 X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags) 532 { 533 param->id->hostflags = flags; 534 } 535 536 char * 537 X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) 538 { 539 return param->id->peername; 540 } 541 542 int 543 X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, 544 size_t emaillen) 545 { 546 if (x509_param_set1_internal(¶m->id->email, ¶m->id->emaillen, 547 email, emaillen, 1)) 548 return 1; 549 param->id->poisoned = 1; 550 return 0; 551 } 552 553 int 554 X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, 555 size_t iplen) 556 { 557 if (iplen != 4 && iplen != 16) 558 goto err; 559 if (x509_param_set1_internal((char **)¶m->id->ip, ¶m->id->iplen, 560 (char *)ip, iplen, 0)) 561 return 1; 562 err: 563 param->id->poisoned = 1; 564 return 0; 565 } 566 567 int 568 X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) 569 { 570 unsigned char ipout[16]; 571 size_t iplen; 572 573 iplen = (size_t)a2i_ipadd(ipout, ipasc); 574 return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); 575 } 576 577 int 578 X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) 579 { 580 return param->depth; 581 } 582 583 const char * 584 X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) 585 { 586 return param->name; 587 } 588 589 static const X509_VERIFY_PARAM_ID _empty_id = { NULL }; 590 591 #define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id 592 593 /* 594 * Default verify parameters: these are used for various applications and can 595 * be overridden by the user specified table. 596 */ 597 598 static const X509_VERIFY_PARAM default_table[] = { 599 { 600 .name = "default", 601 .depth = 100, 602 .trust = 0, /* XXX This is not the default trust value */ 603 .id = vpm_empty_id 604 }, 605 { 606 .name = "pkcs7", 607 .purpose = X509_PURPOSE_SMIME_SIGN, 608 .trust = X509_TRUST_EMAIL, 609 .depth = -1, 610 .id = vpm_empty_id 611 }, 612 { 613 .name = "smime_sign", 614 .purpose = X509_PURPOSE_SMIME_SIGN, 615 .trust = X509_TRUST_EMAIL, 616 .depth = -1, 617 .id = vpm_empty_id 618 }, 619 { 620 .name = "ssl_client", 621 .purpose = X509_PURPOSE_SSL_CLIENT, 622 .trust = X509_TRUST_SSL_CLIENT, 623 .depth = -1, 624 .id = vpm_empty_id 625 }, 626 { 627 .name = "ssl_server", 628 .purpose = X509_PURPOSE_SSL_SERVER, 629 .trust = X509_TRUST_SSL_SERVER, 630 .depth = -1, 631 .id = vpm_empty_id 632 } 633 }; 634 635 static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; 636 637 static int 638 param_cmp(const X509_VERIFY_PARAM * const *a, 639 const X509_VERIFY_PARAM * const *b) 640 { 641 return strcmp((*a)->name, (*b)->name); 642 } 643 644 int 645 X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) 646 { 647 X509_VERIFY_PARAM *ptmp; 648 if (!param_table) { 649 param_table = sk_X509_VERIFY_PARAM_new(param_cmp); 650 if (!param_table) 651 return 0; 652 } else { 653 size_t idx; 654 655 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param)) 656 != -1) { 657 ptmp = sk_X509_VERIFY_PARAM_value(param_table, 658 idx); 659 X509_VERIFY_PARAM_free(ptmp); 660 (void)sk_X509_VERIFY_PARAM_delete(param_table, 661 idx); 662 } 663 } 664 if (!sk_X509_VERIFY_PARAM_push(param_table, param)) 665 return 0; 666 return 1; 667 } 668 669 int 670 X509_VERIFY_PARAM_get_count(void) 671 { 672 int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); 673 if (param_table) 674 num += sk_X509_VERIFY_PARAM_num(param_table); 675 return num; 676 } 677 678 const X509_VERIFY_PARAM * 679 X509_VERIFY_PARAM_get0(int id) 680 { 681 int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); 682 if (id < num) 683 return default_table + id; 684 return sk_X509_VERIFY_PARAM_value(param_table, id - num); 685 } 686 687 const X509_VERIFY_PARAM * 688 X509_VERIFY_PARAM_lookup(const char *name) 689 { 690 X509_VERIFY_PARAM pm; 691 unsigned int i, limit; 692 693 pm.name = (char *)name; 694 if (param_table) { 695 size_t idx; 696 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1) 697 return sk_X509_VERIFY_PARAM_value(param_table, idx); 698 } 699 700 limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); 701 for (i = 0; i < limit; i++) { 702 if (strcmp(default_table[i].name, name) == 0) { 703 return &default_table[i]; 704 } 705 } 706 return NULL; 707 } 708 709 void 710 X509_VERIFY_PARAM_table_cleanup(void) 711 { 712 if (param_table) 713 sk_X509_VERIFY_PARAM_pop_free(param_table, 714 X509_VERIFY_PARAM_free); 715 param_table = NULL; 716 } 717