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