-bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) {
- *rsa = RSA_new();
- BN_hex2bn(&(*rsa)->n, n);
- BN_hex2bn(&(*rsa)->e, e);
- return true;
+#if OPENSSL_VERSION_MAJOR >= 3
+static EVP_PKEY *build_rsa_key(int selection, const BIGNUM *bn_n, const BIGNUM *bn_e, const BIGNUM *bn_d) {
+ assert(bn_n);
+ assert(bn_e);
+
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+
+ if(!ctx) {
+ openssl_err("initialize key context");
+ return NULL;
+ }
+
+ OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, bn_n);
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, bn_e);
+
+ if(bn_d) {
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, bn_d);
+ }
+
+ OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
+ EVP_PKEY *key = NULL;
+
+ bool ok = EVP_PKEY_fromdata_init(ctx) > 0
+ && EVP_PKEY_fromdata(ctx, &key, selection, params) > 0;
+
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(bld);
+ EVP_PKEY_CTX_free(ctx);
+
+ if(ok) {
+ return key;
+ }
+
+ openssl_err("build key");
+ return NULL;
+}
+#endif
+
+static bool hex_to_bn(BIGNUM **bn, const char *hex) {
+ return (size_t)BN_hex2bn(bn, hex) == strlen(hex);