Beispiel #1
0
/* returns 1 if the modulus of k1 is < than the one of k2 */
static int modulus_smaller(ssh_public_key k1, ssh_public_key k2){
    bignum n1;
    bignum n2;
    int res;
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
    sexp=gcry_sexp_find_token(k1->rsa_pub,"n",0);
    n1=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
    sexp=gcry_sexp_find_token(k2->rsa_pub,"n",0);
    n2=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
    n1=k1->rsa_pub->n;
    n2=k2->rsa_pub->n;
#endif
    if(bignum_cmp(n1,n2)<0)
        res=1;
    else
        res=0;
#ifdef HAVE_LIBGCRYPT
    bignum_free(n1);
    bignum_free(n2);
#endif
    return res;
    
}
Beispiel #2
0
char* encrypt(rsa_packet * packet, char *public_key, char *plaintext){
	gcry_error_t error;

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

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

	gcry_sexp_t public_sexp = sexp_new(public_key);
	gcry_sexp_t r_ciph;
	struct timeval timer;
	timer_start(&timer);
	if ((error = gcry_pk_encrypt(&r_ciph, data, public_sexp))) {
		printf("Error in gcry_pk_encrypt(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}
	timer_poll("\nSoftware encrypt: %d.%06d    seconds\n", &timer);
	
	gcry_sexp_t cipher_sexp = gcry_sexp_cdr(gcry_sexp_find_token(r_ciph, "a", 1));
	gcry_mpi_t cipher_mpi = gcry_sexp_nth_mpi(cipher_sexp, 0, GCRYMPI_FMT_USG);
	gcry_mpi_print(GCRYMPI_FMT_USG, packet->ciphertext, 256, &packet->cipher_len, cipher_mpi);  
	
	return sexp_string(r_ciph);
}
Beispiel #3
0
/* Return the number of bits of the Q parameter from the DSA key
   KEY.  */
static unsigned int
get_dsa_qbits (gcry_sexp_t key)
{
  gcry_sexp_t l1, l2;
  gcry_mpi_t q;
  unsigned int nbits;

  l1 = gcry_sexp_find_token (key, "public-key", 0);
  if (!l1)
    return 0; /* Does not contain a key object.  */
  l2 = gcry_sexp_cadr (l1);
  gcry_sexp_release  (l1);
  l1 = gcry_sexp_find_token (l2, "q", 1);
  gcry_sexp_release (l2);
  if (!l1)
    return 0; /* Invalid object.  */
  q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (l1);
  if (!q)
    return 0; /* Missing value.  */
  nbits = gcry_mpi_get_nbits (q);
  gcry_mpi_release (q);

  return nbits;
}
Beispiel #4
0
char* decrypt(char *private_key, char *ciphertext){
	gcry_error_t error;
	gcry_sexp_t data = sexp_new(ciphertext);

	gcry_sexp_t private_sexp = sexp_new(private_key);
	gcry_sexp_t r_plain;
	struct timeval timer;
	timer_start(&timer);
	if ((error = gcry_pk_decrypt(&r_plain, data, private_sexp))) {
		printf("Error in gcry_pk_decrypt(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}
	timer_poll("\nSoftware decrypt: %d.%06d    seconds\n", &timer);

	gcry_mpi_t r_mpi = gcry_sexp_nth_mpi(r_plain, 0, GCRYMPI_FMT_USG);

	unsigned char *plaintext;
	size_t plaintext_size;
	if ((error = gcry_mpi_aprint(GCRYMPI_FMT_HEX, &plaintext, &plaintext_size, r_mpi))) {
		printf("Error in gcry_mpi_aprint(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}

	// Return type hack
	return (char *) plaintext;
}
Beispiel #5
0
gcry_error_t
jsapi_privkey_get_dsa_token(OtrlPrivKey *keyToExport, const char* token,
            unsigned char *buffer, size_t buflen, size_t *nbytes)
{
    gcry_error_t err;
    gcry_mpi_t x;
    gcry_sexp_t dsas,xs;
    size_t nx;

    gcry_sexp_t privkey = keyToExport->privkey;

    dsas = gcry_sexp_find_token(privkey, "dsa", 0);
    if (dsas == NULL) {
        return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
    }

    xs = gcry_sexp_find_token(dsas, token, 0);
    gcry_sexp_release(dsas);

    if (!xs) return gcry_error(GPG_ERR_UNUSABLE_SECKEY);

    x = gcry_sexp_nth_mpi(xs, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(xs);

    if (!x) return gcry_error(GPG_ERR_UNUSABLE_SECKEY);

    err =  gcry_mpi_print(GCRYMPI_FMT_HEX, buffer,buflen,nbytes,x);
    gcry_mpi_release(x);
    return err;
}
Beispiel #6
0
/* Sign data using a private key.  The data must be small enough to be
 * signed (i.e. already hashed, if necessary).  The signature will be
 * returned in *sigp, which the caller must free().  Its length will be
 * returned in *siglenp. */
gcry_error_t otrl_privkey_sign(unsigned char **sigp, size_t *siglenp,
	OtrlPrivKey *privkey, const unsigned char *data, size_t len)
{
    gcry_mpi_t r,s, datampi;
    gcry_sexp_t dsas, rs, ss, sigs, datas;
    size_t nr, ns;
    const enum gcry_mpi_format format = GCRYMPI_FMT_USG;

    if (privkey->pubkey_type != OTRL_PUBKEY_TYPE_DSA)
	return gcry_error(GPG_ERR_INV_VALUE);

    *sigp = malloc(40);
    if (sigp == NULL) return gcry_error(GPG_ERR_ENOMEM);
    *siglenp = 40;

    if (len) {
	gcry_mpi_scan(&datampi, GCRYMPI_FMT_USG, data, len, NULL);
    } else {
	datampi = gcry_mpi_set_ui(NULL, 0);
    }
    gcry_sexp_build(&datas, NULL, "(%m)", datampi);
    gcry_mpi_release(datampi);
    gcry_pk_sign(&sigs, datas, privkey->privkey);
    gcry_sexp_release(datas);
    dsas = gcry_sexp_find_token(sigs, "dsa", 0);
    gcry_sexp_release(sigs);
    rs = gcry_sexp_find_token(dsas, "r", 0);
    ss = gcry_sexp_find_token(dsas, "s", 0);
    gcry_sexp_release(dsas);
    r = gcry_sexp_nth_mpi(rs, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(rs);
    s = gcry_sexp_nth_mpi(ss, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(ss);
    gcry_mpi_print(format, NULL, 0, &nr, r);
    gcry_mpi_print(format, NULL, 0, &ns, s);
    memset(*sigp, 0, 40);
    gcry_mpi_print(format, (*sigp)+(20-nr), nr, NULL, r);
    gcry_mpi_print(format, (*sigp)+20+(20-ns), ns, NULL, s);
    gcry_mpi_release(r);
    gcry_mpi_release(s);

    return gcry_error(GPG_ERR_NO_ERROR);
}
Beispiel #7
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 #8
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 #9
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 #10
0
/**
 * Extract values from an S-expression.
 *
 * @param array where to store the result(s)
 * @param sexp S-expression to parse
 * @param topname top-level name in the S-expression that is of interest
 * @param elems names of the elements to extract
 * @return 0 on success
 */
static int
key_from_sexp (gcry_mpi_t *array,
               gcry_sexp_t sexp,
               const char *topname,
               const char *elems)
{
  gcry_sexp_t list;
  gcry_sexp_t l2;
  const char *s;
  unsigned int i;
  unsigned int idx;

  if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
    return 1;
  l2 = gcry_sexp_cadr (list);
  gcry_sexp_release (list);
  list = l2;
  if (! list)
    return 2;
  idx = 0;
  for (s = elems; *s; s++, idx++)
  {
    if (! (l2 = gcry_sexp_find_token (list, s, 1)))
    {
      for (i = 0; i < idx; i++)
      {
        gcry_free (array[i]);
        array[i] = NULL;
      }
      gcry_sexp_release (list);
      return 3;                 /* required parameter not found */
    }
    array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release (l2);
    if (! array[idx])
    {
      for (i = 0; i < idx; i++)
      {
        gcry_free (array[i]);
        array[i] = NULL;
      }
      gcry_sexp_release (list);
      return 4;                 /* required parameter is invalid */
    }
  }
  gcry_sexp_release (list);
  return 0;
}
Beispiel #11
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 #12
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 #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
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 #15
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 #16
0
static void
check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
{
    gcry_sexp_t skey, pkey, list;

    pkey = gcry_sexp_find_token (key, "public-key", 0);
    if (!pkey)
        fail ("public part missing in return value\n");
    else
    {
        gcry_mpi_t e = NULL;

        list = gcry_sexp_find_token (pkey, "e", 0);
        if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) )
            fail ("public exponent not found\n");
        else if (!expected_e)
        {
            if (verbose)
                show_mpi ("public exponent: ", e);
        }
        else if ( gcry_mpi_cmp_ui (e, expected_e))
        {
            show_mpi ("public exponent: ", e);
            fail ("public exponent is not %lu\n", expected_e);
        }
        gcry_sexp_release (list);
        gcry_mpi_release (e);
        gcry_sexp_release (pkey);
    }

    skey = gcry_sexp_find_token (key, "private-key", 0);
    if (!skey)
        fail ("private part missing in return value\n");
    else
    {
        int rc = gcry_pk_testkey (skey);
        if (rc)
            fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
        gcry_sexp_release (skey);
    }
}
Beispiel #17
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 #18
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 #19
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 #20
0
/**
 * cdk_pk_decrypt:
 * @sk: the secret key
 * @pke: public key encrypted packet
 * @r_sk: the object to store the plain session key
 *
 * Decrypt the encrypted session key from @pke into @r_sk.
 **/
cdk_error_t
cdk_pk_decrypt (cdk_seckey_t sk, cdk_pkt_pubkey_enc_t pke,
                gcry_mpi_t *r_sk)
{
  gcry_sexp_t s_data = NULL, s_skey = NULL, s_plain = NULL;
  cdk_error_t rc;
  gcry_error_t err;
  
  if (!sk || !r_sk || !pke)
    return CDK_Inv_Value;
  
  if (!is_unprotected (sk))
    return CDK_Inv_Mode;
  
  *r_sk = NULL;
  rc = seckey_to_sexp (&s_skey, sk);
  if (rc)
    return rc;

  rc = pubenc_to_sexp (&s_data, pke);
  if (rc)
    {
      gcry_sexp_release (s_skey);
      return rc;
    }
  
  err = gcry_pk_decrypt (&s_plain, s_data, s_skey);
  if (err)
    rc = map_gcry_error (err);
  else
    *r_sk  = gcry_sexp_nth_mpi (s_plain, 0, 0);

  gcry_sexp_release (s_data);
  gcry_sexp_release (s_skey);
  gcry_sexp_release (s_plain);
  return rc;
}
Beispiel #21
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 #22
0
/* Return the public key for the keygrip GRIP.  The result is stored
   at RESULT.  This function extracts the public key from the private
   key database.  On failure an error code is returned and NULL stored
   at RESULT. */
gpg_error_t
agent_public_key_from_file (ctrl_t ctrl,
                            const unsigned char *grip,
                            gcry_sexp_t *result)
{
  int i, idx, rc;
  gcry_sexp_t s_skey;
  const char *algoname;
  gcry_sexp_t uri_sexp, comment_sexp;
  const char *uri, *comment;
  size_t uri_length, comment_length;
  char *format, *p;
  void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
                           for comment + end-of-list.  */
  int argidx;
  gcry_sexp_t list, l2;
  const char *name;
  const char *s;
  size_t n;
  const char *elems;
  gcry_mpi_t *array;

  (void)ctrl;

  *result = NULL;

  rc = read_key_file (grip, &s_skey);
  if (rc)
    return rc;

  list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
  if (!list)
    list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
  if (!list)
    list = gcry_sexp_find_token (s_skey, "private-key", 0 );
  if (!list)
    {
      log_error ("invalid private key format\n");
      gcry_sexp_release (s_skey);
      return gpg_error (GPG_ERR_BAD_SECKEY);
    }

  l2 = gcry_sexp_cadr (list);
  gcry_sexp_release (list);
  list = l2;
  name = gcry_sexp_nth_data (list, 0, &n);
  if (n==3 && !memcmp (name, "rsa", 3))
    {
      algoname = "rsa";
      elems = "ne";
    }
  else if (n==3 && !memcmp (name, "dsa", 3))
    {
      algoname = "dsa";
      elems = "pqgy";
    }
  else if (n==3 && !memcmp (name, "elg", 3))
    {
      algoname = "elg";
      elems = "pgy";
    }
  else
    {
      log_error ("unknown private key algorithm\n");
      gcry_sexp_release (list);
      gcry_sexp_release (s_skey);
      return gpg_error (GPG_ERR_BAD_SECKEY);
    }

  /* Allocate an array for the parameters and copy them out of the
     secret key.   FIXME: We should have a generic copy function. */
  array = xtrycalloc (strlen(elems) + 1, sizeof *array);
  if (!array)
    {
      rc = gpg_error_from_syserror ();
      gcry_sexp_release (list);
      gcry_sexp_release (s_skey);
      return rc;
    }

  for (idx=0, s=elems; *s; s++, idx++ )
    {
      l2 = gcry_sexp_find_token (list, s, 1);
      if (!l2)
        {
          /* Required parameter not found.  */
          for (i=0; i<idx; i++)
            gcry_mpi_release (array[i]);
          xfree (array);
          gcry_sexp_release (list);
          gcry_sexp_release (s_skey);
          return gpg_error (GPG_ERR_BAD_SECKEY);
	}
      array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
      gcry_sexp_release (l2);
      if (!array[idx])
        {
          /* Required parameter is invalid. */
          for (i=0; i<idx; i++)
            gcry_mpi_release (array[i]);
          xfree (array);
          gcry_sexp_release (list);
          gcry_sexp_release (s_skey);
          return gpg_error (GPG_ERR_BAD_SECKEY);
	}
    }
  gcry_sexp_release (list);
  list = NULL;

  uri = NULL;
  uri_length = 0;
  uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
  if (uri_sexp)
    uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);

  comment = NULL;
  comment_length = 0;
  comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
  if (comment_sexp)
    comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);

  gcry_sexp_release (s_skey);
  s_skey = NULL;


  /* FIXME: The following thing is pretty ugly code; we should
     investigate how to make it cleaner. Probably code to handle
     canonical S-expressions in a memory buffer is better suioted for
     such a task.  After all that is what we do in protect.c.  Neeed
     to find common patterns and write a straightformward API to use
     them.  */
  assert (sizeof (size_t) <= sizeof (void*));

  format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
  if (!format)
    {
      rc = gpg_error_from_syserror ();
      for (i=0; array[i]; i++)
        gcry_mpi_release (array[i]);
      xfree (array);
      gcry_sexp_release (uri_sexp);
      gcry_sexp_release (comment_sexp);
      return rc;
    }

  argidx = 0;
  p = stpcpy (stpcpy (format, "(public-key("), algoname);
  for (idx=0, s=elems; *s; s++, idx++ )
    {
      *p++ = '(';
      *p++ = *s;
      p = stpcpy (p, " %m)");
      assert (argidx < DIM (args));
      args[argidx++] = &array[idx];
    }
  *p++ = ')';
  if (uri)
    {
      p = stpcpy (p, "(uri %b)");
      assert (argidx+1 < DIM (args));
      args[argidx++] = (void *)&uri_length;
      args[argidx++] = (void *)&uri;
    }
  if (comment)
    {
      p = stpcpy (p, "(comment %b)");
      assert (argidx+1 < DIM (args));
      args[argidx++] = (void *)&comment_length;
      args[argidx++] = (void*)&comment;
    }
  *p++ = ')';
  *p = 0;
  assert (argidx < DIM (args));
  args[argidx] = NULL;

  rc = gcry_sexp_build_array (&list, NULL, format, args);
  xfree (format);
  for (i=0; array[i]; i++)
    gcry_mpi_release (array[i]);
  xfree (array);
  gcry_sexp_release (uri_sexp);
  gcry_sexp_release (comment_sexp);

  if (!rc)
    *result = list;
  return rc;
}
Beispiel #23
0
static int
_gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey,
		    int pkey_len)
{
  gcry_sexp_t s_plain, s_data, s_pkey;
  int rc = -1;

  /* make a sexp from pkey */
  switch (algo)
    {
    case GCRY_PK_RSA:
      if (pkey_len >= 6)
	rc = gcry_sexp_build (&s_pkey, 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]);
      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, "(enc-val(rsa(a%m)))", data))
    {
      gnutls_assert ();
      gcry_sexp_release (s_pkey);
      return GNUTLS_E_INTERNAL_ERROR;
    }

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

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

    }
  else
    {				/* add better error handling or make gnupg use S-Exp directly */
      resarr[0] = gcry_sexp_nth_mpi (s_plain, 0, 0);

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

  gcry_sexp_release (s_plain);
  return rc;
}
Beispiel #24
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);
}
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 #26
0
static int
_rsa_generate_params (bigint_t * resarr, int *resarr_len, int bits)
{

  int ret, i;
  gcry_sexp_t parms, key, list;
  bigint_t tmp;

  if (*resarr_len < RSA_PRIVATE_PARAMS)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret = gcry_sexp_build (&parms, NULL, "(genkey(rsa(nbits %d)))", bits);
  if (ret != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* generate the RSA key */
  ret = gcry_pk_genkey (&key, parms);
  gcry_sexp_release (parms);

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

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

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

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

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

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

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

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

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


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

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


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

  resarr[5] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);

  gcry_sexp_release (list);
  gcry_sexp_release (key);

  _gnutls_mpi_log ("n: ", resarr[0]);
  _gnutls_mpi_log ("e: ", resarr[1]);
  _gnutls_mpi_log ("d: ", resarr[2]);
  _gnutls_mpi_log ("p: ", resarr[3]);
  _gnutls_mpi_log ("q: ", resarr[4]);
  _gnutls_mpi_log ("u: ", resarr[5]);

  /* generate e1 and e2 */

  *resarr_len = 6;

  tmp = _gnutls_mpi_alloc_like (resarr[0]);
  if (tmp == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  ret = _gnutls_calc_rsa_exp (resarr, 2 + *resarr_len);
  if (ret < 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  (*resarr_len) += 2;

  return 0;

cleanup:
  for (i = 0; i < *resarr_len; i++)
    _gnutls_mpi_release (&resarr[i]);

  return ret;
}
Beispiel #27
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 #28
0
/**
 * @brief Write the current server as known in the known hosts file.
 *
 * This will create the known hosts file if it does not exist. You generaly use
 * it when ssh_is_server_known() answered SSH_SERVER_NOT_KNOWN.
 *
 * @param[in]  session  The ssh session to use.
 *
 * @return              SSH_OK on success, SSH_ERROR on error.
 */
int ssh_write_knownhost(ssh_session session) {
  ssh_string pubkey;
  unsigned char *pubkey_64;
  char buffer[4096] = {0};
  FILE *file;
  char *dir;
  char *host;
  char *hostport;
  size_t len = 0;

  if (session->host == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Can't write host in known hosts if the hostname isn't known");
    return SSH_ERROR;
  }

  host = ssh_lowercase(session->host);
  /* If using a nonstandard port, save the host in the [host]:port format */
  if(session->port != 22){
    hostport = ssh_hostport(host,session->port);
    SAFE_FREE(host);
    host=hostport;
    hostport=NULL;
  }

  if (session->knownhosts == NULL) {
    if (ssh_options_apply(session) < 0) {
      ssh_set_error(session, SSH_FATAL, "Can't find a known_hosts file");
      return SSH_ERROR;
    }
  }

  if(session->current_crypto==NULL) {
  	ssh_set_error(session, SSH_FATAL, "No current crypto context");
  	return SSH_ERROR;
  }

  pubkey = session->current_crypto->server_pubkey;
  if(pubkey == NULL){
  	ssh_set_error(session, SSH_FATAL, "No public key present");
  	return SSH_ERROR;
  }

  /* Check if ~/.ssh exists and create it if not */
  dir = ssh_dirname(session->knownhosts);
  if (dir == NULL) {
    ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
    return -1;
  }
  if (! ssh_file_readaccess_ok(dir)) {
    if (ssh_mkdir(dir, 0700) < 0) {
      ssh_set_error(session, SSH_FATAL,
          "Cannot create %s directory.", dir);
      SAFE_FREE(dir);
      return -1;
    }
  }
  SAFE_FREE(dir);

  file = fopen(session->knownhosts, "a");
  if (file == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Couldn't open known_hosts file %s for appending: %s",
        session->knownhosts, strerror(errno));
    SAFE_FREE(host);
    return -1;
  }

  if (strcmp(session->current_crypto->server_pubkey_type, "ssh-rsa1") == 0) {
    /* openssh uses a different format for ssh-rsa1 keys.
       Be compatible --kv */
    ssh_public_key key;
    char *e_string = NULL;
    char *n_string = NULL;
    bignum e = NULL;
    bignum n = NULL;
    int rsa_size;
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
#endif

    key = publickey_from_string(session, pubkey);
    if (key == NULL) {
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

#ifdef HAVE_LIBGCRYPT
    sexp = gcry_sexp_find_token(key->rsa_pub, "e", 0);
    if (sexp == NULL) {
      publickey_free(key);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }
    e = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
    if (e == NULL) {
      publickey_free(key);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    sexp = gcry_sexp_find_token(key->rsa_pub, "n", 0);
    if (sexp == NULL) {
      publickey_free(key);
      bignum_free(e);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }
    n = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(sexp);
    if (n == NULL) {
      publickey_free(key);
      bignum_free(e);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    rsa_size = (gcry_pk_get_nbits(key->rsa_pub) + 7) / 8;
#elif defined HAVE_LIBCRYPTO
    e = key->rsa_pub->e;
    n = key->rsa_pub->n;
    rsa_size = RSA_size(key->rsa_pub);
#endif

    e_string = bignum_bn2dec(e);
    n_string = bignum_bn2dec(n);
    if (e_string == NULL || n_string == NULL) {
#ifdef HAVE_LIBGCRYPT
      bignum_free(e);
      bignum_free(n);
      SAFE_FREE(e_string);
      SAFE_FREE(n_string);
#elif defined HAVE_LIBCRYPTO
      OPENSSL_free(e_string);
      OPENSSL_free(n_string);
#endif
      publickey_free(key);
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    snprintf(buffer, sizeof(buffer),
        "%s %d %s %s\n",
        host,
        rsa_size << 3,
        e_string,
        n_string);

#ifdef HAVE_LIBGCRYPT
    bignum_free(e);
    bignum_free(n);
    SAFE_FREE(e_string);
    SAFE_FREE(n_string);
#elif defined HAVE_LIBCRYPTO
    OPENSSL_free(e_string);
    OPENSSL_free(n_string);
#endif

    publickey_free(key);
  } else {
    pubkey_64 = bin_to_base64(pubkey->string, ssh_string_len(pubkey));
    if (pubkey_64 == NULL) {
      fclose(file);
      SAFE_FREE(host);
      return -1;
    }

    snprintf(buffer, sizeof(buffer),
        "%s %s %s\n",
        host,
        session->current_crypto->server_pubkey_type,
        pubkey_64);

    SAFE_FREE(pubkey_64);
  }
  SAFE_FREE(host);
  len = strlen(buffer);
  if (fwrite(buffer, len, 1, file) != 1 || ferror(file)) {
    fclose(file);
    return -1;
  }

  fclose(file);
  return 0;
}
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
/**
 * ntfs_raw_fek_decrypt -
 *
 * Note: decrypting into the input buffer.
 */
static unsigned ntfs_raw_fek_decrypt(u8 *fek, u32 fek_size,
                                     ntfs_rsa_private_key rsa_key)
{
    gcry_mpi_t fek_mpi;
    gcry_sexp_t fek_sexp, fek_sexp2;
    gcry_error_t err;
    size_t size, padding;

    /* Reverse the raw FEK. */
    ntfs_buffer_reverse(fek, fek_size);
    /* Convert the FEK to internal MPI format. */
    err = gcry_mpi_scan(&fek_mpi, GCRYMPI_FMT_USG, fek, fek_size, NULL);
    if (err != GPG_ERR_NO_ERROR) {
        ntfs_log_error("Failed to convert file encryption key to "
                       "internal MPI format: %s\n",
                       gcry_strerror(err));
        return 0;
    }
    /* Create an internal S-expression from the FEK. */
    err = gcry_sexp_build(&fek_sexp, NULL,
                          "(enc-val (flags) (rsa (a %m)))", fek_mpi);
    gcry_mpi_release(fek_mpi);
    if (err != GPG_ERR_NO_ERROR) {
        ntfs_log_error("Failed to create internal S-expression of "
                       "the file encryption key: %s\n",
                       gcry_strerror(err));
        return 0;
    }
    /* Decrypt the FEK. */
    err = gcry_pk_decrypt(&fek_sexp2, fek_sexp, (gcry_sexp_t)rsa_key);
    gcry_sexp_release(fek_sexp);
    if (err != GPG_ERR_NO_ERROR) {
        ntfs_log_error("Failed to decrypt the file encryption key: "
                       "%s\n", gcry_strerror(err));
        return 0;
    }
    /* Extract the actual FEK from the decrypted raw S-expression. */
    fek_sexp = gcry_sexp_find_token(fek_sexp2, "value", 0);
    gcry_sexp_release(fek_sexp2);
    if (!fek_sexp) {
        ntfs_log_error("Failed to find the decrypted file encryption "
                       "key in the internal S-expression.\n");
        return 0;
    }
    /* Convert the decrypted FEK S-expression into MPI format. */
    fek_mpi = gcry_sexp_nth_mpi(fek_sexp, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(fek_sexp);
    if (!fek_mpi) {
        ntfs_log_error("Failed to convert the decrypted file "
                       "encryption key S-expression to internal MPI "
                       "format.\n");
        return 0;
    }
    /* Convert the decrypted FEK from MPI format to binary data. */
    err = gcry_mpi_print(GCRYMPI_FMT_USG, fek, fek_size, &size, fek_mpi);
    gcry_mpi_release(fek_mpi);
    if (err != GPG_ERR_NO_ERROR || !size) {
        ntfs_log_error("Failed to convert decrypted file encryption "
                       "key from internal MPI format to binary data: "
                       "%s\n", gcry_strerror(err));
        return 0;
    }
    /*
     * Finally, remove the PKCS#1 padding and return the size of the
     * decrypted FEK.
     */
    padding = strnlen((char *)fek, size) + 1;
    if (padding > size) {
        ntfs_log_error("Failed to remove PKCS#1 padding from "
                       "decrypted file encryption key.\n");
        return 0;
    }
    size -= padding;
    memmove(fek, fek + padding, size);
    return size;
}