int x509_cert_build_create_csr()

in core/asn1/x509_cert_build.c [423:521]


int x509_cert_build_create_csr (const struct x509_engine *engine, const uint8_t *priv_key,
	size_t key_length, enum hash_type sig_hash, const char *name, int type, const uint8_t *eku,
	size_t eku_length, const struct x509_extension_builder *const *extra_extensions,
	size_t ext_count, uint8_t **csr, size_t *csr_length)
{
	const struct x509_engine_cert_build *x509 = (const struct x509_engine_cert_build*) engine;
	DERBuilderContext *der;
	struct ecc_public_key ecc_pub_key;
	uint8_t *pub_key_der = NULL;
	size_t pub_key_der_len;
	const int *sig_oid;
	int status;

	if (csr == NULL) {
		return X509_ENGINE_INVALID_ARGUMENT;
	}

	*csr = NULL;

	if ((x509 == NULL) || (priv_key == NULL) || (name == NULL) || (csr_length == NULL) ||
		(key_length == 0)) {
		return X509_ENGINE_INVALID_ARGUMENT;
	}

	if ((eku_length != 0) && (eku == NULL)) {
		return X509_ENGINE_INVALID_ARGUMENT;
	}

	if ((ext_count != 0) && (extra_extensions == NULL)) {
		return X509_ENGINE_INVALID_ARGUMENT;
	}

	if ((type == X509_CERT_END_ENTITY) && (eku != NULL)) {
		return X509_ENGINE_NOT_CA_CERT;
	}

	switch (sig_hash) {
		case HASH_TYPE_SHA256:
			sig_oid = ecdsaWithSHA256OID;
			break;

		case HASH_TYPE_SHA384:
			sig_oid = ecdsaWithSHA384OID;
			break;

		case HASH_TYPE_SHA512:
			sig_oid = ecdsaWithSHA512OID;
			break;

		default:
			return X509_ENGINE_UNSUPPORTED_SIG_HASH;
	}

	status = x509->ecc->init_key_pair (x509->ecc, priv_key, key_length, NULL, &ecc_pub_key);
	if (status != 0) {
		return status;
	}

	status = x509->ecc->get_public_key_der (x509->ecc, &ecc_pub_key, &pub_key_der,
		&pub_key_der_len);
	if (status != 0) {
		goto err_free_key;
	}

	der = x509_cert_build_new_cert (x509);
	if (der == NULL) {
		status = X509_ENGINE_NO_MEMORY;
		goto err_free_key_der;
	}

	status = x509_cert_build_build_csr_tbs_data (der, name, pub_key_der, pub_key_der_len, type, eku,
		eku_length, extra_extensions, ext_count);
	if (status != 0) {
		status = (status == -1) ? X509_ENGINE_CSR_FAILED : status;
		goto err_free_cert;
	}

	status = x509_cert_build_sign_certificate (der, priv_key, key_length, x509->ecc, x509->hash,
		sig_hash, sig_oid);
	if (status != 0) {
		status = (status == -1) ? X509_ENGINE_CSR_FAILED : status;
		goto err_free_cert;
	}

	*csr_length = DERGetEncodedLength (der);
	*csr = der->Buffer;

	der->Buffer = NULL;
	status = 0;

err_free_cert:
	x509_cert_build_free_cert (der);
err_free_key_der:
	platform_free (pub_key_der);
err_free_key:
	x509->ecc->release_key_pair (x509->ecc, NULL, &ecc_pub_key);

	return status;
}