23058eccfc3d7d263b8d6a5748818bf215b481df
[strongswan.git] / src / libstrongswan / plugins / pubkey / pubkey_cert.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * $Id$
16 */
17
18 #include "pubkey_cert.h"
19
20 #include <debug.h>
21
22 /**
23 * defined in pubkey_public_key.c
24 */
25 extern public_key_t *pubkey_public_key_load(chunk_t blob);
26
27 typedef struct private_pubkey_cert_t private_pubkey_cert_t;
28
29 /**
30 * private data of pubkey_cert
31 */
32 struct private_pubkey_cert_t {
33
34 /**
35 * public functions
36 */
37 pubkey_cert_t public;
38
39 /**
40 * wrapped public key
41 */
42 public_key_t *key;
43
44 /**
45 * dummy issuer id, ID_ANY
46 */
47 identification_t *issuer;
48
49 /**
50 * reference count
51 */
52 refcount_t ref;
53 };
54
55 /**
56 * Implementation of certificate_t.get_type
57 */
58 static certificate_type_t get_type(private_pubkey_cert_t *this)
59 {
60 return CERT_TRUSTED_PUBKEY;
61 }
62
63 /**
64 * Implementation of certificate_t.get_subject
65 */
66 static identification_t* get_subject(private_pubkey_cert_t *this)
67 {
68 return this->key->get_id(this->key, ID_PUBKEY_SHA1);
69 }
70
71 /**
72 * Implementation of certificate_t.get_issuer
73 */
74 static identification_t* get_issuer(private_pubkey_cert_t *this)
75 {
76 return this->issuer;
77 }
78
79 /**
80 * Implementation of certificate_t.has_subject.
81 */
82 static id_match_t has_subject(private_pubkey_cert_t *this,
83 identification_t *subject)
84 {
85 identification_t *id;
86
87 id = this->key->get_id(this->key, subject->get_type(subject));
88 if (id)
89 {
90 return id->matches(id, subject);
91 }
92 return ID_MATCH_NONE;
93 }
94
95 /**
96 * Implementation of certificate_t.has_subject.
97 */
98 static id_match_t has_issuer(private_pubkey_cert_t *this,
99 identification_t *issuer)
100 {
101 return ID_MATCH_NONE;
102 }
103
104 /**
105 * Implementation of certificate_t.equals.
106 */
107 static bool equals(private_pubkey_cert_t *this, certificate_t *other)
108 {
109 if (this == (private_pubkey_cert_t*)other)
110 {
111 return TRUE;
112 }
113 if (other->get_type(other) != CERT_TRUSTED_PUBKEY)
114 {
115 return FALSE;
116 }
117 return other->has_subject(other, this->key->get_id(this->key, ID_PUBKEY_SHA1));
118 }
119
120 /**
121 * Implementation of certificate_t.issued_by
122 */
123 static bool issued_by(private_pubkey_cert_t *this, certificate_t *issuer)
124 {
125 return equals(this, issuer);
126 }
127
128 /**
129 * Implementation of certificate_t.get_public_key
130 */
131 static public_key_t* get_public_key(private_pubkey_cert_t *this)
132 {
133 this->key->get_ref(this->key);
134 return this->key;
135 }
136 /**
137 * Implementation of certificate_t.get_validity.
138 */
139 static bool get_validity(private_pubkey_cert_t *this, time_t *when,
140 time_t *not_before, time_t *not_after)
141 {
142 if (not_before)
143 {
144 *not_before = 0;
145 }
146 if (not_after)
147 {
148 *not_after = ~0;
149 }
150 return TRUE;
151 }
152
153 /**
154 * Implementation of certificate_t.is_newer.
155 */
156 static bool is_newer(certificate_t *this, certificate_t *that)
157 {
158 return FALSE;
159 }
160
161 /**
162 * Implementation of certificate_t.get_encoding.
163 */
164 static chunk_t get_encoding(private_pubkey_cert_t *this)
165 {
166 return this->key->get_encoding(this->key);
167 }
168
169 /**
170 * Implementation of certificate_t.get_ref
171 */
172 static private_pubkey_cert_t* get_ref(private_pubkey_cert_t *this)
173 {
174 ref_get(&this->ref);
175 return this;
176 }
177
178 /**
179 * Implementation of pubkey_cert_t.destroy
180 */
181 static void destroy(private_pubkey_cert_t *this)
182 {
183 if (ref_put(&this->ref))
184 {
185 this->issuer->destroy(this->issuer);
186 this->key->destroy(this->key);
187 free(this);
188 }
189 }
190
191 /*
192 * see header file
193 */
194 static pubkey_cert_t *pubkey_cert_create(public_key_t *key)
195 {
196 private_pubkey_cert_t *this = malloc_thing(private_pubkey_cert_t);
197
198 this->public.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
199 this->public.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
200 this->public.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
201 this->public.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
202 this->public.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
203 this->public.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
204 this->public.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
205 this->public.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
206 this->public.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
207 this->public.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
208 this->public.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
209 this->public.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
210 this->public.interface.destroy = (void (*)(certificate_t *this))destroy;
211
212 this->ref = 1;
213 this->key = key;
214 this->issuer = identification_create_from_encoding(ID_ANY, chunk_empty);
215
216 return &this->public;
217 }
218
219 static pubkey_cert_t *pubkey_cert_create_from_chunk(chunk_t blob)
220 {
221 public_key_t *key = pubkey_public_key_load(chunk_clone(blob));
222
223 return (key)? pubkey_cert_create(key) : NULL;
224 }
225
226 typedef struct private_builder_t private_builder_t;
227 /**
228 * Builder implementation for key loading
229 */
230 struct private_builder_t {
231 /** implements the builder interface */
232 builder_t public;
233 /** loaded public key */
234 pubkey_cert_t *key;
235 };
236
237 /**
238 * Implementation of builder_t.build
239 */
240 static pubkey_cert_t *build(private_builder_t *this)
241 {
242 pubkey_cert_t *key = this->key;
243
244 free(this);
245 return key;
246 }
247
248 /**
249 * Implementation of builder_t.add
250 */
251 static void add(private_builder_t *this, builder_part_t part, ...)
252 {
253 if (!this->key)
254 {
255 va_list args;
256
257 switch (part)
258 {
259 case BUILD_BLOB_ASN1_DER:
260 {
261 va_start(args, part);
262 this->key = pubkey_cert_create_from_chunk(va_arg(args, chunk_t));
263 va_end(args);
264 return;
265 }
266 case BUILD_PUBLIC_KEY:
267 {
268 va_start(args, part);
269 this->key = pubkey_cert_create(va_arg(args, public_key_t*));
270 va_end(args);
271 return;
272 }
273 default:
274 break;
275 }
276 }
277 if (this->key)
278 {
279 destroy((private_pubkey_cert_t*)this->key);
280 }
281 builder_cancel(&this->public);
282 }
283
284 /**
285 * Builder construction function
286 */
287 builder_t *pubkey_cert_builder(certificate_type_t type)
288 {
289 private_builder_t *this;
290
291 if (type != CERT_TRUSTED_PUBKEY)
292 {
293 return NULL;
294 }
295
296 this = malloc_thing(private_builder_t);
297
298 this->key = NULL;
299 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
300 this->public.build = (void*(*)(builder_t *this))build;
301
302 return &this->public;
303 }
304