1 /* $NetBSD: ca.c,v 1.1.1.2 2014/04/24 12:45:41 pettai Exp $ */
4 * Copyright (c) 2006 - 2010 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <krb5/pkinit_asn1.h>
40 * @page page_ca Hx509 CA functions
42 * See the library functions here: @ref hx509_ca
47 SubjectPublicKeyInfo spki
;
56 unsigned int serial
:1;
57 unsigned int domaincontroller
:1;
58 unsigned int xUniqueID
:1;
62 int pathLenConstraint
; /* both for CA and Proxy */
63 CRLDistributionPoints crldp
;
64 heim_bit_string subjectUniqueID
;
65 heim_bit_string issuerUniqueID
;
70 * Allocate an to-be-signed certificate object that will be converted
71 * into an certificate.
73 * @param context A hx509 context.
74 * @param tbs returned to-be-signed certicate object, free with
75 * hx509_ca_tbs_free().
77 * @return An hx509 error code, see hx509_get_error_string().
83 hx509_ca_tbs_init(hx509_context context
, hx509_ca_tbs
*tbs
)
85 *tbs
= calloc(1, sizeof(**tbs
));
93 * Free an To Be Signed object.
95 * @param tbs object to free.
101 hx509_ca_tbs_free(hx509_ca_tbs
*tbs
)
103 if (tbs
== NULL
|| *tbs
== NULL
)
106 free_SubjectPublicKeyInfo(&(*tbs
)->spki
);
107 free_GeneralNames(&(*tbs
)->san
);
108 free_ExtKeyUsage(&(*tbs
)->eku
);
109 der_free_heim_integer(&(*tbs
)->serial
);
110 free_CRLDistributionPoints(&(*tbs
)->crldp
);
111 der_free_bit_string(&(*tbs
)->subjectUniqueID
);
112 der_free_bit_string(&(*tbs
)->issuerUniqueID
);
113 hx509_name_free(&(*tbs
)->subject
);
115 memset(*tbs
, 0, sizeof(**tbs
));
121 * Set the absolute time when the certificate is valid from. If not
122 * set the current time will be used.
124 * @param context A hx509 context.
125 * @param tbs object to be signed.
126 * @param t time the certificated will start to be valid
128 * @return An hx509 error code, see hx509_get_error_string().
134 hx509_ca_tbs_set_notBefore(hx509_context context
,
143 * Set the absolute time when the certificate is valid to.
145 * @param context A hx509 context.
146 * @param tbs object to be signed.
147 * @param t time when the certificate will expire
149 * @return An hx509 error code, see hx509_get_error_string().
155 hx509_ca_tbs_set_notAfter(hx509_context context
,
164 * Set the relative time when the certificiate is going to expire.
166 * @param context A hx509 context.
167 * @param tbs object to be signed.
168 * @param delta seconds to the certificate is going to expire.
170 * @return An hx509 error code, see hx509_get_error_string().
176 hx509_ca_tbs_set_notAfter_lifetime(hx509_context context
,
180 return hx509_ca_tbs_set_notAfter(context
, tbs
, time(NULL
) + delta
);
183 static const struct units templatebits
[] = {
184 { "ExtendedKeyUsage", HX509_CA_TEMPLATE_EKU
},
185 { "KeyUsage", HX509_CA_TEMPLATE_KU
},
186 { "SPKI", HX509_CA_TEMPLATE_SPKI
},
187 { "notAfter", HX509_CA_TEMPLATE_NOTAFTER
},
188 { "notBefore", HX509_CA_TEMPLATE_NOTBEFORE
},
189 { "serial", HX509_CA_TEMPLATE_SERIAL
},
190 { "subject", HX509_CA_TEMPLATE_SUBJECT
},
195 * Make of template units, use to build flags argument to
196 * hx509_ca_tbs_set_template() with parse_units().
198 * @return an units structure.
204 hx509_ca_tbs_template_units(void)
210 * Initialize the to-be-signed certificate object from a template certifiate.
212 * @param context A hx509 context.
213 * @param tbs object to be signed.
214 * @param flags bit field selecting what to copy from the template
216 * @param cert template certificate.
218 * @return An hx509 error code, see hx509_get_error_string().
224 hx509_ca_tbs_set_template(hx509_context context
,
231 if (flags
& HX509_CA_TEMPLATE_SUBJECT
) {
233 hx509_name_free(&tbs
->subject
);
234 ret
= hx509_cert_get_subject(cert
, &tbs
->subject
);
236 hx509_set_error_string(context
, 0, ret
,
237 "Failed to get subject from template");
241 if (flags
& HX509_CA_TEMPLATE_SERIAL
) {
242 der_free_heim_integer(&tbs
->serial
);
243 ret
= hx509_cert_get_serialnumber(cert
, &tbs
->serial
);
244 tbs
->flags
.serial
= !ret
;
246 hx509_set_error_string(context
, 0, ret
,
247 "Failed to copy serial number");
251 if (flags
& HX509_CA_TEMPLATE_NOTBEFORE
)
252 tbs
->notBefore
= hx509_cert_get_notBefore(cert
);
253 if (flags
& HX509_CA_TEMPLATE_NOTAFTER
)
254 tbs
->notAfter
= hx509_cert_get_notAfter(cert
);
255 if (flags
& HX509_CA_TEMPLATE_SPKI
) {
256 free_SubjectPublicKeyInfo(&tbs
->spki
);
257 ret
= hx509_cert_get_SPKI(context
, cert
, &tbs
->spki
);
258 tbs
->flags
.key
= !ret
;
262 if (flags
& HX509_CA_TEMPLATE_KU
) {
264 ret
= _hx509_cert_get_keyusage(context
, cert
, &ku
);
267 tbs
->key_usage
= KeyUsage2int(ku
);
269 if (flags
& HX509_CA_TEMPLATE_EKU
) {
272 ret
= _hx509_cert_get_eku(context
, cert
, &eku
);
275 for (i
= 0; i
< eku
.len
; i
++) {
276 ret
= hx509_ca_tbs_add_eku(context
, tbs
, &eku
.val
[i
]);
278 free_ExtKeyUsage(&eku
);
282 free_ExtKeyUsage(&eku
);
288 * Make the to-be-signed certificate object a CA certificate. If the
289 * pathLenConstraint is negative path length constraint is used.
291 * @param context A hx509 context.
292 * @param tbs object to be signed.
293 * @param pathLenConstraint path length constraint, negative, no
296 * @return An hx509 error code, see hx509_get_error_string().
302 hx509_ca_tbs_set_ca(hx509_context context
,
304 int pathLenConstraint
)
307 tbs
->pathLenConstraint
= pathLenConstraint
;
312 * Make the to-be-signed certificate object a proxy certificate. If the
313 * pathLenConstraint is negative path length constraint is used.
315 * @param context A hx509 context.
316 * @param tbs object to be signed.
317 * @param pathLenConstraint path length constraint, negative, no
320 * @return An hx509 error code, see hx509_get_error_string().
326 hx509_ca_tbs_set_proxy(hx509_context context
,
328 int pathLenConstraint
)
330 tbs
->flags
.proxy
= 1;
331 tbs
->pathLenConstraint
= pathLenConstraint
;
337 * Make the to-be-signed certificate object a windows domain controller certificate.
339 * @param context A hx509 context.
340 * @param tbs object to be signed.
342 * @return An hx509 error code, see hx509_get_error_string().
348 hx509_ca_tbs_set_domaincontroller(hx509_context context
,
351 tbs
->flags
.domaincontroller
= 1;
356 * Set the subject public key info (SPKI) in the to-be-signed certificate
357 * object. SPKI is the public key and key related parameters in the
360 * @param context A hx509 context.
361 * @param tbs object to be signed.
362 * @param spki subject public key info to use for the to-be-signed certificate object.
364 * @return An hx509 error code, see hx509_get_error_string().
370 hx509_ca_tbs_set_spki(hx509_context context
,
372 const SubjectPublicKeyInfo
*spki
)
375 free_SubjectPublicKeyInfo(&tbs
->spki
);
376 ret
= copy_SubjectPublicKeyInfo(spki
, &tbs
->spki
);
377 tbs
->flags
.key
= !ret
;
382 * Set the serial number to use for to-be-signed certificate object.
384 * @param context A hx509 context.
385 * @param tbs object to be signed.
386 * @param serialNumber serial number to use for the to-be-signed
387 * certificate object.
389 * @return An hx509 error code, see hx509_get_error_string().
395 hx509_ca_tbs_set_serialnumber(hx509_context context
,
397 const heim_integer
*serialNumber
)
400 der_free_heim_integer(&tbs
->serial
);
401 ret
= der_copy_heim_integer(serialNumber
, &tbs
->serial
);
402 tbs
->flags
.serial
= !ret
;
407 * An an extended key usage to the to-be-signed certificate object.
408 * Duplicates will detected and not added.
410 * @param context A hx509 context.
411 * @param tbs object to be signed.
412 * @param oid extended key usage to add.
414 * @return An hx509 error code, see hx509_get_error_string().
420 hx509_ca_tbs_add_eku(hx509_context context
,
428 /* search for duplicates */
429 for (i
= 0; i
< tbs
->eku
.len
; i
++) {
430 if (der_heim_oid_cmp(oid
, &tbs
->eku
.val
[i
]) == 0)
434 ptr
= realloc(tbs
->eku
.val
, sizeof(tbs
->eku
.val
[0]) * (tbs
->eku
.len
+ 1));
436 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
440 ret
= der_copy_oid(oid
, &tbs
->eku
.val
[tbs
->eku
.len
]);
442 hx509_set_error_string(context
, 0, ret
, "out of memory");
450 * Add CRL distribution point URI to the to-be-signed certificate
453 * @param context A hx509 context.
454 * @param tbs object to be signed.
455 * @param uri uri to the CRL.
456 * @param issuername name of the issuer.
458 * @return An hx509 error code, see hx509_get_error_string().
464 hx509_ca_tbs_add_crl_dp_uri(hx509_context context
,
467 hx509_name issuername
)
469 DistributionPoint dp
;
472 memset(&dp
, 0, sizeof(dp
));
474 dp
.distributionPoint
= ecalloc(1, sizeof(*dp
.distributionPoint
));
477 DistributionPointName name
;
481 name
.element
= choice_DistributionPointName_fullName
;
482 name
.u
.fullName
.len
= 1;
483 name
.u
.fullName
.val
= &gn
;
485 gn
.element
= choice_GeneralName_uniformResourceIdentifier
;
486 gn
.u
.uniformResourceIdentifier
.data
= rk_UNCONST(uri
);
487 gn
.u
.uniformResourceIdentifier
.length
= strlen(uri
);
489 ASN1_MALLOC_ENCODE(DistributionPointName
,
490 dp
.distributionPoint
->data
,
491 dp
.distributionPoint
->length
,
494 hx509_set_error_string(context
, 0, ret
,
495 "Failed to encoded DistributionPointName");
498 if (dp
.distributionPoint
->length
!= size
)
499 _hx509_abort("internal ASN.1 encoder error");
505 * issuername not supported
507 hx509_set_error_string(context
, 0, EINVAL
,
508 "CRLDistributionPoints.name.issuername not yet supported");
511 GeneralNames
*crlissuer
;
515 crlissuer
= calloc(1, sizeof(*crlissuer
));
516 if (crlissuer
== NULL
) {
519 memset(&gn
, 0, sizeof(gn
));
521 gn
.element
= choice_GeneralName_directoryName
;
522 ret
= hx509_name_to_Name(issuername
, &n
);
524 hx509_set_error_string(context
, 0, ret
, "out of memory");
528 gn
.u
.directoryName
.element
= n
.element
;
529 gn
.u
.directoryName
.u
.rdnSequence
= n
.u
.rdnSequence
;
531 ret
= add_GeneralNames(&crlissuer
, &gn
);
534 hx509_set_error_string(context
, 0, ret
, "out of memory");
538 dp
.cRLIssuer
= &crlissuer
;
542 ret
= add_CRLDistributionPoints(&tbs
->crldp
, &dp
);
544 hx509_set_error_string(context
, 0, ret
, "out of memory");
549 free_DistributionPoint(&dp
);
555 * Add Subject Alternative Name otherName to the to-be-signed
556 * certificate object.
558 * @param context A hx509 context.
559 * @param tbs object to be signed.
560 * @param oid the oid of the OtherName.
561 * @param os data in the other name.
563 * @return An hx509 error code, see hx509_get_error_string().
569 hx509_ca_tbs_add_san_otherName(hx509_context context
,
572 const heim_octet_string
*os
)
576 memset(&gn
, 0, sizeof(gn
));
577 gn
.element
= choice_GeneralName_otherName
;
578 gn
.u
.otherName
.type_id
= *oid
;
579 gn
.u
.otherName
.value
= *os
;
581 return add_GeneralNames(&tbs
->san
, &gn
);
585 * Add Kerberos Subject Alternative Name to the to-be-signed
586 * certificate object. The principal string is a UTF8 string.
588 * @param context A hx509 context.
589 * @param tbs object to be signed.
590 * @param principal Kerberos principal to add to the certificate.
592 * @return An hx509 error code, see hx509_get_error_string().
598 hx509_ca_tbs_add_san_pkinit(hx509_context context
,
600 const char *principal
)
602 heim_octet_string os
;
608 memset(&p
, 0, sizeof(p
));
610 /* parse principal */
616 /* count number of component */
618 for(str
= principal
; *str
!= '\0' && *str
!= '@'; str
++){
620 if(str
[1] == '\0' || str
[1] == '@') {
621 ret
= HX509_PARSING_NAME_FAILED
;
622 hx509_set_error_string(context
, 0, ret
,
623 "trailing \\ in principal name");
627 } else if(*str
== '/')
630 p
.principalName
.name_string
.val
=
631 calloc(n
, sizeof(*p
.principalName
.name_string
.val
));
632 if (p
.principalName
.name_string
.val
== NULL
) {
634 hx509_set_error_string(context
, 0, ret
, "malloc: out of memory");
637 p
.principalName
.name_string
.len
= n
;
639 p
.principalName
.name_type
= KRB5_NT_PRINCIPAL
;
640 q
= s
= strdup(principal
);
643 hx509_set_error_string(context
, 0, ret
, "malloc: out of memory");
646 p
.realm
= strrchr(q
, '@');
647 if (p
.realm
== NULL
) {
648 ret
= HX509_PARSING_NAME_FAILED
;
649 hx509_set_error_string(context
, 0, ret
, "Missing @ in principal");
656 p
.principalName
.name_string
.val
[n
++] = q
;
663 ASN1_MALLOC_ENCODE(KRB5PrincipalName
, os
.data
, os
.length
, &p
, &size
, ret
);
665 hx509_set_error_string(context
, 0, ret
, "Out of memory");
668 if (size
!= os
.length
)
669 _hx509_abort("internal ASN.1 encoder error");
671 ret
= hx509_ca_tbs_add_san_otherName(context
,
673 &asn1_oid_id_pkinit_san
,
677 if (p
.principalName
.name_string
.val
)
678 free (p
.principalName
.name_string
.val
);
689 add_utf8_san(hx509_context context
,
694 const PKIXXmppAddr ustring
= (const PKIXXmppAddr
)(intptr_t)string
;
695 heim_octet_string os
;
702 ASN1_MALLOC_ENCODE(PKIXXmppAddr
, os
.data
, os
.length
, &ustring
, &size
, ret
);
704 hx509_set_error_string(context
, 0, ret
, "Out of memory");
707 if (size
!= os
.length
)
708 _hx509_abort("internal ASN.1 encoder error");
710 ret
= hx509_ca_tbs_add_san_otherName(context
,
720 * Add Microsoft UPN Subject Alternative Name to the to-be-signed
721 * certificate object. The principal string is a UTF8 string.
723 * @param context A hx509 context.
724 * @param tbs object to be signed.
725 * @param principal Microsoft UPN string.
727 * @return An hx509 error code, see hx509_get_error_string().
733 hx509_ca_tbs_add_san_ms_upn(hx509_context context
,
735 const char *principal
)
737 return add_utf8_san(context
, tbs
, &asn1_oid_id_pkinit_ms_san
, principal
);
741 * Add a Jabber/XMPP jid Subject Alternative Name to the to-be-signed
742 * certificate object. The jid is an UTF8 string.
744 * @param context A hx509 context.
745 * @param tbs object to be signed.
746 * @param jid string of an a jabber id in UTF8.
748 * @return An hx509 error code, see hx509_get_error_string().
754 hx509_ca_tbs_add_san_jid(hx509_context context
,
758 return add_utf8_san(context
, tbs
, &asn1_oid_id_pkix_on_xmppAddr
, jid
);
763 * Add a Subject Alternative Name hostname to to-be-signed certificate
764 * object. A domain match starts with ., an exact match does not.
766 * Example of a an domain match: .domain.se matches the hostname
769 * @param context A hx509 context.
770 * @param tbs object to be signed.
771 * @param dnsname a hostame.
773 * @return An hx509 error code, see hx509_get_error_string().
779 hx509_ca_tbs_add_san_hostname(hx509_context context
,
785 memset(&gn
, 0, sizeof(gn
));
786 gn
.element
= choice_GeneralName_dNSName
;
787 gn
.u
.dNSName
.data
= rk_UNCONST(dnsname
);
788 gn
.u
.dNSName
.length
= strlen(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
.data
= rk_UNCONST(rfc822Name
);
816 gn
.u
.rfc822Name
.length
= strlen(rfc822Name
);
818 return add_GeneralNames(&tbs
->san
, &gn
);
822 * Set the subject name of a to-be-signed certificate object.
824 * @param context A hx509 context.
825 * @param tbs object to be signed.
826 * @param subject the name to set a subject.
828 * @return An hx509 error code, see hx509_get_error_string().
834 hx509_ca_tbs_set_subject(hx509_context context
,
839 hx509_name_free(&tbs
->subject
);
840 return hx509_name_copy(context
, subject
, &tbs
->subject
);
844 * Set the issuerUniqueID and subjectUniqueID
846 * These are only supposed to be used considered with version 2
847 * certificates, replaced by the two extensions SubjectKeyIdentifier
848 * and IssuerKeyIdentifier. This function is to allow application
849 * using legacy protocol to issue them.
851 * @param context A hx509 context.
852 * @param tbs object to be signed.
853 * @param issuerUniqueID to be set
854 * @param subjectUniqueID to be set
856 * @return An hx509 error code, see hx509_get_error_string().
862 hx509_ca_tbs_set_unique(hx509_context context
,
864 const heim_bit_string
*subjectUniqueID
,
865 const heim_bit_string
*issuerUniqueID
)
869 der_free_bit_string(&tbs
->subjectUniqueID
);
870 der_free_bit_string(&tbs
->issuerUniqueID
);
872 if (subjectUniqueID
) {
873 ret
= der_copy_bit_string(subjectUniqueID
, &tbs
->subjectUniqueID
);
878 if (issuerUniqueID
) {
879 ret
= der_copy_bit_string(issuerUniqueID
, &tbs
->issuerUniqueID
);
888 * Expand the the subject name in the to-be-signed certificate object
889 * using hx509_name_expand().
891 * @param context A hx509 context.
892 * @param tbs object to be signed.
893 * @param env enviroment variable to expand variables in the subject
894 * name, see hx509_env_init().
896 * @return An hx509 error code, see hx509_get_error_string().
902 hx509_ca_tbs_subject_expand(hx509_context context
,
906 return hx509_name_expand(context
, tbs
->subject
, env
);
914 add_extension(hx509_context context
,
915 TBSCertificate
*tbsc
,
918 const heim_octet_string
*data
)
923 memset(&ext
, 0, sizeof(ext
));
926 ext
.critical
= malloc(sizeof(*ext
.critical
));
927 if (ext
.critical
== NULL
) {
929 hx509_set_error_string(context
, 0, ret
, "Out of memory");
932 *ext
.critical
= TRUE
;
935 ret
= der_copy_oid(oid
, &ext
.extnID
);
937 hx509_set_error_string(context
, 0, ret
, "Out of memory");
940 ret
= der_copy_octet_string(data
, &ext
.extnValue
);
942 hx509_set_error_string(context
, 0, ret
, "Out of memory");
945 ret
= add_Extensions(tbsc
->extensions
, &ext
);
947 hx509_set_error_string(context
, 0, ret
, "Out of memory");
951 free_Extension(&ext
);
956 build_proxy_prefix(hx509_context context
, const Name
*issuer
, Name
*subject
)
962 ret
= copy_Name(issuer
, subject
);
964 hx509_set_error_string(context
, 0, ret
,
965 "Failed to copy subject name");
970 asprintf(&tstr
, "ts-%lu", (unsigned long)t
);
972 hx509_set_error_string(context
, 0, ENOMEM
,
973 "Failed to copy subject name");
976 /* prefix with CN=<ts>,...*/
977 ret
= _hx509_name_modify(context
, subject
, 1, &asn1_oid_id_at_commonName
, tstr
);
985 ca_sign(hx509_context context
,
987 hx509_private_key signer
,
988 const AuthorityKeyIdentifier
*ai
,
989 const Name
*issuername
,
990 hx509_cert
*certificate
)
992 heim_octet_string data
;
994 TBSCertificate
*tbsc
;
997 const AlgorithmIdentifier
*sigalg
;
1002 sigalg
= _hx509_crypto_default_sig_alg
;
1004 memset(&c
, 0, sizeof(c
));
1007 * Default values are: Valid since 24h ago, valid one year into
1008 * the future, KeyUsage digitalSignature and keyEncipherment set,
1009 * and keyCertSign for CA certificates.
1011 notBefore
= tbs
->notBefore
;
1013 notBefore
= time(NULL
) - 3600 * 24;
1014 notAfter
= tbs
->notAfter
;
1016 notAfter
= time(NULL
) + 3600 * 24 * 365;
1018 key_usage
= tbs
->key_usage
;
1019 if (key_usage
== 0) {
1021 memset(&ku
, 0, sizeof(ku
));
1022 ku
.digitalSignature
= 1;
1023 ku
.keyEncipherment
= 1;
1024 key_usage
= KeyUsage2int(ku
);
1027 if (tbs
->flags
.ca
) {
1029 memset(&ku
, 0, sizeof(ku
));
1032 key_usage
|= KeyUsage2int(ku
);
1039 tbsc
= &c
.tbsCertificate
;
1041 if (tbs
->flags
.key
== 0) {
1043 hx509_set_error_string(context
, 0, ret
, "No public key set");
1047 * Don't put restrictions on proxy certificate's subject name, it
1048 * will be generated below.
1050 if (!tbs
->flags
.proxy
) {
1051 if (tbs
->subject
== NULL
) {
1052 hx509_set_error_string(context
, 0, EINVAL
, "No subject name set");
1055 if (hx509_name_is_null_p(tbs
->subject
) && tbs
->san
.len
== 0) {
1056 hx509_set_error_string(context
, 0, EINVAL
,
1057 "NULL subject and no SubjectAltNames");
1061 if (tbs
->flags
.ca
&& tbs
->flags
.proxy
) {
1062 hx509_set_error_string(context
, 0, EINVAL
, "Can't be proxy and CA "
1063 "at the same time");
1066 if (tbs
->flags
.proxy
) {
1067 if (tbs
->san
.len
> 0) {
1068 hx509_set_error_string(context
, 0, EINVAL
,
1069 "Proxy certificate is not allowed "
1070 "to have SubjectAltNames");
1075 /* version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1, */
1076 tbsc
->version
= calloc(1, sizeof(*tbsc
->version
));
1077 if (tbsc
->version
== NULL
) {
1079 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1082 *tbsc
->version
= rfc3280_version_3
;
1083 /* serialNumber CertificateSerialNumber, */
1084 if (tbs
->flags
.serial
) {
1085 ret
= der_copy_heim_integer(&tbs
->serial
, &tbsc
->serialNumber
);
1087 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1091 tbsc
->serialNumber
.length
= 20;
1092 tbsc
->serialNumber
.data
= malloc(tbsc
->serialNumber
.length
);
1093 if (tbsc
->serialNumber
.data
== NULL
){
1095 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1099 RAND_bytes(tbsc
->serialNumber
.data
, tbsc
->serialNumber
.length
);
1100 ((unsigned char *)tbsc
->serialNumber
.data
)[0] &= 0x7f;
1102 /* signature AlgorithmIdentifier, */
1103 ret
= copy_AlgorithmIdentifier(sigalg
, &tbsc
->signature
);
1105 hx509_set_error_string(context
, 0, ret
, "Failed to copy sigature alg");
1110 ret
= copy_Name(issuername
, &tbsc
->issuer
);
1112 ret
= hx509_name_to_Name(tbs
->subject
, &tbsc
->issuer
);
1114 hx509_set_error_string(context
, 0, ret
, "Failed to copy issuer name");
1117 /* validity Validity, */
1118 tbsc
->validity
.notBefore
.element
= choice_Time_generalTime
;
1119 tbsc
->validity
.notBefore
.u
.generalTime
= notBefore
;
1120 tbsc
->validity
.notAfter
.element
= choice_Time_generalTime
;
1121 tbsc
->validity
.notAfter
.u
.generalTime
= notAfter
;
1123 if (tbs
->flags
.proxy
) {
1124 ret
= build_proxy_prefix(context
, &tbsc
->issuer
, &tbsc
->subject
);
1128 ret
= hx509_name_to_Name(tbs
->subject
, &tbsc
->subject
);
1130 hx509_set_error_string(context
, 0, ret
,
1131 "Failed to copy subject name");
1135 /* subjectPublicKeyInfo SubjectPublicKeyInfo, */
1136 ret
= copy_SubjectPublicKeyInfo(&tbs
->spki
, &tbsc
->subjectPublicKeyInfo
);
1138 hx509_set_error_string(context
, 0, ret
, "Failed to copy spki");
1141 /* issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL */
1142 if (tbs
->issuerUniqueID
.length
) {
1143 tbsc
->issuerUniqueID
= calloc(1, sizeof(*tbsc
->issuerUniqueID
));
1144 if (tbsc
->issuerUniqueID
== NULL
) {
1146 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1149 ret
= der_copy_bit_string(&tbs
->issuerUniqueID
, tbsc
->issuerUniqueID
);
1151 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1155 /* subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL */
1156 if (tbs
->subjectUniqueID
.length
) {
1157 tbsc
->subjectUniqueID
= calloc(1, sizeof(*tbsc
->subjectUniqueID
));
1158 if (tbsc
->subjectUniqueID
== NULL
) {
1160 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1164 ret
= der_copy_bit_string(&tbs
->subjectUniqueID
, tbsc
->subjectUniqueID
);
1166 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1171 /* extensions [3] EXPLICIT Extensions OPTIONAL */
1172 tbsc
->extensions
= calloc(1, sizeof(*tbsc
->extensions
));
1173 if (tbsc
->extensions
== NULL
) {
1175 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1179 /* Add the text BMP string Domaincontroller to the cert */
1180 if (tbs
->flags
.domaincontroller
) {
1181 data
.data
= rk_UNCONST("\x1e\x20\x00\x44\x00\x6f\x00\x6d"
1182 "\x00\x61\x00\x69\x00\x6e\x00\x43"
1183 "\x00\x6f\x00\x6e\x00\x74\x00\x72"
1184 "\x00\x6f\x00\x6c\x00\x6c\x00\x65"
1188 ret
= add_extension(context
, tbsc
, 0,
1189 &asn1_oid_id_ms_cert_enroll_domaincontroller
,
1199 ku
= int2KeyUsage(key_usage
);
1200 ASN1_MALLOC_ENCODE(KeyUsage
, data
.data
, data
.length
, &ku
, &size
, ret
);
1202 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1205 if (size
!= data
.length
)
1206 _hx509_abort("internal ASN.1 encoder error");
1207 ret
= add_extension(context
, tbsc
, 1,
1208 &asn1_oid_id_x509_ce_keyUsage
, &data
);
1214 /* add ExtendedKeyUsage */
1215 if (tbs
->eku
.len
> 0) {
1216 ASN1_MALLOC_ENCODE(ExtKeyUsage
, data
.data
, data
.length
,
1217 &tbs
->eku
, &size
, ret
);
1219 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1222 if (size
!= data
.length
)
1223 _hx509_abort("internal ASN.1 encoder error");
1224 ret
= add_extension(context
, tbsc
, 0,
1225 &asn1_oid_id_x509_ce_extKeyUsage
, &data
);
1231 /* add Subject Alternative Name */
1232 if (tbs
->san
.len
> 0) {
1233 ASN1_MALLOC_ENCODE(GeneralNames
, data
.data
, data
.length
,
1234 &tbs
->san
, &size
, ret
);
1236 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1239 if (size
!= data
.length
)
1240 _hx509_abort("internal ASN.1 encoder error");
1241 ret
= add_extension(context
, tbsc
, 0,
1242 &asn1_oid_id_x509_ce_subjectAltName
,
1249 /* Add Authority Key Identifier */
1251 ASN1_MALLOC_ENCODE(AuthorityKeyIdentifier
, data
.data
, data
.length
,
1254 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1257 if (size
!= data
.length
)
1258 _hx509_abort("internal ASN.1 encoder error");
1259 ret
= add_extension(context
, tbsc
, 0,
1260 &asn1_oid_id_x509_ce_authorityKeyIdentifier
,
1267 /* Add Subject Key Identifier */
1269 SubjectKeyIdentifier si
;
1270 unsigned char hash
[SHA_DIGEST_LENGTH
];
1275 ctx
= EVP_MD_CTX_create();
1276 EVP_DigestInit_ex(ctx
, EVP_sha1(), NULL
);
1277 EVP_DigestUpdate(ctx
, tbs
->spki
.subjectPublicKey
.data
,
1278 tbs
->spki
.subjectPublicKey
.length
/ 8);
1279 EVP_DigestFinal_ex(ctx
, hash
, NULL
);
1280 EVP_MD_CTX_destroy(ctx
);
1284 si
.length
= sizeof(hash
);
1286 ASN1_MALLOC_ENCODE(SubjectKeyIdentifier
, data
.data
, data
.length
,
1289 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1292 if (size
!= data
.length
)
1293 _hx509_abort("internal ASN.1 encoder error");
1294 ret
= add_extension(context
, tbsc
, 0,
1295 &asn1_oid_id_x509_ce_subjectKeyIdentifier
,
1302 /* Add BasicConstraints */
1304 BasicConstraints bc
;
1308 memset(&bc
, 0, sizeof(bc
));
1310 if (tbs
->flags
.ca
) {
1312 if (tbs
->pathLenConstraint
>= 0) {
1313 path
= tbs
->pathLenConstraint
;
1314 bc
.pathLenConstraint
= &path
;
1318 ASN1_MALLOC_ENCODE(BasicConstraints
, data
.data
, data
.length
,
1321 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1324 if (size
!= data
.length
)
1325 _hx509_abort("internal ASN.1 encoder error");
1326 /* Critical if this is a CA */
1327 ret
= add_extension(context
, tbsc
, tbs
->flags
.ca
,
1328 &asn1_oid_id_x509_ce_basicConstraints
,
1336 if (tbs
->flags
.proxy
) {
1339 memset(&info
, 0, sizeof(info
));
1341 if (tbs
->pathLenConstraint
>= 0) {
1342 info
.pCPathLenConstraint
=
1343 malloc(sizeof(*info
.pCPathLenConstraint
));
1344 if (info
.pCPathLenConstraint
== NULL
) {
1346 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1349 *info
.pCPathLenConstraint
= tbs
->pathLenConstraint
;
1352 ret
= der_copy_oid(&asn1_oid_id_pkix_ppl_inheritAll
,
1353 &info
.proxyPolicy
.policyLanguage
);
1355 free_ProxyCertInfo(&info
);
1356 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1360 ASN1_MALLOC_ENCODE(ProxyCertInfo
, data
.data
, data
.length
,
1362 free_ProxyCertInfo(&info
);
1364 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1367 if (size
!= data
.length
)
1368 _hx509_abort("internal ASN.1 encoder error");
1369 ret
= add_extension(context
, tbsc
, 0,
1370 &asn1_oid_id_pkix_pe_proxyCertInfo
,
1377 if (tbs
->crldp
.len
) {
1379 ASN1_MALLOC_ENCODE(CRLDistributionPoints
, data
.data
, data
.length
,
1380 &tbs
->crldp
, &size
, ret
);
1382 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1385 if (size
!= data
.length
)
1386 _hx509_abort("internal ASN.1 encoder error");
1387 ret
= add_extension(context
, tbsc
, FALSE
,
1388 &asn1_oid_id_x509_ce_cRLDistributionPoints
,
1395 ASN1_MALLOC_ENCODE(TBSCertificate
, data
.data
, data
.length
,tbsc
, &size
, ret
);
1397 hx509_set_error_string(context
, 0, ret
, "malloc out of memory");
1400 if (data
.length
!= size
)
1401 _hx509_abort("internal ASN.1 encoder error");
1403 ret
= _hx509_create_signature_bitstring(context
,
1407 &c
.signatureAlgorithm
,
1413 ret
= hx509_cert_init(context
, &c
, certificate
);
1417 free_Certificate(&c
);
1422 free_Certificate(&c
);
1427 get_AuthorityKeyIdentifier(hx509_context context
,
1428 const Certificate
*certificate
,
1429 AuthorityKeyIdentifier
*ai
)
1431 SubjectKeyIdentifier si
;
1434 ret
= _hx509_find_extension_subject_key_id(certificate
, &si
);
1436 ai
->keyIdentifier
= calloc(1, sizeof(*ai
->keyIdentifier
));
1437 if (ai
->keyIdentifier
== NULL
) {
1438 free_SubjectKeyIdentifier(&si
);
1440 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1443 ret
= der_copy_octet_string(&si
, ai
->keyIdentifier
);
1444 free_SubjectKeyIdentifier(&si
);
1446 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1454 memset(&gn
, 0, sizeof(gn
));
1455 memset(&gns
, 0, sizeof(gns
));
1456 memset(&name
, 0, sizeof(name
));
1458 ai
->authorityCertIssuer
=
1459 calloc(1, sizeof(*ai
->authorityCertIssuer
));
1460 if (ai
->authorityCertIssuer
== NULL
) {
1462 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1465 ai
->authorityCertSerialNumber
=
1466 calloc(1, sizeof(*ai
->authorityCertSerialNumber
));
1467 if (ai
->authorityCertSerialNumber
== NULL
) {
1469 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1474 * XXX unbreak when asn1 compiler handle IMPLICIT
1476 * This is so horrible.
1479 ret
= copy_Name(&certificate
->tbsCertificate
.subject
, &name
);
1481 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1485 memset(&gn
, 0, sizeof(gn
));
1486 gn
.element
= choice_GeneralName_directoryName
;
1487 gn
.u
.directoryName
.element
=
1488 choice_GeneralName_directoryName_rdnSequence
;
1489 gn
.u
.directoryName
.u
.rdnSequence
= name
.u
.rdnSequence
;
1491 ret
= add_GeneralNames(&gns
, &gn
);
1493 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1497 ai
->authorityCertIssuer
->val
= gns
.val
;
1498 ai
->authorityCertIssuer
->len
= gns
.len
;
1500 ret
= der_copy_heim_integer(&certificate
->tbsCertificate
.serialNumber
,
1501 ai
->authorityCertSerialNumber
);
1502 if (ai
->authorityCertSerialNumber
== NULL
) {
1504 hx509_set_error_string(context
, 0, ret
, "Out of memory");
1510 free_AuthorityKeyIdentifier(ai
);
1516 * Sign a to-be-signed certificate object with a issuer certificate.
1518 * The caller needs to at least have called the following functions on the
1519 * to-be-signed certificate object:
1520 * - hx509_ca_tbs_init()
1521 * - hx509_ca_tbs_set_subject()
1522 * - hx509_ca_tbs_set_spki()
1524 * When done the to-be-signed certificate object should be freed with
1525 * hx509_ca_tbs_free().
1527 * When creating self-signed certificate use hx509_ca_sign_self() instead.
1529 * @param context A hx509 context.
1530 * @param tbs object to be signed.
1531 * @param signer the CA certificate object to sign with (need private key).
1532 * @param certificate return cerificate, free with hx509_cert_free().
1534 * @return An hx509 error code, see hx509_get_error_string().
1540 hx509_ca_sign(hx509_context context
,
1543 hx509_cert
*certificate
)
1545 const Certificate
*signer_cert
;
1546 AuthorityKeyIdentifier ai
;
1549 memset(&ai
, 0, sizeof(ai
));
1551 signer_cert
= _hx509_get_cert(signer
);
1553 ret
= get_AuthorityKeyIdentifier(context
, signer_cert
, &ai
);
1557 ret
= ca_sign(context
,
1559 _hx509_cert_private_key(signer
),
1561 &signer_cert
->tbsCertificate
.subject
,
1565 free_AuthorityKeyIdentifier(&ai
);
1571 * Work just like hx509_ca_sign() but signs it-self.
1573 * @param context A hx509 context.
1574 * @param tbs object to be signed.
1575 * @param signer private key to sign with.
1576 * @param certificate return cerificate, free with hx509_cert_free().
1578 * @return An hx509 error code, see hx509_get_error_string().
1584 hx509_ca_sign_self(hx509_context context
,
1586 hx509_private_key signer
,
1587 hx509_cert
*certificate
)
1589 return ca_sign(context
,