]>
Commit | Line | Data |
---|---|---|
510c3426 JH |
1 | /** |
2 | * @file certreq_payload.c | |
3 | * | |
4 | * @brief Implementation of certreq_payload_t. | |
5 | * | |
6 | */ | |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
10 | * Hochschule fuer Technik Rapperswil | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify it | |
13 | * under the terms of the GNU General Public License as published by the | |
14 | * Free Software Foundation; either version 2 of the License, or (at your | |
15 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, but | |
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
19 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
20 | * for more details. | |
21 | */ | |
22 | ||
5113680f | 23 | #include <stddef.h> |
510c3426 | 24 | |
5113680f | 25 | #include "certreq_payload.h" |
510c3426 JH |
26 | |
27 | ||
28 | typedef struct private_certreq_payload_t private_certreq_payload_t; | |
29 | ||
30 | /** | |
31 | * Private data of an certreq_payload_t object. | |
32 | * | |
33 | */ | |
34 | struct private_certreq_payload_t { | |
35 | /** | |
36 | * Public certreq_payload_t interface. | |
37 | */ | |
38 | certreq_payload_t public; | |
39 | ||
40 | /** | |
41 | * Next payload type. | |
42 | */ | |
43 | u_int8_t next_payload; | |
44 | ||
45 | /** | |
46 | * Critical flag. | |
47 | */ | |
48 | bool critical; | |
49 | ||
50 | /** | |
51 | * Length of this payload. | |
52 | */ | |
53 | u_int16_t payload_length; | |
54 | ||
55 | /** | |
56 | * Encoding of the CERT Data. | |
57 | */ | |
58 | u_int8_t cert_encoding; | |
59 | ||
60 | /** | |
61 | * The contained certreq data value. | |
62 | */ | |
63 | chunk_t certreq_data; | |
64 | }; | |
65 | ||
66 | /** | |
67 | * Encoding rules to parse or generate a CERTREQ payload | |
68 | * | |
69 | * The defined offsets are the positions in a object of type | |
70 | * private_certreq_payload_t. | |
71 | * | |
72 | */ | |
73 | encoding_rule_t certreq_payload_encodings[] = { | |
74 | /* 1 Byte next payload type, stored in the field next_payload */ | |
75 | { U_INT_8, offsetof(private_certreq_payload_t, next_payload) }, | |
76 | /* the critical bit */ | |
77 | { FLAG, offsetof(private_certreq_payload_t, critical) }, | |
78 | /* 7 Bit reserved bits, nowhere stored */ | |
79 | { RESERVED_BIT, 0 }, | |
80 | { RESERVED_BIT, 0 }, | |
81 | { RESERVED_BIT, 0 }, | |
82 | { RESERVED_BIT, 0 }, | |
83 | { RESERVED_BIT, 0 }, | |
84 | { RESERVED_BIT, 0 }, | |
85 | { RESERVED_BIT, 0 }, | |
86 | /* Length of the whole payload*/ | |
87 | { PAYLOAD_LENGTH, offsetof(private_certreq_payload_t, payload_length)}, | |
88 | /* 1 Byte CERTREQ type*/ | |
89 | { U_INT_8, offsetof(private_certreq_payload_t, cert_encoding)}, | |
90 | /* some certreq data bytes, length is defined in PAYLOAD_LENGTH */ | |
91 | { CERTREQ_DATA, offsetof(private_certreq_payload_t, certreq_data)} | |
92 | }; | |
93 | ||
94 | /* | |
95 | 1 2 3 | |
96 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
97 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
98 | ! Next Payload !C! RESERVED ! Payload Length ! | |
99 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
100 | ! Cert Encoding ! ! | |
101 | +-+-+-+-+-+-+-+-+ ! | |
102 | ~ Certification Authority ~ | |
103 | ! ! | |
104 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
105 | */ | |
106 | ||
107 | /** | |
108 | * Implementation of payload_t.verify. | |
109 | */ | |
110 | static status_t verify(private_certreq_payload_t *this) | |
111 | { | |
510c3426 JH |
112 | if ((this->cert_encoding == 0) || |
113 | ((this->cert_encoding >= 14) && (this->cert_encoding <= 200))) | |
114 | { | |
115 | /* reserved IDs */ | |
116 | return FAILED; | |
117 | } | |
118 | return SUCCESS; | |
119 | } | |
120 | ||
121 | /** | |
122 | * Implementation of certreq_payload_t.get_encoding_rules. | |
123 | */ | |
124 | static void get_encoding_rules(private_certreq_payload_t *this, encoding_rule_t **rules, size_t *rule_count) | |
125 | { | |
126 | *rules = certreq_payload_encodings; | |
127 | *rule_count = sizeof(certreq_payload_encodings) / sizeof(encoding_rule_t); | |
128 | } | |
129 | ||
130 | /** | |
131 | * Implementation of payload_t.get_type. | |
132 | */ | |
133 | static payload_type_t get_payload_type(private_certreq_payload_t *this) | |
134 | { | |
135 | return CERTIFICATE_REQUEST; | |
136 | } | |
137 | ||
138 | /** | |
139 | * Implementation of payload_t.get_next_type. | |
140 | */ | |
141 | static payload_type_t get_next_type(private_certreq_payload_t *this) | |
142 | { | |
143 | return (this->next_payload); | |
144 | } | |
145 | ||
146 | /** | |
147 | * Implementation of payload_t.set_next_type. | |
148 | */ | |
149 | static void set_next_type(private_certreq_payload_t *this,payload_type_t type) | |
150 | { | |
151 | this->next_payload = type; | |
152 | } | |
153 | ||
154 | /** | |
155 | * Implementation of payload_t.get_length. | |
156 | */ | |
157 | static size_t get_length(private_certreq_payload_t *this) | |
158 | { | |
159 | return this->payload_length; | |
160 | } | |
161 | ||
162 | /** | |
163 | * Implementation of certreq_payload_t.set_cert_encoding. | |
164 | */ | |
165 | static void set_cert_encoding (private_certreq_payload_t *this, cert_encoding_t encoding) | |
166 | { | |
167 | this->cert_encoding = encoding; | |
168 | } | |
169 | ||
170 | /** | |
171 | * Implementation of certreq_payload_t.get_cert_encoding. | |
172 | */ | |
173 | static cert_encoding_t get_cert_encoding (private_certreq_payload_t *this) | |
174 | { | |
175 | return (this->cert_encoding); | |
176 | } | |
177 | ||
178 | /** | |
179 | * Implementation of certreq_payload_t.set_data. | |
180 | */ | |
181 | static void set_data (private_certreq_payload_t *this, chunk_t data) | |
182 | { | |
183 | if (this->certreq_data.ptr != NULL) | |
184 | { | |
5113680f | 185 | chunk_free(&(this->certreq_data)); |
510c3426 | 186 | } |
5113680f | 187 | this->certreq_data.ptr = clalloc(data.ptr,data.len); |
510c3426 JH |
188 | this->certreq_data.len = data.len; |
189 | this->payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH + this->certreq_data.len; | |
190 | } | |
191 | ||
192 | /** | |
193 | * Implementation of certreq_payload_t.get_data. | |
194 | */ | |
195 | static chunk_t get_data (private_certreq_payload_t *this) | |
196 | { | |
197 | return (this->certreq_data); | |
198 | } | |
199 | ||
200 | /** | |
201 | * Implementation of certreq_payload_t.get_data_clone. | |
202 | */ | |
203 | static chunk_t get_data_clone (private_certreq_payload_t *this) | |
204 | { | |
205 | chunk_t cloned_data; | |
206 | if (this->certreq_data.ptr == NULL) | |
207 | { | |
208 | return (this->certreq_data); | |
209 | } | |
5113680f | 210 | cloned_data.ptr = clalloc(this->certreq_data.ptr,this->certreq_data.len); |
510c3426 JH |
211 | cloned_data.len = this->certreq_data.len; |
212 | return cloned_data; | |
213 | } | |
214 | ||
215 | /** | |
216 | * Implementation of payload_t.destroy and certreq_payload_t.destroy. | |
217 | */ | |
218 | static void destroy(private_certreq_payload_t *this) | |
219 | { | |
220 | if (this->certreq_data.ptr != NULL) | |
221 | { | |
5113680f | 222 | chunk_free(&(this->certreq_data)); |
510c3426 JH |
223 | } |
224 | ||
5113680f | 225 | free(this); |
510c3426 JH |
226 | } |
227 | ||
228 | /* | |
229 | * Described in header | |
230 | */ | |
231 | certreq_payload_t *certreq_payload_create() | |
232 | { | |
5113680f | 233 | private_certreq_payload_t *this = malloc_thing(private_certreq_payload_t); |
510c3426 JH |
234 | |
235 | /* interface functions */ | |
236 | this->public.payload_interface.verify = (status_t (*) (payload_t *))verify; | |
237 | this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules; | |
238 | this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length; | |
239 | this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type; | |
240 | this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type; | |
241 | this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type; | |
242 | this->public.payload_interface.destroy = (void (*) (payload_t *))destroy; | |
243 | ||
244 | /* public functions */ | |
245 | this->public.destroy = (void (*) (certreq_payload_t *)) destroy; | |
246 | this->public.set_cert_encoding = (void (*) (certreq_payload_t *,cert_encoding_t)) set_cert_encoding; | |
247 | this->public.get_cert_encoding = (cert_encoding_t (*) (certreq_payload_t *)) get_cert_encoding; | |
248 | this->public.set_data = (void (*) (certreq_payload_t *,chunk_t)) set_data; | |
249 | this->public.get_data_clone = (chunk_t (*) (certreq_payload_t *)) get_data_clone; | |
250 | this->public.get_data = (chunk_t (*) (certreq_payload_t *)) get_data; | |
251 | ||
252 | /* private variables */ | |
253 | this->critical = FALSE; | |
254 | this->next_payload = NO_PAYLOAD; | |
255 | this->payload_length =CERTREQ_PAYLOAD_HEADER_LENGTH; | |
256 | this->certreq_data = CHUNK_INITIALIZER; | |
257 | ||
258 | return (&(this->public)); | |
259 | } |