Remove unneeded stuff.
[gnutls.git] / lib / gnutls_pk.c
blobe80c38092af2822f0f4e6fff5ea27572e376d2e1
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 3 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 License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 /* This file contains the functions needed for RSA/DSA public key
25 * encryption and signatures.
28 #include <gnutls_int.h>
29 #include <gnutls_mpi.h>
30 #include <gnutls_pk.h>
31 #include <gnutls_errors.h>
32 #include <gnutls_datum.h>
33 #include <gnutls_global.h>
34 #include <gnutls_num.h>
35 #include "debug.h"
36 #include <x509/x509_int.h>
37 #include <x509/common.h>
38 #include <random.h>
40 /* Do PKCS-1 RSA encryption.
41 * params is modulus, public exp.
43 int
44 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
45 const gnutls_datum_t * plaintext,
46 gnutls_pk_params_st * params,
47 unsigned btype)
49 unsigned int i, pad;
50 int ret;
51 opaque *edata, *ps;
52 size_t k, psize;
53 size_t mod_bits;
54 gnutls_datum_t to_encrypt, encrypted;
56 mod_bits = _gnutls_mpi_get_nbits (params->params[0]);
57 k = mod_bits / 8;
58 if (mod_bits % 8 != 0)
59 k++;
61 if (plaintext->size > k - 11)
63 gnutls_assert ();
64 return GNUTLS_E_PK_ENCRYPTION_FAILED;
67 edata = gnutls_malloc (k);
68 if (edata == NULL)
70 gnutls_assert ();
71 return GNUTLS_E_MEMORY_ERROR;
74 /* EB = 00||BT||PS||00||D
75 * (use block type 'btype')
78 edata[0] = 0;
79 edata[1] = btype;
80 psize = k - 3 - plaintext->size;
82 ps = &edata[2];
83 switch (btype)
85 case 2:
86 /* using public key */
87 if (params->params_nr < RSA_PUBLIC_PARAMS)
89 gnutls_assert ();
90 gnutls_free (edata);
91 return GNUTLS_E_INTERNAL_ERROR;
94 ret = gnutls_rnd (GNUTLS_RND_RANDOM, ps, psize);
95 if (ret < 0)
97 gnutls_assert ();
98 gnutls_free (edata);
99 return ret;
101 for (i = 0; i < psize; i++)
102 while (ps[i] == 0)
104 ret = gnutls_rnd (GNUTLS_RND_RANDOM, &ps[i], 1);
105 if (ret < 0)
107 gnutls_assert ();
108 gnutls_free (edata);
109 return ret;
112 break;
113 case 1:
114 /* using private key */
116 if (params->params_nr < RSA_PRIVATE_PARAMS)
118 gnutls_assert ();
119 gnutls_free (edata);
120 return GNUTLS_E_INTERNAL_ERROR;
123 for (i = 0; i < psize; i++)
124 ps[i] = 0xff;
125 break;
126 default:
127 gnutls_assert ();
128 gnutls_free (edata);
129 return GNUTLS_E_INTERNAL_ERROR;
132 ps[psize] = 0;
133 memcpy (&ps[psize + 1], plaintext->data, plaintext->size);
135 to_encrypt.data = edata;
136 to_encrypt.size = k;
138 if (btype == 2) /* encrypt */
139 ret =
140 _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, params);
141 else /* sign */
142 ret =
143 _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, params);
145 gnutls_free (edata);
147 if (ret < 0)
149 gnutls_assert ();
150 return ret;
153 psize = encrypted.size;
154 if (psize < k)
156 /* padding psize */
157 pad = k - psize;
158 psize = k;
160 else if (psize == k)
162 /* pad = 0;
163 * no need to do anything else
165 ciphertext->data = encrypted.data;
166 ciphertext->size = encrypted.size;
167 return 0;
169 else
170 { /* psize > k !!! */
171 /* This is an impossible situation */
172 gnutls_assert ();
173 _gnutls_free_datum (&encrypted);
174 return GNUTLS_E_INTERNAL_ERROR;
177 ciphertext->data = gnutls_malloc (psize);
178 if (ciphertext->data == NULL)
180 gnutls_assert ();
181 ret = GNUTLS_E_MEMORY_ERROR;
182 goto cleanup;
185 memcpy (&ciphertext->data[pad], encrypted.data, encrypted.size);
186 for (i = 0; i < pad; i++)
187 ciphertext->data[i] = 0;
189 ciphertext->size = k;
191 ret = 0;
193 cleanup:
194 _gnutls_free_datum (&encrypted);
196 return ret;
200 /* Do PKCS-1 RSA decryption.
201 * params is modulus, public exp., private key
202 * Can decrypt block type 1 and type 2 packets.
205 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
206 const gnutls_datum_t * ciphertext,
207 gnutls_pk_params_st* params,
208 unsigned btype)
210 unsigned int k, i;
211 int ret;
212 size_t esize, mod_bits;
214 mod_bits = _gnutls_mpi_get_nbits (params->params[0]);
215 k = mod_bits / 8;
216 if (mod_bits % 8 != 0)
217 k++;
219 esize = ciphertext->size;
221 if (esize != k)
223 gnutls_assert ();
224 return GNUTLS_E_PK_DECRYPTION_FAILED;
227 /* we can use btype to see if the private key is
228 * available.
230 if (btype == 2)
232 ret =
233 _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params);
235 else
237 ret =
238 _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params);
241 if (ret < 0)
243 gnutls_assert ();
244 return ret;
247 /* EB = 00||BT||PS||00||D
248 * (use block type 'btype')
250 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
251 * avoid attacks similar to the one described by Bleichenbacher in:
252 * "Chosen Ciphertext Attacks against Protocols Based on RSA
253 * Encryption Standard PKCS #1".
255 if (plaintext->data[0] != 0 || plaintext->data[1] != btype)
257 gnutls_assert ();
258 return GNUTLS_E_DECRYPTION_FAILED;
261 ret = GNUTLS_E_DECRYPTION_FAILED;
262 switch (btype)
264 case 2:
265 for (i = 2; i < plaintext->size; i++)
267 if (plaintext->data[i] == 0)
269 ret = 0;
270 break;
273 break;
274 case 1:
275 for (i = 2; i < plaintext->size; i++)
277 if (plaintext->data[i] == 0 && i > 2)
279 ret = 0;
280 break;
282 if (plaintext->data[i] != 0xff)
284 _gnutls_handshake_log ("PKCS #1 padding error");
285 _gnutls_free_datum (plaintext);
286 /* PKCS #1 padding error. Don't use
287 GNUTLS_E_PKCS1_WRONG_PAD here. */
288 break;
291 break;
292 default:
293 gnutls_assert ();
294 _gnutls_free_datum (plaintext);
295 break;
298 if (ret < 0)
300 gnutls_assert ();
301 _gnutls_free_datum (plaintext);
302 return GNUTLS_E_DECRYPTION_FAILED;
305 i++;
306 memmove (plaintext->data, &plaintext->data[i], esize - i);
307 plaintext->size = esize - i;
309 return 0;
314 _gnutls_rsa_verify (const gnutls_datum_t * vdata,
315 const gnutls_datum_t * ciphertext,
316 gnutls_pk_params_st * params,
317 int btype)
320 gnutls_datum_t plain;
321 int ret;
323 /* decrypt signature */
324 if ((ret =
325 _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params,
326 btype)) < 0)
328 gnutls_assert ();
329 return ret;
332 if (plain.size != vdata->size)
334 gnutls_assert ();
335 _gnutls_free_datum (&plain);
336 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
339 if (memcmp (plain.data, vdata->data, plain.size) != 0)
341 gnutls_assert ();
342 _gnutls_free_datum (&plain);
343 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
346 _gnutls_free_datum (&plain);
348 return 0; /* ok */
351 /* encodes the Dss-Sig-Value structure
354 _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
356 ASN1_TYPE sig;
357 int result;
359 if ((result =
360 asn1_create_element (_gnutls_get_gnutls_asn (),
361 "GNUTLS.DSASignatureValue",
362 &sig)) != ASN1_SUCCESS)
364 gnutls_assert ();
365 return _gnutls_asn2err (result);
368 result = _gnutls_x509_write_int (sig, "r", r, 1);
369 if (result < 0)
371 gnutls_assert ();
372 asn1_delete_structure (&sig);
373 return result;
376 result = _gnutls_x509_write_int (sig, "s", s, 1);
377 if (result < 0)
379 gnutls_assert ();
380 asn1_delete_structure (&sig);
381 return result;
384 result = _gnutls_x509_der_encode (sig, "", sig_value, 0);
386 asn1_delete_structure (&sig);
388 if (result < 0)
390 gnutls_assert ();
391 return result;
394 return 0;
398 /* decodes the Dss-Sig-Value structure
401 _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
402 bigint_t * s)
404 ASN1_TYPE sig;
405 int result;
407 if ((result =
408 asn1_create_element (_gnutls_get_gnutls_asn (),
409 "GNUTLS.DSASignatureValue",
410 &sig)) != ASN1_SUCCESS)
412 gnutls_assert ();
413 return _gnutls_asn2err (result);
416 result = asn1_der_decoding (&sig, sig_value->data, sig_value->size, NULL);
417 if (result != ASN1_SUCCESS)
419 gnutls_assert ();
420 asn1_delete_structure (&sig);
421 return _gnutls_asn2err (result);
424 result = _gnutls_x509_read_int (sig, "r", r);
425 if (result < 0)
427 gnutls_assert ();
428 asn1_delete_structure (&sig);
429 return result;
432 result = _gnutls_x509_read_int (sig, "s", s);
433 if (result < 0)
435 gnutls_assert ();
436 _gnutls_mpi_release (s);
437 asn1_delete_structure (&sig);
438 return result;
441 asn1_delete_structure (&sig);
443 return 0;
446 /* some generic pk functions */
448 int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st * src)
450 int i, j;
451 dst->params_nr = 0;
453 if (src == NULL || src->params_nr == 0)
455 gnutls_assert ();
456 return GNUTLS_E_INVALID_REQUEST;
459 for (i = 0; i < src->params_nr; i++)
461 dst->params[i] = _gnutls_mpi_set (NULL, src->params[i]);
462 if (dst->params[i] == NULL)
464 for (j = 0; j < i; j++)
465 _gnutls_mpi_release (&dst->params[j]);
466 return GNUTLS_E_MEMORY_ERROR;
468 dst->params_nr++;
471 return 0;
474 void
475 gnutls_pk_params_init (gnutls_pk_params_st * p)
477 memset (p, 0, sizeof (gnutls_pk_params_st));
480 void
481 gnutls_pk_params_release (gnutls_pk_params_st * p)
483 unsigned int i;
484 for (i = 0; i < p->params_nr; i++)
486 _gnutls_mpi_release (&p->params[i]);
488 p->params_nr = 0;
492 _gnutls_calc_rsa_exp (gnutls_pk_params_st* params)
494 bigint_t tmp = _gnutls_mpi_alloc_like (params->params[0]);
496 if (params->params_nr < RSA_PRIVATE_PARAMS - 2)
498 gnutls_assert ();
499 return GNUTLS_E_INTERNAL_ERROR;
502 if (tmp == NULL)
504 gnutls_assert ();
505 return GNUTLS_E_MEMORY_ERROR;
508 /* [6] = d % p-1, [7] = d % q-1 */
509 _gnutls_mpi_sub_ui (tmp, params->params[3], 1);
510 params->params[6] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp);
512 _gnutls_mpi_sub_ui (tmp, params->params[4], 1);
513 params->params[7] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp);
515 _gnutls_mpi_release (&tmp);
517 if (params->params[7] == NULL || params->params[6] == NULL)
519 gnutls_assert ();
520 return GNUTLS_E_MEMORY_ERROR;
523 return 0;
527 _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk,
528 gnutls_pk_params_st* params,
529 gnutls_digest_algorithm_t * dig,
530 unsigned int *mand)
532 if (mand)
534 if (pk == GNUTLS_PK_DSA)
535 *mand = 1;
536 else
537 *mand = 0;
540 return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) dig,
541 NULL, pk, params);