00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <gnutls_int.h>
00030 #include <gnutls_mpi.h>
00031 #include <gnutls_pk.h>
00032 #include <gnutls_errors.h>
00033 #include <gnutls_datum.h>
00034 #include <gnutls_global.h>
00035 #include <gnutls_num.h>
00036 #include "debug.h"
00037 #include <gc.h>
00038
00039
00040 #include "common.h"
00041 #include "mpi.h"
00042
00043 static int MHD__gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data,
00044 mpi_t * pkey, int pkey_len);
00045 static int MHD__gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash,
00046 mpi_t * pkey, int);
00047 static int MHD__gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data,
00048 mpi_t * pkey, int);
00049
00050
00051
00052
00053
00054 int
00055 MHD_gtls_pkcs1_rsa_encrypt (MHD_gnutls_datum_t * ciphertext,
00056 const MHD_gnutls_datum_t * plaintext,
00057 mpi_t * params, unsigned params_len,
00058 unsigned btype)
00059 {
00060 unsigned int i, pad;
00061 int ret;
00062 mpi_t m, res;
00063 opaque *edata, *ps;
00064 size_t k, psize;
00065 size_t mod_bits;
00066
00067 mod_bits = MHD__gnutls_mpi_get_nbits (params[0]);
00068 k = mod_bits / 8;
00069 if (mod_bits % 8 != 0)
00070 k++;
00071
00072 if (plaintext->size > k - 11)
00073 {
00074 MHD_gnutls_assert ();
00075 return GNUTLS_E_PK_ENCRYPTION_FAILED;
00076 }
00077
00078 edata = MHD_gnutls_alloca (k);
00079 if (edata == NULL)
00080 {
00081 MHD_gnutls_assert ();
00082 return GNUTLS_E_MEMORY_ERROR;
00083 }
00084
00085
00086
00087
00088
00089 edata[0] = 0;
00090 edata[1] = btype;
00091 psize = k - 3 - plaintext->size;
00092
00093 ps = &edata[2];
00094 switch (btype)
00095 {
00096 case 2:
00097
00098 if (params_len < RSA_PUBLIC_PARAMS)
00099 {
00100 MHD_gnutls_assert ();
00101 MHD_gnutls_afree (edata);
00102 return GNUTLS_E_INTERNAL_ERROR;
00103 }
00104
00105 if (MHD_gc_pseudo_random ((char *) ps, psize) != GC_OK)
00106 {
00107 MHD_gnutls_assert ();
00108 MHD_gnutls_afree (edata);
00109 return GNUTLS_E_RANDOM_FAILED;
00110 }
00111 for (i = 0; i < psize; i++)
00112 while (ps[i] == 0)
00113 {
00114 if (MHD_gc_pseudo_random ((char *) &ps[i], 1) != GC_OK)
00115 {
00116 MHD_gnutls_assert ();
00117 MHD_gnutls_afree (edata);
00118 return GNUTLS_E_RANDOM_FAILED;
00119 }
00120 }
00121 break;
00122 case 1:
00123
00124
00125 if (params_len < RSA_PRIVATE_PARAMS)
00126 {
00127 MHD_gnutls_assert ();
00128 MHD_gnutls_afree (edata);
00129 return GNUTLS_E_INTERNAL_ERROR;
00130 }
00131
00132 for (i = 0; i < psize; i++)
00133 ps[i] = 0xff;
00134 break;
00135 default:
00136 MHD_gnutls_assert ();
00137 MHD_gnutls_afree (edata);
00138 return GNUTLS_E_INTERNAL_ERROR;
00139 }
00140
00141 ps[psize] = 0;
00142 memcpy (&ps[psize + 1], plaintext->data, plaintext->size);
00143
00144 if (MHD_gtls_mpi_scan_nz (&m, edata, &k) != 0)
00145 {
00146 MHD_gnutls_assert ();
00147 MHD_gnutls_afree (edata);
00148 return GNUTLS_E_MPI_SCAN_FAILED;
00149 }
00150 MHD_gnutls_afree (edata);
00151
00152 if (btype == 2)
00153 ret = MHD__gnutls_pk_encrypt (GCRY_PK_RSA, &res, m, params, params_len);
00154 else
00155 ret = MHD__gnutls_pk_sign (GCRY_PK_RSA, &res, m, params, params_len);
00156
00157 MHD_gtls_mpi_release (&m);
00158
00159 if (ret < 0)
00160 {
00161 MHD_gnutls_assert ();
00162 return ret;
00163 }
00164
00165 MHD_gtls_mpi_print (NULL, &psize, res);
00166
00167 if (psize < k)
00168 {
00169
00170 pad = k - psize;
00171 psize = k;
00172 }
00173 else if (psize == k)
00174 {
00175 pad = 0;
00176 }
00177 else
00178 {
00179
00180 MHD_gnutls_assert ();
00181 MHD_gtls_mpi_release (&res);
00182 return GNUTLS_E_INTERNAL_ERROR;
00183 }
00184
00185 ciphertext->data = MHD_gnutls_malloc (psize);
00186 if (ciphertext->data == NULL)
00187 {
00188 MHD_gnutls_assert ();
00189 MHD_gtls_mpi_release (&res);
00190 return GNUTLS_E_MEMORY_ERROR;
00191 }
00192 MHD_gtls_mpi_print (&ciphertext->data[pad], &psize, res);
00193 for (i = 0; i < pad; i++)
00194 ciphertext->data[i] = 0;
00195
00196 ciphertext->size = k;
00197
00198 MHD_gtls_mpi_release (&res);
00199
00200 return 0;
00201 }
00202
00203
00204
00205
00206
00207
00208 int
00209 MHD_gtls_pkcs1_rsa_decrypt (MHD_gnutls_datum_t * plaintext,
00210 const MHD_gnutls_datum_t * ciphertext,
00211 mpi_t * params, unsigned params_len,
00212 unsigned btype)
00213 {
00214 unsigned k, i;
00215 int ret;
00216 mpi_t c, res;
00217 opaque *edata;
00218 size_t esize, mod_bits;
00219
00220 mod_bits = MHD__gnutls_mpi_get_nbits (params[0]);
00221 k = mod_bits / 8;
00222 if (mod_bits % 8 != 0)
00223 k++;
00224
00225 esize = ciphertext->size;
00226
00227 if (esize != k)
00228 {
00229 MHD_gnutls_assert ();
00230 return GNUTLS_E_PK_DECRYPTION_FAILED;
00231 }
00232
00233 if (MHD_gtls_mpi_scan_nz (&c, ciphertext->data, &esize) != 0)
00234 {
00235 MHD_gnutls_assert ();
00236 return GNUTLS_E_MPI_SCAN_FAILED;
00237 }
00238
00239
00240
00241
00242 if (btype == 2)
00243 ret = MHD__gnutls_pk_decrypt (GCRY_PK_RSA, &res, c, params, params_len);
00244 else
00245 {
00246 ret = MHD__gnutls_pk_encrypt (GCRY_PK_RSA, &res, c, params, params_len);
00247 }
00248 MHD_gtls_mpi_release (&c);
00249
00250 if (ret < 0)
00251 {
00252 MHD_gnutls_assert ();
00253 return ret;
00254 }
00255
00256 MHD_gtls_mpi_print (NULL, &esize, res);
00257 edata = MHD_gnutls_alloca (esize + 1);
00258 if (edata == NULL)
00259 {
00260 MHD_gnutls_assert ();
00261 MHD_gtls_mpi_release (&res);
00262 return GNUTLS_E_MEMORY_ERROR;
00263 }
00264 MHD_gtls_mpi_print (&edata[1], &esize, res);
00265
00266 MHD_gtls_mpi_release (&res);
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 edata[0] = 0;
00279 esize++;
00280
00281 if (edata[0] != 0 || edata[1] != btype)
00282 {
00283 MHD_gnutls_assert ();
00284 MHD_gnutls_afree (edata);
00285 return GNUTLS_E_DECRYPTION_FAILED;
00286 }
00287
00288 ret = GNUTLS_E_DECRYPTION_FAILED;
00289 switch (btype)
00290 {
00291 case 2:
00292 for (i = 2; i < esize; i++)
00293 {
00294 if (edata[i] == 0)
00295 {
00296 ret = 0;
00297 break;
00298 }
00299 }
00300 break;
00301 case 1:
00302 for (i = 2; i < esize; i++)
00303 {
00304 if (edata[i] == 0 && i > 2)
00305 {
00306 ret = 0;
00307 break;
00308 }
00309 if (edata[i] != 0xff)
00310 {
00311 MHD__gnutls_handshake_log ("PKCS #1 padding error");
00312
00313
00314 break;
00315 }
00316 }
00317 break;
00318 default:
00319 MHD_gnutls_assert ();
00320 MHD_gnutls_afree (edata);
00321 return GNUTLS_E_DECRYPTION_FAILED;
00322 }
00323 i++;
00324
00325 if (ret < 0)
00326 {
00327 MHD_gnutls_assert ();
00328 MHD_gnutls_afree (edata);
00329 return GNUTLS_E_DECRYPTION_FAILED;
00330 }
00331
00332 if (MHD__gnutls_sset_datum (plaintext, &edata[i], esize - i) < 0)
00333 {
00334 MHD_gnutls_assert ();
00335 MHD_gnutls_afree (edata);
00336 return GNUTLS_E_MEMORY_ERROR;
00337 }
00338
00339 MHD_gnutls_afree (edata);
00340
00341 return 0;
00342 }
00343
00344
00345 int
00346 MHD_gtls_rsa_verify (const MHD_gnutls_datum_t * vdata,
00347 const MHD_gnutls_datum_t * ciphertext, mpi_t * params,
00348 int params_len, int btype)
00349 {
00350
00351 MHD_gnutls_datum_t plain;
00352 int ret;
00353
00354
00355 if ((ret =
00356 MHD_gtls_pkcs1_rsa_decrypt (&plain, ciphertext, params, params_len,
00357 btype)) < 0)
00358 {
00359 MHD_gnutls_assert ();
00360 return ret;
00361 }
00362
00363 if (plain.size != vdata->size)
00364 {
00365 MHD_gnutls_assert ();
00366 MHD__gnutls_free_datum (&plain);
00367 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
00368 }
00369
00370 if (memcmp (plain.data, vdata->data, plain.size) != 0)
00371 {
00372 MHD_gnutls_assert ();
00373 MHD__gnutls_free_datum (&plain);
00374 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
00375 }
00376
00377 MHD__gnutls_free_datum (&plain);
00378
00379 return 0;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 static int
00391 MHD__gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data,
00392 mpi_t * pkey, int pkey_len)
00393 {
00394 gcry_sexp_t s_ciph, s_data, s_pkey;
00395 int rc = -1;
00396
00397
00398 switch (algo)
00399 {
00400 case GCRY_PK_RSA:
00401 if (pkey_len >= 2)
00402 rc = gcry_sexp_build (&s_pkey, NULL,
00403 "(public-key(rsa(n%m)(e%m)))",
00404 pkey[0], pkey[1]);
00405 break;
00406
00407 default:
00408 MHD_gnutls_assert ();
00409 return GNUTLS_E_INTERNAL_ERROR;
00410 }
00411
00412 if (rc != 0)
00413 {
00414 MHD_gnutls_assert ();
00415 return GNUTLS_E_INTERNAL_ERROR;
00416 }
00417
00418
00419 if (gcry_sexp_build (&s_data, NULL, "%m", data))
00420 {
00421 MHD_gnutls_assert ();
00422 gcry_sexp_release (s_pkey);
00423 return GNUTLS_E_INTERNAL_ERROR;
00424 }
00425
00426
00427 rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
00428 gcry_sexp_release (s_data);
00429 gcry_sexp_release (s_pkey);
00430
00431 if (rc != 0)
00432 {
00433 MHD_gnutls_assert ();
00434 return GNUTLS_E_PK_ENCRYPTION_FAILED;
00435
00436 }
00437 else
00438 {
00439 gcry_sexp_t list = gcry_sexp_find_token (s_ciph, "a", 0);
00440 if (list == NULL)
00441 {
00442 MHD_gnutls_assert ();
00443 gcry_sexp_release (s_ciph);
00444 return GNUTLS_E_INTERNAL_ERROR;
00445 }
00446
00447 resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
00448 gcry_sexp_release (list);
00449
00450 if (resarr[0] == NULL)
00451 {
00452 MHD_gnutls_assert ();
00453 gcry_sexp_release (s_ciph);
00454 return GNUTLS_E_INTERNAL_ERROR;
00455 }
00456 }
00457
00458 gcry_sexp_release (s_ciph);
00459 return rc;
00460 }
00461
00462 static int
00463 MHD__gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey,
00464 int pkey_len)
00465 {
00466 gcry_sexp_t s_plain, s_data, s_pkey;
00467 int rc = -1;
00468
00469
00470 switch (algo)
00471 {
00472 case GCRY_PK_RSA:
00473 if (pkey_len >= 6)
00474 rc = gcry_sexp_build (&s_pkey, NULL,
00475 "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
00476 pkey[0], pkey[1], pkey[2], pkey[3],
00477 pkey[4], pkey[5]);
00478 break;
00479
00480 default:
00481 MHD_gnutls_assert ();
00482 return GNUTLS_E_INTERNAL_ERROR;
00483 }
00484
00485 if (rc != 0)
00486 {
00487 MHD_gnutls_assert ();
00488 return GNUTLS_E_INTERNAL_ERROR;
00489 }
00490
00491
00492 if (gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data))
00493 {
00494 MHD_gnutls_assert ();
00495 gcry_sexp_release (s_pkey);
00496 return GNUTLS_E_INTERNAL_ERROR;
00497 }
00498
00499
00500 rc = gcry_pk_decrypt (&s_plain, s_data, s_pkey);
00501 gcry_sexp_release (s_data);
00502 gcry_sexp_release (s_pkey);
00503
00504 if (rc != 0)
00505 {
00506 MHD_gnutls_assert ();
00507 return GNUTLS_E_PK_DECRYPTION_FAILED;
00508
00509 }
00510 else
00511 {
00512 resarr[0] = gcry_sexp_nth_mpi (s_plain, 0, 0);
00513
00514 if (resarr[0] == NULL)
00515 {
00516 MHD_gnutls_assert ();
00517 gcry_sexp_release (s_plain);
00518 return GNUTLS_E_INTERNAL_ERROR;
00519 }
00520 }
00521
00522 gcry_sexp_release (s_plain);
00523 return rc;
00524 }
00525
00526
00527
00528
00529 static int
00530 MHD__gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, mpi_t * pkey,
00531 int pkey_len)
00532 {
00533 gcry_sexp_t s_hash, s_key, s_sig;
00534 int rc = -1;
00535
00536
00537 switch (algo)
00538 {
00539 case GCRY_PK_DSA:
00540 if (pkey_len >= 5)
00541 rc = gcry_sexp_build (&s_key, NULL,
00542 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
00543 pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]);
00544 else
00545 {
00546 MHD_gnutls_assert ();
00547 }
00548
00549 break;
00550 case GCRY_PK_RSA:
00551 if (pkey_len >= 6)
00552 rc = gcry_sexp_build (&s_key, NULL,
00553 "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
00554 pkey[0], pkey[1], pkey[2], pkey[3],
00555 pkey[4], pkey[5]);
00556 else
00557 {
00558 MHD_gnutls_assert ();
00559 }
00560 break;
00561
00562 default:
00563 MHD_gnutls_assert ();
00564 return GNUTLS_E_INTERNAL_ERROR;
00565 }
00566
00567 if (rc != 0)
00568 {
00569 MHD_gnutls_assert ();
00570 return GNUTLS_E_INTERNAL_ERROR;
00571 }
00572
00573
00574 if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
00575 {
00576 MHD_gnutls_assert ();
00577 return GNUTLS_E_INTERNAL_ERROR;
00578 }
00579
00580
00581 rc = gcry_pk_sign (&s_sig, s_hash, s_key);
00582 gcry_sexp_release (s_hash);
00583 gcry_sexp_release (s_key);
00584
00585 if (rc != 0)
00586 {
00587 MHD_gnutls_assert ();
00588 return GNUTLS_E_PK_SIGN_FAILED;
00589
00590 }
00591 else
00592 {
00593 gcry_sexp_t list;
00594
00595 if (algo == GCRY_PK_DSA)
00596 {
00597 list = gcry_sexp_find_token (s_sig, "r", 0);
00598 if (list == NULL)
00599 {
00600 MHD_gnutls_assert ();
00601 gcry_sexp_release (s_sig);
00602 return GNUTLS_E_INTERNAL_ERROR;
00603 }
00604
00605 data[0] = gcry_sexp_nth_mpi (list, 1, 0);
00606 gcry_sexp_release (list);
00607
00608 list = gcry_sexp_find_token (s_sig, "s", 0);
00609 if (list == NULL)
00610 {
00611 MHD_gnutls_assert ();
00612 gcry_sexp_release (s_sig);
00613 return GNUTLS_E_INTERNAL_ERROR;
00614 }
00615
00616 data[1] = gcry_sexp_nth_mpi (list, 1, 0);
00617 gcry_sexp_release (list);
00618 }
00619 else
00620 {
00621 list = gcry_sexp_find_token (s_sig, "s", 0);
00622 if (list == NULL)
00623 {
00624 MHD_gnutls_assert ();
00625 gcry_sexp_release (s_sig);
00626 return GNUTLS_E_INTERNAL_ERROR;
00627 }
00628
00629 data[0] = gcry_sexp_nth_mpi (list, 1, 0);
00630 gcry_sexp_release (list);
00631 }
00632 }
00633
00634 gcry_sexp_release (s_sig);
00635 return 0;
00636 }