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