params: add helper functions to allocate & copy params

Added a function to allocate a buffer and copy a maching param.
Added a function to allocate a buffer and concatenate all matching params.

Fixes #20717

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20724)
This commit is contained in:
Pauli 2023-04-13 12:10:50 +10:00
parent d9b811dc01
commit 79523d5592
2 changed files with 145 additions and 0 deletions

View file

@ -14,6 +14,8 @@
#include "internal/thread_once.h"
#include "internal/numbers.h"
#include "internal/endian.h"
#include "internal/params.h"
#include "internal/packet.h"
/* Shortcuts for raising errors that are widely used */
#define err_unsigned_negative \
@ -1481,6 +1483,111 @@ OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize);
}
/*
* Extract the parameter into an allocated buffer.
* Any existing allocation in *out is cleared and freed.
*
* Returns 1 on success, 0 on failure and -1 if there are no matching params.
*
* *out and *out_len are guaranteed to be untouched if this function
* doesn't return success.
*/
int ossl_param_get1_octet_string(const OSSL_PARAM *params, const char *name,
unsigned char **out, size_t *out_len)
{
const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name);
void *buf = NULL;
size_t len = 0;
if (p == NULL)
return -1;
if (p->data != NULL
&& p->data_size > 0
&& !OSSL_PARAM_get_octet_string(p, &buf, 0, &len))
return 0;
OPENSSL_clear_free(*out, *out_len);
*out = buf;
*out_len = len;
return 1;
}
static int setbuf_fromparams(const OSSL_PARAM *p, const char *name,
unsigned char *out, size_t *outlen)
{
int ret = 0;
WPACKET pkt;
if (out == NULL) {
if (!WPACKET_init_null(&pkt, 0))
return 0;
} else {
if (!WPACKET_init_static_len(&pkt, out, *outlen, 0))
return 0;
}
for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, name)) {
if (p->data_type != OSSL_PARAM_OCTET_STRING)
goto err;
if (p->data != NULL
&& p->data_size != 0
&& !WPACKET_memcpy(&pkt, p->data, p->data_size))
goto err;
}
if (!WPACKET_get_total_written(&pkt, outlen)
|| !WPACKET_finish(&pkt))
goto err;
ret = 1;
err:
WPACKET_cleanup(&pkt);
return ret;
}
int ossl_param_get1_concat_octet_string(const OSSL_PARAM *params, const char *name,
unsigned char **out,
size_t *out_len, size_t maxsize)
{
const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name);
unsigned char *res;
size_t sz = 0;
if (p == NULL)
return -1;
/* Calculate the total size */
if (!setbuf_fromparams(p, name, NULL, &sz))
return 0;
/* Check that it's not oversized */
if (maxsize > 0 && sz > maxsize)
return 0;
/* Special case zero length */
if (sz == 0) {
if ((res = OPENSSL_zalloc(1)) == NULL)
return 0;
goto fin;
}
/* Allocate the buffer */
res = OPENSSL_malloc(sz);
if (res == NULL)
return 0;
/* Concat one or more OSSL_KDF_PARAM_INFO fields */
if (!setbuf_fromparams(p, name, res, &sz)) {
OPENSSL_clear_free(res, sz);
return 0;
}
fin:
OPENSSL_clear_free(*out, *out_len);
*out = res;
*out_len = sz;
return 1;
}
OSSL_PARAM OSSL_PARAM_construct_end(void)
{
OSSL_PARAM end = OSSL_PARAM_END;

38
include/internal/params.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright 2023 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
*/
#include <stddef.h>
#include <openssl/params.h>
/*
* Extract the parameter into an allocated buffer.
* Any existing allocation in *out is cleared and freed.
*
* Returns 1 on success, 0 on failure and -1 if there are no matching params.
*
* *out and *out_len are guaranteed to be untouched if this function
* doesn't return success.
*/
int ossl_param_get1_octet_string(const OSSL_PARAM *params, const char *name,
unsigned char **out, size_t *out_len);
/*
* Concatenate all of the matching params together.
* *out will point to an allocated buffer on successful return.
* Any existing allocation in *out is cleared and freed.
*
* Passing 0 for maxsize means unlimited size output.
*
* Returns 1 on success, 0 on failure and -1 if there are no matching params.
*
* *out and *out_len are guaranteed to be untouched if this function
* doesn't return success.
*/
int ossl_param_get1_concat_octet_string(const OSSL_PARAM *params, const char *name,
unsigned char **out, size_t *out_len,
size_t maxsize);