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