Home | History | Annotate | Line # | Download | only in hx509
      1 /*	$NetBSD: ca.c,v 1.2 2017/01/28 21:31:48 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2006 - 2010 Kungliga Tekniska Hgskolan
      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