summaryrefslogtreecommitdiffstats
path: root/crypto/rsa
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2016-04-25 20:28:54 +0200
committerRichard Levitte <levitte@openssl.org>2016-04-27 15:07:53 +0200
commit1da12e34ed69cec206f3a251a1e62ceeb694a6ea (patch)
tree5dfc32c8085b5e1cf77134786e778b861e38640d /crypto/rsa
parent3aec886ed4af1ca945f5d10da2ce40e4538fe5fc (diff)
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 <matt@openssl.org>
Diffstat (limited to 'crypto/rsa')
-rw-r--r--crypto/rsa/rsa_lib.c75
1 files changed, 55 insertions, 20 deletions
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index 7ee575d663..222631685c 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -286,44 +286,79 @@ int RSA_security_bits(const RSA *rsa)
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
{
- /* d is the private component and may be NULL */
- if (n == NULL || e == NULL)
+ /* If the fields in r are NULL, the corresponding input
+ * parameters MUST be non-NULL for n and e. d may be
+ * left NULL (in case only the public key is used).
+ *
+ * It is an error to give the results from get0 on r
+ * as input parameters.
+ */
+ if (n == r->n || e == r->e
+ || (r->d != NULL && d == r->d))
return 0;
- BN_free(r->n);
- BN_free(r->e);
- BN_free(r->d);
- r->n = n;
- r->e = e;
- r->d = d;
+ if (n != NULL) {
+ BN_free(r->n);
+ r->n = n;
+ }
+ if (e != NULL) {
+ BN_free(r->e);
+ r->e = e;
+ }
+ if (d != NULL) {
+ BN_free(r->d);
+ r->d = d;
+ }
return 1;
}
int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
{
- if (p == NULL || q == NULL)
+ /* If the fields in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ *
+ * It is an error to give the results from get0 on r
+ * as input parameters.
+ */
+ if (p == r->p || q == r->q)
return 0;
- BN_free(r->p);
- BN_free(r->q);
- r->p = p;
- r->q = q;
+ if (p != NULL) {
+ BN_free(r->p);
+ r->p = p;
+ }
+ if (q != NULL) {
+ BN_free(r->q);
+ r->q = q;
+ }
return 1;
}
int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
{
- if (dmp1 == NULL || dmq1 == NULL || iqmp == NULL)
+ /* If the fields in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ *
+ * It is an error to give the results from get0 on r
+ * as input parameters.
+ */
+ if (dmp1 == r->dmp1 || dmq1 == r->dmq1 || iqmp == r->iqmp)
return 0;
- BN_free(r->dmp1);
- BN_free(r->dmq1);
- BN_free(r->iqmp);
- r->dmp1 = dmp1;
- r->dmq1 = dmq1;
- r->iqmp = iqmp;
+ if (dmp1 != NULL) {
+ BN_free(r->dmp1);
+ r->dmp1 = dmp1;
+ }
+ if (dmq1 != NULL) {
+ BN_free(r->dmq1);
+ r->dmq1 = dmq1;
+ }
+ if (iqmp != NULL) {
+ BN_free(r->iqmp);
+ r->iqmp = iqmp;
+ }
return 1;
}