xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/hx509/ca.c (revision d3273b5b76f5afaafe308cead5511dbb8df8c5e9)
1 /*	$NetBSD: ca.c,v 1.2 2017/01/28 21:31:48 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2006 - 2010 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the Institute nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include "hx_locl.h"
37 #include <krb5/pkinit_asn1.h>
38 
39 /**
40  * @page page_ca Hx509 CA functions
41  *
42  * See the library functions here: @ref hx509_ca
43  */
44 
45 struct hx509_ca_tbs {
46     hx509_name subject;
47     SubjectPublicKeyInfo spki;
48     ExtKeyUsage eku;
49     GeneralNames san;
50     unsigned key_usage;
51     heim_integer serial;
52     struct {
53 	unsigned int proxy:1;
54 	unsigned int ca:1;
55 	unsigned int key:1;
56 	unsigned int serial:1;
57 	unsigned int domaincontroller:1;
58 	unsigned int xUniqueID:1;
59     } flags;
60     time_t notBefore;
61     time_t notAfter;
62     int pathLenConstraint; /* both for CA and Proxy */
63     CRLDistributionPoints crldp;
64     heim_bit_string subjectUniqueID;
65     heim_bit_string issuerUniqueID;
66     AlgorithmIdentifier *sigalg;
67 };
68 
69 /**
70  * Allocate an to-be-signed certificate object that will be converted
71  * into an certificate.
72  *
73  * @param context A hx509 context.
74  * @param tbs returned to-be-signed certicate object, free with
75  * hx509_ca_tbs_free().
76  *
77  * @return An hx509 error code, see hx509_get_error_string().
78  *
79  * @ingroup hx509_ca
80  */
81 
82 int
hx509_ca_tbs_init(hx509_context context,hx509_ca_tbs * tbs)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
hx509_ca_tbs_free(hx509_ca_tbs * tbs)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
hx509_ca_tbs_set_notBefore(hx509_context context,hx509_ca_tbs tbs,time_t t)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
hx509_ca_tbs_set_notAfter(hx509_context context,hx509_ca_tbs tbs,time_t t)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
hx509_ca_tbs_set_notAfter_lifetime(hx509_context context,hx509_ca_tbs tbs,time_t delta)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 *
hx509_ca_tbs_template_units(void)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
hx509_ca_tbs_set_template(hx509_context context,hx509_ca_tbs tbs,int flags,hx509_cert cert)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
hx509_ca_tbs_set_ca(hx509_context context,hx509_ca_tbs tbs,int pathLenConstraint)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
hx509_ca_tbs_set_proxy(hx509_context context,hx509_ca_tbs tbs,int pathLenConstraint)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
hx509_ca_tbs_set_domaincontroller(hx509_context context,hx509_ca_tbs tbs)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
hx509_ca_tbs_set_spki(hx509_context context,hx509_ca_tbs tbs,const SubjectPublicKeyInfo * spki)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
hx509_ca_tbs_set_serialnumber(hx509_context context,hx509_ca_tbs tbs,const heim_integer * serialNumber)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
hx509_ca_tbs_add_eku(hx509_context context,hx509_ca_tbs tbs,const heim_oid * oid)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
hx509_ca_tbs_add_crl_dp_uri(hx509_context context,hx509_ca_tbs tbs,const char * uri,hx509_name issuername)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
hx509_ca_tbs_add_san_otherName(hx509_context context,hx509_ca_tbs tbs,const heim_oid * oid,const heim_octet_string * os)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
hx509_ca_tbs_add_san_pkinit(hx509_context context,hx509_ca_tbs tbs,const char * principal)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
add_utf8_san(hx509_context context,hx509_ca_tbs tbs,const heim_oid * oid,const char * string)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
hx509_ca_tbs_add_san_ms_upn(hx509_context context,hx509_ca_tbs tbs,const char * principal)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
hx509_ca_tbs_add_san_jid(hx509_context context,hx509_ca_tbs tbs,const char * jid)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
hx509_ca_tbs_add_san_hostname(hx509_context context,hx509_ca_tbs tbs,const char * dnsname)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
hx509_ca_tbs_add_san_rfc822name(hx509_context context,hx509_ca_tbs tbs,const char * rfc822Name)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
hx509_ca_tbs_set_subject(hx509_context context,hx509_ca_tbs tbs,hx509_name subject)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
hx509_ca_tbs_set_unique(hx509_context context,hx509_ca_tbs tbs,const heim_bit_string * subjectUniqueID,const heim_bit_string * issuerUniqueID)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
hx509_ca_tbs_subject_expand(hx509_context context,hx509_ca_tbs tbs,hx509_env env)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
hx509_ca_tbs_set_signature_algorithm(hx509_context context,hx509_ca_tbs tbs,const AlgorithmIdentifier * sigalg)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
add_extension(hx509_context context,TBSCertificate * tbsc,int critical_flag,const heim_oid * oid,const heim_octet_string * data)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
build_proxy_prefix(hx509_context context,const Name * issuer,Name * subject)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
ca_sign(hx509_context context,hx509_ca_tbs tbs,hx509_private_key signer,const AuthorityKeyIdentifier * ai,const Name * issuername,hx509_cert * certificate)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
get_AuthorityKeyIdentifier(hx509_context context,const Certificate * certificate,AuthorityKeyIdentifier * ai)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
hx509_ca_sign(hx509_context context,hx509_ca_tbs tbs,hx509_cert signer,hx509_cert * certificate)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
hx509_ca_sign_self(hx509_context context,hx509_ca_tbs tbs,hx509_private_key signer,hx509_cert * certificate)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