1 /* Build a X.509 attribute certificate
2 * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
3 * Copyright (C) 2004 Andreas Steffen
4 * Zuercher Hochschule Winterthur, 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
16 * RCSID $Id: build.c,v 1.14 2005/09/06 11:47:57 as Exp $
24 #include "../pluto/constants.h"
25 #include "../pluto/defs.h"
26 #include "../pluto/oid.h"
27 #include "../pluto/asn1.h"
28 #include "../pluto/x509.h"
29 #include "../pluto/log.h"
33 static u_char ASN1_group_oid_str
[] = {
35 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
38 static const chunk_t ASN1_group_oid
= strchunk(ASN1_group_oid_str
);
40 static u_char ASN1_authorityKeyIdentifier_oid_str
[] = {
45 static const chunk_t ASN1_authorityKeyIdentifier_oid
46 = strchunk(ASN1_authorityKeyIdentifier_oid_str
);
48 static u_char ASN1_noRevAvail_ext_str
[] = {
56 static const chunk_t ASN1_noRevAvail_ext
= strchunk(ASN1_noRevAvail_ext_str
);
61 static chunk_t
build_directoryName(asn1_t tag
, chunk_t name
)
63 return asn1_wrap(tag
, "m",
64 asn1_simple_object(ASN1_CONTEXT_C_4
, name
));
70 static chunk_t
build_holder(void)
72 return asn1_wrap(ASN1_SEQUENCE
, "mm",
73 asn1_wrap(ASN1_CONTEXT_C_0
, "mm",
74 build_directoryName(ASN1_SEQUENCE
, user
->issuer
),
75 asn1_simple_object(ASN1_INTEGER
, user
->serialNumber
)
77 build_directoryName(ASN1_CONTEXT_C_1
, user
->subject
));
83 static chunk_t
build_v2_form(void)
85 return asn1_wrap(ASN1_CONTEXT_C_0
, "m",
86 build_directoryName(ASN1_SEQUENCE
, signer
->subject
));
90 * build attrCertValidityPeriod
92 static chunk_t
build_attr_cert_validity(void)
94 return asn1_wrap(ASN1_SEQUENCE
, "mm",
95 timetoasn1(¬Before
, ASN1_GENERALIZEDTIME
),
96 timetoasn1(¬After
, ASN1_GENERALIZEDTIME
));
102 static chunk_t
build_ietfAttributes(ietfAttrList_t
*list
)
104 chunk_t ietfAttributes
;
105 ietfAttrList_t
*item
= list
;
109 /* precalculate the total size of all values */
112 size_t len
= item
->attr
->value
.len
;
114 size
+= 1 + (len
> 0) + (len
>= 128) + (len
>= 256) + (len
>= 65536) + len
;
117 pos
= build_asn1_object(&ietfAttributes
, ASN1_SEQUENCE
, size
);
121 ietfAttr_t
*attr
= list
->attr
;
122 asn1_t type
= ASN1_NULL
;
126 case IETF_ATTRIBUTE_OCTETS
:
127 type
= ASN1_OCTET_STRING
;
129 case IETF_ATTRIBUTE_STRING
:
130 type
= ASN1_UTF8STRING
;
132 case IETF_ATTRIBUTE_OID
:
136 mv_chunk(&pos
, asn1_simple_object(type
, attr
->value
));
141 return asn1_wrap(ASN1_SEQUENCE
, "m", ietfAttributes
);
145 * build attribute type
147 static chunk_t
build_attribute_type(const chunk_t type
, chunk_t content
)
149 return asn1_wrap(ASN1_SEQUENCE
, "cm",
151 asn1_wrap(ASN1_SET
, "m", content
));
157 static chunk_t
build_attributes(void)
159 return asn1_wrap(ASN1_SEQUENCE
, "m",
160 build_attribute_type(ASN1_group_oid
,
161 build_ietfAttributes(groups
)));
165 * build authorityKeyIdentifier
167 static chunk_t
build_authorityKeyID(x509cert_t
*signer
)
169 chunk_t keyIdentifier
= (signer
->subjectKeyID
.ptr
== NULL
)
171 : asn1_simple_object(ASN1_CONTEXT_S_0
,
172 signer
->subjectKeyID
);
174 chunk_t authorityCertIssuer
= build_directoryName(ASN1_CONTEXT_C_1
,
177 chunk_t authorityCertSerialNumber
= asn1_simple_object(ASN1_CONTEXT_S_2
,
178 signer
->serialNumber
);
180 return asn1_wrap(ASN1_SEQUENCE
, "cm",
181 ASN1_authorityKeyIdentifier_oid
,
182 asn1_wrap(ASN1_OCTET_STRING
, "m",
183 asn1_wrap(ASN1_SEQUENCE
, "mmm",
186 authorityCertSerialNumber
195 static chunk_t
build_extensions(void)
197 return asn1_wrap(ASN1_SEQUENCE
, "mc",
198 build_authorityKeyID(signer
),
199 ASN1_noRevAvail_ext
);
203 * build attributeCertificateInfo
205 static chunk_t
build_attr_cert_info(void)
207 return asn1_wrap(ASN1_SEQUENCE
, "cmmcmmmm",
212 asn1_simple_object(ASN1_INTEGER
, serial
),
213 build_attr_cert_validity(),
219 * build an X.509 attribute certificate
221 chunk_t
build_attr_cert(void)
223 chunk_t attributeCertificateInfo
= build_attr_cert_info();
224 chunk_t signatureValue
= pkcs1_build_signature(attributeCertificateInfo
,
225 OID_SHA1
, signerkey
, TRUE
);
227 return asn1_wrap(ASN1_SEQUENCE
, "mcm",
228 attributeCertificateInfo
,