Exemple #1
0
void _gnutls_x509_privkey_reinit(gnutls_x509_privkey_t key)
{
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);
	asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
	key->key = ASN1_TYPE_EMPTY;
}
Exemple #2
0
int _gnutls_dh_compute_key(gnutls_dh_params_t dh_params,
			   const gnutls_datum_t *priv_key, const gnutls_datum_t *pub_key,
			   const gnutls_datum_t *peer_key, gnutls_datum_t *Z)
{
	gnutls_pk_params_st pub, priv;
	int ret;

	gnutls_pk_params_init(&pub);
	gnutls_pk_params_init(&priv);
	pub.algo = GNUTLS_PK_DH;

	if (_gnutls_mpi_init_scan_nz
		    (&pub.params[DH_Y], peer_key->data,
		     peer_key->size) != 0) {
		ret =
		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
		goto cleanup;
	}

	priv.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]);
	priv.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]);

	if (_gnutls_mpi_init_scan_nz
		    (&priv.params[DH_X], priv_key->data,
		     priv_key->size) != 0) {
		ret =
		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
		goto cleanup;
	}

	priv.params_nr = 3; /* include empty q */
	priv.algo = GNUTLS_PK_DH;

	Z->data = NULL;

	ret = _gnutls_pk_derive(GNUTLS_PK_DH, Z, &priv, &pub);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = 0;
 cleanup:
 	gnutls_pk_params_clear(&pub);
 	gnutls_pk_params_clear(&priv);
 	return ret;
}
Exemple #3
0
/**
 * gnutls_x509_privkey_generate:
 * @key: should contain a #gnutls_x509_privkey_t structure
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
 * @bits: the size of the modulus
 * @flags: unused for now.  Must be 0.
 *
 * This function will generate a random private key. Note that this
 * function must be called on an empty private key.
 *
 * Note that when generating an elliptic curve key, the curve
 * can be substituted in the place of the bits parameter using the
 * GNUTLS_CURVE_TO_BITS() macro.
 *
 * For DSA keys, if the subgroup size needs to be specified check
 * the GNUTLS_SUBGROUP_TO_BITS() macro.
 *
 * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
			     gnutls_pk_algorithm_t algo, unsigned int bits,
			     unsigned int flags)
{
	int ret;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	gnutls_pk_params_init(&key->params);

	if (algo == GNUTLS_PK_EC) {
		if (GNUTLS_BITS_ARE_CURVE(bits))
			bits = GNUTLS_BITS_TO_CURVE(bits);
		else
			bits = _gnutls_ecc_bits_to_curve(bits);
	}

	ret = _gnutls_pk_generate_params(algo, bits, &key->params);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_pk_generate_keys(algo, bits, &key->params);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

#ifndef ENABLE_FIPS140
	ret = _gnutls_pk_verify_priv_params(algo, &key->params);
#else
	ret = pct_test(algo, &key->params);
#endif
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_asn1_encode_privkey(algo, &key->key, &key->params);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}
	key->pk_algorithm = algo;

	return 0;

      cleanup:
	key->pk_algorithm = GNUTLS_PK_UNKNOWN;
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);

	return ret;
}
Exemple #4
0
/*-
 * _gnutls_openpgp_privkey_decrypt_data:
 * @key: Holds the key
 * @flags: (0) for now
 * @ciphertext: holds the data to be decrypted
 * @plaintext: will contain newly allocated plaintext
 *
 * This function will sign the given hash using the private key.  You
 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
 * calling this function to set the subkey to use.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 -*/
int
_gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
                                     unsigned int flags,
                                     const gnutls_datum_t * ciphertext,
                                     gnutls_datum_t * plaintext)
{
  int result, i;
  gnutls_pk_params_st params;
  int pk_algorithm;
  uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
  char buf[2*GNUTLS_OPENPGP_KEYID_SIZE+1];

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
  if (result == 0)
    {
      uint32_t kid[2];

      KEYID_IMPORT (kid, keyid);

      _gnutls_hard_log("Decrypting using PGP key ID %s\n", _gnutls_bin2hex(keyid, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL));

      result = _gnutls_openpgp_privkey_get_mpis (key, kid, &params);

      i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);

      pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
    }
  else
    {
      _gnutls_hard_log("Decrypting using master PGP key\n");

      pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);

      result = _gnutls_openpgp_privkey_get_mpis (key, NULL, &params);

    }

  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  result = _gnutls_pk_decrypt (pk_algorithm, plaintext, ciphertext, &params);

  gnutls_pk_params_clear(&params);
  gnutls_pk_params_release(&params);

  if (result < 0)
    return gnutls_assert_val(result);

  return 0;
}
Exemple #5
0
int
_gnutls_gen_dh_common_client_kx_int(gnutls_session_t session,
				    gnutls_buffer_st * data,
				    gnutls_datum_t * pskkey)
{
	int ret;
	gnutls_pk_params_st peer_pub;
	gnutls_datum_t tmp_dh_key = {NULL, 0};
	
	gnutls_pk_params_init(&peer_pub);

	ret =
	    _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0,
				     &session->key.dh_params, 1);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X]));

	ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	
	peer_pub.params[DH_Y] = session->key.client_Y;

	/* calculate the key after calculating the message */
	ret = _gnutls_pk_derive(GNUTLS_PK_DH, &tmp_dh_key, &session->key.dh_params, &peer_pub);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (_gnutls_cipher_suite_get_kx_algo
	    (session->security_parameters.cipher_suite)
	    != GNUTLS_KX_DHE_PSK) {
		session->key.key.data = tmp_dh_key.data;
		session->key.key.size = tmp_dh_key.size;
	} else {		/* In DHE_PSK the key is set differently */
		ret =
		    _gnutls_set_psk_session_key(session, pskkey,
						&tmp_dh_key);
		_gnutls_free_temp_key_datum(&tmp_dh_key);
	}

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = data->length;

 error:
	gnutls_pk_params_clear(&session->key.dh_params);
	return ret;
}
Exemple #6
0
int _gnutls_ecdh_generate_key(gnutls_ecc_curve_t curve,
			      gnutls_datum_t *x, gnutls_datum_t *y,
			      gnutls_datum_t *k)
{
	gnutls_pk_params_st params;
	int ret;

	gnutls_pk_params_init(&params);
	params.flags = curve;
	params.algo = GNUTLS_PK_EC;

	x->data = NULL;
	y->data = NULL;
	k->data = NULL;

	ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, &params);
	if (ret < 0) {
		return gnutls_assert_val(ret);
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[ECC_X], x);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[ECC_Y], y);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[ECC_K], k);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret = 0;
	goto cleanup;
 fail:
 	gnutls_free(y->data);
 	gnutls_free(x->data);
 	gnutls_free(k->data);
 cleanup:
 	gnutls_pk_params_clear(&params);
 	return ret;
}
Exemple #7
0
/**
 * gnutls_x509_privkey_import_ecc_raw:
 * @key: The structure to store the parsed key
 * @curve: holds the curve
 * @x: holds the x
 * @y: holds the y
 * @k: holds the k
 *
 * This function will convert the given elliptic curve parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored
 * in @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0
 **/
int
gnutls_x509_privkey_import_ecc_raw(gnutls_x509_privkey_t key,
				   gnutls_ecc_curve_t curve,
				   const gnutls_datum_t * x,
				   const gnutls_datum_t * y,
				   const gnutls_datum_t * k)
{
	int ret;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	key->params.flags = curve;

	if (_gnutls_mpi_init_scan_nz
	    (&key->params.params[ECC_X], x->data, x->size)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	if (_gnutls_mpi_init_scan_nz
	    (&key->params.params[ECC_Y], y->data, y->size)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	if (_gnutls_mpi_init_scan_nz
	    (&key->params.params[ECC_K], k->data, k->size)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	key->pk_algorithm = GNUTLS_PK_EC;

	return 0;

      cleanup:
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);
	return ret;

}
Exemple #8
0
int
_gnutls_gen_ecdh_common_client_kx_int(gnutls_session_t session,
				      gnutls_buffer_st * data,
				      gnutls_datum_t * psk_key)
{
	int ret;
	gnutls_datum_t out;
	int curve = _gnutls_session_ecc_curve_get(session);

	/* generate temporal key */
	ret =
	    _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve,
				     &session->key.ecdh_params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret =
	    _gnutls_ecc_ansi_x963_export(curve,
					 session->key.ecdh_params.
					 params[ECC_X] /* x */ ,
					 session->key.ecdh_params.
					 params[ECC_Y] /* y */ , &out);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_buffer_append_data_prefix(data, 8, out.data, out.size);

	_gnutls_free_datum(&out);

	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* generate pre-shared key */
	ret = calc_ecdh_key(session, psk_key, curve);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = data->length;
cleanup:
      	gnutls_pk_params_clear(&session->key.ecdh_params);
	return ret;
}
Exemple #9
0
int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params,
			    gnutls_datum_t *priv_key, gnutls_datum_t *pub_key)
{
	gnutls_pk_params_st params;
	int ret;

	gnutls_pk_params_init(&params);
	params.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]);
	params.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]);

	params.params_nr = 3; /* include empty q */
	params.algo = GNUTLS_PK_DH;

	priv_key->data = NULL;
	pub_key->data = NULL;

	ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, &params);
	if (ret < 0) {
		return gnutls_assert_val(ret);
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[DH_X], priv_key);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[DH_Y], pub_key);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret = 0;
	goto cleanup;
 fail:
 	gnutls_free(pub_key->data);
 	gnutls_free(priv_key->data);
 cleanup:
 	gnutls_pk_params_clear(&params);
 	return ret;
}
Exemple #10
0
int _gnutls_proc_ecdh_common_client_kx(gnutls_session_t session,
				       uint8_t * data, size_t _data_size,
				       gnutls_ecc_curve_t curve,
				       gnutls_datum_t * psk_key)
{
	ssize_t data_size = _data_size;
	int ret, i = 0;
	int point_size;

	if (curve == GNUTLS_ECC_CURVE_INVALID)
		return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);

	DECR_LEN(data_size, 1);
	point_size = data[i];
	i += 1;

	DECR_LEN(data_size, point_size);
	ret =
	    _gnutls_ecc_ansi_x963_import(&data[i], point_size,
					 &session->key.ecdh_x,
					 &session->key.ecdh_y);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* generate pre-shared key */
	ret = calc_ecdh_key(session, psk_key, curve);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

cleanup:
      	gnutls_pk_params_clear(&session->key.ecdh_params);
	return ret;
}
Exemple #11
0
int
_gnutls_proc_dh_common_client_kx(gnutls_session_t session,
				 uint8_t * data, size_t _data_size,
				 bigint_t g, bigint_t p,
				 gnutls_datum_t * psk_key)
{
	uint16_t n_Y;
	size_t _n_Y;
	int ret;
	ssize_t data_size = _data_size;
	gnutls_datum_t tmp_dh_key = {NULL, 0};
	gnutls_pk_params_st peer_pub;
	
	gnutls_pk_params_init(&peer_pub);

	DECR_LEN(data_size, 2);
	n_Y = _gnutls_read_uint16(&data[0]);
	_n_Y = n_Y;

	DECR_LEN(data_size, n_Y);

	if (data_size != 0)
		return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);

	if (_gnutls_mpi_init_scan_nz(&session->key.client_Y, &data[2], _n_Y)) {
		gnutls_assert();
		return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; /* most likely zero or illegal size */
	}

	_gnutls_dh_set_peer_public(session, session->key.client_Y);

	peer_pub.params[DH_Y] = session->key.client_Y;

	/* calculate the key after calculating the message */
	ret = _gnutls_pk_derive(GNUTLS_PK_DH, &tmp_dh_key, &session->key.dh_params, &peer_pub);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (psk_key == NULL) {
		session->key.key.data = tmp_dh_key.data;
		session->key.key.size = tmp_dh_key.size;
	} else {		/* In DHE_PSK the key is set differently */
		ret =
		    _gnutls_set_psk_session_key(session, psk_key,
						&tmp_dh_key);
		_gnutls_free_temp_key_datum(&tmp_dh_key);
	}
	
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = 0;
 error:
	_gnutls_mpi_release(&session->key.client_Y);
	gnutls_pk_params_clear(&session->key.dh_params);

	return ret;
}
Exemple #12
0
/* Converts an ECC key to
 * an internal structure (gnutls_private_key)
 */
int
_gnutls_privkey_decode_ecc_key(ASN1_TYPE* pkey_asn, const gnutls_datum_t * raw_key,
			       gnutls_x509_privkey_t pkey, gnutls_ecc_curve_t curve)
{
	int ret;
	unsigned int version;
	char oid[MAX_OID_SIZE];
	int oid_size;
	gnutls_datum out;

	gnutls_pk_params_init(&pkey->params);

	pkey->params.algo = GNUTLS_PK_EC;
	if ((ret =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.ECPrivateKey",
				 pkey_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(ret);
	}

	ret =
	    asn1_der_decoding(pkey_asn, raw_key->data, raw_key->size,
			      NULL);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(ret);
		goto error;
	}

	ret = _gnutls_x509_read_uint(*pkey_asn, "Version", &version);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (version != 1) {
		_gnutls_debug_log
		    ("ECC private key version %u is not supported\n",
		     version);
		gnutls_assert();
		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
		goto error;
	}

	/* read the curve */
	if (curve == GNUTLS_ECC_CURVE_INVALID) {
		oid_size = sizeof(oid);
		ret =
		    asn1_read_value(*pkey_asn, "parameters.namedCurve", oid,
			    &oid_size);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		pkey->params.flags = _gnutls_oid_to_ecc_curve(oid);

		if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID) {
			_gnutls_debug_log("Curve %s is not supported\n", oid);
			gnutls_assert();
			ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
			goto error;
		}
	} else {
		pkey->params.flags = curve;
	}


	/* read the public key */
	ret = _gnutls_x509_read_value(*pkey_asn, "publicKey", &out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_ecc_ansi_x963_import(out.data, out.size,
					 &pkey->params.params[ECC_X],
					 &pkey->params.params[ECC_Y]);

	_gnutls_free_datum(&out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr += 2;

	/* read the private key */
	ret =
	    _gnutls_x509_read_key_int(*pkey_asn, "privateKey",
				  &pkey->params.params[ECC_K]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	return 0;

      error:
	asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);
	return ret;

}
Exemple #13
0
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
 */
static int
_gnutls_asn1_encode_rsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
{
    int result, ret;
    uint8_t null = '\0';
    gnutls_pk_params_st pk_params;

    /* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
     * i.e., regenerate some parameters in case they were broken */
    gnutls_pk_params_init(&pk_params);

    ret = _gnutls_pk_params_copy(&pk_params, params);
    if (ret < 0) {
        gnutls_assert();
        return ret;
    }

    ret =
        _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    /* Ok. Now we have the data. Create the asn1 structures
     */

    /* first make sure that no previously allocated data are leaked */
    if (*c2 != ASN1_TYPE_EMPTY) {
        asn1_delete_structure(c2);
        *c2 = ASN1_TYPE_EMPTY;
    }

    if ((result = asn1_create_element
                  (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", c2))
            != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    /* Write PRIME
     */
    ret =
        _gnutls_x509_write_int(*c2, "modulus",
                               params->params[RSA_MODULUS], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_int(*c2, "publicExponent",
                               params->params[RSA_PUB], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "privateExponent",
                                   params->params[RSA_PRIV], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "prime1",
                                   params->params[RSA_PRIME1], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "prime2",
                                   params->params[RSA_PRIME2], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "coefficient",
                                   params->params[RSA_COEF], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "exponent1",
                                   params->params[RSA_E1], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "exponent2",
                                   params->params[RSA_E2], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    if ((result = asn1_write_value(*c2, "otherPrimeInfos",
                                   NULL, 0)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    if ((result =
                asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    ret = 0;

cleanup:
    if (ret < 0)
        asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);

    gnutls_pk_params_clear(&pk_params);
    gnutls_pk_params_release(&pk_params);
    return ret;
}
Exemple #14
0
static ASN1_TYPE
decode_dsa_key(const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
{
	int result;
	ASN1_TYPE dsa_asn;

	if ((result =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.DSAPrivateKey",
				 &dsa_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return NULL;
	}

	gnutls_pk_params_init(&pkey->params);

	pkey->params.algo = GNUTLS_PK_DSA;

	result =
	    asn1_der_decoding(&dsa_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		goto error;
	}

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "p",
				   &pkey->params.params[0])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "q",
				   &pkey->params.params[1])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "g",
				   &pkey->params.params[2])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "Y",
				   &pkey->params.params[3])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(dsa_asn, "priv",
					    &pkey->params.params[4])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	return dsa_asn;

      error:
	asn1_delete_structure2(&dsa_asn, ASN1_DELETE_FLAG_ZEROIZE);
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);
	return NULL;

}
Exemple #15
0
/**
 * gnutls_x509_privkey_import_rsa_raw2:
 * @key: The structure to store the parsed key
 * @m: holds the modulus
 * @e: holds the public exponent
 * @d: holds the private exponent
 * @p: holds the first prime (p)
 * @q: holds the second prime (q)
 * @u: holds the coefficient (optional)
 * @e1: holds e1 = d mod (p-1) (optional)
 * @e2: holds e2 = d mod (q-1) (optional)
 *
 * This function will convert the given RSA raw parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored in
 * @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_rsa_raw2(gnutls_x509_privkey_t key,
				    const gnutls_datum_t * m,
				    const gnutls_datum_t * e,
				    const gnutls_datum_t * d,
				    const gnutls_datum_t * p,
				    const gnutls_datum_t * q,
				    const gnutls_datum_t * u,
				    const gnutls_datum_t * e1,
				    const gnutls_datum_t * e2)
{
	int ret;
	size_t siz = 0;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	gnutls_pk_params_init(&key->params);

	siz = m->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[0], m->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	siz = e->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[1], e->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	siz = d->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[2], d->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	siz = p->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[3], p->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	siz = q->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[4], q->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}
	key->params.params_nr++;

	if (u) {
		siz = u->size;
		if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_COEF], u->data, siz)) {
			gnutls_assert();
			ret = GNUTLS_E_MPI_SCAN_FAILED;
			goto cleanup;
		}
		key->params.params_nr++;
	}

	if (e1 && e2) {
		siz = e1->size;
		if (_gnutls_mpi_init_scan_nz
		    (&key->params.params[RSA_E1], e1->data, siz)) {
			gnutls_assert();
			ret = GNUTLS_E_MPI_SCAN_FAILED;
			goto cleanup;
		}
		key->params.params_nr++;

		siz = e2->size;
		if (_gnutls_mpi_init_scan_nz
		    (&key->params.params[RSA_E2], e2->data, siz)) {
			gnutls_assert();
			ret = GNUTLS_E_MPI_SCAN_FAILED;
			goto cleanup;
		}
		key->params.params_nr++;
	}

	ret = _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_asn1_encode_privkey(GNUTLS_PK_RSA, &key->key,
					&key->params);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	key->params.params_nr = RSA_PRIVATE_PARAMS;
	key->pk_algorithm = GNUTLS_PK_RSA;

	return 0;

      cleanup:
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);
	return ret;

}
Exemple #16
0
/* Extracts DSA and RSA parameters from a certificate.
 */
int
_gnutls_openpgp_privkey_get_mpis(gnutls_openpgp_privkey_t pkey,
				 uint32_t * keyid /*[2] */ ,
				 gnutls_pk_params_st * params)
{
	int result;
	unsigned int i, pk_algorithm;
	cdk_packet_t pkt;
	unsigned total;

	gnutls_pk_params_init(params);

	if (keyid == NULL)
		pkt =
		    cdk_kbnode_find_packet(pkey->knode,
					   CDK_PKT_SECRET_KEY);
	else
		pkt = _gnutls_openpgp_find_key(pkey->knode, keyid, 1);

	if (pkt == NULL) {
		gnutls_assert();
		return GNUTLS_E_OPENPGP_GETKEY_FAILED;
	}

	pk_algorithm =
	    _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo);

	switch (pk_algorithm) {
	case GNUTLS_PK_RSA:
		/* openpgp does not hold all parameters as in PKCS #1
		 */
		total = RSA_PRIVATE_PARAMS - 2;
		break;
	case GNUTLS_PK_DSA:
		total = DSA_PRIVATE_PARAMS;
		break;
	default:
		gnutls_assert();
		return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
	}

	for (i = 0; i < total; i++) {
		result =
		    _gnutls_read_pgp_mpi(pkt, 1, i, &params->params[i]);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}
		params->params_nr++;
	}

	/* fixup will generate exp1 and exp2 that are not
	 * available here.
	 */
	result = _gnutls_pk_fixup(pk_algorithm, GNUTLS_IMPORT, params);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	return 0;

      error:
	gnutls_pk_params_clear(params);
	gnutls_pk_params_release(params);

	return result;
}
Exemple #17
0
/* Decodes a GOST privateKey from a PKCS8 structure.
 */
static int
_decode_pkcs8_gost_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey,
		       gnutls_pk_algorithm_t algo)
{
	int ret;
	gnutls_datum_t tmp;
	unsigned char oid[3 * MAX_OID_SIZE]; /* GOST parameters can have 3 OIDs at most */
	int len, result;

	gnutls_pk_params_init(&pkey->params);

	len = sizeof(oid);
	result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters",
				 oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto error;
	} else {
		ret = _gnutls_x509_read_gost_params(oid, len, &pkey->params, algo);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	}

	/* Will be fixed later by pk_fixup */
	ret = _gnutls_mpi_init(&pkey->params.params[GOST_X]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	ret = _gnutls_mpi_init(&pkey->params.params[GOST_Y]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	_gnutls_mpi_set_ui(pkey->params.params[GOST_X], 0);
	_gnutls_mpi_set_ui(pkey->params.params[GOST_Y], 0);

	ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _privkey_decode_gost_key(&tmp, pkey);
	_gnutls_free_key_datum(&tmp);

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->params.algo = algo;

	return 0;

error:
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);

	return ret;
}
Exemple #18
0
/**
 * gnutls_x509_privkey_import_dsa_raw:
 * @key: The structure to store the parsed key
 * @p: holds the p
 * @q: holds the q
 * @g: holds the g
 * @y: holds the y
 * @x: holds the x
 *
 * This function will convert the given DSA raw parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored
 * in @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,
				   const gnutls_datum_t * p,
				   const gnutls_datum_t * q,
				   const gnutls_datum_t * g,
				   const gnutls_datum_t * y,
				   const gnutls_datum_t * x)
{
	int ret;
	size_t siz = 0;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	siz = p->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[0], p->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	siz = q->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[1], q->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	siz = g->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[2], g->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	siz = y->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[3], y->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	siz = x->size;
	if (_gnutls_mpi_init_scan_nz(&key->params.params[4], x->data, siz)) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	ret =
	    _gnutls_asn1_encode_privkey(GNUTLS_PK_DSA, &key->key,
					&key->params);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	key->params.params_nr = DSA_PRIVATE_PARAMS;
	key->pk_algorithm = GNUTLS_PK_DSA;

	return 0;

      cleanup:
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);
	return ret;

}
Exemple #19
0
/**
 * gnutls_openpgp_privkey_sign_hash:
 * @key: Holds the key
 * @hash: holds the data to be signed
 * @signature: will contain newly allocated signature
 *
 * This function will sign the given hash using the private key.  You
 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
 * calling this function to set the subkey to use.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Deprecated: Use gnutls_privkey_sign_hash() instead.
 */
int
gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key,
				 const gnutls_datum_t * hash,
				 gnutls_datum_t * signature)
{
	int result;
	gnutls_pk_params_st params;
	int pk_algorithm;
	uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
	char buf[2 * GNUTLS_OPENPGP_KEYID_SIZE + 1];

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	result = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid);
	if (result == 0) {
		uint32_t kid[2];
		int idx;

		KEYID_IMPORT(kid, keyid);

		_gnutls_hard_log("Signing using PGP key ID %s\n",
				 _gnutls_bin2hex(keyid,
						 GNUTLS_OPENPGP_KEYID_SIZE,
						 buf, sizeof(buf), NULL));

		idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid);
		pk_algorithm =
		    gnutls_openpgp_privkey_get_subkey_pk_algorithm(key,
								   idx,
								   NULL);
		result =
		    _gnutls_openpgp_privkey_get_mpis(key, kid, &params);
	} else {
		_gnutls_hard_log("Signing using master PGP key\n");

		pk_algorithm =
		    gnutls_openpgp_privkey_get_pk_algorithm(key, NULL);
		result =
		    _gnutls_openpgp_privkey_get_mpis(key, NULL, &params);
	}

	if (result < 0) {
		gnutls_assert();
		return result;
	}


	result = _gnutls_pk_sign(pk_algorithm, signature, hash, &params);

	gnutls_pk_params_clear(&params);
	gnutls_pk_params_release(&params);

	if (result < 0) {
		gnutls_assert();
		return result;
	}

	return 0;
}
Exemple #20
0
int _gnutls_ecdh_compute_key(gnutls_ecc_curve_t curve,
			   const gnutls_datum_t *x, const gnutls_datum_t *y,
			   const gnutls_datum_t *k,
			   const gnutls_datum_t *peer_x, const gnutls_datum_t *peer_y,
			   gnutls_datum_t *Z)
{
	gnutls_pk_params_st pub, priv;
	int ret;

	gnutls_pk_params_init(&pub);
	gnutls_pk_params_init(&priv);

	pub.algo = GNUTLS_PK_EC;
	pub.flags = curve;

	if (_gnutls_mpi_init_scan_nz
		    (&pub.params[ECC_Y], peer_y->data,
		     peer_y->size) != 0) {
		ret =
		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
		goto cleanup;
	}

	if (_gnutls_mpi_init_scan_nz
		    (&pub.params[ECC_X], peer_x->data,
		     peer_x->size) != 0) {
		ret =
		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
		goto cleanup;
	}

	pub.params_nr = 2;

	if (_gnutls_mpi_init_scan_nz
		    (&priv.params[ECC_Y], y->data,
		     y->size) != 0) {
		ret =
		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
		goto cleanup;
	}

	if (_gnutls_mpi_init_scan_nz
		    (&priv.params[ECC_X], x->data,
		     x->size) != 0) {
		ret =
		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
		goto cleanup;
	}

	if (_gnutls_mpi_init_scan_nz
		    (&priv.params[ECC_K], k->data,
		     k->size) != 0) {
		ret =
		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
		goto cleanup;
	}


	priv.params_nr = 3;
	priv.algo = GNUTLS_PK_EC;
	priv.flags = curve;

	Z->data = NULL;

	ret = _gnutls_pk_derive(GNUTLS_PK_EC, Z, &priv, &pub);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = 0;
 cleanup:
 	gnutls_pk_params_clear(&pub);
 	gnutls_pk_params_clear(&priv);
 	return ret;
}
Exemple #21
0
static int
_get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey,
		gnutls_openpgp_keyid_t keyid, gnutls_datum_t * p,
		gnutls_datum_t * q, gnutls_datum_t * g, gnutls_datum_t * y,
		gnutls_datum_t * x)
{
	int pk_algorithm, ret;
	cdk_packet_t pkt;
	uint32_t kid32[2];
	gnutls_pk_params_st params;

	if (pkey == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	KEYID_IMPORT(kid32, keyid);

	pkt = _gnutls_openpgp_find_key(pkey->knode, kid32, 1);
	if (pkt == NULL) {
		gnutls_assert();
		return GNUTLS_E_OPENPGP_GETKEY_FAILED;
	}

	pk_algorithm =
	    _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo);

	if (pk_algorithm != GNUTLS_PK_DSA) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	ret = _gnutls_openpgp_privkey_get_mpis(pkey, kid32, &params);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	/* P */
	ret = _gnutls_mpi_dprint(params.params[0], p);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* Q */
	ret = _gnutls_mpi_dprint(params.params[1], q);
	if (ret < 0) {
		gnutls_assert();
		_gnutls_free_datum(p);
		goto cleanup;
	}


	/* G */
	ret = _gnutls_mpi_dprint(params.params[2], g);
	if (ret < 0) {
		gnutls_assert();
		_gnutls_free_datum(p);
		_gnutls_free_datum(q);
		goto cleanup;
	}


	/* Y */
	ret = _gnutls_mpi_dprint(params.params[3], y);
	if (ret < 0) {
		gnutls_assert();
		_gnutls_free_datum(p);
		_gnutls_free_datum(g);
		_gnutls_free_datum(q);
		goto cleanup;
	}

	ret = _gnutls_mpi_dprint(params.params[4], x);
	if (ret < 0) {
		gnutls_assert();
		_gnutls_free_datum(y);
		_gnutls_free_datum(p);
		_gnutls_free_datum(g);
		_gnutls_free_datum(q);
		goto cleanup;
	}

	ret = 0;

      cleanup:
	gnutls_pk_params_clear(&params);
	gnutls_pk_params_release(&params);
	return ret;
}
Exemple #22
0
/* Converts an RSA PKCS#1 key to
 * an internal structure (gnutls_private_key)
 */
ASN1_TYPE
_gnutls_privkey_decode_pkcs1_rsa_key(const gnutls_datum_t * raw_key,
				     gnutls_x509_privkey_t pkey)
{
	int result;
	ASN1_TYPE pkey_asn;

	gnutls_pk_params_init(&pkey->params);

	pkey->params.algo = GNUTLS_PK_RSA;

	if ((result =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.RSAPrivateKey",
				 &pkey_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return NULL;
	}

	result =
	    asn1_der_decoding(&pkey_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		goto error;
	}

	if ((result = _gnutls_x509_read_int(pkey_asn, "modulus",
					    &pkey->params.params[0])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(pkey_asn, "publicExponent",
				   &pkey->params.params[1])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_key_int(pkey_asn, "privateExponent",
				   &pkey->params.params[2])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime1",
					    &pkey->params.params[3])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime2",
					    &pkey->params.params[4])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "coefficient",
					    &pkey->params.params[5])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "exponent1",
					    &pkey->params.params[6])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "exponent2",
					    &pkey->params.params[7])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	result =
	    _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->params.params_nr = RSA_PRIVATE_PARAMS;

	return pkey_asn;

      error:
	asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);
	return NULL;

}