2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
35 #include <pkinit_asn1.h>
36 RCSID("$Id: ca.c 21379 2007-06-28 07:38:17Z lha $");
40 SubjectPublicKeyInfo spki;
49 unsigned int serial:1;
50 unsigned int domaincontroller:1;
54 int pathLenConstraint; /* both for CA and Proxy */
55 CRLDistributionPoints crldp;
59 hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs)
61 *tbs = calloc(1, sizeof(**tbs));
65 (*tbs)->subject = NULL;
67 (*tbs)->san.val = NULL;
69 (*tbs)->eku.val = NULL;
70 (*tbs)->pathLenConstraint = 0;
71 (*tbs)->crldp.len = 0;
72 (*tbs)->crldp.val = NULL;
78 hx509_ca_tbs_free(hx509_ca_tbs *tbs)
80 if (tbs == NULL || *tbs == NULL)
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);
89 hx509_name_free(&(*tbs)->subject);
91 memset(*tbs, 0, sizeof(**tbs));
97 hx509_ca_tbs_set_notBefore(hx509_context context,
106 hx509_ca_tbs_set_notAfter(hx509_context context,
115 hx509_ca_tbs_set_notAfter_lifetime(hx509_context context,
119 return hx509_ca_tbs_set_notAfter(context, tbs, time(NULL) + delta);
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 },
134 hx509_ca_tbs_template_units(void)
140 hx509_ca_tbs_set_template(hx509_context context,
147 if (flags & HX509_CA_TEMPLATE_SUBJECT) {
149 hx509_name_free(&tbs->subject);
150 ret = hx509_cert_get_subject(cert, &tbs->subject);
152 hx509_set_error_string(context, 0, ret,
153 "Failed to get subject from template");
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;
162 hx509_set_error_string(context, 0, ret,
163 "Failed to copy serial number");
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;
176 hx509_set_error_string(context, 0, ret, "Failed to copy SPKI");
180 if (flags & HX509_CA_TEMPLATE_KU) {
182 ret = _hx509_cert_get_keyusage(context, cert, &ku);
185 tbs->key_usage = KeyUsage2int(ku);
187 if (flags & HX509_CA_TEMPLATE_EKU) {
190 ret = _hx509_cert_get_eku(context, cert, &eku);
193 for (i = 0; i < eku.len; i++) {
194 ret = hx509_ca_tbs_add_eku(context, tbs, &eku.val[i]);
196 free_ExtKeyUsage(&eku);
200 free_ExtKeyUsage(&eku);
206 hx509_ca_tbs_set_ca(hx509_context context,
208 int pathLenConstraint)
211 tbs->pathLenConstraint = pathLenConstraint;
216 hx509_ca_tbs_set_proxy(hx509_context context,
218 int pathLenConstraint)
220 tbs->flags.proxy = 1;
221 tbs->pathLenConstraint = pathLenConstraint;
227 hx509_ca_tbs_set_domaincontroller(hx509_context context,
230 tbs->flags.domaincontroller = 1;
235 hx509_ca_tbs_set_spki(hx509_context context,
237 const SubjectPublicKeyInfo *spki)
240 free_SubjectPublicKeyInfo(&tbs->spki);
241 ret = copy_SubjectPublicKeyInfo(spki, &tbs->spki);
242 tbs->flags.key = !ret;
247 hx509_ca_tbs_set_serialnumber(hx509_context context,
249 const heim_integer *serialNumber)
252 der_free_heim_integer(&tbs->serial);
253 ret = der_copy_heim_integer(serialNumber, &tbs->serial);
254 tbs->flags.serial = !ret;
259 hx509_ca_tbs_add_eku(hx509_context context,
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)
273 ptr = realloc(tbs->eku.val, sizeof(tbs->eku.val[0]) * (tbs->eku.len + 1));
275 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
279 ret = der_copy_oid(oid, &tbs->eku.val[tbs->eku.len]);
281 hx509_set_error_string(context, 0, ret, "out of memory");
289 hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
292 hx509_name issuername)
294 DistributionPoint dp;
297 memset(&dp, 0, sizeof(dp));
299 dp.distributionPoint = ecalloc(1, sizeof(*dp.distributionPoint));
302 DistributionPointName name;
306 name.element = choice_DistributionPointName_fullName;
307 name.u.fullName.len = 1;
308 name.u.fullName.val = &gn;
310 gn.element = choice_GeneralName_uniformResourceIdentifier;
311 gn.u.uniformResourceIdentifier = rk_UNCONST(uri);
313 ASN1_MALLOC_ENCODE(DistributionPointName,
314 dp.distributionPoint->data,
315 dp.distributionPoint->length,
318 hx509_set_error_string(context, 0, ret,
319 "Failed to encoded DistributionPointName");
322 if (dp.distributionPoint->length != size)
323 _hx509_abort("internal ASN.1 encoder error");
328 hx509_set_error_string(context, 0, EINVAL,
329 "CRLDistributionPoints.name.issuername not yet supported");
332 GeneralNames *crlissuer;
336 crlissuer = calloc(1, sizeof(*crlissuer));
337 if (crlissuer == NULL) {
340 memset(&gn, 0, sizeof(gn));
342 gn.element = choice_GeneralName_directoryName;
343 ret = hx509_name_to_Name(issuername, &n);
345 hx509_set_error_string(context, 0, ret, "out of memory");
349 gn.u.directoryName.element = n.element;
350 gn.u.directoryName.u.rdnSequence = n.u.rdnSequence;
352 ret = add_GeneralNames(&crlissuer, &gn);
355 hx509_set_error_string(context, 0, ret, "out of memory");
359 dp.cRLIssuer = &crlissuer;
363 ret = add_CRLDistributionPoints(&tbs->crldp, &dp);
365 hx509_set_error_string(context, 0, ret, "out of memory");
370 free_DistributionPoint(&dp);
376 hx509_ca_tbs_add_san_otherName(hx509_context context,
379 const heim_octet_string *os)
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;
388 return add_GeneralNames(&tbs->san, &gn);
393 hx509_ca_tbs_add_san_pkinit(hx509_context context,
395 const char *principal)
397 heim_octet_string os;
403 memset(&p, 0, sizeof(p));
405 /* parse principal */
411 /* count number of component */
413 for(str = principal; *str != '\0' && *str != '@'; 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");
422 } else if(*str == '/')
425 p.principalName.name_string.val =
426 calloc(n, sizeof(*p.principalName.name_string.val));
427 if (p.principalName.name_string.val == NULL) {
429 hx509_set_error_string(context, 0, ret, "malloc: out of memory");
432 p.principalName.name_string.len = n;
434 p.principalName.name_type = KRB5_NT_PRINCIPAL;
435 q = s = strdup(principal);
438 hx509_set_error_string(context, 0, ret, "malloc: out of memory");
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");
451 p.principalName.name_string.val[n++] = q;
458 ASN1_MALLOC_ENCODE(KRB5PrincipalName, os.data, os.length, &p, &size, ret);
460 hx509_set_error_string(context, 0, ret, "Out of memory");
463 if (size != os.length)
464 _hx509_abort("internal ASN.1 encoder error");
466 ret = hx509_ca_tbs_add_san_otherName(context,
472 if (p.principalName.name_string.val)
473 free (p.principalName.name_string.val);
484 add_utf8_san(hx509_context context,
489 const PKIXXmppAddr ustring = (const PKIXXmppAddr)string;
490 heim_octet_string os;
497 ASN1_MALLOC_ENCODE(PKIXXmppAddr, os.data, os.length, &ustring, &size, ret);
499 hx509_set_error_string(context, 0, ret, "Out of memory");
502 if (size != os.length)
503 _hx509_abort("internal ASN.1 encoder error");
505 ret = hx509_ca_tbs_add_san_otherName(context,
515 hx509_ca_tbs_add_san_ms_upn(hx509_context context,
517 const char *principal)
519 return add_utf8_san(context, tbs, oid_id_pkinit_ms_san(), principal);
523 hx509_ca_tbs_add_san_jid(hx509_context context,
527 return add_utf8_san(context, tbs, oid_id_pkix_on_xmppAddr(), jid);
532 hx509_ca_tbs_add_san_hostname(hx509_context context,
538 memset(&gn, 0, sizeof(gn));
539 gn.element = choice_GeneralName_dNSName;
540 gn.u.dNSName = rk_UNCONST(dnsname);
542 return add_GeneralNames(&tbs->san, &gn);
546 hx509_ca_tbs_add_san_rfc822name(hx509_context context,
548 const char *rfc822Name)
552 memset(&gn, 0, sizeof(gn));
553 gn.element = choice_GeneralName_rfc822Name;
554 gn.u.rfc822Name = rk_UNCONST(rfc822Name);
556 return add_GeneralNames(&tbs->san, &gn);
561 hx509_ca_tbs_set_subject(hx509_context context,
566 hx509_name_free(&tbs->subject);
567 return hx509_name_copy(context, subject, &tbs->subject);
571 hx509_ca_tbs_subject_expand(hx509_context context,
575 return hx509_name_expand(context, tbs->subject, env);
579 add_extension(hx509_context context,
580 TBSCertificate *tbsc,
583 const heim_octet_string *data)
588 memset(&ext, 0, sizeof(ext));
591 ext.critical = malloc(sizeof(*ext.critical));
592 if (ext.critical == NULL) {
594 hx509_set_error_string(context, 0, ret, "Out of memory");
597 *ext.critical = TRUE;
600 ret = der_copy_oid(oid, &ext.extnID);
602 hx509_set_error_string(context, 0, ret, "Out of memory");
605 ret = der_copy_octet_string(data, &ext.extnValue);
607 hx509_set_error_string(context, 0, ret, "Out of memory");
610 ret = add_Extensions(tbsc->extensions, &ext);
612 hx509_set_error_string(context, 0, ret, "Out of memory");
616 free_Extension(&ext);
621 build_proxy_prefix(hx509_context context, const Name *issuer, Name *subject)
627 ret = copy_Name(issuer, subject);
629 hx509_set_error_string(context, 0, ret,
630 "Failed to copy subject name");
635 asprintf(&tstr, "ts-%lu", (unsigned long)t);
637 hx509_set_error_string(context, 0, ENOMEM,
638 "Failed to copy subject name");
641 /* prefix with CN=<ts>,...*/
642 ret = _hx509_name_modify(context, subject, 1, oid_id_at_commonName(), tstr);
650 ca_sign(hx509_context context,
652 hx509_private_key signer,
653 const AuthorityKeyIdentifier *ai,
654 const Name *issuername,
655 hx509_cert *certificate)
657 heim_octet_string data;
659 TBSCertificate *tbsc;
662 const AlgorithmIdentifier *sigalg;
667 sigalg = _hx509_crypto_default_sig_alg;
669 memset(&c, 0, sizeof(c));
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.
676 notBefore = tbs->notBefore;
678 notBefore = time(NULL) - 3600 * 24;
679 notAfter = tbs->notAfter;
681 notAfter = time(NULL) + 3600 * 24 * 365;
683 key_usage = tbs->key_usage;
684 if (key_usage == 0) {
686 memset(&ku, 0, sizeof(ku));
687 ku.digitalSignature = 1;
688 ku.keyEncipherment = 1;
689 key_usage = KeyUsage2int(ku);
694 memset(&ku, 0, sizeof(ku));
697 key_usage |= KeyUsage2int(ku);
704 tbsc = &c.tbsCertificate;
706 if (tbs->flags.key == 0) {
708 hx509_set_error_string(context, 0, ret, "No public key set");
712 * Don't put restrictions on proxy certificate's subject name, it
713 * will be generated below.
715 if (!tbs->flags.proxy) {
716 if (tbs->subject == NULL) {
717 hx509_set_error_string(context, 0, EINVAL, "No subject name set");
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");
726 if (tbs->flags.ca && tbs->flags.proxy) {
727 hx509_set_error_string(context, 0, EINVAL, "Can't be proxy and CA "
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");
740 /* version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1, */
741 tbsc->version = calloc(1, sizeof(*tbsc->version));
742 if (tbsc->version == NULL) {
744 hx509_set_error_string(context, 0, ret, "Out of memory");
747 *tbsc->version = rfc3280_version_3;
748 /* serialNumber CertificateSerialNumber, */
749 if (tbs->flags.serial) {
750 ret = der_copy_heim_integer(&tbs->serial, &tbsc->serialNumber);
752 hx509_set_error_string(context, 0, ret, "Out of memory");
756 tbsc->serialNumber.length = 20;
757 tbsc->serialNumber.data = malloc(tbsc->serialNumber.length);
758 if (tbsc->serialNumber.data == NULL){
760 hx509_set_error_string(context, 0, ret, "Out of memory");
764 RAND_bytes(tbsc->serialNumber.data, tbsc->serialNumber.length);
765 ((unsigned char *)tbsc->serialNumber.data)[0] &= 0x7f;
767 /* signature AlgorithmIdentifier, */
768 ret = copy_AlgorithmIdentifier(sigalg, &tbsc->signature);
770 hx509_set_error_string(context, 0, ret, "Failed to copy sigature alg");
775 ret = copy_Name(issuername, &tbsc->issuer);
777 ret = hx509_name_to_Name(tbs->subject, &tbsc->issuer);
779 hx509_set_error_string(context, 0, ret, "Failed to copy issuer name");
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;
788 if (tbs->flags.proxy) {
789 ret = build_proxy_prefix(context, &tbsc->issuer, &tbsc->subject);
793 ret = hx509_name_to_Name(tbs->subject, &tbsc->subject);
795 hx509_set_error_string(context, 0, ret,
796 "Failed to copy subject name");
800 /* subjectPublicKeyInfo SubjectPublicKeyInfo, */
801 ret = copy_SubjectPublicKeyInfo(&tbs->spki, &tbsc->subjectPublicKeyInfo);
803 hx509_set_error_string(context, 0, ret, "Failed to copy spki");
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) {
812 hx509_set_error_string(context, 0, ret, "Out of memory");
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"
825 ret = add_extension(context, tbsc, 0,
826 oid_id_ms_cert_enroll_domaincontroller(),
836 ku = int2KeyUsage(key_usage);
837 ASN1_MALLOC_ENCODE(KeyUsage, data.data, data.length, &ku, &size, ret);
839 hx509_set_error_string(context, 0, ret, "Out of memory");
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);
851 /* add ExtendedKeyUsage */
852 if (tbs->eku.len > 0) {
853 ASN1_MALLOC_ENCODE(ExtKeyUsage, data.data, data.length,
854 &tbs->eku, &size, ret);
856 hx509_set_error_string(context, 0, ret, "Out of memory");
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);
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);
873 hx509_set_error_string(context, 0, ret, "Out of memory");
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(),
886 /* Add Authority Key Identifier */
888 ASN1_MALLOC_ENCODE(AuthorityKeyIdentifier, data.data, data.length,
891 hx509_set_error_string(context, 0, ret, "Out of memory");
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(),
904 /* Add Subject Key Identifier */
906 SubjectKeyIdentifier si;
907 unsigned char hash[SHA_DIGEST_LENGTH];
913 SHA1_Update(&m, tbs->spki.subjectPublicKey.data,
914 tbs->spki.subjectPublicKey.length / 8);
915 SHA1_Final (hash, &m);
919 si.length = sizeof(hash);
921 ASN1_MALLOC_ENCODE(SubjectKeyIdentifier, data.data, data.length,
924 hx509_set_error_string(context, 0, ret, "Out of memory");
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(),
937 /* Add BasicConstraints */
943 memset(&bc, 0, sizeof(bc));
947 if (tbs->pathLenConstraint >= 0) {
948 path = tbs->pathLenConstraint;
949 bc.pathLenConstraint = &path;
953 ASN1_MALLOC_ENCODE(BasicConstraints, data.data, data.length,
956 hx509_set_error_string(context, 0, ret, "Out of memory");
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(),
971 if (tbs->flags.proxy) {
974 memset(&info, 0, sizeof(info));
976 if (tbs->pathLenConstraint >= 0) {
977 info.pCPathLenConstraint =
978 malloc(sizeof(*info.pCPathLenConstraint));
979 if (info.pCPathLenConstraint == NULL) {
981 hx509_set_error_string(context, 0, ret, "Out of memory");
984 *info.pCPathLenConstraint = tbs->pathLenConstraint;
987 ret = der_copy_oid(oid_id_pkix_ppl_inheritAll(),
988 &info.proxyPolicy.policyLanguage);
990 free_ProxyCertInfo(&info);
991 hx509_set_error_string(context, 0, ret, "Out of memory");
995 ASN1_MALLOC_ENCODE(ProxyCertInfo, data.data, data.length,
997 free_ProxyCertInfo(&info);
999 hx509_set_error_string(context, 0, ret, "Out of memory");
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(),
1012 if (tbs->crldp.len) {
1014 ASN1_MALLOC_ENCODE(CRLDistributionPoints, data.data, data.length,
1015 &tbs->crldp, &size, ret);
1017 hx509_set_error_string(context, 0, ret, "Out of memory");
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(),
1030 ASN1_MALLOC_ENCODE(TBSCertificate, data.data, data.length,tbsc, &size, ret);
1032 hx509_set_error_string(context, 0, ret, "malloc out of memory");
1035 if (data.length != size)
1036 _hx509_abort("internal ASN.1 encoder error");
1038 ret = _hx509_create_signature_bitstring(context,
1042 &c.signatureAlgorithm,
1048 ret = hx509_cert_init(context, &c, certificate);
1052 free_Certificate(&c);
1057 free_Certificate(&c);
1062 get_AuthorityKeyIdentifier(hx509_context context,
1063 const Certificate *certificate,
1064 AuthorityKeyIdentifier *ai)
1066 SubjectKeyIdentifier si;
1069 ret = _hx509_find_extension_subject_key_id(certificate, &si);
1071 ai->keyIdentifier = calloc(1, sizeof(*ai->keyIdentifier));
1072 if (ai->keyIdentifier == NULL) {
1073 free_SubjectKeyIdentifier(&si);
1075 hx509_set_error_string(context, 0, ret, "Out of memory");
1078 ret = der_copy_octet_string(&si, ai->keyIdentifier);
1079 free_SubjectKeyIdentifier(&si);
1081 hx509_set_error_string(context, 0, ret, "Out of memory");
1089 memset(&gn, 0, sizeof(gn));
1090 memset(&gns, 0, sizeof(gns));
1091 memset(&name, 0, sizeof(name));
1093 ai->authorityCertIssuer =
1094 calloc(1, sizeof(*ai->authorityCertIssuer));
1095 if (ai->authorityCertIssuer == NULL) {
1097 hx509_set_error_string(context, 0, ret, "Out of memory");
1100 ai->authorityCertSerialNumber =
1101 calloc(1, sizeof(*ai->authorityCertSerialNumber));
1102 if (ai->authorityCertSerialNumber == NULL) {
1104 hx509_set_error_string(context, 0, ret, "Out of memory");
1109 * XXX unbreak when asn1 compiler handle IMPLICIT
1111 * This is so horrible.
1114 ret = copy_Name(&certificate->tbsCertificate.subject, &name);
1115 if (ai->authorityCertSerialNumber == NULL) {
1117 hx509_set_error_string(context, 0, ret, "Out of memory");
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;
1127 ret = add_GeneralNames(&gns, &gn);
1129 hx509_set_error_string(context, 0, ret, "Out of memory");
1133 ai->authorityCertIssuer->val = gns.val;
1134 ai->authorityCertIssuer->len = gns.len;
1136 ret = der_copy_heim_integer(&certificate->tbsCertificate.serialNumber,
1137 ai->authorityCertSerialNumber);
1138 if (ai->authorityCertSerialNumber == NULL) {
1140 hx509_set_error_string(context, 0, ret, "Out of memory");
1146 free_AuthorityKeyIdentifier(ai);
1152 hx509_ca_sign(hx509_context context,
1155 hx509_cert *certificate)
1157 const Certificate *signer_cert;
1158 AuthorityKeyIdentifier ai;
1161 memset(&ai, 0, sizeof(ai));
1163 signer_cert = _hx509_get_cert(signer);
1165 ret = get_AuthorityKeyIdentifier(context, signer_cert, &ai);
1169 ret = ca_sign(context,
1171 _hx509_cert_private_key(signer),
1173 &signer_cert->tbsCertificate.subject,
1177 free_AuthorityKeyIdentifier(&ai);
1183 hx509_ca_sign_self(hx509_context context,
1185 hx509_private_key signer,
1186 hx509_cert *certificate)
1188 return ca_sign(context,