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