srp: fix double free,
[openssl.git] / crypto / srp / srp_vfy.c
index 4ed94b7fb230c6e69bfa770959d9ae6a94169862..2c2ec11cd4d88fe9a0d45b4d721aa20fe19a2aa7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2004, EdelKey Project. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * for the EdelKey project.
  */
 
+/* All the SRP APIs in this file are deprecated */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
 #ifndef OPENSSL_NO_SRP
 # include "internal/cryptlib.h"
-# include "internal/evp_int.h"
+# include "crypto/evp.h"
 # include <openssl/sha.h>
 # include <openssl/srp.h>
 # include <openssl/evp.h>
@@ -187,9 +190,9 @@ void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
 SRP_user_pwd *SRP_user_pwd_new(void)
 {
     SRP_user_pwd *ret;
-    
+
     if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
-        /* SRPerr(SRP_F_SRP_USER_PWD_NEW, ERR_R_MALLOC_FAILURE); */ /*ckerr_ignore*/
+        /* ERR_raise(ERR_LIB_SRP, ERR_R_MALLOC_FAILURE); */ /*ckerr_ignore*/
         return NULL;
     }
     ret->N = NULL;
@@ -525,7 +528,7 @@ int SRP_VBASE_add0_user(SRP_VBASE *vb, SRP_user_pwd *user_pwd)
     return 1;
 }
 
-# if !OPENSSL_API_1_1_0
+# ifndef OPENSSL_NO_DEPRECATED_1_1_0
 /*
  * DEPRECATED: use SRP_VBASE_get1_by_user instead.
  * This method ignores the configured seed and fails for an unknown user.
@@ -594,8 +597,9 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
 /*
  * create a verifier (*salt,*verifier,g and N are in base64)
  */
-char *SRP_create_verifier(const char *user, const char *pass, char **salt,
-                          char **verifier, const char *N, const char *g)
+char *SRP_create_verifier_ex(const char *user, const char *pass, char **salt,
+                             char **verifier, const char *N, const char *g,
+                             OSSL_LIB_CTX *libctx, const char *propq)
 {
     int len;
     char *result = NULL, *vf = NULL;
@@ -614,10 +618,14 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
         if ((len = t_fromb64(tmp, sizeof(tmp), N)) <= 0)
             goto err;
         N_bn_alloc = BN_bin2bn(tmp, len, NULL);
+        if (N_bn_alloc == NULL)
+            goto err;
         N_bn = N_bn_alloc;
         if ((len = t_fromb64(tmp, sizeof(tmp) ,g)) <= 0)
             goto err;
         g_bn_alloc = BN_bin2bn(tmp, len, NULL);
+        if (g_bn_alloc == NULL)
+            goto err;
         g_bn = g_bn_alloc;
         defgNid = "*";
     } else {
@@ -630,7 +638,7 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
     }
 
     if (*salt == NULL) {
-        if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
+        if (RAND_bytes_ex(libctx, tmp2, SRP_RANDOM_SALT_LEN) <= 0)
             goto err;
 
         s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
@@ -639,15 +647,20 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
             goto err;
         s = BN_bin2bn(tmp2, len, NULL);
     }
+    if (s == NULL)
+        goto err;
 
-    if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn))
+    if (!SRP_create_verifier_BN_ex(user, pass, &s, &v, N_bn, g_bn, libctx,
+                                   propq))
         goto err;
 
-    BN_bn2bin(v, tmp);
+    if (BN_bn2bin(v, tmp) < 0)
+        goto err;
     vfsize = BN_num_bytes(v) * 2;
     if (((vf = OPENSSL_malloc(vfsize)) == NULL))
         goto err;
-    t_tob64(vf, tmp, BN_num_bytes(v));
+    if (!t_tob64(vf, tmp, BN_num_bytes(v)))
+        goto err;
 
     if (*salt == NULL) {
         char *tmp_salt;
@@ -655,7 +668,10 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
         if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) {
             goto err;
         }
-        t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
+        if (!t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN)) {
+            OPENSSL_free(tmp_salt);
+            goto err;
+        }
         *salt = tmp_salt;
     }
 
@@ -672,6 +688,12 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
     return result;
 }
 
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+                          char **verifier, const char *N, const char *g)
+{
+    return SRP_create_verifier_ex(user, pass, salt, verifier, N, g, NULL, NULL);
+}
+
 /*
  * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL
  * then the provided salt will be used. On successful exit *verifier will point
@@ -681,15 +703,16 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
  * The caller is responsible for freeing the allocated *salt and *verifier
  * BIGNUMS.
  */
-int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
-                           BIGNUM **verifier, const BIGNUM *N,
-                           const BIGNUM *g)
+int SRP_create_verifier_BN_ex(const char *user, const char *pass, BIGNUM **salt,
+                              BIGNUM **verifier, const BIGNUM *N,
+                              const BIGNUM *g, OSSL_LIB_CTX *libctx,
+                              const char *propq)
 {
     int result = 0;
     BIGNUM *x = NULL;
-    BN_CTX *bn_ctx = BN_CTX_new();
+    BN_CTX *bn_ctx = BN_CTX_new_ex(libctx);
     unsigned char tmp2[MAX_LEN];
-    BIGNUM *salttmp = NULL;
+    BIGNUM *salttmp = NULL, *verif;
 
     if ((user == NULL) ||
         (pass == NULL) ||
@@ -698,27 +721,32 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
         goto err;
 
     if (*salt == NULL) {
-        if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
+        if (RAND_bytes_ex(libctx, tmp2, SRP_RANDOM_SALT_LEN) <= 0)
             goto err;
 
         salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
+        if (salttmp == NULL)
+            goto err;
     } else {
         salttmp = *salt;
     }
 
-    x = SRP_Calc_x(salttmp, user, pass);
+    x = SRP_Calc_x_ex(salttmp, user, pass, libctx, propq);
+    if (x == NULL)
+        goto err;
 
-    *verifier = BN_new();
-    if (*verifier == NULL)
+    verif = BN_new();
+    if (verif == NULL)
         goto err;
 
-    if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) {
-        BN_clear_free(*verifier);
+    if (!BN_mod_exp(verif, g, x, N, bn_ctx)) {
+        BN_clear_free(verif);
         goto err;
     }
 
     result = 1;
     *salt = salttmp;
+    *verifier = verif;
 
  err:
     if (salt != NULL && *salt != salttmp)
@@ -728,4 +756,11 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
     return result;
 }
 
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
+                           BIGNUM **verifier, const BIGNUM *N,
+                           const BIGNUM *g)
+{
+    return SRP_create_verifier_BN_ex(user, pass, salt, verifier, N, g, NULL,
+                                     NULL);
+}
 #endif