bf8fe1be1a4c91bc7bd16dc94d7df89139ef1049
[samba.git] / source4 / heimdal / lib / hx509 / ca.c
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: ca.c 21379 2007-06-28 07:38:17Z lha $");
37
38 struct hx509_ca_tbs {
39     hx509_name subject;
40     SubjectPublicKeyInfo spki;
41     ExtKeyUsage eku;
42     GeneralNames san;
43     unsigned key_usage;
44     heim_integer serial;
45     struct {
46         unsigned int proxy:1;
47         unsigned int ca:1;
48         unsigned int key:1;
49         unsigned int serial:1;
50         unsigned int domaincontroller:1;
51     } flags;
52     time_t notBefore;
53     time_t notAfter;
54     int pathLenConstraint; /* both for CA and Proxy */
55     CRLDistributionPoints crldp;
56 };
57
58 int
59 hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs)
60 {
61     *tbs = calloc(1, sizeof(**tbs));
62     if (*tbs == NULL)
63         return ENOMEM;
64
65     (*tbs)->subject = NULL;
66     (*tbs)->san.len = 0;
67     (*tbs)->san.val = NULL;
68     (*tbs)->eku.len = 0;
69     (*tbs)->eku.val = NULL;
70     (*tbs)->pathLenConstraint = 0;
71     (*tbs)->crldp.len = 0;
72     (*tbs)->crldp.val = NULL;
73
74     return 0;
75 }
76
77 void
78 hx509_ca_tbs_free(hx509_ca_tbs *tbs)
79 {
80     if (tbs == NULL || *tbs == NULL)
81         return;
82
83     free_SubjectPublicKeyInfo(&(*tbs)->spki);
84     free_GeneralNames(&(*tbs)->san);
85     free_ExtKeyUsage(&(*tbs)->eku);
86     der_free_heim_integer(&(*tbs)->serial);
87     free_CRLDistributionPoints(&(*tbs)->crldp);
88
89     hx509_name_free(&(*tbs)->subject);
90
91     memset(*tbs, 0, sizeof(**tbs));
92     free(*tbs);
93     *tbs = NULL;
94 }
95
96 int
97 hx509_ca_tbs_set_notBefore(hx509_context context,
98                            hx509_ca_tbs tbs,
99                            time_t t)
100 {
101     tbs->notBefore = t;
102     return 0;
103 }
104
105 int
106 hx509_ca_tbs_set_notAfter(hx509_context context,
107                            hx509_ca_tbs tbs,
108                            time_t t)
109 {
110     tbs->notAfter = t;
111     return 0;
112 }
113
114 int
115 hx509_ca_tbs_set_notAfter_lifetime(hx509_context context,
116                                    hx509_ca_tbs tbs,
117                                    time_t delta)
118 {
119     return hx509_ca_tbs_set_notAfter(context, tbs, time(NULL) + delta);
120 }
121
122 static const struct units templatebits[] = {
123     { "ExtendedKeyUsage", HX509_CA_TEMPLATE_EKU },
124     { "KeyUsage", HX509_CA_TEMPLATE_KU },
125     { "SPKI", HX509_CA_TEMPLATE_SPKI },
126     { "notAfter", HX509_CA_TEMPLATE_NOTAFTER },
127     { "notBefore", HX509_CA_TEMPLATE_NOTBEFORE },
128     { "serial", HX509_CA_TEMPLATE_SERIAL },
129     { "subject", HX509_CA_TEMPLATE_SUBJECT },
130     { NULL, 0 }
131 };
132
133 const struct units *
134 hx509_ca_tbs_template_units(void)
135 {
136     return templatebits;
137 }
138
139 int
140 hx509_ca_tbs_set_template(hx509_context context,
141                           hx509_ca_tbs tbs,
142                           int flags,
143                           hx509_cert cert)
144 {
145     int ret;
146
147     if (flags & HX509_CA_TEMPLATE_SUBJECT) {
148         if (tbs->subject)
149             hx509_name_free(&tbs->subject);
150         ret = hx509_cert_get_subject(cert, &tbs->subject);
151         if (ret) {
152             hx509_set_error_string(context, 0, ret, 
153                                    "Failed to get subject from template");
154             return ret;
155         }
156     }
157     if (flags & HX509_CA_TEMPLATE_SERIAL) {
158         der_free_heim_integer(&tbs->serial);
159         ret = hx509_cert_get_serialnumber(cert, &tbs->serial);
160         tbs->flags.serial = !ret;
161         if (ret) {
162             hx509_set_error_string(context, 0, ret, 
163                                    "Failed to copy serial number");
164             return ret;
165         }
166     }
167     if (flags & HX509_CA_TEMPLATE_NOTBEFORE)
168         tbs->notBefore = hx509_cert_get_notBefore(cert);
169     if (flags & HX509_CA_TEMPLATE_NOTAFTER)
170         tbs->notAfter = hx509_cert_get_notAfter(cert);
171     if (flags & HX509_CA_TEMPLATE_SPKI) {
172         free_SubjectPublicKeyInfo(&tbs->spki);
173         ret = hx509_cert_get_SPKI(cert, &tbs->spki);
174         tbs->flags.key = !ret;
175         if (ret) {
176             hx509_set_error_string(context, 0, ret, "Failed to copy SPKI");
177             return ret;
178         }
179     }
180     if (flags & HX509_CA_TEMPLATE_KU) {
181         KeyUsage ku;
182         ret = _hx509_cert_get_keyusage(context, cert, &ku);
183         if (ret)
184             return ret;
185         tbs->key_usage = KeyUsage2int(ku);
186     }
187     if (flags & HX509_CA_TEMPLATE_EKU) {
188         ExtKeyUsage eku;
189         int i;
190         ret = _hx509_cert_get_eku(context, cert, &eku);
191         if (ret)
192             return ret;
193         for (i = 0; i < eku.len; i++) {
194             ret = hx509_ca_tbs_add_eku(context, tbs, &eku.val[i]);
195             if (ret) {
196                 free_ExtKeyUsage(&eku);
197                 return ret;
198             }
199         }
200         free_ExtKeyUsage(&eku);
201     }
202     return 0;
203 }
204
205 int
206 hx509_ca_tbs_set_ca(hx509_context context,
207                     hx509_ca_tbs tbs,
208                     int pathLenConstraint)
209 {
210     tbs->flags.ca = 1;
211     tbs->pathLenConstraint = pathLenConstraint;
212     return 0;
213 }
214
215 int
216 hx509_ca_tbs_set_proxy(hx509_context context,
217                        hx509_ca_tbs tbs,
218                        int pathLenConstraint)
219 {
220     tbs->flags.proxy = 1;
221     tbs->pathLenConstraint = pathLenConstraint;
222     return 0;
223 }
224
225
226 int
227 hx509_ca_tbs_set_domaincontroller(hx509_context context,
228                                   hx509_ca_tbs tbs)
229 {
230     tbs->flags.domaincontroller = 1;
231     return 0;
232 }
233
234 int
235 hx509_ca_tbs_set_spki(hx509_context context,
236                       hx509_ca_tbs tbs,
237                       const SubjectPublicKeyInfo *spki)
238 {
239     int ret;
240     free_SubjectPublicKeyInfo(&tbs->spki);
241     ret = copy_SubjectPublicKeyInfo(spki, &tbs->spki);
242     tbs->flags.key = !ret;
243     return ret;
244 }
245
246 int
247 hx509_ca_tbs_set_serialnumber(hx509_context context,
248                               hx509_ca_tbs tbs,
249                               const heim_integer *serialNumber)
250 {
251     int ret;
252     der_free_heim_integer(&tbs->serial);
253     ret = der_copy_heim_integer(serialNumber, &tbs->serial);
254     tbs->flags.serial = !ret;
255     return ret;
256 }
257
258 int
259 hx509_ca_tbs_add_eku(hx509_context context,
260                      hx509_ca_tbs tbs,
261                      const heim_oid *oid)
262 {
263     void *ptr;
264     int ret;
265     unsigned i;
266
267     /* search for duplicates */
268     for (i = 0; i < tbs->eku.len; i++) {
269         if (der_heim_oid_cmp(oid, &tbs->eku.val[i]) == 0)
270             return 0;
271     }
272
273     ptr = realloc(tbs->eku.val, sizeof(tbs->eku.val[0]) * (tbs->eku.len + 1));
274     if (ptr == NULL) {
275         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
276         return ENOMEM;
277     }
278     tbs->eku.val = ptr;
279     ret = der_copy_oid(oid, &tbs->eku.val[tbs->eku.len]);
280     if (ret) {
281         hx509_set_error_string(context, 0, ret, "out of memory");
282         return ret;
283     }
284     tbs->eku.len += 1;
285     return 0;
286 }
287
288 int
289 hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
290                             hx509_ca_tbs tbs,
291                             const char *uri,
292                             hx509_name issuername)
293 {
294     DistributionPoint dp;
295     int ret;
296
297     memset(&dp, 0, sizeof(dp));
298     
299     dp.distributionPoint = ecalloc(1, sizeof(*dp.distributionPoint));
300
301     {
302         DistributionPointName name;
303         GeneralName gn;
304         size_t size;
305
306         name.element = choice_DistributionPointName_fullName;
307         name.u.fullName.len = 1;
308         name.u.fullName.val = &gn;
309
310         gn.element = choice_GeneralName_uniformResourceIdentifier;
311         gn.u.uniformResourceIdentifier = rk_UNCONST(uri);
312
313         ASN1_MALLOC_ENCODE(DistributionPointName, 
314                            dp.distributionPoint->data, 
315                            dp.distributionPoint->length,
316                            &name, &size, ret);
317         if (ret) {
318             hx509_set_error_string(context, 0, ret,
319                                    "Failed to encoded DistributionPointName");
320             goto out;
321         }
322         if (dp.distributionPoint->length != size)
323             _hx509_abort("internal ASN.1 encoder error");
324     }
325
326     if (issuername) {
327 #if 1
328         hx509_set_error_string(context, 0, EINVAL,
329                                "CRLDistributionPoints.name.issuername not yet supported");
330         return EINVAL;
331 #else 
332         GeneralNames *crlissuer;
333         GeneralName gn;
334         Name n;
335
336         crlissuer = calloc(1, sizeof(*crlissuer));
337         if (crlissuer == NULL) {
338             return ENOMEM;
339         }
340         memset(&gn, 0, sizeof(gn));
341
342         gn.element = choice_GeneralName_directoryName;
343         ret = hx509_name_to_Name(issuername, &n);
344         if (ret) {
345             hx509_set_error_string(context, 0, ret, "out of memory");
346             goto out;
347         }
348
349         gn.u.directoryName.element = n.element;
350         gn.u.directoryName.u.rdnSequence = n.u.rdnSequence;
351
352         ret = add_GeneralNames(&crlissuer, &gn);
353         free_Name(&n);
354         if (ret) {
355             hx509_set_error_string(context, 0, ret, "out of memory");
356             goto out;
357         }
358
359         dp.cRLIssuer = &crlissuer;
360 #endif
361     }
362
363     ret = add_CRLDistributionPoints(&tbs->crldp, &dp);
364     if (ret) {
365         hx509_set_error_string(context, 0, ret, "out of memory");
366         goto out;
367     }
368
369 out:
370     free_DistributionPoint(&dp);
371
372     return ret;
373 }
374
375 int
376 hx509_ca_tbs_add_san_otherName(hx509_context context,
377                                hx509_ca_tbs tbs,
378                                const heim_oid *oid,
379                                const heim_octet_string *os)
380 {
381     GeneralName gn;
382
383     memset(&gn, 0, sizeof(gn));
384     gn.element = choice_GeneralName_otherName;
385     gn.u.otherName.type_id = *oid;
386     gn.u.otherName.value = *os;
387     
388     return add_GeneralNames(&tbs->san, &gn);
389 }
390
391
392 int
393 hx509_ca_tbs_add_san_pkinit(hx509_context context,
394                             hx509_ca_tbs tbs,
395                             const char *principal)
396 {
397     heim_octet_string os;
398     KRB5PrincipalName p;
399     size_t size;
400     int ret;
401     char *s = NULL;
402
403     memset(&p, 0, sizeof(p));
404
405     /* parse principal */
406     {
407         const char *str;
408         char *q;
409         int n;
410         
411         /* count number of component */
412         n = 1;
413         for(str = principal; *str != '\0' && *str != '@'; str++){
414             if(*str=='\\'){
415                 if(str[1] == '\0' || str[1] == '@') {
416                     ret = HX509_PARSING_NAME_FAILED;
417                     hx509_set_error_string(context, 0, ret, 
418                                            "trailing \\ in principal name");
419                     goto out;
420                 }
421                 str++;
422             } else if(*str == '/')
423                 n++;
424         }
425         p.principalName.name_string.val = 
426             calloc(n, sizeof(*p.principalName.name_string.val));
427         if (p.principalName.name_string.val == NULL) {
428             ret = ENOMEM;
429             hx509_set_error_string(context, 0, ret, "malloc: out of memory");
430             goto out;
431         }
432         p.principalName.name_string.len = n;
433         
434         p.principalName.name_type = KRB5_NT_PRINCIPAL;
435         q = s = strdup(principal);
436         if (q == NULL) {
437             ret = ENOMEM;
438             hx509_set_error_string(context, 0, ret, "malloc: out of memory");
439             goto out;
440         }
441         p.realm = strrchr(q, '@');
442         if (p.realm == NULL) {
443             ret = HX509_PARSING_NAME_FAILED;
444             hx509_set_error_string(context, 0, ret, "Missing @ in principal");
445             goto out;
446         };
447         *p.realm++ = '\0';
448
449         n = 0;
450         while (q) {
451             p.principalName.name_string.val[n++] = q;
452             q = strchr(q, '/');
453             if (q)
454                 *q++ = '\0';
455         }
456     }
457     
458     ASN1_MALLOC_ENCODE(KRB5PrincipalName, os.data, os.length, &p, &size, ret);
459     if (ret) {
460         hx509_set_error_string(context, 0, ret, "Out of memory");
461         goto out;
462     }
463     if (size != os.length)
464         _hx509_abort("internal ASN.1 encoder error");
465     
466     ret = hx509_ca_tbs_add_san_otherName(context,
467                                          tbs,
468                                          oid_id_pkinit_san(),
469                                          &os);
470     free(os.data);
471 out:
472     if (p.principalName.name_string.val)
473         free (p.principalName.name_string.val);
474     if (s)
475         free(s);
476     return ret;
477 }
478     
479 /*
480  *
481  */
482
483 static int
484 add_utf8_san(hx509_context context,
485              hx509_ca_tbs tbs,
486              const heim_oid *oid,
487              const char *string)
488 {
489     const PKIXXmppAddr ustring = (const PKIXXmppAddr)string;
490     heim_octet_string os;
491     size_t size;
492     int ret;
493
494     os.length = 0;
495     os.data = NULL;
496
497     ASN1_MALLOC_ENCODE(PKIXXmppAddr, os.data, os.length, &ustring, &size, ret);
498     if (ret) {
499         hx509_set_error_string(context, 0, ret, "Out of memory");
500         goto out;
501     }
502     if (size != os.length)
503         _hx509_abort("internal ASN.1 encoder error");
504     
505     ret = hx509_ca_tbs_add_san_otherName(context,
506                                          tbs,
507                                          oid,
508                                          &os);
509     free(os.data);
510 out:
511     return ret;
512 }
513
514 int
515 hx509_ca_tbs_add_san_ms_upn(hx509_context context,
516                             hx509_ca_tbs tbs,
517                             const char *principal)
518 {
519     return add_utf8_san(context, tbs, oid_id_pkinit_ms_san(), principal);
520 }
521
522 int
523 hx509_ca_tbs_add_san_jid(hx509_context context,
524                          hx509_ca_tbs tbs,
525                          const char *jid)
526 {
527     return add_utf8_san(context, tbs, oid_id_pkix_on_xmppAddr(), jid);
528 }
529
530
531 int
532 hx509_ca_tbs_add_san_hostname(hx509_context context,
533                               hx509_ca_tbs tbs,
534                               const char *dnsname)
535 {
536     GeneralName gn;
537
538     memset(&gn, 0, sizeof(gn));
539     gn.element = choice_GeneralName_dNSName;
540     gn.u.dNSName = rk_UNCONST(dnsname);
541     
542     return add_GeneralNames(&tbs->san, &gn);
543 }
544
545 int
546 hx509_ca_tbs_add_san_rfc822name(hx509_context context,
547                                 hx509_ca_tbs tbs,
548                                 const char *rfc822Name)
549 {
550     GeneralName gn;
551
552     memset(&gn, 0, sizeof(gn));
553     gn.element = choice_GeneralName_rfc822Name;
554     gn.u.rfc822Name = rk_UNCONST(rfc822Name);
555     
556     return add_GeneralNames(&tbs->san, &gn);
557 }
558
559
560 int
561 hx509_ca_tbs_set_subject(hx509_context context,
562                          hx509_ca_tbs tbs,
563                          hx509_name subject)
564 {
565     if (tbs->subject)
566         hx509_name_free(&tbs->subject);
567     return hx509_name_copy(context, subject, &tbs->subject);
568 }
569
570 int
571 hx509_ca_tbs_subject_expand(hx509_context context,
572                             hx509_ca_tbs tbs,
573                             hx509_env env)
574 {
575     return hx509_name_expand(context, tbs->subject, env);
576 }
577
578 static int
579 add_extension(hx509_context context,
580               TBSCertificate *tbsc,
581               int critical_flag,
582               const heim_oid *oid,
583               const heim_octet_string *data)
584 {
585     Extension ext;
586     int ret;
587
588     memset(&ext, 0, sizeof(ext));
589
590     if (critical_flag) {
591         ext.critical = malloc(sizeof(*ext.critical));
592         if (ext.critical == NULL) {
593             ret = ENOMEM;
594             hx509_set_error_string(context, 0, ret, "Out of memory");
595             goto out;
596         }
597         *ext.critical = TRUE;
598     }
599
600     ret = der_copy_oid(oid, &ext.extnID);
601     if (ret) {
602         hx509_set_error_string(context, 0, ret, "Out of memory");
603         goto out;
604     }
605     ret = der_copy_octet_string(data, &ext.extnValue);
606     if (ret) {
607         hx509_set_error_string(context, 0, ret, "Out of memory");
608         goto out;
609     }
610     ret = add_Extensions(tbsc->extensions, &ext);
611     if (ret) {
612         hx509_set_error_string(context, 0, ret, "Out of memory");
613         goto out;
614     }
615 out:
616     free_Extension(&ext);
617     return ret;
618 }
619
620 static int
621 build_proxy_prefix(hx509_context context, const Name *issuer, Name *subject)
622 {
623     char *tstr;
624     time_t t;
625     int ret;
626
627     ret = copy_Name(issuer, subject);
628     if (ret) {
629         hx509_set_error_string(context, 0, ret,
630                                "Failed to copy subject name");
631         return ret;
632     }
633
634     t = time(NULL);
635     asprintf(&tstr, "ts-%lu", (unsigned long)t);
636     if (tstr == NULL) {
637         hx509_set_error_string(context, 0, ENOMEM,
638                                "Failed to copy subject name");
639         return ENOMEM;
640     }
641     /* prefix with CN=<ts>,...*/
642     ret = _hx509_name_modify(context, subject, 1, oid_id_at_commonName(), tstr);
643     free(tstr);
644     if (ret)
645         free_Name(subject);
646     return ret;
647 }
648
649 static int
650 ca_sign(hx509_context context,
651         hx509_ca_tbs tbs,
652         hx509_private_key signer,
653         const AuthorityKeyIdentifier *ai,
654         const Name *issuername,
655         hx509_cert *certificate)
656 {
657     heim_octet_string data;
658     Certificate c;
659     TBSCertificate *tbsc;
660     size_t size;
661     int ret;
662     const AlgorithmIdentifier *sigalg;
663     time_t notBefore;
664     time_t notAfter;
665     unsigned key_usage;
666
667     sigalg = _hx509_crypto_default_sig_alg;
668
669     memset(&c, 0, sizeof(c));
670
671     /*
672      * Default values are: Valid since 24h ago, valid one year into
673      * the future, KeyUsage digitalSignature and keyEncipherment set,
674      * and keyCertSign for CA certificates.
675      */
676     notBefore = tbs->notBefore;
677     if (notBefore == 0)
678         notBefore = time(NULL) - 3600 * 24;
679     notAfter = tbs->notAfter;
680     if (notAfter == 0)
681         notAfter = time(NULL) + 3600 * 24 * 365;
682
683     key_usage = tbs->key_usage;
684     if (key_usage == 0) {
685         KeyUsage ku;
686         memset(&ku, 0, sizeof(ku));
687         ku.digitalSignature = 1;
688         ku.keyEncipherment = 1;
689         key_usage = KeyUsage2int(ku);
690     }
691
692     if (tbs->flags.ca) {
693         KeyUsage ku;
694         memset(&ku, 0, sizeof(ku));
695         ku.keyCertSign = 1;
696         ku.cRLSign = 1;
697         key_usage |= KeyUsage2int(ku);
698     }
699
700     /*
701      *
702      */
703
704     tbsc = &c.tbsCertificate;
705
706     if (tbs->flags.key == 0) {
707         ret = EINVAL;
708         hx509_set_error_string(context, 0, ret, "No public key set");
709         return ret;
710     }
711     /*
712      * Don't put restrictions on proxy certificate's subject name, it
713      * will be generated below.
714      */
715     if (!tbs->flags.proxy) {
716         if (tbs->subject == NULL) {
717             hx509_set_error_string(context, 0, EINVAL, "No subject name set");
718             return EINVAL;
719         }
720         if (hx509_name_is_null_p(tbs->subject) && tbs->san.len == 0) {
721             hx509_set_error_string(context, 0, EINVAL, 
722                                    "NULL subject and no SubjectAltNames");
723             return EINVAL;
724         }
725     }
726     if (tbs->flags.ca && tbs->flags.proxy) {
727         hx509_set_error_string(context, 0, EINVAL, "Can't be proxy and CA "
728                                "at the same time");
729         return EINVAL;
730     }
731     if (tbs->flags.proxy) {
732         if (tbs->san.len > 0) {
733             hx509_set_error_string(context, 0, EINVAL, 
734                                    "Proxy certificate is not allowed "
735                                    "to have SubjectAltNames");
736             return EINVAL;
737         }
738     }
739
740     /* version         [0]  Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1, */
741     tbsc->version = calloc(1, sizeof(*tbsc->version));
742     if (tbsc->version == NULL) {
743         ret = ENOMEM;
744         hx509_set_error_string(context, 0, ret, "Out of memory");
745         goto out;
746     }
747     *tbsc->version = rfc3280_version_3;
748     /* serialNumber         CertificateSerialNumber, */
749     if (tbs->flags.serial) {
750         ret = der_copy_heim_integer(&tbs->serial, &tbsc->serialNumber);
751         if (ret) {
752             hx509_set_error_string(context, 0, ret, "Out of memory");
753             goto out;
754         }
755     } else {
756         tbsc->serialNumber.length = 20;
757         tbsc->serialNumber.data = malloc(tbsc->serialNumber.length);
758         if (tbsc->serialNumber.data == NULL){
759             ret = ENOMEM;
760             hx509_set_error_string(context, 0, ret, "Out of memory");
761             goto out;
762         }
763         /* XXX diffrent */
764         RAND_bytes(tbsc->serialNumber.data, tbsc->serialNumber.length);
765         ((unsigned char *)tbsc->serialNumber.data)[0] &= 0x7f;
766     }
767     /* signature            AlgorithmIdentifier, */
768     ret = copy_AlgorithmIdentifier(sigalg, &tbsc->signature);
769     if (ret) {
770         hx509_set_error_string(context, 0, ret, "Failed to copy sigature alg");
771         goto out;
772     }
773     /* issuer               Name, */
774     if (issuername)
775         ret = copy_Name(issuername, &tbsc->issuer);
776     else
777         ret = hx509_name_to_Name(tbs->subject, &tbsc->issuer);
778     if (ret) {
779         hx509_set_error_string(context, 0, ret, "Failed to copy issuer name");
780         goto out;
781     }
782     /* validity             Validity, */
783     tbsc->validity.notBefore.element = choice_Time_generalTime;
784     tbsc->validity.notBefore.u.generalTime = notBefore;
785     tbsc->validity.notAfter.element = choice_Time_generalTime;
786     tbsc->validity.notAfter.u.generalTime = notAfter;
787     /* subject              Name, */
788     if (tbs->flags.proxy) {
789         ret = build_proxy_prefix(context, &tbsc->issuer, &tbsc->subject);
790         if (ret)
791             goto out;
792     } else {
793         ret = hx509_name_to_Name(tbs->subject, &tbsc->subject);
794         if (ret) {
795             hx509_set_error_string(context, 0, ret,
796                                    "Failed to copy subject name");
797             goto out;
798         }
799     }
800     /* subjectPublicKeyInfo SubjectPublicKeyInfo, */
801     ret = copy_SubjectPublicKeyInfo(&tbs->spki, &tbsc->subjectPublicKeyInfo);
802     if (ret) {
803         hx509_set_error_string(context, 0, ret, "Failed to copy spki");
804         goto out;
805     }
806     /* issuerUniqueID  [1]  IMPLICIT BIT STRING OPTIONAL */
807     /* subjectUniqueID [2]  IMPLICIT BIT STRING OPTIONAL */
808     /* extensions      [3]  EXPLICIT Extensions OPTIONAL */
809     tbsc->extensions = calloc(1, sizeof(*tbsc->extensions));
810     if (tbsc->extensions == NULL) {
811         ret = ENOMEM;
812         hx509_set_error_string(context, 0, ret, "Out of memory");
813         goto out;
814     }
815     
816     /* Add the text BMP string Domaincontroller to the cert */
817     if (tbs->flags.domaincontroller) {
818         data.data = rk_UNCONST("\x1e\x20\x00\x44\x00\x6f\x00\x6d"
819                                "\x00\x61\x00\x69\x00\x6e\x00\x43"
820                                "\x00\x6f\x00\x6e\x00\x74\x00\x72"
821                                "\x00\x6f\x00\x6c\x00\x6c\x00\x65"
822                                "\x00\x72");
823         data.length = 34;
824
825         ret = add_extension(context, tbsc, 0,
826                             oid_id_ms_cert_enroll_domaincontroller(),
827                             &data);
828         if (ret)
829             goto out;
830     }
831
832     /* add KeyUsage */
833     {
834         KeyUsage ku;
835
836         ku = int2KeyUsage(key_usage);
837         ASN1_MALLOC_ENCODE(KeyUsage, data.data, data.length, &ku, &size, ret);
838         if (ret) {
839             hx509_set_error_string(context, 0, ret, "Out of memory");
840             goto out;
841         }
842         if (size != data.length)
843             _hx509_abort("internal ASN.1 encoder error");
844         ret = add_extension(context, tbsc, 1,
845                             oid_id_x509_ce_keyUsage(), &data);
846         free(data.data);
847         if (ret)
848             goto out;
849     }
850
851     /* add ExtendedKeyUsage */
852     if (tbs->eku.len > 0) {
853         ASN1_MALLOC_ENCODE(ExtKeyUsage, data.data, data.length, 
854                            &tbs->eku, &size, ret);
855         if (ret) {
856             hx509_set_error_string(context, 0, ret, "Out of memory");
857             goto out;
858         }
859         if (size != data.length)
860             _hx509_abort("internal ASN.1 encoder error");
861         ret = add_extension(context, tbsc, 0,
862                             oid_id_x509_ce_extKeyUsage(), &data);
863         free(data.data);
864         if (ret)
865             goto out;
866     }
867
868     /* add Subject Alternative Name */
869     if (tbs->san.len > 0) {
870         ASN1_MALLOC_ENCODE(GeneralNames, data.data, data.length, 
871                            &tbs->san, &size, ret);
872         if (ret) {
873             hx509_set_error_string(context, 0, ret, "Out of memory");
874             goto out;
875         }
876         if (size != data.length)
877             _hx509_abort("internal ASN.1 encoder error");
878         ret = add_extension(context, tbsc, 0,
879                             oid_id_x509_ce_subjectAltName(),
880                             &data);
881         free(data.data);
882         if (ret)
883             goto out;
884     }
885
886     /* Add Authority Key Identifier */
887     if (ai) {
888         ASN1_MALLOC_ENCODE(AuthorityKeyIdentifier, data.data, data.length, 
889                            ai, &size, ret);
890         if (ret) {
891             hx509_set_error_string(context, 0, ret, "Out of memory");
892             goto out;
893         }
894         if (size != data.length)
895             _hx509_abort("internal ASN.1 encoder error");
896         ret = add_extension(context, tbsc, 0,
897                             oid_id_x509_ce_authorityKeyIdentifier(),
898                             &data);
899         free(data.data);
900         if (ret)
901             goto out;
902     }
903
904     /* Add Subject Key Identifier */
905     {
906         SubjectKeyIdentifier si;
907         unsigned char hash[SHA_DIGEST_LENGTH];
908
909         {
910             SHA_CTX m;
911             
912             SHA1_Init(&m);
913             SHA1_Update(&m, tbs->spki.subjectPublicKey.data,
914                         tbs->spki.subjectPublicKey.length / 8);
915             SHA1_Final (hash, &m);
916         }
917
918         si.data = hash;
919         si.length = sizeof(hash);
920
921         ASN1_MALLOC_ENCODE(SubjectKeyIdentifier, data.data, data.length, 
922                            &si, &size, ret);
923         if (ret) {
924             hx509_set_error_string(context, 0, ret, "Out of memory");
925             goto out;
926         }
927         if (size != data.length)
928             _hx509_abort("internal ASN.1 encoder error");
929         ret = add_extension(context, tbsc, 0,
930                             oid_id_x509_ce_subjectKeyIdentifier(),
931                             &data);
932         free(data.data);
933         if (ret)
934             goto out;
935     }
936
937     /* Add BasicConstraints */ 
938     {
939         BasicConstraints bc;
940         int aCA = 1;
941         uint32_t path;
942
943         memset(&bc, 0, sizeof(bc));
944
945         if (tbs->flags.ca) {
946             bc.cA = &aCA;
947             if (tbs->pathLenConstraint >= 0) {
948                 path = tbs->pathLenConstraint;
949                 bc.pathLenConstraint = &path;
950             }
951         }
952
953         ASN1_MALLOC_ENCODE(BasicConstraints, data.data, data.length, 
954                            &bc, &size, ret);
955         if (ret) {
956             hx509_set_error_string(context, 0, ret, "Out of memory");
957             goto out;
958         }
959         if (size != data.length)
960             _hx509_abort("internal ASN.1 encoder error");
961         /* Critical if this is a CA */
962         ret = add_extension(context, tbsc, tbs->flags.ca,
963                             oid_id_x509_ce_basicConstraints(),
964                             &data);
965         free(data.data);
966         if (ret)
967             goto out;
968     }
969
970     /* add Proxy */
971     if (tbs->flags.proxy) {
972         ProxyCertInfo info;
973
974         memset(&info, 0, sizeof(info));
975
976         if (tbs->pathLenConstraint >= 0) {
977             info.pCPathLenConstraint = 
978                 malloc(sizeof(*info.pCPathLenConstraint));
979             if (info.pCPathLenConstraint == NULL) {
980                 ret = ENOMEM;
981                 hx509_set_error_string(context, 0, ret, "Out of memory");
982                 goto out;
983             }
984             *info.pCPathLenConstraint = tbs->pathLenConstraint;
985         }
986
987         ret = der_copy_oid(oid_id_pkix_ppl_inheritAll(),
988                            &info.proxyPolicy.policyLanguage);
989         if (ret) {
990             free_ProxyCertInfo(&info);
991             hx509_set_error_string(context, 0, ret, "Out of memory");
992             goto out;
993         }
994
995         ASN1_MALLOC_ENCODE(ProxyCertInfo, data.data, data.length, 
996                            &info, &size, ret);
997         free_ProxyCertInfo(&info);
998         if (ret) {
999             hx509_set_error_string(context, 0, ret, "Out of memory");
1000             goto out;
1001         }
1002         if (size != data.length)
1003             _hx509_abort("internal ASN.1 encoder error");
1004         ret = add_extension(context, tbsc, 0,
1005                             oid_id_pkix_pe_proxyCertInfo(),
1006                             &data);
1007         free(data.data);
1008         if (ret)
1009             goto out;
1010     }
1011
1012     if (tbs->crldp.len) {
1013
1014         ASN1_MALLOC_ENCODE(CRLDistributionPoints, data.data, data.length,
1015                            &tbs->crldp, &size, ret);
1016         if (ret) {
1017             hx509_set_error_string(context, 0, ret, "Out of memory");
1018             goto out;
1019         }
1020         if (size != data.length)
1021             _hx509_abort("internal ASN.1 encoder error");
1022         ret = add_extension(context, tbsc, FALSE,
1023                             oid_id_x509_ce_cRLDistributionPoints(),
1024                             &data);
1025         free(data.data);
1026         if (ret)
1027             goto out;
1028     }
1029
1030     ASN1_MALLOC_ENCODE(TBSCertificate, data.data, data.length,tbsc, &size, ret);
1031     if (ret) {
1032         hx509_set_error_string(context, 0, ret, "malloc out of memory");
1033         goto out;
1034     }
1035     if (data.length != size)
1036         _hx509_abort("internal ASN.1 encoder error");
1037
1038     ret = _hx509_create_signature_bitstring(context,
1039                                             signer,
1040                                             sigalg,
1041                                             &data,
1042                                             &c.signatureAlgorithm,
1043                                             &c.signatureValue);
1044     free(data.data);
1045     if (ret)
1046         goto out;
1047
1048     ret = hx509_cert_init(context, &c, certificate);
1049     if (ret)
1050         goto out;
1051
1052     free_Certificate(&c);
1053
1054     return 0;
1055
1056 out:
1057     free_Certificate(&c);
1058     return ret;
1059 }
1060
1061 static int
1062 get_AuthorityKeyIdentifier(hx509_context context,
1063                            const Certificate *certificate,
1064                            AuthorityKeyIdentifier *ai)
1065 {
1066     SubjectKeyIdentifier si;
1067     int ret;
1068
1069     ret = _hx509_find_extension_subject_key_id(certificate, &si);
1070     if (ret == 0) {
1071         ai->keyIdentifier = calloc(1, sizeof(*ai->keyIdentifier));
1072         if (ai->keyIdentifier == NULL) {
1073             free_SubjectKeyIdentifier(&si);
1074             ret = ENOMEM;
1075             hx509_set_error_string(context, 0, ret, "Out of memory");
1076             goto out;
1077         }
1078         ret = der_copy_octet_string(&si, ai->keyIdentifier);
1079         free_SubjectKeyIdentifier(&si);
1080         if (ret) {
1081             hx509_set_error_string(context, 0, ret, "Out of memory");
1082             goto out;
1083         }
1084     } else {
1085         GeneralNames gns;
1086         GeneralName gn;
1087         Name name;
1088
1089         memset(&gn, 0, sizeof(gn));
1090         memset(&gns, 0, sizeof(gns));
1091         memset(&name, 0, sizeof(name));
1092
1093         ai->authorityCertIssuer = 
1094             calloc(1, sizeof(*ai->authorityCertIssuer));
1095         if (ai->authorityCertIssuer == NULL) {
1096             ret = ENOMEM;
1097             hx509_set_error_string(context, 0, ret, "Out of memory");
1098             goto out;
1099         }
1100         ai->authorityCertSerialNumber = 
1101             calloc(1, sizeof(*ai->authorityCertSerialNumber));
1102         if (ai->authorityCertSerialNumber == NULL) {
1103             ret = ENOMEM;
1104             hx509_set_error_string(context, 0, ret, "Out of memory");
1105             goto out;
1106         }
1107
1108         /* 
1109          * XXX unbreak when asn1 compiler handle IMPLICIT
1110          *
1111          * This is so horrible.
1112          */
1113
1114         ret = copy_Name(&certificate->tbsCertificate.subject, &name);
1115         if (ai->authorityCertSerialNumber == NULL) {
1116             ret = ENOMEM;
1117             hx509_set_error_string(context, 0, ret, "Out of memory");
1118             goto out;
1119         }
1120
1121         memset(&gn, 0, sizeof(gn));
1122         gn.element = choice_GeneralName_directoryName;
1123         gn.u.directoryName.element = 
1124             choice_GeneralName_directoryName_rdnSequence;
1125         gn.u.directoryName.u.rdnSequence = name.u.rdnSequence;
1126
1127         ret = add_GeneralNames(&gns, &gn);
1128         if (ret) {
1129             hx509_set_error_string(context, 0, ret, "Out of memory");
1130             goto out;
1131         }
1132
1133         ai->authorityCertIssuer->val = gns.val;
1134         ai->authorityCertIssuer->len = gns.len;
1135
1136         ret = der_copy_heim_integer(&certificate->tbsCertificate.serialNumber,
1137                                     ai->authorityCertSerialNumber);
1138         if (ai->authorityCertSerialNumber == NULL) {
1139             ret = ENOMEM;
1140             hx509_set_error_string(context, 0, ret, "Out of memory");
1141             goto out;
1142         }
1143     }
1144 out:
1145     if (ret)
1146         free_AuthorityKeyIdentifier(ai);
1147     return ret;
1148 }
1149
1150
1151 int
1152 hx509_ca_sign(hx509_context context,
1153               hx509_ca_tbs tbs,
1154               hx509_cert signer,
1155               hx509_cert *certificate)
1156 {
1157     const Certificate *signer_cert;
1158     AuthorityKeyIdentifier ai;
1159     int ret;
1160
1161     memset(&ai, 0, sizeof(ai));
1162
1163     signer_cert = _hx509_get_cert(signer);
1164
1165     ret = get_AuthorityKeyIdentifier(context, signer_cert, &ai);
1166     if (ret)
1167         goto out;
1168
1169     ret = ca_sign(context,
1170                   tbs, 
1171                   _hx509_cert_private_key(signer),
1172                   &ai,
1173                   &signer_cert->tbsCertificate.subject,
1174                   certificate);
1175
1176 out:
1177     free_AuthorityKeyIdentifier(&ai);
1178
1179     return ret;
1180 }
1181
1182 int
1183 hx509_ca_sign_self(hx509_context context,
1184                    hx509_ca_tbs tbs,
1185                    hx509_private_key signer,
1186                    hx509_cert *certificate)
1187 {
1188     return ca_sign(context,
1189                    tbs, 
1190                    signer,
1191                    NULL,
1192                    NULL,
1193                    certificate);
1194 }