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>
38 * @page page_ca Hx509 CA functions
40 * See the library functions here: @ref hx509_ca
45 SubjectPublicKeyInfo spki
;
54 unsigned int serial
:1;
55 unsigned int domaincontroller
:1;
59 int pathLenConstraint
; /* both for CA and Proxy */
60 CRLDistributionPoints crldp
;
64 * Allocate an to-be-signed certificate object that will be converted
65 * into an certificate.
67 * @param context A hx509 context.
68 * @param tbs returned to-be-signed certicate object, free with
69 * hx509_ca_tbs_free().
71 * @return An hx509 error code, see hx509_get_error_string().
77 hx509_ca_tbs_init(hx509_context context
, hx509_ca_tbs
*tbs
)
79 *tbs
= calloc(1, sizeof(**tbs
));
83 (*tbs
)->subject
= NULL
;
85 (*tbs
)->san
.val
= NULL
;
87 (*tbs
)->eku
.val
= NULL
;
88 (*tbs
)->pathLenConstraint
= 0;
89 (*tbs
)->crldp
.len
= 0;
90 (*tbs
)->crldp
.val
= NULL
;
96 * Free an To Be Signed object.
98 * @param tbs object to free.
104 hx509_ca_tbs_free(hx509_ca_tbs
*tbs
)
106 if (tbs
== NULL
|| *tbs
== NULL
)
109 free_SubjectPublicKeyInfo(&(*tbs
)->spki
);
110 free_GeneralNames(&(*tbs
)->san
);
111 free_ExtKeyUsage(&(*tbs
)->eku
);
112 der_free_heim_integer(&(*tbs
)->serial
);
113 free_CRLDistributionPoints(&(*tbs
)->crldp
);
115 hx509_name_free(&(*tbs
)->subject
);
117 memset(*tbs
, 0, sizeof(**tbs
));
123 * Set the absolute time when the certificate is valid from. If not
124 * set the current time will be used.
126 * @param context A hx509 context.
127 * @param tbs object to be signed.
128 * @param t time the certificated will start to be valid
130 * @return An hx509 error code, see hx509_get_error_string().
136 hx509_ca_tbs_set_notBefore(hx509_context context
,
145 * Set the absolute time when the certificate is valid to.
147 * @param context A hx509 context.
148 * @param tbs object to be signed.
149 * @param t time when the certificate will expire
151 * @return An hx509 error code, see hx509_get_error_string().
157 hx509_ca_tbs_set_notAfter(hx509_context context
,
166 * Set the relative time when the certificiate is going to expire.
168 * @param context A hx509 context.
169 * @param tbs object to be signed.
170 * @param delta seconds to the certificate is going to expire.
172 * @return An hx509 error code, see hx509_get_error_string().
178 hx509_ca_tbs_set_notAfter_lifetime(hx509_context context
,
182 return hx509_ca_tbs_set_notAfter(context
, tbs
, time(NULL
) + delta
);
185 static const struct units templatebits
[] = {
186 { "ExtendedKeyUsage", HX509_CA_TEMPLATE_EKU
},
187 { "KeyUsage", HX509_CA_TEMPLATE_KU
},
188 { "SPKI", HX509_CA_TEMPLATE_SPKI
},
189 { "notAfter", HX509_CA_TEMPLATE_NOTAFTER
},
190 { "notBefore", HX509_CA_TEMPLATE_NOTBEFORE
},
191 { "serial", HX509_CA_TEMPLATE_SERIAL
},
192 { "subject", HX509_CA_TEMPLATE_SUBJECT
},
197 * Make of template units, use to build flags argument to
198 * hx509_ca_tbs_set_template() with parse_units().
200 * @return an units structure.
206 hx509_ca_tbs_template_units(void)
212 * Initialize the to-be-signed certificate object from a template certifiate.
214 * @param context A hx509 context.
215 * @param tbs object to be signed.
216 * @param flags bit field selecting what to copy from the template
218 * @param cert template certificate.
220 * @return An hx509 error code, see hx509_get_error_string().
226 hx509_ca_tbs_set_template(hx509_context context
,
233 if (flags
& HX509_CA_TEMPLATE_SUBJECT
) {
235 hx509_name_free(&tbs
->subject
);
236 ret
= hx509_cert_get_subject(cert
, &tbs
->subject
);
238 hx509_set_error_string(context
, 0, ret
,
239 "Failed to get subject from template");
243 if (flags
& HX509_CA_TEMPLATE_SERIAL
) {
244 der_free_heim_integer(&tbs
->serial
);
245 ret
= hx509_cert_get_serialnumber(cert
, &tbs
->serial
);
246 tbs
->flags
.serial
= !ret
;
248 hx509_set_error_string(context
, 0, ret
,
249 "Failed to copy serial number");
253 if (flags
& HX509_CA_TEMPLATE_NOTBEFORE
)
254 tbs
->notBefore
= hx509_cert_get_notBefore(cert
);
255 if (flags
& HX509_CA_TEMPLATE_NOTAFTER
)
256 tbs
->notAfter
= hx509_cert_get_notAfter(cert
);
257 if (flags
& HX509_CA_TEMPLATE_SPKI
) {
258 free_SubjectPublicKeyInfo(&tbs
->spki
);
259 ret
= hx509_cert_get_SPKI(context
, cert
, &tbs
->spki
);
260 tbs
->flags
.key
= !ret
;
264 if (flags
& HX509_CA_TEMPLATE_KU
) {
266 ret
= _hx509_cert_get_keyusage(context
, cert
, &ku
);
269 tbs
->key_usage
= KeyUsage2int(ku
);
271 if (flags
& HX509_CA_TEMPLATE_EKU
) {
274 ret
= _hx509_cert_get_eku(context
, cert
, &eku
);
277 for (i
= 0; i
< eku
.len
; i
++) {
278 ret
= hx509_ca_tbs_add_eku(context
, tbs
, &eku
.val
[i
]);
280 free_ExtKeyUsage(&eku
);
284 free_ExtKeyUsage(&eku
);
290 * Make the to-be-signed certificate object a CA certificate. If the
291 * pathLenConstraint is negative path length constraint is used.
293 * @param context A hx509 context.
294 * @param tbs object to be signed.
295 * @param pathLenConstraint path length constraint, negative, no
298 * @return An hx509 error code, see hx509_get_error_string().
304 hx509_ca_tbs_set_ca(hx509_context context
,
306 int pathLenConstraint
)
309 tbs
->pathLenConstraint
= pathLenConstraint
;
314 * Make the to-be-signed certificate object a proxy certificate. If the
315 * pathLenConstraint is negative path length constraint is used.
317 * @param context A hx509 context.
318 * @param tbs object to be signed.
319 * @param pathLenConstraint path length constraint, negative, no
322 * @return An hx509 error code, see hx509_get_error_string().
328 hx509_ca_tbs_set_proxy(hx509_context context
,
330 int pathLenConstraint
)
332 tbs
->flags
.proxy
= 1;
333 tbs
->pathLenConstraint
= pathLenConstraint
;
339 * Make the to-be-signed certificate object a windows domain controller certificate.
341 * @param context A hx509 context.
342 * @param tbs object to be signed.
344 * @return An hx509 error code, see hx509_get_error_string().
350 hx509_ca_tbs_set_domaincontroller(hx509_context context
,
353 tbs
->flags
.domaincontroller
= 1;
358 * Set the subject public key info (SPKI) in the to-be-signed certificate
359 * object. SPKI is the public key and key related parameters in the
362 * @param context A hx509 context.
363 * @param tbs object to be signed.
364 * @param spki subject public key info to use for the to-be-signed certificate object.
366 * @return An hx509 error code, see hx509_get_error_string().
372 hx509_ca_tbs_set_spki(hx509_context context
,
374 const SubjectPublicKeyInfo
*spki
)
377 free_SubjectPublicKeyInfo(&tbs
->spki
);
378 ret
= copy_SubjectPublicKeyInfo(spki
, &tbs
->spki
);
379 tbs
->flags
.key
= !ret
;
384 * Set the serial number to use for to-be-signed certificate object.
386 * @param context A hx509 context.
387 * @param tbs object to be signed.
388 * @param serialNumber serial number to use for the to-be-signed
389 * certificate object.
391 * @return An hx509 error code, see hx509_get_error_string().
397 hx509_ca_tbs_set_serialnumber(hx509_context context
,
399 const heim_integer
*serialNumber
)
402 der_free_heim_integer(&tbs
->serial
);
403 ret
= der_copy_heim_integer(serialNumber
, &tbs
->serial
);
404 tbs
->flags
.serial
= !ret
;
409 * An an extended key usage to the to-be-signed certificate object.
410 * Duplicates will detected and not added.
412 * @param context A hx509 context.
413 * @param tbs object to be signed.
414 * @param oid extended key usage to add.
416 * @return An hx509 error code, see hx509_get_error_string().
422 hx509_ca_tbs_add_eku(hx509_context context
,
430 /* search for duplicates */
431 for (i
= 0; i
< tbs
->eku
.len
; i
++) {
432 if (der_heim_oid_cmp(oid
, &tbs
->eku
.val
[i
]) == 0)
436 ptr
= realloc(tbs
->eku
.val
, sizeof(tbs
->eku
.val
[0]) * (tbs
->eku
.len
+ 1));
438 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
442 ret
= der_copy_oid(oid
, &tbs
->eku
.val
[tbs
->eku
.len
]);
444 hx509_set_error_string(context
, 0, ret
, "out of memory");
452 * Add CRL distribution point URI to the to-be-signed certificate
455 * @param context A hx509 context.
456 * @param tbs object to be signed.
457 * @param uri uri to the CRL.
458 * @param issuername name of the issuer.
460 * @return An hx509 error code, see hx509_get_error_string().
466 hx509_ca_tbs_add_crl_dp_uri(hx509_context context
,
469 hx509_name issuername
)
471 DistributionPoint dp
;
474 memset(&dp
, 0, sizeof(dp
));
476 dp
.distributionPoint
= ecalloc(1, sizeof(*dp
.distributionPoint
));
479 DistributionPointName name
;
483 name
.element
= choice_DistributionPointName_fullName
;
484 name
.u
.fullName
.len
= 1;
485 name
.u
.fullName
.val
= &gn
;
487 gn
.element
= choice_GeneralName_uniformResourceIdentifier
;
488 gn
.u
.uniformResourceIdentifier
= rk_UNCONST(uri
);
490 ASN1_MALLOC_ENCODE(DistributionPointName
,
491 dp
.distributionPoint
->data
,
492 dp
.distributionPoint
->length
,
495 hx509_set_error_string(context
, 0, ret
,
496 "Failed to encoded DistributionPointName");
499 if (dp
.distributionPoint
->length
!= size
)
500 _hx509_abort("internal ASN.1 encoder error");
506 * issuername not supported
508 hx509_set_error_string(context
, 0, EINVAL
,
509 "CRLDistributionPoints.name.issuername not yet supported");
512 GeneralNames
*crlissuer
;
516 crlissuer
= calloc(1, sizeof(*crlissuer
));
517 if (crlissuer
== NULL
) {
520 memset(&gn
, 0, sizeof(gn
));
522 gn
.element
= choice_GeneralName_directoryName
;
523 ret
= hx509_name_to_Name(issuername
, &n
);
525 hx509_set_error_string(context
, 0, ret
, "out of memory");
529 gn
.u
.directoryName
.element
= n
.element
;
530 gn
.u
.directoryName
.u
.rdnSequence
= n
.u
.rdnSequence
;
532 ret
= add_GeneralNames(&crlissuer
, &gn
);
535 hx509_set_error_string(context
, 0, ret
, "out of memory");
539 dp
.cRLIssuer
= &crlissuer
;
543 ret
= add_CRLDistributionPoints(&tbs
->crldp
, &dp
);
545 hx509_set_error_string(context
, 0, ret
, "out of memory");
550 free_DistributionPoint(&dp
);
556 * Add Subject Alternative Name otherName to the to-be-signed
557 * certificate object.
559 * @param context A hx509 context.
560 * @param tbs object to be signed.
561 * @param oid the oid of the OtherName.
562 * @param os data in the other name.
564 * @return An hx509 error code, see hx509_get_error_string().
570 hx509_ca_tbs_add_san_otherName(hx509_context context
,
573 const heim_octet_string
*os
)
577 memset(&gn
, 0, sizeof(gn
));
578 gn
.element
= choice_GeneralName_otherName
;
579 gn
.u
.otherName
.type_id
= *oid
;
580 gn
.u
.otherName
.value
= *os
;
582 return add_GeneralNames(&tbs
->san
, &gn
);
586 * Add Kerberos Subject Alternative Name to the to-be-signed
587 * certificate object. The principal string is a UTF8 string.
589 * @param context A hx509 context.
590 * @param tbs object to be signed.
591 * @param principal Kerberos principal to add to the certificate.
593 * @return An hx509 error code, see hx509_get_error_string().
599 hx509_ca_tbs_add_san_pkinit(hx509_context context
,
601 const char *principal
)
603 heim_octet_string os
;
609 memset(&p
, 0, sizeof(p
));
611 /* parse principal */
617 /* count number of component */
619 for(str
= principal
; *str
!= '\0' && *str
!= '@'; str
++){
621 if(str
[1] == '\0' || str
[1] == '@') {
622 ret
= HX509_PARSING_NAME_FAILED
;
623 hx509_set_error_string(context
, 0, ret
,
624 "trailing \\ in principal name");
628 } else if(*str
== '/')
631 p
.principalName
.name_string
.val
=
632 calloc(n
, sizeof(*p
.principalName
.name_string
.val
));
633 if (p
.principalName
.name_string
.val
== NULL
) {
635 hx509_set_error_string(context
, 0, ret
, "malloc: out of memory");
638 p
.principalName
.name_string
.len
= n
;
640 p
.principalName
.name_type
= KRB5_NT_PRINCIPAL
;
641 q
= s
= strdup(principal
);
644 hx509_set_error_string(context
, 0, ret
, "malloc: out of memory");
647 p
.realm
= strrchr(q
, '@');
648 if (p
.realm
== NULL
) {
649 ret
= HX509_PARSING_NAME_FAILED
;
650 hx509_set_error_string(context
, 0, ret
, "Missing @ in principal");
657 p
.principalName
.name_string
.val
[n
++] = q
;
664 ASN1_MALLOC_ENCODE(KRB5PrincipalName
, os
.data
, os
.length
, &p
, &size
, ret
);
666 hx509_set_error_string(context
, 0, ret
, "Out of memory");
669 if (size
!= os
.length
)
670 _hx509_abort("internal ASN.1 encoder error");
672 ret
= hx509_ca_tbs_add_san_otherName(context
,
674 &asn1_oid_id_pkinit_san
,
678 if (p
.principalName
.name_string
.val
)
679 free (p
.principalName
.name_string
.val
);
690 add_utf8_san(hx509_context context
,
695 const PKIXXmppAddr ustring
= (const PKIXXmppAddr
)string
;
696 heim_octet_string os
;
703 ASN1_MALLOC_ENCODE(PKIXXmppAddr
, os
.data
, os
.length
, &ustring
, &size
, ret
);
705 hx509_set_error_string(context
, 0, ret
, "Out of memory");
708 if (size
!= os
.length
)
709 _hx509_abort("internal ASN.1 encoder error");
711 ret
= hx509_ca_tbs_add_san_otherName(context
,
721 * Add Microsoft UPN Subject Alternative Name to the to-be-signed
722 * certificate object. The principal string is a UTF8 string.
724 * @param context A hx509 context.
725 * @param tbs object to be signed.
726 * @param principal Microsoft UPN string.
728 * @return An hx509 error code, see hx509_get_error_string().
734 hx509_ca_tbs_add_san_ms_upn(hx509_context context
,
736 const char *principal
)
738 return add_utf8_san(context
, tbs
, &asn1_oid_id_pkinit_ms_san
, principal
);
742 * Add a Jabber/XMPP jid Subject Alternative Name to the to-be-signed
743 * certificate object. The jid is an UTF8 string.
745 * @param context A hx509 context.
746 * @param tbs object to be signed.
747 * @param jid string of an a jabber id in UTF8.
749 * @return An hx509 error code, see hx509_get_error_string().
755 hx509_ca_tbs_add_san_jid(hx509_context context
,
759 return add_utf8_san(context
, tbs
, &asn1_oid_id_pkix_on_xmppAddr
, jid
);
764 * Add a Subject Alternative Name hostname to to-be-signed certificate
765 * object. A domain match starts with ., an exact match does not.
767 * Example of a an domain match: .domain.se matches the hostname
770 * @param context A hx509 context.
771 * @param tbs object to be signed.
772 * @param dnsname a hostame.
774 * @return An hx509 error code, see hx509_get_error_string().
780 hx509_ca_tbs_add_san_hostname(hx509_context context
,
786 memset(&gn
, 0, sizeof(gn
));
787 gn
.element
= choice_GeneralName_dNSName
;
788 gn
.u
.dNSName
= rk_UNCONST(dnsname
);
790 return add_GeneralNames(&tbs
->san
, &gn
);
794 * Add a Subject Alternative Name rfc822 (email address) to
795 * to-be-signed certificate object.
797 * @param context A hx509 context.
798 * @param tbs object to be signed.
799 * @param rfc822Name a string to a email address.
801 * @return An hx509 error code, see hx509_get_error_string().
807 hx509_ca_tbs_add_san_rfc822name(hx509_context context
,
809 const char *rfc822Name
)
813 memset(&gn
, 0, sizeof(gn
));
814 gn
.element
= choice_GeneralName_rfc822Name
;
815 gn
.u
.rfc822Name
= rk_UNCONST(rfc822Name
);
817 return add_GeneralNames(&tbs
->san
, &gn
);
821 * Set the subject name of a to-be-signed certificate object.
823 * @param context A hx509 context.
824 * @param tbs object to be signed.
825 * @param subject the name to set a subject.
827 * @return An hx509 error code, see hx509_get_error_string().
833 hx509_ca_tbs_set_subject(hx509_context context
,
838 hx509_name_free(&tbs
->subject
);
839 return hx509_name_copy(context
, subject
, &tbs
->subject
);
843 * Expand the the subject name in the to-be-signed certificate object
844 * using hx509_name_expand().
846 * @param context A hx509 context.
847 * @param tbs object to be signed.
848 * @param env enviroment variable to expand variables in the subject
849 * name, see hx509_env_init().
851 * @return An hx509 error code, see hx509_get_error_string().
857 hx509_ca_tbs_subject_expand(hx509_context context
,
861 return hx509_name_expand(context
, tbs
->subject
, env
);
865 add_extension(hx509_context context
,
866 TBSCertificate
*tbsc
,
869 const heim_octet_string
*data
)
874 memset(&ext
, 0, sizeof(ext
));
877 ext
.critical
= malloc(sizeof(*ext
.critical
));
878 if (ext
.critical
== NULL
) {
880 hx509_set_error_string(context
, 0, ret
, "Out of memory");
883 *ext
.critical
= TRUE
;
886 ret
= der_copy_oid(oid
, &ext
.extnID
);
888 hx509_set_error_string(context
, 0, ret
, "Out of memory");
891 ret
= der_copy_octet_string(data
, &ext
.extnValue
);
893 hx509_set_error_string(context
, 0, ret
, "Out of memory");
896 ret
= add_Extensions(tbsc
->extensions
, &ext
);
898 hx509_set_error_string(context
, 0, ret
, "Out of memory");
902 free_Extension(&ext
);
907 build_proxy_prefix(hx509_context context
, const Name
*issuer
, Name
*subject
)
913 ret
= copy_Name(issuer
, subject
);
915 hx509_set_error_string(context
, 0, ret
,
916 "Failed to copy subject name");
921 asprintf(&tstr
, "ts-%lu", (unsigned long)t
);
923 hx509_set_error_string(context
, 0, ENOMEM
,
924 "Failed to copy subject name");
927 /* prefix with CN=<ts>,...*/
928 ret
= _hx509_name_modify(context
, subject
, 1, &asn1_oid_id_at_commonName
, tstr
);
936 ca_sign(hx509_context context
,
938 hx509_private_key signer
,
939 const AuthorityKeyIdentifier
*ai
,
940 const Name
*issuername
,
941 hx509_cert
*certificate
)
943 heim_octet_string data
;
945 TBSCertificate
*tbsc
;
948 const AlgorithmIdentifier
*sigalg
;
953 sigalg
= _hx509_crypto_default_sig_alg
;
955 memset(&c
, 0, sizeof(c
));
958 * Default values are: Valid since 24h ago, valid one year into
959 * the future, KeyUsage digitalSignature and keyEncipherment set,
960 * and keyCertSign for CA certificates.
962 notBefore
= tbs
->notBefore
;
964 notBefore
= time(NULL
) - 3600 * 24;
965 notAfter
= tbs
->notAfter
;
967 notAfter
= time(NULL
) + 3600 * 24 * 365;
969 key_usage
= tbs
->key_usage
;
970 if (key_usage
== 0) {
972 memset(&ku
, 0, sizeof(ku
));
973 ku
.digitalSignature
= 1;
974 ku
.keyEncipherment
= 1;
975 key_usage
= KeyUsage2int(ku
);
980 memset(&ku
, 0, sizeof(ku
));
983 key_usage
|= KeyUsage2int(ku
);
990 tbsc
= &c
.tbsCertificate
;
992 if (tbs
->flags
.key
== 0) {
994 hx509_set_error_string(context
, 0, ret
, "No public key set");
998 * Don't put restrictions on proxy certificate's subject name, it
999 * will be generated below.
1001 if (!tbs
->flags
.proxy
) {
1002 if (tbs
->subject
== NULL
) {
1003 hx509_set_error_string(context
, 0, EINVAL
, "No subject name set");
1006 if (hx509_name_is_null_p(tbs
->subject
) && tbs
->san
.len
== 0) {
1007 hx509_set_error_string(context
, 0, EINVAL
,
1008 "NULL subject and no SubjectAltNames");
1012 if (tbs
->flags
.ca
&& tbs
->flags
.proxy
) {
1013 hx509_set_error_string(context
, 0, EINVAL
, "Can't be proxy and CA "
1014 "at the same time");
1017 if (tbs
->flags
.proxy
) {
1018 if (tbs
->san
.len
> 0) {
1019 hx509_set_error_string(context
, 0, EINVAL
,
1020 "Proxy certificate is not allowed "
1021 "to have SubjectAltNames");
1026 /* version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1, */
1027 tbsc
->version
= calloc(1, sizeof(*tbsc
->version
));
1028 if (tbsc
->version
== NULL
) {
1030 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1033 *tbsc
->version
= rfc3280_version_3
;
1034 /* serialNumber CertificateSerialNumber, */
1035 if (tbs
->flags
.serial
) {
1036 ret
= der_copy_heim_integer(&tbs
->serial
, &tbsc
->serialNumber
);
1038 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1042 tbsc
->serialNumber
.length
= 20;
1043 tbsc
->serialNumber
.data
= malloc(tbsc
->serialNumber
.length
);
1044 if (tbsc
->serialNumber
.data
== NULL
){
1046 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1050 RAND_bytes(tbsc
->serialNumber
.data
, tbsc
->serialNumber
.length
);
1051 ((unsigned char *)tbsc
->serialNumber
.data
)[0] &= 0x7f;
1053 /* signature AlgorithmIdentifier, */
1054 ret
= copy_AlgorithmIdentifier(sigalg
, &tbsc
->signature
);
1056 hx509_set_error_string(context
, 0, ret
, "Failed to copy sigature alg");
1061 ret
= copy_Name(issuername
, &tbsc
->issuer
);
1063 ret
= hx509_name_to_Name(tbs
->subject
, &tbsc
->issuer
);
1065 hx509_set_error_string(context
, 0, ret
, "Failed to copy issuer name");
1068 /* validity Validity, */
1069 tbsc
->validity
.notBefore
.element
= choice_Time_generalTime
;
1070 tbsc
->validity
.notBefore
.u
.generalTime
= notBefore
;
1071 tbsc
->validity
.notAfter
.element
= choice_Time_generalTime
;
1072 tbsc
->validity
.notAfter
.u
.generalTime
= notAfter
;
1074 if (tbs
->flags
.proxy
) {
1075 ret
= build_proxy_prefix(context
, &tbsc
->issuer
, &tbsc
->subject
);
1079 ret
= hx509_name_to_Name(tbs
->subject
, &tbsc
->subject
);
1081 hx509_set_error_string(context
, 0, ret
,
1082 "Failed to copy subject name");
1086 /* subjectPublicKeyInfo SubjectPublicKeyInfo, */
1087 ret
= copy_SubjectPublicKeyInfo(&tbs
->spki
, &tbsc
->subjectPublicKeyInfo
);
1089 hx509_set_error_string(context
, 0, ret
, "Failed to copy spki");
1092 /* issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL */
1093 /* subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL */
1094 /* extensions [3] EXPLICIT Extensions OPTIONAL */
1095 tbsc
->extensions
= calloc(1, sizeof(*tbsc
->extensions
));
1096 if (tbsc
->extensions
== NULL
) {
1098 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1102 /* Add the text BMP string Domaincontroller to the cert */
1103 if (tbs
->flags
.domaincontroller
) {
1104 data
.data
= rk_UNCONST("\x1e\x20\x00\x44\x00\x6f\x00\x6d"
1105 "\x00\x61\x00\x69\x00\x6e\x00\x43"
1106 "\x00\x6f\x00\x6e\x00\x74\x00\x72"
1107 "\x00\x6f\x00\x6c\x00\x6c\x00\x65"
1111 ret
= add_extension(context
, tbsc
, 0,
1112 &asn1_oid_id_ms_cert_enroll_domaincontroller
,
1122 ku
= int2KeyUsage(key_usage
);
1123 ASN1_MALLOC_ENCODE(KeyUsage
, data
.data
, data
.length
, &ku
, &size
, ret
);
1125 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1128 if (size
!= data
.length
)
1129 _hx509_abort("internal ASN.1 encoder error");
1130 ret
= add_extension(context
, tbsc
, 1,
1131 &asn1_oid_id_x509_ce_keyUsage
, &data
);
1137 /* add ExtendedKeyUsage */
1138 if (tbs
->eku
.len
> 0) {
1139 ASN1_MALLOC_ENCODE(ExtKeyUsage
, data
.data
, data
.length
,
1140 &tbs
->eku
, &size
, ret
);
1142 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1145 if (size
!= data
.length
)
1146 _hx509_abort("internal ASN.1 encoder error");
1147 ret
= add_extension(context
, tbsc
, 0,
1148 &asn1_oid_id_x509_ce_extKeyUsage
, &data
);
1154 /* add Subject Alternative Name */
1155 if (tbs
->san
.len
> 0) {
1156 ASN1_MALLOC_ENCODE(GeneralNames
, data
.data
, data
.length
,
1157 &tbs
->san
, &size
, ret
);
1159 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1162 if (size
!= data
.length
)
1163 _hx509_abort("internal ASN.1 encoder error");
1164 ret
= add_extension(context
, tbsc
, 0,
1165 &asn1_oid_id_x509_ce_subjectAltName
,
1172 /* Add Authority Key Identifier */
1174 ASN1_MALLOC_ENCODE(AuthorityKeyIdentifier
, data
.data
, data
.length
,
1177 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1180 if (size
!= data
.length
)
1181 _hx509_abort("internal ASN.1 encoder error");
1182 ret
= add_extension(context
, tbsc
, 0,
1183 &asn1_oid_id_x509_ce_authorityKeyIdentifier
,
1190 /* Add Subject Key Identifier */
1192 SubjectKeyIdentifier si
;
1193 unsigned char hash
[SHA_DIGEST_LENGTH
];
1198 ctx
= EVP_MD_CTX_create();
1199 EVP_DigestInit_ex(ctx
, EVP_sha1(), NULL
);
1200 EVP_DigestUpdate(ctx
, tbs
->spki
.subjectPublicKey
.data
,
1201 tbs
->spki
.subjectPublicKey
.length
/ 8);
1202 EVP_DigestFinal_ex(ctx
, hash
, NULL
);
1203 EVP_MD_CTX_destroy(ctx
);
1207 si
.length
= sizeof(hash
);
1209 ASN1_MALLOC_ENCODE(SubjectKeyIdentifier
, data
.data
, data
.length
,
1212 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1215 if (size
!= data
.length
)
1216 _hx509_abort("internal ASN.1 encoder error");
1217 ret
= add_extension(context
, tbsc
, 0,
1218 &asn1_oid_id_x509_ce_subjectKeyIdentifier
,
1225 /* Add BasicConstraints */
1227 BasicConstraints bc
;
1231 memset(&bc
, 0, sizeof(bc
));
1233 if (tbs
->flags
.ca
) {
1235 if (tbs
->pathLenConstraint
>= 0) {
1236 path
= tbs
->pathLenConstraint
;
1237 bc
.pathLenConstraint
= &path
;
1241 ASN1_MALLOC_ENCODE(BasicConstraints
, data
.data
, data
.length
,
1244 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1247 if (size
!= data
.length
)
1248 _hx509_abort("internal ASN.1 encoder error");
1249 /* Critical if this is a CA */
1250 ret
= add_extension(context
, tbsc
, tbs
->flags
.ca
,
1251 &asn1_oid_id_x509_ce_basicConstraints
,
1259 if (tbs
->flags
.proxy
) {
1262 memset(&info
, 0, sizeof(info
));
1264 if (tbs
->pathLenConstraint
>= 0) {
1265 info
.pCPathLenConstraint
=
1266 malloc(sizeof(*info
.pCPathLenConstraint
));
1267 if (info
.pCPathLenConstraint
== NULL
) {
1269 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1272 *info
.pCPathLenConstraint
= tbs
->pathLenConstraint
;
1275 ret
= der_copy_oid(&asn1_oid_id_pkix_ppl_inheritAll
,
1276 &info
.proxyPolicy
.policyLanguage
);
1278 free_ProxyCertInfo(&info
);
1279 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1283 ASN1_MALLOC_ENCODE(ProxyCertInfo
, data
.data
, data
.length
,
1285 free_ProxyCertInfo(&info
);
1287 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1290 if (size
!= data
.length
)
1291 _hx509_abort("internal ASN.1 encoder error");
1292 ret
= add_extension(context
, tbsc
, 0,
1293 &asn1_oid_id_pkix_pe_proxyCertInfo
,
1300 if (tbs
->crldp
.len
) {
1302 ASN1_MALLOC_ENCODE(CRLDistributionPoints
, data
.data
, data
.length
,
1303 &tbs
->crldp
, &size
, ret
);
1305 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1308 if (size
!= data
.length
)
1309 _hx509_abort("internal ASN.1 encoder error");
1310 ret
= add_extension(context
, tbsc
, FALSE
,
1311 &asn1_oid_id_x509_ce_cRLDistributionPoints
,
1318 ASN1_MALLOC_ENCODE(TBSCertificate
, data
.data
, data
.length
,tbsc
, &size
, ret
);
1320 hx509_set_error_string(context
, 0, ret
, "malloc out of memory");
1323 if (data
.length
!= size
)
1324 _hx509_abort("internal ASN.1 encoder error");
1326 ret
= _hx509_create_signature_bitstring(context
,
1330 &c
.signatureAlgorithm
,
1336 ret
= hx509_cert_init(context
, &c
, certificate
);
1340 free_Certificate(&c
);
1345 free_Certificate(&c
);
1350 get_AuthorityKeyIdentifier(hx509_context context
,
1351 const Certificate
*certificate
,
1352 AuthorityKeyIdentifier
*ai
)
1354 SubjectKeyIdentifier si
;
1357 ret
= _hx509_find_extension_subject_key_id(certificate
, &si
);
1359 ai
->keyIdentifier
= calloc(1, sizeof(*ai
->keyIdentifier
));
1360 if (ai
->keyIdentifier
== NULL
) {
1361 free_SubjectKeyIdentifier(&si
);
1363 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1366 ret
= der_copy_octet_string(&si
, ai
->keyIdentifier
);
1367 free_SubjectKeyIdentifier(&si
);
1369 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1377 memset(&gn
, 0, sizeof(gn
));
1378 memset(&gns
, 0, sizeof(gns
));
1379 memset(&name
, 0, sizeof(name
));
1381 ai
->authorityCertIssuer
=
1382 calloc(1, sizeof(*ai
->authorityCertIssuer
));
1383 if (ai
->authorityCertIssuer
== NULL
) {
1385 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1388 ai
->authorityCertSerialNumber
=
1389 calloc(1, sizeof(*ai
->authorityCertSerialNumber
));
1390 if (ai
->authorityCertSerialNumber
== NULL
) {
1392 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1397 * XXX unbreak when asn1 compiler handle IMPLICIT
1399 * This is so horrible.
1402 ret
= copy_Name(&certificate
->tbsCertificate
.subject
, &name
);
1404 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1408 memset(&gn
, 0, sizeof(gn
));
1409 gn
.element
= choice_GeneralName_directoryName
;
1410 gn
.u
.directoryName
.element
=
1411 choice_GeneralName_directoryName_rdnSequence
;
1412 gn
.u
.directoryName
.u
.rdnSequence
= name
.u
.rdnSequence
;
1414 ret
= add_GeneralNames(&gns
, &gn
);
1416 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1420 ai
->authorityCertIssuer
->val
= gns
.val
;
1421 ai
->authorityCertIssuer
->len
= gns
.len
;
1423 ret
= der_copy_heim_integer(&certificate
->tbsCertificate
.serialNumber
,
1424 ai
->authorityCertSerialNumber
);
1425 if (ai
->authorityCertSerialNumber
== NULL
) {
1427 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1433 free_AuthorityKeyIdentifier(ai
);
1439 * Sign a to-be-signed certificate object with a issuer certificate.
1441 * The caller needs to at least have called the following functions on the
1442 * to-be-signed certificate object:
1443 * - hx509_ca_tbs_init()
1444 * - hx509_ca_tbs_set_subject()
1445 * - hx509_ca_tbs_set_spki()
1447 * When done the to-be-signed certificate object should be freed with
1448 * hx509_ca_tbs_free().
1450 * When creating self-signed certificate use hx509_ca_sign_self() instead.
1452 * @param context A hx509 context.
1453 * @param tbs object to be signed.
1454 * @param signer the CA certificate object to sign with (need private key).
1455 * @param certificate return cerificate, free with hx509_cert_free().
1457 * @return An hx509 error code, see hx509_get_error_string().
1463 hx509_ca_sign(hx509_context context
,
1466 hx509_cert
*certificate
)
1468 const Certificate
*signer_cert
;
1469 AuthorityKeyIdentifier ai
;
1472 memset(&ai
, 0, sizeof(ai
));
1474 signer_cert
= _hx509_get_cert(signer
);
1476 ret
= get_AuthorityKeyIdentifier(context
, signer_cert
, &ai
);
1480 ret
= ca_sign(context
,
1482 _hx509_cert_private_key(signer
),
1484 &signer_cert
->tbsCertificate
.subject
,
1488 free_AuthorityKeyIdentifier(&ai
);
1494 * Work just like hx509_ca_sign() but signs it-self.
1496 * @param context A hx509 context.
1497 * @param tbs object to be signed.
1498 * @param signer private key to sign with.
1499 * @param certificate return cerificate, free with hx509_cert_free().
1501 * @return An hx509 error code, see hx509_get_error_string().
1507 hx509_ca_sign_self(hx509_context context
,
1509 hx509_private_key signer
,
1510 hx509_cert
*certificate
)
1512 return ca_sign(context
,