/* reads the curve from the certificate. * params[0-4]. It does NOT set params_nr. */ int _gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params) { int ret; ASN1_TYPE spk = ASN1_TYPE_EMPTY; char oid[MAX_OID_SIZE]; int oid_size; if ((ret = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (ret); } ret = asn1_der_decoding (&spk, der, dersize, NULL); if (ret != ASN1_SUCCESS) { gnutls_assert (); ret = _gnutls_asn2err (ret); goto cleanup; } /* Read curve */ /* read the curve */ oid_size = sizeof(oid); ret = asn1_read_value(spk, "namedCurve", oid, &oid_size); if (ret != ASN1_SUCCESS) { gnutls_assert (); ret = _gnutls_asn2err (ret); goto cleanup; } params->flags = _gnutls_oid_to_ecc_curve(oid); if (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 cleanup; } ret = _gnutls_ecc_curve_fill_params(params->flags, params); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = 0; cleanup: asn1_delete_structure (&spk); return ret; }
/** * 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; ret = _gnutls_ecc_curve_fill_params(curve, &key->params); if (ret < 0) return gnutls_assert_val(ret); if (_gnutls_mpi_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_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_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_release(&key->params); return ret; }
/* 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; }