Fix init_thread_stop
[openssl.git] / crypto / param_build.c
index 851b735896035d645412a8f9a8cec9a650f7ac9b..21bed31393fd8be89acc27e2a6acf74aadb69882 100644 (file)
@@ -15,6 +15,8 @@
 #include "internal/cryptlib.h"
 #include "internal/param_build.h"
 
+#define OSSL_PARAM_ALLOCATED_END    127
+
 typedef union {
     OSSL_UNION_ALIGN;
 } OSSL_PARAM_BLD_BLOCK;
@@ -136,21 +138,30 @@ int ossl_param_bld_push_double(OSSL_PARAM_BLD *bld, const char *key,
 int ossl_param_bld_push_BN(OSSL_PARAM_BLD *bld, const char *key,
                            const BIGNUM *bn)
 {
-    int sz = -1, secure = 0;
+    return ossl_param_bld_push_BN_pad(bld, key, bn,
+                                      bn == NULL ? 0 : BN_num_bytes(bn));
+}
+
+int ossl_param_bld_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key,
+                               const BIGNUM *bn, size_t sz)
+{
+    int n, secure = 0;
     OSSL_PARAM_BLD_DEF *pd;
 
     if (bn != NULL) {
-        sz = BN_num_bytes(bn);
-        if (sz < 0) {
-            CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_BN,
-                      CRYPTO_R_ZERO_LENGTH_NUMBER);
+        n = BN_num_bytes(bn);
+        if (n < 0) {
+            CRYPTOerr(0, CRYPTO_R_ZERO_LENGTH_NUMBER);
+            return 0;
+        }
+        if (sz < (size_t)n) {
+            CRYPTOerr(0, CRYPTO_R_TOO_SMALL_BUFFER);
             return 0;
         }
         if (BN_get_flags(bn, BN_FLG_SECURE) == BN_FLG_SECURE)
             secure = 1;
     }
-    pd = param_push(bld, key, sz, sz >= 0 ? sz : 0,
-                    OSSL_PARAM_UNSIGNED_INTEGER, secure);
+    pd = param_push(bld, key, sz, sz, OSSL_PARAM_UNSIGNED_INTEGER, secure);
     if (pd == NULL)
         return 0;
     pd->bn = bn;
@@ -158,7 +169,7 @@ int ossl_param_bld_push_BN(OSSL_PARAM_BLD *bld, const char *key,
 }
 
 int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
-                                    char *buf, size_t bsize)
+                                    const char *buf, size_t bsize)
 {
     OSSL_PARAM_BLD_DEF *pd;
 
@@ -196,7 +207,7 @@ int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
 }
 
 int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
-                                     void *buf, size_t bsize)
+                                     const void *buf, size_t bsize)
 {
     OSSL_PARAM_BLD_DEF *pd;
 
@@ -258,7 +269,7 @@ static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param,
         } else if (pd->type == OSSL_PARAM_OCTET_PTR
                    || pd->type == OSSL_PARAM_UTF8_PTR) {
             /* PTR */
-            *(void **)p = pd->string;
+            *(const void **)p = pd->string;
         } else if (pd->type == OSSL_PARAM_OCTET_STRING
                    || pd->type == OSSL_PARAM_UTF8_STRING) {
             if (pd->string != NULL)
@@ -274,40 +285,50 @@ static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param,
         }
     }
     param[i] = OSSL_PARAM_construct_end();
-    return param;
+    return param + i;
 }
 
-OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld, void **secure)
+OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld)
 {
     OSSL_PARAM_BLD_BLOCK *blk, *s = NULL;
-    OSSL_PARAM *param;
-    const size_t p_blks = bytes_to_blocks((bld->curr + 1) * sizeof(*param));
+    OSSL_PARAM *params, *last;
+    const size_t p_blks = bytes_to_blocks((1 + bld->curr) * sizeof(*params));
     const size_t total = ALIGN_SIZE * (p_blks + bld->total_blocks);
+    const size_t ss = ALIGN_SIZE * bld->secure_blocks;
 
-    if (bld->secure_blocks > 0) {
-        if (secure == NULL) {
-            CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM,
-                      CRYPTO_R_INVALID_NULL_ARGUMENT);
-            return NULL;
-        }
-        s = OPENSSL_secure_malloc(bld->secure_blocks * ALIGN_SIZE);
+    if (ss > 0) {
+        s = OPENSSL_secure_malloc(ss);
         if (s == NULL) {
             CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM,
                       CRYPTO_R_SECURE_MALLOC_FAILURE);
             return NULL;
         }
     }
-    param = OPENSSL_malloc(total);
-    if (param == NULL) {
+    params = OPENSSL_malloc(total);
+    if (params == NULL) {
         CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM, ERR_R_MALLOC_FAILURE);
         OPENSSL_secure_free(s);
         return NULL;
     }
-    if (secure != NULL)
-        *secure = s;
-    blk = p_blks + (OSSL_PARAM_BLD_BLOCK *)(param);
-    param_bld_convert(bld, param, blk, s);
-    return param;
+    blk = p_blks + (OSSL_PARAM_BLD_BLOCK *)(params);
+    last = param_bld_convert(bld, params, blk, s);
+    last->data_size = ss;
+    last->data = s;
+    last->data_type = OSSL_PARAM_ALLOCATED_END;
+    return params;
+}
+
+void ossl_param_bld_free(OSSL_PARAM *params)
+{
+    if (params != NULL) {
+        OSSL_PARAM *p;
+
+        for (p = params; p->key != NULL; p++)
+            ;
+        if (p->data_type == OSSL_PARAM_ALLOCATED_END)
+            OPENSSL_secure_clear_free(p->data, p->data_size);
+        OPENSSL_free(params);
+    }
 }
 
 OSSL_PARAM *ossl_param_bld_to_param_ex(OSSL_PARAM_BLD *bld, OSSL_PARAM *params,