int _gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t algo, uint8_t * der, int dersize, gnutls_pk_params_st * params) { switch (algo) { case GNUTLS_PK_RSA: return 0; case GNUTLS_PK_DSA: return _gnutls_x509_read_dsa_params(der, dersize, params); case GNUTLS_PK_EC: return _gnutls_x509_read_ecc_params(der, dersize, ¶ms->flags); default: return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); } }
/* Decodes an ECC privateKey from a PKCS8 structure. */ static int _decode_pkcs8_ecc_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) { int ret; gnutls_datum_t tmp = {NULL, 0}; unsigned char oid[MAX_OID_SIZE]; unsigned curve = GNUTLS_ECC_CURVE_INVALID; int len, result; /* openssl PKCS #8 files with ECC keys place the curve in * privateKeyAlgorithm.parameters instead of the ECPrivateKey.parameters. */ len = sizeof(oid); result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters", oid, &len); if (result == ASN1_SUCCESS) { ret = _gnutls_x509_read_ecc_params(oid, len, &curve); if (ret < 0) { _gnutls_debug_log("PKCS#8: unknown curve OID %s\n", oid); curve = GNUTLS_ECC_CURVE_INVALID; } } ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp); if (ret < 0) { gnutls_assert(); goto error; } ret = _gnutls_privkey_decode_ecc_key(&pkey->key, &tmp, pkey, curve); _gnutls_free_key_datum(&tmp); if (ret < 0) { gnutls_assert(); goto error; } ret = 0; error: return ret; }