Param build: make structures opaque.
[openssl.git] / crypto / param_build.c
index db2182196c85e69e4fe9dbaaf5d7878c2a3c1220..11986d999b29edc3e66ee8afd063f9f192b6de52 100644 (file)
 #include <openssl/err.h>
 #include <openssl/cryptoerr.h>
 #include <openssl/params.h>
+#include <openssl/types.h>
 #include "internal/cryptlib.h"
-#include "internal/param_build.h"
+#include "openssl/param_build.h"
 
+/*
+ * The number of OSSL_PARAM elements a builder will allow.
+ */
+#define OSSL_PARAM_BLD_MAX          25
+
+/*
+ * Special internal param type to indicate the end of an allocate OSSL_PARAM
+ * array.
+ */
 #define OSSL_PARAM_ALLOCATED_END    127
 
+typedef struct {
+    const char *key;
+    int type;
+    int secure;
+    size_t size;
+    size_t alloc_blocks;
+    const BIGNUM *bn;
+    const void *string;
+    union {
+        /*
+         * These fields are never directly addressed, but their sizes are
+         * imporant so that all native types can be copied here without overrun.
+         */
+        ossl_intmax_t i;
+        ossl_uintmax_t u;
+        double d;
+    } num;
+} OSSL_PARAM_BLD_DEF;
+
+struct ossl_param_bld_st {
+    size_t curr;
+    size_t total_blocks;
+    size_t secure_blocks;
+    OSSL_PARAM_BLD_DEF params[OSSL_PARAM_BLD_MAX];
+};
+
 typedef union {
     OSSL_UNION_ALIGN;
 } OSSL_PARAM_BLD_BLOCK;
@@ -66,100 +102,114 @@ static int param_push_num(OSSL_PARAM_BLD *bld, const char *key,
     return 1;
 }
 
-void ossl_param_bld_init(OSSL_PARAM_BLD *bld)
+OSSL_PARAM_BLD *OSSL_PARAM_BLD_new(void)
 {
-    memset(bld, 0, sizeof(*bld));
+    return OPENSSL_zalloc(sizeof(OSSL_PARAM_BLD));
 }
 
-int ossl_param_bld_push_int(OSSL_PARAM_BLD *bld, const char *key, int num)
+void OSSL_PARAM_BLD_free(OSSL_PARAM_BLD *bld)
+{
+    OPENSSL_free(bld);
+}
+
+int OSSL_PARAM_BLD_push_int(OSSL_PARAM_BLD *bld, const char *key, int num)
 {
     return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
 }
 
-int ossl_param_bld_push_uint(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_uint(OSSL_PARAM_BLD *bld, const char *key,
                              unsigned int num)
 {
     return param_push_num(bld, key, &num, sizeof(num),
                           OSSL_PARAM_UNSIGNED_INTEGER);
 }
 
-int ossl_param_bld_push_long(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_long(OSSL_PARAM_BLD *bld, const char *key,
                              long int num)
 {
     return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
 }
 
-int ossl_param_bld_push_ulong(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_ulong(OSSL_PARAM_BLD *bld, const char *key,
                               unsigned long int num)
 {
     return param_push_num(bld, key, &num, sizeof(num),
                           OSSL_PARAM_UNSIGNED_INTEGER);
 }
 
-int ossl_param_bld_push_int32(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD *bld, const char *key,
                               int32_t num)
 {
     return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
 }
 
-int ossl_param_bld_push_uint32(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_uint32(OSSL_PARAM_BLD *bld, const char *key,
                                uint32_t num)
 {
     return param_push_num(bld, key, &num, sizeof(num),
                           OSSL_PARAM_UNSIGNED_INTEGER);
 }
 
-int ossl_param_bld_push_int64(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_int64(OSSL_PARAM_BLD *bld, const char *key,
                               int64_t num)
 {
     return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
 }
 
-int ossl_param_bld_push_uint64(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_uint64(OSSL_PARAM_BLD *bld, const char *key,
                                uint64_t num)
 {
     return param_push_num(bld, key, &num, sizeof(num),
                           OSSL_PARAM_UNSIGNED_INTEGER);
 }
 
-int ossl_param_bld_push_size_t(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_size_t(OSSL_PARAM_BLD *bld, const char *key,
                                size_t num)
 {
     return param_push_num(bld, key, &num, sizeof(num),
                           OSSL_PARAM_UNSIGNED_INTEGER);
 }
 
-int ossl_param_bld_push_double(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_double(OSSL_PARAM_BLD *bld, const char *key,
                                double num)
 {
     return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_REAL);
 }
 
-int ossl_param_bld_push_BN(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;
     return 1;
 }
 
-int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
                                     const char *buf, size_t bsize)
 {
     OSSL_PARAM_BLD_DEF *pd;
@@ -178,7 +228,7 @@ int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
     return 1;
 }
 
-int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
                                  char *buf, size_t bsize)
 {
     OSSL_PARAM_BLD_DEF *pd;
@@ -197,7 +247,7 @@ int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
     return 1;
 }
 
-int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
                                      const void *buf, size_t bsize)
 {
     OSSL_PARAM_BLD_DEF *pd;
@@ -214,7 +264,7 @@ int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
     return 1;
 }
 
-int ossl_param_bld_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key,
+int OSSL_PARAM_BLD_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key,
                                   void *buf, size_t bsize)
 {
     OSSL_PARAM_BLD_DEF *pd;
@@ -260,7 +310,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)
@@ -279,7 +329,7 @@ static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param,
     return param + i;
 }
 
-OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld)
+OSSL_PARAM *OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld)
 {
     OSSL_PARAM_BLD_BLOCK *blk, *s = NULL;
     OSSL_PARAM *params, *last;
@@ -292,12 +342,14 @@ OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld)
         if (s == NULL) {
             CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM,
                       CRYPTO_R_SECURE_MALLOC_FAILURE);
+            OPENSSL_free(bld);
             return NULL;
         }
     }
     params = OPENSSL_malloc(total);
     if (params == NULL) {
         CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(bld);
         OPENSSL_secure_free(s);
         return NULL;
     }
@@ -306,10 +358,13 @@ OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld)
     last->data_size = ss;
     last->data = s;
     last->data_type = OSSL_PARAM_ALLOCATED_END;
+
+    /* Reset for reuse */
+    memset(bld, 0, sizeof(*bld));
     return params;
 }
 
-void ossl_param_bld_free(OSSL_PARAM *params)
+void OSSL_PARAM_BLD_free_params(OSSL_PARAM *params)
 {
     if (params != NULL) {
         OSSL_PARAM *p;
@@ -321,33 +376,3 @@ void ossl_param_bld_free(OSSL_PARAM *params)
         OPENSSL_free(params);
     }
 }
-
-OSSL_PARAM *ossl_param_bld_to_param_ex(OSSL_PARAM_BLD *bld, OSSL_PARAM *params,
-                                       size_t param_n, void *data,
-                                       size_t data_n, void *secure,
-                                       size_t secure_n)
-{
-    if (params == NULL || data == NULL) {
-        CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX,
-                  CRYPTO_R_INVALID_NULL_ARGUMENT);
-        return NULL;
-    }
-    if (param_n < bld->curr + 1) {
-        CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX,
-                  CRYPTO_R_INSUFFICIENT_PARAM_SIZE);
-        return NULL;
-    }
-    if (data_n < ALIGN_SIZE * bld->total_blocks) {
-        CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX,
-                  CRYPTO_R_INSUFFICIENT_DATA_SPACE);
-        return NULL;
-    }
-    if (bld->secure_blocks > 0 && secure_n < ALIGN_SIZE * bld->secure_blocks) {
-        CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX,
-                  CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE);
-        return NULL;
-    }
-    param_bld_convert(bld, params, (OSSL_PARAM_BLD_BLOCK *)data,
-                      (OSSL_PARAM_BLD_BLOCK *)secure);
-    return params;
-}