asn1_integer() ensures correct DER encoding of ASN1_INTEGER (two's complement)
[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 case SIGN_DEFAULT:
142 /* parsing hash OID currently not supported by gcrypt, fall */
143 default:
144 DBG1("signature scheme %N not supported in RSA",
145 signature_scheme_names, scheme);
146 return FALSE;
147 }
148 }
149
150 /**
151 * Implementation of public_key_t.get_keysize.
152 */
153 static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t crypto,
154 chunk_t *plain)
155 {
156 DBG1("RSA public key encryption not implemented");
157 return FALSE;
158 }
159
160 /**
161 * Implementation of gcrypt_rsa_public_key.equals.
162 */
163 static bool equals(private_gcrypt_rsa_public_key_t *this, public_key_t *other)
164 {
165 identification_t *keyid;
166
167 if (&this->public.interface == other)
168 {
169 return TRUE;
170 }
171 if (other->get_type(other) != KEY_RSA)
172 {
173 return FALSE;
174 }
175 keyid = other->get_id(other, ID_PUBKEY_SHA1);
176 if (keyid && keyid->equals(keyid, this->keyid))
177 {
178 return TRUE;
179 }
180 keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
181 if (keyid && keyid->equals(keyid, this->keyid_info))
182 {
183 return TRUE;
184 }
185 return FALSE;
186 }
187
188 /**
189 * Implementation of public_key_t.get_keysize.
190 */
191 static size_t get_keysize(private_gcrypt_rsa_public_key_t *this)
192 {
193 return gcry_pk_get_nbits(this->key) / 8;
194 }
195
196 /**
197 * Implementation of public_key_t.get_id.
198 */
199 static identification_t *get_id(private_gcrypt_rsa_public_key_t *this,
200 id_type_t type)
201 {
202 switch (type)
203 {
204 case ID_PUBKEY_INFO_SHA1:
205 return this->keyid_info;
206 case ID_PUBKEY_SHA1:
207 return this->keyid;
208 default:
209 return NULL;
210 }
211 }
212
213 /*
214 * Implementation of public_key_t.get_encoding.
215 */
216 static chunk_t get_encoding(private_gcrypt_rsa_public_key_t *this)
217 {
218 return asn1_wrap(ASN1_SEQUENCE, "mm",
219 asn1_integer("m", gcrypt_rsa_find_token(this->key, "n")),
220 asn1_integer("m", gcrypt_rsa_find_token(this->key, "e")));
221 }
222
223 /**
224 * Implementation of public_key_t.get_ref.
225 */
226 static public_key_t* get_ref(private_gcrypt_rsa_public_key_t *this)
227 {
228 ref_get(&this->ref);
229 return &this->public.interface;
230 }
231
232 /**
233 * Implementation of gcrypt_rsa_public_key.destroy.
234 */
235 static void destroy(private_gcrypt_rsa_public_key_t *this)
236 {
237 if (ref_put(&this->ref))
238 {
239 DESTROY_IF(this->keyid);
240 DESTROY_IF(this->keyid_info);
241 gcry_sexp_release(this->key);
242 free(this);
243 }
244 }
245
246 /**
247 * Generic private constructor
248 */
249 static private_gcrypt_rsa_public_key_t *gcrypt_rsa_public_key_create_empty()
250 {
251 private_gcrypt_rsa_public_key_t *this = malloc_thing(private_gcrypt_rsa_public_key_t);
252
253 this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
254 this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
255 this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
256 this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
257 this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
258 this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
259 this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
260 this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
261 this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
262
263 this->key = NULL;
264 this->keyid = NULL;
265 this->keyid_info = NULL;
266 this->ref = 1;
267
268 return this;
269 }
270
271 /**
272 * Create a public key from a S-expression, used in gcrypt_rsa_private_key
273 */
274 public_key_t *gcrypt_rsa_public_key_create_from_sexp(gcry_sexp_t key)
275 {
276 private_gcrypt_rsa_public_key_t *this;
277 gcry_error_t err;
278 chunk_t n, e;
279
280 this = gcrypt_rsa_public_key_create_empty();
281 n = gcrypt_rsa_find_token(key, "n");
282 e = gcrypt_rsa_find_token(key, "e");
283
284 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
285 n.len, n.ptr, e.len, e.ptr);
286 chunk_free(&n);
287 chunk_free(&e);
288 if (err)
289 {
290 DBG1("loading public key failed: %s", gpg_strerror(err));
291 free(this);
292 return NULL;
293 }
294 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
295 {
296 destroy(this);
297 return NULL;
298 }
299 return &this->public.interface;
300 }
301
302 /**
303 * ASN.1 definition of RSApublicKey
304 */
305 static const asn1Object_t pubkeyObjects[] = {
306 { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
307 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
308 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
309 { 0, "exit", ASN1_EOC, ASN1_EXIT }
310 };
311 #define PUB_KEY_RSA_PUBLIC_KEY 0
312 #define PUB_KEY_MODULUS 1
313 #define PUB_KEY_EXPONENT 2
314
315 /**
316 * Load a public key from an ASN1 encoded blob
317 */
318 static gcrypt_rsa_public_key_t *load(chunk_t blob)
319 {
320 private_gcrypt_rsa_public_key_t *this;
321 asn1_parser_t *parser;
322 chunk_t object, n, e;
323 int objectID;
324 bool success = FALSE;
325 gcry_error_t err;
326
327 parser = asn1_parser_create(pubkeyObjects, blob);
328 while (parser->iterate(parser, &objectID, &object))
329 {
330 switch (objectID)
331 {
332 case PUB_KEY_MODULUS:
333 n = object;
334 break;
335 case PUB_KEY_EXPONENT:
336 e = object;
337 break;
338 }
339 }
340 success = parser->success(parser);
341 parser->destroy(parser);
342
343 if (!success)
344 {
345 return NULL;
346 }
347
348 this = gcrypt_rsa_public_key_create_empty();
349 err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
350 n.len, n.ptr, e.len, e.ptr);
351 if (err)
352 {
353 DBG1("loading public key failed: %s", gpg_strerror(err));
354 free(this);
355 return NULL;
356 }
357 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
358 {
359 destroy(this);
360 return NULL;
361 }
362 return &this->public;
363 }
364
365 typedef struct private_builder_t private_builder_t;
366 /**
367 * Builder implementation for key loading
368 */
369 struct private_builder_t {
370 /** implements the builder interface */
371 builder_t public;
372 /** loaded public key */
373 gcrypt_rsa_public_key_t *key;
374 };
375
376 /**
377 * Implementation of builder_t.build
378 */
379 static gcrypt_rsa_public_key_t *build(private_builder_t *this)
380 {
381 gcrypt_rsa_public_key_t *key = this->key;
382
383 free(this);
384 return key;
385 }
386
387 /**
388 * Implementation of builder_t.add
389 */
390 static void add(private_builder_t *this, builder_part_t part, ...)
391 {
392 if (!this->key)
393 {
394 va_list args;
395
396 switch (part)
397 {
398 case BUILD_BLOB_ASN1_DER:
399 {
400 va_start(args, part);
401 this->key = load(va_arg(args, chunk_t));
402 va_end(args);
403 return;
404 }
405 default:
406 break;
407 }
408 }
409 if (this->key)
410 {
411 destroy((private_gcrypt_rsa_public_key_t*)this->key);
412 }
413 builder_cancel(&this->public);
414 }
415
416 /**
417 * Builder construction function
418 */
419 builder_t *gcrypt_rsa_public_key_builder(key_type_t type)
420 {
421 private_builder_t *this;
422
423 if (type != KEY_RSA)
424 {
425 return NULL;
426 }
427
428 this = malloc_thing(private_builder_t);
429
430 this->key = NULL;
431 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
432 this->public.build = (void*(*)(builder_t *this))build;
433
434 return &this->public;
435 }
436