enforce correct RSA signature lenght in gcrypt
[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, gcry_sexp_t key);
64 bool gcrypt_rsa_build_keyids(gcry_sexp_t key, identification_t **keyid,
65 identification_t **keyid_info);
66
67 /**
68 * verification of a padded PKCS1 signature without an OID
69 */
70 static bool verify_raw(private_gcrypt_rsa_public_key_t *this,
71 chunk_t data, chunk_t signature)
72 {
73 gcry_sexp_t in, sig;
74 gcry_error_t err;
75 chunk_t em;
76 size_t k;
77
78 /* EM = 0x00 || 0x01 || PS || 0x00 || T
79 * PS = 0xFF padding, with length to fill em
80 * T = data
81 */
82 k = gcry_pk_get_nbits(this->key) / 8;
83 if (data.len > k - 3)
84 {
85 return FALSE;
86 }
87 em = chunk_alloc(k);
88 memset(em.ptr, 0xFF, em.len);
89 em.ptr[0] = 0x00;
90 em.ptr[1] = 0x01;
91 em.ptr[em.len - data.len - 1] = 0x00;
92 memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
93
94 err = gcry_sexp_build(&in, NULL, "(data(flags raw)(value %b))",
95 em.len, em.ptr);
96 chunk_free(&em);
97 if (err)
98 {
99 DBG1("building data S-expression failed: %s", gpg_strerror(err));
100 return FALSE;
101 }
102 err = gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
103 signature.len, signature.ptr);
104 if (err)
105 {
106 DBG1("building signature S-expression failed: %s", gpg_strerror(err));
107 gcry_sexp_release(in);
108 return FALSE;
109 }
110 err = gcry_pk_verify(sig, in, this->key);
111 gcry_sexp_release(in);
112 gcry_sexp_release(sig);
113 if (err)
114 {
115 DBG1("RSA signature verification failed: %s", gpg_strerror(err));
116 return FALSE;
117 }
118 return TRUE;
119 }
120
121 /**
122 * Verification of an EMSA PKCS1 signature described in PKCS#1
123 */
124 static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this,
125 hash_algorithm_t algorithm, char *hash_name,
126 chunk_t data, chunk_t signature)
127 {
128 hasher_t *hasher;
129 chunk_t hash;
130 gcry_error_t err;
131 gcry_sexp_t in, sig;
132
133 hasher = lib->crypto->create_hasher(lib->crypto, algorithm);
134 if (!hasher)
135 {
136 return FALSE;
137 }
138 hasher->allocate_hash(hasher, data, &hash);
139 hasher->destroy(hasher);
140
141 err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
142 hash_name, hash.len, hash.ptr);
143 chunk_free(&hash);
144 if (err)
145 {
146 DBG1("building data S-expression failed: %s", gpg_strerror(err));
147 return FALSE;
148 }
149
150 err = gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
151 signature.len, signature.ptr);
152 if (err)
153 {
154 DBG1("building signature S-expression failed: %s", gpg_strerror(err));
155 gcry_sexp_release(in);
156 return FALSE;
157 }
158 err = gcry_pk_verify(sig, in, this->key);
159 gcry_sexp_release(in);
160 gcry_sexp_release(sig);
161 if (err)
162 {
163 DBG1("RSA signature verification failed: %s", gpg_strerror(err));
164 return FALSE;
165 }
166 return TRUE;
167 }
168
169 /**
170 * Implementation of public_key_t.get_type.
171 */
172 static key_type_t get_type(private_gcrypt_rsa_public_key_t *this)
173 {
174 return KEY_RSA;
175 }
176
177 /**
178 * Implementation of public_key_t.verify.
179 */
180 static bool verify(private_gcrypt_rsa_public_key_t *this,
181 signature_scheme_t scheme, chunk_t data, chunk_t signature)
182 {
183 switch (scheme)
184 {
185 case SIGN_RSA_EMSA_PKCS1_NULL:
186 return verify_raw(this, data, signature);
187 case SIGN_RSA_EMSA_PKCS1_MD5:
188 return verify_pkcs1(this, HASH_MD5, "md5", data, signature);
189 case SIGN_RSA_EMSA_PKCS1_SHA1:
190 return verify_pkcs1(this, HASH_SHA1, "sha1", data, signature);
191 case SIGN_RSA_EMSA_PKCS1_SHA256:
192 return verify_pkcs1(this, HASH_SHA256, "sha256", data, signature);
193 case SIGN_RSA_EMSA_PKCS1_SHA384:
194 return verify_pkcs1(this, HASH_SHA384, "sha384", data, signature);
195 case SIGN_RSA_EMSA_PKCS1_SHA512:
196 return verify_pkcs1(this, HASH_SHA512, "sha512", data, signature);
197 default:
198 DBG1("signature scheme %N not supported in RSA",
199 signature_scheme_names, scheme);
200 return FALSE;
201 }
202 }
203
204 /**
205 * Implementation of public_key_t.encrypt.
206 */
207 static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t plain,
208 chunk_t *encrypted)
209 {
210 gcry_sexp_t in, out;
211 gcry_error_t err;
212
213 /* "pkcs1" uses PKCS 1.5 (section 8.1) block type 2 encryption:
214 * 00 | 02 | RANDOM | 00 | DATA */
215 err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(value %b))",
216 plain.len, plain.ptr);
217 if (err)
218 {
219 DBG1("building encryption S-expression failed: %s", gpg_strerror(err));
220 return FALSE;
221 }
222 err = gcry_pk_encrypt(&out, in, this->key);
223 gcry_sexp_release(in);
224 if (err)
225 {
226 DBG1("encrypting data using pkcs1 failed: %s", gpg_strerror(err));
227 return FALSE;
228 }
229 *encrypted = gcrypt_rsa_find_token(out, "a", this->key);
230 gcry_sexp_release(out);
231 return !!encrypted->len;
232 }
233
234 /**
235 * Implementation of gcrypt_rsa_public_key.equals.
236 */
237 static bool equals(private_gcrypt_rsa_public_key_t *this, public_key_t *other)
238 {
239 identification_t *keyid;
240
241 if (&this->public.interface == other)
242 {
243 return TRUE;
244 }
245 if (other->get_type(other) != KEY_RSA)
246 {
247 return FALSE;
248 }
249 keyid = other->get_id(other, ID_PUBKEY_SHA1);
250 if (keyid && keyid->equals(keyid, this->keyid))
251 {
252 return TRUE;
253 }
254 keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
255 if (keyid && keyid->equals(keyid, this->keyid_info))
256 {
257 return TRUE;
258 }
259 return FALSE;
260 }
261
262 /**
263 * Implementation of public_key_t.get_keysize.
264 */
265 static size_t get_keysize(private_gcrypt_rsa_public_key_t *this)
266 {
267 return gcry_pk_get_nbits(this->key) / 8;
268 }
269
270 /**
271 * Implementation of public_key_t.get_id.
272 */
273 static identification_t *get_id(private_gcrypt_rsa_public_key_t *this,
274 id_type_t type)
275 {
276 switch (type)
277 {
278 case ID_PUBKEY_INFO_SHA1:
279 return this->keyid_info;
280 case ID_PUBKEY_SHA1:
281 return this->keyid;
282 default:
283 return NULL;
284 }
285 }
286
287 /*
288 * Implementation of public_key_t.get_encoding.
289 */
290 static chunk_t get_encoding(private_gcrypt_rsa_public_key_t *this)
291 {
292 return asn1_wrap(ASN1_SEQUENCE, "mm",
293 asn1_integer("m", gcrypt_rsa_find_token(this->key, "n", NULL)),
294 asn1_integer("m", gcrypt_rsa_find_token(this->key, "e", NULL)));
295 }
296
297 /**
298 * Implementation of public_key_t.get_ref.
299 */
300 static public_key_t* get_ref(private_gcrypt_rsa_public_key_t *this)
301 {
302 ref_get(&this->ref);
303 return &this->public.interface;
304 }
305
306 /**
307 * Implementation of gcrypt_rsa_public_key.destroy.
308 */
309 static void destroy(private_gcrypt_rsa_public_key_t *this)
310 {
311 if (ref_put(&this->ref))
312 {
313 DESTROY_IF(this->keyid);
314 DESTROY_IF(this->keyid_info);
315 gcry_sexp_release(this->key);
316 free(this);
317 }
318 }
319
320 /**
321 * Generic private constructor
322 */
323 static private_gcrypt_rsa_public_key_t *gcrypt_rsa_public_key_create_empty()
324 {
325 private_gcrypt_rsa_public_key_t *this = malloc_thing(private_gcrypt_rsa_public_key_t);
326
327 this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
328 this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
329 this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
330 this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
331 this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
332 this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
333 this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
334 this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
335 this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
336
337 this->key = NULL;
338 this->keyid = NULL;
339 this->keyid_info = NULL;
340 this->ref = 1;
341
342 return this;
343 }
344
345 /**
346 * Create a public key from a S-expression, used in gcrypt_rsa_private_key
347 */
348 public_key_t *gcrypt_rsa_public_key_create_from_sexp(gcry_sexp_t key)
349 {
350 private_gcrypt_rsa_public_key_t *this;
351 gcry_error_t err;
352 chunk_t n, e;
353
354 this = gcrypt_rsa_public_key_create_empty();
355 n = gcrypt_rsa_find_token(key, "n", NULL);
356 e = gcrypt_rsa_find_token(key, "e", NULL);
357
358 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
359 n.len, n.ptr, e.len, e.ptr);
360 chunk_free(&n);
361 chunk_free(&e);
362 if (err)
363 {
364 DBG1("loading public key failed: %s", gpg_strerror(err));
365 free(this);
366 return NULL;
367 }
368 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
369 {
370 destroy(this);
371 return NULL;
372 }
373 return &this->public.interface;
374 }
375
376 /**
377 * ASN.1 definition of RSApublicKey
378 */
379 static const asn1Object_t pubkeyObjects[] = {
380 { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
381 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
382 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
383 { 0, "exit", ASN1_EOC, ASN1_EXIT }
384 };
385 #define PUB_KEY_RSA_PUBLIC_KEY 0
386 #define PUB_KEY_MODULUS 1
387 #define PUB_KEY_EXPONENT 2
388
389 /**
390 * Load a public key from an ASN1 encoded blob
391 */
392 static gcrypt_rsa_public_key_t *load(chunk_t blob)
393 {
394 private_gcrypt_rsa_public_key_t *this;
395 asn1_parser_t *parser;
396 chunk_t object, n, e;
397 int objectID;
398 bool success = FALSE;
399 gcry_error_t err;
400
401 n = e = chunk_empty;
402
403 parser = asn1_parser_create(pubkeyObjects, blob);
404 while (parser->iterate(parser, &objectID, &object))
405 {
406 switch (objectID)
407 {
408 case PUB_KEY_MODULUS:
409 n = object;
410 break;
411 case PUB_KEY_EXPONENT:
412 e = object;
413 break;
414 }
415 }
416 success = parser->success(parser);
417 parser->destroy(parser);
418
419 if (!success)
420 {
421 return NULL;
422 }
423
424 this = gcrypt_rsa_public_key_create_empty();
425 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
426 n.len, n.ptr, e.len, e.ptr);
427 if (err)
428 {
429 DBG1("loading public key failed: %s", gpg_strerror(err));
430 free(this);
431 return NULL;
432 }
433 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
434 {
435 destroy(this);
436 return NULL;
437 }
438 return &this->public;
439 }
440
441 typedef struct private_builder_t private_builder_t;
442 /**
443 * Builder implementation for key loading
444 */
445 struct private_builder_t {
446 /** implements the builder interface */
447 builder_t public;
448 /** loaded public key */
449 gcrypt_rsa_public_key_t *key;
450 };
451
452 /**
453 * Implementation of builder_t.build
454 */
455 static gcrypt_rsa_public_key_t *build(private_builder_t *this)
456 {
457 gcrypt_rsa_public_key_t *key = this->key;
458
459 free(this);
460 return key;
461 }
462
463 /**
464 * Implementation of builder_t.add
465 */
466 static void add(private_builder_t *this, builder_part_t part, ...)
467 {
468 if (!this->key)
469 {
470 va_list args;
471
472 switch (part)
473 {
474 case BUILD_BLOB_ASN1_DER:
475 {
476 va_start(args, part);
477 this->key = load(va_arg(args, chunk_t));
478 va_end(args);
479 return;
480 }
481 default:
482 break;
483 }
484 }
485 if (this->key)
486 {
487 destroy((private_gcrypt_rsa_public_key_t*)this->key);
488 }
489 builder_cancel(&this->public);
490 }
491
492 /**
493 * Builder construction function
494 */
495 builder_t *gcrypt_rsa_public_key_builder(key_type_t type)
496 {
497 private_builder_t *this;
498
499 if (type != KEY_RSA)
500 {
501 return NULL;
502 }
503
504 this = malloc_thing(private_builder_t);
505
506 this->key = NULL;
507 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
508 this->public.build = (void*(*)(builder_t *this))build;
509
510 return &this->public;
511 }
512