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