5b85f52566144919a2e7a4baa2167ee0961d352a
[strongswan.git] / Source / lib / crypto / rsa / rsa_public_key.c
1 /**
2 * @file rsa_public_key.c
3 *
4 * @brief Implementation of rsa_public_key_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <gmp.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <string.h>
27
28 #include "rsa_public_key.h"
29
30 #include <daemon.h>
31 #include <crypto/hashers/hasher.h>
32 #include <asn1/der_decoder.h>
33
34 /*
35 * For simplicity,
36 * we use these predefined values for
37 * hash algorithm OIDs. These also contain
38 * the length of the following hash.
39 * These values are also used in rsa_private_key.c.
40 */
41
42 u_int8_t md2_oid[] = {
43 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,
44 0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,
45 0x04,0x10
46 };
47
48 u_int8_t md5_oid[] = {
49 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,
50 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,
51 0x04,0x10
52 };
53
54 u_int8_t sha1_oid[] = {
55 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,
56 0x03,0x02,0x1a,0x05,0x00,0x04,0x14
57 };
58
59 u_int8_t sha256_oid[] = {
60 0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,
61 0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,
62 0x00,0x04,0x20
63 };
64
65 u_int8_t sha384_oid[] = {
66 0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,
67 0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,
68 0x00,0x04,0x30
69 };
70
71 u_int8_t sha512_oid[] = {
72 0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,
73 0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,
74 0x00,0x04,0x40
75 };
76
77
78 typedef struct private_rsa_public_key_t private_rsa_public_key_t;
79
80 /**
81 * Private data structure with signing context.
82 */
83 struct private_rsa_public_key_t {
84 /**
85 * Public interface for this signer.
86 */
87 rsa_public_key_t public;
88
89 /**
90 * Public modulus.
91 */
92 mpz_t n;
93
94 /**
95 * Public exponent.
96 */
97 mpz_t e;
98
99 /**
100 * Keysize in bytes.
101 */
102 size_t k;
103
104 /**
105 * @brief Implements the RSAEP algorithm specified in PKCS#1.
106 *
107 * @param this calling object
108 * @param data data to process
109 * @return processed data
110 */
111 chunk_t (*rsaep) (private_rsa_public_key_t *this, chunk_t data);
112
113 /**
114 * @brief Implements the RSASVP1 algorithm specified in PKCS#1.
115 *
116 * @param this calling object
117 * @param data data to process
118 * @return processed data
119 */
120 chunk_t (*rsavp1) (private_rsa_public_key_t *this, chunk_t data);
121 };
122
123
124 typedef struct rsa_public_key_info_t rsa_public_key_info_t;
125
126 /**
127 * KeyInfo, as it appears in a public key file
128 */
129 struct rsa_public_key_info_t {
130 /**
131 * Algorithm for this key
132 */
133 chunk_t algorithm_oid;
134
135 /**
136 * Public key, parseable with rsa_public_key_rules
137 */
138 chunk_t public_key;
139 };
140
141 /**
142 * Rules for de-/encoding of a public key from/in ASN1
143 */
144 static asn1_rule_t rsa_public_key_rules[] = {
145 {ASN1_SEQUENCE, 0, 0, 0},
146 { ASN1_INTEGER, ASN1_MPZ, offsetof(private_rsa_public_key_t, n), 0},
147 { ASN1_INTEGER, ASN1_MPZ, offsetof(private_rsa_public_key_t, e), 0},
148 {ASN1_END, 0, 0, 0},
149 };
150
151 /**
152 * Rules for de-/encoding of a PublicKeyInfo from/in ASN1
153 */
154 static asn1_rule_t rsa_public_key_info_rules[] = {
155 {ASN1_SEQUENCE, 0, 0, 0},
156 { ASN1_SEQUENCE, 0, 0, 0},
157 { ASN1_OID, 0, offsetof(rsa_public_key_info_t, algorithm_oid), 0},
158 { ASN1_NULL, 0, 0, 0},
159 { ASN1_END, 0, 0, 0},
160 { ASN1_BITSTRING, 0, offsetof(rsa_public_key_info_t, public_key), 0},
161 {ASN1_END, 0, 0, 0},
162 };
163
164 private_rsa_public_key_t *rsa_public_key_create_empty();
165
166 /**
167 * Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1
168 */
169 static chunk_t rsaep(private_rsa_public_key_t *this, chunk_t data)
170 {
171 mpz_t m, c;
172 chunk_t encrypted;
173
174 mpz_init(c);
175 mpz_init(m);
176
177 mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
178
179 mpz_powm(c, m, this->e, this->n);
180
181 encrypted.len = this->k;
182 encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
183
184 mpz_clear(c);
185 mpz_clear(m);
186
187 return encrypted;
188 }
189
190 /**
191 * Implementation of rsa_public_key.verify_emsa_pkcs1_signature.
192 */
193 static status_t verify_emsa_pkcs1_signature(private_rsa_public_key_t *this, chunk_t data, chunk_t signature)
194 {
195 hasher_t *hasher = NULL;
196 chunk_t hash;
197 chunk_t em;
198 u_int8_t *pos;
199
200 if (signature.len > this->k)
201 {
202 return INVALID_ARG;
203 }
204
205 /* unpack signature */
206 em = this->rsavp1(this, signature);
207
208 /* result should look like this:
209 * EM = 0x00 || 0x01 || PS || 0x00 || T.
210 * PS = 0xFF padding, with length to fill em
211 * T = oid || hash
212 */
213
214 /* check magic bytes */
215 if ((*(em.ptr) != 0x00) ||
216 (*(em.ptr+1) != 0x01))
217 {
218 free(em.ptr);
219 return FAILED;
220 }
221
222 /* find magic 0x00 */
223 pos = em.ptr + 2;
224 while (pos <= em.ptr + em.len)
225 {
226 if (*pos == 0x00)
227 {
228 /* found magic byte, stop */
229 pos++;
230 break;
231 }
232 else if (*pos != 0xFF)
233 {
234 /* bad padding, decryption failed ?!*/
235 free(em.ptr);
236 return FAILED;
237 }
238 pos++;
239 }
240
241 if (pos + 20 > em.ptr + em.len)
242 {
243 /* not enought room for oid compare */
244 free(em.ptr);
245 return FAILED;
246 }
247
248 if (memcmp(md2_oid, pos, sizeof(md2_oid)) == 0)
249 {
250 hasher = hasher_create(HASH_MD2);
251 pos += sizeof(md2_oid);
252 }
253 else if (memcmp(md5_oid, pos, sizeof(md5_oid)) == 0)
254 {
255 hasher = hasher_create(HASH_MD5);
256 pos += sizeof(md5_oid);
257 }
258 else if (memcmp(sha1_oid, pos, sizeof(sha1_oid)) == 0)
259 {
260 hasher = hasher_create(HASH_SHA1);
261 pos += sizeof(sha1_oid);
262 }
263 else if (memcmp(sha256_oid, pos, sizeof(sha256_oid)) == 0)
264 {
265 hasher = hasher_create(HASH_SHA256);
266 pos += sizeof(sha256_oid);
267 }
268 else if (memcmp(sha384_oid, pos, sizeof(sha384_oid)) == 0)
269 {
270 hasher = hasher_create(HASH_SHA384);
271 pos += sizeof(sha384_oid);
272 }
273 else if (memcmp(sha512_oid, pos, sizeof(sha512_oid)) == 0)
274 {
275 hasher = hasher_create(HASH_SHA512);
276 pos += sizeof(sha512_oid);
277 }
278
279 if (hasher == NULL)
280 {
281 /* not supported hash algorithm */
282 free(em.ptr);
283 return NOT_SUPPORTED;
284 }
285
286 if (pos + hasher->get_block_size(hasher) != em.ptr + em.len)
287 {
288 /* bad length */
289 free(em.ptr);
290 hasher->destroy(hasher);
291 return FAILED;
292 }
293
294 /* build own hash for a compare */
295 hasher->allocate_hash(hasher, data, &hash);
296 hasher->destroy(hasher);
297
298 if (memcmp(hash.ptr, pos, hash.len) != 0)
299 {
300 /* hash does not equal */
301 free(hash.ptr);
302 free(em.ptr);
303 return FAILED;
304
305 }
306
307 /* seems good */
308 free(hash.ptr);
309 free(em.ptr);
310 return SUCCESS;
311 }
312
313 /**
314 * Implementation of rsa_public_key.get_key.
315 */
316 static status_t get_key(private_rsa_public_key_t *this, chunk_t *key)
317 {
318 chunk_t n, e;
319
320 n.len = this->k;
321 n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, this->n);
322 e.len = this->k;
323 e.ptr = mpz_export(NULL, NULL, 1, e.len, 1, 0, this->e);
324
325 key->len = this->k * 2;
326 key->ptr = malloc(key->len);
327 memcpy(key->ptr, n.ptr, n.len);
328 memcpy(key->ptr + n.len, e.ptr, e.len);
329 free(n.ptr);
330 free(e.ptr);
331
332 return SUCCESS;
333 }
334
335 /**
336 * Implementation of rsa_public_key.save_key.
337 */
338 static status_t save_key(private_rsa_public_key_t *this, char *file)
339 {
340 return NOT_SUPPORTED;
341 }
342
343 /**
344 * Implementation of rsa_public_key.get_modulus.
345 */
346 static mpz_t *get_modulus(private_rsa_public_key_t *this)
347 {
348 return &this->n;
349 }
350
351 /**
352 * Implementation of rsa_public_key.clone.
353 */
354 static rsa_public_key_t* _clone(private_rsa_public_key_t *this)
355 {
356 private_rsa_public_key_t *clone = rsa_public_key_create_empty();
357
358 mpz_init_set(clone->n, this->n);
359 mpz_init_set(clone->e, this->e);
360 clone->k = this->k;
361
362 return &clone->public;
363 }
364
365 /**
366 * Implementation of rsa_public_key.destroy.
367 */
368 static void destroy(private_rsa_public_key_t *this)
369 {
370 mpz_clear(this->n);
371 mpz_clear(this->e);
372 free(this);
373 }
374
375 /**
376 * Generic private constructor
377 */
378 private_rsa_public_key_t *rsa_public_key_create_empty()
379 {
380 private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t);
381
382 /* public functions */
383 this->public.verify_emsa_pkcs1_signature = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t))verify_emsa_pkcs1_signature;
384 this->public.get_key = (status_t (*) (rsa_public_key_t*,chunk_t*))get_key;
385 this->public.save_key = (status_t (*) (rsa_public_key_t*,char*))save_key;
386 this->public.get_modulus = (mpz_t *(*) (rsa_public_key_t*))get_modulus;
387 this->public.clone = (rsa_public_key_t* (*) (rsa_public_key_t*))_clone;
388 this->public.destroy = (void (*) (rsa_public_key_t*))destroy;
389
390 /* private functions */
391 this->rsaep = rsaep;
392 this->rsavp1 = rsaep; /* same algorithm */
393
394 return this;
395 }
396
397 /*
398 * See header
399 */
400 rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t chunk)
401 {
402 der_decoder_t *dd;
403 status_t status;
404 private_rsa_public_key_t *this;
405
406 this = rsa_public_key_create_empty();
407 mpz_init(this->n);
408 mpz_init(this->e);
409
410 dd = der_decoder_create(rsa_public_key_rules);
411 status = dd->decode(dd, chunk, this);
412 dd->destroy(dd);
413 if (status != SUCCESS)
414 {
415 destroy(this);
416 return NULL;
417 }
418 this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
419 return &this->public;
420 }
421
422 /*
423 * See header
424 */
425 rsa_public_key_t *rsa_public_key_create_from_file(char *filename)
426 {
427 struct stat stb;
428 FILE *file;
429 char *buffer;
430 chunk_t chunk;
431 rsa_public_key_info_t key_info = {CHUNK_INITIALIZER, CHUNK_INITIALIZER};
432 der_decoder_t *dd;
433 status_t status;
434 rsa_public_key_t *public_key = NULL;
435
436 if (stat(filename, &stb) == -1)
437 {
438 return NULL;
439 }
440
441 buffer = alloca(stb.st_size);
442
443 file = fopen(filename, "r");
444 if (file == NULL)
445 {
446 return NULL;
447 }
448
449 if (fread(buffer, stb.st_size, 1, file) != 1)
450 {
451 return NULL;
452 }
453
454 chunk.ptr = buffer;
455 chunk.len = stb.st_size;
456
457 /* parse public key info first */
458 dd = der_decoder_create(rsa_public_key_info_rules);
459 status = dd->decode(dd, chunk, &key_info);
460 dd->destroy(dd);
461 chunk_free(&key_info.algorithm_oid);
462 if (status == SUCCESS)
463 {
464 public_key = rsa_public_key_create_from_chunk(chunk);
465 }
466 chunk_free(&key_info.public_key);
467 return public_key;
468 }