예제 #1
0
파일: ecdhe.c 프로젝트: randombit/hacrypto
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)
		return gnutls_assert_val(ret);

	/* generate pre-shared key */
	ret = calc_ecdh_key(session, psk_key, curve);
	if (ret < 0)
		return gnutls_assert_val(ret);

	return 0;
}
예제 #2
0
/*
 * some x509 certificate parsing functions that relate to MPI parameter
 * extraction. This reads the BIT STRING subjectPublicKey.
 * Returns 2 parameters (m,e). It does not set params_nr.
 */
int
_gnutls_x509_read_ecc_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params)
{
/* Eventhough RFC5480 defines the public key to be an ECPoint (i.e. OCTET STRING),
 * it is actually copied in raw there. Why do they use ASN.1 anyway?
 */
  return _gnutls_ecc_ansi_x963_import (der, dersize, &params->params[ECC_X],
                                     &params->params[ECC_Y]);
}
예제 #3
0
파일: ecdhe.c 프로젝트: attilamolnar/gnutls
int
_gnutls_proc_ecdh_common_server_kx(gnutls_session_t session,
				   uint8_t * data, size_t _data_size)
{
	int i, ret, point_size;
	gnutls_ecc_curve_t curve;
	ssize_t data_size = _data_size;

	/* just in case we are resuming a session */
	gnutls_pk_params_release(&session->key.ecdh_params);

	gnutls_pk_params_init(&session->key.ecdh_params);

	i = 0;
	DECR_LEN(data_size, 1);
	if (data[i++] != 3)
		return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);

	DECR_LEN(data_size, 2);
	curve = _gnutls_tls_id_to_ecc_curve(_gnutls_read_uint16(&data[i]));
	i += 2;

	ret = _gnutls_session_supports_ecc_curve(session, curve);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_session_ecc_curve_set(session, curve);

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

	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)
		return gnutls_assert_val(ret);

	i += point_size;

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

  gnutls_pk_params_init(&pkey->params);

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

  ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      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();
      goto error;
    }

  /* read the curve */
  oid_size = sizeof(oid);
  ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      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();
      goto error;
    }
    
  ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }

  /* read the public key */
  ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2);
  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_int (pkey_asn, "privateKey", &pkey->params.params[ECC_K]);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }
  pkey->params.params_nr ++;

  return pkey_asn;

error:
  asn1_delete_structure (&pkey_asn);
  gnutls_pk_params_release (&pkey->params);
  return NULL;

}
예제 #5
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;

}