Пример #1
0
unsigned pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params)
{
	switch (pk) {
	case GNUTLS_PK_RSA:
		return _gnutls_mpi_get_nbits(params->params[RSA_MODULUS]);
	case GNUTLS_PK_DSA:
		return _gnutls_mpi_get_nbits(params->params[DSA_P]);
	case GNUTLS_PK_EC:
		return gnutls_ecc_curve_get_size(params->flags) * 8;
	default:
		return 0;
	}
}
Пример #2
0
static void print_ecdh_info(gnutls_session_t session, const char *str)
{
	int curve;

	printf("- %sEC Diffie-Hellman parameters\n", str);

	curve = gnutls_ecc_curve_get(session);

	printf(" - Using curve: %s\n", gnutls_ecc_curve_get_name(curve));
	printf(" - Curve size: %d bits\n",
	       gnutls_ecc_curve_get_size(curve) * 8);

}
Пример #3
0
int
_gnutls_ecc_ansi_x963_export(gnutls_ecc_curve_t curve, bigint_t x,
			     bigint_t y, gnutls_datum_t * out)
{
	int numlen = gnutls_ecc_curve_get_size(curve);
	int byte_size, ret;
	size_t size;

	if (numlen == 0)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	out->size = 1 + 2 * numlen;

	out->data = gnutls_malloc(out->size);
	if (out->data == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	memset(out->data, 0, out->size);

	/* store byte 0x04 */
	out->data[0] = 0x04;

	/* pad and store x */
	byte_size = (_gnutls_mpi_get_nbits(x) + 7) / 8;
	size = out->size - (1 + (numlen - byte_size));
	ret =
	    _gnutls_mpi_print(x, &out->data[1 + (numlen - byte_size)],
			      &size);
	if (ret < 0)
		return gnutls_assert_val(ret);

	byte_size = (_gnutls_mpi_get_nbits(y) + 7) / 8;
	size = out->size - (1 + (numlen + numlen - byte_size));
	ret =
	    _gnutls_mpi_print(y,
			      &out->data[1 + numlen + numlen - byte_size],
			      &size);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* pad and store y */
	return 0;
}
Пример #4
0
/* Converts a GOST key to
 * an internal structure (gnutls_private_key)
 */
static int
_privkey_decode_gost_key(const gnutls_datum_t * raw_key,
			 gnutls_x509_privkey_t pkey)
{
	int ret;
	int ecc_size = gnutls_ecc_curve_get_size(pkey->params.curve);

	/* Just to be sure here */
	if (ecc_size <= 0) {
		gnutls_assert();
		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
		goto error;
	}

	/* Private key form described in R 50.1.112-2016.
	 * Private key can come up as masked value concatenated with several masks.
	 * each part is of ecc_size bytes. Key will be unmasked in pk_fixup */
	if (raw_key->size % ecc_size == 0) {
		ret = _gnutls_mpi_init_scan_le(&pkey->params.params[GOST_K],
				raw_key->data, raw_key->size);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (raw_key->data[0] == ASN1_TAG_INTEGER) {
		ASN1_TYPE pkey_asn;

		/* Very old format: INTEGER packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKeyOld",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

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

		ret = _gnutls_x509_read_key_int(pkey_asn, "",
						&pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else if (raw_key->data[0] == ASN1_TAG_OCTET_STRING) {
		ASN1_TYPE pkey_asn;

		/* format: OCTET STRING packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKey",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

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

		ret = _gnutls_x509_read_key_int_le(pkey_asn, "",
						   &pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto error;
	}

	pkey->params.params_nr++;

	return 0;

      error:
	return ret;

}
Пример #5
0
static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
				  gnutls_datum_t * out,
				  const gnutls_pk_params_st * priv,
				  const gnutls_pk_params_st * pub)
{
	int ret;

	switch (algo) {
	case GNUTLS_PK_EC:
		{
			struct ecc_scalar ecc_priv;
			struct ecc_point ecc_pub;
			const struct ecc_curve *curve;

			out->data = NULL;

			curve = get_supported_curve(priv->flags);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve);
			if (ret < 0)
				return gnutls_assert_val(ret);

			ret =
			    _ecc_params_to_privkey(priv, &ecc_priv, curve);
			if (ret < 0) {
				ecc_point_clear(&ecc_pub);
				return gnutls_assert_val(ret);
			}

			out->size = gnutls_ecc_curve_get_size(priv->flags);
			/*ecc_size(curve)*sizeof(mp_limb_t); */
			out->data = gnutls_malloc(out->size);
			if (out->data == NULL) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);
				goto ecc_cleanup;
			}

			ecc_shared_secret(&ecc_priv, &ecc_pub, out->data,
					  out->size);

		      ecc_cleanup:
			ecc_point_clear(&ecc_pub);
			ecc_scalar_clear(&ecc_priv);
			if (ret < 0)
				goto cleanup;
			break;
		}
	default:
		gnutls_assert();
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto cleanup;
	}

	ret = 0;

      cleanup:

	return ret;
}
Пример #6
0
/* This is used for DH or ECDH key derivation. In DH for example
 * it is given the peers Y and our x, and calculates Y^x 
 */
static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
				  gnutls_datum_t * out,
				  const gnutls_pk_params_st * priv,
				  const gnutls_pk_params_st * pub)
{
	int ret;

	switch (algo) {
	case GNUTLS_PK_DH: {
		bigint_t f, x, prime;
		bigint_t k = NULL, ff = NULL;
		unsigned int bits;

		f = pub->params[DH_Y];
		x = priv->params[DH_X];
		prime = priv->params[DH_P];

		ret = _gnutls_mpi_init_multi(&k, &ff, NULL);
		if (ret < 0)
			return gnutls_assert_val(ret);

		ret = _gnutls_mpi_modm(ff, f, prime);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = _gnutls_mpi_add_ui(ff, ff, 1);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		/* check if f==0,1,p-1. 
		 * or (ff=f+1) equivalently ff==1,2,p */
		if ((_gnutls_mpi_cmp_ui(ff, 2) == 0)
		    || (_gnutls_mpi_cmp_ui(ff, 1) == 0)
		    || (_gnutls_mpi_cmp(ff, prime) == 0)) {
			gnutls_assert();
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			goto dh_cleanup;
		}

		/* prevent denial of service */
		bits = _gnutls_mpi_get_nbits(prime);
		if (bits == 0 || bits > MAX_DH_BITS) {
			gnutls_assert();
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			goto dh_cleanup;
		}


		ret = _gnutls_mpi_powm(k, f, x, prime);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = _gnutls_mpi_dprint(k, out);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = 0;
dh_cleanup:
		_gnutls_mpi_release(&ff);
		zrelease_temp_mpi_key(&k);
		if (ret < 0)
			goto cleanup;

		break;
	}
	case GNUTLS_PK_EC:
		{
			struct ecc_scalar ecc_priv;
			struct ecc_point ecc_pub;
			const struct ecc_curve *curve;

			out->data = NULL;

			curve = get_supported_curve(priv->flags);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve);
			if (ret < 0)
				return gnutls_assert_val(ret);

			ret =
			    _ecc_params_to_privkey(priv, &ecc_priv, curve);
			if (ret < 0) {
				ecc_point_clear(&ecc_pub);
				return gnutls_assert_val(ret);
			}

			out->size = gnutls_ecc_curve_get_size(priv->flags);
			/*ecc_size(curve)*sizeof(mp_limb_t); */
			out->data = gnutls_malloc(out->size);
			if (out->data == NULL) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);
				goto ecc_cleanup;
			}

			ecc_shared_secret(&ecc_priv, &ecc_pub, out->data,
					  out->size);

		      ecc_cleanup:
			ecc_point_clear(&ecc_pub);
			ecc_scalar_zclear(&ecc_priv);
			if (ret < 0)
				goto cleanup;
			break;
		}
	default:
		gnutls_assert();
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto cleanup;
	}

	ret = 0;

      cleanup:

	return ret;
}