implemented IKEv1 specific SIGN_RSA_EMSA_PKCS1_NULL scheme 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);
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.get_keysize.
206 */
207 static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t crypto,
208 chunk_t *plain)
209 {
210 DBG1("RSA public key encryption not implemented");
211 return FALSE;
212 }
213
214 /**
215 * Implementation of gcrypt_rsa_public_key.equals.
216 */
217 static bool equals(private_gcrypt_rsa_public_key_t *this, public_key_t *other)
218 {
219 identification_t *keyid;
220
221 if (&this->public.interface == other)
222 {
223 return TRUE;
224 }
225 if (other->get_type(other) != KEY_RSA)
226 {
227 return FALSE;
228 }
229 keyid = other->get_id(other, ID_PUBKEY_SHA1);
230 if (keyid && keyid->equals(keyid, this->keyid))
231 {
232 return TRUE;
233 }
234 keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
235 if (keyid && keyid->equals(keyid, this->keyid_info))
236 {
237 return TRUE;
238 }
239 return FALSE;
240 }
241
242 /**
243 * Implementation of public_key_t.get_keysize.
244 */
245 static size_t get_keysize(private_gcrypt_rsa_public_key_t *this)
246 {
247 return gcry_pk_get_nbits(this->key) / 8;
248 }
249
250 /**
251 * Implementation of public_key_t.get_id.
252 */
253 static identification_t *get_id(private_gcrypt_rsa_public_key_t *this,
254 id_type_t type)
255 {
256 switch (type)
257 {
258 case ID_PUBKEY_INFO_SHA1:
259 return this->keyid_info;
260 case ID_PUBKEY_SHA1:
261 return this->keyid;
262 default:
263 return NULL;
264 }
265 }
266
267 /*
268 * Implementation of public_key_t.get_encoding.
269 */
270 static chunk_t get_encoding(private_gcrypt_rsa_public_key_t *this)
271 {
272 return asn1_wrap(ASN1_SEQUENCE, "mm",
273 asn1_integer("m", gcrypt_rsa_find_token(this->key, "n")),
274 asn1_integer("m", gcrypt_rsa_find_token(this->key, "e")));
275 }
276
277 /**
278 * Implementation of public_key_t.get_ref.
279 */
280 static public_key_t* get_ref(private_gcrypt_rsa_public_key_t *this)
281 {
282 ref_get(&this->ref);
283 return &this->public.interface;
284 }
285
286 /**
287 * Implementation of gcrypt_rsa_public_key.destroy.
288 */
289 static void destroy(private_gcrypt_rsa_public_key_t *this)
290 {
291 if (ref_put(&this->ref))
292 {
293 DESTROY_IF(this->keyid);
294 DESTROY_IF(this->keyid_info);
295 gcry_sexp_release(this->key);
296 free(this);
297 }
298 }
299
300 /**
301 * Generic private constructor
302 */
303 static private_gcrypt_rsa_public_key_t *gcrypt_rsa_public_key_create_empty()
304 {
305 private_gcrypt_rsa_public_key_t *this = malloc_thing(private_gcrypt_rsa_public_key_t);
306
307 this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
308 this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
309 this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
310 this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
311 this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
312 this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
313 this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
314 this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
315 this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
316
317 this->key = NULL;
318 this->keyid = NULL;
319 this->keyid_info = NULL;
320 this->ref = 1;
321
322 return this;
323 }
324
325 /**
326 * Create a public key from a S-expression, used in gcrypt_rsa_private_key
327 */
328 public_key_t *gcrypt_rsa_public_key_create_from_sexp(gcry_sexp_t key)
329 {
330 private_gcrypt_rsa_public_key_t *this;
331 gcry_error_t err;
332 chunk_t n, e;
333
334 this = gcrypt_rsa_public_key_create_empty();
335 n = gcrypt_rsa_find_token(key, "n");
336 e = gcrypt_rsa_find_token(key, "e");
337
338 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
339 n.len, n.ptr, e.len, e.ptr);
340 chunk_free(&n);
341 chunk_free(&e);
342 if (err)
343 {
344 DBG1("loading public key failed: %s", gpg_strerror(err));
345 free(this);
346 return NULL;
347 }
348 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
349 {
350 destroy(this);
351 return NULL;
352 }
353 return &this->public.interface;
354 }
355
356 /**
357 * ASN.1 definition of RSApublicKey
358 */
359 static const asn1Object_t pubkeyObjects[] = {
360 { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
361 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
362 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
363 { 0, "exit", ASN1_EOC, ASN1_EXIT }
364 };
365 #define PUB_KEY_RSA_PUBLIC_KEY 0
366 #define PUB_KEY_MODULUS 1
367 #define PUB_KEY_EXPONENT 2
368
369 /**
370 * Load a public key from an ASN1 encoded blob
371 */
372 static gcrypt_rsa_public_key_t *load(chunk_t blob)
373 {
374 private_gcrypt_rsa_public_key_t *this;
375 asn1_parser_t *parser;
376 chunk_t object, n, e;
377 int objectID;
378 bool success = FALSE;
379 gcry_error_t err;
380
381 parser = asn1_parser_create(pubkeyObjects, blob);
382 while (parser->iterate(parser, &objectID, &object))
383 {
384 switch (objectID)
385 {
386 case PUB_KEY_MODULUS:
387 n = object;
388 break;
389 case PUB_KEY_EXPONENT:
390 e = object;
391 break;
392 }
393 }
394 success = parser->success(parser);
395 parser->destroy(parser);
396
397 if (!success)
398 {
399 return NULL;
400 }
401
402 this = gcrypt_rsa_public_key_create_empty();
403 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
404 n.len, n.ptr, e.len, e.ptr);
405 if (err)
406 {
407 DBG1("loading public key failed: %s", gpg_strerror(err));
408 free(this);
409 return NULL;
410 }
411 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
412 {
413 destroy(this);
414 return NULL;
415 }
416 return &this->public;
417 }
418
419 typedef struct private_builder_t private_builder_t;
420 /**
421 * Builder implementation for key loading
422 */
423 struct private_builder_t {
424 /** implements the builder interface */
425 builder_t public;
426 /** loaded public key */
427 gcrypt_rsa_public_key_t *key;
428 };
429
430 /**
431 * Implementation of builder_t.build
432 */
433 static gcrypt_rsa_public_key_t *build(private_builder_t *this)
434 {
435 gcrypt_rsa_public_key_t *key = this->key;
436
437 free(this);
438 return key;
439 }
440
441 /**
442 * Implementation of builder_t.add
443 */
444 static void add(private_builder_t *this, builder_part_t part, ...)
445 {
446 if (!this->key)
447 {
448 va_list args;
449
450 switch (part)
451 {
452 case BUILD_BLOB_ASN1_DER:
453 {
454 va_start(args, part);
455 this->key = load(va_arg(args, chunk_t));
456 va_end(args);
457 return;
458 }
459 default:
460 break;
461 }
462 }
463 if (this->key)
464 {
465 destroy((private_gcrypt_rsa_public_key_t*)this->key);
466 }
467 builder_cancel(&this->public);
468 }
469
470 /**
471 * Builder construction function
472 */
473 builder_t *gcrypt_rsa_public_key_builder(key_type_t type)
474 {
475 private_builder_t *this;
476
477 if (type != KEY_RSA)
478 {
479 return NULL;
480 }
481
482 this = malloc_thing(private_builder_t);
483
484 this->key = NULL;
485 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
486 this->public.build = (void*(*)(builder_t *this))build;
487
488 return &this->public;
489 }
490