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