コード例 #1
0
ファイル: dsa-compat-keygen.c プロジェクト: Distrotech/nettle
/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048, 224),
   (2048, 256), (3072, 256). */
int
dsa_compat_generate_keypair(struct dsa_public_key *pub,
			    struct dsa_private_key *key,
			    void *random_ctx, nettle_random_func *random,
			    void *progress_ctx, nettle_progress_func *progress,
			    unsigned p_bits, unsigned q_bits)
{
  struct dsa_params *params;

  switch (q_bits)
    {
    case 160:
      if (p_bits < DSA_SHA1_MIN_P_BITS)
	return 0;
      break;
    case 224:
    case 256:
      if (p_bits < DSA_SHA256_MIN_P_BITS)
	return 0;
      break;
    default:
      return 0;
    }

  /* NOTE: Depends on identical layout! */
  params = (struct dsa_params *) pub;

  if (!dsa_generate_params (params,
			    random_ctx, random,
			    progress_ctx, progress,
			    p_bits, q_bits))
    return 0;

  dsa_generate_keypair (params, pub->y, key->x, random_ctx, random);

  return 1;
}
コード例 #2
0
ファイル: main.c プロジェクト: jamella/matasano
int main(int argc, char *argv[])
{
	// seed RNG (in a shitty way)
	// !!proper seeding needed here!!
	unsigned int rseed = time(NULL);
	void *buf = &rseed;
	RAND_seed(buf, 9);

	/**       Set 6 Challenge 41       **/
	/** RSA unpadded msg oracle attack **/
	rsa_unpadded_msg_oracle_attack_test();

	/**       Set 6 Challenge 42       **/
	/** Bleichenbacher e=3 RSA attack **/
	rsa_simple_pad_test();

	rsa_key_t pik, puk;
	unsigned int sign_len;
	unsigned char *sign;
	unsigned char *sign_hex;

	pik.e = BN_new();
	pik.n = BN_new();
	puk.e = BN_new();
	puk.n = BN_new();

	rsa_generate_keypair(&puk, &pik, 512);

	sign_len = rsa_sign(&sign, "hi mom", 6, &pik);

	hex_encode(&sign_hex, sign, sign_len);

	printf("[s6c2] RSA signature (%d bits): %s\n", sign_len*8, sign_hex);

	if(rsa_sign_verify("hi mom", 6, sign, sign_len, &puk)) {
		printf("[s6c2] RSA signature successfully verified!\n");
	} else {
		printf("[s6c2] RSA signature *NOT* verified!\n");
	}

	free(sign_hex);

	unsigned char *forged_sign = NULL;
	unsigned int forged_sign_len = 0;

	forged_sign_len = rsa_sign_forge(&forged_sign, "hi mom", 6, &puk);

	sign_len = hex_encode(&sign_hex, forged_sign, forged_sign_len);

	printf("[s6c2] Forged RSA signature (%d bits): %s\n", sign_len*8, sign_hex);

	if(rsa_sign_verify("hi mom", 6, forged_sign, forged_sign_len, &puk)) {
		printf("[s6c2] Forged RSA signature successfully verified!\n");
	} else {
		printf("[s6c2] Forged RSA signature *NOT* verified!\n");
	}

	free(forged_sign);
	free(sign_hex);
	free(sign);

	/**      Set 6 Challenge 43     **/
	/** DSA key recovery from nonce **/
	unsigned char sha1sum[41];
	unsigned char *test_msg = "For those that envy a MC it can be hazardous to your health\n\
So be friendly, a matter of life and death, just like a etch-a-sketch\n";

	hash_sha1(sha1sum, test_msg, strlen(test_msg));

	printf("[s6c3] sha1() = %s\n", sha1sum);

	dsa_key_t dsa_puk;
	dsa_key_t dsa_pik;
	dsa_signature_t dsa_sign;

	dsa_puk.g = BN_new();
	dsa_puk.p = BN_new();
	dsa_puk.q = BN_new();
	dsa_puk.xy = BN_new();

	dsa_pik.g = BN_new();
	dsa_pik.p = BN_new();
	dsa_pik.q = BN_new();
	dsa_pik.xy = BN_new();

	dsa_sign.r = BN_new();
	dsa_sign.s = BN_new();

	dsa_generate_keypair(&dsa_puk, &dsa_pik, 256);
	dsa_sha1_sign(&dsa_sign, test_msg, strlen(test_msg), &dsa_pik);
	if(dsa_sha1_sign_verify(test_msg, strlen(test_msg), &dsa_sign, &dsa_puk)) {
		printf("[s6c3] DSA-SHA1 signature successfully verified!\n");
	} else {
		printf("[s6c3] DSA-SHA1 signature *NOT* verified!\n");
	}

	BN_hex2bn(&dsa_puk.xy, "84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4\
bab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004\
e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed\
1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07b\
bb283e6633451e535c45513b2d33c99ea17");
	BN_dec2bn(&dsa_sign.r, "548099063082341131477253921760299949438196259240");
	BN_dec2bn(&dsa_sign.s, "857042759984254168557880549501802188789837994940");

//	BN_print_fp(stdout, dsa_sign.s);
//	printf("\n");

//	BN_dec2bn(&dsa_puk.g, "60");
//	BN_dec2bn(&dsa_puk.p, "283");
//	BN_dec2bn(&dsa_puk.q, "47");
//	BN_dec2bn(&dsa_puk.xy, "158");
//
//	BN_dec2bn(&dsa_sign.r, "19");
//	BN_dec2bn(&dsa_sign.s, "30");

	if(dsa_calc_private_key_from_k_range(&dsa_pik, &dsa_sign, 65536, test_msg, strlen(test_msg), &dsa_puk)) {
		unsigned char *dsa_pik_hex = BN_bn2hex(dsa_pik.xy);
		unsigned int i;

		// convert to lower case
		for(i=0; i<strlen(dsa_pik_hex); i++) {
			dsa_pik_hex[i] = tolower(dsa_pik_hex[i]);
		}
		printf("[s6c3] DSA private key: %s\n", dsa_pik_hex);

		unsigned char dsa_pik_hex_sha1[SHA_DIGEST_LENGTH*2+1];
		hash_sha1(dsa_pik_hex_sha1, dsa_pik_hex, strlen(dsa_pik_hex));
		printf("[s6c3] SHA1(private key): %s\n", dsa_pik_hex_sha1);

		OPENSSL_free(dsa_pik_hex);
	} else {
		printf("[s6c3] DSA private key *NOT* found!\n");
	}

	dsa_signature_free(&dsa_sign);

	/**   Set 6 Challenge 44    **/
	/** DSA nonce recovery from **/
	/**     repeated nonce     **/
	dsa_signature_t sigs[11];
	// input messages
	unsigned char *msgs[] = {
			"Listen for me, you better listen for me now. ",
			"Listen for me, you better listen for me now. ",
			"When me rockin' the microphone me rock on steady, ",
			"Yes a Daddy me Snow me are de article dan. ",
			"But in a in an' a out de dance em ",
			"Aye say where you come from a, ",
			"People em say ya come from Jamaica, ",
			"But me born an' raised in the ghetto that I want yas to know, ",
			"Pure black people mon is all I mon know. ",
			"Yeah me shoes a an tear up an' now me toes is a show a ",
			"Where me a born in are de one Toronto, so "
	};
	// signature r values for msgs
	unsigned char *sig_r[] = {
			"1105520928110492191417703162650245113664610474875",
			"51241962016175933742870323080382366896234169532",
			"228998983350752111397582948403934722619745721541",
			"1099349585689717635654222811555852075108857446485",
			"425320991325990345751346113277224109611205133736",
			"486260321619055468276539425880393574698069264007",
			"537050122560927032962561247064393639163940220795",
			"826843595826780327326695197394862356805575316699",
			"1105520928110492191417703162650245113664610474875",
			"51241962016175933742870323080382366896234169532",
			"228998983350752111397582948403934722619745721541"
	};
	// signature s values for msgs
	unsigned char *sig_s[] = {
			"1267396447369736888040262262183731677867615804316",
			"29097472083055673620219739525237952924429516683",
			"277954141006005142760672187124679727147013405915",
			"1013310051748123261520038320957902085950122277350",
			"203941148183364719753516612269608665183595279549",
			"502033987625712840101435170279955665681605114553",
			"1133410958677785175751131958546453870649059955513",
			"559339368782867010304266546527989050544914568162",
			"1021643638653719618255840562522049391608552714967",
			"506591325247687166499867321330657300306462367256",
			"458429062067186207052865988429747640462282138703"
	};

	unsigned int i, j;
	int identical_nonce[11];
	BIGNUM *k = BN_new();

	// init
	BN_hex2bn(&dsa_puk.xy, "2d026f4bf30195ede3a088da85e398ef869611d0f68f07\
13d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b8\
5519b1c23cc3ecdc6062650462e3063bd179c2a6581519\
f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430\
f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d3\
2971c3de5084cce04a2e147821");

	for(i=0; i<11; i++) {
		sigs[i].r = BN_new();
		sigs[i].s = BN_new();
		BN_dec2bn(&(sigs[i].r), sig_r[i]);
		BN_dec2bn(&(sigs[i].s), sig_s[i]);
		identical_nonce[i] = -1;
	}

	// build array containing info about reused nonces
	for(i=0; i<10; i++) {
		for(j=i+1; j<11; j++) {
			if(!dsa_sign_nonce_cmp(&sigs[i], &sigs[j])) {
				identical_nonce[i] = j;
				break;
			}
		}
//		printf("[s6c4] id[%02d] = %02d\n", i, identical_nonce[i]);
	}

	int success = 0;

	for(i=0; i<11; i++) {
		j = identical_nonce[i];
		if(j >= 0) {
			if((success=dsa_calc_private_key_from_reused_k(&dsa_pik, k, &sigs[i], &sigs[j], msgs[i], strlen(msgs[i]), msgs[j], strlen(msgs[j]), &dsa_puk))) {
				break;
			}
		}
	}

	if(success) {
		unsigned char *dsa_pik_hex = BN_bn2hex(dsa_pik.xy);

		// convert to lower case
		for(i=0; i<strlen(dsa_pik_hex); i++) {
			dsa_pik_hex[i] = tolower(dsa_pik_hex[i]);
		}

		printf("[s6c4] k = ");
		BN_print_fp(stdout, k);
		printf("\n[s6c4] DSA private key: %s\n", dsa_pik_hex);

		unsigned char dsa_pik_hex_sha1[SHA_DIGEST_LENGTH*2+1];
		hash_sha1(dsa_pik_hex_sha1, dsa_pik_hex, strlen(dsa_pik_hex));
		printf("[s6c4] SHA1(private key): %s\n", dsa_pik_hex_sha1);

		OPENSSL_free(dsa_pik_hex);
	} else {
		printf("[s6c3] DSA private key *NOT* found!\n");
	}

	// free
	for(i=0; i<11; i++) {
		dsa_signature_free(&sigs[i]);
	}

	BN_free(k);

	dsa_key_free(&dsa_puk);
	dsa_key_free(&dsa_pik);

	return 0;
}
コード例 #3
0
ファイル: pk.c プロジェクト: intgr/gnutls
static int
wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo,
                                unsigned int level /*bits */ ,
                                gnutls_pk_params_st * params)
{
  int ret;
  unsigned int i, q_bits;

  memset(params, 0, sizeof(*params));

  switch (algo)
    {

    case GNUTLS_PK_DSA:
      {
        struct dsa_public_key pub;
        struct dsa_private_key priv;

        dsa_public_key_init (&pub);
        dsa_private_key_init (&priv);

        /* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
         * but we do NIST DSA here */
        if (level <= 1024)
          q_bits = 160;
        else
          q_bits = 256;

        ret =
          dsa_generate_keypair (&pub, &priv, NULL,
                                rnd_func, NULL, NULL, level, q_bits);
        if (ret != 1)
          {
            gnutls_assert ();
            ret = GNUTLS_E_INTERNAL_ERROR;
            goto dsa_fail;
          }

        params->params_nr = 0;
        for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like (&pub.p);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto dsa_fail;
              }
            params->params_nr++;
          }

        ret = 0;
        _gnutls_mpi_set (params->params[0], pub.p);
        _gnutls_mpi_set (params->params[1], pub.q);
        _gnutls_mpi_set (params->params[2], pub.g);
        _gnutls_mpi_set (params->params[3], pub.y);
        _gnutls_mpi_set (params->params[4], priv.x);

dsa_fail:
        dsa_private_key_clear (&priv);
        dsa_public_key_clear (&pub);

        if (ret < 0)
          goto fail;

        break;
      }
    case GNUTLS_PK_RSA:
      {
        struct rsa_public_key pub;
        struct rsa_private_key priv;

        rsa_public_key_init (&pub);
        rsa_private_key_init (&priv);

        _gnutls_mpi_set_ui (&pub.e, 65537);

        ret =
          rsa_generate_keypair (&pub, &priv, NULL,
                                rnd_func, NULL, NULL, level, 0);
        if (ret != 1)
          {
            gnutls_assert ();
            ret = GNUTLS_E_INTERNAL_ERROR;
            goto rsa_fail;
          }

        params->params_nr = 0;
        for (i = 0; i < RSA_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like (&pub.n);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto rsa_fail;
              }
            params->params_nr++;

          }
          
        ret = 0;

        _gnutls_mpi_set (params->params[0], pub.n);
        _gnutls_mpi_set (params->params[1], pub.e);
        _gnutls_mpi_set (params->params[2], priv.d);
        _gnutls_mpi_set (params->params[3], priv.p);
        _gnutls_mpi_set (params->params[4], priv.q);
        _gnutls_mpi_set (params->params[5], priv.c);
        _gnutls_mpi_set (params->params[6], priv.a);
        _gnutls_mpi_set (params->params[7], priv.b);

rsa_fail:
        rsa_private_key_clear (&priv);
        rsa_public_key_clear (&pub);

        if (ret < 0)
          goto fail;

        break;
      }
    case GNUTLS_PK_EC:
      {
        ecc_key key;
        ecc_set_type tls_ecc_set;
        const gnutls_ecc_curve_entry_st *st;

        st = _gnutls_ecc_curve_get_params(level);
        if (st == NULL)
          return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
        
        tls_ecc_set.size = st->size;
        tls_ecc_set.prime = st->prime;
        tls_ecc_set.order = st->order;
        tls_ecc_set.Gx = st->Gx;
        tls_ecc_set.Gy = st->Gy;
        tls_ecc_set.A = st->A;
        tls_ecc_set.B = st->B;

        ret = ecc_make_key(NULL, rnd_func, &key, &tls_ecc_set, st->id);
        if (ret != 0)
          return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

        params->params_nr = 0;
        for (i = 0; i < ECC_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like(&key.prime);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto ecc_fail;
              }
            params->params_nr++;
          }
        params->flags = level;

        mpz_set(TOMPZ(params->params[ECC_PRIME]), key.prime);
        mpz_set(TOMPZ(params->params[ECC_ORDER]), key.order);
        mpz_set(TOMPZ(params->params[ECC_A]), key.A);
        mpz_set(TOMPZ(params->params[ECC_B]), key.B);
        mpz_set(TOMPZ(params->params[ECC_GX]), key.Gx);
        mpz_set(TOMPZ(params->params[ECC_GY]), key.Gy);
        mpz_set(TOMPZ(params->params[ECC_X]), key.pubkey.x);
        mpz_set(TOMPZ(params->params[ECC_Y]), key.pubkey.y);
        mpz_set(TOMPZ(params->params[ECC_K]), key.k);
        
ecc_fail:
        ecc_free(&key);
        
        if (ret < 0)
          goto fail;

        break;
      }
    default:
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  return 0;

fail:

  for (i = 0; i < params->params_nr; i++)
    {
      _gnutls_mpi_release (&params->params[i]);
    }
  params->params_nr = 0;

  return ret;
}
コード例 #4
0
ファイル: pk.c プロジェクト: randombit/hacrypto
static int
wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
			       unsigned int level /*bits */ ,
			       gnutls_pk_params_st * params)
{
	int ret;
	unsigned int i, q_bits;

	memset(params, 0, sizeof(*params));

	switch (algo) {

	case GNUTLS_PK_DSA:
		{
			struct dsa_public_key pub;
			struct dsa_private_key priv;

			dsa_public_key_init(&pub);
			dsa_private_key_init(&priv);

			/* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
			 * but we do NIST DSA here */
			if (level <= 1024)
				q_bits = 160;
			else
				q_bits = 256;

			ret =
			    dsa_generate_keypair(&pub, &priv, NULL,
						 rnd_func, NULL, NULL,
						 level, q_bits);
			if (ret != 1) {
				gnutls_assert();
				ret = GNUTLS_E_INTERNAL_ERROR;
				goto dsa_fail;
			}

			params->params_nr = 0;
			for (i = 0; i < DSA_PRIVATE_PARAMS; i++) {
				params->params[i] =
				    _gnutls_mpi_alloc_like(&pub.p);
				if (params->params[i] == NULL) {
					ret = GNUTLS_E_MEMORY_ERROR;
					goto dsa_fail;
				}
				params->params_nr++;
			}

			ret = 0;
			_gnutls_mpi_set(params->params[0], pub.p);
			_gnutls_mpi_set(params->params[1], pub.q);
			_gnutls_mpi_set(params->params[2], pub.g);
			_gnutls_mpi_set(params->params[3], pub.y);
			_gnutls_mpi_set(params->params[4], priv.x);

		      dsa_fail:
			dsa_private_key_clear(&priv);
			dsa_public_key_clear(&pub);

			if (ret < 0)
				goto fail;

			break;
		}
	case GNUTLS_PK_RSA:
		{
			struct rsa_public_key pub;
			struct rsa_private_key priv;

			rsa_public_key_init(&pub);
			rsa_private_key_init(&priv);

			_gnutls_mpi_set_ui(&pub.e, 65537);

			ret =
			    rsa_generate_keypair(&pub, &priv, NULL,
						 rnd_func, NULL, NULL,
						 level, 0);
			if (ret != 1) {
				gnutls_assert();
				ret = GNUTLS_E_INTERNAL_ERROR;
				goto rsa_fail;
			}

			params->params_nr = 0;
			for (i = 0; i < RSA_PRIVATE_PARAMS; i++) {
				params->params[i] =
				    _gnutls_mpi_alloc_like(&pub.n);
				if (params->params[i] == NULL) {
					ret = GNUTLS_E_MEMORY_ERROR;
					goto rsa_fail;
				}
				params->params_nr++;

			}

			ret = 0;

			_gnutls_mpi_set(params->params[0], pub.n);
			_gnutls_mpi_set(params->params[1], pub.e);
			_gnutls_mpi_set(params->params[2], priv.d);
			_gnutls_mpi_set(params->params[3], priv.p);
			_gnutls_mpi_set(params->params[4], priv.q);
			_gnutls_mpi_set(params->params[5], priv.c);
			_gnutls_mpi_set(params->params[6], priv.a);
			_gnutls_mpi_set(params->params[7], priv.b);

		      rsa_fail:
			rsa_private_key_clear(&priv);
			rsa_public_key_clear(&pub);

			if (ret < 0)
				goto fail;

			break;
		}
	case GNUTLS_PK_EC:
		{
			struct ecc_scalar key;
			struct ecc_point pub;
			const struct ecc_curve *curve;

			curve = get_supported_curve(level);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ecc_scalar_init(&key, curve);
			ecc_point_init(&pub, curve);

			ecdsa_generate_keypair(&pub, &key, NULL, rnd_func);

			params->params[ECC_X] = _gnutls_mpi_new(0);
			params->params[ECC_Y] = _gnutls_mpi_new(0);
			params->params[ECC_K] = _gnutls_mpi_new(0);

			if (params->params[ECC_X] == NULL
			    || params->params[ECC_Y] == NULL
			    || params->params[ECC_K] == NULL) {
				_gnutls_mpi_release(&params->
						    params[ECC_X]);
				_gnutls_mpi_release(&params->
						    params[ECC_Y]);
				_gnutls_mpi_release(&params->
						    params[ECC_K]);
				goto ecc_cleanup;
			}

			params->flags = level;
			params->params_nr = ECC_PRIVATE_PARAMS;

			ecc_point_get(&pub, TOMPZ(params->params[ECC_X]),
				      TOMPZ(params->params[ECC_Y]));
			ecc_scalar_get(&key, TOMPZ(params->params[ECC_K]));

		      ecc_cleanup:
			ecc_point_clear(&pub);
			ecc_scalar_clear(&key);

			break;
		}
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	return 0;

      fail:

	for (i = 0; i < params->params_nr; i++) {
		_gnutls_mpi_release(&params->params[i]);
	}
	params->params_nr = 0;

	return ret;
}
コード例 #5
0
ファイル: pk.c プロジェクト: Drakey83/steamlink-sdk
/* Generates algorithm's parameters. That is:
 *  For DSA: p, q, and g are generated.
 *  For RSA: nothing
 *  For ECDSA: just checks the curve is ok
 */
static int
wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
			       unsigned int level /*bits or curve*/ ,
			       gnutls_pk_params_st * params)
{
	int ret;
	unsigned int i, q_bits;

	params->algo = algo;

	switch (algo) {
	case GNUTLS_PK_DSA:
	case GNUTLS_PK_DH:
		{
			struct dsa_public_key pub;
			struct dsa_private_key priv;
#ifdef ENABLE_FIPS140
			struct dss_params_validation_seeds cert;
			unsigned index;
#endif

			dsa_public_key_init(&pub);
			dsa_private_key_init(&priv);

			if (GNUTLS_BITS_HAVE_SUBGROUP(level)) {
				q_bits = GNUTLS_BITS_TO_SUBGROUP(level);
				level = GNUTLS_BITS_TO_GROUP(level);
			} else {
				q_bits = _gnutls_pk_bits_to_subgroup_bits(level);
			}

			if (q_bits == 0)
				return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);

#ifdef ENABLE_FIPS140
			if (algo==GNUTLS_PK_DSA)
				index = 1;
			else
				index = 2;

			ret =
			    dsa_generate_dss_pqg(&pub, &cert,
			    			 index,
						 NULL, rnd_func, 
						 NULL, NULL,
						 level, q_bits);
			if (ret != 1) {
				gnutls_assert();
				ret = GNUTLS_E_PK_GENERATION_ERROR;
				goto dsa_fail;
			}

			/* verify the generated parameters */
			ret = dsa_validate_dss_pqg(&pub, &cert, index);
			if (ret != 1) {
				gnutls_assert();
				ret = GNUTLS_E_PK_GENERATION_ERROR;
				goto dsa_fail;
			}
#else
			/* unfortunately nettle only accepts 160 or 256
			 * q_bits size. The check below makes sure we handle
			 * cases in between by rounding up, but fail when
			 * larger numbers are requested. */
			if (q_bits < 160)
				q_bits = 160;
			else if (q_bits > 160 && q_bits <= 256)
				q_bits = 256;
			ret =
			    dsa_generate_keypair(&pub, &priv,
						 NULL, rnd_func, 
						 NULL, NULL,
						 level, q_bits);
			if (ret != 1) {
				gnutls_assert();
				ret = GNUTLS_E_PK_GENERATION_ERROR;
				goto dsa_fail;
			}
#endif

			params->params_nr = 0;

			ret = _gnutls_mpi_init_multi(&params->params[DSA_P], &params->params[DSA_Q],
					&params->params[DSA_G], NULL);
			if (ret < 0) {
				gnutls_assert();
				goto dsa_fail;
			}
			params->params_nr = 3;

			mpz_set(TOMPZ(params->params[DSA_P]), pub.p);
			mpz_set(TOMPZ(params->params[DSA_Q]), pub.q);
			mpz_set(TOMPZ(params->params[DSA_G]), pub.g);

			ret = 0;

		      dsa_fail:
			dsa_private_key_clear(&priv);
			dsa_public_key_clear(&pub);

			if (ret < 0)
				goto fail;

			break;
		}
	case GNUTLS_PK_RSA:
	case GNUTLS_PK_EC:
		ret = 0;
		break;
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	FAIL_IF_LIB_ERROR;
	return 0;

      fail:

	for (i = 0; i < params->params_nr; i++) {
		_gnutls_mpi_release(&params->params[i]);
	}
	params->params_nr = 0;

	FAIL_IF_LIB_ERROR;
	return ret;
}