A fuller implementation of PARAMS_TEMPLATE as per #9266 but renamed.
This introduces a statis data type which can be used to constructor a
description of a parameter array. It can then be converted into a OSSL_PARAM
array and the allocated storage freed by a single call to OPENSSL_free.
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9305)
$UTIL_COMMON=\
cryptlib.c params.c bsearch.c ex_data.c o_str.c \
ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \
- context.c sparse_array.c $CPUIDASM
+ context.c sparse_array.c param_build.c $CPUIDASM
$UTIL_DEFINE=$CPUIDDEF
SOURCE[../libcrypto]=$UTIL_COMMON \
"fips mode not supported"},
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ILLEGAL_HEX_DIGIT),
"illegal hex digit"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_DATA_SPACE),
+ "insufficient data space"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_PARAM_SIZE),
+ "insufficient param size"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE),
+ "insufficient secure data space"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_NULL_ARGUMENT),
+ "invalid null argument"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_OSSL_PARAM_TYPE),
+ "invalid ossl param type"},
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ODD_NUMBER_OF_DIGITS),
"odd number of digits"},
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_ALREADY_EXISTS),
"provider already exists"},
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_SECTION_ERROR),
"provider section error"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_SECURE_MALLOC_FAILURE),
+ "secure malloc failure"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_STRING_TOO_LONG), "string too long"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_BYTES), "too many bytes"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_RECORDS),
+ "too many records"},
+ {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ZERO_LENGTH_NUMBER),
+ "zero length number"},
{0, NULL}
};
CRYPTO_F_OPENSSL_LH_NEW:126:OPENSSL_LH_new
CRYPTO_F_OPENSSL_SK_DEEP_COPY:127:OPENSSL_sk_deep_copy
CRYPTO_F_OPENSSL_SK_DUP:128:OPENSSL_sk_dup
+CRYPTO_F_OSSL_PARAM_BLD_PUSH_BN:143:
+CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_PTR:144:
+CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_STRING:145:
+CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_PTR:146:
+CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_STRING:147:
+CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM:148:
+CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX:149:
+CRYPTO_F_OSSL_PARAM_TYPE_TO_PARAM:150:
CRYPTO_F_OSSL_PROVIDER_ACTIVATE:130:ossl_provider_activate
CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN:132:OSSL_PROVIDER_add_builtin
CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER:139:ossl_provider_add_parameter
CRYPTO_F_OSSL_PROVIDER_NEW:131:ossl_provider_new
CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH:140:ossl_provider_set_module_path
+CRYPTO_F_PARAM_PUSH:151:
+CRYPTO_F_PARAM_PUSH_NUM:152:
CRYPTO_F_PKEY_HMAC_INIT:123:pkey_hmac_init
CRYPTO_F_PKEY_POLY1305_INIT:124:pkey_poly1305_init
CRYPTO_F_PKEY_SIPHASH_INIT:125:pkey_siphash_init
EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate
EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate
-EVP_F_EVP_KEYEXCH_FROM_DISPATCH:244:evp_keyexch_from_dispatch
EVP_F_EVP_KDF_CTRL:224:EVP_KDF_ctrl
EVP_F_EVP_KDF_CTRL_STR:225:EVP_KDF_ctrl_str
EVP_F_EVP_KDF_CTX_NEW:240:EVP_KDF_CTX_new
EVP_F_EVP_KDF_CTX_NEW_ID:226:EVP_KDF_CTX_new_id
+EVP_F_EVP_KEYEXCH_FROM_DISPATCH:244:evp_keyexch_from_dispatch
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
EVP_F_EVP_MAC_CTX_DUP:211:EVP_MAC_CTX_dup
CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted
CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported
CRYPTO_R_ILLEGAL_HEX_DIGIT:102:illegal hex digit
+CRYPTO_R_INSUFFICIENT_DATA_SPACE:106:insufficient data space
+CRYPTO_R_INSUFFICIENT_PARAM_SIZE:107:insufficient param size
+CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE:108:insufficient secure data space
+CRYPTO_R_INVALID_NULL_ARGUMENT:109:invalid null argument
+CRYPTO_R_INVALID_OSSL_PARAM_TYPE:110:invalid ossl param type
CRYPTO_R_ODD_NUMBER_OF_DIGITS:103:odd number of digits
CRYPTO_R_PROVIDER_ALREADY_EXISTS:104:provider already exists
CRYPTO_R_PROVIDER_SECTION_ERROR:105:provider section error
+CRYPTO_R_SECURE_MALLOC_FAILURE:111:secure malloc failure
+CRYPTO_R_STRING_TOO_LONG:112:string too long
+CRYPTO_R_TOO_MANY_BYTES:113:too many bytes
+CRYPTO_R_TOO_MANY_RECORDS:114:too many records
+CRYPTO_R_ZERO_LENGTH_NUMBER:115:zero length number
CT_R_BASE64_DECODE_ERROR:108:base64 decode error
CT_R_INVALID_LOG_ID_LENGTH:100:invalid log id length
CT_R_LOG_CONF_INVALID:109:log conf invalid
--- /dev/null
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/cryptoerr.h>
+#include <openssl/params.h>
+#include "internal/cryptlib.h"
+#include "internal/param_build.h"
+
+typedef union {
+ OSSL_UNION_ALIGN;
+} OSSL_PARAM_BLD_BLOCK;
+
+#define ALIGN_SIZE sizeof(OSSL_PARAM_BLD_BLOCK)
+
+static size_t bytes_to_blocks(size_t bytes)
+{
+ return (bytes + ALIGN_SIZE - 1) / ALIGN_SIZE;
+}
+
+static OSSL_PARAM_BLD_DEF *param_push(OSSL_PARAM_BLD *bld, const char *key,
+ int size, size_t alloc, int type,
+ int secure)
+{
+ OSSL_PARAM_BLD_DEF *pd;
+
+ if (bld->curr >= OSSL_PARAM_BLD_MAX) {
+ CRYPTOerr(CRYPTO_F_PARAM_PUSH, CRYPTO_R_TOO_MANY_RECORDS);
+ return NULL;
+ }
+ pd = bld->params + bld->curr++;
+ memset(pd, 0, sizeof(*pd));
+ pd->key = key;
+ pd->type = type;
+ pd->size = size;
+ pd->alloc_blocks = bytes_to_blocks(size);
+ if ((pd->secure = secure) != 0)
+ bld->secure_blocks += pd->alloc_blocks;
+ else
+ bld->total_blocks += pd->alloc_blocks;
+ return pd;
+}
+
+static int param_push_num(OSSL_PARAM_BLD *bld, const char *key,
+ void *num, size_t size, int type)
+{
+ OSSL_PARAM_BLD_DEF *pd = param_push(bld, key, size, size, type, 0);
+
+ if (pd == NULL)
+ return 0;
+ if (size > sizeof(pd->num)) {
+ CRYPTOerr(CRYPTO_F_PARAM_PUSH_NUM, CRYPTO_R_TOO_MANY_BYTES);
+ return 0;
+ }
+ memcpy(&pd->num, num, size);
+ return 1;
+}
+
+void ossl_param_bld_init(OSSL_PARAM_BLD *bld)
+{
+ memset(bld, 0, sizeof(*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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ const BIGNUM *bn)
+{
+ int sz = -1, 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);
+ 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);
+ if (pd == NULL)
+ return 0;
+ pd->bn = bn;
+ return 1;
+}
+
+int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
+ char *buf, size_t bsize)
+{
+ OSSL_PARAM_BLD_DEF *pd;
+
+ if (bsize == 0) {
+ bsize = strlen(buf) + 1;
+ } else if (bsize > INT_MAX) {
+ CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_STRING,
+ CRYPTO_R_STRING_TOO_LONG);
+ return 0;
+ }
+ pd = param_push(bld, key, bsize, bsize, OSSL_PARAM_UTF8_STRING, 0);
+ if (pd == NULL)
+ return 0;
+ pd->string = buf;
+ return 1;
+}
+
+int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
+ char *buf, size_t bsize)
+{
+ OSSL_PARAM_BLD_DEF *pd;
+
+ if (bsize == 0) {
+ bsize = strlen(buf) + 1;
+ } else if (bsize > INT_MAX) {
+ CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_PTR,
+ CRYPTO_R_STRING_TOO_LONG);
+ return 0;
+ }
+ pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_UTF8_PTR, 0);
+ if (pd == NULL)
+ return 0;
+ pd->string = buf;
+ return 1;
+}
+
+int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
+ void *buf, size_t bsize)
+{
+ OSSL_PARAM_BLD_DEF *pd;
+
+ if (bsize > INT_MAX) {
+ CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_STRING,
+ CRYPTO_R_STRING_TOO_LONG);
+ return 0;
+ }
+ pd = param_push(bld, key, bsize, bsize, OSSL_PARAM_OCTET_STRING, 0);
+ if (pd == NULL)
+ return 0;
+ pd->string = buf;
+ return 1;
+}
+
+int ossl_param_bld_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key,
+ void *buf, size_t bsize)
+{
+ OSSL_PARAM_BLD_DEF *pd;
+
+ if (bsize > INT_MAX) {
+ CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_PTR,
+ CRYPTO_R_STRING_TOO_LONG);
+ return 0;
+ }
+ pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_OCTET_PTR, 0);
+ if (pd == NULL)
+ return 0;
+ pd->string = buf;
+ return 1;
+}
+
+static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param,
+ OSSL_PARAM_BLD_BLOCK *blk,
+ OSSL_PARAM_BLD_BLOCK *secure)
+{
+ size_t i;
+ OSSL_PARAM_BLD_DEF *pd;
+ void *p;
+
+ for (i = 0; i < bld->curr; i++) {
+ pd = bld->params + i;
+ param[i].key = pd->key;
+ param[i].data_type = pd->type;
+ param[i].data_size = pd->size;
+ param[i].return_size = 0;
+
+ if (pd->secure) {
+ p = secure;
+ secure += pd->alloc_blocks;
+ } else {
+ p = blk;
+ blk += pd->alloc_blocks;
+ }
+ param[i].data = p;
+ if (pd->bn != NULL) {
+ /* BIGNUM */
+ BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size);
+ } else if (pd->type == OSSL_PARAM_OCTET_PTR
+ || pd->type == OSSL_PARAM_UTF8_PTR) {
+ /* PTR */
+ *(void **)p = pd->string;
+ } else if (pd->type == OSSL_PARAM_OCTET_STRING
+ || pd->type == OSSL_PARAM_UTF8_STRING) {
+ if (pd->string != NULL)
+ memcpy(p, pd->string, pd->size);
+ else
+ memset(p, 0, pd->size);
+ } else {
+ /* Number, but could also be a NULL BIGNUM */
+ if (pd->size > sizeof(pd->num))
+ memset(p, 0, pd->size);
+ else if (pd->size > 0)
+ memcpy(p, &pd->num, pd->size);
+ }
+ }
+ param[i] = OSSL_PARAM_construct_end();
+ return param;
+}
+
+OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld, void **secure)
+{
+ OSSL_PARAM_BLD_BLOCK *blk, *s = NULL;
+ OSSL_PARAM *param;
+ const size_t p_blks = bytes_to_blocks((bld->curr + 1) * sizeof(*param));
+ const size_t total = ALIGN_SIZE * (p_blks + bld->total_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 (s == NULL) {
+ CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM,
+ CRYPTO_R_SECURE_MALLOC_FAILURE);
+ return NULL;
+ }
+ }
+ param = OPENSSL_malloc(total);
+ if (param == 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;
+}
+
+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;
+}
--- /dev/null
+=pod
+
+=head1 NAME
+
+ossl_param_build_init,
+ossl_param_build_to_param, ossl_param_build_push_int,
+ossl_param_build_push_uint, ossl_param_build_push_long,
+ossl_param_build_push_ulong, ossl_param_build_push_int32,
+ossl_param_build_push_uint32, ossl_param_build_push_int64,
+ossl_param_build_push_uint64, ossl_param_build_push_size_t,
+ossl_param_build_push_double, ossl_param_build_push_BN,
+ossl_param_build_push_utf8_string, ossl_param_build_push_utf8_ptr,
+ossl_param_build_push_octet_string, ossl_param_build_push_octet_ptr
+- functions to assist in the creation of OSSL_PARAM arrays
+
+=head1 SYNOPSIS
+
+=for comment generic
+
+ #include "internal/params_template.h"
+
+ #define OSSL_PARAM_BLD_MAX 10
+ typedef struct { ... } OSSL_PARAM_BLD;
+
+ void ossl_param_build_init(OSSL_PARAM_BLD *bld);
+ OSSL_PARAM *ossl_param_build_to_param(OSSL_PARAM_BLD *bld, void **secure);
+ OSSL_PARAM *ossl_param_build_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);
+
+ int ossl_param_build_push_TYPE(OSSL_PARAM_BLD *bld, const char *key, TYPE val);
+
+ int ossl_param_build_push_BN(OSSL_PARAM_BLD *bld, const char *key,
+ const BIGNUM *bn);
+
+ int ossl_param_build_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
+ char *buf, size_t bsize);
+ int ossl_param_build_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
+ char *buf, size_t bsize);
+ int ossl_param_build_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
+ void *buf, size_t bsize);
+ int ossl_param_build_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key,
+ void *buf, size_t bsize);
+
+
+=head1 DESCRIPTION
+
+A collection of utility functions that simplify the creation of OSSL_PARAM
+arrays. The B<TYPE> names are as per L<OSSL_PARAM_int(3)>.
+
+ossl_param_build_init() initialises the OSSL_PARAM_BLD structure so that values
+can be added.
+Any existing values are cleared.
+
+ossl_param_build_to_param() converts a built up OSSL_PARAM_BLD structure
+B<bld> into an allocated OSSL_PARAM array.
+The pointer referenced by the B<secure> argument is set to point to an
+allocated block of secure memory if required and to NULL it not.
+The OSSL_PARAM array and all associated storage can be freed by calling
+OPENSSL_free() with the functions return value and OPENSSL_secure_free()
+with the pointer referenced by B<secure>.
+
+ossl_param_build_to_param_ex() behaves like ossl_param_build_to_param(), except that
+no additional memory is allocated.
+An OSSL_PARAM array of at least B<param_n> elements is passed in as B<params>.
+The auxiliary storage for the parameters is a block of memory pointed to
+by B<data> of at least B<data_n> bytes in size.
+If required, secure memory for private BIGNUMs should be pointed to by
+B<secure> of at least B<secure_n> bytes in size.
+
+ossl_param_build_push_TYPE() are a series of functions which will create
+OSSL_PARAM objects of the specified size and correct type for the B<val>
+argument.
+B<val> is stored by value and an expression or auto variable can be used.
+
+ossl_param_build_push_BN() is a function that will create an OSSL_PARAM object
+that holds the specified BIGNUM B<bn>.
+If B<bn> is marked as being securely allocated, the secure flag is
+set in the OSSL_PARAM_BLD structure.
+The B<bn> argument is stored by reference and the underlying BIGNUM object
+must exist until after ossl_param_build_to_param() has been called.
+
+ossl_param_build_push_utf8_string() is a function that will create an OSSL_PARAM
+object that references the UTF8 string specified by B<buf>.
+If the length of the string, B<bsize>, is zero then it will be calculated.
+The string that B<buf> points to is stored by reference and must remain in
+scope until after ossl_param_build_to_param() has been called.
+
+ossl_param_build_push_octet_string() is a function that will create an OSSL_PARAM
+object that references the octet string specified by B<buf> and <bsize>.
+The memory that B<buf> points to is stored by reference and must remain in
+scope until after ossl_param_build_to_param() has been called.
+
+ossl_param_build_push_utf8_ptr() is a function that will create an OSSL_PARAM
+object that references the UTF8 string specified by B<buf>.
+If the length of the string, B<bsize>, is zero then it will be calculated.
+The string B<buf> points to is stored by reference and must remain in
+scope until the OSSL_PARAM array is freed.
+
+ossl_param_build_push_octet_ptr() is a function that will create an OSSL_PARAM
+object that references the octet string specified by B<buf>.
+The memory B<buf> points to is stored by reference and must remain in
+scope until the OSSL_PARAM array is freed.
+
+=head1 RETURN VALUES
+
+ossl_param_build_to_param() and ossl_param_bld_to_param_ex() return the
+allocated OSSL_PARAM array, or NULL on error.
+
+All of the ossl_param_build_push_TYPE functions return 1 on success and 0
+on error.
+
+=head1 NOTES
+
+The constant B<OSSL_PARAM_BLD_MAX> specifies the maximum number of parameters
+that can be added.
+Exceeding this will result in the push functions returning errors.
+
+The structure B<OSSL_PARAM_BLD> should be considered opaque and subject to
+change between versions.
+
+=head1 EXAMPLES
+
+Both examples creating an OSSL_PARAM array that contains an RSA key.
+For both, the predefined key variables are:
+
+ BIGNUM *p, *q; /* both prime */
+ BIGNUM *n; /* = p * q */
+ unsigned int e; /* exponent, usually 65537 */
+ BIGNUM *d; /* e^-1 */
+
+=head2 Example 1
+
+This example shows how to create an OSSL_PARAM array that contains an RSA
+private key.
+
+ OSSL_PARAM_BLD bld;
+ OSSL_PARAM *params;
+ void *secure;
+
+ ossl_param_build_init(&bld, &secure);
+ if (!ossl_param_build_push_BN(&bld, "p", p)
+ || !ossl_param_build_push_BN(&bld, "q", q)
+ || !ossl_param_build_push_uint(&bld, "e", e)
+ || !ossl_param_build_push_BN(&bld, "n", n)
+ || !ossl_param_build_push_BN(&bld, "d", d)
+ || (params = ossl_param_build_to_param(&bld)) == NULL)
+ goto err;
+ /* Use params */
+ ...
+ OPENSSL_free(params);
+ OPENSSL_secure_free(secure);
+
+=head2 Example 2
+
+This example shows how to create an OSSL_PARAM array that contains an RSA
+public key.
+
+ OSSL_PARAM_BLD bld;
+ OSSL_PARAM *params;
+ void *secure;
+
+ ossl_param_build_init(&bld, &secure);
+ if (!ossl_param_build_push_BN(&bld, "n", n)
+ || !ossl_param_build_push_BN(&bld, "d", d)
+ || (params = ossl_param_build_to_param(&bld)) == NULL)
+ goto err;
+ /* Use params */
+ ...
+ OPENSSL_free(params);
+ OPENSSL_secure_free(secure);
+
+=head1 SEE ALSO
+
+L<OSSL_PARAM_int>, L<OSSL_PARAM>
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
--- /dev/null
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/params.h>
+#include <openssl/ossl_typ.h>
+
+#define OSSL_PARAM_BLD_MAX 10
+
+typedef struct {
+ const char *key;
+ int type;
+ int secure;
+ size_t size;
+ size_t alloc_blocks;
+ const BIGNUM *bn;
+ 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;
+
+typedef struct {
+ size_t curr;
+ size_t total_blocks;
+ size_t secure_blocks;
+ OSSL_PARAM_BLD_DEF params[OSSL_PARAM_BLD_MAX];
+} OSSL_PARAM_BLD;
+
+void ossl_param_bld_init(OSSL_PARAM_BLD *bld);
+OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld, void **secure);
+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);
+
+int ossl_param_bld_push_int(OSSL_PARAM_BLD *bld, const char *key, int val);
+int ossl_param_bld_push_uint(OSSL_PARAM_BLD *bld, const char *key,
+ unsigned int val);
+int ossl_param_bld_push_long(OSSL_PARAM_BLD *bld, const char *key,
+ long int val);
+int ossl_param_bld_push_ulong(OSSL_PARAM_BLD *bld, const char *key,
+ unsigned long int val);
+int ossl_param_bld_push_int32(OSSL_PARAM_BLD *bld, const char *key,
+ int32_t val);
+int ossl_param_bld_push_uint32(OSSL_PARAM_BLD *bld, const char *key,
+ uint32_t val);
+int ossl_param_bld_push_int64(OSSL_PARAM_BLD *bld, const char *key,
+ int64_t val);
+int ossl_param_bld_push_uint64(OSSL_PARAM_BLD *bld, const char *key,
+ uint64_t val);
+int ossl_param_bld_push_size_t(OSSL_PARAM_BLD *bld, const char *key,
+ size_t val);
+int ossl_param_bld_push_double(OSSL_PARAM_BLD *bld, const char *key,
+ double val);
+int ossl_param_bld_push_BN(OSSL_PARAM_BLD *bld, const char *key,
+ const BIGNUM *bn);
+int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
+ char *buf, size_t bsize);
+int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
+ char *buf, size_t bsize);
+int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
+ void *buf, size_t bsize);
+int ossl_param_bld_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key,
+ void *buf, size_t bsize);
# define CRYPTO_F_OPENSSL_LH_NEW 0
# define CRYPTO_F_OPENSSL_SK_DEEP_COPY 0
# define CRYPTO_F_OPENSSL_SK_DUP 0
+# define CRYPTO_F_OSSL_PARAM_BLD_PUSH_BN 0
+# define CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_PTR 0
+# define CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_STRING 0
+# define CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_PTR 0
+# define CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_STRING 0
+# define CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM 0
+# define CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX 0
+# define CRYPTO_F_OSSL_PARAM_TYPE_TO_PARAM 0
# define CRYPTO_F_OSSL_PROVIDER_ACTIVATE 0
# define CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN 0
# define CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER 0
# define CRYPTO_F_OSSL_PROVIDER_NEW 0
# define CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH 0
+# define CRYPTO_F_PARAM_PUSH 0
+# define CRYPTO_F_PARAM_PUSH_NUM 0
# define CRYPTO_F_PKEY_HMAC_INIT 0
# define CRYPTO_F_PKEY_POLY1305_INIT 0
# define CRYPTO_F_PKEY_SIPHASH_INIT 0
*/
# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101
# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102
+# define CRYPTO_R_INSUFFICIENT_DATA_SPACE 106
+# define CRYPTO_R_INSUFFICIENT_PARAM_SIZE 107
+# define CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE 108
+# define CRYPTO_R_INVALID_NULL_ARGUMENT 109
+# define CRYPTO_R_INVALID_OSSL_PARAM_TYPE 110
# define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103
# define CRYPTO_R_PROVIDER_ALREADY_EXISTS 104
# define CRYPTO_R_PROVIDER_SECTION_ERROR 105
+# define CRYPTO_R_SECURE_MALLOC_FAILURE 111
+# define CRYPTO_R_STRING_TOO_LONG 112
+# define CRYPTO_R_TOO_MANY_BYTES 113
+# define CRYPTO_R_TOO_MANY_RECORDS 114
+# define CRYPTO_R_ZERO_LENGTH_NUMBER 115
#endif
packettest asynctest secmemtest srptest memleaktest stack_test \
dtlsv1listentest ct_test threadstest afalgtest d2i_test \
ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \
- bio_callback_test bio_memleak_test \
+ bio_callback_test bio_memleak_test param_build_test \
bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \
pkey_meth_test pkey_meth_kdf_test evp_kdf_test uitest \
cipherbytes_test \
INCLUDE[params_conversion_test]=../include ../apps/include
DEPEND[params_conversion_test]=../libcrypto libtestutil.a
+ SOURCE[param_build_test]=param_build_test.c
+ INCLUDE[param_build_test]=../include ../apps/include
+ DEPEND[param_build_test]=../libcrypto.a libtestutil.a
+
SOURCE[sslapitest]=sslapitest.c ssltestlib.c
INCLUDE[sslapitest]=../include ../apps/include ..
DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a
--- /dev/null
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+#include <openssl/params.h>
+#include "internal/param_build.h"
+#include "internal/nelem.h"
+#include "testutil.h"
+
+static int template_public_test(void)
+{
+ OSSL_PARAM_BLD bld;
+ OSSL_PARAM *params = NULL, *p;
+ void *secure = (void *)"abc";
+ int i;
+ long int l;
+ int32_t i32;
+ int64_t i64;
+ double d;
+ char *utf = NULL;
+ const char *cutf;
+ int res = 0;
+
+ ossl_param_bld_init(&bld);
+ if (!TEST_true(ossl_param_bld_push_int(&bld, "i", -6))
+ || !TEST_true(ossl_param_bld_push_long(&bld, "l", 42))
+ || !TEST_true(ossl_param_bld_push_int32(&bld, "i32", 1532))
+ || !TEST_true(ossl_param_bld_push_int64(&bld, "i64", -9999999))
+ || !TEST_true(ossl_param_bld_push_double(&bld, "d", 1.61803398875))
+ || !TEST_true(ossl_param_bld_push_utf8_string(&bld, "utf8_s", "foo",
+ sizeof("foo")))
+ || !TEST_true(ossl_param_bld_push_utf8_ptr(&bld, "utf8_p", "bar-boom",
+ 0))
+ || !TEST_ptr(params = ossl_param_bld_to_param(&bld, &secure))
+ || !TEST_ptr_null(secure)
+ /* Check int */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "i"))
+ || !TEST_true(OSSL_PARAM_get_int(p, &i))
+ || !TEST_str_eq(p->key, "i")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(int))
+ || !TEST_int_eq(i, -6)
+ /* Check int32 */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "i32"))
+ || !TEST_true(OSSL_PARAM_get_int32(p, &i32))
+ || !TEST_str_eq(p->key, "i32")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(int32_t))
+ || !TEST_int_eq((int)i32, 1532)
+ /* Check int64 */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "i64"))
+ || !TEST_str_eq(p->key, "i64")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(int64_t))
+ || !TEST_true(OSSL_PARAM_get_int64(p, &i64))
+ || !TEST_long_eq((long)i64, -9999999)
+ /* Check long */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "l"))
+ || !TEST_str_eq(p->key, "l")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(long int))
+ || !TEST_true(OSSL_PARAM_get_long(p, &l))
+ || !TEST_long_eq(l, 42)
+ /* Check double */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "d"))
+ || !TEST_true(OSSL_PARAM_get_double(p, &d))
+ || !TEST_str_eq(p->key, "d")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_REAL)
+ || !TEST_size_t_eq(p->data_size, sizeof(double))
+ || !TEST_double_eq(d, 1.61803398875)
+ /* Check UTF8 string */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "utf8_s"))
+ || !TEST_str_eq(p->data, "foo")
+ || !TEST_true(OSSL_PARAM_get_utf8_string(p, &utf, 0))
+ || !TEST_str_eq(utf, "foo")
+ /* Check UTF8 pointer */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "utf8_p"))
+ || !TEST_true(OSSL_PARAM_get_utf8_ptr(p, &cutf))
+ || !TEST_str_eq(cutf, "bar-boom"))
+ goto err;
+ res = 1;
+err:
+ OPENSSL_free(params);
+ OPENSSL_secure_free(secure);
+ OPENSSL_free(utf);
+ return res;
+}
+
+static int template_private_test(void)
+{
+ static int data1[] = { 2, 3, 5, 7, 11, 15, 17 };
+ static unsigned char data2[] = { 2, 4, 6, 8, 10 };
+ OSSL_PARAM_BLD bld;
+ OSSL_PARAM *params = NULL, *p;
+ void *secure = (void *)"abc";
+ unsigned int i;
+ unsigned long int l;
+ uint32_t i32;
+ uint64_t i64;
+ size_t st;
+ BIGNUM *bn = NULL, *bn_res = NULL;
+ int res = 0;
+
+ ossl_param_bld_init(&bld);
+ if (!TEST_true(ossl_param_bld_push_uint(&bld, "i", 6))
+ || !TEST_true(ossl_param_bld_push_ulong(&bld, "l", 42))
+ || !TEST_true(ossl_param_bld_push_uint32(&bld, "i32", 1532))
+ || !TEST_true(ossl_param_bld_push_uint64(&bld, "i64", 9999999))
+ || !TEST_true(ossl_param_bld_push_size_t(&bld, "st", 65537))
+ || !TEST_ptr(bn = BN_new())
+ || !TEST_true(BN_set_word(bn, 1729))
+ || !TEST_true(ossl_param_bld_push_BN(&bld, "bignumber", bn))
+ || !TEST_true(ossl_param_bld_push_octet_string(&bld, "oct_s", data1,
+ sizeof(data1)))
+ || !TEST_true(ossl_param_bld_push_octet_ptr(&bld, "oct_p", data2,
+ sizeof(data2)))
+ || !TEST_ptr(params = ossl_param_bld_to_param(&bld, &secure))
+ /* Check unsigned int */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "i"))
+ || !TEST_true(OSSL_PARAM_get_uint(p, &i))
+ || !TEST_str_eq(p->key, "i")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(int))
+ || !TEST_uint_eq(i, 6)
+ /* Check unsigned int32 */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "i32"))
+ || !TEST_true(OSSL_PARAM_get_uint32(p, &i32))
+ || !TEST_str_eq(p->key, "i32")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(int32_t))
+ || !TEST_uint_eq((unsigned int)i32, 1532)
+ /* Check unsigned int64 */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "i64"))
+ || !TEST_str_eq(p->key, "i64")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(int64_t))
+ || !TEST_true(OSSL_PARAM_get_uint64(p, &i64))
+ || !TEST_ulong_eq((unsigned long)i64, 9999999)
+ /* Check unsigned long int */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "l"))
+ || !TEST_str_eq(p->key, "l")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(unsigned long int))
+ || !TEST_true(OSSL_PARAM_get_ulong(p, &l))
+ || !TEST_ulong_eq(l, 42)
+ /* Check size_t */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "st"))
+ || !TEST_str_eq(p->key, "st")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(size_t))
+ || !TEST_true(OSSL_PARAM_get_size_t(p, &st))
+ || !TEST_size_t_eq(st, 65537)
+ /* Check octet string */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "oct_s"))
+ || !TEST_str_eq(p->key, "oct_s")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_OCTET_STRING)
+ || !TEST_mem_eq(p->data, p->data_size, data1, sizeof(data1))
+ /* Check octet pointer */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "oct_p"))
+ || !TEST_str_eq(p->key, "oct_p")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_OCTET_PTR)
+ || !TEST_mem_eq(*(void **)p->data, p->data_size, data2, sizeof(data2))
+ /* Check BN */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "bignumber"))
+ || !TEST_str_eq(p->key, "bignumber")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_true(OSSL_PARAM_get_BN(p, &bn_res))
+ || !TEST_int_eq(BN_cmp(bn_res, bn), 0))
+ goto err;
+ res = 1;
+err:
+ OPENSSL_secure_free(secure);
+ OPENSSL_free(params);
+ BN_free(bn);
+ BN_free(bn_res);
+ return res;
+}
+
+static int template_static_params_test(int n)
+{
+ unsigned char data[1000], secure[500];
+ OSSL_PARAM_BLD bld;
+ OSSL_PARAM params[20], *p;
+ BIGNUM *bn = NULL, *bn_r = NULL;
+ unsigned int i;
+ char *utf = NULL;
+ int res = 0;
+
+ ossl_param_bld_init(&bld);
+ if (!TEST_true(ossl_param_bld_push_uint(&bld, "i", 6))
+ || !TEST_ptr(bn = (n & 1) == 0 ? BN_new() : BN_secure_new())
+ || !TEST_true(BN_set_word(bn, 1337))
+ || !TEST_true(ossl_param_bld_push_BN(&bld, "bn", bn))
+ || !TEST_true(ossl_param_bld_push_utf8_string(&bld, "utf8_s", "bar",
+ 0))
+ || !TEST_ptr(ossl_param_bld_to_param_ex(&bld, params,
+ OSSL_NELEM(params),
+ data, sizeof(data),
+ secure, sizeof(secure)))
+ /* Check unsigned int */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "i"))
+ || !TEST_true(OSSL_PARAM_get_uint(p, &i))
+ || !TEST_str_eq(p->key, "i")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_size_t_eq(p->data_size, sizeof(int))
+ || !TEST_uint_eq(i, 6)
+ /* Check BIGNUM */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "bn"))
+ || !TEST_true(OSSL_PARAM_get_BN(p, &bn_r))
+ || !TEST_str_eq(p->key, "bn")
+ || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)
+ || !TEST_size_t_le(p->data_size, sizeof(BN_ULONG))
+ || !TEST_uint_eq((unsigned int)BN_get_word(bn_r), 1337)
+ /* Check UTF8 string */
+ || !TEST_ptr(p = OSSL_PARAM_locate(params, "utf8_s"))
+ || !TEST_str_eq(p->data, "bar")
+ || !TEST_true(OSSL_PARAM_get_utf8_string(p, &utf, 0))
+ || !TEST_str_eq(utf, "bar"))
+ goto err;
+ res = 1;
+err:
+ OPENSSL_free(utf);
+ BN_free(bn);
+ BN_free(bn_r);
+ return res;
+}
+
+static int template_static_fail_test(int n)
+{
+ unsigned char data[10000], secure[500];
+ OSSL_PARAM_BLD bld;
+ OSSL_PARAM prms[20];
+ BIGNUM *bn = NULL;
+ int res = 0;
+
+ ossl_param_bld_init(&bld);
+ if (!TEST_true(ossl_param_bld_push_uint(&bld, "i", 6))
+ || !TEST_ptr(bn = (n & 1) == 0 ? BN_new() : BN_secure_new())
+ || !TEST_true(BN_hex2bn(&bn, "ABCDEF78901234567890ABCDEF0987987654321"))
+ || !TEST_true(ossl_param_bld_push_BN(&bld, "bn", bn))
+ || !TEST_true(ossl_param_bld_push_utf8_string(&bld, "utf8_s", "abc",
+ 1000))
+ /* No OSSL_PARAMS */
+ || !TEST_ptr_null(ossl_param_bld_to_param_ex(&bld, NULL, 0, data,
+ sizeof(data), secure,
+ sizeof(secure)))
+ /* Short OSSL_PARAMS */
+ || !TEST_ptr_null(ossl_param_bld_to_param_ex(&bld, prms, 2,
+ data, sizeof(data),
+ secure, sizeof(secure)))
+ /* No normal data */
+ || !TEST_ptr_null(ossl_param_bld_to_param_ex(&bld, prms,
+ OSSL_NELEM(prms),
+ NULL, 0, secure,
+ sizeof(secure)))
+ /* Not enough normal data */
+ || !TEST_ptr_null(ossl_param_bld_to_param_ex(&bld, prms,
+ OSSL_NELEM(prms),
+ data, 50, secure,
+ sizeof(secure))))
+ goto err;
+ if ((n & 1) == 1) {
+ /* No secure data */
+ if (!TEST_ptr_null(ossl_param_bld_to_param_ex(&bld, prms,
+ OSSL_NELEM(prms),
+ data, sizeof(data),
+ NULL, 0))
+ /* Not enough secure data */
+ || !TEST_ptr_null(ossl_param_bld_to_param_ex(&bld, prms,
+ OSSL_NELEM(prms),
+ data, sizeof(data),
+ secure, 4)))
+ goto err;
+ }
+ res = 1;
+err:
+ BN_free(bn);
+ return res;
+}
+
+int setup_tests(void)
+{
+ ADD_TEST(template_public_test);
+ ADD_TEST(template_private_test);
+ ADD_ALL_TESTS(template_static_params_test, 2);
+ ADD_ALL_TESTS(template_static_fail_test, 2);
+ return 1;
+}
--- /dev/null
+#! /usr/bin/env perl
+# Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use OpenSSL::Test;
+use OpenSSL::Test::Simple;
+
+setup("test_param_build");
+
+simple_test("test_param_build", "param_build_test");