[openssl-dev] [openssl.org #4518] OpenSSL-1.1.0-pre5 RSA_set0_key and related RSA_get0_*, RSA_set0_*, DSA_set0_* and DSA_get0_* problems
deengert@gmail.com via RT
rt at openssl.org
Sun Apr 24 20:28:22 UTC 2016
The new routines in OpenSSL-1.1.0-pre5 RSA_get0_key and RSA_set0_key with their multiple
arguments are not very user friendly requiring much more code being replaced and may lead to freeing
an active pointers.
Would not a set of routines like:
BIGNUM* RSA_get0_key_n(RSA *rsa);
int RSA_set0_key_n(RSA *rsa, BIGNUM *n);
(A set for: n, e, d, p, q, idmp1, idmq1, iqmp)
be much more backward compatible?
It would allow for code which contained lines like rsa->n to be replaced by
RSA_get0_key_n(rsa) or assignments to be replaced by RSA_get0_key_n(rsa, n);
and for backward compatibly a user could define something like:
#if OPENSSL_VERSION_NUMBER < 0x10100005L
#define RSA_get0_key_n(R) ((R)->n)
#define RSA_set0_key_n(R, N) ((R)->n = (N))
...
The above also applies to DSA_get0_* and DSA_set0_* routines too.
While converting some existing code, the problem with RSA_set0_key came up.
The code would create rsa with n and e in one routine, then in another
using rsa and getting n and e would created d, p, q. But to set d
required RSA_set0_key(rsa, n, e, d)
the sequence of
RSA_get0_key(rsa, &n, &e, NULL);
... calculate d ...
RSA_set0_key(rsa, n, e, d);
RSA_set0_key will free an existing rsa->n, and replace it with the new n,
but in the simple case above the point returned by RSA_get0_key for n and e
would be freed, but the new pointer points at the same location which were just freed.
This is an example of what had to be done using BN_dup to avoid the above problem.
If nothing else, all the RSA_set0 routines should test if the same pointer value
is being replaced if so do not free it.
The same logic need to be done for all the RSA_set0_* functions
as well as the DSA_set0_* functions.
diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c
index 109aa35..366fdaa 100644
--- a/src/tools/cryptoflex-tool.c
+++ b/src/tools/cryptoflex-tool.c
@@ -217,8 +217,8 @@ static int parse_public_key(const u8 *key, size_t keysize, RSA *rsa)
if (e == NULL)
return -1;
cf2bn(p, 4, e);
- rsa->n = n;
- rsa->e = e;
+ if (RSA_set0_key(rsa, n, e, NULL) != 1)
+ return -1;
return 0;
}
@@ -226,6 +226,8 @@ static int gen_d(RSA *rsa)
{
BN_CTX *bnctx;
BIGNUM *r0, *r1, *r2;
+ BIGNUM *rsa_p, *rsa_q, *rsa_n, *rsa_e, *rsa_d;
+ BIGNUM *rsa_n_new, *rsa_e_new;
bnctx = BN_CTX_new();
if (bnctx == NULL)
@@ -234,13 +236,25 @@ static int gen_d(RSA *rsa)
r0 = BN_CTX_get(bnctx);
r1 = BN_CTX_get(bnctx);
r2 = BN_CTX_get(bnctx);
- BN_sub(r1, rsa->p, BN_value_one());
- BN_sub(r2, rsa->q, BN_value_one());
+ RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
+ RSA_get0_factors(rsa, &rsa_p, &rsa_q);
+
+ BN_sub(r1, rsa_p, BN_value_one());
+ BN_sub(r2, rsa_q, BN_value_one());
BN_mul(r0, r1, r2, bnctx);
- if ((rsa->d = BN_mod_inverse(NULL, rsa->e, r0, bnctx)) == NULL) {
+ if ((rsa_d = BN_mod_inverse(NULL, rsa_e, r0, bnctx)) == NULL) {
fprintf(stderr, "BN_mod_inverse() failed.\n");
return -1;
}
+
+ /* RSA_set0_key will free previous value, and replace with new value
+ * Thus the need to copy the contents of rsa_n and rsa_e
+ */
+ rsa_n_new = BN_dup(rsa_n);
+ rsa_e_new = BN_dup(rsa_e);
+ if (RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d) != 1)
+ return -1;
+
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return 0;
--
Douglas E. Engert <DEEngert at gmail.com>
--
Ticket here: http://rt.openssl.org/Ticket/Display.html?id=4518
Please log in as guest with password guest if prompted
More information about the openssl-dev
mailing list