1 /* $NetBSD: ca.c,v 1.2 2017/01/28 21:31:48 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2006 - 2010 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "hx_locl.h" 37 #include <krb5/pkinit_asn1.h> 38 39 /** 40 * @page page_ca Hx509 CA functions 41 * 42 * See the library functions here: @ref hx509_ca 43 */ 44 45 struct hx509_ca_tbs { 46 hx509_name subject; 47 SubjectPublicKeyInfo spki; 48 ExtKeyUsage eku; 49 GeneralNames san; 50 unsigned key_usage; 51 heim_integer serial; 52 struct { 53 unsigned int proxy:1; 54 unsigned int ca:1; 55 unsigned int key:1; 56 unsigned int serial:1; 57 unsigned int domaincontroller:1; 58 unsigned int xUniqueID:1; 59 } flags; 60 time_t notBefore; 61 time_t notAfter; 62 int pathLenConstraint; /* both for CA and Proxy */ 63 CRLDistributionPoints crldp; 64 heim_bit_string subjectUniqueID; 65 heim_bit_string issuerUniqueID; 66 AlgorithmIdentifier *sigalg; 67 }; 68 69 /** 70 * Allocate an to-be-signed certificate object that will be converted 71 * into an certificate. 72 * 73 * @param context A hx509 context. 74 * @param tbs returned to-be-signed certicate object, free with 75 * hx509_ca_tbs_free(). 76 * 77 * @return An hx509 error code, see hx509_get_error_string(). 78 * 79 * @ingroup hx509_ca 80 */ 81 82 int 83 hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs) 84 { 85 *tbs = calloc(1, sizeof(**tbs)); 86 if (*tbs == NULL) 87 return ENOMEM; 88 89 return 0; 90 } 91 92 /** 93 * Free an To Be Signed object. 94 * 95 * @param tbs object to free. 96 * 97 * @ingroup hx509_ca 98 */ 99 100 void 101 hx509_ca_tbs_free(hx509_ca_tbs *tbs) 102 { 103 if (tbs == NULL || *tbs == NULL) 104 return; 105 106 free_SubjectPublicKeyInfo(&(*tbs)->spki); 107 free_GeneralNames(&(*tbs)->san); 108 free_ExtKeyUsage(&(*tbs)->eku); 109 der_free_heim_integer(&(*tbs)->serial); 110 free_CRLDistributionPoints(&(*tbs)->crldp); 111 der_free_bit_string(&(*tbs)->subjectUniqueID); 112 der_free_bit_string(&(*tbs)->issuerUniqueID); 113 hx509_name_free(&(*tbs)->subject); 114 if ((*tbs)->sigalg) { 115 free_AlgorithmIdentifier((*tbs)->sigalg); 116 free((*tbs)->sigalg); 117 } 118 119 memset(*tbs, 0, sizeof(**tbs)); 120 free(*tbs); 121 *tbs = NULL; 122 } 123 124 /** 125 * Set the absolute time when the certificate is valid from. If not 126 * set the current time will be used. 127 * 128 * @param context A hx509 context. 129 * @param tbs object to be signed. 130 * @param t time the certificated will start to be valid 131 * 132 * @return An hx509 error code, see hx509_get_error_string(). 133 * 134 * @ingroup hx509_ca 135 */ 136 137 int 138 hx509_ca_tbs_set_notBefore(hx509_context context, 139 hx509_ca_tbs tbs, 140 time_t t) 141 { 142 tbs->notBefore = t; 143 return 0; 144 } 145 146 /** 147 * Set the absolute time when the certificate is valid to. 148 * 149 * @param context A hx509 context. 150 * @param tbs object to be signed. 151 * @param t time when the certificate will expire 152 * 153 * @return An hx509 error code, see hx509_get_error_string(). 154 * 155 * @ingroup hx509_ca 156 */ 157 158 int 159 hx509_ca_tbs_set_notAfter(hx509_context context, 160 hx509_ca_tbs tbs, 161 time_t t) 162 { 163 tbs->notAfter = t; 164 return 0; 165 } 166 167 /** 168 * Set the relative time when the certificiate is going to expire. 169 * 170 * @param context A hx509 context. 171 * @param tbs object to be signed. 172 * @param delta seconds to the certificate is going to expire. 173 * 174 * @return An hx509 error code, see hx509_get_error_string(). 175 * 176 * @ingroup hx509_ca 177 */ 178 179 int 180 hx509_ca_tbs_set_notAfter_lifetime(hx509_context context, 181 hx509_ca_tbs tbs, 182 time_t delta) 183 { 184 return hx509_ca_tbs_set_notAfter(context, tbs, time(NULL) + delta); 185 } 186 187 static const struct units templatebits[] = { 188 { "ExtendedKeyUsage", HX509_CA_TEMPLATE_EKU }, 189 { "KeyUsage", HX509_CA_TEMPLATE_KU }, 190 { "SPKI", HX509_CA_TEMPLATE_SPKI }, 191 { "notAfter", HX509_CA_TEMPLATE_NOTAFTER }, 192 { "notBefore", HX509_CA_TEMPLATE_NOTBEFORE }, 193 { "serial", HX509_CA_TEMPLATE_SERIAL }, 194 { "subject", HX509_CA_TEMPLATE_SUBJECT }, 195 { NULL, 0 } 196 }; 197 198 /** 199 * Make of template units, use to build flags argument to 200 * hx509_ca_tbs_set_template() with parse_units(). 201 * 202 * @return an units structure. 203 * 204 * @ingroup hx509_ca 205 */ 206 207 const struct units * 208 hx509_ca_tbs_template_units(void) 209 { 210 return templatebits; 211 } 212 213 /** 214 * Initialize the to-be-signed certificate object from a template certifiate. 215 * 216 * @param context A hx509 context. 217 * @param tbs object to be signed. 218 * @param flags bit field selecting what to copy from the template 219 * certifiate. 220 * @param cert template certificate. 221 * 222 * @return An hx509 error code, see hx509_get_error_string(). 223 * 224 * @ingroup hx509_ca 225 */ 226 227 int 228 hx509_ca_tbs_set_template(hx509_context context, 229 hx509_ca_tbs tbs, 230 int flags, 231 hx509_cert cert) 232 { 233 int ret; 234 235 if (flags & HX509_CA_TEMPLATE_SUBJECT) { 236 if (tbs->subject) 237 hx509_name_free(&tbs->subject); 238 ret = hx509_cert_get_subject(cert, &tbs->subject); 239 if (ret) { 240 hx509_set_error_string(context, 0, ret, 241 "Failed to get subject from template"); 242 return ret; 243 } 244 } 245 if (flags & HX509_CA_TEMPLATE_SERIAL) { 246 der_free_heim_integer(&tbs->serial); 247 ret = hx509_cert_get_serialnumber(cert, &tbs->serial); 248 tbs->flags.serial = !ret; 249 if (ret) { 250 hx509_set_error_string(context, 0, ret, 251 "Failed to copy serial number"); 252 return ret; 253 } 254 } 255 if (flags & HX509_CA_TEMPLATE_NOTBEFORE) 256 tbs->notBefore = hx509_cert_get_notBefore(cert); 257 if (flags & HX509_CA_TEMPLATE_NOTAFTER) 258 tbs->notAfter = hx509_cert_get_notAfter(cert); 259 if (flags & HX509_CA_TEMPLATE_SPKI) { 260 free_SubjectPublicKeyInfo(&tbs->spki); 261 ret = hx509_cert_get_SPKI(context, cert, &tbs->spki); 262 tbs->flags.key = !ret; 263 if (ret) 264 return ret; 265 } 266 if (flags & HX509_CA_TEMPLATE_KU) { 267 KeyUsage ku; 268 ret = _hx509_cert_get_keyusage(context, cert, &ku); 269 if (ret) 270 return ret; 271 tbs->key_usage = KeyUsage2int(ku); 272 } 273 if (flags & HX509_CA_TEMPLATE_EKU) { 274 ExtKeyUsage eku; 275 size_t i; 276 ret = _hx509_cert_get_eku(context, cert, &eku); 277 if (ret) 278 return ret; 279 for (i = 0; i < eku.len; i++) { 280 ret = hx509_ca_tbs_add_eku(context, tbs, &eku.val[i]); 281 if (ret) { 282 free_ExtKeyUsage(&eku); 283 return ret; 284 } 285 } 286 free_ExtKeyUsage(&eku); 287 } 288 return 0; 289 } 290 291 /** 292 * Make the to-be-signed certificate object a CA certificate. If the 293 * pathLenConstraint is negative path length constraint is used. 294 * 295 * @param context A hx509 context. 296 * @param tbs object to be signed. 297 * @param pathLenConstraint path length constraint, negative, no 298 * constraint. 299 * 300 * @return An hx509 error code, see hx509_get_error_string(). 301 * 302 * @ingroup hx509_ca 303 */ 304 305 int 306 hx509_ca_tbs_set_ca(hx509_context context, 307 hx509_ca_tbs tbs, 308 int pathLenConstraint) 309 { 310 tbs->flags.ca = 1; 311 tbs->pathLenConstraint = pathLenConstraint; 312 return 0; 313 } 314 315 /** 316 * Make the to-be-signed certificate object a proxy certificate. If the 317 * pathLenConstraint is negative path length constraint is used. 318 * 319 * @param context A hx509 context. 320 * @param tbs object to be signed. 321 * @param pathLenConstraint path length constraint, negative, no 322 * constraint. 323 * 324 * @return An hx509 error code, see hx509_get_error_string(). 325 * 326 * @ingroup hx509_ca 327 */ 328 329 int 330 hx509_ca_tbs_set_proxy(hx509_context context, 331 hx509_ca_tbs tbs, 332 int pathLenConstraint) 333 { 334 tbs->flags.proxy = 1; 335 tbs->pathLenConstraint = pathLenConstraint; 336 return 0; 337 } 338 339 340 /** 341 * Make the to-be-signed certificate object a windows domain controller certificate. 342 * 343 * @param context A hx509 context. 344 * @param tbs object to be signed. 345 * 346 * @return An hx509 error code, see hx509_get_error_string(). 347 * 348 * @ingroup hx509_ca 349 */ 350 351 int 352 hx509_ca_tbs_set_domaincontroller(hx509_context context, 353 hx509_ca_tbs tbs) 354 { 355 tbs->flags.domaincontroller = 1; 356 return 0; 357 } 358 359 /** 360 * Set the subject public key info (SPKI) in the to-be-signed certificate 361 * object. SPKI is the public key and key related parameters in the 362 * certificate. 363 * 364 * @param context A hx509 context. 365 * @param tbs object to be signed. 366 * @param spki subject public key info to use for the to-be-signed certificate object. 367 * 368 * @return An hx509 error code, see hx509_get_error_string(). 369 * 370 * @ingroup hx509_ca 371 */ 372 373 int 374 hx509_ca_tbs_set_spki(hx509_context context, 375 hx509_ca_tbs tbs, 376 const SubjectPublicKeyInfo *spki) 377 { 378 int ret; 379 free_SubjectPublicKeyInfo(&tbs->spki); 380 ret = copy_SubjectPublicKeyInfo(spki, &tbs->spki); 381 tbs->flags.key = !ret; 382 return ret; 383 } 384 385 /** 386 * Set the serial number to use for to-be-signed certificate object. 387 * 388 * @param context A hx509 context. 389 * @param tbs object to be signed. 390 * @param serialNumber serial number to use for the to-be-signed 391 * certificate object. 392 * 393 * @return An hx509 error code, see hx509_get_error_string(). 394 * 395 * @ingroup hx509_ca 396 */ 397 398 int 399 hx509_ca_tbs_set_serialnumber(hx509_context context, 400 hx509_ca_tbs tbs, 401 const heim_integer *serialNumber) 402 { 403 int ret; 404 der_free_heim_integer(&tbs->serial); 405 ret = der_copy_heim_integer(serialNumber, &tbs->serial); 406 tbs->flags.serial = !ret; 407 return ret; 408 } 409 410 /** 411 * An an extended key usage to the to-be-signed certificate object. 412 * Duplicates will detected and not added. 413 * 414 * @param context A hx509 context. 415 * @param tbs object to be signed. 416 * @param oid extended key usage to add. 417 * 418 * @return An hx509 error code, see hx509_get_error_string(). 419 * 420 * @ingroup hx509_ca 421 */ 422 423 int 424 hx509_ca_tbs_add_eku(hx509_context context, 425 hx509_ca_tbs tbs, 426 const heim_oid *oid) 427 { 428 void *ptr; 429 int ret; 430 unsigned i; 431 432 /* search for duplicates */ 433 for (i = 0; i < tbs->eku.len; i++) { 434 if (der_heim_oid_cmp(oid, &tbs->eku.val[i]) == 0) 435 return 0; 436 } 437 438 ptr = realloc(tbs->eku.val, sizeof(tbs->eku.val[0]) * (tbs->eku.len + 1)); 439 if (ptr == NULL) { 440 hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 441 return ENOMEM; 442 } 443 tbs->eku.val = ptr; 444 ret = der_copy_oid(oid, &tbs->eku.val[tbs->eku.len]); 445 if (ret) { 446 hx509_set_error_string(context, 0, ret, "out of memory"); 447 return ret; 448 } 449 tbs->eku.len += 1; 450 return 0; 451 } 452 453 /** 454 * Add CRL distribution point URI to the to-be-signed certificate 455 * object. 456 * 457 * @param context A hx509 context. 458 * @param tbs object to be signed. 459 * @param uri uri to the CRL. 460 * @param issuername name of the issuer. 461 * 462 * @return An hx509 error code, see hx509_get_error_string(). 463 * 464 * @ingroup hx509_ca 465 */ 466 467 int 468 hx509_ca_tbs_add_crl_dp_uri(hx509_context context, 469 hx509_ca_tbs tbs, 470 const char *uri, 471 hx509_name issuername) 472 { 473 DistributionPoint dp; 474 int ret; 475 476 memset(&dp, 0, sizeof(dp)); 477 478 dp.distributionPoint = ecalloc(1, sizeof(*dp.distributionPoint)); 479 480 { 481 DistributionPointName name; 482 GeneralName gn; 483 size_t size; 484 485 name.element = choice_DistributionPointName_fullName; 486 name.u.fullName.len = 1; 487 name.u.fullName.val = &gn; 488 489 gn.element = choice_GeneralName_uniformResourceIdentifier; 490 gn.u.uniformResourceIdentifier.data = rk_UNCONST(uri); 491 gn.u.uniformResourceIdentifier.length = strlen(uri); 492 493 ASN1_MALLOC_ENCODE(DistributionPointName, 494 dp.distributionPoint->data, 495 dp.distributionPoint->length, 496 &name, &size, ret); 497 if (ret) { 498 hx509_set_error_string(context, 0, ret, 499 "Failed to encoded DistributionPointName"); 500 goto out; 501 } 502 if (dp.distributionPoint->length != size) 503 _hx509_abort("internal ASN.1 encoder error"); 504 } 505 506 if (issuername) { 507 #if 1 508 /** 509 * issuername not supported 510 */ 511 hx509_set_error_string(context, 0, EINVAL, 512 "CRLDistributionPoints.name.issuername not yet supported"); 513 return EINVAL; 514 #else 515 GeneralNames *crlissuer; 516 GeneralName gn; 517 Name n; 518 519 crlissuer = calloc(1, sizeof(*crlissuer)); 520 if (crlissuer == NULL) { 521 return ENOMEM; 522 } 523 memset(&gn, 0, sizeof(gn)); 524 525 gn.element = choice_GeneralName_directoryName; 526 ret = hx509_name_to_Name(issuername, &n); 527 if (ret) { 528 hx509_set_error_string(context, 0, ret, "out of memory"); 529 goto out; 530 } 531 532 gn.u.directoryName.element = n.element; 533 gn.u.directoryName.u.rdnSequence = n.u.rdnSequence; 534 535 ret = add_GeneralNames(&crlissuer, &gn); 536 free_Name(&n); 537 if (ret) { 538 hx509_set_error_string(context, 0, ret, "out of memory"); 539 goto out; 540 } 541 542 dp.cRLIssuer = &crlissuer; 543 #endif 544 } 545 546 ret = add_CRLDistributionPoints(&tbs->crldp, &dp); 547 if (ret) { 548 hx509_set_error_string(context, 0, ret, "out of memory"); 549 goto out; 550 } 551 552 out: 553 free_DistributionPoint(&dp); 554 555 return ret; 556 } 557 558 /** 559 * Add Subject Alternative Name otherName to the to-be-signed 560 * certificate object. 561 * 562 * @param context A hx509 context. 563 * @param tbs object to be signed. 564 * @param oid the oid of the OtherName. 565 * @param os data in the other name. 566 * 567 * @return An hx509 error code, see hx509_get_error_string(). 568 * 569 * @ingroup hx509_ca 570 */ 571 572 int 573 hx509_ca_tbs_add_san_otherName(hx509_context context, 574 hx509_ca_tbs tbs, 575 const heim_oid *oid, 576 const heim_octet_string *os) 577 { 578 GeneralName gn; 579 580 memset(&gn, 0, sizeof(gn)); 581 gn.element = choice_GeneralName_otherName; 582 gn.u.otherName.type_id = *oid; 583 gn.u.otherName.value = *os; 584 585 return add_GeneralNames(&tbs->san, &gn); 586 } 587 588 /** 589 * Add Kerberos Subject Alternative Name to the to-be-signed 590 * certificate object. The principal string is a UTF8 string. 591 * 592 * @param context A hx509 context. 593 * @param tbs object to be signed. 594 * @param principal Kerberos principal to add to the certificate. 595 * 596 * @return An hx509 error code, see hx509_get_error_string(). 597 * 598 * @ingroup hx509_ca 599 */ 600 601 int 602 hx509_ca_tbs_add_san_pkinit(hx509_context context, 603 hx509_ca_tbs tbs, 604 const char *principal) 605 { 606 heim_octet_string os; 607 KRB5PrincipalName p; 608 size_t size; 609 int ret; 610 char *s = NULL; 611 612 memset(&p, 0, sizeof(p)); 613 614 /* parse principal */ 615 { 616 const char *str; 617 char *q; 618 int n; 619 620 /* count number of component */ 621 n = 1; 622 for(str = principal; *str != '\0' && *str != '@'; str++){ 623 if(*str=='\\'){ 624 if(str[1] == '\0' || str[1] == '@') { 625 ret = HX509_PARSING_NAME_FAILED; 626 hx509_set_error_string(context, 0, ret, 627 "trailing \\ in principal name"); 628 goto out; 629 } 630 str++; 631 } else if(*str == '/') 632 n++; 633 } 634 p.principalName.name_string.val = 635 calloc(n, sizeof(*p.principalName.name_string.val)); 636 if (p.principalName.name_string.val == NULL) { 637 ret = ENOMEM; 638 hx509_set_error_string(context, 0, ret, "malloc: out of memory"); 639 goto out; 640 } 641 p.principalName.name_string.len = n; 642 643 p.principalName.name_type = KRB5_NT_PRINCIPAL; 644 q = s = strdup(principal); 645 if (q == NULL) { 646 ret = ENOMEM; 647 hx509_set_error_string(context, 0, ret, "malloc: out of memory"); 648 goto out; 649 } 650 p.realm = strrchr(q, '@'); 651 if (p.realm == NULL) { 652 ret = HX509_PARSING_NAME_FAILED; 653 hx509_set_error_string(context, 0, ret, "Missing @ in principal"); 654 goto out; 655 }; 656 *p.realm++ = '\0'; 657 658 n = 0; 659 while (q) { 660 p.principalName.name_string.val[n++] = q; 661 q = strchr(q, '/'); 662 if (q) 663 *q++ = '\0'; 664 } 665 } 666 667 ASN1_MALLOC_ENCODE(KRB5PrincipalName, os.data, os.length, &p, &size, ret); 668 if (ret) { 669 hx509_set_error_string(context, 0, ret, "Out of memory"); 670 goto out; 671 } 672 if (size != os.length) 673 _hx509_abort("internal ASN.1 encoder error"); 674 675 ret = hx509_ca_tbs_add_san_otherName(context, 676 tbs, 677 &asn1_oid_id_pkinit_san, 678 &os); 679 free(os.data); 680 out: 681 if (p.principalName.name_string.val) 682 free (p.principalName.name_string.val); 683 if (s) 684 free(s); 685 return ret; 686 } 687 688 /* 689 * 690 */ 691 692 static int 693 add_utf8_san(hx509_context context, 694 hx509_ca_tbs tbs, 695 const heim_oid *oid, 696 const char *string) 697 { 698 const PKIXXmppAddr ustring = (const PKIXXmppAddr)(intptr_t)string; 699 heim_octet_string os; 700 size_t size; 701 int ret; 702 703 os.length = 0; 704 os.data = NULL; 705 706 ASN1_MALLOC_ENCODE(PKIXXmppAddr, os.data, os.length, &ustring, &size, ret); 707 if (ret) { 708 hx509_set_error_string(context, 0, ret, "Out of memory"); 709 goto out; 710 } 711 if (size != os.length) 712 _hx509_abort("internal ASN.1 encoder error"); 713 714 ret = hx509_ca_tbs_add_san_otherName(context, 715 tbs, 716 oid, 717 &os); 718 free(os.data); 719 out: 720 return ret; 721 } 722 723 /** 724 * Add Microsoft UPN Subject Alternative Name to the to-be-signed 725 * certificate object. The principal string is a UTF8 string. 726 * 727 * @param context A hx509 context. 728 * @param tbs object to be signed. 729 * @param principal Microsoft UPN string. 730 * 731 * @return An hx509 error code, see hx509_get_error_string(). 732 * 733 * @ingroup hx509_ca 734 */ 735 736 int 737 hx509_ca_tbs_add_san_ms_upn(hx509_context context, 738 hx509_ca_tbs tbs, 739 const char *principal) 740 { 741 return add_utf8_san(context, tbs, &asn1_oid_id_pkinit_ms_san, principal); 742 } 743 744 /** 745 * Add a Jabber/XMPP jid Subject Alternative Name to the to-be-signed 746 * certificate object. The jid is an UTF8 string. 747 * 748 * @param context A hx509 context. 749 * @param tbs object to be signed. 750 * @param jid string of an a jabber id in UTF8. 751 * 752 * @return An hx509 error code, see hx509_get_error_string(). 753 * 754 * @ingroup hx509_ca 755 */ 756 757 int 758 hx509_ca_tbs_add_san_jid(hx509_context context, 759 hx509_ca_tbs tbs, 760 const char *jid) 761 { 762 return add_utf8_san(context, tbs, &asn1_oid_id_pkix_on_xmppAddr, jid); 763 } 764 765 766 /** 767 * Add a Subject Alternative Name hostname to to-be-signed certificate 768 * object. A domain match starts with ., an exact match does not. 769 * 770 * Example of a an domain match: .domain.se matches the hostname 771 * host.domain.se. 772 * 773 * @param context A hx509 context. 774 * @param tbs object to be signed. 775 * @param dnsname a hostame. 776 * 777 * @return An hx509 error code, see hx509_get_error_string(). 778 * 779 * @ingroup hx509_ca 780 */ 781 782 int 783 hx509_ca_tbs_add_san_hostname(hx509_context context, 784 hx509_ca_tbs tbs, 785 const char *dnsname) 786 { 787 GeneralName gn; 788 789 memset(&gn, 0, sizeof(gn)); 790 gn.element = choice_GeneralName_dNSName; 791 gn.u.dNSName.data = rk_UNCONST(dnsname); 792 gn.u.dNSName.length = strlen(dnsname); 793 794 return add_GeneralNames(&tbs->san, &gn); 795 } 796 797 /** 798 * Add a Subject Alternative Name rfc822 (email address) to 799 * to-be-signed certificate object. 800 * 801 * @param context A hx509 context. 802 * @param tbs object to be signed. 803 * @param rfc822Name a string to a email address. 804 * 805 * @return An hx509 error code, see hx509_get_error_string(). 806 * 807 * @ingroup hx509_ca 808 */ 809 810 int 811 hx509_ca_tbs_add_san_rfc822name(hx509_context context, 812 hx509_ca_tbs tbs, 813 const char *rfc822Name) 814 { 815 GeneralName gn; 816 817 memset(&gn, 0, sizeof(gn)); 818 gn.element = choice_GeneralName_rfc822Name; 819 gn.u.rfc822Name.data = rk_UNCONST(rfc822Name); 820 gn.u.rfc822Name.length = strlen(rfc822Name); 821 822 return add_GeneralNames(&tbs->san, &gn); 823 } 824 825 /** 826 * Set the subject name of a to-be-signed certificate object. 827 * 828 * @param context A hx509 context. 829 * @param tbs object to be signed. 830 * @param subject the name to set a subject. 831 * 832 * @return An hx509 error code, see hx509_get_error_string(). 833 * 834 * @ingroup hx509_ca 835 */ 836 837 int 838 hx509_ca_tbs_set_subject(hx509_context context, 839 hx509_ca_tbs tbs, 840 hx509_name subject) 841 { 842 if (tbs->subject) 843 hx509_name_free(&tbs->subject); 844 return hx509_name_copy(context, subject, &tbs->subject); 845 } 846 847 /** 848 * Set the issuerUniqueID and subjectUniqueID 849 * 850 * These are only supposed to be used considered with version 2 851 * certificates, replaced by the two extensions SubjectKeyIdentifier 852 * and IssuerKeyIdentifier. This function is to allow application 853 * using legacy protocol to issue them. 854 * 855 * @param context A hx509 context. 856 * @param tbs object to be signed. 857 * @param issuerUniqueID to be set 858 * @param subjectUniqueID to be set 859 * 860 * @return An hx509 error code, see hx509_get_error_string(). 861 * 862 * @ingroup hx509_ca 863 */ 864 865 int 866 hx509_ca_tbs_set_unique(hx509_context context, 867 hx509_ca_tbs tbs, 868 const heim_bit_string *subjectUniqueID, 869 const heim_bit_string *issuerUniqueID) 870 { 871 int ret; 872 873 der_free_bit_string(&tbs->subjectUniqueID); 874 der_free_bit_string(&tbs->issuerUniqueID); 875 876 if (subjectUniqueID) { 877 ret = der_copy_bit_string(subjectUniqueID, &tbs->subjectUniqueID); 878 if (ret) 879 return ret; 880 } 881 882 if (issuerUniqueID) { 883 ret = der_copy_bit_string(issuerUniqueID, &tbs->issuerUniqueID); 884 if (ret) 885 return ret; 886 } 887 888 return 0; 889 } 890 891 /** 892 * Expand the the subject name in the to-be-signed certificate object 893 * using hx509_name_expand(). 894 * 895 * @param context A hx509 context. 896 * @param tbs object to be signed. 897 * @param env environment variable to expand variables in the subject 898 * name, see hx509_env_init(). 899 * 900 * @return An hx509 error code, see hx509_get_error_string(). 901 * 902 * @ingroup hx509_ca 903 */ 904 905 int 906 hx509_ca_tbs_subject_expand(hx509_context context, 907 hx509_ca_tbs tbs, 908 hx509_env env) 909 { 910 return hx509_name_expand(context, tbs->subject, env); 911 } 912 913 /** 914 * Set signature algorithm on the to be signed certificate 915 * 916 * @param context A hx509 context. 917 * @param tbs object to be signed. 918 * @param sigalg signature algorithm to use 919 * 920 * @return An hx509 error code, see hx509_get_error_string(). 921 * 922 * @ingroup hx509_ca 923 */ 924 925 int 926 hx509_ca_tbs_set_signature_algorithm(hx509_context context, 927 hx509_ca_tbs tbs, 928 const AlgorithmIdentifier *sigalg) 929 { 930 int ret; 931 932 tbs->sigalg = calloc(1, sizeof(*tbs->sigalg)); 933 if (tbs->sigalg == NULL) { 934 hx509_set_error_string(context, 0, ENOMEM, "Out of memory"); 935 return ENOMEM; 936 } 937 ret = copy_AlgorithmIdentifier(sigalg, tbs->sigalg); 938 if (ret) { 939 free(tbs->sigalg); 940 tbs->sigalg = NULL; 941 return ret; 942 } 943 return 0; 944 } 945 946 /* 947 * 948 */ 949 950 static int 951 add_extension(hx509_context context, 952 TBSCertificate *tbsc, 953 int critical_flag, 954 const heim_oid *oid, 955 const heim_octet_string *data) 956 { 957 Extension ext; 958 int ret; 959 960 memset(&ext, 0, sizeof(ext)); 961 962 if (critical_flag) { 963 ext.critical = malloc(sizeof(*ext.critical)); 964 if (ext.critical == NULL) { 965 ret = ENOMEM; 966 hx509_set_error_string(context, 0, ret, "Out of memory"); 967 goto out; 968 } 969 *ext.critical = TRUE; 970 } 971 972 ret = der_copy_oid(oid, &ext.extnID); 973 if (ret) { 974 hx509_set_error_string(context, 0, ret, "Out of memory"); 975 goto out; 976 } 977 ret = der_copy_octet_string(data, &ext.extnValue); 978 if (ret) { 979 hx509_set_error_string(context, 0, ret, "Out of memory"); 980 goto out; 981 } 982 ret = add_Extensions(tbsc->extensions, &ext); 983 if (ret) { 984 hx509_set_error_string(context, 0, ret, "Out of memory"); 985 goto out; 986 } 987 out: 988 free_Extension(&ext); 989 return ret; 990 } 991 992 static int 993 build_proxy_prefix(hx509_context context, const Name *issuer, Name *subject) 994 { 995 char *tstr; 996 time_t t; 997 int ret; 998 999 ret = copy_Name(issuer, subject); 1000 if (ret) { 1001 hx509_set_error_string(context, 0, ret, 1002 "Failed to copy subject name"); 1003 return ret; 1004 } 1005 1006 t = time(NULL); 1007 ret = asprintf(&tstr, "ts-%lu", (unsigned long)t); 1008 if (ret == -1 || tstr == NULL) { 1009 hx509_set_error_string(context, 0, ENOMEM, 1010 "Failed to copy subject name"); 1011 return ENOMEM; 1012 } 1013 /* prefix with CN=<ts>,...*/ 1014 ret = _hx509_name_modify(context, subject, 1, &asn1_oid_id_at_commonName, tstr); 1015 free(tstr); 1016 if (ret) 1017 free_Name(subject); 1018 return ret; 1019 } 1020 1021 static int 1022 ca_sign(hx509_context context, 1023 hx509_ca_tbs tbs, 1024 hx509_private_key signer, 1025 const AuthorityKeyIdentifier *ai, 1026 const Name *issuername, 1027 hx509_cert *certificate) 1028 { 1029 heim_error_t error = NULL; 1030 heim_octet_string data; 1031 Certificate c; 1032 TBSCertificate *tbsc; 1033 size_t size; 1034 int ret; 1035 const AlgorithmIdentifier *sigalg; 1036 time_t notBefore; 1037 time_t notAfter; 1038 unsigned key_usage; 1039 1040 sigalg = tbs->sigalg; 1041 if (sigalg == NULL) 1042 sigalg = _hx509_crypto_default_sig_alg; 1043 1044 memset(&c, 0, sizeof(c)); 1045 1046 /* 1047 * Default values are: Valid since 24h ago, valid one year into 1048 * the future, KeyUsage digitalSignature and keyEncipherment set, 1049 * and keyCertSign for CA certificates. 1050 */ 1051 notBefore = tbs->notBefore; 1052 if (notBefore == 0) 1053 notBefore = time(NULL) - 3600 * 24; 1054 notAfter = tbs->notAfter; 1055 if (notAfter == 0) 1056 notAfter = time(NULL) + 3600 * 24 * 365; 1057 1058 key_usage = tbs->key_usage; 1059 if (key_usage == 0) { 1060 KeyUsage ku; 1061 memset(&ku, 0, sizeof(ku)); 1062 ku.digitalSignature = 1; 1063 ku.keyEncipherment = 1; 1064 key_usage = KeyUsage2int(ku); 1065 } 1066 1067 if (tbs->flags.ca) { 1068 KeyUsage ku; 1069 memset(&ku, 0, sizeof(ku)); 1070 ku.keyCertSign = 1; 1071 ku.cRLSign = 1; 1072 key_usage |= KeyUsage2int(ku); 1073 } 1074 1075 /* 1076 * 1077 */ 1078 1079 tbsc = &c.tbsCertificate; 1080 1081 if (tbs->flags.key == 0) { 1082 ret = EINVAL; 1083 hx509_set_error_string(context, 0, ret, "No public key set"); 1084 return ret; 1085 } 1086 /* 1087 * Don't put restrictions on proxy certificate's subject name, it 1088 * will be generated below. 1089 */ 1090 if (!tbs->flags.proxy) { 1091 if (tbs->subject == NULL) { 1092 hx509_set_error_string(context, 0, EINVAL, "No subject name set"); 1093 return EINVAL; 1094 } 1095 if (hx509_name_is_null_p(tbs->subject) && tbs->san.len == 0) { 1096 hx509_set_error_string(context, 0, EINVAL, 1097 "NULL subject and no SubjectAltNames"); 1098 return EINVAL; 1099 } 1100 } 1101 if (tbs->flags.ca && tbs->flags.proxy) { 1102 hx509_set_error_string(context, 0, EINVAL, "Can't be proxy and CA " 1103 "at the same time"); 1104 return EINVAL; 1105 } 1106 if (tbs->flags.proxy) { 1107 if (tbs->san.len > 0) { 1108 hx509_set_error_string(context, 0, EINVAL, 1109 "Proxy certificate is not allowed " 1110 "to have SubjectAltNames"); 1111 return EINVAL; 1112 } 1113 } 1114 1115 /* version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1, */ 1116 tbsc->version = calloc(1, sizeof(*tbsc->version)); 1117 if (tbsc->version == NULL) { 1118 ret = ENOMEM; 1119 hx509_set_error_string(context, 0, ret, "Out of memory"); 1120 goto out; 1121 } 1122 *tbsc->version = rfc3280_version_3; 1123 /* serialNumber CertificateSerialNumber, */ 1124 if (tbs->flags.serial) { 1125 ret = der_copy_heim_integer(&tbs->serial, &tbsc->serialNumber); 1126 if (ret) { 1127 hx509_set_error_string(context, 0, ret, "Out of memory"); 1128 goto out; 1129 } 1130 } else { 1131 /* 1132 * If no explicit serial number is specified, 20 random bytes should be 1133 * sufficiently collision resistant. Since the serial number must be a 1134 * positive integer, ensure minimal ASN.1 DER form by forcing the high 1135 * bit off and the next bit on (thus avoiding an all zero first octet). 1136 */ 1137 tbsc->serialNumber.length = 20; 1138 tbsc->serialNumber.data = malloc(tbsc->serialNumber.length); 1139 if (tbsc->serialNumber.data == NULL){ 1140 ret = ENOMEM; 1141 hx509_set_error_string(context, 0, ret, "Out of memory"); 1142 goto out; 1143 } 1144 RAND_bytes(tbsc->serialNumber.data, tbsc->serialNumber.length); 1145 ((unsigned char *)tbsc->serialNumber.data)[0] &= 0x7f; 1146 ((unsigned char *)tbsc->serialNumber.data)[0] |= 0x40; 1147 } 1148 /* signature AlgorithmIdentifier, */ 1149 ret = copy_AlgorithmIdentifier(sigalg, &tbsc->signature); 1150 if (ret) { 1151 hx509_set_error_string(context, 0, ret, "Failed to copy sigature alg"); 1152 goto out; 1153 } 1154 /* issuer Name, */ 1155 if (issuername) 1156 ret = copy_Name(issuername, &tbsc->issuer); 1157 else 1158 ret = hx509_name_to_Name(tbs->subject, &tbsc->issuer); 1159 if (ret) { 1160 hx509_set_error_string(context, 0, ret, "Failed to copy issuer name"); 1161 goto out; 1162 } 1163 /* validity Validity, */ 1164 tbsc->validity.notBefore.element = choice_Time_generalTime; 1165 tbsc->validity.notBefore.u.generalTime = notBefore; 1166 tbsc->validity.notAfter.element = choice_Time_generalTime; 1167 tbsc->validity.notAfter.u.generalTime = notAfter; 1168 /* subject Name, */ 1169 if (tbs->flags.proxy) { 1170 ret = build_proxy_prefix(context, &tbsc->issuer, &tbsc->subject); 1171 if (ret) 1172 goto out; 1173 } else { 1174 ret = hx509_name_to_Name(tbs->subject, &tbsc->subject); 1175 if (ret) { 1176 hx509_set_error_string(context, 0, ret, 1177 "Failed to copy subject name"); 1178 goto out; 1179 } 1180 } 1181 /* subjectPublicKeyInfo SubjectPublicKeyInfo, */ 1182 ret = copy_SubjectPublicKeyInfo(&tbs->spki, &tbsc->subjectPublicKeyInfo); 1183 if (ret) { 1184 hx509_set_error_string(context, 0, ret, "Failed to copy spki"); 1185 goto out; 1186 } 1187 /* issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL */ 1188 if (tbs->issuerUniqueID.length) { 1189 tbsc->issuerUniqueID = calloc(1, sizeof(*tbsc->issuerUniqueID)); 1190 if (tbsc->issuerUniqueID == NULL) { 1191 ret = ENOMEM; 1192 hx509_set_error_string(context, 0, ret, "Out of memory"); 1193 goto out; 1194 } 1195 ret = der_copy_bit_string(&tbs->issuerUniqueID, tbsc->issuerUniqueID); 1196 if (ret) { 1197 hx509_set_error_string(context, 0, ret, "Out of memory"); 1198 goto out; 1199 } 1200 } 1201 /* subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL */ 1202 if (tbs->subjectUniqueID.length) { 1203 tbsc->subjectUniqueID = calloc(1, sizeof(*tbsc->subjectUniqueID)); 1204 if (tbsc->subjectUniqueID == NULL) { 1205 ret = ENOMEM; 1206 hx509_set_error_string(context, 0, ret, "Out of memory"); 1207 goto out; 1208 } 1209 1210 ret = der_copy_bit_string(&tbs->subjectUniqueID, tbsc->subjectUniqueID); 1211 if (ret) { 1212 hx509_set_error_string(context, 0, ret, "Out of memory"); 1213 goto out; 1214 } 1215 } 1216 1217 /* extensions [3] EXPLICIT Extensions OPTIONAL */ 1218 tbsc->extensions = calloc(1, sizeof(*tbsc->extensions)); 1219 if (tbsc->extensions == NULL) { 1220 ret = ENOMEM; 1221 hx509_set_error_string(context, 0, ret, "Out of memory"); 1222 goto out; 1223 } 1224 1225 /* Add the text BMP string Domaincontroller to the cert */ 1226 if (tbs->flags.domaincontroller) { 1227 data.data = rk_UNCONST("\x1e\x20\x00\x44\x00\x6f\x00\x6d" 1228 "\x00\x61\x00\x69\x00\x6e\x00\x43" 1229 "\x00\x6f\x00\x6e\x00\x74\x00\x72" 1230 "\x00\x6f\x00\x6c\x00\x6c\x00\x65" 1231 "\x00\x72"); 1232 data.length = 34; 1233 1234 ret = add_extension(context, tbsc, 0, 1235 &asn1_oid_id_ms_cert_enroll_domaincontroller, 1236 &data); 1237 if (ret) 1238 goto out; 1239 } 1240 1241 /* add KeyUsage */ 1242 { 1243 KeyUsage ku; 1244 1245 ku = int2KeyUsage(key_usage); 1246 ASN1_MALLOC_ENCODE(KeyUsage, data.data, data.length, &ku, &size, ret); 1247 if (ret) { 1248 hx509_set_error_string(context, 0, ret, "Out of memory"); 1249 goto out; 1250 } 1251 if (size != data.length) 1252 _hx509_abort("internal ASN.1 encoder error"); 1253 ret = add_extension(context, tbsc, 1, 1254 &asn1_oid_id_x509_ce_keyUsage, &data); 1255 free(data.data); 1256 if (ret) 1257 goto out; 1258 } 1259 1260 /* add ExtendedKeyUsage */ 1261 if (tbs->eku.len > 0) { 1262 ASN1_MALLOC_ENCODE(ExtKeyUsage, data.data, data.length, 1263 &tbs->eku, &size, ret); 1264 if (ret) { 1265 hx509_set_error_string(context, 0, ret, "Out of memory"); 1266 goto out; 1267 } 1268 if (size != data.length) 1269 _hx509_abort("internal ASN.1 encoder error"); 1270 ret = add_extension(context, tbsc, 0, 1271 &asn1_oid_id_x509_ce_extKeyUsage, &data); 1272 free(data.data); 1273 if (ret) 1274 goto out; 1275 } 1276 1277 /* add Subject Alternative Name */ 1278 if (tbs->san.len > 0) { 1279 ASN1_MALLOC_ENCODE(GeneralNames, data.data, data.length, 1280 &tbs->san, &size, ret); 1281 if (ret) { 1282 hx509_set_error_string(context, 0, ret, "Out of memory"); 1283 goto out; 1284 } 1285 if (size != data.length) 1286 _hx509_abort("internal ASN.1 encoder error"); 1287 ret = add_extension(context, tbsc, 0, 1288 &asn1_oid_id_x509_ce_subjectAltName, 1289 &data); 1290 free(data.data); 1291 if (ret) 1292 goto out; 1293 } 1294 1295 /* Add Authority Key Identifier */ 1296 if (ai) { 1297 ASN1_MALLOC_ENCODE(AuthorityKeyIdentifier, data.data, data.length, 1298 ai, &size, ret); 1299 if (ret) { 1300 hx509_set_error_string(context, 0, ret, "Out of memory"); 1301 goto out; 1302 } 1303 if (size != data.length) 1304 _hx509_abort("internal ASN.1 encoder error"); 1305 ret = add_extension(context, tbsc, 0, 1306 &asn1_oid_id_x509_ce_authorityKeyIdentifier, 1307 &data); 1308 free(data.data); 1309 if (ret) 1310 goto out; 1311 } 1312 1313 /* Add Subject Key Identifier */ 1314 { 1315 SubjectKeyIdentifier si; 1316 unsigned char hash[SHA_DIGEST_LENGTH]; 1317 1318 { 1319 EVP_MD_CTX *ctx; 1320 1321 ctx = EVP_MD_CTX_create(); 1322 EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); 1323 EVP_DigestUpdate(ctx, tbs->spki.subjectPublicKey.data, 1324 tbs->spki.subjectPublicKey.length / 8); 1325 EVP_DigestFinal_ex(ctx, hash, NULL); 1326 EVP_MD_CTX_destroy(ctx); 1327 } 1328 1329 si.data = hash; 1330 si.length = sizeof(hash); 1331 1332 ASN1_MALLOC_ENCODE(SubjectKeyIdentifier, data.data, data.length, 1333 &si, &size, ret); 1334 if (ret) { 1335 hx509_set_error_string(context, 0, ret, "Out of memory"); 1336 goto out; 1337 } 1338 if (size != data.length) 1339 _hx509_abort("internal ASN.1 encoder error"); 1340 ret = add_extension(context, tbsc, 0, 1341 &asn1_oid_id_x509_ce_subjectKeyIdentifier, 1342 &data); 1343 free(data.data); 1344 if (ret) 1345 goto out; 1346 } 1347 1348 /* Add BasicConstraints */ 1349 { 1350 BasicConstraints bc; 1351 int aCA = 1; 1352 unsigned int path; 1353 1354 memset(&bc, 0, sizeof(bc)); 1355 1356 if (tbs->flags.ca) { 1357 bc.cA = &aCA; 1358 if (tbs->pathLenConstraint >= 0) { 1359 path = tbs->pathLenConstraint; 1360 bc.pathLenConstraint = &path; 1361 } 1362 } 1363 1364 ASN1_MALLOC_ENCODE(BasicConstraints, data.data, data.length, 1365 &bc, &size, ret); 1366 if (ret) { 1367 hx509_set_error_string(context, 0, ret, "Out of memory"); 1368 goto out; 1369 } 1370 if (size != data.length) 1371 _hx509_abort("internal ASN.1 encoder error"); 1372 /* Critical if this is a CA */ 1373 ret = add_extension(context, tbsc, tbs->flags.ca, 1374 &asn1_oid_id_x509_ce_basicConstraints, 1375 &data); 1376 free(data.data); 1377 if (ret) 1378 goto out; 1379 } 1380 1381 /* add Proxy */ 1382 if (tbs->flags.proxy) { 1383 ProxyCertInfo info; 1384 1385 memset(&info, 0, sizeof(info)); 1386 1387 if (tbs->pathLenConstraint >= 0) { 1388 info.pCPathLenConstraint = 1389 malloc(sizeof(*info.pCPathLenConstraint)); 1390 if (info.pCPathLenConstraint == NULL) { 1391 ret = ENOMEM; 1392 hx509_set_error_string(context, 0, ret, "Out of memory"); 1393 goto out; 1394 } 1395 *info.pCPathLenConstraint = tbs->pathLenConstraint; 1396 } 1397 1398 ret = der_copy_oid(&asn1_oid_id_pkix_ppl_inheritAll, 1399 &info.proxyPolicy.policyLanguage); 1400 if (ret) { 1401 free_ProxyCertInfo(&info); 1402 hx509_set_error_string(context, 0, ret, "Out of memory"); 1403 goto out; 1404 } 1405 1406 ASN1_MALLOC_ENCODE(ProxyCertInfo, data.data, data.length, 1407 &info, &size, ret); 1408 free_ProxyCertInfo(&info); 1409 if (ret) { 1410 hx509_set_error_string(context, 0, ret, "Out of memory"); 1411 goto out; 1412 } 1413 if (size != data.length) 1414 _hx509_abort("internal ASN.1 encoder error"); 1415 ret = add_extension(context, tbsc, 0, 1416 &asn1_oid_id_pkix_pe_proxyCertInfo, 1417 &data); 1418 free(data.data); 1419 if (ret) 1420 goto out; 1421 } 1422 1423 if (tbs->crldp.len) { 1424 1425 ASN1_MALLOC_ENCODE(CRLDistributionPoints, data.data, data.length, 1426 &tbs->crldp, &size, ret); 1427 if (ret) { 1428 hx509_set_error_string(context, 0, ret, "Out of memory"); 1429 goto out; 1430 } 1431 if (size != data.length) 1432 _hx509_abort("internal ASN.1 encoder error"); 1433 ret = add_extension(context, tbsc, FALSE, 1434 &asn1_oid_id_x509_ce_cRLDistributionPoints, 1435 &data); 1436 free(data.data); 1437 if (ret) 1438 goto out; 1439 } 1440 1441 ASN1_MALLOC_ENCODE(TBSCertificate, data.data, data.length,tbsc, &size, ret); 1442 if (ret) { 1443 hx509_set_error_string(context, 0, ret, "malloc out of memory"); 1444 goto out; 1445 } 1446 if (data.length != size) 1447 _hx509_abort("internal ASN.1 encoder error"); 1448 1449 ret = _hx509_create_signature_bitstring(context, 1450 signer, 1451 sigalg, 1452 &data, 1453 &c.signatureAlgorithm, 1454 &c.signatureValue); 1455 free(data.data); 1456 if (ret) 1457 goto out; 1458 1459 *certificate = hx509_cert_init(context, &c, &error); 1460 if (*certificate == NULL) { 1461 ret = heim_error_get_code(error); 1462 heim_release(error); 1463 goto out; 1464 } 1465 1466 free_Certificate(&c); 1467 1468 return 0; 1469 1470 out: 1471 free_Certificate(&c); 1472 return ret; 1473 } 1474 1475 static int 1476 get_AuthorityKeyIdentifier(hx509_context context, 1477 const Certificate *certificate, 1478 AuthorityKeyIdentifier *ai) 1479 { 1480 SubjectKeyIdentifier si; 1481 int ret; 1482 1483 ret = _hx509_find_extension_subject_key_id(certificate, &si); 1484 if (ret == 0) { 1485 ai->keyIdentifier = calloc(1, sizeof(*ai->keyIdentifier)); 1486 if (ai->keyIdentifier == NULL) { 1487 free_SubjectKeyIdentifier(&si); 1488 ret = ENOMEM; 1489 hx509_set_error_string(context, 0, ret, "Out of memory"); 1490 goto out; 1491 } 1492 ret = der_copy_octet_string(&si, ai->keyIdentifier); 1493 free_SubjectKeyIdentifier(&si); 1494 if (ret) { 1495 hx509_set_error_string(context, 0, ret, "Out of memory"); 1496 goto out; 1497 } 1498 } else { 1499 GeneralNames gns; 1500 GeneralName gn; 1501 Name name; 1502 1503 memset(&gn, 0, sizeof(gn)); 1504 memset(&gns, 0, sizeof(gns)); 1505 memset(&name, 0, sizeof(name)); 1506 1507 ai->authorityCertIssuer = 1508 calloc(1, sizeof(*ai->authorityCertIssuer)); 1509 if (ai->authorityCertIssuer == NULL) { 1510 ret = ENOMEM; 1511 hx509_set_error_string(context, 0, ret, "Out of memory"); 1512 goto out; 1513 } 1514 ai->authorityCertSerialNumber = 1515 calloc(1, sizeof(*ai->authorityCertSerialNumber)); 1516 if (ai->authorityCertSerialNumber == NULL) { 1517 ret = ENOMEM; 1518 hx509_set_error_string(context, 0, ret, "Out of memory"); 1519 goto out; 1520 } 1521 1522 /* 1523 * XXX unbreak when asn1 compiler handle IMPLICIT 1524 * 1525 * This is so horrible. 1526 */ 1527 1528 ret = copy_Name(&certificate->tbsCertificate.subject, &name); 1529 if (ret) { 1530 hx509_set_error_string(context, 0, ret, "Out of memory"); 1531 goto out; 1532 } 1533 1534 memset(&gn, 0, sizeof(gn)); 1535 gn.element = choice_GeneralName_directoryName; 1536 gn.u.directoryName.element = 1537 choice_GeneralName_directoryName_rdnSequence; 1538 gn.u.directoryName.u.rdnSequence = name.u.rdnSequence; 1539 1540 ret = add_GeneralNames(&gns, &gn); 1541 if (ret) { 1542 hx509_set_error_string(context, 0, ret, "Out of memory"); 1543 goto out; 1544 } 1545 1546 ai->authorityCertIssuer->val = gns.val; 1547 ai->authorityCertIssuer->len = gns.len; 1548 1549 ret = der_copy_heim_integer(&certificate->tbsCertificate.serialNumber, 1550 ai->authorityCertSerialNumber); 1551 if (ai->authorityCertSerialNumber == NULL) { 1552 ret = ENOMEM; 1553 hx509_set_error_string(context, 0, ret, "Out of memory"); 1554 goto out; 1555 } 1556 } 1557 out: 1558 if (ret) 1559 free_AuthorityKeyIdentifier(ai); 1560 return ret; 1561 } 1562 1563 1564 /** 1565 * Sign a to-be-signed certificate object with a issuer certificate. 1566 * 1567 * The caller needs to at least have called the following functions on the 1568 * to-be-signed certificate object: 1569 * - hx509_ca_tbs_init() 1570 * - hx509_ca_tbs_set_subject() 1571 * - hx509_ca_tbs_set_spki() 1572 * 1573 * When done the to-be-signed certificate object should be freed with 1574 * hx509_ca_tbs_free(). 1575 * 1576 * When creating self-signed certificate use hx509_ca_sign_self() instead. 1577 * 1578 * @param context A hx509 context. 1579 * @param tbs object to be signed. 1580 * @param signer the CA certificate object to sign with (need private key). 1581 * @param certificate return cerificate, free with hx509_cert_free(). 1582 * 1583 * @return An hx509 error code, see hx509_get_error_string(). 1584 * 1585 * @ingroup hx509_ca 1586 */ 1587 1588 int 1589 hx509_ca_sign(hx509_context context, 1590 hx509_ca_tbs tbs, 1591 hx509_cert signer, 1592 hx509_cert *certificate) 1593 { 1594 const Certificate *signer_cert; 1595 AuthorityKeyIdentifier ai; 1596 int ret; 1597 1598 memset(&ai, 0, sizeof(ai)); 1599 1600 signer_cert = _hx509_get_cert(signer); 1601 1602 ret = get_AuthorityKeyIdentifier(context, signer_cert, &ai); 1603 if (ret) 1604 goto out; 1605 1606 ret = ca_sign(context, 1607 tbs, 1608 _hx509_cert_private_key(signer), 1609 &ai, 1610 &signer_cert->tbsCertificate.subject, 1611 certificate); 1612 1613 out: 1614 free_AuthorityKeyIdentifier(&ai); 1615 1616 return ret; 1617 } 1618 1619 /** 1620 * Work just like hx509_ca_sign() but signs it-self. 1621 * 1622 * @param context A hx509 context. 1623 * @param tbs object to be signed. 1624 * @param signer private key to sign with. 1625 * @param certificate return cerificate, free with hx509_cert_free(). 1626 * 1627 * @return An hx509 error code, see hx509_get_error_string(). 1628 * 1629 * @ingroup hx509_ca 1630 */ 1631 1632 int 1633 hx509_ca_sign_self(hx509_context context, 1634 hx509_ca_tbs tbs, 1635 hx509_private_key signer, 1636 hx509_cert *certificate) 1637 { 1638 return ca_sign(context, 1639 tbs, 1640 signer, 1641 NULL, 1642 NULL, 1643 certificate); 1644 } 1645