cosmetics
[strongswan.git] / src / openac / build.c
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
5 *
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>.
10 *
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
14 * for more details.
15 *
16 * RCSID $Id$
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22
23 #include <asn1/oid.h>
24 #include <asn1/asn1.h>
25 #include <crypto/ietf_attr_list.h>
26 #include <utils/identification.h>
27
28 #include "build.h"
29
30 static u_char ASN1_group_oid_str[] = {
31 0x06, 0x08,
32 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
33 };
34
35 static const chunk_t ASN1_group_oid = chunk_from_buf(ASN1_group_oid_str);
36
37 static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
38 0x06, 0x03,
39 0x55, 0x1d, 0x23
40 };
41
42 static const chunk_t ASN1_authorityKeyIdentifier_oid =
43 chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str);
44
45 static u_char ASN1_noRevAvail_ext_str[] = {
46 0x30, 0x09,
47 0x06, 0x03,
48 0x55, 0x1d, 0x38,
49 0x04, 0x02,
50 0x05, 0x00
51 };
52
53 static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str);
54
55 /**
56 * build directoryName
57 */
58 static chunk_t build_directoryName(asn1_t tag, chunk_t name)
59 {
60 return asn1_wrap(tag, "m",
61 asn1_simple_object(ASN1_CONTEXT_C_4, name));
62 }
63
64 /**
65 * build holder
66 */
67 static chunk_t build_holder(void)
68 {
69 identification_t *issuer = usercert->get_issuer(usercert);
70 identification_t *subject = usercert->get_subject(usercert);
71
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))
76 ),
77 build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
78 }
79
80 /**
81 * build v2Form
82 */
83 static chunk_t build_v2_form(void)
84 {
85 identification_t *subject = signercert->get_subject(signercert);
86
87 return asn1_wrap(ASN1_CONTEXT_C_0, "m",
88 build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
89 }
90
91 /**
92 * build attrCertValidityPeriod
93 */
94 static chunk_t build_attr_cert_validity(void)
95 {
96 return asn1_wrap(ASN1_SEQUENCE, "mm",
97 timetoasn1(&notBefore, ASN1_GENERALIZEDTIME),
98 timetoasn1(&notAfter, ASN1_GENERALIZEDTIME));
99 }
100
101
102 /**
103 * build attribute type
104 */
105 static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
106 {
107 return asn1_wrap(ASN1_SEQUENCE, "cm",
108 type,
109 asn1_wrap(ASN1_SET, "m", content));
110 }
111
112 /**
113 * build attributes
114 */
115 static chunk_t build_attributes(void)
116 {
117 return asn1_wrap(ASN1_SEQUENCE, "m",
118 build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(groups)));
119 }
120
121 /**
122 * build authorityKeyIdentifier
123 */
124 static chunk_t build_authorityKeyID(x509_t *signer)
125 {
126 identification_t *issuer = signer->get_issuer(signer);
127 chunk_t subjectKeyID = signer->get_subjectKeyID(signer);
128
129 chunk_t keyIdentifier = (subjectKeyID.ptr == NULL)
130 ? chunk_empty
131 : asn1_simple_object(ASN1_CONTEXT_S_0, subjectKeyID);
132
133 chunk_t authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
134 issuer->get_encoding(issuer));
135
136 chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
137 signer->get_serialNumber(signer));
138
139 return asn1_wrap(ASN1_SEQUENCE, "cm",
140 ASN1_authorityKeyIdentifier_oid,
141 asn1_wrap(ASN1_OCTET_STRING, "m",
142 asn1_wrap(ASN1_SEQUENCE, "mmm",
143 keyIdentifier,
144 authorityCertIssuer,
145 authorityCertSerialNumber
146 )
147 )
148 );
149 }
150
151 /**
152 * build extensions
153 */
154 static chunk_t build_extensions(void)
155 {
156 return asn1_wrap(ASN1_SEQUENCE, "mc",
157 build_authorityKeyID(signercert),
158 ASN1_noRevAvail_ext);
159 }
160
161 /**
162 * build attributeCertificateInfo
163 */
164 static chunk_t build_attr_cert_info(void)
165 {
166 return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
167 ASN1_INTEGER_1,
168 build_holder(),
169 build_v2_form(),
170 ASN1_sha1WithRSA_id,
171 asn1_simple_object(ASN1_INTEGER, serial),
172 build_attr_cert_validity(),
173 build_attributes(),
174 build_extensions());
175 }
176
177
178 /**
179 * build an X.509 attribute certificate
180 */
181 chunk_t build_attr_cert(void)
182 {
183 u_char *pos;
184 chunk_t rawSignature, signatureValue;
185 chunk_t attributeCertificateInfo = build_attr_cert_info();
186
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);
192 *pos++ = 0x00;
193 memcpy(pos, rawSignature.ptr, rawSignature.len);
194 free(rawSignature.ptr);
195
196 return asn1_wrap(ASN1_SEQUENCE, "mcm",
197 attributeCertificateInfo,
198 ASN1_sha1WithRSA_id,
199 signatureValue);
200 }