/* Reads and returns the PK algorithm of the given certificate-like * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo". */ int _gnutls_x509_get_pk_algorithm(ASN1_TYPE src, const char *src_name, unsigned int *bits) { int result; int algo; char oid[64]; int len; gnutls_pk_params_st params; char name[128]; gnutls_pk_params_init(¶ms); _asnstr_append_name(name, sizeof(name), src_name, ".algorithm.algorithm"); len = sizeof(oid); result = asn1_read_value(src, name, oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } algo = gnutls_oid_to_pk(oid); if (algo == GNUTLS_PK_UNKNOWN) { _gnutls_debug_log ("%s: unknown public key algorithm: %s\n", __func__, oid); } if (bits == NULL) { return algo; } /* Now read the parameters' bits */ result = _gnutls_get_asn_mpis(src, src_name, ¶ms); if (result < 0) return gnutls_assert_val(result); bits[0] = pubkey_to_bits(algo, ¶ms); gnutls_pk_params_release(¶ms); return algo; }
static int decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey) { int result, len; char oid[MAX_OID_SIZE]; ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY; gnutls_datum_t sder; int ret; if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-8-PrivateKeyInfo", &pkcs8_asn)) != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } result = _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } /* Check the private key algorithm OID */ len = sizeof(oid); result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.algorithm", oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } pkey->params.algo = gnutls_oid_to_pk(oid); if (pkey->params.algo == GNUTLS_PK_UNKNOWN) { gnutls_assert(); _gnutls_debug_log ("PKCS #8 private key OID '%s' is unsupported.\n", oid); result = GNUTLS_E_UNKNOWN_PK_ALGORITHM; goto error; } /* Get the DER encoding of the actual private key. */ switch(pkey->params.algo) { case GNUTLS_PK_RSA: result = _decode_pkcs8_rsa_key(pkcs8_asn, pkey); break; case GNUTLS_PK_RSA_PSS: result = _decode_pkcs8_rsa_pss_key(pkcs8_asn, pkey); break; case GNUTLS_PK_DSA: result = _decode_pkcs8_dsa_key(pkcs8_asn, pkey); break; case GNUTLS_PK_ECDSA: result = _decode_pkcs8_ecc_key(pkcs8_asn, pkey); break; case GNUTLS_PK_EDDSA_ED25519: result = _decode_pkcs8_eddsa_key(pkcs8_asn, pkey, oid); break; case GNUTLS_PK_GOST_01: case GNUTLS_PK_GOST_12_256: case GNUTLS_PK_GOST_12_512: result = _decode_pkcs8_gost_key(pkcs8_asn, pkey, pkey->params.algo); break; default: result = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); goto error; } if (result < 0) { gnutls_assert(); goto error; } /* check for provable parameters attribute */ ret = _x509_parse_attribute(pkcs8_asn, "attributes", OID_ATTR_PROV_SEED, 0, 1, &sder); if (ret >= 0) { /* ignore it when not being present */ ret = _x509_decode_provable_seed(pkey, &sder); gnutls_free(sder.data); if (ret < 0) { gnutls_assert(); } } result = 0; error: asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE); return result; }