From 1da12e34ed69cec206f3a251a1e62ceeb694a6ea Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 25 Apr 2016 20:28:54 +0200 Subject: RSA, DSA, DH: Allow some given input to be NULL on already initialised keys The diverse {RSA,DSA,DH}_set0_* functions are made to allow some parameters to be NULL IF the corresponding numbers in the given key structure have already been previously initialised. Specifically, this allows the addition of private components to be added to a key that already has the public half, approximately like this: RSA_get0_key(rsa, NULL, &e, NULL); RSA_get0_factors(rsa, &p, &q); /* calculate new d */ RSA_set0_key(rsa, NULL, NULL, d); Reviewed-by: Matt Caswell --- crypto/dsa/dsa_lib.c | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'crypto/dsa') diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index facb97fb5e..383b48ba46 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -315,14 +315,27 @@ void DSA_get0_pqg(const DSA *d, BIGNUM **p, BIGNUM **q, BIGNUM **g) int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { - if (p == NULL || q == NULL || g == NULL) + /* If the fields in d are NULL, the corresponding input + * parameters MUST be non-NULL. + * + * It is an error to give the results from get0 on d + * as input parameters. + */ + if (p == d->p || q == d->q || g == d->g) return 0; - BN_free(d->p); - BN_free(d->q); - BN_free(d->g); - d->p = p; - d->q = q; - d->g = g; + + if (p != NULL) { + BN_free(d->p); + d->p = p; + } + if (q != NULL) { + BN_free(d->q); + d->q = q; + } + if (g != NULL) { + BN_free(d->g); + d->g = g; + } return 1; } @@ -337,14 +350,25 @@ void DSA_get0_key(const DSA *d, BIGNUM **pub_key, BIGNUM **priv_key) int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { - /* Note that it is valid for priv_key to be NULL */ - if (pub_key == NULL) + /* If the pub_key in d is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + * + * It is an error to give the results from get0 on d + * as input parameters. + */ + if (d->pub_key == pub_key + || (d->priv_key != NULL && priv_key != d->priv_key)) return 0; - BN_free(d->pub_key); - BN_free(d->priv_key); - d->pub_key = pub_key; - d->priv_key = priv_key; + if (pub_key != NULL) { + BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(d->priv_key); + d->priv_key = priv_key; + } return 1; } -- cgit v1.2.3