Beispiel #1
0
int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
                       libssh2_dsa_ctx * rsactx,
                       const unsigned char *hash,
                       size_t hash_len,
                       unsigned char **signature, size_t *signature_len)
{
    gcry_sexp_t sig_sexp;
    gcry_sexp_t data;
    int rc;
    const char *tmp;
    size_t size;

    if (hash_len != SHA_DIGEST_LENGTH) {
        return -1;
    }

    if (gcry_sexp_build(&data, NULL,
                        "(data (flags pkcs1) (hash sha1 %b))",
                        hash_len, hash)) {
        return -1;
    }

    rc = gcry_pk_sign(&sig_sexp, data, rsactx);

    gcry_sexp_release(data);

    if (rc != 0) {
        return -1;
    }

    data = gcry_sexp_find_token(sig_sexp, "s", 0);
    if (!data) {
        return -1;
    }

    tmp = gcry_sexp_nth_data(data, 1, &size);
    if (!tmp) {
        return -1;
    }

    if (tmp[0] == '\0') {
        tmp++;
        size--;
    }

    *signature = LIBSSH2_ALLOC(session, size);
    memcpy(*signature, tmp, size);
    *signature_len = size;

    return rc;
}
Beispiel #2
0
static int
read_single_mpi( gcry_sexp_t s_key, const char * val, gcry_mpi_t * r_resarr )
{
    gcry_sexp_t list;

    if( !r_resarr )
        return CDK_Inv_Value;
    list = gcry_sexp_find_token( s_key, val, 0 );
    if( list )
        *r_resarr = gcry_sexp_nth_mpi( list, 1, 0 );
    gcry_sexp_release( list );
    return list? 0 : CDK_Gcry_Error;
}
Beispiel #3
0
static gcry_mpi_t
key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
{
  gcry_sexp_t l1, l2;
  gcry_mpi_t result;

  l1 = gcry_sexp_find_token (sexp, topname, 0);
  if (!l1)
    return NULL;

  l2 = gcry_sexp_find_token (l1, name, 0);
  if (!l2)
    {
      gcry_sexp_release (l1);
      return NULL;
    }

  result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (l2);
  gcry_sexp_release (l1);
  return result;
}
Beispiel #4
0
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);
}
Beispiel #5
0
static void
get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
{
  gcry_sexp_t key_spec, key, pub_key, sec_key;
  int rc;

  rc = gcry_sexp_new
    (&key_spec,
     "(genkey"
     "  (dsa"
     "    (nbits 4:1024)"
     "    (use-fips186)"
     "    (transient-key)"
     "    (derive-parms"
     "      (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))",
     0, 1);
  if (rc)
    die ("error creating S-expression: %s\n", gcry_strerror (rc));
  rc = gcry_pk_genkey (&key, key_spec);
  gcry_sexp_release (key_spec);
  if (rc)
    die ("error generating DSA key: %s\n", gcry_strerror (rc));

  if (verbose > 1)
    show_sexp ("generated DSA key (fips 186 with seed):\n", key);

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

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

  gcry_sexp_release (key);
  *pkey = pub_key;
  *skey = sec_key;
}
Beispiel #6
0
void generate_key(rsa_packet * packet, char **public_key, char **private_key) {
	gcry_error_t error;
	int i;
	// Generate a reduced strength (to save time) RSA key, 1024 bits long
//	gcry_sexp_t params = sexp_new( "(genkey (rsa (transient-key) (nbits 3:512)))" );
	gcry_sexp_t params = sexp_new( "(genkey (rsa (transient-key) (nbits 4:1024)))" );
	gcry_sexp_t r_key;
	if ((error = gcry_pk_genkey(&r_key, params))) {
		printf("Error in gcry_pk_genkey(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}

	// Parse the S expression strings
	gcry_sexp_t public_sexp  = gcry_sexp_nth(r_key, 1);
	gcry_sexp_t private_sexp = gcry_sexp_nth(r_key, 2);
	gcry_sexp_t mod_sexp = gcry_sexp_cdr(gcry_sexp_find_token(private_sexp, "n", 1));
	gcry_sexp_t priv_exp_sexp = gcry_sexp_cdr(gcry_sexp_find_token(private_sexp, "d", 1));
	gcry_sexp_t pub_exp_sexp = gcry_sexp_cdr(gcry_sexp_find_token(public_sexp, "e", 1));

	
	// Extract the raw data in MPI format
	gcry_mpi_t mod_mpi, pubexp_mpi, privexp_mpi;
  mod_mpi = gcry_sexp_nth_mpi(mod_sexp, 0, GCRYMPI_FMT_USG); 
  privexp_mpi = gcry_sexp_nth_mpi(priv_exp_sexp, 0, GCRYMPI_FMT_USG);   
  pubexp_mpi = gcry_sexp_nth_mpi(pub_exp_sexp, 0, GCRYMPI_FMT_USG); 

  //gcry_mpi_aprint(GCRYMPI_FMT_HEX, public_key,  NULL, mod_mpi);
  // Now pack it into unsigned char
	gcry_mpi_print(GCRYMPI_FMT_USG, packet->mod, 256, &packet->mod_len, mod_mpi);
	gcry_mpi_print(GCRYMPI_FMT_USG, packet->priv_exp, 256, &packet->priv_len, privexp_mpi);
	gcry_mpi_print(GCRYMPI_FMT_USG, packet->pub_exp, 256, &packet->pub_len, pubexp_mpi);  
  
 // printf ("fmt: %i: %.*s\n", (int)len, (int) len, );

	*public_key = sexp_string(public_sexp);
	*private_key = sexp_string(private_sexp);
}
Beispiel #7
0
static void
extract_cmp_int (gcry_sexp_t sexp, const char *name, int expected)
{
  gcry_sexp_t l1;
  char *a;

  l1 = gcry_sexp_find_token (sexp, name, 0);
  a = gcry_sexp_nth_string (l1, 1);
  if (!a)
    fail ("parameter \"%s\" missing in key\n", name);
  else if ( strtoul (a, NULL, 10) != expected )
    fail ("parameter \"%s\" does not match expected value\n", name);
  gcry_free (a);
  gcry_sexp_release (l1);
}
Beispiel #8
0
static void
extract_cmp_mpi (gcry_sexp_t sexp, const char *name, const char *expected)
{
  gcry_sexp_t l1;
  gcry_mpi_t a, b;

  l1 = gcry_sexp_find_token (sexp, name, 0);
  a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
  b = mpi_from_string (expected);
  if (!a)
    fail ("parameter \"%s\" missing in key\n", name);
  else if ( gcry_mpi_cmp (a, b) )
    fail ("parameter \"%s\" does not match expected value\n", name);
  gcry_mpi_release (b);
  gcry_mpi_release (a);
  gcry_sexp_release (l1);
}
Beispiel #9
0
/**
 * Duplicate the given public key
 *
 * @param key the public key to duplicate
 * @return the duplicate key; NULL upon error
 */
struct GNUNET_CRYPTO_rsa_PublicKey *
GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_rsa_PublicKey *key)
{
  struct GNUNET_CRYPTO_rsa_PublicKey *dup;
  gcry_sexp_t dup_sexp;
  size_t erroff;

  /* check if we really are exporting a public key */
  dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
  GNUNET_assert (NULL != dup_sexp);
  gcry_sexp_release (dup_sexp);
  /* copy the sexp */
  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
  dup = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
  dup->sexp = dup_sexp;
  return dup;
}
Beispiel #10
0
static gpg_err_code_t
elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
                  const gcry_sexp_t genparms,
                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
                  gcry_sexp_t *r_extrainfo)
{
  gpg_err_code_t ec;
  ELG_secret_key sk;
  gcry_mpi_t xvalue = NULL;
  gcry_sexp_t l1;

  (void)algo;
  (void)evalue;
  (void)r_extrainfo;

  if (genparms)
    {
      /* Parse the optional xvalue element. */
      l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
      if (l1)
        {
          xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
          gcry_sexp_release (l1);
          if (!xvalue)
            return GPG_ERR_BAD_MPI;
        }
    }

  if (xvalue)
    {
      ec = generate_using_x (&sk, nbits, xvalue, retfactors);
      mpi_free (xvalue);
    }
  else
    {
      generate (&sk, nbits, retfactors);
      ec = 0;
    }

  skey[0] = sk.p;
  skey[1] = sk.g;
  skey[2] = sk.y;
  skey[3] = sk.x;

  return ec;
}
Beispiel #11
0
/* Generate a private DSA key for a given account, storing it into a
 * FILE*, and loading it into the given OtrlUserState.  Overwrite any
 * previously generated keys for that account in that OtrlUserState.
 * The FILE* must be open for reading and writing. */
gcry_error_t otrl_privkey_generate_FILEp(OtrlUserState us, FILE *privf,
	const char *accountname, const char *protocol)
{
    gcry_error_t err;
    gcry_sexp_t key, parms, privkey;
    static const char *parmstr = "(genkey (dsa (nbits 4:1024)))";
    OtrlPrivKey *p;

    if (!privf) return gcry_error(GPG_ERR_NO_ERROR);

    /* Create a DSA key */
    err = gcry_sexp_new(&parms, parmstr, strlen(parmstr), 0);
    if (err) {
	return err;
    }
    err = gcry_pk_genkey(&key, parms);
    gcry_sexp_release(parms);
    if (err) {
	return err;
    }

    /* Extract the privkey */
    privkey = gcry_sexp_find_token(key, "private-key", 0);
    gcry_sexp_release(key);

    /* Output the other keys we know */
    fprintf(privf, "(privkeys\n");

    for (p=us->privkey_root; p; p=p->next) {
	/* Skip this one if our new key replaces it */
	if (!strcmp(p->accountname, accountname) &&
		!strcmp(p->protocol, protocol)) {
	    continue;
	}

	account_write(privf, p->accountname, p->protocol, p->privkey);
    }
    account_write(privf, accountname, protocol, privkey);
    gcry_sexp_release(privkey);
    fprintf(privf, ")\n");

    fseek(privf, 0, SEEK_SET);

    return otrl_privkey_read_FILEp(us, privf);
}
Beispiel #12
0
static cdk_error_t
sexp_to_mpi (gcry_sexp_t sexp, const char *val, gcry_mpi_t *ret_buf)
{
  gcry_sexp_t list;
  
  if (!sexp || !val || !ret_buf)
    return CDK_Inv_Value;
  
  list = gcry_sexp_find_token (sexp, val, 0);
  if (!list)
    return CDK_Inv_Value;
  
  *ret_buf = gcry_sexp_nth_mpi (list, 1, 0);
  gcry_sexp_release (list);
  if (! *ret_buf)
    return CDK_Inv_Value;
  return 0;
}
Beispiel #13
0
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;
}
Beispiel #14
0
/*
 * Extract an MPI from the given s-expression SEXP named NAME which is
 * encoded using INFORMAT and store it in a newly allocated ssh_string
 * encoded using OUTFORMAT.
 */
ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
                                const char *name,
                                enum gcry_mpi_format informat,
                                enum gcry_mpi_format outformat)
{
    gpg_error_t err;
    ssh_string result = NULL;
    gcry_sexp_t fragment = NULL;
    gcry_mpi_t mpi = NULL;
    size_t size;

    fragment = gcry_sexp_find_token(sexp, name, 0);
    if (fragment == NULL) {
        goto fail;
    }

    mpi = gcry_sexp_nth_mpi(fragment, 1, informat);
    if (mpi == NULL) {
        goto fail;
    }

    err = gcry_mpi_print(outformat, NULL, 0, &size, mpi);
    if (err != 0) {
        goto fail;
    }

    result = ssh_string_new(size);
    if (result == NULL) {
        goto fail;
    }

    err = gcry_mpi_print(outformat, ssh_string_data(result), size, NULL, mpi);
    if (err != 0) {
        ssh_string_burn(result);
        ssh_string_free(result);
        result = NULL;
        goto fail;
    }

fail:
    gcry_sexp_release(fragment);
    gcry_mpi_release(mpi);
    return result;
}
Beispiel #15
0
static void
extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
{
  gcry_sexp_t l1;
  const void *a;
  size_t alen;
  void *b;
  size_t blen;

  l1 = gcry_sexp_find_token (sexp, name, 0);
  a = gcry_sexp_nth_data (l1, 1, &alen);
  b = data_from_hex (expected, &blen);
  if (!a)
    fail ("parameter \"%s\" missing in key\n", name);
  else if ( alen != blen || memcmp (a, b, alen) )
    fail ("parameter \"%s\" does not match expected value\n", name);
  gcry_free (b);
  gcry_sexp_release (l1);
}
Beispiel #16
0
static libspectrum_error
get_mpi( gcry_mpi_t *mpi, gcry_sexp_t sexp, const char *token )
{
  gcry_sexp_t pair;

  pair = gcry_sexp_find_token( sexp, token, strlen( token ) );
  if( !pair ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "get_mpis: couldn't find '%s'", token );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  *mpi = gcry_sexp_nth_mpi( pair, 1, GCRYMPI_FMT_STD );
  if( !(*mpi) ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "get_mpis: couldn't create MPI '%s'", token );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  return LIBSPECTRUM_ERROR_NONE;
}
Beispiel #17
0
static char *
gcry_prikey2jwk (gcry_sexp_t * pubkey)
{

    assert (NULL != pubkey);

    gcry_error_t  rc = -1;
    gcry_sexp_t sexp_q;
    gcry_mpi_t mpi_q;
    unsigned char *raw_q;
    size_t size_q;
    size_t d_b64_len;
    char *d_b64 = NULL;

    if (NULL == (sexp_q = gcry_sexp_find_token(*pubkey, "d", 0)))
        goto OUT;

    if (NULL == (mpi_q = gcry_sexp_nth_mpi (sexp_q, 1, GCRYMPI_FMT_USG)))
        goto FREE_Q;

    rc = gcry_mpi_aprint(GCRYMPI_FMT_USG, &raw_q, &size_q, mpi_q);
    if (rc)
        goto FREE_MPI_Q;

    if (0 == (d_b64_len = base64url_encode_alloc (raw_q, size_q, &d_b64)))
      goto FREE_MPI_Q;



    gcry_free (raw_q);

FREE_MPI_Q:
    gcry_mpi_release (mpi_q);
FREE_Q:
    gcry_sexp_release (sexp_q);
OUT:
    return d_b64;
}
Beispiel #18
0
static int dsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) {
#elif defined HAVE_LIBCRYPTO
static int dsa_public_to_string(DSA *key, ssh_buffer buffer) {
#endif
    ssh_string p = NULL;
    ssh_string q = NULL;
    ssh_string g = NULL;
    ssh_string n = NULL;

    int rc = -1;

#ifdef HAVE_LIBGCRYPT
    const char *tmp = NULL;
    size_t size;
    gcry_sexp_t sexp;

    sexp = gcry_sexp_find_token(key, "p", 0);
    if (sexp == NULL) {
        goto error;
    }
    tmp = gcry_sexp_nth_data(sexp, 1, &size);
    p = ssh_string_new(size);
    if (p == NULL) {
        goto error;
    }
    ssh_string_fill(p, (char *) tmp, size);
    gcry_sexp_release(sexp);

    sexp = gcry_sexp_find_token(key, "q", 0);
    if (sexp == NULL) {
        goto error;
    }
    tmp = gcry_sexp_nth_data(sexp, 1, &size);
    q = ssh_string_new(size);
    if (q == NULL) {
        goto error;
    }
    ssh_string_fill(q, (char *) tmp, size);
    gcry_sexp_release(sexp);

    sexp = gcry_sexp_find_token(key, "g", 0);
    if (sexp == NULL) {
        goto error;
    }
    tmp = gcry_sexp_nth_data(sexp, 1, &size);
    g = ssh_string_new(size);
    if (g == NULL) {
        goto error;
    }
    ssh_string_fill(g, (char *) tmp, size);
    gcry_sexp_release(sexp);

    sexp = gcry_sexp_find_token(key, "y", 0);
    if (sexp == NULL) {
        goto error;
    }
    tmp = gcry_sexp_nth_data(sexp, 1, &size);
    n = ssh_string_new(size);
    if (n == NULL) {
        goto error;
    }
    ssh_string_fill(n, (char *) tmp, size);

#elif defined HAVE_LIBCRYPTO
    p = make_bignum_string(key->p);
    q = make_bignum_string(key->q);
    g = make_bignum_string(key->g);
    n = make_bignum_string(key->pub_key);
    if (p == NULL || q == NULL || g == NULL || n == NULL) {
        goto error;
    }
#endif /* HAVE_LIBCRYPTO */
    if (buffer_add_ssh_string(buffer, p) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, q) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, g) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, n) < 0) {
        goto error;
    }

    rc = 0;
error:
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_release(sexp);
#endif

    ssh_string_burn(p);
    ssh_string_free(p);
    ssh_string_burn(q);
    ssh_string_free(q);
    ssh_string_burn(g);
    ssh_string_free(g);
    ssh_string_burn(n);
    ssh_string_free(n);

    return rc;
#if defined(HAVE_LIBGCRYPT) || defined(HAVE_LIBCRYPTO)
}
Beispiel #19
0
/**
 * @brief Make a public_key object out of a private_key object.
 *
 * @param[in]  prv      The private key to generate the public key.
 *
 * @returns             The generated public key, NULL on error.
 *
 * @see publickey_to_string()
 */
ssh_public_key publickey_from_privatekey(ssh_private_key prv) {
    ssh_public_key key = NULL;
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
    const char *tmp = NULL;
    size_t size;
    ssh_string p = NULL;
    ssh_string q = NULL;
    ssh_string g = NULL;
    ssh_string y = NULL;
    ssh_string e = NULL;
    ssh_string n = NULL;
#endif /* HAVE_LIBGCRYPT */

    key = malloc(sizeof(struct ssh_public_key_struct));
    if (key == NULL) {
        return NULL;
    }
    ZERO_STRUCTP(key);
    key->type = prv->type;
    switch(key->type) {
    case SSH_KEYTYPE_DSS:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(prv->dsa_priv, "p", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp, 1, &size);
        p = ssh_string_new(size);
        if (p == NULL) {
            goto error;
        }
        ssh_string_fill(p,(char *) tmp, size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->dsa_priv,"q",0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp,1,&size);
        q = ssh_string_new(size);
        if (q == NULL) {
            goto error;
        }
        ssh_string_fill(q,(char *) tmp,size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->dsa_priv, "g", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp,1,&size);
        g = ssh_string_new(size);
        if (g == NULL) {
            goto error;
        }
        ssh_string_fill(g,(char *) tmp,size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->dsa_priv,"y",0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp,1,&size);
        y = ssh_string_new(size);
        if (y == NULL) {
            goto error;
        }
        ssh_string_fill(y,(char *) tmp,size);
        gcry_sexp_release(sexp);

        gcry_sexp_build(&key->dsa_pub, NULL,
                        "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",
                        ssh_string_len(p), ssh_string_data(p),
                        ssh_string_len(q), ssh_string_data(q),
                        ssh_string_len(g), ssh_string_data(g),
                        ssh_string_len(y), ssh_string_data(y));

        ssh_string_burn(p);
        ssh_string_free(p);
        ssh_string_burn(q);
        ssh_string_free(q);
        ssh_string_burn(g);
        ssh_string_free(g);
        ssh_string_burn(y);
        ssh_string_free(y);
#elif defined HAVE_LIBCRYPTO
        key->dsa_pub = DSA_new();
        if (key->dsa_pub == NULL) {
            goto error;
        }
        key->dsa_pub->p = BN_dup(prv->dsa_priv->p);
        key->dsa_pub->q = BN_dup(prv->dsa_priv->q);
        key->dsa_pub->g = BN_dup(prv->dsa_priv->g);
        key->dsa_pub->pub_key = BN_dup(prv->dsa_priv->pub_key);
        if (key->dsa_pub->p == NULL ||
                key->dsa_pub->q == NULL ||
                key->dsa_pub->g == NULL ||
                key->dsa_pub->pub_key == NULL) {
            goto error;
        }
#endif /* HAVE_LIBCRYPTO */
        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(prv->rsa_priv, "n", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp, 1, &size);
        n = ssh_string_new(size);
        if (n == NULL) {
            goto error;
        }
        ssh_string_fill(n, (char *) tmp, size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->rsa_priv, "e", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp, 1, &size);
        e = ssh_string_new(size);
        if (e == NULL) {
            goto error;
        }
        ssh_string_fill(e, (char *) tmp, size);
        gcry_sexp_release(sexp);

        gcry_sexp_build(&key->rsa_pub, NULL,
                        "(public-key(rsa(n %b)(e %b)))",
                        ssh_string_len(n), ssh_string_data(n),
                        ssh_string_len(e), ssh_string_data(e));
        if (key->rsa_pub == NULL) {
            goto error;
        }

        ssh_string_burn(e);
        ssh_string_free(e);
        ssh_string_burn(n);
        ssh_string_free(n);
#elif defined HAVE_LIBCRYPTO
        key->rsa_pub = RSA_new();
        if (key->rsa_pub == NULL) {
            goto error;
        }
        key->rsa_pub->e = BN_dup(prv->rsa_priv->e);
        key->rsa_pub->n = BN_dup(prv->rsa_priv->n);
        if (key->rsa_pub->e == NULL ||
                key->rsa_pub->n == NULL) {
            goto error;
        }
#endif
        break;
    default:
        publickey_free(key);
        return NULL;
    }
    key->type_c = ssh_type_to_char(prv->type);

    return key;
error:
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_release(sexp);
    ssh_string_burn(p);
    ssh_string_free(p);
    ssh_string_burn(q);
    ssh_string_free(q);
    ssh_string_burn(g);
    ssh_string_free(g);
    ssh_string_burn(y);
    ssh_string_free(y);

    ssh_string_burn(e);
    ssh_string_free(e);
    ssh_string_burn(n);
    ssh_string_free(n);
#endif
    publickey_free(key);

    return NULL;
}
Beispiel #20
0
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;
}
Beispiel #21
0
STRING *signature_to_string(SIGNATURE *sign){
    STRING *str;
    STRING *rs;
#ifdef HAVE_LIBGCRYPT
    const char *r,*s;
    gcry_sexp_t sexp;
    size_t size;
#elif defined HAVE_LIBCRYPTO
    STRING *r,*s;
#endif
    unsigned char buffer[40];
    BUFFER *tmpbuf=buffer_new();
    STRING *tmp;
    tmp=string_from_char(ssh_type_to_char(sign->type));
    buffer_add_ssh_string(tmpbuf,tmp);
    free(tmp);
    switch(sign->type){
        case TYPE_DSS:
            memset(buffer,0,40);
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(sign->dsa_sign,"r",0);
            r=gcry_sexp_nth_data(sexp,1,&size);
            if (*r == 0)      /* libgcrypt put 0 when first bit is set */
            {
              size--;
              r++;
            }
            memcpy(buffer,r + size - 20,20);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(sign->dsa_sign,"s",0);
            s=gcry_sexp_nth_data(sexp,1,&size);
            if (*s == 0)
            {
              size--;
              s++;
            }
            memcpy(buffer+ 20, s + size - 20, 20);
            gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
            r=make_bignum_string(sign->dsa_sign->r);
            s=make_bignum_string(sign->dsa_sign->s);
            rs=string_new(40);
            memcpy(buffer,r->string+string_len(r)-20,20);
            memcpy(buffer+ 20, s->string + string_len(s) - 20, 20);
            free(r);
            free(s);
#endif
            rs=string_new(40);
            string_fill(rs,buffer,40);
            buffer_add_ssh_string(tmpbuf,rs);
            free(rs);
            break;
        case TYPE_RSA:
        case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(sign->rsa_sign,"s",0);
            s=gcry_sexp_nth_data(sexp,1,&size);
            if (*s == 0)
            {
              size--;
              s++;
            }
            rs=string_new(size);
            string_fill(rs,(char *)s,size);
            buffer_add_ssh_string(tmpbuf,rs);
            gcry_sexp_release(sexp);
            free(rs);
#elif defined HAVE_LIBCRYPTO
            buffer_add_ssh_string(tmpbuf,sign->rsa_sign);
#endif 
            break;
    }
    str=string_new(buffer_get_len(tmpbuf));
    string_fill(str,buffer_get(tmpbuf),buffer_get_len(tmpbuf));
    buffer_free(tmpbuf);
    return str;
}
Beispiel #22
0
/** \brief Makes a PUBLIC_KEY object out of a PRIVATE_KEY object
 * \param prv the Private key
 * \returns the public key
 * \see publickey_to_string()
 */
PUBLIC_KEY *publickey_from_privatekey(PRIVATE_KEY *prv){
    PUBLIC_KEY *key=malloc(sizeof(PUBLIC_KEY));
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
    const char *tmp;
    size_t size;
    STRING *p,*q,*g,*y,*e,*n;
#endif
    key->type=prv->type;
    switch(key->type){
        case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(prv->dsa_priv,"p",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            p=string_new(size);
            string_fill(p,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->dsa_priv,"q",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            q=string_new(size);
            string_fill(q,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->dsa_priv,"g",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            g=string_new(size);
            string_fill(g,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->dsa_priv,"y",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            y=string_new(size);
            string_fill(y,(char *)tmp,size);
            gcry_sexp_release(sexp);
            gcry_sexp_build(&key->dsa_pub,NULL,"(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",string_len(p),p->string,string_len(q),q->string,string_len(g),g->string,string_len(y),y->string);
            free(p);
            free(q);
            free(g);
            free(y);
#elif defined HAVE_LIBCRYPTO
            key->dsa_pub=DSA_new();
            key->dsa_pub->p=BN_dup(prv->dsa_priv->p);
            key->dsa_pub->q=BN_dup(prv->dsa_priv->q);
            key->dsa_pub->pub_key=BN_dup(prv->dsa_priv->pub_key);
            key->dsa_pub->g=BN_dup(prv->dsa_priv->g);
#endif
            break;
        case TYPE_RSA:
        case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(prv->rsa_priv,"n",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            n=string_new(size);
            string_fill(n,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->rsa_priv,"e",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            e=string_new(size);
            string_fill(e,(char *)tmp,size);
            gcry_sexp_release(sexp);
            gcry_sexp_build(&key->rsa_pub,NULL,"(public-key(rsa(n %b)(e %b)))",string_len(n),n->string,string_len(e),e->string);
            free(e);
            free(n);
#elif defined HAVE_LIBCRYPTO
            key->rsa_pub=RSA_new();
            key->rsa_pub->e=BN_dup(prv->rsa_priv->e);
            key->rsa_pub->n=BN_dup(prv->rsa_priv->n);
#endif
            break;
    }
    key->type_c=ssh_type_to_char(prv->type);
    return key;
}
Beispiel #23
0
/****************
 * 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;
}
Beispiel #24
0
static uint8_t*
sig2sigbuf (const gcry_sexp_t *sig, uint8_t **out, size_t *rs_len)
{
  assert (NULL != sig);
  assert (NULL != out);

  gcry_error_t  rc = -1;
  gcry_sexp_t sexp_r, sexp_s;
  gcry_mpi_t mpi_r, mpi_s;
  unsigned char *raw_r, *raw_s;
  size_t size_r, size_s;
  uint8_t *rs;


  if (NULL == (sexp_r = gcry_sexp_find_token(*sig, "r", 0)))
    goto OUT;

  if (NULL == (sexp_s = gcry_sexp_find_token(*sig, "s", 0)))
    goto FREE_R;

  if (NULL == (mpi_r = gcry_sexp_nth_mpi (sexp_r, 1, GCRYMPI_FMT_USG)))
    goto FREE_S;

  if (NULL == (mpi_s = gcry_sexp_nth_mpi (sexp_s, 1, GCRYMPI_FMT_USG)))
    goto FREE_MPI_R;

  rc = gcry_mpi_aprint(GCRYMPI_FMT_USG, &raw_r, &size_r, mpi_r);
  if (rc)
    goto FREE_MPI_S;

  rc = gcry_mpi_aprint(GCRYMPI_FMT_USG, &raw_s, &size_s, mpi_s);
  if (rc)
    goto FREE_RAW_R;

  rs = malloc (size_r+size_s);
  memset (rs, 0, size_r+size_s);

  memcpy (rs, raw_r, size_r);
  memcpy (rs+size_r, raw_s, size_s);

  *rs_len = size_r + size_s;

  rc = 0;

  gcry_free (raw_s);
 FREE_RAW_R:
  gcry_free (raw_r);
 FREE_MPI_S:
  gcry_mpi_release (mpi_s);
 FREE_MPI_R:
  gcry_mpi_release (mpi_r);
 FREE_S:
  gcry_sexp_release (sexp_s);
 FREE_R:
  gcry_sexp_release (sexp_r);
 OUT:
  if (rc == 0)
    return rs;
  else
    return NULL;

}
Beispiel #25
0
/* A test based on bug 1594.  */
static void
bug_1594 (void)
{
static char thing[] =
  "(signature"
  " (public-key"
  "  (rsa"
  "   (n #00A53A6B3A50BE571F805BD98ECE1FCE4CE291C3D4D3E971740E1EE6D447F526"
  "       6AC8973DDC82F0ADD234CC82E0A0A3F48B81ACC8B038DB8ACC3E78DC2ED2642F"
  "       6BA353FCA60F47C2801DEB477B37FB8B2F5508AA1C6D922780DB142DEA19B812"
  "       C4E64F1138AD3BD61C58DB2D2591BE0BF36A1AC588AA45763BCDFF581050ABA8"
  "       CA47BD9723ADD6A308AE28471EDD2B16D03C941D4F2B7E019C43AF8972880633"
  "       54E97B7E19F1677D84B69A26B184A77B719DD72C48E0EE36107046F786566A9D"
  "       13BAD724D6D78F24700FC22FC000E1B2A8C1B08ED62008395B0764CD9B55E80D"
  "       A0A2B61C698DC27EA98E68BB576ACFC2B91B4D7283E7D960948D049D6E3C4CB1"
  "       F489B460A120A4BB6C04A843FD3A67454136DE61CF68A927871EFFA9141BD372"
  "       A748593C703E0301F039A9E674C50301BFC385BABE5B154250E7D57B82DB31F1"
  "       E1AC696F870DCD8FE8DEC75608B988FCA3B484F1FD7755BF452F99597269AF02"
  "       E8AF87D0F93DB427291659183D077254C835BFB6DDFD87CD0B5E0738682FCD34"
  "       923F22551F73944E6CBE3ED6879B4414676B5DA0F30ED21DFA12BD2230C3C5D2"
  "       EA116A3EFEB4AEC21C58E63FAFA549A63190F01859445E9B80F427B80FD4C884"
  "       2AD41FE760A3E9DEDFB56CEBE8EA783838B2B392CACDDC760CCE212E388AFBC1"
  "       95DC6D0ED87E9091F82A82CE372738C8DE8ABD76ACD06AC8B80AA0597162DF59"
  "       67#)"
  "   (e #010001#))))";
  gcry_sexp_t sig, pubkey, n, n_val;

  info ("checking fix for bug 1594\n");

  if (gcry_sexp_new (&sig, thing, 0, 1))
    die ("scanning fixed string failed\n");
  pubkey = gcry_sexp_find_token (sig, "public-key", 0);
  gcry_sexp_release (sig);
  if (!pubkey)
    {
      fail ("'public-key' token not found");
      return;
    }
  n = gcry_sexp_find_token (pubkey, "n", 0);
  if (!n)
    {
      fail ("'n' token not found");
      gcry_sexp_release (pubkey);
      return;
    }
  n_val = gcry_sexp_nth (n, 1);
  /* Bug 1594 would require the following test:
   *   if (n_val)
   *     fail ("extracting 1-th of 'n' list did not fail");
   * However, we meanwhile modified the S-expression functions to
   * behave like Scheme to allow the access of any element of a list.
   */
  if (!n_val)
    fail ("extracting 1-th of 'n' list failed");
  /*gcry_log_debugsxp ("1-th", n_val); => "(#00A5...#)"  */
  gcry_sexp_release (n_val);
  n_val = gcry_sexp_nth (n, 2);
  if (n_val)
    fail ("extracting 2-th of 'n' list did not fail");
  n_val = gcry_sexp_nth (n, 0);
  if (!n_val)
    fail ("extracting 0-th of 'n' list failed");
  /*gcry_log_debugsxp ("0-th", n_val); => "(n)"  */
  if (gcry_sexp_nth (n_val, 1))
    fail ("extracting 1-th of car of 'n' list did not fail");
  gcry_sexp_release (n_val);
  gcry_sexp_release (n);
  gcry_sexp_release (pubkey);
}
Beispiel #26
0
static int rsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) {
#elif defined HAVE_LIBCRYPTO
static int rsa_public_to_string(RSA *key, ssh_buffer buffer) {
#endif

    ssh_string e = NULL;
    ssh_string n = NULL;

    int rc = -1;

#ifdef HAVE_LIBGCRYPT
    const char *tmp;
    size_t size;
    gcry_sexp_t sexp;

    sexp = gcry_sexp_find_token(key, "n", 0);
    if (sexp == NULL) {
        goto error;
    }
    tmp = gcry_sexp_nth_data(sexp, 1, &size);
    n = ssh_string_new(size);
    if (n == NULL) {
        goto error;
    }
    ssh_string_fill(n, (char *) tmp, size);
    gcry_sexp_release(sexp);

    sexp = gcry_sexp_find_token(key, "e", 0);
    if (sexp == NULL) {
        goto error;
    }
    tmp = gcry_sexp_nth_data(sexp, 1, &size);
    e = ssh_string_new(size);
    if (e == NULL) {
        goto error;
    }
    ssh_string_fill(e, (char *) tmp, size);

#elif defined HAVE_LIBCRYPTO
    e = make_bignum_string(key->e);
    n = make_bignum_string(key->n);
    if (e == NULL || n == NULL) {
        goto error;
    }
#endif

    if (buffer_add_ssh_string(buffer, e) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, n) < 0) {
        goto error;
    }

    rc = 0;
error:
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_release(sexp);
#endif

    ssh_string_burn(e);
    ssh_string_free(e);
    ssh_string_burn(n);
    ssh_string_free(n);

    return rc;
#if defined(HAVE_LIBGCRYPT) || defined(HAVE_LIBCRYPTO)
}
Beispiel #27
0
/* Signature decoding functions */
ssh_string signature_to_string(SIGNATURE *sign) {
    unsigned char buffer[40] = {0};
    ssh_buffer tmpbuf = NULL;
    ssh_string str = NULL;
    ssh_string tmp = NULL;
    ssh_string rs = NULL;
    int rc = -1;
#ifdef HAVE_LIBGCRYPT
    const char *r = NULL;
    const char *s = NULL;
    gcry_sexp_t sexp;
    size_t size = 0;
#elif defined HAVE_LIBCRYPTO
    ssh_string r = NULL;
    ssh_string s = NULL;
#endif

    tmpbuf = ssh_buffer_new();
    if (tmpbuf == NULL) {
        return NULL;
    }

    tmp = ssh_string_from_char(ssh_type_to_char(sign->type));
    if (tmp == NULL) {
        ssh_buffer_free(tmpbuf);
        return NULL;
    }
    if (buffer_add_ssh_string(tmpbuf, tmp) < 0) {
        ssh_buffer_free(tmpbuf);
        ssh_string_free(tmp);
        return NULL;
    }
    ssh_string_free(tmp);

    switch(sign->type) {
    case SSH_KEYTYPE_DSS:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(sign->dsa_sign, "r", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        r = gcry_sexp_nth_data(sexp, 1, &size);
        if (*r == 0) {      /* libgcrypt put 0 when first bit is set */
            size--;
            r++;
        }
        memcpy(buffer, r + size - 20, 20);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(sign->dsa_sign, "s", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = gcry_sexp_nth_data(sexp,1,&size);
        if (*s == 0) {
            size--;
            s++;
        }
        memcpy(buffer+ 20, s + size - 20, 20);
        gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
        r = make_bignum_string(sign->dsa_sign->r);
        if (r == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = make_bignum_string(sign->dsa_sign->s);
        if (s == NULL) {
            ssh_buffer_free(tmpbuf);
            ssh_string_free(r);
            return NULL;
        }

        memcpy(buffer, (char *)ssh_string_data(r) + ssh_string_len(r) - 20, 20);
        memcpy(buffer + 20, (char *)ssh_string_data(s) + ssh_string_len(s) - 20, 20);

        ssh_string_free(r);
        ssh_string_free(s);
#endif /* HAVE_LIBCRYPTO */
        rs = ssh_string_new(40);
        if (rs == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        ssh_string_fill(rs, buffer, 40);
        rc = buffer_add_ssh_string(tmpbuf, rs);
        ssh_string_free(rs);
        if (rc < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(sign->rsa_sign, "s", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = gcry_sexp_nth_data(sexp,1,&size);
        if (*s == 0) {
            size--;
            s++;
        }
        rs = ssh_string_new(size);
        if (rs == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        ssh_string_fill(rs, (char *) s, size);
        rc = buffer_add_ssh_string(tmpbuf, rs);
        gcry_sexp_release(sexp);
        ssh_string_free(rs);
        if (rc < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
#elif defined HAVE_LIBCRYPTO
        if (buffer_add_ssh_string(tmpbuf,sign->rsa_sign) < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
#endif
        break;
    }

    str = ssh_string_new(buffer_get_rest_len(tmpbuf));
    if (str == NULL) {
        ssh_buffer_free(tmpbuf);
        return NULL;
    }
    ssh_string_fill(str, buffer_get_rest(tmpbuf), buffer_get_rest_len(tmpbuf));
    ssh_buffer_free(tmpbuf);

    return str;
}
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_byte))" , "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);

    int hash_len_bits = hash_len*8;

    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
    

    unsigned int j;

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

       gcry_mpi_t empi = gcry_mpi_set_ui(NULL,e);
       gcry_mpi_t twoi = gcry_mpi_new(e);
       gcry_mpi_mul_2exp(empi, one, e);   // twoi = 2^e
       
    	for( j=0; j< 256 ; j++){
            
            gcry_mpi_t jmpi = gcry_mpi_set_ui(NULL,j);
    	       gcry_mpi_mulm(twoi,jmpi,empi,q);
      
        	//retrieve k
            gcry_mpi_mulm(tmp, s_tilda, twoi, q); // s_tilda*(2^e) modq q
            gcry_mpi_subm(result, s_tilda, s, q); // s_tilda - s mod q
            gcry_mpi_invm(result, result, q); // (s_tilda - s mod q)^-1
            gcry_mpi_mulm(result,result, tmp, q); // s_tilda*(2^3)  mod q)*(s_tilda - s mod q)^-1 === 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] BYTE : %d * 2^%d  FAULT: k-j*2^%d\n" , j , (int)e,(int)e); //DEBUG 
                DEBUG_MPI_PRINT(result,"X = ");
        	    printf("\n");
          	    return;  
            }

        }

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

       gcry_mpi_t empi = gcry_mpi_set_ui(NULL,e);
       gcry_mpi_t twoi = gcry_mpi_new(e);
       gcry_mpi_mul_2exp(empi, one, e);   // twoi = 2^e
       
    	for( j=0; j< 256 ; j++){
            
            gcry_mpi_t jmpi = gcry_mpi_set_ui(NULL,j);
    	    gcry_mpi_mulm(twoi,jmpi,empi,q);
      
            //retrieve k
            gcry_mpi_mulm(tmp, s_tilda, twoi, q); // s_tilda*(2^e) modq q
            gcry_mpi_subm(result, s, s_tilda, q); // s_tilda - s mod q
            gcry_mpi_invm(result, result, q); // (s_tilda - s mod q)^-1
            gcry_mpi_mulm(result,result, tmp, q); // s_tilda*(2^3)  mod q)*(s_tilda - s mod q)^-1 === 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) {
                continue;
            }
            else{
                printf("\n[!!!]PRIVATE KEY %d %d BITS CRACKED!!\n" , pbits,qbits );
        	    printf("[DBG] BYTE : %d * 2^%d  FAULT: k+j*2^%d\n" , j , (int)e,(int)e); //DEBUG 
                DEBUG_MPI_PRINT(result,"X = ");
        	    printf("\n");
          	    return;  
            }
        }
    }    
}
Beispiel #29
0
/* in case of DSA puts into data, r,s
 */
static int
_gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, mpi_t * pkey,
		 int pkey_len)
{
  gcry_sexp_t s_hash, s_key, s_sig;
  int rc = -1;

  /* make a sexp from pkey */
  switch (algo)
    {
    case GCRY_PK_DSA:
      if (pkey_len >= 5)
	rc = gcry_sexp_build (&s_key, NULL,
			      "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
			      pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]);
      else
	{
	  gnutls_assert ();
	}

      break;
    case GCRY_PK_RSA:
      if (pkey_len >= 6)
	rc = gcry_sexp_build (&s_key, NULL,
			      "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
			      pkey[0], pkey[1], pkey[2], pkey[3],
			      pkey[4], pkey[5]);
      else
	{
	  gnutls_assert ();
	}
      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 ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* pass it to libgcrypt */
  rc = gcry_pk_sign (&s_sig, s_hash, s_key);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_key);

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

    }
  else
    {
      gcry_sexp_t list;

      if (algo == GCRY_PK_DSA)
	{
	  list = gcry_sexp_find_token (s_sig, "r", 0);
	  if (list == NULL)
	    {
	      gnutls_assert ();
	      gcry_sexp_release (s_sig);
	      return GNUTLS_E_INTERNAL_ERROR;
	    }

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

	  list = gcry_sexp_find_token (s_sig, "s", 0);
	  if (list == NULL)
	    {
	      gnutls_assert ();
	      gcry_sexp_release (s_sig);
	      return GNUTLS_E_INTERNAL_ERROR;
	    }

	  data[1] = gcry_sexp_nth_mpi (list, 1, 0);
	  gcry_sexp_release (list);
	}
      else
	{			/* GCRY_PK_RSA */
	  list = gcry_sexp_find_token (s_sig, "s", 0);
	  if (list == NULL)
	    {
	      gnutls_assert ();
	      gcry_sexp_release (s_sig);
	      return GNUTLS_E_INTERNAL_ERROR;
	    }

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

  gcry_sexp_release (s_sig);
  return 0;
}
Beispiel #30
0
/* fixme: we need better tests */
static void
basic (void)
{
  int pass;
  gcry_sexp_t sexp;
  int idx;
  char *secure_buffer;
  size_t secure_buffer_len;
  const char *string;
  static struct {
    const char *token;
    const char *parm;
  } values[] = {
    { "public-key", NULL },
    { "dsa", NULL },
    { "dsa", "p" },
    { "dsa", "y" },
    { "dsa", "q" },
    { "dsa", "g" },
    { NULL }
  };

  info ("doing some pretty pointless tests\n");

  secure_buffer_len = 99;
  secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
  memset (secure_buffer, 'G', secure_buffer_len);

  for (pass=0;;pass++)
    {
      gcry_mpi_t m;

      switch (pass)
        {
        case 0:
          string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                    "(q #61626364656667#) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 42);
          if ( gcry_sexp_build (&sexp, NULL, string, m ) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          break;

        case 1:
          string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                    "(q %b) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 42);
          if ( gcry_sexp_build (&sexp, NULL, string,
                                15, "foo\0\x01\0x02789012345", m) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          break;

        case 2:
          string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
                    "(q %b) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 17);
          if ( gcry_sexp_build (&sexp, NULL, string,
                                secure_buffer_len, secure_buffer, m) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          if (!gcry_is_secure (sexp))
            fail ("gcry_sexp_build did not switch to secure memory\n");
          break;

        case 3:
          {
            gcry_sexp_t help_sexp;

            if (gcry_sexp_new (&help_sexp,
                               "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
              {
                fail (" scanning fixed string failed\n");
                return;
              }

            string = ("(public-key (dsa (p #41424344#) (parm %S) "
                      "(y dummy)(q %b) (g %m)))");
            m = gcry_mpi_set_ui (NULL, 17);
            if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
                                  secure_buffer_len, secure_buffer, m) )
              {
                gcry_mpi_release (m);
                fail (" scanning `%s' failed\n", string);
                return;
              }
            gcry_mpi_release (m);
            gcry_sexp_release (help_sexp);
          }
          break;


        default:
          return; /* Ready. */
        }


      /* now find something */
      for (idx=0; values[idx].token; idx++)
        {
          const char *token = values[idx].token;
          const char *parm = values[idx].parm;
          gcry_sexp_t s1, s2;
          gcry_mpi_t a;
          const char *p;
          size_t n;

          s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
          if (!s1)
            {
              fail ("didn't found `%s'\n", token);
              continue;
            }

          p = gcry_sexp_nth_data (s1, 0, &n);
          if (!p)
            {
              gcry_sexp_release (s1);
              fail ("no car for `%s'\n", token);
              continue;
            }
          info ("car=`%.*s'\n", (int)n, p);

          s2 = gcry_sexp_cdr (s1);
          if (!s2)
            {
              gcry_sexp_release (s1);
              fail ("no cdr for `%s'\n", token);
              continue;
            }

          p = gcry_sexp_nth_data (s2, 0, &n);
          gcry_sexp_release (s2);
          if (p)
            {
              gcry_sexp_release (s1);
              fail ("data at car of `%s'\n", token);
              continue;
            }

          if (parm)
            {
              s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
              gcry_sexp_release (s1);
              if (!s2)
                {
                  fail ("didn't found `%s'\n", parm);
                  continue;
                }
              p = gcry_sexp_nth_data (s2, 0, &n);
              if (!p)
                {
                  gcry_sexp_release (s2);
                  fail("no car for `%s'\n", parm );
                  continue;
                }
              info ("car=`%.*s'\n", (int)n, p);
              p = gcry_sexp_nth_data (s2, 1, &n);
              if (!p)
                {
                  gcry_sexp_release (s2);
                  fail("no cdr for `%s'\n", parm );
                  continue;
                }
              info ("cdr=`%.*s'\n", (int)n, p);

              a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
              gcry_sexp_release (s2);
              if (!a)
                {
                  fail("failed to cdr the mpi for `%s'\n", parm);
                  continue;
                }
              gcry_mpi_release (a);
            }
          else
            gcry_sexp_release (s1);
        }

      gcry_sexp_release (sexp);
      sexp = NULL;
    }
  gcry_free (secure_buffer);
}