int x509_extension_builder_openssl_dme_build()

in projects/linux/asn1/dme/x509_extension_builder_openssl_dme.c [44:177]


int x509_extension_builder_openssl_dme_build (const struct x509_extension_builder *builder,
	struct x509_extension *extension)
{
	const struct x509_extension_builder_openssl_dme *dme_build =
		(const struct x509_extension_builder_openssl_dme*) builder;
	DME_EXTENSION *dme_ext;
	EVP_PKEY *pubkey;
	ASN1_OBJECT *oid;
	int status;
	uint8_t *ext_der = NULL;
	int ext_der_len;

	if ((dme_build == NULL) || (extension == NULL)) {
		return DME_EXTENSION_INVALID_ARGUMENT;
	}

	if (dme_build->dme == NULL) {
		return DME_EXTENSION_INVALID_ARGUMENT;
	}

	if (dme_build->dme->data_oid == NULL) {
		return DME_EXTENSION_NO_TYPE_OID;
	}

	if (dme_build->dme->data == NULL) {
		return DME_EXTENSION_NO_DATA;
	}

	if (dme_build->dme->sig_oid == NULL) {
		return DME_EXTENSION_NO_SIG_TYPE_OID;
	}

	if (dme_build->dme->signature == NULL) {
		return DME_EXTENSION_NO_SIGNATURE;
	}

	if (dme_build->dme->dme_pub_key == NULL) {
		return DME_EXTENSION_NO_DME_KEY;
	}

	dme_ext = DME_EXTENSION_new ();
	if (dme_ext == NULL) {
		status = -ERR_get_error ();
		goto err_ext;
	}

	pubkey = d2i_PUBKEY (NULL, (const uint8_t**) &dme_build->dme->dme_pub_key,
		dme_build->dme->key_length);
	if (pubkey == NULL) {
		status = -ERR_get_error ();
		goto err_build;
	}

	status = X509_PUBKEY_set (&dme_ext->dme_key, pubkey);
	EVP_PKEY_free (pubkey);
	if (status == 0) {
		status = -ERR_get_error ();
		goto err_build;
	}

	status = x509_openssl_parse_encoded_oid (dme_build->dme->data_oid,
		dme_build->dme->data_oid_length, &oid);
	if (status != 0) {
		goto err_build;
	}

	ASN1_OBJECT_free (dme_ext->struct_format);
	dme_ext->struct_format = oid;

	status = ASN1_OCTET_STRING_set (dme_ext->dme_struct, dme_build->dme->data,
		dme_build->dme->data_length);
	if (status == 0) {
		status = -ERR_get_error ();
		goto err_build;
	}

	status = x509_openssl_parse_encoded_oid (dme_build->dme->sig_oid,
		dme_build->dme->sig_oid_length, &oid);
	if (status != 0) {
		goto err_build;
	}

	status = X509_ALGOR_set0 (dme_ext->sig_alg, oid, V_ASN1_UNDEF, NULL);
	if (status == 0) {
		status = -ERR_get_error ();
		ASN1_OBJECT_free (oid);
		goto err_build;
	}

	status = x509_openssl_set_bit_string (dme_build->dme->signature,
		dme_build->dme->signature_length, dme_ext->signature);
	if (status != 0) {
		goto err_build;
	}

	if (dme_build->dme->device_oid != NULL) {
		status = x509_openssl_parse_encoded_oid (dme_build->dme->device_oid,
			dme_build->dme->dev_oid_length, &dme_ext->device_type);
		if (status != 0) {
			goto err_build;
		}
	}

	if (dme_build->dme->renewal_counter != NULL) {
		dme_ext->renewal_counter = ASN1_BIT_STRING_new ();
		if (dme_ext->renewal_counter == NULL) {
			status = DME_EXTENSION_NO_MEMORY;
			goto err_build;
		}

		status = x509_openssl_set_bit_string (dme_build->dme->renewal_counter,
			dme_build->dme->counter_length, dme_ext->renewal_counter);
		if (status != 0) {
			goto err_build;
		}
	}

	ext_der_len = i2d_DME_EXTENSION (dme_ext, &ext_der);
	if (ext_der_len < 0) {
		status = -ERR_get_error ();
		goto err_build;
	}

	x509_extension_builder_init_extension_descriptor (extension, false,
		X509_EXTENSION_BUILDER_DME_OID, X509_EXTENSION_BUILDER_DME_OID_LENGTH, ext_der,
		ext_der_len);

	status = 0;

err_build:
	DME_EXTENSION_free (dme_ext);
err_ext:
	return status;
}