Fixed leaks in key generation and other cleanups. Patch by Tomas Mraz.
[gnutls.git] / lib / gnutls_pk.c
blob0a580910a3334929344e1efc61873ac65a257f0a
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010
3 * Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* This file contains the functions needed for RSA/DSA public key
27 * encryption and signatures.
30 #include <gnutls_int.h>
31 #include <gnutls_mpi.h>
32 #include <gnutls_pk.h>
33 #include <gnutls_errors.h>
34 #include <gnutls_datum.h>
35 #include <gnutls_global.h>
36 #include <gnutls_num.h>
37 #include "debug.h"
38 #include <x509/x509_int.h>
39 #include <x509/common.h>
40 #include <random.h>
42 /* Do PKCS-1 RSA encryption.
43 * params is modulus, public exp.
45 int
46 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
47 const gnutls_datum_t * plaintext,
48 bigint_t * params, unsigned params_len,
49 unsigned btype)
51 unsigned int i, pad;
52 int ret;
53 opaque *edata, *ps;
54 size_t k, psize;
55 size_t mod_bits;
56 gnutls_pk_params_st pk_params;
57 gnutls_datum_t to_encrypt, encrypted;
59 for (i = 0; i < params_len; i++)
60 pk_params.params[i] = params[i];
61 pk_params.params_nr = params_len;
63 mod_bits = _gnutls_mpi_get_nbits (params[0]);
64 k = mod_bits / 8;
65 if (mod_bits % 8 != 0)
66 k++;
68 if (plaintext->size > k - 11)
70 gnutls_assert ();
71 return GNUTLS_E_PK_ENCRYPTION_FAILED;
74 edata = gnutls_malloc (k);
75 if (edata == NULL)
77 gnutls_assert ();
78 return GNUTLS_E_MEMORY_ERROR;
81 /* EB = 00||BT||PS||00||D
82 * (use block type 'btype')
85 edata[0] = 0;
86 edata[1] = btype;
87 psize = k - 3 - plaintext->size;
89 ps = &edata[2];
90 switch (btype)
92 case 2:
93 /* using public key */
94 if (params_len < RSA_PUBLIC_PARAMS)
96 gnutls_assert ();
97 gnutls_free (edata);
98 return GNUTLS_E_INTERNAL_ERROR;
101 ret = _gnutls_rnd (GNUTLS_RND_RANDOM, ps, psize);
102 if (ret < 0)
104 gnutls_assert ();
105 gnutls_free (edata);
106 return ret;
108 for (i = 0; i < psize; i++)
109 while (ps[i] == 0)
111 ret = _gnutls_rnd (GNUTLS_RND_RANDOM, &ps[i], 1);
112 if (ret < 0)
114 gnutls_assert ();
115 gnutls_free (edata);
116 return ret;
119 break;
120 case 1:
121 /* using private key */
123 if (params_len < RSA_PRIVATE_PARAMS)
125 gnutls_assert ();
126 gnutls_free (edata);
127 return GNUTLS_E_INTERNAL_ERROR;
130 for (i = 0; i < psize; i++)
131 ps[i] = 0xff;
132 break;
133 default:
134 gnutls_assert ();
135 gnutls_free (edata);
136 return GNUTLS_E_INTERNAL_ERROR;
139 ps[psize] = 0;
140 memcpy (&ps[psize + 1], plaintext->data, plaintext->size);
142 to_encrypt.data = edata;
143 to_encrypt.size = k;
145 if (btype == 2) /* encrypt */
146 ret =
147 _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);
148 else /* sign */
149 ret =
150 _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);
152 gnutls_free (edata);
154 if (ret < 0)
156 gnutls_assert ();
157 return ret;
160 psize = encrypted.size;
161 if (psize < k)
163 /* padding psize */
164 pad = k - psize;
165 psize = k;
167 else if (psize == k)
169 /* pad = 0;
170 * no need to do anything else
172 ciphertext->data = encrypted.data;
173 ciphertext->size = encrypted.size;
174 return 0;
176 else
177 { /* psize > k !!! */
178 /* This is an impossible situation */
179 gnutls_assert ();
180 _gnutls_free_datum (&encrypted);
181 return GNUTLS_E_INTERNAL_ERROR;
184 ciphertext->data = gnutls_malloc (psize);
185 if (ciphertext->data == NULL)
187 gnutls_assert ();
188 _gnutls_free_datum (&encrypted);
189 return GNUTLS_E_MEMORY_ERROR;
192 memcpy (&ciphertext->data[pad], encrypted.data, encrypted.size);
193 for (i = 0; i < pad; i++)
194 ciphertext->data[i] = 0;
196 ciphertext->size = k;
198 _gnutls_free_datum (&encrypted);
200 return 0;
204 /* Do PKCS-1 RSA decryption.
205 * params is modulus, public exp., private key
206 * Can decrypt block type 1 and type 2 packets.
209 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
210 const gnutls_datum_t * ciphertext,
211 bigint_t * params, unsigned params_len,
212 unsigned btype)
214 unsigned int k, i;
215 int ret;
216 size_t esize, mod_bits;
217 gnutls_pk_params_st pk_params;
219 if (params_len > GNUTLS_MAX_PK_PARAMS)
220 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
222 for (i = 0; i < params_len; i++)
223 pk_params.params[i] = params[i];
224 pk_params.params_nr = params_len;
226 mod_bits = _gnutls_mpi_get_nbits (params[0]);
227 k = mod_bits / 8;
228 if (mod_bits % 8 != 0)
229 k++;
231 esize = ciphertext->size;
233 if (esize != k)
235 gnutls_assert ();
236 return GNUTLS_E_PK_DECRYPTION_FAILED;
239 /* we can use btype to see if the private key is
240 * available.
242 if (btype == 2)
244 ret =
245 _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params);
247 else
249 ret =
250 _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params);
253 if (ret < 0)
255 gnutls_assert ();
256 return ret;
259 /* EB = 00||BT||PS||00||D
260 * (use block type 'btype')
262 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
263 * avoid attacks similar to the one described by Bleichenbacher in:
264 * "Chosen Ciphertext Attacks against Protocols Based on RSA
265 * Encryption Standard PKCS #1".
267 if (plaintext->data[0] != 0 || plaintext->data[1] != btype)
269 gnutls_assert ();
270 return GNUTLS_E_DECRYPTION_FAILED;
273 ret = GNUTLS_E_DECRYPTION_FAILED;
274 switch (btype)
276 case 2:
277 for (i = 2; i < plaintext->size; i++)
279 if (plaintext->data[i] == 0)
281 ret = 0;
282 break;
285 break;
286 case 1:
287 for (i = 2; i < plaintext->size; i++)
289 if (plaintext->data[i] == 0 && i > 2)
291 ret = 0;
292 break;
294 if (plaintext->data[i] != 0xff)
296 _gnutls_handshake_log ("PKCS #1 padding error");
297 _gnutls_free_datum (plaintext);
298 /* PKCS #1 padding error. Don't use
299 GNUTLS_E_PKCS1_WRONG_PAD here. */
300 break;
303 break;
304 default:
305 gnutls_assert ();
306 _gnutls_free_datum (plaintext);
307 break;
309 i++;
311 if (ret < 0)
313 gnutls_assert ();
314 _gnutls_free_datum (plaintext);
315 return GNUTLS_E_DECRYPTION_FAILED;
318 memmove (plaintext->data, &plaintext->data[i], esize - i);
319 plaintext->size = esize - i;
321 return 0;
326 _gnutls_rsa_verify (const gnutls_datum_t * vdata,
327 const gnutls_datum_t * ciphertext, bigint_t * params,
328 int params_len, int btype)
331 gnutls_datum_t plain;
332 int ret;
334 /* decrypt signature */
335 if ((ret =
336 _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params, params_len,
337 btype)) < 0)
339 gnutls_assert ();
340 return ret;
343 if (plain.size != vdata->size)
345 gnutls_assert ();
346 _gnutls_free_datum (&plain);
347 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
350 if (memcmp (plain.data, vdata->data, plain.size) != 0)
352 gnutls_assert ();
353 _gnutls_free_datum (&plain);
354 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
357 _gnutls_free_datum (&plain);
359 return 0; /* ok */
362 /* encodes the Dss-Sig-Value structure
365 _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
367 ASN1_TYPE sig;
368 int result;
370 if ((result =
371 asn1_create_element (_gnutls_get_gnutls_asn (),
372 "GNUTLS.DSASignatureValue",
373 &sig)) != ASN1_SUCCESS)
375 gnutls_assert ();
376 return _gnutls_asn2err (result);
379 result = _gnutls_x509_write_int (sig, "r", r, 1);
380 if (result < 0)
382 gnutls_assert ();
383 asn1_delete_structure (&sig);
384 return result;
387 result = _gnutls_x509_write_int (sig, "s", s, 1);
388 if (result < 0)
390 gnutls_assert ();
391 asn1_delete_structure (&sig);
392 return result;
395 result = _gnutls_x509_der_encode (sig, "", sig_value, 0);
397 asn1_delete_structure (&sig);
399 if (result < 0)
401 gnutls_assert ();
402 return result;
405 return 0;
409 /* Do DSA signature calculation. params is p, q, g, y, x in that order.
412 _gnutls_dsa_sign (gnutls_datum_t * signature,
413 const gnutls_datum_t * hash, bigint_t * params,
414 unsigned int params_len)
416 int ret;
417 size_t i;
418 size_t k;
419 gnutls_pk_params_st pk_params;
421 for (i = 0; i < params_len; i++)
422 pk_params.params[i] = params[i];
423 pk_params.params_nr = params_len;
425 k = hash->size;
426 if (k < 20)
427 { /* SHA1 or better only */
428 gnutls_assert ();
429 return GNUTLS_E_PK_SIGN_FAILED;
432 ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, &pk_params);
433 /* rs[0], rs[1] now hold r,s */
435 if (ret < 0)
437 gnutls_assert ();
438 return ret;
441 return 0;
444 /* decodes the Dss-Sig-Value structure
447 _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
448 bigint_t * s)
450 ASN1_TYPE sig;
451 int result;
453 if ((result =
454 asn1_create_element (_gnutls_get_gnutls_asn (),
455 "GNUTLS.DSASignatureValue",
456 &sig)) != ASN1_SUCCESS)
458 gnutls_assert ();
459 return _gnutls_asn2err (result);
462 result = asn1_der_decoding (&sig, sig_value->data, sig_value->size, NULL);
463 if (result != ASN1_SUCCESS)
465 gnutls_assert ();
466 asn1_delete_structure (&sig);
467 return _gnutls_asn2err (result);
470 result = _gnutls_x509_read_int (sig, "r", r);
471 if (result < 0)
473 gnutls_assert ();
474 asn1_delete_structure (&sig);
475 return result;
478 result = _gnutls_x509_read_int (sig, "s", s);
479 if (result < 0)
481 gnutls_assert ();
482 _gnutls_mpi_release (s);
483 asn1_delete_structure (&sig);
484 return result;
487 asn1_delete_structure (&sig);
489 return 0;
492 /* params is p, q, g, y in that order
495 _gnutls_dsa_verify (const gnutls_datum_t * vdata,
496 const gnutls_datum_t * sig_value, bigint_t * params,
497 int params_len)
500 int ret, i;
501 gnutls_pk_params_st pk_params;
503 for (i = 0; i < params_len; i++)
504 pk_params.params[i] = params[i];
505 pk_params.params_nr = params_len;
507 if (vdata->size < 20)
508 { /* SHA1 or better only */
509 gnutls_assert ();
510 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
513 /* decrypt signature */
514 ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, &pk_params);
516 if (ret < 0)
518 gnutls_assert ();
519 return ret;
522 return 0; /* ok */
525 /* some generic pk functions */
526 static int
527 _generate_params (int algo, bigint_t * resarr, unsigned int *resarr_len,
528 int bits)
530 gnutls_pk_params_st params;
531 int ret;
532 unsigned int i;
534 ret = _gnutls_pk_ops.generate (algo, bits, &params);
536 if (ret < 0)
538 gnutls_assert ();
539 return ret;
542 if (resarr && resarr_len && *resarr_len >= params.params_nr)
544 *resarr_len = params.params_nr;
545 for (i = 0; i < params.params_nr; i++)
546 resarr[i] = params.params[i];
548 else
550 gnutls_pk_params_release(&params);
551 gnutls_assert ();
552 return GNUTLS_E_INVALID_REQUEST;
554 return 0;
560 _gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
561 int bits)
563 return _generate_params (GNUTLS_PK_RSA, resarr, resarr_len, bits);
567 _gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
568 int bits)
570 return _generate_params (GNUTLS_PK_DSA, resarr, resarr_len, bits);
574 _gnutls_pk_params_copy (gnutls_pk_params_st * dst, bigint_t * params,
575 int params_len)
577 int i, j;
578 dst->params_nr = 0;
580 if (params_len == 0 || params == NULL)
582 gnutls_assert ();
583 return GNUTLS_E_INVALID_REQUEST;
586 for (i = 0; i < params_len; i++)
588 dst->params[i] = _gnutls_mpi_set (NULL, params[i]);
589 if (dst->params[i] == NULL)
591 for (j = 0; j < i; j++)
592 _gnutls_mpi_release (&dst->params[j]);
593 return GNUTLS_E_MEMORY_ERROR;
595 dst->params_nr++;
598 return 0;
601 void
602 gnutls_pk_params_init (gnutls_pk_params_st * p)
604 memset (p, 0, sizeof (gnutls_pk_params_st));
607 void
608 gnutls_pk_params_release (gnutls_pk_params_st * p)
610 unsigned int i;
611 for (i = 0; i < p->params_nr; i++)
613 _gnutls_mpi_release (&p->params[i]);
618 _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size)
620 bigint_t tmp = _gnutls_mpi_alloc_like (params[0]);
622 if (params_size < RSA_PRIVATE_PARAMS - 2)
624 gnutls_assert ();
625 return GNUTLS_E_INTERNAL_ERROR;
628 if (tmp == NULL)
630 gnutls_assert ();
631 return GNUTLS_E_MEMORY_ERROR;
634 /* [6] = d % p-1, [7] = d % q-1 */
635 _gnutls_mpi_sub_ui (tmp, params[3], 1);
636 params[6] = _gnutls_mpi_mod (params[2] /*d */ , tmp);
638 _gnutls_mpi_sub_ui (tmp, params[4], 1);
639 params[7] = _gnutls_mpi_mod (params[2] /*d */ , tmp);
641 _gnutls_mpi_release (&tmp);
643 if (params[7] == NULL || params[6] == NULL)
645 gnutls_assert ();
646 return GNUTLS_E_MEMORY_ERROR;
649 return 0;
653 _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, bigint_t * params,
654 int params_size,
655 gnutls_digest_algorithm_t * dig,
656 unsigned int *mand)
658 if (mand)
660 if (pk == GNUTLS_PK_DSA)
661 *mand = 1;
662 else
663 *mand = 0;
666 return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) dig,
667 NULL, pk, params, params_size);