コード例 #1
0
/**
 * cdk_pk_encrypt:
 * @pk: the public key
 * @pke: the public key encrypted packet
 * @esk: the actual session key
 *
 * Encrypt the session key in @esk and write its encrypted content
 * into the @pke struct.
 **/
cdk_error_t
cdk_pk_encrypt (cdk_pubkey_t pk, cdk_pkt_pubkey_enc_t pke,
                gcry_mpi_t esk)
{
  gcry_sexp_t s_data = NULL, s_pkey = NULL, s_ciph = NULL;
  gcry_error_t err;
  cdk_error_t rc;
  
  if (!pk || !esk || !pke)
    return CDK_Inv_Value;
  
  if (!KEY_CAN_ENCRYPT (pk->pubkey_algo))
    return CDK_Inv_Algo;

  rc = enckey_to_sexp (&s_data, esk);
  if (!rc)
    rc = pubkey_to_sexp (&s_pkey, pk);
  if (!rc)
    {     
      err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
      if (err)
	return map_gcry_error (err);
    }
  if (!rc)
    rc = sexp_to_pubenc (pke, s_ciph);
  
  gcry_sexp_release (s_data);
  gcry_sexp_release (s_pkey);
  gcry_sexp_release (s_ciph);
  return rc;
}
コード例 #2
0
ファイル: keys.c プロジェクト: BackupTheBerlios/libssh-svn
STRING *ssh_encrypt_rsa1(SSH_SESSION *session, STRING *data, PUBLIC_KEY *key){
    int len=string_len(data);
#ifdef HAVE_LIBGCRYPT
    STRING *ret;
    gcry_sexp_t ret_sexp;
    gcry_sexp_t data_sexp;
    const char *tmp;
    size_t size;
    gcry_sexp_build(&data_sexp,NULL,"(data(flags pkcs1)(value %b))",len,data->string);
    gcry_pk_encrypt(&ret_sexp,data_sexp,key->rsa_pub);
    gcry_sexp_release(data_sexp);
    data_sexp=gcry_sexp_find_token(ret_sexp,"a",0);
    tmp=gcry_sexp_nth_data(data_sexp,1,&size);
    if (*tmp == 0)
    {
      size--;
      tmp++;
    }
    ret=string_new(size);
    string_fill(ret,(char *)tmp,size);
    gcry_sexp_release(ret_sexp);
#elif defined HAVE_LIBCRYPTO
    int flen=RSA_size(key->rsa_pub);
    STRING *ret=string_new(flen);
    RSA_public_encrypt(len,data->string,ret->string,key->rsa_pub,
            RSA_PKCS1_PADDING);
#endif
    return ret;
}
コード例 #3
0
ファイル: Tb_rsa.cpp プロジェクト: nforrester/6.375-rsa
char* encrypt(rsa_packet * packet, char *public_key, char *plaintext){
	gcry_error_t error;

	gcry_mpi_t r_mpi;
	if ((error = gcry_mpi_scan(&r_mpi, GCRYMPI_FMT_HEX, plaintext, 0, NULL))) {
		printf("Error in gcry_mpi_scan() in encrypt(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}

	gcry_sexp_t data;
	size_t erroff;
	if ((error = gcry_sexp_build(&data, &erroff, "(data (flags raw) (value %m))", r_mpi))) {
		printf("Error in gcry_sexp_build() in encrypt() at %ld: %s\nSource: %s\n", erroff, gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}

	gcry_sexp_t public_sexp = sexp_new(public_key);
	gcry_sexp_t r_ciph;
	struct timeval timer;
	timer_start(&timer);
	if ((error = gcry_pk_encrypt(&r_ciph, data, public_sexp))) {
		printf("Error in gcry_pk_encrypt(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}
	timer_poll("\nSoftware encrypt: %d.%06d    seconds\n", &timer);
	
	gcry_sexp_t cipher_sexp = gcry_sexp_cdr(gcry_sexp_find_token(r_ciph, "a", 1));
	gcry_mpi_t cipher_mpi = gcry_sexp_nth_mpi(cipher_sexp, 0, GCRYMPI_FMT_USG);
	gcry_mpi_print(GCRYMPI_FMT_USG, packet->ciphertext, 256, &packet->cipher_len, cipher_mpi);  
	
	return sexp_string(r_ciph);
}
コード例 #4
0
ファイル: encrypt.c プロジェクト: aestetix/gnupg
/* Encrypt the DEK under the key contained in CERT and return it as a
   canonical S-Exp in encval. */
static int
encrypt_dek (const DEK dek, ksba_cert_t cert, unsigned char **encval)
{
  gcry_sexp_t s_ciph, s_data, s_pkey;
  int rc;
  ksba_sexp_t buf;
  size_t len;

  *encval = NULL;

  /* get the key from the cert */
  buf = ksba_cert_get_public_key (cert);
  if (!buf)
    {
      log_error ("no public key for recipient\n");
      return gpg_error (GPG_ERR_NO_PUBKEY);
    }
  len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
  if (!len)
    {
      log_error ("libksba did not return a proper S-Exp\n");
      return gpg_error (GPG_ERR_BUG);
    }
  rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)buf, len);
  xfree (buf); buf = NULL;
  if (rc)
    {
      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
      return rc;
    }

  /* Put the encoded cleartext into a simple list. */
  s_data = NULL; /* (avoid compiler warning) */
  rc = encode_session_key (dek, &s_data);
  if (rc)
    {
      log_error ("encode_session_key failed: %s\n", gpg_strerror (rc));
      return rc;
    }

  /* pass it to libgcrypt */
  rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
  gcry_sexp_release (s_data);
  gcry_sexp_release (s_pkey);
  
  /* Reformat it. */
  if (!rc)
    {
      rc = make_canon_sexp (s_ciph, encval, NULL);
      gcry_sexp_release (s_ciph);
    }
  return rc;
}
コード例 #5
0
ファイル: gnutls.c プロジェクト: tenchman/FreeRDP
void
crypto_rsa_encrypt(int len, uint8 * in, uint8 * out, uint32 modulus_size, uint8 * modulus, uint8 * exponent)
{
	/* GnuTLS do not expose raw RSA, so we use the underlying gcrypt lib instead */
	ASSERT(modulus_size <= SEC_MAX_MODULUS_SIZE);

	gcry_mpi_t m;
	gcry_error_t rc = gcry_mpi_scan(&m, GCRYMPI_FMT_USG, modulus, modulus_size, NULL);
	ASSERT(!rc);

	gcry_mpi_t e;
	rc = gcry_mpi_scan(&e, GCRYMPI_FMT_USG, exponent, SEC_EXPONENT_SIZE, NULL);

	gcry_sexp_t publickey_sexp;
	rc = gcry_sexp_build(&publickey_sexp, NULL, "(public-key(rsa(n%m)(e%m)))", m, e);
	ASSERT(!rc);

	gcry_mpi_release(m);
	gcry_mpi_release(e);

	gcry_mpi_t in_gcry;
	rc = gcry_mpi_scan(&in_gcry, GCRYMPI_FMT_USG, in, len, NULL);
	ASSERT(!rc);

	gcry_sexp_t in_sexp;
	rc = gcry_sexp_build(&in_sexp, NULL, "%m", in_gcry);
	ASSERT(!rc);

	gcry_sexp_t out_sexp;
	rc = gcry_pk_encrypt(&out_sexp, in_sexp, publickey_sexp);
	ASSERT(!rc);

	gcry_sexp_t out_list_sexp;
	out_list_sexp = gcry_sexp_find_token(out_sexp, "a", 0);
	ASSERT(out_list_sexp);

	gcry_mpi_t out_gcry = gcry_sexp_nth_mpi(out_list_sexp, 1, GCRYMPI_FMT_NONE);
	ASSERT(out_gcry);

	size_t s;
	rc = gcry_mpi_print(GCRYMPI_FMT_USG, out, modulus_size, &s, out_gcry);
	ASSERT(!rc);
	ASSERT(s == modulus_size);

	gcry_mpi_release(out_gcry);
	gcry_sexp_release(out_list_sexp);
	gcry_mpi_release(in_gcry);
	gcry_sexp_release(out_sexp);
	gcry_sexp_release(in_sexp);
	gcry_sexp_release(publickey_sexp);
}
コード例 #6
0
CK_RV
gkm_rsa_mechanism_encrypt (gcry_sexp_t sexp, EggPadding padding, CK_BYTE_PTR data,
                           CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
{
	gcry_sexp_t splain, sdata;
	gcry_error_t gcry;
	guint nbits;
	CK_RV rv;

	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
	g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);

	nbits = gcry_pk_get_nbits (sexp);
	g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);

	/* Just want to know the length */
	if (!encrypted) {
		*n_encrypted = (nbits + 7) / 8;
		return CKR_OK;
	}

	/* Prepare the input s expression */
	rv = gkm_crypto_data_to_sexp ("(data (flags raw) (value %m))",
	                              nbits, padding, data, n_data, &splain);
	if (rv != CKR_OK)
		return rv;

	/* Do the magic */
	gcry = gcry_pk_encrypt (&sdata, splain, sexp);
	gcry_sexp_release (splain);

	/* TODO: Certain codes should be returned (data too big etc... ) */
	if (gcry) {
		g_message ("encrypting of the data failed: %s", gcry_strerror (gcry));
		return CKR_FUNCTION_FAILED;
	}

	/* Now extract and send it back out */
	rv = gkm_crypto_sexp_to_data (sdata, nbits, encrypted, n_encrypted, NULL,
	                              "enc-val", "rsa", "a", NULL);
	gcry_sexp_release (sdata);

	return rv;
}
コード例 #7
0
ファイル: p2p_crypt.c プロジェクト: tjhall13/p2p_net
int p2p_encrypt(unsigned char *msg, size_t msglen, unsigned char *buf, size_t buflen, gcry_sexp_t r_key) {
    gcry_sexp_t ciph, data;
    size_t err;
    gcry_sexp_build(&data, &err, "(data (flags pkcs1) (value %b))", msglen, msg);
    
    gcry_pk_encrypt(&ciph, data, r_key);
    gcry_sexp_release(data);
    
    gcry_sexp_t a = gcry_sexp_find_token(ciph, "a", 0);
    gcry_sexp_release(ciph);
    gcry_sexp_t sexp_mpi = gcry_sexp_cdr(a);
    gcry_sexp_release(a);
    
    gcry_mpi_t data_mpi = gcry_sexp_nth_mpi(sexp_mpi, 0, GCRYMPI_FMT_USG);
    gcry_mpi_print(GCRYMPI_FMT_PGP, buf, buflen, &err, data_mpi);
    
    return err;
}
コード例 #8
0
ファイル: gnutls_pk.c プロジェクト: uvbs/SupportCenter
/****************
 * Emulate our old PK interface here - sometime in the future we might
 * change the internal design to directly fit to libgcrypt.
 */
static int
_gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data,
		    mpi_t * pkey, int pkey_len)
{
  gcry_sexp_t s_ciph, s_data, s_pkey;
  int rc = -1;

  /* make a sexp from pkey */
  switch (algo)
    {
    case GCRY_PK_RSA:
      if (pkey_len >= 2)
	rc = gcry_sexp_build (&s_pkey, NULL,
			      "(public-key(rsa(n%m)(e%m)))",
			      pkey[0], pkey[1]);
      break;

    default:
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  if (rc != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* put the data into a simple list */
  if (gcry_sexp_build (&s_data, NULL, "%m", data))
    {
      gnutls_assert ();
      gcry_sexp_release (s_pkey);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* pass it to libgcrypt */
  rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
  gcry_sexp_release (s_data);
  gcry_sexp_release (s_pkey);

  if (rc != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_ENCRYPTION_FAILED;

    }
  else
    {				/* add better error handling or make gnupg use S-Exp directly */
      gcry_sexp_t list = gcry_sexp_find_token (s_ciph, "a", 0);
      if (list == NULL)
	{
	  gnutls_assert ();
	  gcry_sexp_release (s_ciph);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
      gcry_sexp_release (list);

      if (resarr[0] == NULL)
	{
	  gnutls_assert ();
	  gcry_sexp_release (s_ciph);
	  return GNUTLS_E_INTERNAL_ERROR;
	}
    }

  gcry_sexp_release (s_ciph);
  return rc;
}
コード例 #9
0
ファイル: keys.c プロジェクト: rofl0r/libssh
ssh_string ssh_encrypt_rsa1(ssh_session session, ssh_string data, ssh_public_key key) {
    ssh_string str = NULL;
    size_t len = ssh_string_len(data);
    size_t size = 0;
#ifdef HAVE_LIBGCRYPT
    const char *tmp = NULL;
    gcry_sexp_t ret_sexp;
    gcry_sexp_t data_sexp;

    if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))",
                        len, ssh_string_data(data))) {
        ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
        return NULL;
    }
    if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) {
        gcry_sexp_release(data_sexp);
        ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
        return NULL;
    }

    gcry_sexp_release(data_sexp);

    data_sexp = gcry_sexp_find_token(ret_sexp, "a", 0);
    if (data_sexp == NULL) {
        ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
        gcry_sexp_release(ret_sexp);
        return NULL;
    }
    tmp = gcry_sexp_nth_data(data_sexp, 1, &size);
    if (*tmp == 0) {
        size--;
        tmp++;
    }

    str = ssh_string_new(size);
    if (str == NULL) {
        ssh_set_error(session, SSH_FATAL, "Not enough space");
        gcry_sexp_release(data_sexp);
        gcry_sexp_release(ret_sexp);
        return NULL;
    }
    ssh_string_fill(str, tmp, size);

    gcry_sexp_release(data_sexp);
    gcry_sexp_release(ret_sexp);
#elif defined HAVE_LIBCRYPTO
    size = RSA_size(key->rsa_pub);

    str = ssh_string_new(size);
    if (str == NULL) {
        ssh_set_error(session, SSH_FATAL, "Not enough space");
        return NULL;
    }

    if (RSA_public_encrypt(len, ssh_string_data(data), ssh_string_data(str), key->rsa_pub,
                           RSA_PKCS1_PADDING) < 0) {
        ssh_string_free(str);
        return NULL;
    }
#endif

    return str;
}
コード例 #10
0
ファイル: pk.c プロジェクト: dezelin/maily
static int
_wrap_gcry_pk_encrypt (gnutls_pk_algorithm_t algo,
                       gnutls_datum_t * ciphertext,
                       const gnutls_datum_t * plaintext,
                       const gnutls_pk_params_st * pk_params)
{
  gcry_sexp_t s_ciph = NULL, s_data = NULL, s_pkey = NULL;
  int rc = -1;
  int ret;
  bigint_t data, res;
  gcry_sexp_t list;

  if (_gnutls_mpi_scan_nz (&data, plaintext->data, plaintext->size) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  /* make a sexp from pkey */
  switch (algo)
    {
    case GNUTLS_PK_RSA:
      if (pk_params->params_nr >= 2)
        rc = gcry_sexp_build (&s_pkey, NULL,
                              "(public-key(rsa(n%m)(e%m)))",
                              pk_params->params[0], pk_params->params[1]);
      break;

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

  if (rc != 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  /* put the data into a simple list */
  if (gcry_sexp_build (&s_data, NULL, "%m", data))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  /* pass it to libgcrypt */
  rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
  if (rc != 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_PK_ENCRYPTION_FAILED;
      goto cleanup;
    }

  list = gcry_sexp_find_token (s_ciph, "a", 0);
  if (list == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  res = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (list);
  if (res == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  ret = _gnutls_mpi_dprint_size (res, ciphertext, plaintext->size);
  _gnutls_mpi_release (&res);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  ret = 0;

cleanup:
  _gnutls_mpi_release (&data);
  if (s_ciph)
    gcry_sexp_release (s_ciph);
  if (s_data)
    gcry_sexp_release (s_data);
  if (s_pkey)
    gcry_sexp_release (s_pkey);

  return ret;
}
コード例 #11
0
ファイル: steam-crypt.c プロジェクト: bitlbee/bitlbee-steam
GByteArray *
steam_crypt_rsa_enc(const GByteArray *mod, const GByteArray *exp,
                    const GByteArray *bytes)
{
    GByteArray *ret = NULL;
    gcry_error_t res;
    gcry_mpi_t dmpi = NULL;
    gcry_mpi_t empi = NULL;
    gcry_mpi_t mmpi = NULL;
    gcry_sexp_t cata = NULL;
    gcry_sexp_t data = NULL;
    gcry_sexp_t kata = NULL;
    gsize size;

    g_return_val_if_fail(mod != NULL, NULL);
    g_return_val_if_fail(exp != NULL, NULL);
    g_return_val_if_fail(bytes != NULL, NULL);

    res = gcry_mpi_scan(&mmpi, GCRYMPI_FMT_USG, mod->data,
                         mod->len, NULL);
    res |= gcry_mpi_scan(&empi, GCRYMPI_FMT_USG, exp->data,
                         exp->len, NULL);
    res |= gcry_mpi_scan(&dmpi, GCRYMPI_FMT_USG, bytes->data,
                         bytes->len, NULL);

    if (G_UNLIKELY(res != 0)) {
        goto finish;
    }

    res = gcry_sexp_build(&kata, NULL, "(public-key(rsa(n %m)(e %m)))",
                           mmpi, empi);
    res |= gcry_sexp_build(&data, NULL, "(data(flags pkcs1)(value %m))",
                           dmpi);

    if (G_UNLIKELY(res != 0)) {
        goto finish;
    }

    res = gcry_pk_encrypt(&cata, data, kata);

    if (G_UNLIKELY(res != 0)) {
        goto finish;
    }

    gcry_sexp_release(data);
    data = gcry_sexp_find_token(cata, "a", 0);

    if (G_UNLIKELY(data == NULL)) {
        g_warn_if_reached();
        goto finish;
    }

    gcry_mpi_release(dmpi);
    dmpi = gcry_sexp_nth_mpi(data, 1, GCRYMPI_FMT_USG);

    if (G_UNLIKELY(dmpi == NULL)) {
        g_warn_if_reached();
        goto finish;
    }

    ret = g_byte_array_new();
    g_byte_array_set_size(ret, mod->len);
    gcry_mpi_print(GCRYMPI_FMT_USG, ret->data, ret->len, &size, dmpi);

    g_warn_if_fail(size <= mod->len);
    g_byte_array_set_size(ret, size);

finish:
    gcry_sexp_release(cata);
    gcry_sexp_release(data);
    gcry_sexp_release(kata);

    gcry_mpi_release(dmpi);
    gcry_mpi_release(empi);
    gcry_mpi_release(mmpi);

    return ret;
}
コード例 #12
0
ファイル: pkcs1v2.c プロジェクト: GostCrypt/libgcrypt
/* Check against PKCS#1 v1.5 encryption test  vectors as found at
   ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt .  */
static void
check_v15crypt (void)
{
#include "pkcs1v2-v15c.h"
  gpg_error_t err;
  int tno, mno;

  for (tno = 0; tno < DIM (tbl); tno++)
    {
      void *rsa_n, *rsa_e, *rsa_d;
      size_t rsa_n_len, rsa_e_len, rsa_d_len;
      gcry_sexp_t sec_key, pub_key;

      if (verbose > 1)
        info ("(%s)\n", tbl[tno].desc);

      rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
      rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
      rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
      err = gcry_sexp_build (&sec_key, NULL,
                             "(private-key (rsa (n %b)(e %b)(d %b)))",
                             (int)rsa_n_len, rsa_n,
                             (int)rsa_e_len, rsa_e,
                             (int)rsa_d_len, rsa_d);
      if (err)
        die ("constructing private key failed: %s\n", gpg_strerror (err));
      err = gcry_sexp_build (&pub_key, NULL,
                             "(public-key (rsa (n %b)(e %b)))",
                             (int)rsa_n_len, rsa_n,
                             (int)rsa_e_len, rsa_e);
      if (err)
        die ("constructing public key failed: %s\n", gpg_strerror (err));
      gcry_free (rsa_n);
      gcry_free (rsa_e);
      gcry_free (rsa_d);

      for (mno = 0; mno < DIM (tbl[0].m); mno++)
        {
          void *mesg, *seed, *encr;
          size_t mesg_len, seed_len, encr_len;
          gcry_sexp_t plain, ciph;

          if (verbose)
            info ("running test: %s\n", tbl[tno].m[mno].desc);

          mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
          seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);

          err = gcry_sexp_build (&plain, NULL,
                                 "(data (flags pkcs1)(hash-algo sha1)"
                                 "(value %b)(random-override %b))",
                                 (int)mesg_len, mesg,
                                 (int)seed_len, seed);
          if (err)
            die ("constructing plain data failed: %s\n", gpg_strerror (err));
          gcry_free (mesg);
          gcry_free (seed);

          err = gcry_pk_encrypt (&ciph, plain, pub_key);
          if (err)
            {
              show_sexp ("plain:\n", ciph);
              fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
            }
          else
            {
              if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
                                    tbl[tno].m[mno].desc))
                {
                  show_sexp ("encrypt result:\n", ciph);
                  fail ("mismatch in gcry_pk_encrypt\n");
                }
              gcry_sexp_release (ciph);
              ciph = NULL;
            }
          gcry_sexp_release (plain);
          plain = NULL;

          /* Now test the decryption.  */
          seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
          encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);

          err = gcry_sexp_build (&ciph, NULL,
                                 "(enc-val (flags pkcs1)(hash-algo sha1)"
                                 "(random-override %b)"
                                 "(rsa (a %b)))",
                                 (int)seed_len, seed,
                                 (int)encr_len, encr);
          if (err)
            die ("constructing cipher data failed: %s\n", gpg_strerror (err));
          gcry_free (encr);
          gcry_free (seed);

          err = gcry_pk_decrypt (&plain, ciph, sec_key);
          if (err)
            {
              show_sexp ("ciph:\n", ciph);
              fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
            }
          else
            {
              if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
                                    tbl[tno].m[mno].desc))
                {
                  show_sexp ("decrypt result:\n", plain);
                  fail ("mismatch in gcry_pk_decrypt\n");
                }
              gcry_sexp_release (plain);
              plain = NULL;
            }
          gcry_sexp_release (ciph);
          ciph = NULL;
        }

      gcry_sexp_release (sec_key);
      gcry_sexp_release (pub_key);
    }
}
コード例 #13
0
ファイル: crypto-gnutls.c プロジェクト: ukservers/vpnc
unsigned char *crypto_decrypt_signature(crypto_ctx *ctx,
                                        const unsigned char *sig_data,
                                        size_t sig_len,
                                        size_t *out_len,
                                        unsigned int padding,
                                        crypto_error **error)
{
    unsigned char *buf = NULL, *rec_hash = NULL;
    gnutls_datum_t n = { NULL, 0 }, e = { NULL, 0 };
    int err, algo;
    gcry_sexp_t key = NULL, sig = NULL, decrypted = NULL, child = NULL;
    gcry_mpi_t n_mpi = NULL, e_mpi = NULL, sig_mpi = NULL, dec_mpi = NULL;
    size_t buf_len = 0, hash_len = 0;

    if (!ctx) {
        crypto_error_set(error, 1, 0, "invalid crypto context");
        return NULL;
    }

    if (!ctx->num) {
        crypto_error_set(error, 1, 0, "no certificates in the stack");
        return NULL;
    }

    algo = gnutls_x509_crt_get_pk_algorithm(ctx->stack[ctx->num - 1], NULL);
    if (algo != GNUTLS_PK_RSA) {
        crypto_error_set(error, 1, 0, "certificate public key algorithm not RSA");
        return NULL;
    }

    err = gnutls_x509_crt_get_pk_rsa_raw(ctx->stack[ctx->num - 1], &n, &e);
    if (err != GNUTLS_E_SUCCESS) {
        crypto_error_set(error, 1, 0, "error getting certificate public key");
        return NULL;
    }

    err = gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_USG, n.data, n.size, NULL);
    if (err) {
        crypto_error_set(error, 1, 0, "invalid RSA key 'n' format");
        goto out;
    }

    err = gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_USG, e.data, e.size, NULL);
    if (err) {
        crypto_error_set(error, 1, 0, "invalid RSA key 'e' format");
        goto out;
    }

    err = gcry_sexp_build(&key, NULL, "(public-key (rsa (n %m) (e %m)))", n_mpi, e_mpi);
    if (err) {
        crypto_error_set(error, 1, 0, "could not create public-key expression");
        goto out;
    }

    err = gcry_mpi_scan(&sig_mpi, GCRYMPI_FMT_USG, sig_data, sig_len, NULL);
    if (err) {
        crypto_error_set(error, 1, 0, "invalid signature format");
        goto out;
    }

    err = gcry_sexp_build(&sig, NULL, "(data (flags raw) (value %m))", sig_mpi);
    if (err) {
        crypto_error_set(error, 1, 0, "could not create signature expression");
        goto out;
    }

    /* encrypt is equivalent to public key decryption for RSA keys */
    err = gcry_pk_encrypt(&decrypted, sig, key);
    if (err) {
        crypto_error_set(error, 1, 0, "could not decrypt signature");
        goto out;
    }

    child = gcry_sexp_find_token(decrypted, "a", 1);
    if (!child) {
        crypto_error_set(error, 1, 0, "could not get decrypted signature result");
        goto out;
    }

    dec_mpi = gcry_sexp_nth_mpi(child, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(child);

    if (!dec_mpi) {
        crypto_error_set(error, 1, 0, "could not get decrypted signature result");
        goto out;
    }

    gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &buf_len, dec_mpi);
    if (!buf) {
        crypto_error_set(error, 1, 0, "could not get extract decrypted signature");
        goto out;
    }

    switch (padding) {
    case CRYPTO_PAD_NONE:
        rec_hash = buf;
        hash_len = buf_len;
        buf = NULL;
        *out_len = (int) hash_len;
        break;
    case CRYPTO_PAD_PKCS1:
        rec_hash = check_pkcs1_padding(buf, buf_len, &hash_len, error);
        if (!rec_hash) {
            crypto_error_set(error, 1, 0, "could not get extract decrypted padded signature");
            goto out;
        }
        *out_len = (int) hash_len;
        break;
    default:
        crypto_error_set(error, 1, 0, "unknown padding mechanism %d", padding);
        break;
    }

out:
    if (buf)
        free(buf);
    if (dec_mpi)
        gcry_mpi_release(dec_mpi);
    if (decrypted)
        gcry_sexp_release(decrypted);
    if (key)
        gcry_sexp_release(key);
    if (sig)
        gcry_sexp_release(sig);
    if (sig_mpi)
        gcry_mpi_release(sig_mpi);
    if (n_mpi)
        gcry_mpi_release(n_mpi);
    if (e_mpi)
        gcry_mpi_release(e_mpi);
    if (n.data)
        gcry_free(n.data);
    if (e.data)
        gcry_free(e.data);

    return rec_hash;
}
コード例 #14
0
ファイル: pubkey.c プロジェクト: creationst/Creation2
static void
check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
		  gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
{
  gcry_sexp_t plain1, cipher, l;
  gcry_mpi_t x0, x1;
  int rc;
  int have_flags;

  /* Extract data from plaintext.  */
  l = gcry_sexp_find_token (plain0, "value", 0);
  x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (l);

  /* Encrypt data.  */
  rc = gcry_pk_encrypt (&cipher, plain0, pkey);
  if (rc)
    die ("encryption failed: %s\n", gcry_strerror (rc));

  l = gcry_sexp_find_token (cipher, "flags", 0);
  have_flags = !!l;
  gcry_sexp_release (l);

  /* Decrypt data.  */
  rc = gcry_pk_decrypt (&plain1, cipher, skey);
  gcry_sexp_release (cipher);
  if (rc)
    {
      if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
	{
	  gcry_mpi_release (x0);
	  return; /* This is the expected failure code.  */
	}
      die ("decryption failed: %s\n", gcry_strerror (rc));
    }

  /* Extract decrypted data.  Note that for compatibility reasons, the
     output of gcry_pk_decrypt depends on whether a flags lists (even
     if empty) occurs in its input data.  Because we passed the output
     of encrypt directly to decrypt, such a flag value won't be there
     as of today.  We check it anyway. */
  l = gcry_sexp_find_token (plain1, "value", 0);
  if (l)
    {
      if (!have_flags)
        die ("compatibility mode of pk_decrypt broken\n");
      gcry_sexp_release (plain1);
      x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
      gcry_sexp_release (l);
    }
  else
    {
      if (have_flags)
        die ("compatibility mode of pk_decrypt broken\n");
      x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
      gcry_sexp_release (plain1);
    }

  /* Compare.  */
  if (gcry_mpi_cmp (x0, x1))
    die ("data corrupted\n");
  gcry_mpi_release (x0);
  gcry_mpi_release (x1);
}
コード例 #15
0
ファイル: t-cv25519.c プロジェクト: GostCrypt/libgcrypt
/*
 * Test X25519 functionality through higher layer crypto routines.
 *
 * Input: K (as hex string), U (as hex string), R (as hex string)
 *
 * where R is expected result of X25519 (K, U).
 *
 * It calls gcry_pk_decrypt with Curve25519 private key and let
 * it compute X25519.
 */
static void
test_cv (int testno, const char *k_str, const char *u_str,
         const char *result_str)
{
  gpg_error_t err;
  void *buffer = NULL;
  size_t buflen;
  gcry_sexp_t s_pk = NULL;
  gcry_mpi_t mpi_k = NULL;
  gcry_sexp_t s_data = NULL;
  gcry_sexp_t s_result = NULL;
  gcry_sexp_t s_tmp = NULL;
  unsigned char *res = NULL;
  size_t res_len;

  if (verbose > 1)
    info ("Running test %d\n", testno);

  if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "k", "invalid hex string");
      goto leave;
    }

  reverse_buffer (buffer, buflen);
  if ((err = gcry_mpi_scan (&mpi_k, GCRYMPI_FMT_USG, buffer, buflen, NULL)))
    {
      fail ("error converting MPI for test %d: %s", testno, gpg_strerror (err));
      goto leave;
    }

  if ((err = gcry_sexp_build (&s_data, NULL, "%m", mpi_k)))
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "data", gpg_strerror (err));
      goto leave;
    }

  xfree (buffer);
  if (!(buffer = hex2buffer (u_str, &buflen)) || buflen != 32)
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "u", "invalid hex string");
      goto leave;
    }

  /*
   * The procedure of decodeUCoordinate will be done internally
   * by _gcry_ecc_mont_decodepoint.  So, we just put the little-endian
   * binary to build S-exp.
   *
   * We could add the prefix 0x40, but libgcrypt also supports
   * format with no prefix.  So, it is OK not to put the prefix.
   */
  if ((err = gcry_sexp_build (&s_pk, NULL,
                              "(public-key"
                              " (ecc"
                              "  (curve \"Curve25519\")"
                              "  (flags djb-tweak)"
                              "  (q%b)))", (int)buflen, buffer)))
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "pk", gpg_strerror (err));
      goto leave;
    }

  xfree (buffer);
  buffer = NULL;

  if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk)))
    fail ("gcry_pk_encrypt failed for test %d: %s", testno,
          gpg_strerror (err));

  s_tmp = gcry_sexp_find_token (s_result, "s", 0);
  if (!s_tmp || !(res = gcry_sexp_nth_buffer (s_tmp, 1, &res_len)))
    fail ("gcry_pk_encrypt failed for test %d: %s", testno, "missing value");
  else
    {
      char *r, *r0;
      int i;

      /* To skip the prefix 0x40, for-loop start with i=1 */
      r0 = r = xmalloc (2*(res_len)+1);
      if (!r0)
        {
          fail ("memory allocation for test %d", testno);
          goto leave;
        }

      for (i=1; i < res_len; i++, r += 2)
        snprintf (r, 3, "%02x", res[i]);
      if (strcmp (result_str, r0))
        {
          fail ("gcry_pk_encrypt failed for test %d: %s",
                testno, "wrong value returned");
          info ("  expected: '%s'", result_str);
          info ("       got: '%s'", r0);
        }
      xfree (r0);
    }

 leave:
  xfree (res);
  gcry_mpi_release (mpi_k);
  gcry_sexp_release (s_tmp);
  gcry_sexp_release (s_result);
  gcry_sexp_release (s_data);
  gcry_sexp_release (s_pk);
  xfree (buffer);
}