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>
39 * @page page_ca Hx509 CA functions
41 * See the library functions here: @ref hx509_ca
46 SubjectPublicKeyInfo spki
;
55 unsigned int serial
:1;
56 unsigned int domaincontroller
:1;
60 int pathLenConstraint
; /* both for CA and Proxy */
61 CRLDistributionPoints crldp
;
65 * Allocate an to-be-signed certificate object that will be converted
66 * into an certificate.
68 * @param context A hx509 context.
69 * @param tbs returned to-be-signed certicate object, free with
70 * hx509_ca_tbs_free().
72 * @return An hx509 error code, see hx509_get_error_string().
78 hx509_ca_tbs_init(hx509_context context
, hx509_ca_tbs
*tbs
)
80 *tbs
= calloc(1, sizeof(**tbs
));
84 (*tbs
)->subject
= NULL
;
86 (*tbs
)->san
.val
= NULL
;
88 (*tbs
)->eku
.val
= NULL
;
89 (*tbs
)->pathLenConstraint
= 0;
90 (*tbs
)->crldp
.len
= 0;
91 (*tbs
)->crldp
.val
= NULL
;
97 * Free an To Be Signed object.
99 * @param tbs object to free.
105 hx509_ca_tbs_free(hx509_ca_tbs
*tbs
)
107 if (tbs
== NULL
|| *tbs
== NULL
)
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
);
116 hx509_name_free(&(*tbs
)->subject
);
118 memset(*tbs
, 0, sizeof(**tbs
));
124 * Set the absolute time when the certificate is valid from. If not
125 * set the current time will be used.
127 * @param context A hx509 context.
128 * @param tbs object to be signed.
129 * @param t time the certificated will start to be valid
131 * @return An hx509 error code, see hx509_get_error_string().
137 hx509_ca_tbs_set_notBefore(hx509_context context
,
146 * Set the absolute time when the certificate is valid to.
148 * @param context A hx509 context.
149 * @param tbs object to be signed.
150 * @param t time when the certificate will expire
152 * @return An hx509 error code, see hx509_get_error_string().
158 hx509_ca_tbs_set_notAfter(hx509_context context
,
167 * Set the relative time when the certificiate is going to expire.
169 * @param context A hx509 context.
170 * @param tbs object to be signed.
171 * @param delta seconds to the certificate is going to expire.
173 * @return An hx509 error code, see hx509_get_error_string().
179 hx509_ca_tbs_set_notAfter_lifetime(hx509_context context
,
183 return hx509_ca_tbs_set_notAfter(context
, tbs
, time(NULL
) + delta
);
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
},
198 * Make of template units, use to build flags argument to
199 * hx509_ca_tbs_set_template() with parse_units().
201 * @return an units structure.
207 hx509_ca_tbs_template_units(void)
213 * Initialize the to-be-signed certificate object from a template certifiate.
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
219 * @param cert template certificate.
221 * @return An hx509 error code, see hx509_get_error_string().
227 hx509_ca_tbs_set_template(hx509_context context
,
234 if (flags
& HX509_CA_TEMPLATE_SUBJECT
) {
236 hx509_name_free(&tbs
->subject
);
237 ret
= hx509_cert_get_subject(cert
, &tbs
->subject
);
239 hx509_set_error_string(context
, 0, ret
,
240 "Failed to get subject from template");
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
;
249 hx509_set_error_string(context
, 0, ret
,
250 "Failed to copy serial number");
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(cert
, &tbs
->spki
);
261 tbs
->flags
.key
= !ret
;
263 hx509_set_error_string(context
, 0, ret
, "Failed to copy SPKI");
267 if (flags
& HX509_CA_TEMPLATE_KU
) {
269 ret
= _hx509_cert_get_keyusage(context
, cert
, &ku
);
272 tbs
->key_usage
= KeyUsage2int(ku
);
274 if (flags
& HX509_CA_TEMPLATE_EKU
) {
277 ret
= _hx509_cert_get_eku(context
, cert
, &eku
);
280 for (i
= 0; i
< eku
.len
; i
++) {
281 ret
= hx509_ca_tbs_add_eku(context
, tbs
, &eku
.val
[i
]);
283 free_ExtKeyUsage(&eku
);
287 free_ExtKeyUsage(&eku
);
293 * Make the to-be-signed certificate object a CA certificate. If the
294 * pathLenConstraint is negative path length constraint is used.
296 * @param context A hx509 context.
297 * @param tbs object to be signed.
298 * @param pathLenConstraint path length constraint, negative, no
301 * @return An hx509 error code, see hx509_get_error_string().
307 hx509_ca_tbs_set_ca(hx509_context context
,
309 int pathLenConstraint
)
312 tbs
->pathLenConstraint
= pathLenConstraint
;
317 * Make the to-be-signed certificate object a proxy certificate. If the
318 * pathLenConstraint is negative path length constraint is used.
320 * @param context A hx509 context.
321 * @param tbs object to be signed.
322 * @param pathLenConstraint path length constraint, negative, no
325 * @return An hx509 error code, see hx509_get_error_string().
331 hx509_ca_tbs_set_proxy(hx509_context context
,
333 int pathLenConstraint
)
335 tbs
->flags
.proxy
= 1;
336 tbs
->pathLenConstraint
= pathLenConstraint
;
342 * Make the to-be-signed certificate object a windows domain controller certificate.
344 * @param context A hx509 context.
345 * @param tbs object to be signed.
347 * @return An hx509 error code, see hx509_get_error_string().
353 hx509_ca_tbs_set_domaincontroller(hx509_context context
,
356 tbs
->flags
.domaincontroller
= 1;
361 * Set the subject public key info (SPKI) in the to-be-signed certificate
362 * object. SPKI is the public key and key related parameters in the
365 * @param context A hx509 context.
366 * @param tbs object to be signed.
367 * @param spki subject public key info to use for the to-be-signed certificate object.
369 * @return An hx509 error code, see hx509_get_error_string().
375 hx509_ca_tbs_set_spki(hx509_context context
,
377 const SubjectPublicKeyInfo
*spki
)
380 free_SubjectPublicKeyInfo(&tbs
->spki
);
381 ret
= copy_SubjectPublicKeyInfo(spki
, &tbs
->spki
);
382 tbs
->flags
.key
= !ret
;
387 * Set the serial number to use for to-be-signed certificate object.
389 * @param context A hx509 context.
390 * @param tbs object to be signed.
391 * @param serialNumber serial number to use for the to-be-signed
392 * certificate object.
394 * @return An hx509 error code, see hx509_get_error_string().
400 hx509_ca_tbs_set_serialnumber(hx509_context context
,
402 const heim_integer
*serialNumber
)
405 der_free_heim_integer(&tbs
->serial
);
406 ret
= der_copy_heim_integer(serialNumber
, &tbs
->serial
);
407 tbs
->flags
.serial
= !ret
;
412 * An an extended key usage to the to-be-signed certificate object.
413 * Duplicates will detected and not added.
415 * @param context A hx509 context.
416 * @param tbs object to be signed.
417 * @param oid extended key usage to add.
419 * @return An hx509 error code, see hx509_get_error_string().
425 hx509_ca_tbs_add_eku(hx509_context context
,
433 /* search for duplicates */
434 for (i
= 0; i
< tbs
->eku
.len
; i
++) {
435 if (der_heim_oid_cmp(oid
, &tbs
->eku
.val
[i
]) == 0)
439 ptr
= realloc(tbs
->eku
.val
, sizeof(tbs
->eku
.val
[0]) * (tbs
->eku
.len
+ 1));
441 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
445 ret
= der_copy_oid(oid
, &tbs
->eku
.val
[tbs
->eku
.len
]);
447 hx509_set_error_string(context
, 0, ret
, "out of memory");
455 * Add CRL distribution point URI to the to-be-signed certificate
458 * @param context A hx509 context.
459 * @param tbs object to be signed.
460 * @param uri uri to the CRL.
461 * @param issuername name of the issuer.
463 * @return An hx509 error code, see hx509_get_error_string().
469 hx509_ca_tbs_add_crl_dp_uri(hx509_context context
,
472 hx509_name issuername
)
474 DistributionPoint dp
;
477 memset(&dp
, 0, sizeof(dp
));
479 dp
.distributionPoint
= ecalloc(1, sizeof(*dp
.distributionPoint
));
482 DistributionPointName name
;
486 name
.element
= choice_DistributionPointName_fullName
;
487 name
.u
.fullName
.len
= 1;
488 name
.u
.fullName
.val
= &gn
;
490 gn
.element
= choice_GeneralName_uniformResourceIdentifier
;
491 gn
.u
.uniformResourceIdentifier
= rk_UNCONST(uri
);
493 ASN1_MALLOC_ENCODE(DistributionPointName
,
494 dp
.distributionPoint
->data
,
495 dp
.distributionPoint
->length
,
498 hx509_set_error_string(context
, 0, ret
,
499 "Failed to encoded DistributionPointName");
502 if (dp
.distributionPoint
->length
!= size
)
503 _hx509_abort("internal ASN.1 encoder error");
509 * issuername not supported
511 hx509_set_error_string(context
, 0, EINVAL
,
512 "CRLDistributionPoints.name.issuername not yet supported");
515 GeneralNames
*crlissuer
;
519 crlissuer
= calloc(1, sizeof(*crlissuer
));
520 if (crlissuer
== NULL
) {
523 memset(&gn
, 0, sizeof(gn
));
525 gn
.element
= choice_GeneralName_directoryName
;
526 ret
= hx509_name_to_Name(issuername
, &n
);
528 hx509_set_error_string(context
, 0, ret
, "out of memory");
532 gn
.u
.directoryName
.element
= n
.element
;
533 gn
.u
.directoryName
.u
.rdnSequence
= n
.u
.rdnSequence
;
535 ret
= add_GeneralNames(&crlissuer
, &gn
);
538 hx509_set_error_string(context
, 0, ret
, "out of memory");
542 dp
.cRLIssuer
= &crlissuer
;
546 ret
= add_CRLDistributionPoints(&tbs
->crldp
, &dp
);
548 hx509_set_error_string(context
, 0, ret
, "out of memory");
553 free_DistributionPoint(&dp
);
559 * Add Subject Alternative Name otherName to the to-be-signed
560 * certificate object.
562 * @param context A hx509 context.
563 * @param tbs object to be signed.
564 * @param oid the oid of the OtherName.
565 * @param os data in the other name.
567 * @return An hx509 error code, see hx509_get_error_string().
573 hx509_ca_tbs_add_san_otherName(hx509_context context
,
576 const heim_octet_string
*os
)
580 memset(&gn
, 0, sizeof(gn
));
581 gn
.element
= choice_GeneralName_otherName
;
582 gn
.u
.otherName
.type_id
= *oid
;
583 gn
.u
.otherName
.value
= *os
;
585 return add_GeneralNames(&tbs
->san
, &gn
);
589 * Add Kerberos Subject Alternative Name to the to-be-signed
590 * certificate object. The principal string is a UTF8 string.
592 * @param context A hx509 context.
593 * @param tbs object to be signed.
594 * @param principal Kerberos principal to add to the certificate.
596 * @return An hx509 error code, see hx509_get_error_string().
602 hx509_ca_tbs_add_san_pkinit(hx509_context context
,
604 const char *principal
)
606 heim_octet_string os
;
612 memset(&p
, 0, sizeof(p
));
614 /* parse principal */
620 /* count number of component */
622 for(str
= principal
; *str
!= '\0' && *str
!= '@'; str
++){
624 if(str
[1] == '\0' || str
[1] == '@') {
625 ret
= HX509_PARSING_NAME_FAILED
;
626 hx509_set_error_string(context
, 0, ret
,
627 "trailing \\ in principal name");
631 } else if(*str
== '/')
634 p
.principalName
.name_string
.val
=
635 calloc(n
, sizeof(*p
.principalName
.name_string
.val
));
636 if (p
.principalName
.name_string
.val
== NULL
) {
638 hx509_set_error_string(context
, 0, ret
, "malloc: out of memory");
641 p
.principalName
.name_string
.len
= n
;
643 p
.principalName
.name_type
= KRB5_NT_PRINCIPAL
;
644 q
= s
= strdup(principal
);
647 hx509_set_error_string(context
, 0, ret
, "malloc: out of memory");
650 p
.realm
= strrchr(q
, '@');
651 if (p
.realm
== NULL
) {
652 ret
= HX509_PARSING_NAME_FAILED
;
653 hx509_set_error_string(context
, 0, ret
, "Missing @ in principal");
660 p
.principalName
.name_string
.val
[n
++] = q
;
667 ASN1_MALLOC_ENCODE(KRB5PrincipalName
, os
.data
, os
.length
, &p
, &size
, ret
);
669 hx509_set_error_string(context
, 0, ret
, "Out of memory");
672 if (size
!= os
.length
)
673 _hx509_abort("internal ASN.1 encoder error");
675 ret
= hx509_ca_tbs_add_san_otherName(context
,
681 if (p
.principalName
.name_string
.val
)
682 free (p
.principalName
.name_string
.val
);
693 add_utf8_san(hx509_context context
,
698 const PKIXXmppAddr ustring
= (const PKIXXmppAddr
)string
;
699 heim_octet_string os
;
706 ASN1_MALLOC_ENCODE(PKIXXmppAddr
, os
.data
, os
.length
, &ustring
, &size
, ret
);
708 hx509_set_error_string(context
, 0, ret
, "Out of memory");
711 if (size
!= os
.length
)
712 _hx509_abort("internal ASN.1 encoder error");
714 ret
= hx509_ca_tbs_add_san_otherName(context
,
724 * Add Microsoft UPN Subject Alternative Name to the to-be-signed
725 * certificate object. The principal string is a UTF8 string.
727 * @param context A hx509 context.
728 * @param tbs object to be signed.
729 * @param principal Microsoft UPN string.
731 * @return An hx509 error code, see hx509_get_error_string().
737 hx509_ca_tbs_add_san_ms_upn(hx509_context context
,
739 const char *principal
)
741 return add_utf8_san(context
, tbs
, oid_id_pkinit_ms_san(), principal
);
745 * Add a Jabber/XMPP jid Subject Alternative Name to the to-be-signed
746 * certificate object. The jid is an UTF8 string.
748 * @param context A hx509 context.
749 * @param tbs object to be signed.
750 * @param jid string of an a jabber id in UTF8.
752 * @return An hx509 error code, see hx509_get_error_string().
758 hx509_ca_tbs_add_san_jid(hx509_context context
,
762 return add_utf8_san(context
, tbs
, oid_id_pkix_on_xmppAddr(), jid
);
767 * Add a Subject Alternative Name hostname to to-be-signed certificate
768 * object. A domain match starts with ., an exact match does not.
770 * Example of a an domain match: .domain.se matches the hostname
773 * @param context A hx509 context.
774 * @param tbs object to be signed.
775 * @param dnsname a hostame.
777 * @return An hx509 error code, see hx509_get_error_string().
783 hx509_ca_tbs_add_san_hostname(hx509_context context
,
789 memset(&gn
, 0, sizeof(gn
));
790 gn
.element
= choice_GeneralName_dNSName
;
791 gn
.u
.dNSName
= rk_UNCONST(dnsname
);
793 return add_GeneralNames(&tbs
->san
, &gn
);
797 * Add a Subject Alternative Name rfc822 (email address) to
798 * to-be-signed certificate object.
800 * @param context A hx509 context.
801 * @param tbs object to be signed.
802 * @param rfc822Name a string to a email address.
804 * @return An hx509 error code, see hx509_get_error_string().
810 hx509_ca_tbs_add_san_rfc822name(hx509_context context
,
812 const char *rfc822Name
)
816 memset(&gn
, 0, sizeof(gn
));
817 gn
.element
= choice_GeneralName_rfc822Name
;
818 gn
.u
.rfc822Name
= rk_UNCONST(rfc822Name
);
820 return add_GeneralNames(&tbs
->san
, &gn
);
824 * Set the subject name of a to-be-signed certificate object.
826 * @param context A hx509 context.
827 * @param tbs object to be signed.
828 * @param subject the name to set a subject.
830 * @return An hx509 error code, see hx509_get_error_string().
836 hx509_ca_tbs_set_subject(hx509_context context
,
841 hx509_name_free(&tbs
->subject
);
842 return hx509_name_copy(context
, subject
, &tbs
->subject
);
846 * Expand the the subject name in the to-be-signed certificate object
847 * using hx509_name_expand().
849 * @param context A hx509 context.
850 * @param tbs object to be signed.
851 * @param env enviroment variable to expand variables in the subject
852 * name, see hx509_env_init().
854 * @return An hx509 error code, see hx509_get_error_string().
860 hx509_ca_tbs_subject_expand(hx509_context context
,
864 return hx509_name_expand(context
, tbs
->subject
, env
);
868 add_extension(hx509_context context
,
869 TBSCertificate
*tbsc
,
872 const heim_octet_string
*data
)
877 memset(&ext
, 0, sizeof(ext
));
880 ext
.critical
= malloc(sizeof(*ext
.critical
));
881 if (ext
.critical
== NULL
) {
883 hx509_set_error_string(context
, 0, ret
, "Out of memory");
886 *ext
.critical
= TRUE
;
889 ret
= der_copy_oid(oid
, &ext
.extnID
);
891 hx509_set_error_string(context
, 0, ret
, "Out of memory");
894 ret
= der_copy_octet_string(data
, &ext
.extnValue
);
896 hx509_set_error_string(context
, 0, ret
, "Out of memory");
899 ret
= add_Extensions(tbsc
->extensions
, &ext
);
901 hx509_set_error_string(context
, 0, ret
, "Out of memory");
905 free_Extension(&ext
);
910 build_proxy_prefix(hx509_context context
, const Name
*issuer
, Name
*subject
)
916 ret
= copy_Name(issuer
, subject
);
918 hx509_set_error_string(context
, 0, ret
,
919 "Failed to copy subject name");
924 asprintf(&tstr
, "ts-%lu", (unsigned long)t
);
926 hx509_set_error_string(context
, 0, ENOMEM
,
927 "Failed to copy subject name");
930 /* prefix with CN=<ts>,...*/
931 ret
= _hx509_name_modify(context
, subject
, 1, oid_id_at_commonName(), tstr
);
939 ca_sign(hx509_context context
,
941 hx509_private_key signer
,
942 const AuthorityKeyIdentifier
*ai
,
943 const Name
*issuername
,
944 hx509_cert
*certificate
)
946 heim_octet_string data
;
948 TBSCertificate
*tbsc
;
951 const AlgorithmIdentifier
*sigalg
;
956 sigalg
= _hx509_crypto_default_sig_alg
;
958 memset(&c
, 0, sizeof(c
));
961 * Default values are: Valid since 24h ago, valid one year into
962 * the future, KeyUsage digitalSignature and keyEncipherment set,
963 * and keyCertSign for CA certificates.
965 notBefore
= tbs
->notBefore
;
967 notBefore
= time(NULL
) - 3600 * 24;
968 notAfter
= tbs
->notAfter
;
970 notAfter
= time(NULL
) + 3600 * 24 * 365;
972 key_usage
= tbs
->key_usage
;
973 if (key_usage
== 0) {
975 memset(&ku
, 0, sizeof(ku
));
976 ku
.digitalSignature
= 1;
977 ku
.keyEncipherment
= 1;
978 key_usage
= KeyUsage2int(ku
);
983 memset(&ku
, 0, sizeof(ku
));
986 key_usage
|= KeyUsage2int(ku
);
993 tbsc
= &c
.tbsCertificate
;
995 if (tbs
->flags
.key
== 0) {
997 hx509_set_error_string(context
, 0, ret
, "No public key set");
1001 * Don't put restrictions on proxy certificate's subject name, it
1002 * will be generated below.
1004 if (!tbs
->flags
.proxy
) {
1005 if (tbs
->subject
== NULL
) {
1006 hx509_set_error_string(context
, 0, EINVAL
, "No subject name set");
1009 if (hx509_name_is_null_p(tbs
->subject
) && tbs
->san
.len
== 0) {
1010 hx509_set_error_string(context
, 0, EINVAL
,
1011 "NULL subject and no SubjectAltNames");
1015 if (tbs
->flags
.ca
&& tbs
->flags
.proxy
) {
1016 hx509_set_error_string(context
, 0, EINVAL
, "Can't be proxy and CA "
1017 "at the same time");
1020 if (tbs
->flags
.proxy
) {
1021 if (tbs
->san
.len
> 0) {
1022 hx509_set_error_string(context
, 0, EINVAL
,
1023 "Proxy certificate is not allowed "
1024 "to have SubjectAltNames");
1029 /* version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1, */
1030 tbsc
->version
= calloc(1, sizeof(*tbsc
->version
));
1031 if (tbsc
->version
== NULL
) {
1033 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1036 *tbsc
->version
= rfc3280_version_3
;
1037 /* serialNumber CertificateSerialNumber, */
1038 if (tbs
->flags
.serial
) {
1039 ret
= der_copy_heim_integer(&tbs
->serial
, &tbsc
->serialNumber
);
1041 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1045 tbsc
->serialNumber
.length
= 20;
1046 tbsc
->serialNumber
.data
= malloc(tbsc
->serialNumber
.length
);
1047 if (tbsc
->serialNumber
.data
== NULL
){
1049 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1053 RAND_bytes(tbsc
->serialNumber
.data
, tbsc
->serialNumber
.length
);
1054 ((unsigned char *)tbsc
->serialNumber
.data
)[0] &= 0x7f;
1056 /* signature AlgorithmIdentifier, */
1057 ret
= copy_AlgorithmIdentifier(sigalg
, &tbsc
->signature
);
1059 hx509_set_error_string(context
, 0, ret
, "Failed to copy sigature alg");
1064 ret
= copy_Name(issuername
, &tbsc
->issuer
);
1066 ret
= hx509_name_to_Name(tbs
->subject
, &tbsc
->issuer
);
1068 hx509_set_error_string(context
, 0, ret
, "Failed to copy issuer name");
1071 /* validity Validity, */
1072 tbsc
->validity
.notBefore
.element
= choice_Time_generalTime
;
1073 tbsc
->validity
.notBefore
.u
.generalTime
= notBefore
;
1074 tbsc
->validity
.notAfter
.element
= choice_Time_generalTime
;
1075 tbsc
->validity
.notAfter
.u
.generalTime
= notAfter
;
1077 if (tbs
->flags
.proxy
) {
1078 ret
= build_proxy_prefix(context
, &tbsc
->issuer
, &tbsc
->subject
);
1082 ret
= hx509_name_to_Name(tbs
->subject
, &tbsc
->subject
);
1084 hx509_set_error_string(context
, 0, ret
,
1085 "Failed to copy subject name");
1089 /* subjectPublicKeyInfo SubjectPublicKeyInfo, */
1090 ret
= copy_SubjectPublicKeyInfo(&tbs
->spki
, &tbsc
->subjectPublicKeyInfo
);
1092 hx509_set_error_string(context
, 0, ret
, "Failed to copy spki");
1095 /* issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL */
1096 /* subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL */
1097 /* extensions [3] EXPLICIT Extensions OPTIONAL */
1098 tbsc
->extensions
= calloc(1, sizeof(*tbsc
->extensions
));
1099 if (tbsc
->extensions
== NULL
) {
1101 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1105 /* Add the text BMP string Domaincontroller to the cert */
1106 if (tbs
->flags
.domaincontroller
) {
1107 data
.data
= rk_UNCONST("\x1e\x20\x00\x44\x00\x6f\x00\x6d"
1108 "\x00\x61\x00\x69\x00\x6e\x00\x43"
1109 "\x00\x6f\x00\x6e\x00\x74\x00\x72"
1110 "\x00\x6f\x00\x6c\x00\x6c\x00\x65"
1114 ret
= add_extension(context
, tbsc
, 0,
1115 oid_id_ms_cert_enroll_domaincontroller(),
1125 ku
= int2KeyUsage(key_usage
);
1126 ASN1_MALLOC_ENCODE(KeyUsage
, data
.data
, data
.length
, &ku
, &size
, ret
);
1128 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1131 if (size
!= data
.length
)
1132 _hx509_abort("internal ASN.1 encoder error");
1133 ret
= add_extension(context
, tbsc
, 1,
1134 oid_id_x509_ce_keyUsage(), &data
);
1140 /* add ExtendedKeyUsage */
1141 if (tbs
->eku
.len
> 0) {
1142 ASN1_MALLOC_ENCODE(ExtKeyUsage
, data
.data
, data
.length
,
1143 &tbs
->eku
, &size
, ret
);
1145 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1148 if (size
!= data
.length
)
1149 _hx509_abort("internal ASN.1 encoder error");
1150 ret
= add_extension(context
, tbsc
, 0,
1151 oid_id_x509_ce_extKeyUsage(), &data
);
1157 /* add Subject Alternative Name */
1158 if (tbs
->san
.len
> 0) {
1159 ASN1_MALLOC_ENCODE(GeneralNames
, data
.data
, data
.length
,
1160 &tbs
->san
, &size
, ret
);
1162 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1165 if (size
!= data
.length
)
1166 _hx509_abort("internal ASN.1 encoder error");
1167 ret
= add_extension(context
, tbsc
, 0,
1168 oid_id_x509_ce_subjectAltName(),
1175 /* Add Authority Key Identifier */
1177 ASN1_MALLOC_ENCODE(AuthorityKeyIdentifier
, data
.data
, data
.length
,
1180 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1183 if (size
!= data
.length
)
1184 _hx509_abort("internal ASN.1 encoder error");
1185 ret
= add_extension(context
, tbsc
, 0,
1186 oid_id_x509_ce_authorityKeyIdentifier(),
1193 /* Add Subject Key Identifier */
1195 SubjectKeyIdentifier si
;
1196 unsigned char hash
[SHA_DIGEST_LENGTH
];
1202 SHA1_Update(&m
, tbs
->spki
.subjectPublicKey
.data
,
1203 tbs
->spki
.subjectPublicKey
.length
/ 8);
1204 SHA1_Final (hash
, &m
);
1208 si
.length
= sizeof(hash
);
1210 ASN1_MALLOC_ENCODE(SubjectKeyIdentifier
, data
.data
, data
.length
,
1213 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1216 if (size
!= data
.length
)
1217 _hx509_abort("internal ASN.1 encoder error");
1218 ret
= add_extension(context
, tbsc
, 0,
1219 oid_id_x509_ce_subjectKeyIdentifier(),
1226 /* Add BasicConstraints */
1228 BasicConstraints bc
;
1232 memset(&bc
, 0, sizeof(bc
));
1234 if (tbs
->flags
.ca
) {
1236 if (tbs
->pathLenConstraint
>= 0) {
1237 path
= tbs
->pathLenConstraint
;
1238 bc
.pathLenConstraint
= &path
;
1242 ASN1_MALLOC_ENCODE(BasicConstraints
, data
.data
, data
.length
,
1245 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1248 if (size
!= data
.length
)
1249 _hx509_abort("internal ASN.1 encoder error");
1250 /* Critical if this is a CA */
1251 ret
= add_extension(context
, tbsc
, tbs
->flags
.ca
,
1252 oid_id_x509_ce_basicConstraints(),
1260 if (tbs
->flags
.proxy
) {
1263 memset(&info
, 0, sizeof(info
));
1265 if (tbs
->pathLenConstraint
>= 0) {
1266 info
.pCPathLenConstraint
=
1267 malloc(sizeof(*info
.pCPathLenConstraint
));
1268 if (info
.pCPathLenConstraint
== NULL
) {
1270 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1273 *info
.pCPathLenConstraint
= tbs
->pathLenConstraint
;
1276 ret
= der_copy_oid(oid_id_pkix_ppl_inheritAll(),
1277 &info
.proxyPolicy
.policyLanguage
);
1279 free_ProxyCertInfo(&info
);
1280 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1284 ASN1_MALLOC_ENCODE(ProxyCertInfo
, data
.data
, data
.length
,
1286 free_ProxyCertInfo(&info
);
1288 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1291 if (size
!= data
.length
)
1292 _hx509_abort("internal ASN.1 encoder error");
1293 ret
= add_extension(context
, tbsc
, 0,
1294 oid_id_pkix_pe_proxyCertInfo(),
1301 if (tbs
->crldp
.len
) {
1303 ASN1_MALLOC_ENCODE(CRLDistributionPoints
, data
.data
, data
.length
,
1304 &tbs
->crldp
, &size
, ret
);
1306 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1309 if (size
!= data
.length
)
1310 _hx509_abort("internal ASN.1 encoder error");
1311 ret
= add_extension(context
, tbsc
, FALSE
,
1312 oid_id_x509_ce_cRLDistributionPoints(),
1319 ASN1_MALLOC_ENCODE(TBSCertificate
, data
.data
, data
.length
,tbsc
, &size
, ret
);
1321 hx509_set_error_string(context
, 0, ret
, "malloc out of memory");
1324 if (data
.length
!= size
)
1325 _hx509_abort("internal ASN.1 encoder error");
1327 ret
= _hx509_create_signature_bitstring(context
,
1331 &c
.signatureAlgorithm
,
1337 ret
= hx509_cert_init(context
, &c
, certificate
);
1341 free_Certificate(&c
);
1346 free_Certificate(&c
);
1351 get_AuthorityKeyIdentifier(hx509_context context
,
1352 const Certificate
*certificate
,
1353 AuthorityKeyIdentifier
*ai
)
1355 SubjectKeyIdentifier si
;
1358 ret
= _hx509_find_extension_subject_key_id(certificate
, &si
);
1360 ai
->keyIdentifier
= calloc(1, sizeof(*ai
->keyIdentifier
));
1361 if (ai
->keyIdentifier
== NULL
) {
1362 free_SubjectKeyIdentifier(&si
);
1364 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1367 ret
= der_copy_octet_string(&si
, ai
->keyIdentifier
);
1368 free_SubjectKeyIdentifier(&si
);
1370 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1378 memset(&gn
, 0, sizeof(gn
));
1379 memset(&gns
, 0, sizeof(gns
));
1380 memset(&name
, 0, sizeof(name
));
1382 ai
->authorityCertIssuer
=
1383 calloc(1, sizeof(*ai
->authorityCertIssuer
));
1384 if (ai
->authorityCertIssuer
== NULL
) {
1386 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1389 ai
->authorityCertSerialNumber
=
1390 calloc(1, sizeof(*ai
->authorityCertSerialNumber
));
1391 if (ai
->authorityCertSerialNumber
== NULL
) {
1393 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1398 * XXX unbreak when asn1 compiler handle IMPLICIT
1400 * This is so horrible.
1403 ret
= copy_Name(&certificate
->tbsCertificate
.subject
, &name
);
1404 if (ai
->authorityCertSerialNumber
== NULL
) {
1406 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1410 memset(&gn
, 0, sizeof(gn
));
1411 gn
.element
= choice_GeneralName_directoryName
;
1412 gn
.u
.directoryName
.element
=
1413 choice_GeneralName_directoryName_rdnSequence
;
1414 gn
.u
.directoryName
.u
.rdnSequence
= name
.u
.rdnSequence
;
1416 ret
= add_GeneralNames(&gns
, &gn
);
1418 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1422 ai
->authorityCertIssuer
->val
= gns
.val
;
1423 ai
->authorityCertIssuer
->len
= gns
.len
;
1425 ret
= der_copy_heim_integer(&certificate
->tbsCertificate
.serialNumber
,
1426 ai
->authorityCertSerialNumber
);
1427 if (ai
->authorityCertSerialNumber
== NULL
) {
1429 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1435 free_AuthorityKeyIdentifier(ai
);
1441 * Sign a to-be-signed certificate object with a issuer certificate.
1443 * The caller needs to at least have called the following functions on the
1444 * to-be-signed certificate object:
1445 * - hx509_ca_tbs_init()
1446 * - hx509_ca_tbs_set_subject()
1447 * - hx509_ca_tbs_set_spki()
1449 * When done the to-be-signed certificate object should be freed with
1450 * hx509_ca_tbs_free().
1452 * When creating self-signed certificate use hx509_ca_sign_self() instead.
1454 * @param context A hx509 context.
1455 * @param tbs object to be signed.
1456 * @param signer the CA certificate object to sign with (need private key).
1457 * @param certificate return cerificate, free with hx509_cert_free().
1459 * @return An hx509 error code, see hx509_get_error_string().
1465 hx509_ca_sign(hx509_context context
,
1468 hx509_cert
*certificate
)
1470 const Certificate
*signer_cert
;
1471 AuthorityKeyIdentifier ai
;
1474 memset(&ai
, 0, sizeof(ai
));
1476 signer_cert
= _hx509_get_cert(signer
);
1478 ret
= get_AuthorityKeyIdentifier(context
, signer_cert
, &ai
);
1482 ret
= ca_sign(context
,
1484 _hx509_cert_private_key(signer
),
1486 &signer_cert
->tbsCertificate
.subject
,
1490 free_AuthorityKeyIdentifier(&ai
);
1496 * Work just like hx509_ca_sign() but signs it-self.
1498 * @param context A hx509 context.
1499 * @param tbs object to be signed.
1500 * @param signer private key to sign with.
1501 * @param certificate return cerificate, free with hx509_cert_free().
1503 * @return An hx509 error code, see hx509_get_error_string().
1509 hx509_ca_sign_self(hx509_context context
,
1511 hx509_private_key signer
,
1512 hx509_cert
*certificate
)
1514 return ca_sign(context
,