moved RAW public key support to a separate plugin (pubkey)
[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 typedef struct private_pubkey_cert_t private_pubkey_cert_t;
23
24 /**
25 * private data of pubkey_cert
26 */
27 struct private_pubkey_cert_t {
28
29 /**
30 * public functions
31 */
32 pubkey_cert_t public;
33
34 /**
35 * wrapped public key
36 */
37 public_key_t *key;
38
39 /**
40 * dummy issuer id, ID_ANY
41 */
42 identification_t *issuer;
43
44 /**
45 * reference count
46 */
47 refcount_t ref;
48 };
49
50 /**
51 * Implementation of certificate_t.get_type
52 */
53 static certificate_type_t get_type(private_pubkey_cert_t *this)
54 {
55 return CERT_TRUSTED_PUBKEY;
56 }
57
58 /**
59 * Implementation of certificate_t.get_subject
60 */
61 static identification_t* get_subject(private_pubkey_cert_t *this)
62 {
63 return this->key->get_id(this->key, ID_PUBKEY_SHA1);
64 }
65
66 /**
67 * Implementation of certificate_t.get_issuer
68 */
69 static identification_t* get_issuer(private_pubkey_cert_t *this)
70 {
71 return this->issuer;
72 }
73
74 /**
75 * Implementation of certificate_t.has_subject.
76 */
77 static id_match_t has_subject(private_pubkey_cert_t *this,
78 identification_t *subject)
79 {
80 identification_t *id;
81
82 id = this->key->get_id(this->key, subject->get_type(subject));
83 if (id)
84 {
85 return id->matches(id, subject);
86 }
87 return ID_MATCH_NONE;
88 }
89
90 /**
91 * Implementation of certificate_t.has_subject.
92 */
93 static id_match_t has_issuer(private_pubkey_cert_t *this,
94 identification_t *issuer)
95 {
96 return ID_MATCH_NONE;
97 }
98
99 /**
100 * Implementation of certificate_t.equals.
101 */
102 static bool equals(private_pubkey_cert_t *this, certificate_t *other)
103 {
104 if (this == (private_pubkey_cert_t*)other)
105 {
106 return TRUE;
107 }
108 if (other->get_type(other) != CERT_TRUSTED_PUBKEY)
109 {
110 return FALSE;
111 }
112 return other->has_subject(other, this->key->get_id(this->key, ID_PUBKEY_SHA1));
113 }
114
115 /**
116 * Implementation of certificate_t.issued_by
117 */
118 static bool issued_by(private_pubkey_cert_t *this, certificate_t *issuer)
119 {
120 return equals(this, issuer);
121 }
122
123 /**
124 * Implementation of certificate_t.get_public_key
125 */
126 static public_key_t* get_public_key(private_pubkey_cert_t *this)
127 {
128 this->key->get_ref(this->key);
129 return this->key;
130 }
131 /**
132 * Implementation of certificate_t.get_validity.
133 */
134 static bool get_validity(private_pubkey_cert_t *this, time_t *when,
135 time_t *not_before, time_t *not_after)
136 {
137 if (not_before)
138 {
139 *not_before = 0;
140 }
141 if (not_after)
142 {
143 *not_after = ~0;
144 }
145 return TRUE;
146 }
147
148 /**
149 * Implementation of certificate_t.is_newer.
150 */
151 static bool is_newer(certificate_t *this, certificate_t *that)
152 {
153 return FALSE;
154 }
155
156 /**
157 * Implementation of certificate_t.get_encoding.
158 */
159 static chunk_t get_encoding(private_pubkey_cert_t *this)
160 {
161 return this->key->get_encoding(this->key);
162 }
163
164 /**
165 * Implementation of certificate_t.get_ref
166 */
167 static private_pubkey_cert_t* get_ref(private_pubkey_cert_t *this)
168 {
169 ref_get(&this->ref);
170 return this;
171 }
172
173 /**
174 * Implementation of pubkey_cert_t.destroy
175 */
176 static void destroy(private_pubkey_cert_t *this)
177 {
178 if (ref_put(&this->ref))
179 {
180 this->issuer->destroy(this->issuer);
181 this->key->destroy(this->key);
182 free(this);
183 }
184 }
185
186 /*
187 * see header file
188 */
189 static pubkey_cert_t *pubkey_cert_create(public_key_t *key)
190 {
191 private_pubkey_cert_t *this = malloc_thing(private_pubkey_cert_t);
192
193 this->public.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
194 this->public.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
195 this->public.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
196 this->public.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
197 this->public.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
198 this->public.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
199 this->public.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
200 this->public.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
201 this->public.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
202 this->public.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
203 this->public.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
204 this->public.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
205 this->public.interface.destroy = (void (*)(certificate_t *this))destroy;
206
207 this->ref = 1;
208 this->key = key;
209 this->issuer = identification_create_from_encoding(ID_ANY, chunk_empty);
210
211 return &this->public;
212 }
213
214 typedef struct private_builder_t private_builder_t;
215 /**
216 * Builder implementation for key loading
217 */
218 struct private_builder_t {
219 /** implements the builder interface */
220 builder_t public;
221 /** loaded public key */
222 pubkey_cert_t *key;
223 };
224
225 /**
226 * Implementation of builder_t.build
227 */
228 static pubkey_cert_t *build(private_builder_t *this)
229 {
230 pubkey_cert_t *key = this->key;
231
232 free(this);
233 return key;
234 }
235
236 /**
237 * Implementation of builder_t.add
238 */
239 static void add(private_builder_t *this, builder_part_t part, ...)
240 {
241 va_list args;
242
243 if (this->key)
244 {
245 DBG1("ignoring surplus build part %N", builder_part_names, part);
246 return;
247 }
248
249 switch (part)
250 {
251 case BUILD_PUBLIC_KEY:
252 {
253 va_start(args, part);
254 this->key = pubkey_cert_create(va_arg(args, public_key_t*));
255 va_end(args);
256 break;
257 }
258 default:
259 DBG1("ignoring unsupported build part %N", builder_part_names, part);
260 break;
261 }
262 }
263
264 /**
265 * Builder construction function
266 */
267 builder_t *pubkey_cert_builder(certificate_type_t type)
268 {
269 private_builder_t *this;
270
271 if (type != CERT_TRUSTED_PUBKEY)
272 {
273 return NULL;
274 }
275
276 this = malloc_thing(private_builder_t);
277
278 this->key = NULL;
279 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
280 this->public.build = (void*(*)(builder_t *this))build;
281
282 return &this->public;
283 }
284