static int rsa_openssl_load_pubkey()

in projects/linux/crypto/rsa_openssl.c [382:506]


static int rsa_openssl_load_pubkey (EVP_PKEY **rsa, const struct rsa_public_key *key)
{
	uint8_t exp[4];
	BIGNUM *n = NULL;
	BIGNUM *e = NULL;
	int status;

	ERR_clear_error ();

	n = BN_bin2bn (key->modulus, key->mod_length, NULL);
	if (n == NULL) {
		return -ERR_get_error ();
	}

	exp[0] = key->exponent >> 24;
	exp[1] = key->exponent >> 16;
	exp[2] = key->exponent >> 8;
	exp[3] = key->exponent;

	e = BN_bin2bn (exp, sizeof (exp), NULL);
	if (e == NULL) {
		status = -ERR_get_error ();
		goto err_e;
	}

#if OPENSSL_IS_VERSION_3
	{
		OSSL_PARAM_BLD *param_list = NULL;
		OSSL_PARAM *rsa_params = NULL;
		EVP_PKEY_CTX *ctx = NULL;

		param_list = OSSL_PARAM_BLD_new ();
		if (param_list == NULL) {
			status = -ERR_get_error ();
			goto err_list;
		}

		status = OSSL_PARAM_BLD_push_BN (param_list, "n", n);
		if (status != 1) {
			status = -ERR_get_error ();
			goto err_push;
		}

		status = OSSL_PARAM_BLD_push_BN (param_list, "e", e);
		if (status != 1) {
			status = -ERR_get_error ();
			goto err_push;
		}

		rsa_params = OSSL_PARAM_BLD_to_param (param_list);
		if (rsa_params == NULL) {
			status = -ERR_get_error ();
			goto err_push;
		}

		ctx = EVP_PKEY_CTX_new_from_name (NULL, "RSA", NULL);
		if (ctx == NULL) {
			status = -ERR_get_error ();
			goto err_ctx;
		}

		status = EVP_PKEY_fromdata_init (ctx);
		if (status != 1) {
			status = -ERR_get_error ();
			goto err_key;
		}

		status = EVP_PKEY_fromdata (ctx, rsa, EVP_PKEY_PUBLIC_KEY, rsa_params);
		if (status != 1) {
			status = -ERR_get_error ();
			goto err_key;
		}

		status = 0;

err_key:
		EVP_PKEY_CTX_free (ctx);
err_ctx:
		OSSL_PARAM_free (rsa_params);
err_push:
		OSSL_PARAM_BLD_free (param_list);
	}
#else
	{
		RSA *rsa_key;

		rsa_key = RSA_new ();
		if (rsa_key == NULL) {
			status = -ERR_get_error ();
			goto err_list;
		}

		status = RSA_set0_key (rsa_key, n, e, NULL);
		if (status == 0) {
			status = -ERR_get_error ();
			goto err_rsa;
		}

		*rsa = EVP_PKEY_new ();
		if (*rsa == NULL) {
			status = -ERR_get_error ();
			goto err_rsa;
		}

		status = EVP_PKEY_assign_RSA (*rsa, rsa_key);
		if (status != 1) {
			status = -ERR_get_error ();
			goto err_rsa;
		}

		/* Don't free anything that was created. */
		return 0;

err_rsa:
		RSA_free (rsa_key);
	}
#endif

err_list:
	BN_free (e);
err_e:
	BN_free (n);

	return status;
}