Example #1
0
/*
 * Verify an OpenPGP signature made with some DSA public key
 */
static int verify_signature_dsa( signature_packet_t *sign, public_key_packet_t *p_key,
                      uint8_t *p_hash )
{
    int ret = VLC_EGENERIC;

    /* the data to be verified (a hash) */
    const char *hash_sexp_s = "(data(flags raw)(value %m))";
    /* the public key */
    const char *key_sexp_s = "(public-key(dsa(p %m)(q %m)(g %m)(y %m)))";
    /* the signature */
    const char *sig_sexp_s = "(sig-val(dsa(r %m )(s %m )))";

    size_t erroff;
    gcry_mpi_t p, q, g, y, r, s, hash;
    p = q = g = y = r = s = hash = NULL;
    gcry_sexp_t key_sexp, hash_sexp, sig_sexp;
    key_sexp = hash_sexp = sig_sexp = NULL;

    int i_p_len = mpi_len( p_key->sig.dsa.p );
    int i_q_len = mpi_len( p_key->sig.dsa.q );
    int i_g_len = mpi_len( p_key->sig.dsa.g );
    int i_y_len = mpi_len( p_key->sig.dsa.y );
    if( gcry_mpi_scan( &p, GCRYMPI_FMT_USG, p_key->sig.dsa.p + 2, i_p_len, NULL ) ||
        gcry_mpi_scan( &q, GCRYMPI_FMT_USG, p_key->sig.dsa.q + 2, i_q_len, NULL ) ||
        gcry_mpi_scan( &g, GCRYMPI_FMT_USG, p_key->sig.dsa.g + 2, i_g_len, NULL ) ||
        gcry_mpi_scan( &y, GCRYMPI_FMT_USG, p_key->sig.dsa.y + 2, i_y_len, NULL ) ||
        gcry_sexp_build( &key_sexp, &erroff, key_sexp_s, p, q, g, y ) )
        goto out;

    uint8_t *p_r = sign->algo_specific.dsa.r;
    uint8_t *p_s = sign->algo_specific.dsa.s;
    int i_r_len = mpi_len( p_r );
    int i_s_len = mpi_len( p_s );
    if( gcry_mpi_scan( &r, GCRYMPI_FMT_USG, p_r + 2, i_r_len, NULL ) ||
        gcry_mpi_scan( &s, GCRYMPI_FMT_USG, p_s + 2, i_s_len, NULL ) ||
        gcry_sexp_build( &sig_sexp, &erroff, sig_sexp_s, r, s ) )
        goto out;

    int i_hash_len = gcry_md_get_algo_dlen (sign->digest_algo);
    if (i_hash_len > i_q_len)
        i_hash_len = i_q_len;
    if( gcry_mpi_scan( &hash, GCRYMPI_FMT_USG, p_hash, i_hash_len, NULL ) ||
        gcry_sexp_build( &hash_sexp, &erroff, hash_sexp_s, hash ) )
        goto out;

    if( gcry_pk_verify( sig_sexp, hash_sexp, key_sexp ) )
        goto out;

    ret = VLC_SUCCESS;

out:
    if( p ) gcry_mpi_release( p );
    if( q ) gcry_mpi_release( q );
    if( g ) gcry_mpi_release( g );
    if( y ) gcry_mpi_release( y );
    if( r ) gcry_mpi_release( r );
    if( s ) gcry_mpi_release( s );
    if( hash ) gcry_mpi_release( hash );
    if( key_sexp ) gcry_sexp_release( key_sexp );
    if( sig_sexp ) gcry_sexp_release( sig_sexp );
    if( hash_sexp ) gcry_sexp_release( hash_sexp );

    return ret;
}
Example #2
0
File: pk.c Project: dezelin/maily
static int
_wrap_gcry_pk_verify (gnutls_pk_algorithm_t algo,
                      const gnutls_datum_t * vdata,
                      const gnutls_datum_t * signature,
                      const gnutls_pk_params_st * pk_params)
{
  gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
  int rc = -1, ret;
  bigint_t hash;
  bigint_t tmp[2] = { NULL, NULL };

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

  /* make a sexp from pkey */
  switch (algo)
    {
    case GNUTLS_PK_DSA:
      if (pk_params->params_nr >= 4)
        rc = gcry_sexp_build (&s_pkey, NULL,
                              "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
                              pk_params->params[0], pk_params->params[1],
                              pk_params->params[2], pk_params->params[3]);
      break;
    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_hash, NULL, "%m", hash))
    {
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  switch (algo)
    {
    case GNUTLS_PK_DSA:
      ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
      if (ret < 0)
        {
          gnutls_assert ();
          goto cleanup;
        }
      rc = gcry_sexp_build (&s_sig, NULL,
                            "(sig-val(dsa(r%m)(s%m)))", tmp[0], tmp[1]);
      _gnutls_mpi_release (&tmp[0]);
      _gnutls_mpi_release (&tmp[1]);
      break;

    case GNUTLS_PK_RSA:
      ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size);
      if (ret < 0)
        {
          gnutls_assert ();
          goto cleanup;
        }
      rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", tmp[0]);
      _gnutls_mpi_release (&tmp[0]);
      break;

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

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

  rc = gcry_pk_verify (s_sig, s_hash, s_pkey);

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

  ret = 0;

cleanup:
  _gnutls_mpi_release (&hash);
  if (s_sig)
    gcry_sexp_release (s_sig);
  if (s_hash)
    gcry_sexp_release (s_hash);
  if (s_pkey)
    gcry_sexp_release (s_pkey);

  return ret;
}
Example #3
0
static void
dsa_bench (int iterations, int print_header)
{
  gpg_error_t err;
  gcry_sexp_t pub_key[3], sec_key[3];
  int p_sizes[3] = { 1024, 2048, 3072 };
  int q_sizes[3] = { 160, 224, 256 };
  gcry_sexp_t data;
  gcry_sexp_t sig = NULL;
  int i, j;

  err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
                         strlen (sample_public_dsa_key_1024));
  if (!err)
    err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024,
                           strlen (sample_private_dsa_key_1024));
  if (!err)
    err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048,
                           strlen (sample_public_dsa_key_2048));
  if (!err)
    err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048,
                           strlen (sample_private_dsa_key_2048));
  if (!err)
    err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072,
                           strlen (sample_public_dsa_key_3072));
  if (!err)
    err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072,
                           strlen (sample_private_dsa_key_3072));
  if (err)
    {
      fprintf (stderr, PGM ": converting sample keys failed: %s\n",
               gcry_strerror (err));
      exit (1);
    }

  if (print_header)
    printf ("Algorithm         generate %4d*sign %4d*verify\n"
            "------------------------------------------------\n",
            iterations, iterations );
  for (i=0; i < DIM (q_sizes); i++)
    {
      gcry_mpi_t x;

      x = gcry_mpi_new (q_sizes[i]);
      gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM);
      err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
      gcry_mpi_release (x);
      if (err)
        {
          fprintf (stderr, PGM ": converting data failed: %s\n",
                   gcry_strerror (err));
          exit (1);
        }

      printf ("DSA %d/%d             -", p_sizes[i], q_sizes[i]);
      fflush (stdout);

      start_timer ();
      for (j=0; j < iterations; j++)
        {
          gcry_sexp_release (sig);
          err = gcry_pk_sign (&sig, data, sec_key[i]);
          if (err)
            {
              putchar ('\n');
              fprintf (stderr, PGM ": signing failed: %s\n",
                       gpg_strerror (err));
              exit (1);
            }
        }
      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      start_timer ();
      for (j=0; j < iterations; j++)
        {
          err = gcry_pk_verify (sig, data, pub_key[i]);
          if (err)
            {
              putchar ('\n');
              fprintf (stderr, PGM ": verify failed: %s\n",
                       gpg_strerror (err));
              exit (1);
            }
        }
      stop_timer ();
      printf ("     %s\n", elapsed_time ());
      fflush (stdout);

      gcry_sexp_release (sig);
      gcry_sexp_release (data);
      sig = NULL;
    }


  for (i=0; i < DIM (q_sizes); i++)
    {
      gcry_sexp_release (sec_key[i]);
      gcry_sexp_release (pub_key[i]);
    }
}
Example #4
0
static void
ecc_bench (int iterations, int print_header)
{
#if USE_ECC
  gpg_error_t err;
  int p_sizes[] = { 192, 224, 256, 384, 521 };
  int testno;

  if (print_header)
    printf ("Algorithm         generate %4d*sign %4d*verify\n"
            "------------------------------------------------\n",
            iterations, iterations );
  for (testno=0; testno < DIM (p_sizes); testno++)
    {
      gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
      gcry_mpi_t x;
      gcry_sexp_t data;
      gcry_sexp_t sig = NULL;
      int count;

      printf ("ECDSA %3d bit ", p_sizes[testno]);
      fflush (stdout);

      err = gcry_sexp_build (&key_spec, NULL,
                             "(genkey (ECDSA (nbits %d)))", p_sizes[testno]);
      if (err)
        die ("creating S-expression failed: %s\n", gcry_strerror (err));

      start_timer ();
      err = gcry_pk_genkey (&key_pair, key_spec);
      if (err)
        die ("creating %d bit ECC key failed: %s\n",
             p_sizes[testno], gcry_strerror (err));

      pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
      if (! pub_key)
        die ("public part missing in key\n");
      sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
      if (! sec_key)
        die ("private part missing in key\n");
      gcry_sexp_release (key_pair);
      gcry_sexp_release (key_spec);

      stop_timer ();
      printf ("     %s", elapsed_time ());
      fflush (stdout);

      x = gcry_mpi_new (p_sizes[testno]);
      gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM);
      err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
      gcry_mpi_release (x);
      if (err)
        die ("converting data failed: %s\n", gcry_strerror (err));

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          gcry_sexp_release (sig);
          err = gcry_pk_sign (&sig, data, sec_key);
          if (err)
            die ("signing failed: %s\n", gpg_strerror (err));
        }
      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          err = gcry_pk_verify (sig, data, pub_key);
          if (err)
            {
              putchar ('\n');
              show_sexp ("seckey:\n", sec_key);
              show_sexp ("data:\n", data);
              show_sexp ("sig:\n", sig);
              die ("verify failed: %s\n", gpg_strerror (err));
            }
        }
      stop_timer ();
      printf ("     %s\n", elapsed_time ());
      fflush (stdout);

      gcry_sexp_release (sig);
      gcry_sexp_release (data);
      gcry_sexp_release (sec_key);
      gcry_sexp_release (pub_key);
    }
#endif /*USE_ECC*/
}
void attack(int i, unsigned char *digest, int hash_len){
    
        gcry_error_t err;

        gcry_sexp_t ciphertext , plaintext, ptx2, new_dsa_key_pair;
        
        gcry_sexp_t r_param, r_tilda_param, k_tilda_param, msg_digest_param;
        gcry_sexp_t s_param, s_tilda_param;
        gcry_sexp_t g_param;
        gcry_sexp_t p_param;
        gcry_sexp_t q_param;
        gcry_sexp_t x_param, y_param;
        
        
        
        gcry_mpi_t r , r_tilda, k_tilda, x, y;
        gcry_mpi_t s , s_tilda;
        gcry_mpi_t g;
        gcry_mpi_t p;
        gcry_mpi_t q;
        gcry_mpi_t msg_digest;
   

        retrieve_key_pair(files[i]);

        //*************** CORRECT SIGNATURE ********************//

        //20 is the mdlen of sha1 as specified in https://lists.gnupg.org/pipermail/gnupg-devel/2013-September/027916.html
        //a well formatted number for the immaediate has an even number of digits
        err = gcry_sexp_build(&plaintext, NULL, "(data (flags rfc6979) (hash %s %b))" , "sha1", hash_len , digest);

        err = gcry_pk_sign(&ciphertext, plaintext, dsa_key_pair);


        //now let's convert the s-expression representing r into an MPI in order
        //to use it in the equation of the attack 

        //--------- CIPHERTEXT --------------

        r_param = gcry_sexp_find_token(ciphertext, "r", 0);
        r = gcry_sexp_nth_mpi ( r_param , 1, GCRYMPI_FMT_USG);
             
        s_param = gcry_sexp_find_token(ciphertext, "s", 0);
        s = gcry_sexp_nth_mpi ( s_param , 1, GCRYMPI_FMT_USG);


        //--------- PUB KEY --------------

        g_param = gcry_sexp_find_token(dsa_key_pair, "g", 0);
        g = gcry_sexp_nth_mpi ( g_param , 1, GCRYMPI_FMT_USG);

        p_param = gcry_sexp_find_token(dsa_key_pair, "p", 0);
        p = gcry_sexp_nth_mpi ( p_param , 1, GCRYMPI_FMT_USG);

        q_param = gcry_sexp_find_token(dsa_key_pair, "q", 0);
        q = gcry_sexp_nth_mpi ( q_param , 1, GCRYMPI_FMT_USG);

        x_param = gcry_sexp_find_token(dsa_key_pair, "x", 0);
        x = gcry_sexp_nth_mpi ( x_param , 1, GCRYMPI_FMT_USG);

        y_param = gcry_sexp_find_token(dsa_key_pair, "y", 0);
        y = gcry_sexp_nth_mpi ( y_param , 1, GCRYMPI_FMT_USG);

    	unsigned int qbits = mpi_get_nbits(q);
    	unsigned int pbits = mpi_get_nbits(p);
    

        msg_digest_param = gcry_sexp_find_token(plaintext, "hash", 0);
        msg_digest = gcry_sexp_nth_mpi ( msg_digest_param , 2, GCRYMPI_FMT_USG);



        //*************** FAULTY SIGNATURE ********************//

        err = gcry_sexp_build(&ptx2, NULL, "(data (flags rfc6979) (hash %s %b) (attack))" , "sha1", hash_len , digest);

        err = gcry_pk_sign(&ciphertext, ptx2, dsa_key_pair);

        s_tilda_param = gcry_sexp_find_token(ciphertext, "s", 0);
        s_tilda = gcry_sexp_nth_mpi ( s_tilda_param , 1, GCRYMPI_FMT_USG);

        r_tilda_param = gcry_sexp_find_token(ciphertext, "r", 0);
        r_tilda = gcry_sexp_nth_mpi ( r_tilda_param , 1, GCRYMPI_FMT_USG);

        k_tilda_param = gcry_sexp_find_token(ciphertext, "k", 0);
        k_tilda = gcry_sexp_nth_mpi ( k_tilda_param , 1, GCRYMPI_FMT_USG);


        //POC 

        // 1 - choose a message
        // 2 - do the correct sign and obtain s and r
        // 3 - do the faulty sign and obtain s_tilda and r_tilda

        gcry_mpi_t tmp = gcry_mpi_new(mpi_get_nbits(p));

        gcry_mpi_t result = gcry_mpi_new(mpi_get_nbits(p));

        gcry_mpi_subm(tmp, s_tilda, s,q);   //s-tilda -s mod q

        gcry_mpi_mulm(msg_digest, msg_digest, tmp, q);  //m* (s-tilda -s mod q) mod q

        gcry_mpi_mulm(tmp, r_tilda, s, q);  //r_tilda - s mod q

        gcry_mpi_mulm(result, s_tilda, r, q);    //s_tilda - r mod q

        gcry_mpi_subm(result, tmp, result, q);  //(r_tilda - s mod q) - (s_tilda - r mod q) mod q

        gcry_mpi_invm(result,result,q); //((r_tilda - s mod q) - (s_tilda - r mod q) mod q)^-1 mod q

        gcry_mpi_mulm(result, msg_digest, result, q);   //( (m* (s-tilda -s mod q) mod q) * ((r_tilda - s mod q) - (s_tilda - r mod q) mod q)^-1 mod q ) mod q == x (private key)

        err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                     "(key-data"
                     " (public-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                     " (private-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                    p,q,g,y,p,q,g,y,result);
    	     
    	err = gcry_pk_sign(&ciphertext, plaintext, new_dsa_key_pair);

        err = gcry_pk_verify(ciphertext, plaintext, dsa_key_pair);
    
        if (err) {
            printf("\nSomething went wrong...\n");
            exit(0);
        }
        if(!printed){
             DEBUG_MPI_PRINT(result,"\nX = ");
             printed = 1;
        }
}
Example #6
0
static void
rsa_bench (int iterations, int print_header, int no_blinding)
{
  gpg_error_t err;
  int p_sizes[] = { 1024, 2048, 3072, 4096 };
  int testno;

  if (print_header)
    printf ("Algorithm         generate %4d*sign %4d*verify\n"
            "------------------------------------------------\n",
            iterations, iterations );
  for (testno=0; testno < DIM (p_sizes); testno++)
    {
      gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
      gcry_mpi_t x;
      gcry_sexp_t data;
      gcry_sexp_t sig = NULL;
      int count;

      printf ("RSA %3d bit    ", p_sizes[testno]);
      fflush (stdout);

      err = gcry_sexp_build (&key_spec, NULL,
                             gcry_fips_mode_active ()
                             ? "(genkey (RSA (nbits %d)))"
                             : "(genkey (RSA (nbits %d)(transient-key)))",
                             p_sizes[testno]);
      if (err)
        die ("creating S-expression failed: %s\n", gcry_strerror (err));

      start_timer ();
      err = gcry_pk_genkey (&key_pair, key_spec);
      if (err)
        die ("creating %d bit RSA key failed: %s\n",
             p_sizes[testno], gcry_strerror (err));

      pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
      if (! pub_key)
        die ("public part missing in key\n");
      sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
      if (! sec_key)
        die ("private part missing in key\n");
      gcry_sexp_release (key_pair);
      gcry_sexp_release (key_spec);

      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      x = gcry_mpi_new (p_sizes[testno]);
      gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
      err = gcry_sexp_build (&data, NULL,
                             "(data (flags raw) (value %m))", x);
      gcry_mpi_release (x);
      if (err)
        die ("converting data failed: %s\n", gcry_strerror (err));

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          gcry_sexp_release (sig);
          err = gcry_pk_sign (&sig, data, sec_key);
          if (err)
            die ("signing failed (%d): %s\n", count, gpg_strerror (err));
        }
      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          err = gcry_pk_verify (sig, data, pub_key);
          if (err)
            {
              putchar ('\n');
              show_sexp ("seckey:\n", sec_key);
              show_sexp ("data:\n", data);
              show_sexp ("sig:\n", sig);
              die ("verify failed (%d): %s\n", count, gpg_strerror (err));
            }
        }
      stop_timer ();
      printf ("     %s", elapsed_time ());

      if (no_blinding)
        {
          fflush (stdout);
          x = gcry_mpi_new (p_sizes[testno]);
          gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
          err = gcry_sexp_build (&data, NULL,
                                 "(data (flags no-blinding) (value %m))", x);
          gcry_mpi_release (x);
          if (err)
            die ("converting data failed: %s\n", gcry_strerror (err));

          start_timer ();
          for (count=0; count < iterations; count++)
            {
              gcry_sexp_release (sig);
              err = gcry_pk_sign (&sig, data, sec_key);
              if (err)
                die ("signing failed (%d): %s\n", count, gpg_strerror (err));
            }
          stop_timer ();
          printf ("   %s", elapsed_time ());
          fflush (stdout);
        }

      putchar ('\n');
      fflush (stdout);

      gcry_sexp_release (sig);
      gcry_sexp_release (data);
      gcry_sexp_release (sec_key);
      gcry_sexp_release (pub_key);
    }
}
Example #7
0
/* Check against PKCS#1 v1.5 signature test vectors as found at
   ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt .  */
static void
check_v15sign (void)
{
#include "pkcs1v2-v15s.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, *sign;
          size_t mesg_len, sign_len;
          gcry_sexp_t sigtmpl, sig;
          char mhash[20];

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

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

          gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len);
          err = gcry_sexp_build (&sigtmpl, NULL,
                                 "(data (flags pkcs1)"
                                 "(hash sha1 %b))",
                                 20, mhash);
          if (err)
            die ("constructing sig template failed: %s\n", gpg_strerror (err));
          gcry_free (mesg);

          err = gcry_pk_sign (&sig, sigtmpl, sec_key);
          if (err)
            {
              show_sexp ("sigtmpl:\n", sigtmpl);
              fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
            }
          else
            {
              if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign,
                                    tbl[tno].m[mno].desc))
                {
                  show_sexp ("sign result:\n", sig);
                  fail ("mismatch in gcry_pk_sign\n");
                }
              gcry_sexp_release (sig);
              sig = NULL;
            }
          gcry_sexp_release (sigtmpl);
          sigtmpl = NULL;

          /* Now test the verification.  */
          sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len);

          err = gcry_sexp_build (&sig, NULL,
                                 "(sig-val(rsa(s %b)))",
                                 (int)sign_len, sign);
          if (err)
            die ("constructing verify data failed: %s\n", gpg_strerror (err));
          err = gcry_sexp_build (&sigtmpl, NULL,
                                 "(data (flags pkcs1)"
                                 "(hash sha1 %b))",
                                 20, mhash);
          if (err)
            die ("constructing verify tmpl failed: %s\n", gpg_strerror (err));
          gcry_free (sign);

          err = gcry_pk_verify (sig, sigtmpl, pub_key);
          if (err)
            {
              show_sexp ("sig:\n", sig);
              show_sexp ("sigtmpl:\n", sigtmpl);
              fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err));
            }
          gcry_sexp_release (sig);
          sig = NULL;
          gcry_sexp_release (sigtmpl);
          sigtmpl = NULL;
        }

      gcry_sexp_release (sec_key);
      gcry_sexp_release (pub_key);
    }
}
Example #8
0
/* Check the signature on CERT using the ISSUER-CERT.  This function
   does only test the cryptographic signature and nothing else.  It is
   assumed that the ISSUER_CERT is valid. */
int
gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
{
  const char *algoid;
  gcry_md_hd_t md;
  int rc, algo;
  gcry_mpi_t frame;
  ksba_sexp_t p;
  size_t n;
  gcry_sexp_t s_sig, s_hash, s_pkey;

  algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert)));
  if (!algo)
    {
      log_error ("unknown hash algorithm '%s'\n", algoid? algoid:"?");
      if (algoid
          && (  !strcmp (algoid, "1.2.840.113549.1.1.2")
                ||!strcmp (algoid, "1.2.840.113549.2.2")))
        log_info (_("(this is the MD2 algorithm)\n"));
      return gpg_error (GPG_ERR_GENERAL);
    }
  rc = gcry_md_open (&md, algo, 0);
  if (rc)
    {
      log_error ("md_open failed: %s\n", gpg_strerror (rc));
      return rc;
    }
  if (DBG_HASHING)
    gcry_md_debug (md, "hash.cert");

  rc = ksba_cert_hash (cert, 1, HASH_FNC, md);
  if (rc)
    {
      log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc));
      gcry_md_close (md);
      return rc;
    }
  gcry_md_final (md);

  p = ksba_cert_get_sig_val (cert);
  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
  if (!n)
    {
      log_error ("libksba did not return a proper S-Exp\n");
      gcry_md_close (md);
      ksba_free (p);
      return gpg_error (GPG_ERR_BUG);
    }
  if (DBG_CRYPTO)
    {
      int j;
      log_debug ("signature value:");
      for (j=0; j < n; j++)
        log_printf (" %02X", p[j]);
      log_printf ("\n");
    }

  rc = gcry_sexp_sscan ( &s_sig, NULL, (char*)p, n);
  ksba_free (p);
  if (rc)
    {
      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
      gcry_md_close (md);
      return rc;
    }

  p = ksba_cert_get_public_key (issuer_cert);
  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
  if (!n)
    {
      log_error ("libksba did not return a proper S-Exp\n");
      gcry_md_close (md);
      ksba_free (p);
      gcry_sexp_release (s_sig);
      return gpg_error (GPG_ERR_BUG);
    }
  rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n);
  ksba_free (p);
  if (rc)
    {
      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
      gcry_md_close (md);
      gcry_sexp_release (s_sig);
      return rc;
    }

  rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
                     gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
  if (rc)
    {
      gcry_md_close (md);
      gcry_sexp_release (s_sig);
      gcry_sexp_release (s_pkey);
      return rc;
    }

  /* put hash into the S-Exp s_hash */
  if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
    BUG ();
  gcry_mpi_release (frame);


  rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
  if (DBG_X509)
      log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
  gcry_md_close (md);
  gcry_sexp_release (s_sig);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_pkey);
  return rc;
}
Example #9
0
static void
one_test (int testno, const char *sk, const char *pk,
          const char *msg, const char *sig)
{
  gpg_error_t err;
  int i;
  char *p;
  void *buffer = NULL;
  void *buffer2 = NULL;
  size_t buflen, buflen2;
  gcry_sexp_t s_tmp, s_tmp2;
  gcry_sexp_t s_sk = NULL;
  gcry_sexp_t s_pk = NULL;
  gcry_sexp_t s_msg= NULL;
  gcry_sexp_t s_sig= NULL;
  unsigned char *sig_r = NULL;
  unsigned char *sig_s = NULL;
  char *sig_rs_string = NULL;
  size_t sig_r_len, sig_s_len;

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

  if (!(buffer = hex2buffer (sk, &buflen)))
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "sk", "invalid hex string");
      goto leave;
    }
  if (!(buffer2 = hex2buffer (pk, &buflen2)))
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "pk", "invalid hex string");
      goto leave;
    }
  if (sign_with_pk)
    err = gcry_sexp_build (&s_sk, NULL,
                           "(private-key"
                           " (ecc"
                           "  (curve \"Ed25519\")"
                           "  (flags eddsa)"
                           "  (q %b)"
                           "  (d %b)))",
                           (int)buflen2, buffer2,
                           (int)buflen, buffer);
  else
    err = gcry_sexp_build (&s_sk, NULL,
                           "(private-key"
                           " (ecc"
                           "  (curve \"Ed25519\")"
                           "  (flags eddsa)"
                           "  (d %b)))",
                           (int)buflen, buffer);
  if (err)
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "sk", gpg_strerror (err));
      goto leave;
    }

  if ((err = gcry_sexp_build (&s_pk, NULL,
                              "(public-key"
                              " (ecc"
                              "  (curve \"Ed25519\")"
                              "  (flags eddsa)"
                              "  (q %b)))",  (int)buflen2, buffer2)))
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "pk", gpg_strerror (err));
      goto leave;
    }

  xfree (buffer);
  if (!(buffer = hex2buffer (msg, &buflen)))
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "msg", "invalid hex string");
      goto leave;
    }
  if ((err = gcry_sexp_build (&s_msg, NULL,
                              "(data"
                              " (flags eddsa)"
                              " (hash-algo sha512)"
                              " (value %b))",  (int)buflen, buffer)))
    {
      fail ("error building s-exp for test %d, %s: %s",
            testno, "msg", gpg_strerror (err));
      goto leave;
    }

  if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk)))
    fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err));
  if (debug)
    show_sexp ("sig=", s_sig);

  s_tmp2 = NULL;
  s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
  if (s_tmp)
    {
      s_tmp2 = s_tmp;
      s_tmp = gcry_sexp_find_token (s_tmp2, "eddsa", 0);
      if (s_tmp)
        {
          gcry_sexp_release (s_tmp2);
          s_tmp2 = s_tmp;
          s_tmp = gcry_sexp_find_token (s_tmp2, "r", 0);
          if (s_tmp)
            {
              sig_r = gcry_sexp_nth_buffer (s_tmp, 1, &sig_r_len);
              gcry_sexp_release (s_tmp);
            }
          s_tmp = gcry_sexp_find_token (s_tmp2, "s", 0);
          if (s_tmp)
            {
              sig_s = gcry_sexp_nth_buffer (s_tmp, 1, &sig_s_len);
              gcry_sexp_release (s_tmp);
            }
        }
    }
  gcry_sexp_release (s_tmp2); s_tmp2 = NULL;

  if (!sig_r || !sig_s)
    fail ("gcry_pk_sign failed for test %d: %s", testno, "r or s missing");
  else
    {
      sig_rs_string = xmalloc (2*(sig_r_len + sig_s_len)+1);
      p = sig_rs_string;
      *p = 0;
      for (i=0; i < sig_r_len; i++, p += 2)
        snprintf (p, 3, "%02x", sig_r[i]);
      for (i=0; i < sig_s_len; i++, p += 2)
        snprintf (p, 3, "%02x", sig_s[i]);
      if (strcmp (sig_rs_string, sig))
        {
          fail ("gcry_pk_sign failed for test %d: %s",
                testno, "wrong value returned");
          show ("  expected: '%s'", sig);
          show ("       got: '%s'", sig_rs_string);
        }
    }

  if (!no_verify)
    if ((err = gcry_pk_verify (s_sig, s_msg, s_pk)))
      fail ("gcry_pk_verify failed for test %d: %s",
            testno, gpg_strerror (err));


 leave:
  gcry_sexp_release (s_sig);
  gcry_sexp_release (s_sk);
  gcry_sexp_release (s_pk);
  gcry_sexp_release (s_msg);
  xfree (buffer);
  xfree (buffer2);
  xfree (sig_r);
  xfree (sig_s);
  xfree (sig_rs_string);
}
Example #10
0
int sig_verify(ssh_session session, ssh_public_key pubkey,
    SIGNATURE *signature, unsigned char *digest, int size) {
#ifdef HAVE_LIBGCRYPT
  gcry_error_t valid = 0;
  gcry_sexp_t gcryhash;
#elif defined HAVE_LIBCRYPTO
  int valid = 0;
#endif
  unsigned char hash[SHA_DIGEST_LEN + 1] = {0};

  sha1(digest, size, hash + 1);

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("Hash to be verified with dsa", hash + 1, SHA_DIGEST_LEN);
#endif

  switch(pubkey->type) {
    case SSH_KEYTYPE_DSS:
#ifdef HAVE_LIBGCRYPT
      valid = gcry_sexp_build(&gcryhash, NULL, "%b", SHA_DIGEST_LEN + 1, hash);
      if (valid != 0) {
        ssh_set_error(session, SSH_FATAL,
            "RSA error: %s", gcry_strerror(valid));
        return -1;
      }
      valid = gcry_pk_verify(signature->dsa_sign, gcryhash, pubkey->dsa_pub);
      gcry_sexp_release(gcryhash);
      if (valid == 0) {
        return 0;
      }

      if (gcry_err_code(valid) != GPG_ERR_BAD_SIGNATURE) {
        ssh_set_error(session, SSH_FATAL,
            "DSA error: %s", gcry_strerror(valid));
        return -1;
      }
#elif defined HAVE_LIBCRYPTO
      valid = DSA_do_verify(hash + 1, SHA_DIGEST_LEN, signature->dsa_sign,
          pubkey->dsa_pub);
      if (valid == 1) {
        return 0;
      }

      if (valid == -1) {
        ssh_set_error(session, SSH_FATAL,
            "DSA error: %s", ERR_error_string(ERR_get_error(), NULL));
        return -1;
      }
#endif
      ssh_set_error(session, SSH_FATAL, "Invalid DSA signature");
      return -1;

    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
      valid = gcry_sexp_build(&gcryhash, NULL,
          "(data(flags pkcs1)(hash sha1 %b))", SHA_DIGEST_LEN, hash + 1);
      if (valid != 0) {
        ssh_set_error(session, SSH_FATAL,
            "RSA error: %s", gcry_strerror(valid));
        return -1;
      }
      valid = gcry_pk_verify(signature->rsa_sign,gcryhash,pubkey->rsa_pub);
      gcry_sexp_release(gcryhash);
      if (valid == 0) {
        return 0;
      }
      if (gcry_err_code(valid) != GPG_ERR_BAD_SIGNATURE) {
        ssh_set_error(session, SSH_FATAL,
            "RSA error: %s", gcry_strerror(valid));
        return -1;
      }
#elif defined HAVE_LIBCRYPTO
      valid = RSA_verify(NID_sha1, hash + 1, SHA_DIGEST_LEN,
          signature->rsa_sign->string, ssh_string_len(signature->rsa_sign),
          pubkey->rsa_pub);
      if (valid == 1) {
        return 0;
      }
      if (valid == -1) {
        ssh_set_error(session, SSH_FATAL,
            "RSA error: %s", ERR_error_string(ERR_get_error(), NULL));
        return -1;
      }
#endif
      ssh_set_error(session, SSH_FATAL, "Invalid RSA signature");
      return -1;
    default:
      ssh_set_error(session, SSH_FATAL, "Unknown public key type");
      return -1;
  }

  return -1;
}
Example #11
0
static void
check_ecc_sample_key (void)
{
  static const char ecc_private_key[] =
    "(private-key\n"
    " (ecdsa\n"
    "  (curve \"NIST P-256\")\n"
    "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
    "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
    "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
    "))";
  static const char ecc_private_key_wo_q[] =
    "(private-key\n"
    " (ecdsa\n"
    "  (curve \"NIST P-256\")\n"
    "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
    "))";
  static const char ecc_public_key[] =
    "(public-key\n"
    " (ecdsa\n"
    "  (curve \"NIST P-256\")\n"
    "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
    "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)"
    "))";
  static const char hash_string[] =
    "(data (flags raw)\n"
    " (value #00112233445566778899AABBCCDDEEFF"
    /* */    "000102030405060708090A0B0C0D0E0F#))";

  gpg_error_t err;
  gcry_sexp_t key, hash, sig;

  if (verbose)
    fprintf (stderr, "Checking sample ECC key.\n");

  if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign failed: %s", gpg_strerror (err));

  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify failed: %s", gpg_strerror (err));

  /* Now try signing without the Q parameter.  */

  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  gcry_sexp_release (sig);
  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err));

  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err));

  gcry_sexp_release (sig);
  gcry_sexp_release (key);
  gcry_sexp_release (hash);
}
Example #12
0
static void
check_ed25519ecdsa_sample_key (void)
{
  static const char ecc_private_key[] =
    "(private-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
    "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
    "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
    "))";
  static const char ecc_private_key_wo_q[] =
    "(private-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
    "))";
  static const char ecc_public_key[] =
    "(public-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
    "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
    "))";
  static const char ecc_public_key_comp[] =
    "(public-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)"
    "))";
  static const char hash_string[] =
    "(data (flags ecdsa rfc6979)\n"
    " (hash sha256 #00112233445566778899AABBCCDDEEFF"
    /* */          "000102030405060708090A0B0C0D0E0F#))";

  gpg_error_t err;
  gcry_sexp_t key, hash, sig;

  if (verbose)
    fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n");

  /* Sign.  */
  if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign failed: %s", gpg_strerror (err));

  /* Verify.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify failed: %s", gpg_strerror (err));

  /* Verify again using a compressed public key.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err));

  /* Sign without a Q parameter.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  gcry_sexp_release (sig);
  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err));

  /* Verify.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err));

  /* Verify again using a compressed public key.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err));

  extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4"
                               "655d0179e22199bf63691fd88eb64e15"));
  extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185"
                               "623ddaf5d02fa65ca5056cb6bd0f16f1"));

  gcry_sexp_release (sig);
  gcry_sexp_release (key);
  gcry_sexp_release (hash);
}
Example #13
0
int
gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
                           gcry_md_hd_t md, int mdalgo, int *r_pkalgo)
{
  int rc;
  ksba_sexp_t p;
  gcry_mpi_t frame;
  gcry_sexp_t s_sig, s_hash, s_pkey;
  size_t n;
  int pkalgo;

  if (r_pkalgo)
    *r_pkalgo = 0;

  n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
  if (!n)
    {
      log_error ("libksba did not return a proper S-Exp\n");
      return gpg_error (GPG_ERR_BUG);
    }
  rc = gcry_sexp_sscan (&s_sig, NULL, (char*)sigval, n);
  if (rc)
    {
      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
      return rc;
    }

  p = ksba_cert_get_public_key (cert);
  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
  if (!n)
    {
      log_error ("libksba did not return a proper S-Exp\n");
      ksba_free (p);
      gcry_sexp_release (s_sig);
      return gpg_error (GPG_ERR_BUG);
    }
  if (DBG_CRYPTO)
    log_printhex ("public key: ", p, n);

  rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n);
  ksba_free (p);
  if (rc)
    {
      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
      gcry_sexp_release (s_sig);
      return rc;
    }

  pkalgo = pk_algo_from_sexp (s_pkey);
  if (r_pkalgo)
    *r_pkalgo = pkalgo;
  rc = do_encode_md (md, mdalgo, pkalgo,
                     gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
  if (rc)
    {
      gcry_sexp_release (s_sig);
      gcry_sexp_release (s_pkey);
      return rc;
    }
  /* put hash into the S-Exp s_hash */
  if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
    BUG ();
  gcry_mpi_release (frame);

  rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
  if (DBG_X509)
      log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
  gcry_sexp_release (s_sig);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_pkey);
  return rc;
}
Example #14
0
/* Check the signature on CERT using the ISSUER_CERT.  This function
   does only test the cryptographic signature and nothing else.  It is
   assumed that the ISSUER_CERT is valid. */
static gpg_error_t
check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
{
  gpg_error_t err;
  const char *algoid;
  gcry_md_hd_t md;
  int i, algo;
  ksba_sexp_t p;
  size_t n;
  gcry_sexp_t s_sig, s_hash, s_pkey;
  const char *s;
  char algo_name[16+1]; /* hash algorithm name converted to lower case. */
  int digestlen;
  unsigned char *digest;

  /* Hash the target certificate using the algorithm from that certificate.  */
  algoid = ksba_cert_get_digest_algo (cert);
  algo = gcry_md_map_name (algoid);
  if (!algo)
    {
      log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
      return gpg_error (GPG_ERR_GENERAL);
    }
  s = gcry_md_algo_name (algo);
  for (i=0; *s && i < sizeof algo_name - 1; s++, i++)
    algo_name[i] = tolower (*s);
  algo_name[i] = 0;

  err = gcry_md_open (&md, algo, 0);
  if (err)
    {
      log_error ("md_open failed: %s\n", gpg_strerror (err));
      return err;
    }
  if (DBG_HASHING)
    gcry_md_debug (md, "hash.cert");

  err = ksba_cert_hash (cert, 1, HASH_FNC, md);
  if (err)
    {
      log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (err));
      gcry_md_close (md);
      return err;
    }
  gcry_md_final (md);

  /* Get the signature value out of the target certificate.  */
  p = ksba_cert_get_sig_val (cert);
  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
  if (!n)
    {
      log_error ("libksba did not return a proper S-Exp\n");
      gcry_md_close (md);
      ksba_free (p);
      return gpg_error (GPG_ERR_BUG);
    }
  if (DBG_CRYPTO)
    {
      int j;
      log_debug ("signature value:");
      for (j=0; j < n; j++)
        log_printf (" %02X", p[j]);
      log_printf ("\n");
    }

  err = gcry_sexp_sscan ( &s_sig, NULL, p, n);
  ksba_free (p);
  if (err)
    {
      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (err));
      gcry_md_close (md);
      return err;
    }

  /* Get the public key from the issuer certificate.  */
  p = ksba_cert_get_public_key (issuer_cert);
  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
  if (!n)
    {
      log_error ("libksba did not return a proper S-Exp\n");
      gcry_md_close (md);
      ksba_free (p);
      gcry_sexp_release (s_sig);
      return gpg_error (GPG_ERR_BUG);
    }
  err = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
  ksba_free (p);
  if (err)
    {
      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (err));
      gcry_md_close (md);
      gcry_sexp_release (s_sig);
      return err;
    }


  /* Prepare the values for signature verification. At this point we
     have these values:

     S_PKEY    - S-expression with the issuer's public key.
     S_SIG     - Signature value as given in the certrificate.
     MD        - Finalized hash context with hash of the certificate.
     ALGO_NAME - Lowercase hash algorithm name
   */
  digestlen = gcry_md_get_algo_dlen (algo);
  digest = gcry_md_read (md, algo);
  if (pk_algo_from_sexp (s_pkey) == GCRY_PK_DSA)
    {
      if (digestlen != 20)
        {
          log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
          gcry_md_close (md);
          gcry_sexp_release (s_sig);
          gcry_sexp_release (s_pkey);
          return gpg_error (GPG_ERR_INTERNAL);
        }
      if ( gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))",
                            (int)digestlen, digest) )
        BUG ();
    }
  else /* Not DSA.  */
    {
      if ( gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))",
                            algo_name, (int)digestlen, digest) )
        BUG ();

    }

  err = gcry_pk_verify (s_sig, s_hash, s_pkey);
  if (DBG_X509)
    log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
  gcry_md_close (md);
  gcry_sexp_release (s_sig);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_pkey);
  return err;
}
/*
 * Checks the validity of the signature found on the regulatory
 * database against the array 'keys'. Returns 1 if there exists
 * at least one key in the array such that the signature is valid
 * against that key; 0 otherwise.
 */
int crda_verify_db_signature(__u8 *db, int dblen, int siglen)
{
#ifdef USE_OPENSSL
	RSA *rsa;
	__u8 hash[SHA_DIGEST_LENGTH];
	unsigned int i;
	int ok = 0;
	DIR *pubkey_dir;
	struct dirent *nextfile;
	FILE *keyfile;
	char filename[PATH_MAX];

	if (SHA1(db, dblen, hash) != hash) {
		fprintf(stderr, "Failed to calculate SHA1 sum.\n");
		goto out;
	}

	for (i = 0; (i < sizeof(keys)/sizeof(keys[0])) && (!ok); i++) {
		rsa = RSA_new();
		if (!rsa) {
			fprintf(stderr, "Failed to create RSA key.\n");
			goto out;
		}

		rsa->e = &keys[i].e;
		rsa->n = &keys[i].n;

		ok = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
				db + dblen, siglen, rsa) == 1;

		rsa->e = NULL;
		rsa->n = NULL;
		RSA_free(rsa);
	}
	if (!ok && (pubkey_dir = opendir(PUBKEY_DIR))) {
		while (!ok && (nextfile = readdir(pubkey_dir))) {
			snprintf(filename, PATH_MAX, "%s/%s", PUBKEY_DIR,
				nextfile->d_name);
			if ((keyfile = fopen(filename, "rb"))) {
				rsa = PEM_read_RSA_PUBKEY(keyfile,
					NULL, NULL, NULL);
				if (rsa)
					ok = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
						db + dblen, siglen, rsa) == 1;
				RSA_free(rsa);
				fclose(keyfile);
			}
		}
		closedir(pubkey_dir);
	}
#endif

#ifdef USE_GCRYPT
	gcry_mpi_t mpi_e, mpi_n;
	gcry_sexp_t rsa, signature, data;
	__u8 hash[20];
	unsigned int i;
	int ok = 0;

	/* initialise */
	gcry_check_version(NULL);

	/* hash the db */
	gcry_md_hash_buffer(GCRY_MD_SHA1, hash, db, dblen);

	if (gcry_sexp_build(&data, NULL, "(data (flags pkcs1) (hash sha1 %b))",
			    20, hash)) {
		fprintf(stderr, "Failed to build data S-expression.\n");
		goto out;
	}

	if (gcry_sexp_build(&signature, NULL, "(sig-val (rsa (s %b)))",
			    siglen, db + dblen)) {
		fprintf(stderr, "Failed to build signature S-expression.\n");
		goto out;
	}

	for (i = 0; (i < sizeof(keys)/sizeof(keys[0])) && (!ok); i++) {
		if (gcry_mpi_scan(&mpi_e, GCRYMPI_FMT_USG,
				keys[i].e, keys[i].len_e, NULL) ||
		    gcry_mpi_scan(&mpi_n, GCRYMPI_FMT_USG,
				keys[i].n, keys[i].len_n, NULL)) {
			fprintf(stderr, "Failed to convert numbers.\n");
			goto out;
		}

		if (gcry_sexp_build(&rsa, NULL,
				    "(public-key (rsa (n %m) (e %m)))",
				    mpi_n, mpi_e)) {
			fprintf(stderr, "Failed to build RSA S-expression.\n");
			goto out;
		}

		ok = gcry_pk_verify(signature, data, rsa) == 0;
	}
#endif

#if defined(USE_OPENSSL) || defined(USE_GCRYPT)
	if (!ok)
		fprintf(stderr, "Database signature verification failed.\n");

out:
	return ok;
#else
	return 1;
#endif
}
void attack(int i, unsigned char *digest, int hash_len){
	
    void* dsa_buf; 
	
    gcry_sexp_t new_dsa_key_pair;
    gcry_sexp_t ciphertext , plaintext, ptx2, ctx2;
	
    gcry_sexp_t r_param, r_tilda_param;
    gcry_sexp_t s_param, s_tilda_param;
    gcry_sexp_t g_param;
    gcry_sexp_t p_param;
    gcry_sexp_t q_param;
    gcry_sexp_t m_param;
    gcry_sexp_t y_param;

    gcry_sexp_t x_param;
    gcry_sexp_t misc_param;
	
    gcry_error_t err;
	
    gcry_mpi_t msg_digest, m;
	
    gcry_mpi_t r , r_tilda;
    gcry_mpi_t s , s_tilda;
    gcry_mpi_t g;
    gcry_mpi_t p;
    gcry_mpi_t q;
    gcry_mpi_t y;
    gcry_mpi_t x;

    retrieve_key_pair(files[i]);

    //*************** CORRECT SIGNATURE ********************//

	//20 is the mdlen of sha1 as specified in https://lists.gnupg.org/pipermail/gnupg-devel/2013-September/027916.html
    //a well formatted number for the immaediate has an even number of digits
    err = gcry_sexp_build(&plaintext, NULL, "(data (flags rfc6979) (hash %s %b))" , "sha1", hash_len , digest);

    err = gcry_pk_sign(&ciphertext, plaintext, dsa_key_pair);

    //now let's convert the s-expression representing r into an MPI in order
    //to use it in the equation of the attack 

    //--------- CIPHERTEXT --------------

    //intercepted during some sniffing...
    
    r_param = gcry_sexp_find_token(ciphertext, "r", 0);
    r = gcry_sexp_nth_mpi ( r_param , 1, GCRYMPI_FMT_USG);
         
    s_param = gcry_sexp_find_token(ciphertext, "s", 0);
    s = gcry_sexp_nth_mpi ( s_param , 1, GCRYMPI_FMT_USG);


    //--------- PUB KEY --------------
    
    g_param = gcry_sexp_find_token(dsa_key_pair, "g", 0);
    g = gcry_sexp_nth_mpi ( g_param , 1, GCRYMPI_FMT_USG);
    
    p_param = gcry_sexp_find_token(dsa_key_pair, "p", 0);
    p = gcry_sexp_nth_mpi ( p_param , 1, GCRYMPI_FMT_USG);
    
    q_param = gcry_sexp_find_token(dsa_key_pair, "q", 0);
    q = gcry_sexp_nth_mpi ( q_param , 1, GCRYMPI_FMT_USG);

    y_param = gcry_sexp_find_token(dsa_key_pair, "y", 0);
    y = gcry_sexp_nth_mpi ( y_param , 1, GCRYMPI_FMT_USG);

    x_param = gcry_sexp_find_token(dsa_key_pair, "x", 0);
    x = gcry_sexp_nth_mpi ( x_param , 1, GCRYMPI_FMT_USG);

    misc_param = gcry_sexp_find_token(dsa_key_pair, "misc-key-info", 0);

    //*************** FAULTY SIGNATURE ********************//

    err = gcry_sexp_build(&ptx2, NULL, "(data (flags rfc6979) (hash %s %b) (attack2_inv))" , "sha1", hash_len , digest);

    err = gcry_pk_sign(&ctx2, ptx2, dsa_key_pair);

    s_tilda_param = gcry_sexp_find_token(ctx2, "s", 0);
    s_tilda = gcry_sexp_nth_mpi ( s_tilda_param , 1, GCRYMPI_FMT_USG);

    r_tilda_param = gcry_sexp_find_token(ctx2, "r", 0);
    r_tilda = gcry_sexp_nth_mpi ( r_tilda_param , 1, GCRYMPI_FMT_USG);

    m_param = gcry_sexp_find_token(ptx2, "hash", 0);
    m = gcry_sexp_nth_mpi ( m_param , 2, GCRYMPI_FMT_USG);
    
    //NOW LET'S START THE ATTACK 

    unsigned long e = 0;

    unsigned int qbits = mpi_get_nbits(q);
    unsigned int pbits = mpi_get_nbits(p);

    gcry_mpi_t one = gcry_mpi_set_ui(NULL, 1);

    gcry_mpi_t tmp = gcry_mpi_new(qbits);

    gcry_mpi_t result = gcry_mpi_new(mpi_get_nbits(s));

    gcry_mpi_invm(r,r,q); // r^-1
    
    for(e = 0; e < qbits; e++){

        gcry_mpi_t twoi = gcry_mpi_new(e);
        gcry_mpi_mul_2exp(twoi, one, e);   // twoi = 2^e
  
    	//retrieve k
        gcry_mpi_invm(tmp, twoi, q); // (2^e)^-1 mod q
        gcry_mpi_subm(result, s_tilda, s, q); // s_tilda - s mod q
        gcry_mpi_mulm(result,result, tmp, q); // (s_tilda - s mod q)*((2^e)^-1  mod q) === k

        //retrieve x
        gcry_mpi_mulm(result, s, result,q); // s*k mod q
        gcry_mpi_subm(result, result, m, q); // s*k - m mod q
        gcry_mpi_mulm(result, result,r,q); //(s*k -m)*r^-1 mod q

        err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                     "(key-data"
                     " (public-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                     " (private-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                    p,q,g,y,p,q,g,y,result);

        err = gcry_pk_sign(&ctx2, plaintext, new_dsa_key_pair);

        err = gcry_pk_verify(ctx2, plaintext, dsa_key_pair);
    
        if (err) {
            //puts("gcrypt: verify failed");
	       continue;
        }
        else{
            printf("\n[!!!]PRIVATE KEY %d %d BITS CRACKED!!\n" , pbits,qbits );
    	    printf("[DBG] BIT: %d  FAULT: k-2^e\n" , (int)e); //DEBUG 
            DEBUG_MPI_PRINT(result,"X = ");
    	    printf("\n");
      	    return;   
        }


    }
        
    for(e = 0; e < qbits; e++){

        gcry_mpi_t twoi = gcry_mpi_new(e);
        gcry_mpi_mul_2exp(twoi, one, e);   // twoi = 2^e
  
        //retrieve k
        gcry_mpi_invm(tmp, twoi, q); // (2^e)^-1 mod q
        gcry_mpi_subm(result, s, s_tilda, q); // s - s_tilda mod q
        gcry_mpi_mulm(result,result, tmp, q); // (s - s_tilda mod q)*((2^e)^-1  mod q) === k

        //retrieve x
        gcry_mpi_mulm(result, s, result,q); // s*k mod q
        gcry_mpi_subm(result, result, m, q); // s*k - m mod q
        gcry_mpi_mulm(result, result,r,q); //(s*k -m)*r^-1 mod q

        err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                     "(key-data"
                     " (public-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                     " (private-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                    p,q,g,y,p,q,g,y,result);

        err = gcry_pk_sign(&ctx2, plaintext, new_dsa_key_pair);

        err = gcry_pk_verify(ctx2, plaintext, dsa_key_pair);
    
        if (err) {
            //puts("gcrypt: verify failed");
	       continue;
        }
        else{
  	        printf("\n[!!!]PRIVATE KEY %d %d BITS CRACKED!!\n" , pbits,qbits );
    	    printf("[DBG] BIT: %d  FAULT: k+2^e\n" , (int)e); //DEBUG 
    	    DEBUG_MPI_PRINT(result,"X = ");
    	    printf("\n");
      	    return;   
        }

    }
}
Example #17
0
static int
_gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data,
		   mpi_t * pkey, int pkey_len)
{
  gcry_sexp_t s_sig, s_hash, s_pkey;
  int rc = -1;

  /* make a sexp from pkey */
  switch (algo)
    {
    case GCRY_PK_DSA:
      if (pkey_len >= 4)
	rc = gcry_sexp_build (&s_pkey, NULL,
			      "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
			      pkey[0], pkey[1], pkey[2], pkey[3]);
      break;
    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_hash, NULL, "%m", hash))
    {
      gnutls_assert ();
      gcry_sexp_release (s_pkey);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  switch (algo)
    {
    case GCRY_PK_DSA:
      rc = gcry_sexp_build (&s_sig, NULL,
			    "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
      break;
    case GCRY_PK_RSA:
      rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]);
      break;

    default:
      gnutls_assert ();
      gcry_sexp_release (s_pkey);
      gcry_sexp_release (s_hash);
      return GNUTLS_E_INTERNAL_ERROR;
    }

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

  rc = gcry_pk_verify (s_sig, s_hash, s_pkey);

  gcry_sexp_release (s_sig);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_pkey);

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

  return 0;
}