Beispiel #1
0
int p2p_convert_private_key(RSA *key, gcry_sexp_t *r_key) {
    size_t err;
    char *buf;
    
    gcry_mpi_t n_mpi, e_mpi, d_mpi, p_mpi, q_mpi, u_mpi;
    
    buf = BN_bn2hex(key->n);
    gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->e);
    gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->d);
    gcry_mpi_scan(&d_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->p);
    gcry_mpi_scan(&p_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->q);
    gcry_mpi_scan(&q_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->iqmp);
    gcry_mpi_scan(&u_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    if(gcry_mpi_cmp(p_mpi, q_mpi) > 0) {
        gcry_mpi_swap(p_mpi, q_mpi);
        gcry_mpi_invm(u_mpi, p_mpi, q_mpi);
    }
    
    gcry_sexp_build(r_key, &err, "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))", n_mpi, e_mpi, d_mpi, p_mpi, q_mpi, u_mpi);
    
    gcry_mpi_release(n_mpi);
    gcry_mpi_release(e_mpi);
    gcry_mpi_release(d_mpi);
    gcry_mpi_release(p_mpi);
    gcry_mpi_release(q_mpi);
    gcry_mpi_release(u_mpi);
    
    gcry_error_t sane = gcry_pk_testkey(*r_key);
    if(sane) {
        return -1;
    }
    
    return 0;
}
Beispiel #2
0
/**
 * Generate a key pair with a key of size NBITS.
 * @param sk where to store the key
 * @param nbits the number of bits to use
 * @param hc the HC to use for PRNG (modified!)
 */
static void
generate_kblock_key (KBlock_secret_key *sk, unsigned int nbits,
                     struct GNUNET_HashCode * hc)
{
  gcry_mpi_t t1, t2;
  gcry_mpi_t phi;               /* helper: (p-1)(q-1) */
  gcry_mpi_t g;
  gcry_mpi_t f;

  /* make sure that nbits is even so that we generate p, q of equal size */
  if ((nbits & 1))
    nbits++;

  sk->e = gcry_mpi_set_ui (NULL, 257);
  sk->n = gcry_mpi_new (0);
  sk->p = gcry_mpi_new (0);
  sk->q = gcry_mpi_new (0);
  sk->d = gcry_mpi_new (0);
  sk->u = gcry_mpi_new (0);

  t1 = gcry_mpi_new (0);
  t2 = gcry_mpi_new (0);
  phi = gcry_mpi_new (0);
  g = gcry_mpi_new (0);
  f = gcry_mpi_new (0);

  do
  {
    do
    {
      gcry_mpi_release (sk->p);
      gcry_mpi_release (sk->q);
      gen_prime (&sk->p, nbits / 2, hc);
      gen_prime (&sk->q, nbits / 2, hc);

      if (gcry_mpi_cmp (sk->p, sk->q) > 0)      /* p shall be smaller than q (for calc of u) */
        gcry_mpi_swap (sk->p, sk->q);
      /* calculate the modulus */
      gcry_mpi_mul (sk->n, sk->p, sk->q);
    }
    while (gcry_mpi_get_nbits (sk->n) != nbits);

    /* calculate Euler totient: phi = (p-1)(q-1) */
    gcry_mpi_sub_ui (t1, sk->p, 1);
    gcry_mpi_sub_ui (t2, sk->q, 1);
    gcry_mpi_mul (phi, t1, t2);
    gcry_mpi_gcd (g, t1, t2);
    gcry_mpi_div (f, NULL, phi, g, 0);
    while (0 == gcry_mpi_gcd (t1, sk->e, phi))
    {                           /* (while gcd is not 1) */
      gcry_mpi_add_ui (sk->e, sk->e, 2);
    }

    /* calculate the secret key d = e^1 mod phi */
  }
  while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
         (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));

  gcry_mpi_release (t1);
  gcry_mpi_release (t2);
  gcry_mpi_release (phi);
  gcry_mpi_release (f);
  gcry_mpi_release (g);
}
Beispiel #3
0
/* Compute and print missing RSA parameters.  */
static void
compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e)
{
  gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u;
  gcry_mpi_t phi, tmp_g, tmp_f;

  rsa_n = gcry_mpi_new (0);
  rsa_d = gcry_mpi_new (0);
  rsa_pm1 = gcry_mpi_new (0);
  rsa_qm1 = gcry_mpi_new (0);
  rsa_u = gcry_mpi_new (0);

  phi = gcry_mpi_new (0);
  tmp_f = gcry_mpi_new (0);
  tmp_g = gcry_mpi_new (0);

  /* Check that p < q; if not swap p and q.  */
  if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0)
    {
      fprintf (stderr, PGM ": swapping p and q\n");
      gcry_mpi_swap (rsa_p, rsa_q);
    }

  gcry_mpi_mul (rsa_n, rsa_p, rsa_q);


  /* Compute the Euler totient:  phi = (p-1)(q-1)  */
  gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1);
  gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1);
  gcry_mpi_mul (phi, rsa_pm1, rsa_qm1);

  if (!gcry_mpi_gcd (tmp_g, rsa_e, phi))
    die ("parameter 'e' does match 'p' and 'q'\n");

  /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
  gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1);
  gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1);

  /* Compute the secret key:  d = e^{-1} mod lcm(p-1,q-1) */
  gcry_mpi_invm (rsa_d, rsa_e, tmp_f);

  /* Compute the CRT helpers: d mod (p-1), d mod (q-1)   */
  gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1);
  gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1);

  /* Compute the CRT value:   OpenPGP:    u = p^{-1} mod q
                             Standard: iqmp = q^{-1} mod p */
  if (openpgp_mode)
    gcry_mpi_invm (rsa_u, rsa_p, rsa_q);
  else
    gcry_mpi_invm (rsa_u, rsa_q, rsa_p);

  gcry_mpi_release (phi);
  gcry_mpi_release (tmp_f);
  gcry_mpi_release (tmp_g);

  /* Print everything.  */
  print_mpi_line ("n", rsa_n);
  print_mpi_line ("e", rsa_e);
  if (openpgp_mode)
    print_mpi_line ("d", rsa_d);
  print_mpi_line ("p", rsa_p);
  print_mpi_line ("q", rsa_q);
  if (openpgp_mode)
    print_mpi_line ("u", rsa_u);
  else
    {
      print_mpi_line ("dmp1", rsa_pm1);
      print_mpi_line ("dmq1", rsa_qm1);
      print_mpi_line ("iqmp", rsa_u);
    }

  gcry_mpi_release (rsa_n);
  gcry_mpi_release (rsa_d);
  gcry_mpi_release (rsa_pm1);
  gcry_mpi_release (rsa_qm1);
  gcry_mpi_release (rsa_u);
}
Beispiel #4
0
/*
 * Parse the DER-encoded data at ps_data_der
 * saving the key in an S-expression
 */
int RSAKey::readDER( unsigned char const* ps_data_der, size_t length )
{
    struct tag_info tag_inf;
    gcry_mpi_t key_params[8];
    gcry_error_t err;
    int i;

    /* parse the ASN1 structure */
    if( parseTag( &ps_data_der, &length, &tag_inf )
            || tag_inf.tag != TAG_SEQUENCE || tag_inf.class_ || !tag_inf.cons || tag_inf.ndef )
        goto bad_asn1;
    if( parseTag( &ps_data_der, &length, &tag_inf )
       || tag_inf.tag != TAG_INTEGER || tag_inf.class_ || tag_inf.cons || tag_inf.ndef )
        goto bad_asn1;
    if( tag_inf.length != 1 || *ps_data_der )
        goto bad_asn1;  /* The value of the first integer is no 0. */
    ps_data_der += tag_inf.length;
    length -= tag_inf.length;

    for( i = 0; i < 8; i++ )
    {
        if( parseTag( &ps_data_der, &length, &tag_inf )
                || tag_inf.tag != TAG_INTEGER || tag_inf.class_ || tag_inf.cons || tag_inf.ndef )
            goto bad_asn1;
        err = gcry_mpi_scan( key_params + i, GCRYMPI_FMT_USG, ps_data_der, tag_inf.length, NULL );
        if( err )
        {
            msg_Err( this->p_demux, "error scanning RSA parameter %d: %s", i, gpg_strerror( err ) );
            goto error;
        }
        ps_data_der += tag_inf.length;
        length -= tag_inf.length;
    }

    /* Convert from OpenSSL parameter ordering to the OpenPGP order.
     * First check that p < q; if not swap p and q and recompute u.
     */
    if( gcry_mpi_cmp( key_params[3], key_params[4] ) > 0 )
    {
        gcry_mpi_swap( key_params[3], key_params[4] );
        gcry_mpi_invm( key_params[7], key_params[3], key_params[4] );
    }

    /* Build the S-expression.  */
    err = gcry_sexp_build( & this->priv_key, NULL,
                         "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
                         key_params[0], key_params[1], key_params[2],
                         key_params[3], key_params[4], key_params[7] );
    if( err )
    {
        msg_Err( this->p_demux, "error building S-expression: %s", gpg_strerror( err ) );
        goto error;
    }

    /* clear data */
    for( i = 0; i < 8; i++ )
        gcry_mpi_release( key_params[i] );
    return VLC_SUCCESS;

bad_asn1:
    msg_Err( this->p_demux, "could not parse ASN1 structure; key might be corrupted" );

error:
    for( i = 0; i < 8; i++ )
        gcry_mpi_release( key_params[i] );
    return VLC_EGENERIC;
}