Example #1
0
File: pk.c Project: intgr/gnutls
static int
_wrap_nettle_pk_decrypt (gnutls_pk_algorithm_t algo,
                         gnutls_datum_t * plaintext,
                         const gnutls_datum_t * ciphertext,
                         const gnutls_pk_params_st * pk_params)
{
  int ret;

  plaintext->data = NULL;

  /* make a sexp from pkey */
  switch (algo)
    {
    case GNUTLS_PK_RSA:
      {
        struct rsa_private_key priv;
        struct rsa_public_key pub;
        unsigned length;
        bigint_t c;

        _rsa_params_to_privkey (pk_params, &priv);
        _rsa_params_to_pubkey (pk_params, &pub);

        if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
            goto cleanup;
          }

        length = pub.size;
        plaintext->data = gnutls_malloc(length);
        if (plaintext->data == NULL)
          {
            ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
            goto cleanup;
          }
        
        ret = rsa_decrypt_tr(&pub, &priv, NULL, rnd_func, &length, plaintext->data,
                             TOMPZ(c));
        _gnutls_mpi_release (&c);
        plaintext->size = length;

        if (ret == 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
            goto cleanup;
          }

        break;
      }
    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  ret = 0;

cleanup:
  if (ret < 0)
    gnutls_free(plaintext->data);

  return ret;
}
void
test_main(void)
{
  struct rsa_public_key pub;
  struct rsa_private_key key;
  struct knuth_lfib_ctx lfib;

  /* FIXME: How is this spelled? */
  const uint8_t *msg = "Squemish ossifrage";
  size_t msg_length;

  uint8_t *decrypted;
  size_t decrypted_length;
  uint8_t after;

  mpz_t gibberish;

  rsa_private_key_init(&key);
  rsa_public_key_init(&pub);
  mpz_init(gibberish);

  knuth_lfib_init(&lfib, 17);
  
  test_rsa_set_key_1(&pub, &key);
  msg_length = strlen(msg);

  if (verbose)
    fprintf(stderr, "msg: `%s', length = %d\n", msg, (int) msg_length);
  
  ASSERT(rsa_encrypt(&pub,
		     &lfib, (nettle_random_func *) knuth_lfib_random,
		     msg_length, msg,
		     gibberish));

  if (verbose)
    {
      fprintf(stderr, "encrypted: ");
      mpz_out_str(stderr, 10, gibberish);
    }
  
  decrypted = xalloc(msg_length + 1);

  knuth_lfib_random (&lfib, msg_length + 1, decrypted);
  after = decrypted[msg_length];
  
  decrypted_length = msg_length - 1;
  ASSERT(!rsa_decrypt(&key, &decrypted_length, decrypted, gibberish));

  decrypted_length = msg_length;
  ASSERT(rsa_decrypt(&key, &decrypted_length, decrypted, gibberish));
  ASSERT(decrypted_length == msg_length);
  ASSERT(MEMEQ(msg_length, msg, decrypted));
  ASSERT(decrypted[msg_length] == after);

  knuth_lfib_random (&lfib, msg_length + 1, decrypted);
  after = decrypted[msg_length];

  decrypted_length = key.size;
  ASSERT(rsa_decrypt(&key, &decrypted_length, decrypted, gibberish));
  ASSERT(decrypted_length == msg_length);
  ASSERT(MEMEQ(msg_length, msg, decrypted));
  ASSERT(decrypted[msg_length] == after);
  
  knuth_lfib_random (&lfib, msg_length + 1, decrypted);
  after = decrypted[msg_length];

  decrypted_length = msg_length;
  ASSERT(rsa_decrypt_tr(&pub, &key,
			&lfib, (nettle_random_func *) knuth_lfib_random,
			&decrypted_length, decrypted, gibberish));
  ASSERT(decrypted_length == msg_length);
  ASSERT(MEMEQ(msg_length, msg, decrypted));
  ASSERT(decrypted[msg_length] == after);

  /* Test invalid key. */
  mpz_add_ui (key.q, key.q, 2);
  decrypted_length = key.size;
  ASSERT(!rsa_decrypt_tr(&pub, &key,
			 &lfib, (nettle_random_func *) knuth_lfib_random,
			 &decrypted_length, decrypted, gibberish));

  rsa_private_key_clear(&key);
  rsa_public_key_clear(&pub);
  mpz_clear(gibberish);
  free(decrypted);
}