1 /* Build a X.509 attribute certificate
2 * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
3 * Copyright (C) 2004,2007 Andreas Steffen
4 * Hochschule fuer Technik Rapperswil, Switzerland
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 #include <asn1/asn1.h>
25 #include <crypto/ietf_attr_list.h>
26 #include <utils/identification.h>
30 static u_char ASN1_group_oid_str
[] = {
32 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
35 static const chunk_t ASN1_group_oid
= chunk_from_buf(ASN1_group_oid_str
);
37 static u_char ASN1_authorityKeyIdentifier_oid_str
[] = {
42 static const chunk_t ASN1_authorityKeyIdentifier_oid
=
43 chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str
);
45 static u_char ASN1_noRevAvail_ext_str
[] = {
53 static const chunk_t ASN1_noRevAvail_ext
= chunk_from_buf(ASN1_noRevAvail_ext_str
);
58 static chunk_t
build_directoryName(asn1_t tag
, chunk_t name
)
60 return asn1_wrap(tag
, "m",
61 asn1_simple_object(ASN1_CONTEXT_C_4
, name
));
67 static chunk_t
build_holder(void)
69 identification_t
*issuer
= usercert
->get_issuer(usercert
);
70 identification_t
*subject
= usercert
->get_subject(usercert
);
72 return asn1_wrap(ASN1_SEQUENCE
, "mm",
73 asn1_wrap(ASN1_CONTEXT_C_0
, "mm",
74 build_directoryName(ASN1_SEQUENCE
, issuer
->get_encoding(issuer
)),
75 asn1_simple_object(ASN1_INTEGER
, usercert
->get_serialNumber(usercert
))
77 build_directoryName(ASN1_CONTEXT_C_1
, subject
->get_encoding(subject
)));
83 static chunk_t
build_v2_form(void)
85 identification_t
*subject
= signercert
->get_subject(signercert
);
87 return asn1_wrap(ASN1_CONTEXT_C_0
, "m",
88 build_directoryName(ASN1_SEQUENCE
, subject
->get_encoding(subject
)));
92 * build attrCertValidityPeriod
94 static chunk_t
build_attr_cert_validity(void)
96 return asn1_wrap(ASN1_SEQUENCE
, "mm",
97 timetoasn1(¬Before
, ASN1_GENERALIZEDTIME
),
98 timetoasn1(¬After
, ASN1_GENERALIZEDTIME
));
103 * build attribute type
105 static chunk_t
build_attribute_type(const chunk_t type
, chunk_t content
)
107 return asn1_wrap(ASN1_SEQUENCE
, "cm",
109 asn1_wrap(ASN1_SET
, "m", content
));
115 static chunk_t
build_attributes(void)
117 return asn1_wrap(ASN1_SEQUENCE
, "m",
118 build_attribute_type(ASN1_group_oid
, ietfAttr_list_encode(groups
)));
122 * build authorityKeyIdentifier
124 static chunk_t
build_authorityKeyID(x509_t
*signer
)
126 identification_t
*issuer
= signer
->get_issuer(signer
);
127 chunk_t subjectKeyID
= signer
->get_subjectKeyID(signer
);
129 chunk_t keyIdentifier
= (subjectKeyID
.ptr
== NULL
)
131 : asn1_simple_object(ASN1_CONTEXT_S_0
, subjectKeyID
);
133 chunk_t authorityCertIssuer
= build_directoryName(ASN1_CONTEXT_C_1
,
134 issuer
->get_encoding(issuer
));
136 chunk_t authorityCertSerialNumber
= asn1_simple_object(ASN1_CONTEXT_S_2
,
137 signer
->get_serialNumber(signer
));
139 return asn1_wrap(ASN1_SEQUENCE
, "cm",
140 ASN1_authorityKeyIdentifier_oid
,
141 asn1_wrap(ASN1_OCTET_STRING
, "m",
142 asn1_wrap(ASN1_SEQUENCE
, "mmm",
145 authorityCertSerialNumber
154 static chunk_t
build_extensions(void)
156 return asn1_wrap(ASN1_SEQUENCE
, "mc",
157 build_authorityKeyID(signercert
),
158 ASN1_noRevAvail_ext
);
162 * build attributeCertificateInfo
164 static chunk_t
build_attr_cert_info(void)
166 return asn1_wrap(ASN1_SEQUENCE
, "cmmcmmmm",
171 asn1_simple_object(ASN1_INTEGER
, serial
),
172 build_attr_cert_validity(),
179 * build an X.509 attribute certificate
181 chunk_t
build_attr_cert(void)
184 chunk_t rawSignature
, signatureValue
;
185 chunk_t attributeCertificateInfo
= build_attr_cert_info();
187 /* build the signature */
188 signerkey
->build_emsa_pkcs1_signature(signerkey
, HASH_SHA1
,
189 attributeCertificateInfo
, &rawSignature
);
190 pos
= build_asn1_object(&signatureValue
, ASN1_BIT_STRING
,
191 1 + rawSignature
.len
);
193 memcpy(pos
, rawSignature
.ptr
, rawSignature
.len
);
194 free(rawSignature
.ptr
);
196 return asn1_wrap(ASN1_SEQUENCE
, "mcm",
197 attributeCertificateInfo
,