Fix RSA_X931_derive_ex
authorMatt Caswell <matt@openssl.org>
Wed, 11 Mar 2015 17:43:38 +0000 (17:43 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 12 Mar 2015 09:26:14 +0000 (09:26 +0000)
In the RSA_X931_derive_ex a call to BN_CTX_new is made. This can return
NULL on error. However the return value is not tested until *after* it is
derefed! Also at the top of the function a test is made to ensure that
|rsa| is not NULL. If it is we go to the "err" label. Unfortunately the
error handling code deref's rsa.

Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/rsa/rsa_x931g.c

index 74bf197e3702c65feec401c34acbc741f5a2a972..599161578440d97b59de84fc6e2389e089d60c96 100644 (file)
@@ -72,14 +72,15 @@ int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
 {
     BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL;
     BN_CTX *ctx = NULL, *ctx2 = NULL;
 {
     BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL;
     BN_CTX *ctx = NULL, *ctx2 = NULL;
+    int ret = 0;
 
     if (!rsa)
         goto err;
 
     ctx = BN_CTX_new();
 
     if (!rsa)
         goto err;
 
     ctx = BN_CTX_new();
-    BN_CTX_start(ctx);
     if (!ctx)
         goto err;
     if (!ctx)
         goto err;
+    BN_CTX_start(ctx);
 
     r0 = BN_CTX_get(ctx);
     r1 = BN_CTX_get(ctx);
 
     r0 = BN_CTX_get(ctx);
     r1 = BN_CTX_get(ctx);
@@ -176,6 +177,7 @@ int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
     /* calculate inverse of q mod p */
     rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2);
 
     /* calculate inverse of q mod p */
     rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2);
 
+    ret = 1;
  err:
     if (ctx) {
         BN_CTX_end(ctx);
  err:
     if (ctx) {
         BN_CTX_end(ctx);
@@ -183,11 +185,8 @@ int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
     }
     if (ctx2)
         BN_CTX_free(ctx2);
     }
     if (ctx2)
         BN_CTX_free(ctx2);
-    /* If this is set all calls successful */
-    if (rsa->iqmp != NULL)
-        return 1;
 
 
-    return 0;
+    return ret;
 
 }
 
 
 }