1 /* 2 * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "hx_locl.h" 35 #include "crypto-headers.h" 36 #include <rtbl.h> 37 38 /** 39 * @page page_cert The basic certificate 40 * 41 * The basic hx509 cerificate object in hx509 is hx509_cert. The 42 * hx509_cert object is representing one X509/PKIX certificate and 43 * associated attributes; like private key, friendly name, etc. 44 * 45 * A hx509_cert object is usully found via the keyset interfaces (@ref 46 * page_keyset), but its also possible to create a certificate 47 * directly from a parsed object with hx509_cert_init() and 48 * hx509_cert_init_data(). 49 * 50 * See the library functions here: @ref hx509_cert 51 */ 52 53 struct hx509_verify_ctx_data { 54 hx509_certs trust_anchors; 55 int flags; 56 #define HX509_VERIFY_CTX_F_TIME_SET 1 57 #define HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE 2 58 #define HX509_VERIFY_CTX_F_REQUIRE_RFC3280 4 59 #define HX509_VERIFY_CTX_F_CHECK_TRUST_ANCHORS 8 60 #define HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS 16 61 #define HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK 32 62 time_t time_now; 63 unsigned int max_depth; 64 #define HX509_VERIFY_MAX_DEPTH 30 65 hx509_revoke_ctx revoke_ctx; 66 }; 67 68 #define REQUIRE_RFC3280(ctx) ((ctx)->flags & HX509_VERIFY_CTX_F_REQUIRE_RFC3280) 69 #define CHECK_TA(ctx) ((ctx)->flags & HX509_VERIFY_CTX_F_CHECK_TRUST_ANCHORS) 70 #define ALLOW_DEF_TA(ctx) (((ctx)->flags & HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS) == 0) 71 72 struct _hx509_cert_attrs { 73 size_t len; 74 hx509_cert_attribute *val; 75 }; 76 77 struct hx509_cert_data { 78 unsigned int ref; 79 char *friendlyname; 80 Certificate *data; 81 hx509_private_key private_key; 82 struct _hx509_cert_attrs attrs; 83 hx509_name basename; 84 _hx509_cert_release_func release; 85 void *ctx; 86 }; 87 88 typedef struct hx509_name_constraints { 89 NameConstraints *val; 90 size_t len; 91 } hx509_name_constraints; 92 93 #define GeneralSubtrees_SET(g,var) \ 94 (g)->len = (var)->len, (g)->val = (var)->val; 95 96 /** 97 * Creates a hx509 context that most functions in the library 98 * uses. The context is only allowed to be used by one thread at each 99 * moment. Free the context with hx509_context_free(). 100 * 101 * @param context Returns a pointer to new hx509 context. 102 * 103 * @return Returns an hx509 error code. 104 * 105 * @ingroup hx509 106 */ 107 108 int 109 hx509_context_init(hx509_context *context) 110 { 111 *context = calloc(1, sizeof(**context)); 112 if (*context == NULL) 113 return ENOMEM; 114 115 _hx509_ks_null_register(*context); 116 _hx509_ks_mem_register(*context); 117 _hx509_ks_file_register(*context); 118 _hx509_ks_pkcs12_register(*context); 119 _hx509_ks_pkcs11_register(*context); 120 _hx509_ks_dir_register(*context); 121 _hx509_ks_keychain_register(*context); 122 123 ENGINE_add_conf_module(); 124 OpenSSL_add_all_algorithms(); 125 126 (*context)->ocsp_time_diff = HX509_DEFAULT_OCSP_TIME_DIFF; 127 128 initialize_hx_error_table_r(&(*context)->et_list); 129 initialize_asn1_error_table_r(&(*context)->et_list); 130 131 #ifdef HX509_DEFAULT_ANCHORS 132 (void)hx509_certs_init(*context, HX509_DEFAULT_ANCHORS, 0, 133 NULL, &(*context)->default_trust_anchors); 134 #endif 135 136 return 0; 137 } 138 139 /** 140 * Selects if the hx509_revoke_verify() function is going to require 141 * the existans of a revokation method (OCSP, CRL) or not. Note that 142 * hx509_verify_path(), hx509_cms_verify_signed(), and other function 143 * call hx509_revoke_verify(). 144 * 145 * @param context hx509 context to change the flag for. 146 * @param flag zero, revokation method required, non zero missing 147 * revokation method ok 148 * 149 * @ingroup hx509_verify 150 */ 151 152 void 153 hx509_context_set_missing_revoke(hx509_context context, int flag) 154 { 155 if (flag) 156 context->flags |= HX509_CTX_VERIFY_MISSING_OK; 157 else 158 context->flags &= ~HX509_CTX_VERIFY_MISSING_OK; 159 } 160 161 /** 162 * Free the context allocated by hx509_context_init(). 163 * 164 * @param context context to be freed. 165 * 166 * @ingroup hx509 167 */ 168 169 void 170 hx509_context_free(hx509_context *context) 171 { 172 hx509_clear_error_string(*context); 173 if ((*context)->ks_ops) { 174 free((*context)->ks_ops); 175 (*context)->ks_ops = NULL; 176 } 177 (*context)->ks_num_ops = 0; 178 free_error_table ((*context)->et_list); 179 if ((*context)->querystat) 180 free((*context)->querystat); 181 memset(*context, 0, sizeof(**context)); 182 free(*context); 183 *context = NULL; 184 } 185 186 /* 187 * 188 */ 189 190 Certificate * 191 _hx509_get_cert(hx509_cert cert) 192 { 193 return cert->data; 194 } 195 196 /* 197 * 198 */ 199 200 int 201 _hx509_cert_get_version(const Certificate *t) 202 { 203 return t->tbsCertificate.version ? *t->tbsCertificate.version + 1 : 1; 204 } 205 206 /** 207 * Allocate and init an hx509 certificate object from the decoded 208 * certificate `c´. 209 * 210 * @param context A hx509 context. 211 * @param c 212 * @param cert 213 * 214 * @return Returns an hx509 error code. 215 * 216 * @ingroup hx509_cert 217 */ 218 219 int 220 hx509_cert_init(hx509_context context, const Certificate *c, hx509_cert *cert) 221 { 222 int ret; 223 224 *cert = malloc(sizeof(**cert)); 225 if (*cert == NULL) 226 return ENOMEM; 227 (*cert)->ref = 1; 228 (*cert)->friendlyname = NULL; 229 (*cert)->attrs.len = 0; 230 (*cert)->attrs.val = NULL; 231 (*cert)->private_key = NULL; 232 (*cert)->basename = NULL; 233 (*cert)->release = NULL; 234 (*cert)->ctx = NULL; 235 236 (*cert)->data = calloc(1, sizeof(*(*cert)->data)); 237 if ((*cert)->data == NULL) { 238 free(*cert); 239 return ENOMEM; 240 } 241 ret = copy_Certificate(c, (*cert)->data); 242 if (ret) { 243 free((*cert)->data); 244 free(*cert); 245 *cert = NULL; 246 } 247 return ret; 248 } 249 250 /** 251 * Just like hx509_cert_init(), but instead of a decode certificate 252 * takes an pointer and length to a memory region that contains a 253 * DER/BER encoded certificate. 254 * 255 * If the memory region doesn't contain just the certificate and 256 * nothing more the function will fail with 257 * HX509_EXTRA_DATA_AFTER_STRUCTURE. 258 * 259 * @param context A hx509 context. 260 * @param ptr pointer to memory region containing encoded certificate. 261 * @param len length of memory region. 262 * @param cert a return pointer to a hx509 certificate object, will 263 * contain NULL on error. 264 * 265 * @return An hx509 error code, see hx509_get_error_string(). 266 * 267 * @ingroup hx509_cert 268 */ 269 270 int 271 hx509_cert_init_data(hx509_context context, 272 const void *ptr, 273 size_t len, 274 hx509_cert *cert) 275 { 276 Certificate t; 277 size_t size; 278 int ret; 279 280 ret = decode_Certificate(ptr, len, &t, &size); 281 if (ret) { 282 hx509_set_error_string(context, 0, ret, "Failed to decode certificate"); 283 return ret; 284 } 285 if (size != len) { 286 free_Certificate(&t); 287 hx509_set_error_string(context, 0, HX509_EXTRA_DATA_AFTER_STRUCTURE, 288 "Extra data after certificate"); 289 return HX509_EXTRA_DATA_AFTER_STRUCTURE; 290 } 291 292 ret = hx509_cert_init(context, &t, cert); 293 free_Certificate(&t); 294 return ret; 295 } 296 297 void 298 _hx509_cert_set_release(hx509_cert cert, 299 _hx509_cert_release_func release, 300 void *ctx) 301 { 302 cert->release = release; 303 cert->ctx = ctx; 304 } 305 306 307 /* Doesn't make a copy of `private_key'. */ 308 309 int 310 _hx509_cert_assign_key(hx509_cert cert, hx509_private_key private_key) 311 { 312 if (cert->private_key) 313 hx509_private_key_free(&cert->private_key); 314 cert->private_key = _hx509_private_key_ref(private_key); 315 return 0; 316 } 317 318 /** 319 * Free reference to the hx509 certificate object, if the refcounter 320 * reaches 0, the object if freed. Its allowed to pass in NULL. 321 * 322 * @param cert the cert to free. 323 * 324 * @ingroup hx509_cert 325 */ 326 327 void 328 hx509_cert_free(hx509_cert cert) 329 { 330 size_t i; 331 332 if (cert == NULL) 333 return; 334 335 if (cert->ref <= 0) 336 _hx509_abort("cert refcount <= 0 on free"); 337 if (--cert->ref > 0) 338 return; 339 340 if (cert->release) 341 (cert->release)(cert, cert->ctx); 342 343 if (cert->private_key) 344 hx509_private_key_free(&cert->private_key); 345 346 free_Certificate(cert->data); 347 free(cert->data); 348 349 for (i = 0; i < cert->attrs.len; i++) { 350 der_free_octet_string(&cert->attrs.val[i]->data); 351 der_free_oid(&cert->attrs.val[i]->oid); 352 free(cert->attrs.val[i]); 353 } 354 free(cert->attrs.val); 355 free(cert->friendlyname); 356 if (cert->basename) 357 hx509_name_free(&cert->basename); 358 memset(cert, 0, sizeof(*cert)); 359 free(cert); 360 } 361 362 /** 363 * Add a reference to a hx509 certificate object. 364 * 365 * @param cert a pointer to an hx509 certificate object. 366 * 367 * @return the same object as is passed in. 368 * 369 * @ingroup hx509_cert 370 */ 371 372 hx509_cert 373 hx509_cert_ref(hx509_cert cert) 374 { 375 if (cert == NULL) 376 return NULL; 377 if (cert->ref <= 0) 378 _hx509_abort("cert refcount <= 0"); 379 cert->ref++; 380 if (cert->ref == 0) 381 _hx509_abort("cert refcount == 0"); 382 return cert; 383 } 384 385 /** 386 * Allocate an verification context that is used fo control the 387 * verification process. 388 * 389 * @param context A hx509 context. 390 * @param ctx returns a pointer to a hx509_verify_ctx object. 391 * 392 * @return An hx509 error code, see hx509_get_error_string(). 393 * 394 * @ingroup hx509_verify 395 */ 396 397 int 398 hx509_verify_init_ctx(hx509_context context, hx509_verify_ctx *ctx) 399 { 400 hx509_verify_ctx c; 401 402 c = calloc(1, sizeof(*c)); 403 if (c == NULL) 404 return ENOMEM; 405 406 c->max_depth = HX509_VERIFY_MAX_DEPTH; 407 408 *ctx = c; 409 410 return 0; 411 } 412 413 /** 414 * Free an hx509 verification context. 415 * 416 * @param ctx the context to be freed. 417 * 418 * @ingroup hx509_verify 419 */ 420 421 void 422 hx509_verify_destroy_ctx(hx509_verify_ctx ctx) 423 { 424 if (ctx) { 425 hx509_certs_free(&ctx->trust_anchors); 426 hx509_revoke_free(&ctx->revoke_ctx); 427 memset(ctx, 0, sizeof(*ctx)); 428 } 429 free(ctx); 430 } 431 432 /** 433 * Set the trust anchors in the verification context, makes an 434 * reference to the keyset, so the consumer can free the keyset 435 * independent of the destruction of the verification context (ctx). 436 * If there already is a keyset attached, it's released. 437 * 438 * @param ctx a verification context 439 * @param set a keyset containing the trust anchors. 440 * 441 * @ingroup hx509_verify 442 */ 443 444 void 445 hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set) 446 { 447 if (ctx->trust_anchors) 448 hx509_certs_free(&ctx->trust_anchors); 449 ctx->trust_anchors = hx509_certs_ref(set); 450 } 451 452 /** 453 * Attach an revocation context to the verfication context, , makes an 454 * reference to the revoke context, so the consumer can free the 455 * revoke context independent of the destruction of the verification 456 * context. If there is no revoke context, the verification process is 457 * NOT going to check any verification status. 458 * 459 * @param ctx a verification context. 460 * @param revoke_ctx a revoke context. 461 * 462 * @ingroup hx509_verify 463 */ 464 465 void 466 hx509_verify_attach_revoke(hx509_verify_ctx ctx, hx509_revoke_ctx revoke_ctx) 467 { 468 if (ctx->revoke_ctx) 469 hx509_revoke_free(&ctx->revoke_ctx); 470 ctx->revoke_ctx = _hx509_revoke_ref(revoke_ctx); 471 } 472 473 /** 474 * Set the clock time the the verification process is going to 475 * use. Used to check certificate in the past and future time. If not 476 * set the current time will be used. 477 * 478 * @param ctx a verification context. 479 * @param t the time the verifiation is using. 480 * 481 * 482 * @ingroup hx509_verify 483 */ 484 485 void 486 hx509_verify_set_time(hx509_verify_ctx ctx, time_t t) 487 { 488 ctx->flags |= HX509_VERIFY_CTX_F_TIME_SET; 489 ctx->time_now = t; 490 } 491 492 time_t 493 _hx509_verify_get_time(hx509_verify_ctx ctx) 494 { 495 return ctx->time_now; 496 } 497 498 /** 499 * Set the maximum depth of the certificate chain that the path 500 * builder is going to try. 501 * 502 * @param ctx a verification context 503 * @param max_depth maxium depth of the certificate chain, include 504 * trust anchor. 505 * 506 * @ingroup hx509_verify 507 */ 508 509 void 510 hx509_verify_set_max_depth(hx509_verify_ctx ctx, unsigned int max_depth) 511 { 512 ctx->max_depth = max_depth; 513 } 514 515 /** 516 * Allow or deny the use of proxy certificates 517 * 518 * @param ctx a verification context 519 * @param boolean if non zero, allow proxy certificates. 520 * 521 * @ingroup hx509_verify 522 */ 523 524 void 525 hx509_verify_set_proxy_certificate(hx509_verify_ctx ctx, int boolean) 526 { 527 if (boolean) 528 ctx->flags |= HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE; 529 else 530 ctx->flags &= ~HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE; 531 } 532 533 /** 534 * Select strict RFC3280 verification of certificiates. This means 535 * checking key usage on CA certificates, this will make version 1 536 * certificiates unuseable. 537 * 538 * @param ctx a verification context 539 * @param boolean if non zero, use strict verification. 540 * 541 * @ingroup hx509_verify 542 */ 543 544 void 545 hx509_verify_set_strict_rfc3280_verification(hx509_verify_ctx ctx, int boolean) 546 { 547 if (boolean) 548 ctx->flags |= HX509_VERIFY_CTX_F_REQUIRE_RFC3280; 549 else 550 ctx->flags &= ~HX509_VERIFY_CTX_F_REQUIRE_RFC3280; 551 } 552 553 /** 554 * Allow using the operating system builtin trust anchors if no other 555 * trust anchors are configured. 556 * 557 * @param ctx a verification context 558 * @param boolean if non zero, useing the operating systems builtin 559 * trust anchors. 560 * 561 * 562 * @return An hx509 error code, see hx509_get_error_string(). 563 * 564 * @ingroup hx509_cert 565 */ 566 567 void 568 hx509_verify_ctx_f_allow_default_trustanchors(hx509_verify_ctx ctx, int boolean) 569 { 570 if (boolean) 571 ctx->flags &= ~HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS; 572 else 573 ctx->flags |= HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS; 574 } 575 576 void 577 hx509_verify_ctx_f_allow_best_before_signature_algs(hx509_context ctx, 578 int boolean) 579 { 580 if (boolean) 581 ctx->flags &= ~HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK; 582 else 583 ctx->flags |= HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK; 584 } 585 586 static const Extension * 587 find_extension(const Certificate *cert, const heim_oid *oid, size_t *idx) 588 { 589 const TBSCertificate *c = &cert->tbsCertificate; 590 591 if (c->version == NULL || *c->version < 2 || c->extensions == NULL) 592 return NULL; 593 594 for (;*idx < c->extensions->len; (*idx)++) { 595 if (der_heim_oid_cmp(&c->extensions->val[*idx].extnID, oid) == 0) 596 return &c->extensions->val[(*idx)++]; 597 } 598 return NULL; 599 } 600 601 static int 602 find_extension_auth_key_id(const Certificate *subject, 603 AuthorityKeyIdentifier *ai) 604 { 605 const Extension *e; 606 size_t size; 607 size_t i = 0; 608 609 memset(ai, 0, sizeof(*ai)); 610 611 e = find_extension(subject, &asn1_oid_id_x509_ce_authorityKeyIdentifier, &i); 612 if (e == NULL) 613 return HX509_EXTENSION_NOT_FOUND; 614 615 return decode_AuthorityKeyIdentifier(e->extnValue.data, 616 e->extnValue.length, 617 ai, &size); 618 } 619 620 int 621 _hx509_find_extension_subject_key_id(const Certificate *issuer, 622 SubjectKeyIdentifier *si) 623 { 624 const Extension *e; 625 size_t size; 626 size_t i = 0; 627 628 memset(si, 0, sizeof(*si)); 629 630 e = find_extension(issuer, &asn1_oid_id_x509_ce_subjectKeyIdentifier, &i); 631 if (e == NULL) 632 return HX509_EXTENSION_NOT_FOUND; 633 634 return decode_SubjectKeyIdentifier(e->extnValue.data, 635 e->extnValue.length, 636 si, &size); 637 } 638 639 static int 640 find_extension_name_constraints(const Certificate *subject, 641 NameConstraints *nc) 642 { 643 const Extension *e; 644 size_t size; 645 size_t i = 0; 646 647 memset(nc, 0, sizeof(*nc)); 648 649 e = find_extension(subject, &asn1_oid_id_x509_ce_nameConstraints, &i); 650 if (e == NULL) 651 return HX509_EXTENSION_NOT_FOUND; 652 653 return decode_NameConstraints(e->extnValue.data, 654 e->extnValue.length, 655 nc, &size); 656 } 657 658 static int 659 find_extension_subject_alt_name(const Certificate *cert, size_t *i, 660 GeneralNames *sa) 661 { 662 const Extension *e; 663 size_t size; 664 665 memset(sa, 0, sizeof(*sa)); 666 667 e = find_extension(cert, &asn1_oid_id_x509_ce_subjectAltName, i); 668 if (e == NULL) 669 return HX509_EXTENSION_NOT_FOUND; 670 671 return decode_GeneralNames(e->extnValue.data, 672 e->extnValue.length, 673 sa, &size); 674 } 675 676 static int 677 find_extension_eku(const Certificate *cert, ExtKeyUsage *eku) 678 { 679 const Extension *e; 680 size_t size; 681 size_t i = 0; 682 683 memset(eku, 0, sizeof(*eku)); 684 685 e = find_extension(cert, &asn1_oid_id_x509_ce_extKeyUsage, &i); 686 if (e == NULL) 687 return HX509_EXTENSION_NOT_FOUND; 688 689 return decode_ExtKeyUsage(e->extnValue.data, 690 e->extnValue.length, 691 eku, &size); 692 } 693 694 static int 695 add_to_list(hx509_octet_string_list *list, const heim_octet_string *entry) 696 { 697 void *p; 698 int ret; 699 700 p = realloc(list->val, (list->len + 1) * sizeof(list->val[0])); 701 if (p == NULL) 702 return ENOMEM; 703 list->val = p; 704 ret = der_copy_octet_string(entry, &list->val[list->len]); 705 if (ret) 706 return ret; 707 list->len++; 708 return 0; 709 } 710 711 /** 712 * Free a list of octet strings returned by another hx509 library 713 * function. 714 * 715 * @param list list to be freed. 716 * 717 * @ingroup hx509_misc 718 */ 719 720 void 721 hx509_free_octet_string_list(hx509_octet_string_list *list) 722 { 723 size_t i; 724 for (i = 0; i < list->len; i++) 725 der_free_octet_string(&list->val[i]); 726 free(list->val); 727 list->val = NULL; 728 list->len = 0; 729 } 730 731 /** 732 * Return a list of subjectAltNames specified by oid in the 733 * certificate. On error the 734 * 735 * The returned list of octet string should be freed with 736 * hx509_free_octet_string_list(). 737 * 738 * @param context A hx509 context. 739 * @param cert a hx509 certificate object. 740 * @param oid an oid to for SubjectAltName. 741 * @param list list of matching SubjectAltName. 742 * 743 * @return An hx509 error code, see hx509_get_error_string(). 744 * 745 * @ingroup hx509_cert 746 */ 747 748 int 749 hx509_cert_find_subjectAltName_otherName(hx509_context context, 750 hx509_cert cert, 751 const heim_oid *oid, 752 hx509_octet_string_list *list) 753 { 754 GeneralNames sa; 755 int ret; 756 size_t i, j; 757 758 list->val = NULL; 759 list->len = 0; 760 761 i = 0; 762 while (1) { 763 ret = find_extension_subject_alt_name(_hx509_get_cert(cert), &i, &sa); 764 i++; 765 if (ret == HX509_EXTENSION_NOT_FOUND) { 766 return 0; 767 } else if (ret != 0) { 768 hx509_set_error_string(context, 0, ret, "Error searching for SAN"); 769 hx509_free_octet_string_list(list); 770 return ret; 771 } 772 773 for (j = 0; j < sa.len; j++) { 774 if (sa.val[j].element == choice_GeneralName_otherName && 775 der_heim_oid_cmp(&sa.val[j].u.otherName.type_id, oid) == 0) 776 { 777 ret = add_to_list(list, &sa.val[j].u.otherName.value); 778 if (ret) { 779 hx509_set_error_string(context, 0, ret, 780 "Error adding an exra SAN to " 781 "return list"); 782 hx509_free_octet_string_list(list); 783 free_GeneralNames(&sa); 784 return ret; 785 } 786 } 787 } 788 free_GeneralNames(&sa); 789 } 790 } 791 792 793 static int 794 check_key_usage(hx509_context context, const Certificate *cert, 795 unsigned flags, int req_present) 796 { 797 const Extension *e; 798 KeyUsage ku; 799 size_t size; 800 int ret; 801 size_t i = 0; 802 unsigned ku_flags; 803 804 if (_hx509_cert_get_version(cert) < 3) 805 return 0; 806 807 e = find_extension(cert, &asn1_oid_id_x509_ce_keyUsage, &i); 808 if (e == NULL) { 809 if (req_present) { 810 hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING, 811 "Required extension key " 812 "usage missing from certifiate"); 813 return HX509_KU_CERT_MISSING; 814 } 815 return 0; 816 } 817 818 ret = decode_KeyUsage(e->extnValue.data, e->extnValue.length, &ku, &size); 819 if (ret) 820 return ret; 821 ku_flags = KeyUsage2int(ku); 822 if ((ku_flags & flags) != flags) { 823 unsigned missing = (~ku_flags) & flags; 824 char buf[256], *name; 825 826 unparse_flags(missing, asn1_KeyUsage_units(), buf, sizeof(buf)); 827 _hx509_unparse_Name(&cert->tbsCertificate.subject, &name); 828 hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING, 829 "Key usage %s required but missing " 830 "from certifiate %s", buf, name); 831 free(name); 832 return HX509_KU_CERT_MISSING; 833 } 834 return 0; 835 } 836 837 /* 838 * Return 0 on matching key usage 'flags' for 'cert', otherwise return 839 * an error code. If 'req_present' the existance is required of the 840 * KeyUsage extension. 841 */ 842 843 int 844 _hx509_check_key_usage(hx509_context context, hx509_cert cert, 845 unsigned flags, int req_present) 846 { 847 return check_key_usage(context, _hx509_get_cert(cert), flags, req_present); 848 } 849 850 enum certtype { PROXY_CERT, EE_CERT, CA_CERT }; 851 852 static int 853 check_basic_constraints(hx509_context context, const Certificate *cert, 854 enum certtype type, size_t depth) 855 { 856 BasicConstraints bc; 857 const Extension *e; 858 size_t size; 859 int ret; 860 size_t i = 0; 861 862 if (_hx509_cert_get_version(cert) < 3) 863 return 0; 864 865 e = find_extension(cert, &asn1_oid_id_x509_ce_basicConstraints, &i); 866 if (e == NULL) { 867 switch(type) { 868 case PROXY_CERT: 869 case EE_CERT: 870 return 0; 871 case CA_CERT: { 872 char *name; 873 ret = _hx509_unparse_Name(&cert->tbsCertificate.subject, &name); 874 assert(ret == 0); 875 hx509_set_error_string(context, 0, HX509_EXTENSION_NOT_FOUND, 876 "basicConstraints missing from " 877 "CA certifiacte %s", name); 878 free(name); 879 return HX509_EXTENSION_NOT_FOUND; 880 } 881 } 882 } 883 884 ret = decode_BasicConstraints(e->extnValue.data, 885 e->extnValue.length, &bc, 886 &size); 887 if (ret) 888 return ret; 889 switch(type) { 890 case PROXY_CERT: 891 if (bc.cA != NULL && *bc.cA) 892 ret = HX509_PARENT_IS_CA; 893 break; 894 case EE_CERT: 895 ret = 0; 896 break; 897 case CA_CERT: 898 if (bc.cA == NULL || !*bc.cA) 899 ret = HX509_PARENT_NOT_CA; 900 else if (bc.pathLenConstraint) 901 if (depth - 1 > *bc.pathLenConstraint) 902 ret = HX509_CA_PATH_TOO_DEEP; 903 break; 904 } 905 free_BasicConstraints(&bc); 906 return ret; 907 } 908 909 int 910 _hx509_cert_is_parent_cmp(const Certificate *subject, 911 const Certificate *issuer, 912 int allow_self_signed) 913 { 914 int diff; 915 AuthorityKeyIdentifier ai; 916 SubjectKeyIdentifier si; 917 int ret_ai, ret_si, ret; 918 919 ret = _hx509_name_cmp(&issuer->tbsCertificate.subject, 920 &subject->tbsCertificate.issuer, 921 &diff); 922 if (ret) 923 return ret; 924 if (diff) 925 return diff; 926 927 memset(&ai, 0, sizeof(ai)); 928 memset(&si, 0, sizeof(si)); 929 930 /* 931 * Try to find AuthorityKeyIdentifier, if it's not present in the 932 * subject certificate nor the parent. 933 */ 934 935 ret_ai = find_extension_auth_key_id(subject, &ai); 936 if (ret_ai && ret_ai != HX509_EXTENSION_NOT_FOUND) 937 return 1; 938 ret_si = _hx509_find_extension_subject_key_id(issuer, &si); 939 if (ret_si && ret_si != HX509_EXTENSION_NOT_FOUND) 940 return -1; 941 942 if (ret_si && ret_ai) 943 goto out; 944 if (ret_ai) 945 goto out; 946 if (ret_si) { 947 if (allow_self_signed) { 948 diff = 0; 949 goto out; 950 } else if (ai.keyIdentifier) { 951 diff = -1; 952 goto out; 953 } 954 } 955 956 if (ai.keyIdentifier == NULL) { 957 Name name; 958 959 if (ai.authorityCertIssuer == NULL) 960 return -1; 961 if (ai.authorityCertSerialNumber == NULL) 962 return -1; 963 964 diff = der_heim_integer_cmp(ai.authorityCertSerialNumber, 965 &issuer->tbsCertificate.serialNumber); 966 if (diff) 967 return diff; 968 if (ai.authorityCertIssuer->len != 1) 969 return -1; 970 if (ai.authorityCertIssuer->val[0].element != choice_GeneralName_directoryName) 971 return -1; 972 973 name.element = 974 ai.authorityCertIssuer->val[0].u.directoryName.element; 975 name.u.rdnSequence = 976 ai.authorityCertIssuer->val[0].u.directoryName.u.rdnSequence; 977 978 ret = _hx509_name_cmp(&issuer->tbsCertificate.subject, 979 &name, 980 &diff); 981 if (ret) 982 return ret; 983 if (diff) 984 return diff; 985 diff = 0; 986 } else 987 diff = der_heim_octet_string_cmp(ai.keyIdentifier, &si); 988 if (diff) 989 goto out; 990 991 out: 992 free_AuthorityKeyIdentifier(&ai); 993 free_SubjectKeyIdentifier(&si); 994 return diff; 995 } 996 997 static int 998 certificate_is_anchor(hx509_context context, 999 hx509_certs trust_anchors, 1000 const hx509_cert cert) 1001 { 1002 hx509_query q; 1003 hx509_cert c; 1004 int ret; 1005 1006 if (trust_anchors == NULL) 1007 return 0; 1008 1009 _hx509_query_clear(&q); 1010 1011 q.match = HX509_QUERY_MATCH_CERTIFICATE; 1012 q.certificate = _hx509_get_cert(cert); 1013 1014 ret = hx509_certs_find(context, trust_anchors, &q, &c); 1015 if (ret == 0) 1016 hx509_cert_free(c); 1017 return ret == 0; 1018 } 1019 1020 static int 1021 certificate_is_self_signed(hx509_context context, 1022 const Certificate *cert, 1023 int *self_signed) 1024 { 1025 int ret, diff; 1026 ret = _hx509_name_cmp(&cert->tbsCertificate.subject, 1027 &cert->tbsCertificate.issuer, &diff); 1028 *self_signed = (diff == 0); 1029 if (ret) { 1030 hx509_set_error_string(context, 0, ret, 1031 "Failed to check if self signed"); 1032 } else 1033 ret = _hx509_self_signed_valid(context, &cert->signatureAlgorithm); 1034 1035 return ret; 1036 } 1037 1038 /* 1039 * The subjectName is "null" when it's empty set of relative DBs. 1040 */ 1041 1042 static int 1043 subject_null_p(const Certificate *c) 1044 { 1045 return c->tbsCertificate.subject.u.rdnSequence.len == 0; 1046 } 1047 1048 1049 static int 1050 find_parent(hx509_context context, 1051 time_t time_now, 1052 hx509_certs trust_anchors, 1053 hx509_path *path, 1054 hx509_certs pool, 1055 hx509_cert current, 1056 hx509_cert *parent) 1057 { 1058 AuthorityKeyIdentifier ai; 1059 hx509_query q; 1060 int ret; 1061 1062 *parent = NULL; 1063 memset(&ai, 0, sizeof(ai)); 1064 1065 _hx509_query_clear(&q); 1066 1067 if (!subject_null_p(current->data)) { 1068 q.match |= HX509_QUERY_FIND_ISSUER_CERT; 1069 q.subject = _hx509_get_cert(current); 1070 } else { 1071 ret = find_extension_auth_key_id(current->data, &ai); 1072 if (ret) { 1073 hx509_set_error_string(context, 0, HX509_CERTIFICATE_MALFORMED, 1074 "Subjectless certificate missing AuthKeyID"); 1075 return HX509_CERTIFICATE_MALFORMED; 1076 } 1077 1078 if (ai.keyIdentifier == NULL) { 1079 free_AuthorityKeyIdentifier(&ai); 1080 hx509_set_error_string(context, 0, HX509_CERTIFICATE_MALFORMED, 1081 "Subjectless certificate missing keyIdentifier " 1082 "inside AuthKeyID"); 1083 return HX509_CERTIFICATE_MALFORMED; 1084 } 1085 1086 q.subject_id = ai.keyIdentifier; 1087 q.match = HX509_QUERY_MATCH_SUBJECT_KEY_ID; 1088 } 1089 1090 q.path = path; 1091 q.match |= HX509_QUERY_NO_MATCH_PATH; 1092 1093 if (pool) { 1094 q.timenow = time_now; 1095 q.match |= HX509_QUERY_MATCH_TIME; 1096 1097 ret = hx509_certs_find(context, pool, &q, parent); 1098 if (ret == 0) { 1099 free_AuthorityKeyIdentifier(&ai); 1100 return 0; 1101 } 1102 q.match &= ~HX509_QUERY_MATCH_TIME; 1103 } 1104 1105 if (trust_anchors) { 1106 ret = hx509_certs_find(context, trust_anchors, &q, parent); 1107 if (ret == 0) { 1108 free_AuthorityKeyIdentifier(&ai); 1109 return ret; 1110 } 1111 } 1112 free_AuthorityKeyIdentifier(&ai); 1113 1114 { 1115 hx509_name name; 1116 char *str; 1117 1118 ret = hx509_cert_get_subject(current, &name); 1119 if (ret) { 1120 hx509_clear_error_string(context); 1121 return HX509_ISSUER_NOT_FOUND; 1122 } 1123 ret = hx509_name_to_string(name, &str); 1124 hx509_name_free(&name); 1125 if (ret) { 1126 hx509_clear_error_string(context); 1127 return HX509_ISSUER_NOT_FOUND; 1128 } 1129 1130 hx509_set_error_string(context, 0, HX509_ISSUER_NOT_FOUND, 1131 "Failed to find issuer for " 1132 "certificate with subject: '%s'", str); 1133 free(str); 1134 } 1135 return HX509_ISSUER_NOT_FOUND; 1136 } 1137 1138 /* 1139 * 1140 */ 1141 1142 static int 1143 is_proxy_cert(hx509_context context, 1144 const Certificate *cert, 1145 ProxyCertInfo *rinfo) 1146 { 1147 ProxyCertInfo info; 1148 const Extension *e; 1149 size_t size; 1150 int ret; 1151 size_t i = 0; 1152 1153 if (rinfo) 1154 memset(rinfo, 0, sizeof(*rinfo)); 1155 1156 e = find_extension(cert, &asn1_oid_id_pkix_pe_proxyCertInfo, &i); 1157 if (e == NULL) { 1158 hx509_clear_error_string(context); 1159 return HX509_EXTENSION_NOT_FOUND; 1160 } 1161 1162 ret = decode_ProxyCertInfo(e->extnValue.data, 1163 e->extnValue.length, 1164 &info, 1165 &size); 1166 if (ret) { 1167 hx509_clear_error_string(context); 1168 return ret; 1169 } 1170 if (size != e->extnValue.length) { 1171 free_ProxyCertInfo(&info); 1172 hx509_clear_error_string(context); 1173 return HX509_EXTRA_DATA_AFTER_STRUCTURE; 1174 } 1175 if (rinfo == NULL) 1176 free_ProxyCertInfo(&info); 1177 else 1178 *rinfo = info; 1179 1180 return 0; 1181 } 1182 1183 /* 1184 * Path operations are like MEMORY based keyset, but with exposed 1185 * internal so we can do easy searches. 1186 */ 1187 1188 int 1189 _hx509_path_append(hx509_context context, hx509_path *path, hx509_cert cert) 1190 { 1191 hx509_cert *val; 1192 val = realloc(path->val, (path->len + 1) * sizeof(path->val[0])); 1193 if (val == NULL) { 1194 hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 1195 return ENOMEM; 1196 } 1197 1198 path->val = val; 1199 path->val[path->len] = hx509_cert_ref(cert); 1200 path->len++; 1201 1202 return 0; 1203 } 1204 1205 void 1206 _hx509_path_free(hx509_path *path) 1207 { 1208 unsigned i; 1209 1210 for (i = 0; i < path->len; i++) 1211 hx509_cert_free(path->val[i]); 1212 free(path->val); 1213 path->val = NULL; 1214 path->len = 0; 1215 } 1216 1217 /* 1218 * Find path by looking up issuer for the top certificate and continue 1219 * until an anchor certificate is found or max limit is found. A 1220 * certificate never included twice in the path. 1221 * 1222 * If the trust anchors are not given, calculate optimistic path, just 1223 * follow the chain upward until we no longer find a parent or we hit 1224 * the max path limit. In this case, a failure will always be returned 1225 * depending on what error condition is hit first. 1226 * 1227 * The path includes a path from the top certificate to the anchor 1228 * certificate. 1229 * 1230 * The caller needs to free `path´ both on successful built path and 1231 * failure. 1232 */ 1233 1234 int 1235 _hx509_calculate_path(hx509_context context, 1236 int flags, 1237 time_t time_now, 1238 hx509_certs anchors, 1239 unsigned int max_depth, 1240 hx509_cert cert, 1241 hx509_certs pool, 1242 hx509_path *path) 1243 { 1244 hx509_cert parent, current; 1245 int ret; 1246 1247 if (max_depth == 0) 1248 max_depth = HX509_VERIFY_MAX_DEPTH; 1249 1250 ret = _hx509_path_append(context, path, cert); 1251 if (ret) 1252 return ret; 1253 1254 current = hx509_cert_ref(cert); 1255 1256 while (!certificate_is_anchor(context, anchors, current)) { 1257 1258 ret = find_parent(context, time_now, anchors, path, 1259 pool, current, &parent); 1260 hx509_cert_free(current); 1261 if (ret) 1262 return ret; 1263 1264 ret = _hx509_path_append(context, path, parent); 1265 if (ret) 1266 return ret; 1267 current = parent; 1268 1269 if (path->len > max_depth) { 1270 hx509_cert_free(current); 1271 hx509_set_error_string(context, 0, HX509_PATH_TOO_LONG, 1272 "Path too long while bulding " 1273 "certificate chain"); 1274 return HX509_PATH_TOO_LONG; 1275 } 1276 } 1277 1278 if ((flags & HX509_CALCULATE_PATH_NO_ANCHOR) && 1279 path->len > 0 && 1280 certificate_is_anchor(context, anchors, path->val[path->len - 1])) 1281 { 1282 hx509_cert_free(path->val[path->len - 1]); 1283 path->len--; 1284 } 1285 1286 hx509_cert_free(current); 1287 return 0; 1288 } 1289 1290 int 1291 _hx509_AlgorithmIdentifier_cmp(const AlgorithmIdentifier *p, 1292 const AlgorithmIdentifier *q) 1293 { 1294 int diff; 1295 diff = der_heim_oid_cmp(&p->algorithm, &q->algorithm); 1296 if (diff) 1297 return diff; 1298 if (p->parameters) { 1299 if (q->parameters) 1300 return heim_any_cmp(p->parameters, 1301 q->parameters); 1302 else 1303 return 1; 1304 } else { 1305 if (q->parameters) 1306 return -1; 1307 else 1308 return 0; 1309 } 1310 } 1311 1312 int 1313 _hx509_Certificate_cmp(const Certificate *p, const Certificate *q) 1314 { 1315 int diff; 1316 diff = der_heim_bit_string_cmp(&p->signatureValue, &q->signatureValue); 1317 if (diff) 1318 return diff; 1319 diff = _hx509_AlgorithmIdentifier_cmp(&p->signatureAlgorithm, 1320 &q->signatureAlgorithm); 1321 if (diff) 1322 return diff; 1323 diff = der_heim_octet_string_cmp(&p->tbsCertificate._save, 1324 &q->tbsCertificate._save); 1325 return diff; 1326 } 1327 1328 /** 1329 * Compare to hx509 certificate object, useful for sorting. 1330 * 1331 * @param p a hx509 certificate object. 1332 * @param q a hx509 certificate object. 1333 * 1334 * @return 0 the objects are the same, returns > 0 is p is "larger" 1335 * then q, < 0 if p is "smaller" then q. 1336 * 1337 * @ingroup hx509_cert 1338 */ 1339 1340 int 1341 hx509_cert_cmp(hx509_cert p, hx509_cert q) 1342 { 1343 return _hx509_Certificate_cmp(p->data, q->data); 1344 } 1345 1346 /** 1347 * Return the name of the issuer of the hx509 certificate. 1348 * 1349 * @param p a hx509 certificate object. 1350 * @param name a pointer to a hx509 name, should be freed by 1351 * hx509_name_free(). 1352 * 1353 * @return An hx509 error code, see hx509_get_error_string(). 1354 * 1355 * @ingroup hx509_cert 1356 */ 1357 1358 int 1359 hx509_cert_get_issuer(hx509_cert p, hx509_name *name) 1360 { 1361 return _hx509_name_from_Name(&p->data->tbsCertificate.issuer, name); 1362 } 1363 1364 /** 1365 * Return the name of the subject of the hx509 certificate. 1366 * 1367 * @param p a hx509 certificate object. 1368 * @param name a pointer to a hx509 name, should be freed by 1369 * hx509_name_free(). See also hx509_cert_get_base_subject(). 1370 * 1371 * @return An hx509 error code, see hx509_get_error_string(). 1372 * 1373 * @ingroup hx509_cert 1374 */ 1375 1376 int 1377 hx509_cert_get_subject(hx509_cert p, hx509_name *name) 1378 { 1379 return _hx509_name_from_Name(&p->data->tbsCertificate.subject, name); 1380 } 1381 1382 /** 1383 * Return the name of the base subject of the hx509 certificate. If 1384 * the certiicate is a verified proxy certificate, the this function 1385 * return the base certificate (root of the proxy chain). If the proxy 1386 * certificate is not verified with the base certificate 1387 * HX509_PROXY_CERTIFICATE_NOT_CANONICALIZED is returned. 1388 * 1389 * @param context a hx509 context. 1390 * @param c a hx509 certificate object. 1391 * @param name a pointer to a hx509 name, should be freed by 1392 * hx509_name_free(). See also hx509_cert_get_subject(). 1393 * 1394 * @return An hx509 error code, see hx509_get_error_string(). 1395 * 1396 * @ingroup hx509_cert 1397 */ 1398 1399 int 1400 hx509_cert_get_base_subject(hx509_context context, hx509_cert c, 1401 hx509_name *name) 1402 { 1403 if (c->basename) 1404 return hx509_name_copy(context, c->basename, name); 1405 if (is_proxy_cert(context, c->data, NULL) == 0) { 1406 int ret = HX509_PROXY_CERTIFICATE_NOT_CANONICALIZED; 1407 hx509_set_error_string(context, 0, ret, 1408 "Proxy certificate have not been " 1409 "canonicalize yet, no base name"); 1410 return ret; 1411 } 1412 return _hx509_name_from_Name(&c->data->tbsCertificate.subject, name); 1413 } 1414 1415 /** 1416 * Get serial number of the certificate. 1417 * 1418 * @param p a hx509 certificate object. 1419 * @param i serial number, should be freed ith der_free_heim_integer(). 1420 * 1421 * @return An hx509 error code, see hx509_get_error_string(). 1422 * 1423 * @ingroup hx509_cert 1424 */ 1425 1426 int 1427 hx509_cert_get_serialnumber(hx509_cert p, heim_integer *i) 1428 { 1429 return der_copy_heim_integer(&p->data->tbsCertificate.serialNumber, i); 1430 } 1431 1432 /** 1433 * Get notBefore time of the certificate. 1434 * 1435 * @param p a hx509 certificate object. 1436 * 1437 * @return return not before time 1438 * 1439 * @ingroup hx509_cert 1440 */ 1441 1442 time_t 1443 hx509_cert_get_notBefore(hx509_cert p) 1444 { 1445 return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notBefore); 1446 } 1447 1448 /** 1449 * Get notAfter time of the certificate. 1450 * 1451 * @param p a hx509 certificate object. 1452 * 1453 * @return return not after time. 1454 * 1455 * @ingroup hx509_cert 1456 */ 1457 1458 time_t 1459 hx509_cert_get_notAfter(hx509_cert p) 1460 { 1461 return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notAfter); 1462 } 1463 1464 /** 1465 * Get the SubjectPublicKeyInfo structure from the hx509 certificate. 1466 * 1467 * @param context a hx509 context. 1468 * @param p a hx509 certificate object. 1469 * @param spki SubjectPublicKeyInfo, should be freed with 1470 * free_SubjectPublicKeyInfo(). 1471 * 1472 * @return An hx509 error code, see hx509_get_error_string(). 1473 * 1474 * @ingroup hx509_cert 1475 */ 1476 1477 int 1478 hx509_cert_get_SPKI(hx509_context context, hx509_cert p, SubjectPublicKeyInfo *spki) 1479 { 1480 int ret; 1481 1482 ret = copy_SubjectPublicKeyInfo(&p->data->tbsCertificate.subjectPublicKeyInfo, spki); 1483 if (ret) 1484 hx509_set_error_string(context, 0, ret, "Failed to copy SPKI"); 1485 return ret; 1486 } 1487 1488 /** 1489 * Get the AlgorithmIdentifier from the hx509 certificate. 1490 * 1491 * @param context a hx509 context. 1492 * @param p a hx509 certificate object. 1493 * @param alg AlgorithmIdentifier, should be freed with 1494 * free_AlgorithmIdentifier(). The algorithmidentifier is 1495 * typicly rsaEncryption, or id-ecPublicKey, or some other 1496 * public key mechanism. 1497 * 1498 * @return An hx509 error code, see hx509_get_error_string(). 1499 * 1500 * @ingroup hx509_cert 1501 */ 1502 1503 int 1504 hx509_cert_get_SPKI_AlgorithmIdentifier(hx509_context context, 1505 hx509_cert p, 1506 AlgorithmIdentifier *alg) 1507 { 1508 int ret; 1509 1510 ret = copy_AlgorithmIdentifier(&p->data->tbsCertificate.subjectPublicKeyInfo.algorithm, alg); 1511 if (ret) 1512 hx509_set_error_string(context, 0, ret, 1513 "Failed to copy SPKI AlgorithmIdentifier"); 1514 return ret; 1515 } 1516 1517 static int 1518 get_x_unique_id(hx509_context context, const char *name, 1519 const heim_bit_string *cert, heim_bit_string *subject) 1520 { 1521 int ret; 1522 1523 if (cert == NULL) { 1524 ret = HX509_EXTENSION_NOT_FOUND; 1525 hx509_set_error_string(context, 0, ret, "%s unique id doesn't exists", name); 1526 return ret; 1527 } 1528 ret = der_copy_bit_string(cert, subject); 1529 if (ret) { 1530 hx509_set_error_string(context, 0, ret, "malloc out of memory", name); 1531 return ret; 1532 } 1533 return 0; 1534 } 1535 1536 /** 1537 * Get a copy of the Issuer Unique ID 1538 * 1539 * @param context a hx509_context 1540 * @param p a hx509 certificate 1541 * @param issuer the issuer id returned, free with der_free_bit_string() 1542 * 1543 * @return An hx509 error code, see hx509_get_error_string(). The 1544 * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate 1545 * doesn't have a issuerUniqueID 1546 * 1547 * @ingroup hx509_cert 1548 */ 1549 1550 int 1551 hx509_cert_get_issuer_unique_id(hx509_context context, hx509_cert p, heim_bit_string *issuer) 1552 { 1553 return get_x_unique_id(context, "issuer", p->data->tbsCertificate.issuerUniqueID, issuer); 1554 } 1555 1556 /** 1557 * Get a copy of the Subect Unique ID 1558 * 1559 * @param context a hx509_context 1560 * @param p a hx509 certificate 1561 * @param subject the subject id returned, free with der_free_bit_string() 1562 * 1563 * @return An hx509 error code, see hx509_get_error_string(). The 1564 * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate 1565 * doesn't have a subjectUniqueID 1566 * 1567 * @ingroup hx509_cert 1568 */ 1569 1570 int 1571 hx509_cert_get_subject_unique_id(hx509_context context, hx509_cert p, heim_bit_string *subject) 1572 { 1573 return get_x_unique_id(context, "subject", p->data->tbsCertificate.subjectUniqueID, subject); 1574 } 1575 1576 1577 hx509_private_key 1578 _hx509_cert_private_key(hx509_cert p) 1579 { 1580 return p->private_key; 1581 } 1582 1583 int 1584 hx509_cert_have_private_key(hx509_cert p) 1585 { 1586 return p->private_key ? 1 : 0; 1587 } 1588 1589 1590 int 1591 _hx509_cert_private_key_exportable(hx509_cert p) 1592 { 1593 if (p->private_key == NULL) 1594 return 0; 1595 return _hx509_private_key_exportable(p->private_key); 1596 } 1597 1598 int 1599 _hx509_cert_private_decrypt(hx509_context context, 1600 const heim_octet_string *ciphertext, 1601 const heim_oid *encryption_oid, 1602 hx509_cert p, 1603 heim_octet_string *cleartext) 1604 { 1605 cleartext->data = NULL; 1606 cleartext->length = 0; 1607 1608 if (p->private_key == NULL) { 1609 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING, 1610 "Private key missing"); 1611 return HX509_PRIVATE_KEY_MISSING; 1612 } 1613 1614 return hx509_private_key_private_decrypt(context, 1615 ciphertext, 1616 encryption_oid, 1617 p->private_key, 1618 cleartext); 1619 } 1620 1621 int 1622 hx509_cert_public_encrypt(hx509_context context, 1623 const heim_octet_string *cleartext, 1624 const hx509_cert p, 1625 heim_oid *encryption_oid, 1626 heim_octet_string *ciphertext) 1627 { 1628 return _hx509_public_encrypt(context, 1629 cleartext, p->data, 1630 encryption_oid, ciphertext); 1631 } 1632 1633 /* 1634 * 1635 */ 1636 1637 time_t 1638 _hx509_Time2time_t(const Time *t) 1639 { 1640 switch(t->element) { 1641 case choice_Time_utcTime: 1642 return t->u.utcTime; 1643 case choice_Time_generalTime: 1644 return t->u.generalTime; 1645 } 1646 return 0; 1647 } 1648 1649 /* 1650 * 1651 */ 1652 1653 static int 1654 init_name_constraints(hx509_name_constraints *nc) 1655 { 1656 memset(nc, 0, sizeof(*nc)); 1657 return 0; 1658 } 1659 1660 static int 1661 add_name_constraints(hx509_context context, const Certificate *c, int not_ca, 1662 hx509_name_constraints *nc) 1663 { 1664 NameConstraints tnc; 1665 int ret; 1666 1667 ret = find_extension_name_constraints(c, &tnc); 1668 if (ret == HX509_EXTENSION_NOT_FOUND) 1669 return 0; 1670 else if (ret) { 1671 hx509_set_error_string(context, 0, ret, "Failed getting NameConstraints"); 1672 return ret; 1673 } else if (not_ca) { 1674 ret = HX509_VERIFY_CONSTRAINTS; 1675 hx509_set_error_string(context, 0, ret, "Not a CA and " 1676 "have NameConstraints"); 1677 } else { 1678 NameConstraints *val; 1679 val = realloc(nc->val, sizeof(nc->val[0]) * (nc->len + 1)); 1680 if (val == NULL) { 1681 hx509_clear_error_string(context); 1682 ret = ENOMEM; 1683 goto out; 1684 } 1685 nc->val = val; 1686 ret = copy_NameConstraints(&tnc, &nc->val[nc->len]); 1687 if (ret) { 1688 hx509_clear_error_string(context); 1689 goto out; 1690 } 1691 nc->len += 1; 1692 } 1693 out: 1694 free_NameConstraints(&tnc); 1695 return ret; 1696 } 1697 1698 static int 1699 match_RDN(const RelativeDistinguishedName *c, 1700 const RelativeDistinguishedName *n) 1701 { 1702 size_t i; 1703 1704 if (c->len != n->len) 1705 return HX509_NAME_CONSTRAINT_ERROR; 1706 1707 for (i = 0; i < n->len; i++) { 1708 int diff, ret; 1709 1710 if (der_heim_oid_cmp(&c->val[i].type, &n->val[i].type) != 0) 1711 return HX509_NAME_CONSTRAINT_ERROR; 1712 ret = _hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value, &diff); 1713 if (ret) 1714 return ret; 1715 if (diff != 0) 1716 return HX509_NAME_CONSTRAINT_ERROR; 1717 } 1718 return 0; 1719 } 1720 1721 static int 1722 match_X501Name(const Name *c, const Name *n) 1723 { 1724 size_t i; 1725 int ret; 1726 1727 if (c->element != choice_Name_rdnSequence 1728 || n->element != choice_Name_rdnSequence) 1729 return 0; 1730 if (c->u.rdnSequence.len > n->u.rdnSequence.len) 1731 return HX509_NAME_CONSTRAINT_ERROR; 1732 for (i = 0; i < c->u.rdnSequence.len; i++) { 1733 ret = match_RDN(&c->u.rdnSequence.val[i], &n->u.rdnSequence.val[i]); 1734 if (ret) 1735 return ret; 1736 } 1737 return 0; 1738 } 1739 1740 1741 static int 1742 match_general_name(const GeneralName *c, const GeneralName *n, int *match) 1743 { 1744 /* 1745 * Name constraints only apply to the same name type, see RFC3280, 1746 * 4.2.1.11. 1747 */ 1748 assert(c->element == n->element); 1749 1750 switch(c->element) { 1751 case choice_GeneralName_otherName: 1752 if (der_heim_oid_cmp(&c->u.otherName.type_id, 1753 &n->u.otherName.type_id) != 0) 1754 return HX509_NAME_CONSTRAINT_ERROR; 1755 if (heim_any_cmp(&c->u.otherName.value, 1756 &n->u.otherName.value) != 0) 1757 return HX509_NAME_CONSTRAINT_ERROR; 1758 *match = 1; 1759 return 0; 1760 case choice_GeneralName_rfc822Name: { 1761 const char *s; 1762 size_t len1, len2; 1763 s = memchr(c->u.rfc822Name.data, '@', c->u.rfc822Name.length); 1764 if (s) { 1765 if (der_printable_string_cmp(&c->u.rfc822Name, &n->u.rfc822Name) != 0) 1766 return HX509_NAME_CONSTRAINT_ERROR; 1767 } else { 1768 s = memchr(n->u.rfc822Name.data, '@', n->u.rfc822Name.length); 1769 if (s == NULL) 1770 return HX509_NAME_CONSTRAINT_ERROR; 1771 len1 = c->u.rfc822Name.length; 1772 len2 = n->u.rfc822Name.length - 1773 (s - ((char *)n->u.rfc822Name.data)); 1774 if (len1 > len2) 1775 return HX509_NAME_CONSTRAINT_ERROR; 1776 if (memcmp(s + 1 + len2 - len1, c->u.rfc822Name.data, len1) != 0) 1777 return HX509_NAME_CONSTRAINT_ERROR; 1778 if (len1 < len2 && s[len2 - len1 + 1] != '.') 1779 return HX509_NAME_CONSTRAINT_ERROR; 1780 } 1781 *match = 1; 1782 return 0; 1783 } 1784 case choice_GeneralName_dNSName: { 1785 size_t lenc, lenn; 1786 char *ptr; 1787 1788 lenc = c->u.dNSName.length; 1789 lenn = n->u.dNSName.length; 1790 if (lenc > lenn) 1791 return HX509_NAME_CONSTRAINT_ERROR; 1792 ptr = n->u.dNSName.data; 1793 if (memcmp(&ptr[lenn - lenc], c->u.dNSName.data, lenc) != 0) 1794 return HX509_NAME_CONSTRAINT_ERROR; 1795 if (lenn != lenc && ptr[lenn - lenc - 1] != '.') 1796 return HX509_NAME_CONSTRAINT_ERROR; 1797 *match = 1; 1798 return 0; 1799 } 1800 case choice_GeneralName_directoryName: { 1801 Name c_name, n_name; 1802 int ret; 1803 1804 c_name._save.data = NULL; 1805 c_name._save.length = 0; 1806 c_name.element = c->u.directoryName.element; 1807 c_name.u.rdnSequence = c->u.directoryName.u.rdnSequence; 1808 1809 n_name._save.data = NULL; 1810 n_name._save.length = 0; 1811 n_name.element = n->u.directoryName.element; 1812 n_name.u.rdnSequence = n->u.directoryName.u.rdnSequence; 1813 1814 ret = match_X501Name(&c_name, &n_name); 1815 if (ret == 0) 1816 *match = 1; 1817 return ret; 1818 } 1819 case choice_GeneralName_uniformResourceIdentifier: 1820 case choice_GeneralName_iPAddress: 1821 case choice_GeneralName_registeredID: 1822 default: 1823 return HX509_NAME_CONSTRAINT_ERROR; 1824 } 1825 } 1826 1827 static int 1828 match_alt_name(const GeneralName *n, const Certificate *c, 1829 int *same, int *match) 1830 { 1831 GeneralNames sa; 1832 int ret; 1833 size_t i, j; 1834 1835 i = 0; 1836 do { 1837 ret = find_extension_subject_alt_name(c, &i, &sa); 1838 if (ret == HX509_EXTENSION_NOT_FOUND) { 1839 ret = 0; 1840 break; 1841 } else if (ret != 0) 1842 break; 1843 1844 for (j = 0; j < sa.len; j++) { 1845 if (n->element == sa.val[j].element) { 1846 *same = 1; 1847 ret = match_general_name(n, &sa.val[j], match); 1848 } 1849 } 1850 free_GeneralNames(&sa); 1851 } while (1); 1852 return ret; 1853 } 1854 1855 1856 static int 1857 match_tree(const GeneralSubtrees *t, const Certificate *c, int *match) 1858 { 1859 int name, alt_name, same; 1860 unsigned int i; 1861 int ret = 0; 1862 1863 name = alt_name = same = *match = 0; 1864 for (i = 0; i < t->len; i++) { 1865 if (t->val[i].minimum && t->val[i].maximum) 1866 return HX509_RANGE; 1867 1868 /* 1869 * If the constraint apply to directoryNames, test is with 1870 * subjectName of the certificate if the certificate have a 1871 * non-null (empty) subjectName. 1872 */ 1873 1874 if (t->val[i].base.element == choice_GeneralName_directoryName 1875 && !subject_null_p(c)) 1876 { 1877 GeneralName certname; 1878 1879 memset(&certname, 0, sizeof(certname)); 1880 certname.element = choice_GeneralName_directoryName; 1881 certname.u.directoryName.element = 1882 c->tbsCertificate.subject.element; 1883 certname.u.directoryName.u.rdnSequence = 1884 c->tbsCertificate.subject.u.rdnSequence; 1885 1886 ret = match_general_name(&t->val[i].base, &certname, &name); 1887 } 1888 1889 /* Handle subjectAltNames, this is icky since they 1890 * restrictions only apply if the subjectAltName is of the 1891 * same type. So if there have been a match of type, require 1892 * altname to be set. 1893 */ 1894 ret = match_alt_name(&t->val[i].base, c, &same, &alt_name); 1895 } 1896 if (name && (!same || alt_name)) 1897 *match = 1; 1898 return ret; 1899 } 1900 1901 static int 1902 check_name_constraints(hx509_context context, 1903 const hx509_name_constraints *nc, 1904 const Certificate *c) 1905 { 1906 int match, ret; 1907 size_t i; 1908 1909 for (i = 0 ; i < nc->len; i++) { 1910 GeneralSubtrees gs; 1911 1912 if (nc->val[i].permittedSubtrees) { 1913 GeneralSubtrees_SET(&gs, nc->val[i].permittedSubtrees); 1914 ret = match_tree(&gs, c, &match); 1915 if (ret) { 1916 hx509_clear_error_string(context); 1917 return ret; 1918 } 1919 /* allow null subjectNames, they wont matches anything */ 1920 if (match == 0 && !subject_null_p(c)) { 1921 hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS, 1922 "Error verify constraints, " 1923 "certificate didn't match any " 1924 "permitted subtree"); 1925 return HX509_VERIFY_CONSTRAINTS; 1926 } 1927 } 1928 if (nc->val[i].excludedSubtrees) { 1929 GeneralSubtrees_SET(&gs, nc->val[i].excludedSubtrees); 1930 ret = match_tree(&gs, c, &match); 1931 if (ret) { 1932 hx509_clear_error_string(context); 1933 return ret; 1934 } 1935 if (match) { 1936 hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS, 1937 "Error verify constraints, " 1938 "certificate included in excluded " 1939 "subtree"); 1940 return HX509_VERIFY_CONSTRAINTS; 1941 } 1942 } 1943 } 1944 return 0; 1945 } 1946 1947 static void 1948 free_name_constraints(hx509_name_constraints *nc) 1949 { 1950 size_t i; 1951 1952 for (i = 0 ; i < nc->len; i++) 1953 free_NameConstraints(&nc->val[i]); 1954 free(nc->val); 1955 } 1956 1957 /** 1958 * Build and verify the path for the certificate to the trust anchor 1959 * specified in the verify context. The path is constructed from the 1960 * certificate, the pool and the trust anchors. 1961 * 1962 * @param context A hx509 context. 1963 * @param ctx A hx509 verification context. 1964 * @param cert the certificate to build the path from. 1965 * @param pool A keyset of certificates to build the chain from. 1966 * 1967 * @return An hx509 error code, see hx509_get_error_string(). 1968 * 1969 * @ingroup hx509_verify 1970 */ 1971 1972 int 1973 hx509_verify_path(hx509_context context, 1974 hx509_verify_ctx ctx, 1975 hx509_cert cert, 1976 hx509_certs pool) 1977 { 1978 hx509_name_constraints nc; 1979 hx509_path path; 1980 int ret, proxy_cert_depth, selfsigned_depth, diff; 1981 size_t i, k; 1982 enum certtype type; 1983 Name proxy_issuer; 1984 hx509_certs anchors = NULL; 1985 1986 memset(&proxy_issuer, 0, sizeof(proxy_issuer)); 1987 1988 ret = init_name_constraints(&nc); 1989 if (ret) 1990 return ret; 1991 1992 path.val = NULL; 1993 path.len = 0; 1994 1995 if ((ctx->flags & HX509_VERIFY_CTX_F_TIME_SET) == 0) 1996 ctx->time_now = time(NULL); 1997 1998 /* 1999 * 2000 */ 2001 if (ctx->trust_anchors) 2002 anchors = hx509_certs_ref(ctx->trust_anchors); 2003 else if (context->default_trust_anchors && ALLOW_DEF_TA(ctx)) 2004 anchors = hx509_certs_ref(context->default_trust_anchors); 2005 else { 2006 ret = hx509_certs_init(context, "MEMORY:no-TA", 0, NULL, &anchors); 2007 if (ret) 2008 goto out; 2009 } 2010 2011 /* 2012 * Calculate the path from the certificate user presented to the 2013 * to an anchor. 2014 */ 2015 ret = _hx509_calculate_path(context, 0, ctx->time_now, 2016 anchors, ctx->max_depth, 2017 cert, pool, &path); 2018 if (ret) 2019 goto out; 2020 2021 /* 2022 * Check CA and proxy certificate chain from the top of the 2023 * certificate chain. Also check certificate is valid with respect 2024 * to the current time. 2025 * 2026 */ 2027 2028 proxy_cert_depth = 0; 2029 selfsigned_depth = 0; 2030 2031 if (ctx->flags & HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE) 2032 type = PROXY_CERT; 2033 else 2034 type = EE_CERT; 2035 2036 for (i = 0; i < path.len; i++) { 2037 Certificate *c; 2038 time_t t; 2039 2040 c = _hx509_get_cert(path.val[i]); 2041 2042 /* 2043 * Lets do some basic check on issuer like 2044 * keyUsage.keyCertSign and basicConstraints.cA bit depending 2045 * on what type of certificate this is. 2046 */ 2047 2048 switch (type) { 2049 case CA_CERT: 2050 2051 /* XXX make constants for keyusage */ 2052 ret = check_key_usage(context, c, 1 << 5, 2053 REQUIRE_RFC3280(ctx) ? TRUE : FALSE); 2054 if (ret) { 2055 hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 2056 "Key usage missing from CA certificate"); 2057 goto out; 2058 } 2059 2060 /* self signed cert doesn't add to path length */ 2061 if (i + 1 != path.len) { 2062 int selfsigned; 2063 2064 ret = certificate_is_self_signed(context, c, &selfsigned); 2065 if (ret) 2066 goto out; 2067 if (selfsigned) 2068 selfsigned_depth++; 2069 } 2070 2071 break; 2072 case PROXY_CERT: { 2073 ProxyCertInfo info; 2074 2075 if (is_proxy_cert(context, c, &info) == 0) { 2076 size_t j; 2077 2078 if (info.pCPathLenConstraint != NULL && 2079 *info.pCPathLenConstraint < i) 2080 { 2081 free_ProxyCertInfo(&info); 2082 ret = HX509_PATH_TOO_LONG; 2083 hx509_set_error_string(context, 0, ret, 2084 "Proxy certificate chain " 2085 "longer then allowed"); 2086 goto out; 2087 } 2088 /* XXX MUST check info.proxyPolicy */ 2089 free_ProxyCertInfo(&info); 2090 2091 j = 0; 2092 if (find_extension(c, &asn1_oid_id_x509_ce_subjectAltName, &j)) { 2093 ret = HX509_PROXY_CERT_INVALID; 2094 hx509_set_error_string(context, 0, ret, 2095 "Proxy certificate have explicity " 2096 "forbidden subjectAltName"); 2097 goto out; 2098 } 2099 2100 j = 0; 2101 if (find_extension(c, &asn1_oid_id_x509_ce_issuerAltName, &j)) { 2102 ret = HX509_PROXY_CERT_INVALID; 2103 hx509_set_error_string(context, 0, ret, 2104 "Proxy certificate have explicity " 2105 "forbidden issuerAltName"); 2106 goto out; 2107 } 2108 2109 /* 2110 * The subject name of the proxy certificate should be 2111 * CN=XXX,<proxy issuer>, prune of CN and check if its 2112 * the same over the whole chain of proxy certs and 2113 * then check with the EE cert when we get to it. 2114 */ 2115 2116 if (proxy_cert_depth) { 2117 ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject, &diff); 2118 if (ret) { 2119 hx509_set_error_string(context, 0, ret, "Out of memory"); 2120 goto out; 2121 } 2122 if (diff) { 2123 ret = HX509_PROXY_CERT_NAME_WRONG; 2124 hx509_set_error_string(context, 0, ret, 2125 "Base proxy name not right"); 2126 goto out; 2127 } 2128 } 2129 2130 free_Name(&proxy_issuer); 2131 2132 ret = copy_Name(&c->tbsCertificate.subject, &proxy_issuer); 2133 if (ret) { 2134 hx509_clear_error_string(context); 2135 goto out; 2136 } 2137 2138 j = proxy_issuer.u.rdnSequence.len; 2139 if (proxy_issuer.u.rdnSequence.len < 2 2140 || proxy_issuer.u.rdnSequence.val[j - 1].len > 1 2141 || der_heim_oid_cmp(&proxy_issuer.u.rdnSequence.val[j - 1].val[0].type, 2142 &asn1_oid_id_at_commonName)) 2143 { 2144 ret = HX509_PROXY_CERT_NAME_WRONG; 2145 hx509_set_error_string(context, 0, ret, 2146 "Proxy name too short or " 2147 "does not have Common name " 2148 "at the top"); 2149 goto out; 2150 } 2151 2152 free_RelativeDistinguishedName(&proxy_issuer.u.rdnSequence.val[j - 1]); 2153 proxy_issuer.u.rdnSequence.len -= 1; 2154 2155 ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer, &diff); 2156 if (ret) { 2157 hx509_set_error_string(context, 0, ret, "Out of memory"); 2158 goto out; 2159 } 2160 if (diff != 0) { 2161 ret = HX509_PROXY_CERT_NAME_WRONG; 2162 hx509_set_error_string(context, 0, ret, 2163 "Proxy issuer name not as expected"); 2164 goto out; 2165 } 2166 2167 break; 2168 } else { 2169 /* 2170 * Now we are done with the proxy certificates, this 2171 * cert was an EE cert and we we will fall though to 2172 * EE checking below. 2173 */ 2174 type = EE_CERT; 2175 /* FALLTHOUGH */ 2176 } 2177 } 2178 case EE_CERT: 2179 /* 2180 * If there where any proxy certificates in the chain 2181 * (proxy_cert_depth > 0), check that the proxy issuer 2182 * matched proxy certificates "base" subject. 2183 */ 2184 if (proxy_cert_depth) { 2185 2186 ret = _hx509_name_cmp(&proxy_issuer, 2187 &c->tbsCertificate.subject, &diff); 2188 if (ret) { 2189 hx509_set_error_string(context, 0, ret, "out of memory"); 2190 goto out; 2191 } 2192 if (diff) { 2193 ret = HX509_PROXY_CERT_NAME_WRONG; 2194 hx509_clear_error_string(context); 2195 goto out; 2196 } 2197 if (cert->basename) 2198 hx509_name_free(&cert->basename); 2199 2200 ret = _hx509_name_from_Name(&proxy_issuer, &cert->basename); 2201 if (ret) { 2202 hx509_clear_error_string(context); 2203 goto out; 2204 } 2205 } 2206 2207 break; 2208 } 2209 2210 ret = check_basic_constraints(context, c, type, 2211 i - proxy_cert_depth - selfsigned_depth); 2212 if (ret) 2213 goto out; 2214 2215 /* 2216 * Don't check the trust anchors expiration time since they 2217 * are transported out of band, from RFC3820. 2218 */ 2219 if (i + 1 != path.len || CHECK_TA(ctx)) { 2220 2221 t = _hx509_Time2time_t(&c->tbsCertificate.validity.notBefore); 2222 if (t > ctx->time_now) { 2223 ret = HX509_CERT_USED_BEFORE_TIME; 2224 hx509_clear_error_string(context); 2225 goto out; 2226 } 2227 t = _hx509_Time2time_t(&c->tbsCertificate.validity.notAfter); 2228 if (t < ctx->time_now) { 2229 ret = HX509_CERT_USED_AFTER_TIME; 2230 hx509_clear_error_string(context); 2231 goto out; 2232 } 2233 } 2234 2235 if (type == EE_CERT) 2236 type = CA_CERT; 2237 else if (type == PROXY_CERT) 2238 proxy_cert_depth++; 2239 } 2240 2241 /* 2242 * Verify constraints, do this backward so path constraints are 2243 * checked in the right order. 2244 */ 2245 2246 for (ret = 0, k = path.len; k > 0; k--) { 2247 Certificate *c; 2248 int selfsigned; 2249 i = k - 1; 2250 2251 c = _hx509_get_cert(path.val[i]); 2252 2253 ret = certificate_is_self_signed(context, c, &selfsigned); 2254 if (ret) 2255 goto out; 2256 2257 /* verify name constraints, not for selfsigned and anchor */ 2258 if (!selfsigned || i + 1 != path.len) { 2259 ret = check_name_constraints(context, &nc, c); 2260 if (ret) { 2261 goto out; 2262 } 2263 } 2264 ret = add_name_constraints(context, c, i == 0, &nc); 2265 if (ret) 2266 goto out; 2267 2268 /* XXX verify all other silly constraints */ 2269 2270 } 2271 2272 /* 2273 * Verify that no certificates has been revoked. 2274 */ 2275 2276 if (ctx->revoke_ctx) { 2277 hx509_certs certs; 2278 2279 ret = hx509_certs_init(context, "MEMORY:revoke-certs", 0, 2280 NULL, &certs); 2281 if (ret) 2282 goto out; 2283 2284 for (i = 0; i < path.len; i++) { 2285 ret = hx509_certs_add(context, certs, path.val[i]); 2286 if (ret) { 2287 hx509_certs_free(&certs); 2288 goto out; 2289 } 2290 } 2291 ret = hx509_certs_merge(context, certs, pool); 2292 if (ret) { 2293 hx509_certs_free(&certs); 2294 goto out; 2295 } 2296 2297 for (i = 0; i < path.len - 1; i++) { 2298 size_t parent = (i < path.len - 1) ? i + 1 : i; 2299 2300 ret = hx509_revoke_verify(context, 2301 ctx->revoke_ctx, 2302 certs, 2303 ctx->time_now, 2304 path.val[i], 2305 path.val[parent]); 2306 if (ret) { 2307 hx509_certs_free(&certs); 2308 goto out; 2309 } 2310 } 2311 hx509_certs_free(&certs); 2312 } 2313 2314 /* 2315 * Verify signatures, do this backward so public key working 2316 * parameter is passed up from the anchor up though the chain. 2317 */ 2318 2319 for (k = path.len; k > 0; k--) { 2320 hx509_cert signer; 2321 Certificate *c; 2322 i = k - 1; 2323 2324 c = _hx509_get_cert(path.val[i]); 2325 2326 /* is last in chain (trust anchor) */ 2327 if (i + 1 == path.len) { 2328 int selfsigned; 2329 2330 signer = path.val[i]; 2331 2332 ret = certificate_is_self_signed(context, signer->data, &selfsigned); 2333 if (ret) 2334 goto out; 2335 2336 /* if trust anchor is not self signed, don't check sig */ 2337 if (!selfsigned) 2338 continue; 2339 } else { 2340 /* take next certificate in chain */ 2341 signer = path.val[i + 1]; 2342 } 2343 2344 /* verify signatureValue */ 2345 ret = _hx509_verify_signature_bitstring(context, 2346 signer, 2347 &c->signatureAlgorithm, 2348 &c->tbsCertificate._save, 2349 &c->signatureValue); 2350 if (ret) { 2351 hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 2352 "Failed to verify signature of certificate"); 2353 goto out; 2354 } 2355 /* 2356 * Verify that the sigature algorithm "best-before" date is 2357 * before the creation date of the certificate, do this for 2358 * trust anchors too, since any trust anchor that is created 2359 * after a algorithm is known to be bad deserved to be invalid. 2360 * 2361 * Skip the leaf certificate for now... 2362 */ 2363 2364 if (i != 0 && (ctx->flags & HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK) == 0) { 2365 time_t notBefore = 2366 _hx509_Time2time_t(&c->tbsCertificate.validity.notBefore); 2367 ret = _hx509_signature_best_before(context, 2368 &c->signatureAlgorithm, 2369 notBefore); 2370 if (ret) 2371 goto out; 2372 } 2373 } 2374 2375 out: 2376 hx509_certs_free(&anchors); 2377 free_Name(&proxy_issuer); 2378 free_name_constraints(&nc); 2379 _hx509_path_free(&path); 2380 2381 return ret; 2382 } 2383 2384 /** 2385 * Verify a signature made using the private key of an certificate. 2386 * 2387 * @param context A hx509 context. 2388 * @param signer the certificate that made the signature. 2389 * @param alg algorthm that was used to sign the data. 2390 * @param data the data that was signed. 2391 * @param sig the sigature to verify. 2392 * 2393 * @return An hx509 error code, see hx509_get_error_string(). 2394 * 2395 * @ingroup hx509_crypto 2396 */ 2397 2398 int 2399 hx509_verify_signature(hx509_context context, 2400 const hx509_cert signer, 2401 const AlgorithmIdentifier *alg, 2402 const heim_octet_string *data, 2403 const heim_octet_string *sig) 2404 { 2405 return _hx509_verify_signature(context, signer, alg, data, sig); 2406 } 2407 2408 int 2409 _hx509_verify_signature_bitstring(hx509_context context, 2410 const hx509_cert signer, 2411 const AlgorithmIdentifier *alg, 2412 const heim_octet_string *data, 2413 const heim_bit_string *sig) 2414 { 2415 heim_octet_string os; 2416 2417 if (sig->length & 7) { 2418 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT, 2419 "signature not multiple of 8 bits"); 2420 return HX509_CRYPTO_SIG_INVALID_FORMAT; 2421 } 2422 2423 os.data = sig->data; 2424 os.length = sig->length / 8; 2425 2426 return _hx509_verify_signature(context, signer, alg, data, &os); 2427 } 2428 2429 2430 2431 /** 2432 * Verify that the certificate is allowed to be used for the hostname 2433 * and address. 2434 * 2435 * @param context A hx509 context. 2436 * @param cert the certificate to match with 2437 * @param flags Flags to modify the behavior: 2438 * - HX509_VHN_F_ALLOW_NO_MATCH no match is ok 2439 * @param type type of hostname: 2440 * - HX509_HN_HOSTNAME for plain hostname. 2441 * - HX509_HN_DNSSRV for DNS SRV names. 2442 * @param hostname the hostname to check 2443 * @param sa address of the host 2444 * @param sa_size length of address 2445 * 2446 * @return An hx509 error code, see hx509_get_error_string(). 2447 * 2448 * @ingroup hx509_cert 2449 */ 2450 2451 int 2452 hx509_verify_hostname(hx509_context context, 2453 const hx509_cert cert, 2454 int flags, 2455 hx509_hostname_type type, 2456 const char *hostname, 2457 const struct sockaddr *sa, 2458 /* XXX krb5_socklen_t */ int sa_size) 2459 { 2460 GeneralNames san; 2461 const Name *name; 2462 int ret; 2463 size_t i, j, k; 2464 2465 if (sa && sa_size <= 0) 2466 return EINVAL; 2467 2468 memset(&san, 0, sizeof(san)); 2469 2470 i = 0; 2471 do { 2472 ret = find_extension_subject_alt_name(cert->data, &i, &san); 2473 if (ret == HX509_EXTENSION_NOT_FOUND) 2474 break; 2475 else if (ret != 0) 2476 return HX509_PARSING_NAME_FAILED; 2477 2478 for (j = 0; j < san.len; j++) { 2479 switch (san.val[j].element) { 2480 case choice_GeneralName_dNSName: { 2481 heim_printable_string hn; 2482 hn.data = rk_UNCONST(hostname); 2483 hn.length = strlen(hostname); 2484 2485 if (der_printable_string_cmp(&san.val[j].u.dNSName, &hn) == 0) { 2486 free_GeneralNames(&san); 2487 return 0; 2488 } 2489 break; 2490 } 2491 default: 2492 break; 2493 } 2494 } 2495 free_GeneralNames(&san); 2496 } while (1); 2497 2498 name = &cert->data->tbsCertificate.subject; 2499 2500 /* Find first CN= in the name, and try to match the hostname on that */ 2501 for (ret = 0, k = name->u.rdnSequence.len; ret == 0 && k > 0; k--) { 2502 i = k - 1; 2503 for (j = 0; ret == 0 && j < name->u.rdnSequence.val[i].len; j++) { 2504 AttributeTypeAndValue *n = &name->u.rdnSequence.val[i].val[j]; 2505 2506 if (der_heim_oid_cmp(&n->type, &asn1_oid_id_at_commonName) == 0) { 2507 DirectoryString *ds = &n->value; 2508 switch (ds->element) { 2509 case choice_DirectoryString_printableString: { 2510 heim_printable_string hn; 2511 hn.data = rk_UNCONST(hostname); 2512 hn.length = strlen(hostname); 2513 2514 if (der_printable_string_cmp(&ds->u.printableString, &hn) == 0) 2515 return 0; 2516 break; 2517 } 2518 case choice_DirectoryString_ia5String: { 2519 heim_ia5_string hn; 2520 hn.data = rk_UNCONST(hostname); 2521 hn.length = strlen(hostname); 2522 2523 if (der_ia5_string_cmp(&ds->u.ia5String, &hn) == 0) 2524 return 0; 2525 break; 2526 } 2527 case choice_DirectoryString_utf8String: 2528 if (strcasecmp(ds->u.utf8String, hostname) == 0) 2529 return 0; 2530 default: 2531 break; 2532 } 2533 ret = HX509_NAME_CONSTRAINT_ERROR; 2534 } 2535 } 2536 } 2537 2538 if ((flags & HX509_VHN_F_ALLOW_NO_MATCH) == 0) 2539 ret = HX509_NAME_CONSTRAINT_ERROR; 2540 2541 return ret; 2542 } 2543 2544 int 2545 _hx509_set_cert_attribute(hx509_context context, 2546 hx509_cert cert, 2547 const heim_oid *oid, 2548 const heim_octet_string *attr) 2549 { 2550 hx509_cert_attribute a; 2551 void *d; 2552 2553 if (hx509_cert_get_attribute(cert, oid) != NULL) 2554 return 0; 2555 2556 d = realloc(cert->attrs.val, 2557 sizeof(cert->attrs.val[0]) * (cert->attrs.len + 1)); 2558 if (d == NULL) { 2559 hx509_clear_error_string(context); 2560 return ENOMEM; 2561 } 2562 cert->attrs.val = d; 2563 2564 a = malloc(sizeof(*a)); 2565 if (a == NULL) 2566 return ENOMEM; 2567 2568 der_copy_octet_string(attr, &a->data); 2569 der_copy_oid(oid, &a->oid); 2570 2571 cert->attrs.val[cert->attrs.len] = a; 2572 cert->attrs.len++; 2573 2574 return 0; 2575 } 2576 2577 /** 2578 * Get an external attribute for the certificate, examples are 2579 * friendly name and id. 2580 * 2581 * @param cert hx509 certificate object to search 2582 * @param oid an oid to search for. 2583 * 2584 * @return an hx509_cert_attribute, only valid as long as the 2585 * certificate is referenced. 2586 * 2587 * @ingroup hx509_cert 2588 */ 2589 2590 hx509_cert_attribute 2591 hx509_cert_get_attribute(hx509_cert cert, const heim_oid *oid) 2592 { 2593 size_t i; 2594 for (i = 0; i < cert->attrs.len; i++) 2595 if (der_heim_oid_cmp(oid, &cert->attrs.val[i]->oid) == 0) 2596 return cert->attrs.val[i]; 2597 return NULL; 2598 } 2599 2600 /** 2601 * Set the friendly name on the certificate. 2602 * 2603 * @param cert The certificate to set the friendly name on 2604 * @param name Friendly name. 2605 * 2606 * @return An hx509 error code, see hx509_get_error_string(). 2607 * 2608 * @ingroup hx509_cert 2609 */ 2610 2611 int 2612 hx509_cert_set_friendly_name(hx509_cert cert, const char *name) 2613 { 2614 if (cert->friendlyname) 2615 free(cert->friendlyname); 2616 cert->friendlyname = strdup(name); 2617 if (cert->friendlyname == NULL) 2618 return ENOMEM; 2619 return 0; 2620 } 2621 2622 /** 2623 * Get friendly name of the certificate. 2624 * 2625 * @param cert cert to get the friendly name from. 2626 * 2627 * @return an friendly name or NULL if there is. The friendly name is 2628 * only valid as long as the certificate is referenced. 2629 * 2630 * @ingroup hx509_cert 2631 */ 2632 2633 const char * 2634 hx509_cert_get_friendly_name(hx509_cert cert) 2635 { 2636 hx509_cert_attribute a; 2637 PKCS9_friendlyName n; 2638 size_t sz; 2639 int ret; 2640 size_t i; 2641 2642 if (cert->friendlyname) 2643 return cert->friendlyname; 2644 2645 a = hx509_cert_get_attribute(cert, &asn1_oid_id_pkcs_9_at_friendlyName); 2646 if (a == NULL) { 2647 hx509_name name; 2648 2649 ret = hx509_cert_get_subject(cert, &name); 2650 if (ret) 2651 return NULL; 2652 ret = hx509_name_to_string(name, &cert->friendlyname); 2653 hx509_name_free(&name); 2654 if (ret) 2655 return NULL; 2656 return cert->friendlyname; 2657 } 2658 2659 ret = decode_PKCS9_friendlyName(a->data.data, a->data.length, &n, &sz); 2660 if (ret) 2661 return NULL; 2662 2663 if (n.len != 1) { 2664 free_PKCS9_friendlyName(&n); 2665 return NULL; 2666 } 2667 2668 cert->friendlyname = malloc(n.val[0].length + 1); 2669 if (cert->friendlyname == NULL) { 2670 free_PKCS9_friendlyName(&n); 2671 return NULL; 2672 } 2673 2674 for (i = 0; i < n.val[0].length; i++) { 2675 if (n.val[0].data[i] <= 0xff) 2676 cert->friendlyname[i] = n.val[0].data[i] & 0xff; 2677 else 2678 cert->friendlyname[i] = 'X'; 2679 } 2680 cert->friendlyname[i] = '\0'; 2681 free_PKCS9_friendlyName(&n); 2682 2683 return cert->friendlyname; 2684 } 2685 2686 void 2687 _hx509_query_clear(hx509_query *q) 2688 { 2689 memset(q, 0, sizeof(*q)); 2690 } 2691 2692 /** 2693 * Allocate an query controller. Free using hx509_query_free(). 2694 * 2695 * @param context A hx509 context. 2696 * @param q return pointer to a hx509_query. 2697 * 2698 * @return An hx509 error code, see hx509_get_error_string(). 2699 * 2700 * @ingroup hx509_cert 2701 */ 2702 2703 int 2704 hx509_query_alloc(hx509_context context, hx509_query **q) 2705 { 2706 *q = calloc(1, sizeof(**q)); 2707 if (*q == NULL) 2708 return ENOMEM; 2709 return 0; 2710 } 2711 2712 2713 /** 2714 * Set match options for the hx509 query controller. 2715 * 2716 * @param q query controller. 2717 * @param option options to control the query controller. 2718 * 2719 * @return An hx509 error code, see hx509_get_error_string(). 2720 * 2721 * @ingroup hx509_cert 2722 */ 2723 2724 void 2725 hx509_query_match_option(hx509_query *q, hx509_query_option option) 2726 { 2727 switch(option) { 2728 case HX509_QUERY_OPTION_PRIVATE_KEY: 2729 q->match |= HX509_QUERY_PRIVATE_KEY; 2730 break; 2731 case HX509_QUERY_OPTION_KU_ENCIPHERMENT: 2732 q->match |= HX509_QUERY_KU_ENCIPHERMENT; 2733 break; 2734 case HX509_QUERY_OPTION_KU_DIGITALSIGNATURE: 2735 q->match |= HX509_QUERY_KU_DIGITALSIGNATURE; 2736 break; 2737 case HX509_QUERY_OPTION_KU_KEYCERTSIGN: 2738 q->match |= HX509_QUERY_KU_KEYCERTSIGN; 2739 break; 2740 case HX509_QUERY_OPTION_END: 2741 default: 2742 break; 2743 } 2744 } 2745 2746 /** 2747 * Set the issuer and serial number of match in the query 2748 * controller. The function make copies of the isser and serial number. 2749 * 2750 * @param q a hx509 query controller 2751 * @param issuer issuer to search for 2752 * @param serialNumber the serialNumber of the issuer. 2753 * 2754 * @return An hx509 error code, see hx509_get_error_string(). 2755 * 2756 * @ingroup hx509_cert 2757 */ 2758 2759 int 2760 hx509_query_match_issuer_serial(hx509_query *q, 2761 const Name *issuer, 2762 const heim_integer *serialNumber) 2763 { 2764 int ret; 2765 if (q->serial) { 2766 der_free_heim_integer(q->serial); 2767 free(q->serial); 2768 } 2769 q->serial = malloc(sizeof(*q->serial)); 2770 if (q->serial == NULL) 2771 return ENOMEM; 2772 ret = der_copy_heim_integer(serialNumber, q->serial); 2773 if (ret) { 2774 free(q->serial); 2775 q->serial = NULL; 2776 return ret; 2777 } 2778 if (q->issuer_name) { 2779 free_Name(q->issuer_name); 2780 free(q->issuer_name); 2781 } 2782 q->issuer_name = malloc(sizeof(*q->issuer_name)); 2783 if (q->issuer_name == NULL) 2784 return ENOMEM; 2785 ret = copy_Name(issuer, q->issuer_name); 2786 if (ret) { 2787 free(q->issuer_name); 2788 q->issuer_name = NULL; 2789 return ret; 2790 } 2791 q->match |= HX509_QUERY_MATCH_SERIALNUMBER|HX509_QUERY_MATCH_ISSUER_NAME; 2792 return 0; 2793 } 2794 2795 /** 2796 * Set the query controller to match on a friendly name 2797 * 2798 * @param q a hx509 query controller. 2799 * @param name a friendly name to match on 2800 * 2801 * @return An hx509 error code, see hx509_get_error_string(). 2802 * 2803 * @ingroup hx509_cert 2804 */ 2805 2806 int 2807 hx509_query_match_friendly_name(hx509_query *q, const char *name) 2808 { 2809 if (q->friendlyname) 2810 free(q->friendlyname); 2811 q->friendlyname = strdup(name); 2812 if (q->friendlyname == NULL) 2813 return ENOMEM; 2814 q->match |= HX509_QUERY_MATCH_FRIENDLY_NAME; 2815 return 0; 2816 } 2817 2818 /** 2819 * Set the query controller to require an one specific EKU (extended 2820 * key usage). Any previous EKU matching is overwitten. If NULL is 2821 * passed in as the eku, the EKU requirement is reset. 2822 * 2823 * @param q a hx509 query controller. 2824 * @param eku an EKU to match on. 2825 * 2826 * @return An hx509 error code, see hx509_get_error_string(). 2827 * 2828 * @ingroup hx509_cert 2829 */ 2830 2831 int 2832 hx509_query_match_eku(hx509_query *q, const heim_oid *eku) 2833 { 2834 int ret; 2835 2836 if (eku == NULL) { 2837 if (q->eku) { 2838 der_free_oid(q->eku); 2839 free(q->eku); 2840 q->eku = NULL; 2841 } 2842 q->match &= ~HX509_QUERY_MATCH_EKU; 2843 } else { 2844 if (q->eku) { 2845 der_free_oid(q->eku); 2846 } else { 2847 q->eku = calloc(1, sizeof(*q->eku)); 2848 if (q->eku == NULL) 2849 return ENOMEM; 2850 } 2851 ret = der_copy_oid(eku, q->eku); 2852 if (ret) { 2853 free(q->eku); 2854 q->eku = NULL; 2855 return ret; 2856 } 2857 q->match |= HX509_QUERY_MATCH_EKU; 2858 } 2859 return 0; 2860 } 2861 2862 int 2863 hx509_query_match_expr(hx509_context context, hx509_query *q, const char *expr) 2864 { 2865 if (q->expr) { 2866 _hx509_expr_free(q->expr); 2867 q->expr = NULL; 2868 } 2869 2870 if (expr == NULL) { 2871 q->match &= ~HX509_QUERY_MATCH_EXPR; 2872 } else { 2873 q->expr = _hx509_expr_parse(expr); 2874 if (q->expr) 2875 q->match |= HX509_QUERY_MATCH_EXPR; 2876 } 2877 2878 return 0; 2879 } 2880 2881 /** 2882 * Set the query controller to match using a specific match function. 2883 * 2884 * @param q a hx509 query controller. 2885 * @param func function to use for matching, if the argument is NULL, 2886 * the match function is removed. 2887 * @param ctx context passed to the function. 2888 * 2889 * @return An hx509 error code, see hx509_get_error_string(). 2890 * 2891 * @ingroup hx509_cert 2892 */ 2893 2894 int 2895 hx509_query_match_cmp_func(hx509_query *q, 2896 int (*func)(hx509_context, hx509_cert, void *), 2897 void *ctx) 2898 { 2899 if (func) 2900 q->match |= HX509_QUERY_MATCH_FUNCTION; 2901 else 2902 q->match &= ~HX509_QUERY_MATCH_FUNCTION; 2903 q->cmp_func = func; 2904 q->cmp_func_ctx = ctx; 2905 return 0; 2906 } 2907 2908 /** 2909 * Free the query controller. 2910 * 2911 * @param context A hx509 context. 2912 * @param q a pointer to the query controller. 2913 * 2914 * @ingroup hx509_cert 2915 */ 2916 2917 void 2918 hx509_query_free(hx509_context context, hx509_query *q) 2919 { 2920 if (q == NULL) 2921 return; 2922 2923 if (q->serial) { 2924 der_free_heim_integer(q->serial); 2925 free(q->serial); 2926 } 2927 if (q->issuer_name) { 2928 free_Name(q->issuer_name); 2929 free(q->issuer_name); 2930 } 2931 if (q->eku) { 2932 der_free_oid(q->eku); 2933 free(q->eku); 2934 } 2935 if (q->friendlyname) 2936 free(q->friendlyname); 2937 if (q->expr) 2938 _hx509_expr_free(q->expr); 2939 2940 memset(q, 0, sizeof(*q)); 2941 free(q); 2942 } 2943 2944 int 2945 _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert cert) 2946 { 2947 Certificate *c = _hx509_get_cert(cert); 2948 int ret, diff; 2949 2950 _hx509_query_statistic(context, 1, q); 2951 2952 if ((q->match & HX509_QUERY_FIND_ISSUER_CERT) && 2953 _hx509_cert_is_parent_cmp(q->subject, c, 0) != 0) 2954 return 0; 2955 2956 if ((q->match & HX509_QUERY_MATCH_CERTIFICATE) && 2957 _hx509_Certificate_cmp(q->certificate, c) != 0) 2958 return 0; 2959 2960 if ((q->match & HX509_QUERY_MATCH_SERIALNUMBER) 2961 && der_heim_integer_cmp(&c->tbsCertificate.serialNumber, q->serial) != 0) 2962 return 0; 2963 2964 if (q->match & HX509_QUERY_MATCH_ISSUER_NAME) { 2965 ret = _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name, &diff); 2966 if (ret || diff) 2967 return 0; 2968 } 2969 2970 if (q->match & HX509_QUERY_MATCH_SUBJECT_NAME) { 2971 ret = _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name, &diff); 2972 if (ret || diff) 2973 return 0; 2974 } 2975 2976 if (q->match & HX509_QUERY_MATCH_SUBJECT_KEY_ID) { 2977 SubjectKeyIdentifier si; 2978 2979 ret = _hx509_find_extension_subject_key_id(c, &si); 2980 if (ret == 0) { 2981 if (der_heim_octet_string_cmp(&si, q->subject_id) != 0) 2982 ret = 1; 2983 free_SubjectKeyIdentifier(&si); 2984 } 2985 if (ret) 2986 return 0; 2987 } 2988 if ((q->match & HX509_QUERY_MATCH_ISSUER_ID)) 2989 return 0; 2990 if ((q->match & HX509_QUERY_PRIVATE_KEY) && 2991 _hx509_cert_private_key(cert) == NULL) 2992 return 0; 2993 2994 { 2995 unsigned ku = 0; 2996 if (q->match & HX509_QUERY_KU_DIGITALSIGNATURE) 2997 ku |= (1 << 0); 2998 if (q->match & HX509_QUERY_KU_NONREPUDIATION) 2999 ku |= (1 << 1); 3000 if (q->match & HX509_QUERY_KU_ENCIPHERMENT) 3001 ku |= (1 << 2); 3002 if (q->match & HX509_QUERY_KU_DATAENCIPHERMENT) 3003 ku |= (1 << 3); 3004 if (q->match & HX509_QUERY_KU_KEYAGREEMENT) 3005 ku |= (1 << 4); 3006 if (q->match & HX509_QUERY_KU_KEYCERTSIGN) 3007 ku |= (1 << 5); 3008 if (q->match & HX509_QUERY_KU_CRLSIGN) 3009 ku |= (1 << 6); 3010 if (ku && check_key_usage(context, c, ku, TRUE)) 3011 return 0; 3012 } 3013 if ((q->match & HX509_QUERY_ANCHOR)) 3014 return 0; 3015 3016 if (q->match & HX509_QUERY_MATCH_LOCAL_KEY_ID) { 3017 hx509_cert_attribute a; 3018 3019 a = hx509_cert_get_attribute(cert, &asn1_oid_id_pkcs_9_at_localKeyId); 3020 if (a == NULL) 3021 return 0; 3022 if (der_heim_octet_string_cmp(&a->data, q->local_key_id) != 0) 3023 return 0; 3024 } 3025 3026 if (q->match & HX509_QUERY_NO_MATCH_PATH) { 3027 size_t i; 3028 3029 for (i = 0; i < q->path->len; i++) 3030 if (hx509_cert_cmp(q->path->val[i], cert) == 0) 3031 return 0; 3032 } 3033 if (q->match & HX509_QUERY_MATCH_FRIENDLY_NAME) { 3034 const char *name = hx509_cert_get_friendly_name(cert); 3035 if (name == NULL) 3036 return 0; 3037 if (strcasecmp(q->friendlyname, name) != 0) 3038 return 0; 3039 } 3040 if (q->match & HX509_QUERY_MATCH_FUNCTION) { 3041 ret = (*q->cmp_func)(context, cert, q->cmp_func_ctx); 3042 if (ret != 0) 3043 return 0; 3044 } 3045 3046 if (q->match & HX509_QUERY_MATCH_KEY_HASH_SHA1) { 3047 heim_octet_string os; 3048 3049 os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data; 3050 os.length = 3051 c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8; 3052 3053 ret = _hx509_verify_signature(context, 3054 NULL, 3055 hx509_signature_sha1(), 3056 &os, 3057 q->keyhash_sha1); 3058 if (ret != 0) 3059 return 0; 3060 } 3061 3062 if (q->match & HX509_QUERY_MATCH_TIME) { 3063 time_t t; 3064 t = _hx509_Time2time_t(&c->tbsCertificate.validity.notBefore); 3065 if (t > q->timenow) 3066 return 0; 3067 t = _hx509_Time2time_t(&c->tbsCertificate.validity.notAfter); 3068 if (t < q->timenow) 3069 return 0; 3070 } 3071 3072 /* If an EKU is required, check the cert for it. */ 3073 if ((q->match & HX509_QUERY_MATCH_EKU) && 3074 hx509_cert_check_eku(context, cert, q->eku, 0)) 3075 return 0; 3076 3077 if ((q->match & HX509_QUERY_MATCH_EXPR)) { 3078 hx509_env env = NULL; 3079 3080 ret = _hx509_cert_to_env(context, cert, &env); 3081 if (ret) 3082 return 0; 3083 3084 ret = _hx509_expr_eval(context, env, q->expr); 3085 hx509_env_free(&env); 3086 if (ret == 0) 3087 return 0; 3088 } 3089 3090 if (q->match & ~HX509_QUERY_MASK) 3091 return 0; 3092 3093 return 1; 3094 } 3095 3096 /** 3097 * Set a statistic file for the query statistics. 3098 * 3099 * @param context A hx509 context. 3100 * @param fn statistics file name 3101 * 3102 * @ingroup hx509_cert 3103 */ 3104 3105 void 3106 hx509_query_statistic_file(hx509_context context, const char *fn) 3107 { 3108 if (context->querystat) 3109 free(context->querystat); 3110 context->querystat = strdup(fn); 3111 } 3112 3113 void 3114 _hx509_query_statistic(hx509_context context, int type, const hx509_query *q) 3115 { 3116 FILE *f; 3117 if (context->querystat == NULL) 3118 return; 3119 f = fopen(context->querystat, "a"); 3120 if (f == NULL) 3121 return; 3122 rk_cloexec_file(f); 3123 fprintf(f, "%d %d\n", type, q->match); 3124 fclose(f); 3125 } 3126 3127 static const char *statname[] = { 3128 "find issuer cert", 3129 "match serialnumber", 3130 "match issuer name", 3131 "match subject name", 3132 "match subject key id", 3133 "match issuer id", 3134 "private key", 3135 "ku encipherment", 3136 "ku digitalsignature", 3137 "ku keycertsign", 3138 "ku crlsign", 3139 "ku nonrepudiation", 3140 "ku keyagreement", 3141 "ku dataencipherment", 3142 "anchor", 3143 "match certificate", 3144 "match local key id", 3145 "no match path", 3146 "match friendly name", 3147 "match function", 3148 "match key hash sha1", 3149 "match time" 3150 }; 3151 3152 struct stat_el { 3153 unsigned long stats; 3154 unsigned int index; 3155 }; 3156 3157 3158 static int 3159 stat_sort(const void *a, const void *b) 3160 { 3161 const struct stat_el *ae = a; 3162 const struct stat_el *be = b; 3163 return be->stats - ae->stats; 3164 } 3165 3166 /** 3167 * Unparse the statistics file and print the result on a FILE descriptor. 3168 * 3169 * @param context A hx509 context. 3170 * @param printtype tyep to print 3171 * @param out the FILE to write the data on. 3172 * 3173 * @ingroup hx509_cert 3174 */ 3175 3176 void 3177 hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out) 3178 { 3179 rtbl_t t; 3180 FILE *f; 3181 int type, mask, num; 3182 size_t i; 3183 unsigned long multiqueries = 0, totalqueries = 0; 3184 struct stat_el stats[32]; 3185 3186 if (context->querystat == NULL) 3187 return; 3188 f = fopen(context->querystat, "r"); 3189 if (f == NULL) { 3190 fprintf(out, "No statistic file %s: %s.\n", 3191 context->querystat, strerror(errno)); 3192 return; 3193 } 3194 rk_cloexec_file(f); 3195 3196 for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) { 3197 stats[i].index = i; 3198 stats[i].stats = 0; 3199 } 3200 3201 while (fscanf(f, "%d %d\n", &type, &mask) == 2) { 3202 if (type != printtype) 3203 continue; 3204 num = i = 0; 3205 while (mask && i < sizeof(stats)/sizeof(stats[0])) { 3206 if (mask & 1) { 3207 stats[i].stats++; 3208 num++; 3209 } 3210 mask = mask >>1 ; 3211 i++; 3212 } 3213 if (num > 1) 3214 multiqueries++; 3215 totalqueries++; 3216 } 3217 fclose(f); 3218 3219 qsort(stats, sizeof(stats)/sizeof(stats[0]), sizeof(stats[0]), stat_sort); 3220 3221 t = rtbl_create(); 3222 if (t == NULL) 3223 errx(1, "out of memory"); 3224 3225 rtbl_set_separator (t, " "); 3226 3227 rtbl_add_column_by_id (t, 0, "Name", 0); 3228 rtbl_add_column_by_id (t, 1, "Counter", 0); 3229 3230 3231 for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) { 3232 char str[10]; 3233 3234 if (stats[i].index < sizeof(statname)/sizeof(statname[0])) 3235 rtbl_add_column_entry_by_id (t, 0, statname[stats[i].index]); 3236 else { 3237 snprintf(str, sizeof(str), "%d", stats[i].index); 3238 rtbl_add_column_entry_by_id (t, 0, str); 3239 } 3240 snprintf(str, sizeof(str), "%lu", stats[i].stats); 3241 rtbl_add_column_entry_by_id (t, 1, str); 3242 } 3243 3244 rtbl_format(t, out); 3245 rtbl_destroy(t); 3246 3247 fprintf(out, "\nQueries: multi %lu total %lu\n", 3248 multiqueries, totalqueries); 3249 } 3250 3251 /** 3252 * Check the extended key usage on the hx509 certificate. 3253 * 3254 * @param context A hx509 context. 3255 * @param cert A hx509 context. 3256 * @param eku the EKU to check for 3257 * @param allow_any_eku if the any EKU is set, allow that to be a 3258 * substitute. 3259 * 3260 * @return An hx509 error code, see hx509_get_error_string(). 3261 * 3262 * @ingroup hx509_cert 3263 */ 3264 3265 int 3266 hx509_cert_check_eku(hx509_context context, hx509_cert cert, 3267 const heim_oid *eku, int allow_any_eku) 3268 { 3269 ExtKeyUsage e; 3270 int ret; 3271 size_t i; 3272 3273 ret = find_extension_eku(_hx509_get_cert(cert), &e); 3274 if (ret) { 3275 hx509_clear_error_string(context); 3276 return ret; 3277 } 3278 3279 for (i = 0; i < e.len; i++) { 3280 if (der_heim_oid_cmp(eku, &e.val[i]) == 0) { 3281 free_ExtKeyUsage(&e); 3282 return 0; 3283 } 3284 if (allow_any_eku) { 3285 #if 0 3286 if (der_heim_oid_cmp(id_any_eku, &e.val[i]) == 0) { 3287 free_ExtKeyUsage(&e); 3288 return 0; 3289 } 3290 #endif 3291 } 3292 } 3293 free_ExtKeyUsage(&e); 3294 hx509_clear_error_string(context); 3295 return HX509_CERTIFICATE_MISSING_EKU; 3296 } 3297 3298 int 3299 _hx509_cert_get_keyusage(hx509_context context, 3300 hx509_cert c, 3301 KeyUsage *ku) 3302 { 3303 Certificate *cert; 3304 const Extension *e; 3305 size_t size; 3306 int ret; 3307 size_t i = 0; 3308 3309 memset(ku, 0, sizeof(*ku)); 3310 3311 cert = _hx509_get_cert(c); 3312 3313 if (_hx509_cert_get_version(cert) < 3) 3314 return 0; 3315 3316 e = find_extension(cert, &asn1_oid_id_x509_ce_keyUsage, &i); 3317 if (e == NULL) 3318 return HX509_KU_CERT_MISSING; 3319 3320 ret = decode_KeyUsage(e->extnValue.data, e->extnValue.length, ku, &size); 3321 if (ret) 3322 return ret; 3323 return 0; 3324 } 3325 3326 int 3327 _hx509_cert_get_eku(hx509_context context, 3328 hx509_cert cert, 3329 ExtKeyUsage *e) 3330 { 3331 int ret; 3332 3333 memset(e, 0, sizeof(*e)); 3334 3335 ret = find_extension_eku(_hx509_get_cert(cert), e); 3336 if (ret && ret != HX509_EXTENSION_NOT_FOUND) { 3337 hx509_clear_error_string(context); 3338 return ret; 3339 } 3340 return 0; 3341 } 3342 3343 /** 3344 * Encodes the hx509 certificate as a DER encode binary. 3345 * 3346 * @param context A hx509 context. 3347 * @param c the certificate to encode. 3348 * @param os the encode certificate, set to NULL, 0 on case of 3349 * error. Free the os->data with hx509_xfree(). 3350 * 3351 * @return An hx509 error code, see hx509_get_error_string(). 3352 * 3353 * @ingroup hx509_cert 3354 */ 3355 3356 int 3357 hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os) 3358 { 3359 size_t size; 3360 int ret; 3361 3362 os->data = NULL; 3363 os->length = 0; 3364 3365 ASN1_MALLOC_ENCODE(Certificate, os->data, os->length, 3366 _hx509_get_cert(c), &size, ret); 3367 if (ret) { 3368 os->data = NULL; 3369 os->length = 0; 3370 return ret; 3371 } 3372 if (os->length != size) 3373 _hx509_abort("internal ASN.1 encoder error"); 3374 3375 return ret; 3376 } 3377 3378 /* 3379 * Last to avoid lost __attribute__s due to #undef. 3380 */ 3381 3382 #undef __attribute__ 3383 #define __attribute__(X) 3384 3385 void 3386 _hx509_abort(const char *fmt, ...) 3387 __attribute__ ((noreturn, format (printf, 1, 2))) 3388 { 3389 va_list ap; 3390 va_start(ap, fmt); 3391 vprintf(fmt, ap); 3392 va_end(ap); 3393 printf("\n"); 3394 fflush(stdout); 3395 abort(); 3396 } 3397 3398 /** 3399 * Free a data element allocated in the library. 3400 * 3401 * @param ptr data to be freed. 3402 * 3403 * @ingroup hx509_misc 3404 */ 3405 3406 void 3407 hx509_xfree(void *ptr) 3408 { 3409 free(ptr); 3410 } 3411 3412 /** 3413 * 3414 */ 3415 3416 int 3417 _hx509_cert_to_env(hx509_context context, hx509_cert cert, hx509_env *env) 3418 { 3419 ExtKeyUsage eku; 3420 hx509_name name; 3421 char *buf; 3422 int ret; 3423 hx509_env envcert = NULL; 3424 3425 *env = NULL; 3426 3427 /* version */ 3428 asprintf(&buf, "%d", _hx509_cert_get_version(_hx509_get_cert(cert))); 3429 ret = hx509_env_add(context, &envcert, "version", buf); 3430 free(buf); 3431 if (ret) 3432 goto out; 3433 3434 /* subject */ 3435 ret = hx509_cert_get_subject(cert, &name); 3436 if (ret) 3437 goto out; 3438 3439 ret = hx509_name_to_string(name, &buf); 3440 if (ret) { 3441 hx509_name_free(&name); 3442 goto out; 3443 } 3444 3445 ret = hx509_env_add(context, &envcert, "subject", buf); 3446 hx509_name_free(&name); 3447 if (ret) 3448 goto out; 3449 3450 /* issuer */ 3451 ret = hx509_cert_get_issuer(cert, &name); 3452 if (ret) 3453 goto out; 3454 3455 ret = hx509_name_to_string(name, &buf); 3456 hx509_name_free(&name); 3457 if (ret) 3458 goto out; 3459 3460 ret = hx509_env_add(context, &envcert, "issuer", buf); 3461 hx509_xfree(buf); 3462 if (ret) 3463 goto out; 3464 3465 /* eku */ 3466 3467 ret = _hx509_cert_get_eku(context, cert, &eku); 3468 if (ret == HX509_EXTENSION_NOT_FOUND) 3469 ; 3470 else if (ret != 0) 3471 goto out; 3472 else { 3473 size_t i; 3474 hx509_env enveku = NULL; 3475 3476 for (i = 0; i < eku.len; i++) { 3477 3478 ret = der_print_heim_oid(&eku.val[i], '.', &buf); 3479 if (ret) { 3480 free_ExtKeyUsage(&eku); 3481 hx509_env_free(&enveku); 3482 goto out; 3483 } 3484 ret = hx509_env_add(context, &enveku, buf, "oid-name-here"); 3485 free(buf); 3486 if (ret) { 3487 free_ExtKeyUsage(&eku); 3488 hx509_env_free(&enveku); 3489 goto out; 3490 } 3491 } 3492 free_ExtKeyUsage(&eku); 3493 3494 ret = hx509_env_add_binding(context, &envcert, "eku", enveku); 3495 if (ret) { 3496 hx509_env_free(&enveku); 3497 goto out; 3498 } 3499 } 3500 3501 { 3502 Certificate *c = _hx509_get_cert(cert); 3503 heim_octet_string os, sig; 3504 hx509_env envhash = NULL; 3505 3506 os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data; 3507 os.length = 3508 c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8; 3509 3510 ret = _hx509_create_signature(context, 3511 NULL, 3512 hx509_signature_sha1(), 3513 &os, 3514 NULL, 3515 &sig); 3516 if (ret != 0) 3517 goto out; 3518 3519 ret = hex_encode(sig.data, sig.length, &buf); 3520 der_free_octet_string(&sig); 3521 if (ret < 0) { 3522 ret = ENOMEM; 3523 hx509_set_error_string(context, 0, ret, 3524 "Out of memory"); 3525 goto out; 3526 } 3527 3528 ret = hx509_env_add(context, &envhash, "sha1", buf); 3529 free(buf); 3530 if (ret) 3531 goto out; 3532 3533 ret = hx509_env_add_binding(context, &envcert, "hash", envhash); 3534 if (ret) { 3535 hx509_env_free(&envhash); 3536 goto out; 3537 } 3538 } 3539 3540 ret = hx509_env_add_binding(context, env, "certificate", envcert); 3541 if (ret) 3542 goto out; 3543 3544 return 0; 3545 3546 out: 3547 hx509_env_free(&envcert); 3548 return ret; 3549 } 3550 3551 /** 3552 * Print a simple representation of a certificate 3553 * 3554 * @param context A hx509 context, can be NULL 3555 * @param cert certificate to print 3556 * @param out the stdio output stream, if NULL, stdout is used 3557 * 3558 * @return An hx509 error code 3559 * 3560 * @ingroup hx509_cert 3561 */ 3562 3563 int 3564 hx509_print_cert(hx509_context context, hx509_cert cert, FILE *out) 3565 { 3566 hx509_name name; 3567 char *str; 3568 int ret; 3569 3570 if (out == NULL) 3571 out = stderr; 3572 3573 ret = hx509_cert_get_issuer(cert, &name); 3574 if (ret) 3575 return ret; 3576 hx509_name_to_string(name, &str); 3577 hx509_name_free(&name); 3578 fprintf(out, " issuer: \"%s\"\n", str); 3579 free(str); 3580 3581 ret = hx509_cert_get_subject(cert, &name); 3582 if (ret) 3583 return ret; 3584 hx509_name_to_string(name, &str); 3585 hx509_name_free(&name); 3586 fprintf(out, " subject: \"%s\"\n", str); 3587 free(str); 3588 3589 { 3590 heim_integer serialNumber; 3591 3592 ret = hx509_cert_get_serialnumber(cert, &serialNumber); 3593 if (ret) 3594 return ret; 3595 ret = der_print_hex_heim_integer(&serialNumber, &str); 3596 if (ret) 3597 return ret; 3598 der_free_heim_integer(&serialNumber); 3599 fprintf(out, " serial: %s\n", str); 3600 free(str); 3601 } 3602 3603 printf(" keyusage: "); 3604 ret = hx509_cert_keyusage_print(context, cert, &str); 3605 if (ret == 0) { 3606 fprintf(out, "%s\n", str); 3607 free(str); 3608 } else 3609 fprintf(out, "no"); 3610 3611 return 0; 3612 } 3613