Example #1
0
/* 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(&params);

	_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, &params);
	if (result < 0)
		return gnutls_assert_val(result);

	bits[0] = pubkey_to_bits(algo, &params);

	gnutls_pk_params_release(&params);
	return algo;
}
Example #2
0
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;

}