-bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) {
- *rsa = RSA_new();
- BN_hex2bn(&(*rsa)->n, n);
- BN_hex2bn(&(*rsa)->e, e);
- BN_hex2bn(&(*rsa)->d, d);
- return true;
+static bool hex_to_bn(BIGNUM **bn, const char *hex) {
+ return (size_t)BN_hex2bn(bn, hex) == strlen(hex);
+}
+
+static rsa_t *rsa_set_hex_key(const char *n, const char *e, const char *d) {
+ rsa_t *rsa = NULL;
+ BIGNUM *bn_n = NULL;
+ BIGNUM *bn_e = NULL;
+ BIGNUM *bn_d = NULL;
+
+ if(!hex_to_bn(&bn_n, n) || !hex_to_bn(&bn_e, e) || (d && !hex_to_bn(&bn_d, d))) {
+ goto exit;
+ }
+
+#if OPENSSL_VERSION_MAJOR < 3
+ rsa = RSA_new();
+
+ if(rsa) {
+ RSA_set0_key(rsa, bn_n, bn_e, bn_d);
+ }
+
+#else
+ int selection = bn_d ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY;
+ rsa = build_rsa_key(selection, bn_n, bn_e, bn_d);
+#endif
+
+exit:
+#if OPENSSL_VERSION_MAJOR < 3
+
+ if(!rsa)
+#endif
+ {
+ BN_free(bn_d);
+ BN_free(bn_e);
+ BN_free(bn_n);
+ }
+
+ return rsa;
+}
+
+rsa_t *rsa_set_hex_public_key(const char *n, const char *e) {
+ return rsa_set_hex_key(n, e, NULL);
+}
+
+rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) {
+ return rsa_set_hex_key(n, e, d);