pluto supports ECDSA authentication
[strongswan.git] / src / libstrongswan / plugins / gcrypt / gcrypt_rsa_public_key.c
1 /*
2 * Copyright (C) 2005-2009 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 <gcrypt.h>
17
18 #include "gcrypt_rsa_public_key.h"
19
20 #include <debug.h>
21 #include <asn1/oid.h>
22 #include <asn1/asn1.h>
23 #include <asn1/asn1_parser.h>
24 #include <asn1/pem.h>
25 #include <crypto/hashers/hasher.h>
26
27 typedef struct private_gcrypt_rsa_public_key_t private_gcrypt_rsa_public_key_t;
28
29 /**
30 * Private data structure with signing context.
31 */
32 struct private_gcrypt_rsa_public_key_t {
33
34 /**
35 * Public interface for this signer.
36 */
37 gcrypt_rsa_public_key_t public;
38
39 /**
40 * gcrypt S-expression representing an public RSA key
41 */
42 gcry_sexp_t key;
43
44 /**
45 * Keyid formed as a SHA-1 hash of a publicKey object
46 */
47 identification_t* keyid;
48
49 /**
50 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
51 */
52 identification_t* keyid_info;
53
54 /**
55 * reference counter
56 */
57 refcount_t ref;
58 };
59
60 /**
61 * Implemented in gcrypt_rsa_private_key.c
62 */
63 chunk_t gcrypt_rsa_find_token(gcry_sexp_t sexp, char *name);
64 bool gcrypt_rsa_build_keyids(gcry_sexp_t key, identification_t **keyid,
65 identification_t **keyid_info);
66
67 /**
68 * Verification of an EMPSA PKCS1 signature described in PKCS#1
69 */
70 static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this,
71 hash_algorithm_t algorithm, char *hash_name,
72 chunk_t data, chunk_t signature)
73 {
74 hasher_t *hasher;
75 chunk_t hash;
76 gcry_error_t err;
77 gcry_sexp_t in, sig;
78
79 hasher = lib->crypto->create_hasher(lib->crypto, algorithm);
80 if (!hasher)
81 {
82 return FALSE;
83 }
84 hasher->allocate_hash(hasher, data, &hash);
85 hasher->destroy(hasher);
86
87 err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
88 hash_name, hash.len, hash.ptr);
89 chunk_free(&hash);
90 if (err)
91 {
92 DBG1("building data S-expression failed: %s", gpg_strerror(err));
93 return FALSE;
94 }
95
96 err = gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
97 signature.len, signature.ptr);
98 if (err)
99 {
100 DBG1("building signature S-expression failed: %s", gpg_strerror(err));
101 gcry_sexp_release(in);
102 return FALSE;
103 }
104 err = gcry_pk_verify(sig, in, this->key);
105 gcry_sexp_release(in);
106 gcry_sexp_release(sig);
107 if (err)
108 {
109 DBG1("RSA signature verification failed: %s", gpg_strerror(err));
110 return FALSE;
111 }
112 return TRUE;
113 }
114
115 /**
116 * Implementation of public_key_t.get_type.
117 */
118 static key_type_t get_type(private_gcrypt_rsa_public_key_t *this)
119 {
120 return KEY_RSA;
121 }
122
123 /**
124 * Implementation of public_key_t.verify.
125 */
126 static bool verify(private_gcrypt_rsa_public_key_t *this,
127 signature_scheme_t scheme, chunk_t data, chunk_t signature)
128 {
129 switch (scheme)
130 {
131 case SIGN_RSA_EMSA_PKCS1_MD5:
132 return verify_pkcs1(this, HASH_MD5, "md5", data, signature);
133 case SIGN_RSA_EMSA_PKCS1_SHA1:
134 return verify_pkcs1(this, HASH_SHA1, "sha1", data, signature);
135 case SIGN_RSA_EMSA_PKCS1_SHA256:
136 return verify_pkcs1(this, HASH_SHA256, "sha256", data, signature);
137 case SIGN_RSA_EMSA_PKCS1_SHA384:
138 return verify_pkcs1(this, HASH_SHA384, "sha384", data, signature);
139 case SIGN_RSA_EMSA_PKCS1_SHA512:
140 return verify_pkcs1(this, HASH_SHA512, "sha512", data, signature);
141 default:
142 DBG1("signature scheme %N not supported in RSA",
143 signature_scheme_names, scheme);
144 return FALSE;
145 }
146 }
147
148 /**
149 * Implementation of public_key_t.get_keysize.
150 */
151 static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t crypto,
152 chunk_t *plain)
153 {
154 DBG1("RSA public key encryption not implemented");
155 return FALSE;
156 }
157
158 /**
159 * Implementation of gcrypt_rsa_public_key.equals.
160 */
161 static bool equals(private_gcrypt_rsa_public_key_t *this, public_key_t *other)
162 {
163 identification_t *keyid;
164
165 if (&this->public.interface == other)
166 {
167 return TRUE;
168 }
169 if (other->get_type(other) != KEY_RSA)
170 {
171 return FALSE;
172 }
173 keyid = other->get_id(other, ID_PUBKEY_SHA1);
174 if (keyid && keyid->equals(keyid, this->keyid))
175 {
176 return TRUE;
177 }
178 keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
179 if (keyid && keyid->equals(keyid, this->keyid_info))
180 {
181 return TRUE;
182 }
183 return FALSE;
184 }
185
186 /**
187 * Implementation of public_key_t.get_keysize.
188 */
189 static size_t get_keysize(private_gcrypt_rsa_public_key_t *this)
190 {
191 return gcry_pk_get_nbits(this->key) / 8;
192 }
193
194 /**
195 * Implementation of public_key_t.get_id.
196 */
197 static identification_t *get_id(private_gcrypt_rsa_public_key_t *this,
198 id_type_t type)
199 {
200 switch (type)
201 {
202 case ID_PUBKEY_INFO_SHA1:
203 return this->keyid_info;
204 case ID_PUBKEY_SHA1:
205 return this->keyid;
206 default:
207 return NULL;
208 }
209 }
210
211 /*
212 * Implementation of public_key_t.get_encoding.
213 */
214 static chunk_t get_encoding(private_gcrypt_rsa_public_key_t *this)
215 {
216 return asn1_wrap(ASN1_SEQUENCE, "mm",
217 asn1_integer("m", gcrypt_rsa_find_token(this->key, "n")),
218 asn1_integer("m", gcrypt_rsa_find_token(this->key, "e")));
219 }
220
221 /**
222 * Implementation of public_key_t.get_ref.
223 */
224 static public_key_t* get_ref(private_gcrypt_rsa_public_key_t *this)
225 {
226 ref_get(&this->ref);
227 return &this->public.interface;
228 }
229
230 /**
231 * Implementation of gcrypt_rsa_public_key.destroy.
232 */
233 static void destroy(private_gcrypt_rsa_public_key_t *this)
234 {
235 if (ref_put(&this->ref))
236 {
237 DESTROY_IF(this->keyid);
238 DESTROY_IF(this->keyid_info);
239 gcry_sexp_release(this->key);
240 free(this);
241 }
242 }
243
244 /**
245 * Generic private constructor
246 */
247 static private_gcrypt_rsa_public_key_t *gcrypt_rsa_public_key_create_empty()
248 {
249 private_gcrypt_rsa_public_key_t *this = malloc_thing(private_gcrypt_rsa_public_key_t);
250
251 this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
252 this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
253 this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
254 this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
255 this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
256 this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
257 this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
258 this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
259 this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
260
261 this->key = NULL;
262 this->keyid = NULL;
263 this->keyid_info = NULL;
264 this->ref = 1;
265
266 return this;
267 }
268
269 /**
270 * Create a public key from a S-expression, used in gcrypt_rsa_private_key
271 */
272 public_key_t *gcrypt_rsa_public_key_create_from_sexp(gcry_sexp_t key)
273 {
274 private_gcrypt_rsa_public_key_t *this;
275 gcry_error_t err;
276 chunk_t n, e;
277
278 this = gcrypt_rsa_public_key_create_empty();
279 n = gcrypt_rsa_find_token(key, "n");
280 e = gcrypt_rsa_find_token(key, "e");
281
282 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
283 n.len, n.ptr, e.len, e.ptr);
284 chunk_free(&n);
285 chunk_free(&e);
286 if (err)
287 {
288 DBG1("loading public key failed: %s", gpg_strerror(err));
289 free(this);
290 return NULL;
291 }
292 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
293 {
294 destroy(this);
295 return NULL;
296 }
297 return &this->public.interface;
298 }
299
300 /**
301 * ASN.1 definition of RSApublicKey
302 */
303 static const asn1Object_t pubkeyObjects[] = {
304 { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
305 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
306 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
307 { 0, "exit", ASN1_EOC, ASN1_EXIT }
308 };
309 #define PUB_KEY_RSA_PUBLIC_KEY 0
310 #define PUB_KEY_MODULUS 1
311 #define PUB_KEY_EXPONENT 2
312
313 /**
314 * Load a public key from an ASN1 encoded blob
315 */
316 static gcrypt_rsa_public_key_t *load(chunk_t blob)
317 {
318 private_gcrypt_rsa_public_key_t *this;
319 asn1_parser_t *parser;
320 chunk_t object, n, e;
321 int objectID;
322 bool success = FALSE;
323 gcry_error_t err;
324
325 parser = asn1_parser_create(pubkeyObjects, blob);
326 while (parser->iterate(parser, &objectID, &object))
327 {
328 switch (objectID)
329 {
330 case PUB_KEY_MODULUS:
331 n = object;
332 break;
333 case PUB_KEY_EXPONENT:
334 e = object;
335 break;
336 }
337 }
338 success = parser->success(parser);
339 parser->destroy(parser);
340
341 if (!success)
342 {
343 return NULL;
344 }
345
346 this = gcrypt_rsa_public_key_create_empty();
347 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
348 n.len, n.ptr, e.len, e.ptr);
349 if (err)
350 {
351 DBG1("loading public key failed: %s", gpg_strerror(err));
352 free(this);
353 return NULL;
354 }
355 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
356 {
357 destroy(this);
358 return NULL;
359 }
360 return &this->public;
361 }
362
363 typedef struct private_builder_t private_builder_t;
364 /**
365 * Builder implementation for key loading
366 */
367 struct private_builder_t {
368 /** implements the builder interface */
369 builder_t public;
370 /** loaded public key */
371 gcrypt_rsa_public_key_t *key;
372 };
373
374 /**
375 * Implementation of builder_t.build
376 */
377 static gcrypt_rsa_public_key_t *build(private_builder_t *this)
378 {
379 gcrypt_rsa_public_key_t *key = this->key;
380
381 free(this);
382 return key;
383 }
384
385 /**
386 * Implementation of builder_t.add
387 */
388 static void add(private_builder_t *this, builder_part_t part, ...)
389 {
390 if (!this->key)
391 {
392 va_list args;
393
394 switch (part)
395 {
396 case BUILD_BLOB_ASN1_DER:
397 {
398 va_start(args, part);
399 this->key = load(va_arg(args, chunk_t));
400 va_end(args);
401 return;
402 }
403 default:
404 break;
405 }
406 }
407 if (this->key)
408 {
409 destroy((private_gcrypt_rsa_public_key_t*)this->key);
410 }
411 builder_cancel(&this->public);
412 }
413
414 /**
415 * Builder construction function
416 */
417 builder_t *gcrypt_rsa_public_key_builder(key_type_t type)
418 {
419 private_builder_t *this;
420
421 if (type != KEY_RSA)
422 {
423 return NULL;
424 }
425
426 this = malloc_thing(private_builder_t);
427
428 this->key = NULL;
429 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
430 this->public.build = (void*(*)(builder_t *this))build;
431
432 return &this->public;
433 }
434