removed oid.txt and oid.pl in pluto subdir
[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 Andreas Steffen
4 * Zuercher Hochschule Winterthur, 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: build.c,v 1.14 2005/09/06 11:47:57 as Exp $
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <freeswan.h>
23
24 #include <asn1/oid.h>
25
26 #include "../pluto/constants.h"
27 #include "../pluto/defs.h"
28 #include "../pluto/asn1.h"
29 #include "../pluto/x509.h"
30 #include "../pluto/log.h"
31
32 #include "build.h"
33
34 static u_char ASN1_group_oid_str[] = {
35 0x06, 0x08,
36 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
37 };
38
39 static const chunk_t ASN1_group_oid = strchunk(ASN1_group_oid_str);
40
41 static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
42 0x06, 0x03,
43 0x55, 0x1d, 0x23
44 };
45
46 static const chunk_t ASN1_authorityKeyIdentifier_oid
47 = strchunk(ASN1_authorityKeyIdentifier_oid_str);
48
49 static u_char ASN1_noRevAvail_ext_str[] = {
50 0x30, 0x09,
51 0x06, 0x03,
52 0x55, 0x1d, 0x38,
53 0x04, 0x02,
54 0x05, 0x00
55 };
56
57 static const chunk_t ASN1_noRevAvail_ext = strchunk(ASN1_noRevAvail_ext_str);
58
59 /**
60 * build directoryName
61 */
62 static chunk_t build_directoryName(asn1_t tag, chunk_t name)
63 {
64 return asn1_wrap(tag, "m",
65 asn1_simple_object(ASN1_CONTEXT_C_4, name));
66 }
67
68 /**
69 * build holder
70 */
71 static chunk_t build_holder(void)
72 {
73 return asn1_wrap(ASN1_SEQUENCE, "mm",
74 asn1_wrap(ASN1_CONTEXT_C_0, "mm",
75 build_directoryName(ASN1_SEQUENCE, user->issuer),
76 asn1_simple_object(ASN1_INTEGER, user->serialNumber)
77 ),
78 build_directoryName(ASN1_CONTEXT_C_1, user->subject));
79 }
80
81 /**
82 * build v2Form
83 */
84 static chunk_t build_v2_form(void)
85 {
86 return asn1_wrap(ASN1_CONTEXT_C_0, "m",
87 build_directoryName(ASN1_SEQUENCE, signer->subject));
88 }
89
90 /**
91 * build attrCertValidityPeriod
92 */
93 static chunk_t build_attr_cert_validity(void)
94 {
95 return asn1_wrap(ASN1_SEQUENCE, "mm",
96 timetoasn1(&notBefore, ASN1_GENERALIZEDTIME),
97 timetoasn1(&notAfter, ASN1_GENERALIZEDTIME));
98 }
99
100 /**
101 * build attributes
102 */
103 static chunk_t build_ietfAttributes(ietfAttrList_t *list)
104 {
105 chunk_t ietfAttributes;
106 ietfAttrList_t *item = list;
107 size_t size = 0;
108 u_char *pos;
109
110 /* precalculate the total size of all values */
111 while (item != NULL)
112 {
113 size_t len = item->attr->value.len;
114
115 size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
116 item = item->next;
117 }
118 pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
119
120 while (list != NULL)
121 {
122 ietfAttr_t *attr = list->attr;
123 asn1_t type = ASN1_NULL;
124
125 switch (attr->kind)
126 {
127 case IETF_ATTRIBUTE_OCTETS:
128 type = ASN1_OCTET_STRING;
129 break;
130 case IETF_ATTRIBUTE_STRING:
131 type = ASN1_UTF8STRING;
132 break;
133 case IETF_ATTRIBUTE_OID:
134 type = ASN1_OID;
135 break;
136 }
137 mv_chunk(&pos, asn1_simple_object(type, attr->value));
138
139 list = list->next;
140 }
141
142 return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
143 }
144
145 /**
146 * build attribute type
147 */
148 static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
149 {
150 return asn1_wrap(ASN1_SEQUENCE, "cm",
151 type,
152 asn1_wrap(ASN1_SET, "m", content));
153 }
154
155 /**
156 * build attributes
157 */
158 static chunk_t build_attributes(void)
159 {
160 return asn1_wrap(ASN1_SEQUENCE, "m",
161 build_attribute_type(ASN1_group_oid,
162 build_ietfAttributes(groups)));
163 }
164
165 /**
166 * build authorityKeyIdentifier
167 */
168 static chunk_t build_authorityKeyID(x509cert_t *signer)
169 {
170 chunk_t keyIdentifier = (signer->subjectKeyID.ptr == NULL)
171 ? empty_chunk
172 : asn1_simple_object(ASN1_CONTEXT_S_0,
173 signer->subjectKeyID);
174
175 chunk_t authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
176 signer->issuer);
177
178 chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
179 signer->serialNumber);
180
181 return asn1_wrap(ASN1_SEQUENCE, "cm",
182 ASN1_authorityKeyIdentifier_oid,
183 asn1_wrap(ASN1_OCTET_STRING, "m",
184 asn1_wrap(ASN1_SEQUENCE, "mmm",
185 keyIdentifier,
186 authorityCertIssuer,
187 authorityCertSerialNumber
188 )
189 )
190 );
191 }
192
193 /**
194 * build extensions
195 */
196 static chunk_t build_extensions(void)
197 {
198 return asn1_wrap(ASN1_SEQUENCE, "mc",
199 build_authorityKeyID(signer),
200 ASN1_noRevAvail_ext);
201 }
202
203 /**
204 * build attributeCertificateInfo
205 */
206 static chunk_t build_attr_cert_info(void)
207 {
208 return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
209 ASN1_INTEGER_1,
210 build_holder(),
211 build_v2_form(),
212 ASN1_sha1WithRSA_id,
213 asn1_simple_object(ASN1_INTEGER, serial),
214 build_attr_cert_validity(),
215 build_attributes(),
216 build_extensions());
217 }
218
219 /**
220 * build an X.509 attribute certificate
221 */
222 chunk_t build_attr_cert(void)
223 {
224 chunk_t attributeCertificateInfo = build_attr_cert_info();
225 chunk_t signatureValue = pkcs1_build_signature(attributeCertificateInfo,
226 OID_SHA1, signerkey, TRUE);
227
228 return asn1_wrap(ASN1_SEQUENCE, "mcm",
229 attributeCertificateInfo,
230 ASN1_sha1WithRSA_id,
231 signatureValue);
232 }