Params conversion tests.

Add ranged checked OSSL_PARAM conversions between the native types.  A
conversion is legal only if the given value can be exactly represented
by the target type.

Includes a test case that reads a stanza test case file and verified that param
conversions are processed properly.

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8733)
This commit is contained in:
Pauli 2019-05-21 07:42:26 +10:00
parent 538f38db50
commit 9830e7ea42
6 changed files with 1100 additions and 84 deletions

View file

@ -156,12 +156,54 @@ OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf,
int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
{
if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
int64_t i64;
uint32_t u32;
uint64_t u64;
double d;
if (val == NULL || p == NULL )
return 0;
if (p->data_size == sizeof(int32_t)) {
*val = *(const int32_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
*val = *(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
*val = (int32_t)i64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
u32 = *(const uint32_t *)p->data;
if (u32 <= INT32_MAX) {
*val = (int32_t)u32;
return 1;
}
break;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if (u64 <= INT32_MAX) {
*val = (int32_t)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
*val = (int32_t)d;
return 1;
}
break;
}
}
return 0;
}
@ -171,19 +213,35 @@ int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_INTEGER)
return 0;
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int32_t):
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = val;
return 1;
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int32_t):
*(int32_t *)p->data = val;
return 1;
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint32_t):
*(uint32_t *)p->data = (uint32_t)val;
return 1;
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = (uint64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
*(double *)p->data = (double)val;
return 1;
}
}
return 0;
}
@ -197,35 +255,96 @@ OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
{
if (val == NULL
|| p == NULL
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
int32_t i32;
int64_t i64;
uint64_t u64;
double d;
if (val == NULL || p == NULL)
return 0;
if (p->data_size == sizeof(uint32_t)) {
*val = *(const uint32_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if (u64 <= UINT32_MAX) {
*val = (uint32_t)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
i32 = *(const int32_t *)p->data;
if (i32 >= 0) {
*val = i32;
return 1;
}
break;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
if (i64 >= 0 && i64 <= UINT32_MAX) {
*val = (uint32_t)i64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
*val = (uint32_t)d;
return 1;
}
break;
}
}
return 0;
}
int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val)
{
if (p == NULL) return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint32_t):
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = val;
return 1;
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = (uint64_t)val;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint32_t):
*(uint32_t *)p->data = val;
return 1;
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int32_t):
if (val <= INT32_MAX) {
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
*(double *)p->data = (double)val;
return 1;
}
}
return 0;
}
@ -239,34 +358,94 @@ OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
{
if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
uint64_t u64;
double d;
if (val == NULL || p == NULL )
return 0;
switch (p->data_size) {
case sizeof(int32_t):
*val = (int64_t)*(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
*val = *(const int64_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
*val = *(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
*val = *(const int64_t *)p->data;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if (u64 <= INT64_MAX) {
*val = (int64_t)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= INT64_MIN && d <= INT64_MAX && d == (int64_t)d) {
*val = (int64_t)d;
return 1;
}
break;
}
}
return 0;
}
int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val)
{
uint64_t u64;
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_INTEGER)
return 0;
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = val;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(int32_t):
if (val >= INT32_MIN && val <= INT32_MAX) {
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
*(int64_t *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(uint32_t):
if (val <= UINT32_MAX) {
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = (uint32_t)val;
return 1;
}
break;
case sizeof(uint64_t):
*(uint64_t *)p->data = (uint64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
u64 = val < 0 ? -val : val;
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
*(double *)p->data = (double)val;
return 1;
}
break;
}
}
return 0;
}
@ -280,18 +459,49 @@ OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
{
if (val == NULL
|| p == NULL
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
int32_t i32;
int64_t i64;
double d;
if (val == NULL || p == NULL)
return 0;
switch (p->data_size) {
case sizeof(uint32_t):
*val = (uint64_t)*(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
*val = *(const uint64_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
*val = *(const uint64_t *)p->data;
return 1;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
i32 = *(const int32_t *)p->data;
if (i32 >= 0) {
*val = (uint64_t)i32;
return 1;
}
break;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
if (i64 >= 0) {
*val = (uint64_t)i64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= 0 && d <= INT64_MAX && d == (uint64_t)d) {
*val = (uint64_t)d;
return 1;
}
break;
}
}
return 0;
}
@ -301,15 +511,48 @@ int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
return 0;
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = val;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(uint32_t):
if (val <= UINT32_MAX) {
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = (uint32_t)val;
return 1;
}
break;
case sizeof(uint64_t):
*(uint64_t *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(int32_t):
if (val <= INT32_MAX) {
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
if (val <= INT64_MAX) {
*(int64_t *)p->data = (int64_t)val;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
if ((val >> 53) == 0) { /* 53 significant bits in the mantissa */
*(double *)p->data = (double)val;
return 1;
}
break;
}
}
return 0;
}
@ -402,13 +645,45 @@ OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
{
if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_REAL)
int64_t i64;
uint64_t u64;
if (val == NULL || p == NULL)
return 0;
switch (p->data_size) {
case sizeof(double):
*val = *(const double *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
*val = *(const double *)p->data;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
*val = (double)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
*val = *(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
u64 = i64 < 0 ? -i64 : i64;
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
*val = 0.0 + i64;
return 1;
}
break;
}
}
return 0;
}
@ -418,14 +693,50 @@ int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_REAL)
return 0;
switch (p->data_size) {
case sizeof(double):
if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
*(double *)p->data = val;
return 1;
switch (p->data_size) {
case sizeof(double):
*(double *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
&& val == (uintmax_t)val) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(uint32_t):
if (val >= 0 && val <= UINT32_MAX) {
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = (uint32_t)val;
return 1;
}
break;
case sizeof(uint64_t):
if (val >= 0 && val <= UINT64_MAX) {
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = (uint64_t)val;
return 1;
}
break; }
} else if (p->data_type == OSSL_PARAM_INTEGER && val == (intmax_t)val) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(int32_t):
if (val >= INT32_MIN && val <= INT32_MAX) {
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
if (val >= INT64_MIN && val <= INT64_MAX) {
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
}
break;
}
}
return 0;
}

View file

@ -250,7 +250,8 @@ All other functions return B<1> on success and B<0> on failure.
=head1 NOTES
Integral types will be widened and sign extended as required.
Native types will be converted as required only if the value is exactly
representable by the target type or parameter.
Apart from that, the functions must be used appropriately for the
expected type of the parameter.

View file

@ -34,7 +34,7 @@ IF[{- !$disabled{tests} -}]
bftest ssltest_old dsatest dsa_no_digest_size_test exptest rsa_test \
evp_test evp_extra_test igetest v3nametest v3ext \
crltest danetest bad_dtls_test lhash_test sparse_array_test \
conf_include_test params_api_test \
conf_include_test params_api_test params_conversion_test \
constant_time_test verify_extra_test clienthellotest \
packettest asynctest secmemtest srptest memleaktest stack_test \
dtlsv1listentest ct_test threadstest afalgtest d2i_test \
@ -314,6 +314,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[params_api_test]=../include ../apps/include
DEPEND[params_api_test]=../libcrypto libtestutil.a
SOURCE[params_conversion_test]=params_conversion_test.c
INCLUDE[params_conversion_test]=../include ../apps/include
DEPEND[params_conversion_test]=../libcrypto libtestutil.a
SOURCE[sslapitest]=sslapitest.c ssltestlib.c
INCLUDE[sslapitest]=../include ../apps/include ..
DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a

View file

@ -0,0 +1,334 @@
/*
* 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 <inttypes.h>
#include <openssl/params.h>
#include "testutil.h"
#ifdef OPENSSL_SYS_WINDOWS
# define strcasecmp _stricmp
#endif
typedef struct {
const OSSL_PARAM *param;
int32_t i32;
int64_t i64;
uint32_t u32;
uint64_t u64;
double d;
int valid_i32, valid_i64, valid_u32, valid_u64, valid_d;
void *ref, *datum;
size_t size;
} PARAM_CONVERSION;
static int param_conversion_load_stanza(PARAM_CONVERSION *pc, const STANZA *s)
{
static int32_t datum_i32, ref_i32;
static int64_t datum_i64, ref_i64;
static uint32_t datum_u32, ref_u32;
static uint64_t datum_u64, ref_u64;
static double datum_d, ref_d;
static const OSSL_PARAM params[] = {
OSSL_PARAM_int32("int32", &datum_i32),
OSSL_PARAM_int64("int64", &datum_i64),
OSSL_PARAM_uint32("uint32", &datum_u32),
OSSL_PARAM_uint64("uint64", &datum_u64),
OSSL_PARAM_double("double", &datum_d),
OSSL_PARAM_END
};
int def_i32 = 0, def_i64 = 0, def_u32 = 0, def_u64 = 0, def_d = 0;
const PAIR *pp = s->pairs;
const char *type = NULL;
char *p;
int i;
memset(pc, 0, sizeof(*pc));
for (i = 0; i < s->numpairs; i++, pp++) {
p = "";
if (strcasecmp(pp->key, "type") == 0) {
if (type != NULL) {
TEST_info("Line %d: multiple type lines", s->curr);
return 0;
}
pc->param = OSSL_PARAM_locate(params, type = pp->value);
if (pc->param == NULL) {
TEST_info("Line %d: unknown type line", s->curr);
return 0;
}
} else if (strcasecmp(pp->key, "int32") == 0) {
if (def_i32++) {
TEST_info("Line %d: multiple int32 lines", s->curr);
return 0;
}
if (strcasecmp(pp->value, "invalid") != 0) {
pc->valid_i32 = 1;
pc->i32 = (int32_t)strtoimax(pp->value, &p, 10);
}
} else if (strcasecmp(pp->key, "int64") == 0) {
if (def_i64++) {
TEST_info("Line %d: multiple int64 lines", s->curr);
return 0;
}
if (strcasecmp(pp->value, "invalid") != 0) {
pc->valid_i64 = 1;
pc->i64 = (int64_t)strtoimax(pp->value, &p, 10);
}
} else if (strcasecmp(pp->key, "uint32") == 0) {
if (def_u32++) {
TEST_info("Line %d: multiple uint32 lines", s->curr);
return 0;
}
if (strcasecmp(pp->value, "invalid") != 0) {
pc->valid_u32 = 1;
pc->u32 = (uint32_t)strtoumax(pp->value, &p, 10);
}
} else if (strcasecmp(pp->key, "uint64") == 0) {
if (def_u64++) {
TEST_info("Line %d: multiple uint64 lines", s->curr);
return 0;
}
if (strcasecmp(pp->value, "invalid") != 0) {
pc->valid_u64 = 1;
pc->u64 = (uint64_t)strtoumax(pp->value, &p, 10);
}
} else if (strcasecmp(pp->key, "double") == 0) {
if (def_d++) {
TEST_info("Line %d: multiple double lines", s->curr);
return 0;
}
if (strcasecmp(pp->value, "invalid") != 0) {
pc->valid_d = 1;
pc->d = strtod(pp->value, &p);
}
} else {
TEST_info("Line %d: unknown keyword %s", s->curr, pp->key);
return 0;
}
if (*p != '\0') {
TEST_info("Line %d: extra characters at end '%s' for %s",
s->curr, p, pp->key);
return 0;
}
}
if (!TEST_ptr(type)) {
TEST_info("Line %d: type not found", s->curr);
return 0;
}
if (strcasecmp(type, "int32") == 0) {
if (!TEST_true(def_i32) || !TEST_true(pc->valid_i32)) {
TEST_note("errant int32 on line %d", s->curr);
return 0;
}
datum_i32 = ref_i32 = pc->i32;
pc->datum = &datum_i32;
pc->ref = &ref_i32;
pc->size = sizeof(ref_i32);
} else if (strcasecmp(type, "int64") == 0) {
if (!TEST_true(def_i64) || !TEST_true(pc->valid_i64)) {
TEST_note("errant int64 on line %d", s->curr);
return 0;
}
datum_i64 = ref_i64 = pc->i64;
pc->datum = &datum_i64;
pc->ref = &ref_i64;
pc->size = sizeof(ref_i64);
} else if (strcasecmp(type, "uint32") == 0) {
if (!TEST_true(def_u32) || !TEST_true(pc->valid_u32)) {
TEST_note("errant uint32 on line %d", s->curr);
return 0;
}
datum_u32 = ref_u32 = pc->u32;
pc->datum = &datum_u32;
pc->ref = &ref_u32;
pc->size = sizeof(ref_u32);
} else if (strcasecmp(type, "uint64") == 0) {
if (!TEST_true(def_u64) || !TEST_true(pc->valid_u64)) {
TEST_note("errant uint64 on line %d", s->curr);
return 0;
}
datum_u64 = ref_u64 = pc->u64;
pc->datum = &datum_u64;
pc->ref = &ref_u64;
pc->size = sizeof(ref_u64);
} else if (strcasecmp(type, "double") == 0) {
if (!TEST_true(def_d) || !TEST_true(pc->valid_d)) {
TEST_note("errant double on line %d", s->curr);
return 0;
}
datum_d = ref_d = pc->d;
pc->datum = &datum_d;
pc->ref = &ref_d;
pc->size = sizeof(ref_d);
} else {
TEST_error("type unknown at line %d", s->curr);
return 0;
}
return 1;
}
static int param_conversion_test(const PARAM_CONVERSION *pc, int line)
{
int32_t i32;
int64_t i64;
uint32_t u32;
uint64_t u64;
double d;
if (!pc->valid_i32) {
if (!TEST_false(OSSL_PARAM_get_int32(pc->param, &i32))) {
TEST_note("unexpected valid conversion to int32 on line %d", line);
return 0;
}
} else {
if (!TEST_true(OSSL_PARAM_get_int32(pc->param, &i32))
|| !TEST_true(i32 == pc->i32)) {
TEST_note("unexpected conversion to int32 on line %d", line);
return 0;
}
memset(pc->datum, 44, pc->size);
if (!TEST_true(OSSL_PARAM_set_int32(pc->param, i32))
|| !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
TEST_note("unexpected valid conversion from int32 on line %d",
line);
return 0;
}
}
if (!pc->valid_i64) {
if (!TEST_false(OSSL_PARAM_get_int64(pc->param, &i64))) {
TEST_note("unexpected valid conversion to int64 on line %d", line);
return 0;
}
} else {
if (!TEST_true(OSSL_PARAM_get_int64(pc->param, &i64))
|| !TEST_true(i64 == pc->i64)) {
TEST_note("unexpected conversion to int64 on line %d", line);
return 0;
}
memset(pc->datum, 44, pc->size);
if (!TEST_true(OSSL_PARAM_set_int64(pc->param, i64))
|| !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
TEST_note("unexpected valid conversion from int64 on line %d",
line);
return 0;
}
}
if (!pc->valid_u32) {
if (!TEST_false(OSSL_PARAM_get_uint32(pc->param, &u32))) {
TEST_note("unexpected valid conversion to uint32 on line %d", line);
return 0;
}
} else {
if (!TEST_true(OSSL_PARAM_get_uint32(pc->param, &u32))
|| !TEST_true(u32 == pc->u32)) {
TEST_note("unexpected conversion to uint32 on line %d", line);
return 0;
}
memset(pc->datum, 44, pc->size);
if (!TEST_true(OSSL_PARAM_set_uint32(pc->param, u32))
|| !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
TEST_note("unexpected valid conversion from uint32 on line %d",
line);
return 0;
}
}
if (!pc->valid_u64) {
if (!TEST_false(OSSL_PARAM_get_uint64(pc->param, &u64))) {
TEST_note("unexpected valid conversion to uint64 on line %d", line);
return 0;
}
} else {
if (!TEST_true(OSSL_PARAM_get_uint64(pc->param, &u64))
|| !TEST_true(u64 == pc->u64)) {
TEST_note("unexpected conversion to uint64 on line %d", line);
return 0;
}
memset(pc->datum, 44, pc->size);
if (!TEST_true(OSSL_PARAM_set_uint64(pc->param, u64))
|| !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
TEST_note("unexpected valid conversion from uint64 on line %d",
line);
return 0;
}
}
if (!pc->valid_d) {
if (!TEST_false(OSSL_PARAM_get_double(pc->param, &d))) {
TEST_note("unexpected valid conversion to double on line %d", line);
return 0;
}
} else {
if (!TEST_true(OSSL_PARAM_get_double(pc->param, &d))
|| !TEST_true(d == pc->d)) {
TEST_note("unexpected conversion to double on line %d", line);
return 0;
}
memset(pc->datum, 44, pc->size);
if (!TEST_true(OSSL_PARAM_set_double(pc->param, d))
|| !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
TEST_note("unexpected valid conversion from double on line %d",
line);
return 0;
}
}
return 1;
}
static int run_param_file_tests(int i)
{
STANZA *s;
PARAM_CONVERSION pc;
const char *testfile = test_get_argument(i);
int res = 1;
if (!TEST_ptr(s = OPENSSL_zalloc(sizeof(*s))))
return 0;
if (!test_start_file(s, testfile)) {
OPENSSL_free(s);
return 0;
}
while (!BIO_eof(s->fp)) {
if (!test_readstanza(s)) {
res = 0;
goto end;
}
if (s->numpairs != 0)
if (!param_conversion_load_stanza(&pc, s)
|| !param_conversion_test(&pc, s->curr))
res = 0;
test_clearstanza(s);
}
end:
test_end_file(s);
OPENSSL_free(s);
return res;
}
OPT_TEST_DECLARE_USAGE("file...\n")
int setup_tests(void)
{
size_t n = test_get_argument_count();
if (n == 0)
return 0;
ADD_ALL_TESTS(run_param_file_tests, n);
return 1;
}

View file

@ -0,0 +1,23 @@
#! /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 warnings;
use OpenSSL::Test qw/:DEFAULT data_file/;
setup("test_params_conversion");
my @files = ( "native_types.txt" );
plan tests => scalar(@files);
foreach my $f ( @files ) {
ok(run(test(["params_conversion_test", data_file("$f")])),
"running params_conversion_test $f");
}

View file

@ -0,0 +1,343 @@
type=int32
int32=0
int64=0
uint32=0
uint64=0
double=0
type=int32
int32=6
int64=6
uint32=6
uint64=6
double=6
type=int32
int32=-6
int64=-6
uint32=invalid
uint64=invalid
double=-6
type=uint32
int32=0
int64=0
uint32=0
uint64=0
double=0
type=uint32
int32=6
int64=6
uint32=6
uint64=6
double=6
# 2^31-1
type=uint32
int32=2147483647
int64=2147483647
uint32=2147483647
uint64=2147483647
double=2147483647
# 2^31
type=uint32
int32=invalid
int64=2147483648
uint32=2147483648
uint64=2147483648
double=2147483648
type=int64
int32=6
int64=6
uint32=6
uint64=6
double=6
type=int64
int32=-6
int64=-6
uint32=invalid
uint64=invalid
double=-6
# 2^31-1
type=int64
int32=2147483647
int64=2147483647
uint32=2147483647
uint64=2147483647
double=2147483647
# 2^31
type=int64
int32=invalid
int64=2147483648
uint32=2147483648
uint64=2147483648
double=2147483648
# -2^31+1
type=int64
int32=-2147483647
int64=-2147483647
uint32=invalid
uint64=invalid
double=-2147483647
# -2^31
type=int64
int32=-2147483648
int64=-2147483648
uint32=invalid
uint64=invalid
double=-2147483648
# -2^31-1
type=int64
int32=invalid
int64=-2147483649
uint32=invalid
uint64=invalid
double=-2147483649
# 2^32-1
type=int64
int32=invalid
int64=4294967295
uint32=4294967295
uint64=4294967295
double=4294967295
# 2^32
type=int64
int32=invalid
int64=4294967296
uint32=invalid
uint64=4294967296
double=4294967296
# -2^32
type=int64
int32=invalid
int64=-4294967296
uint32=invalid
uint64=invalid
double=-4294967296
# 2^53-1
type=int64
int32=invalid
int64=9007199254740991
uint32=invalid
uint64=9007199254740991
double=9007199254740991
# 2^53
type=int64
int32=invalid
int64=9007199254740992
uint32=invalid
uint64=9007199254740992
double=invalid
# -2^53-1
type=int64
int32=invalid
int64=-9007199254740991
uint32=invalid
uint64=invalid
double=-9007199254740991
# -2^53
type=int64
int32=invalid
int64=-9007199254740992
uint32=invalid
uint64=invalid
double=invalid
type=uint64
int32=6
int64=6
uint32=6
uint64=6
double=6
# 2^31-1
type=uint64
int32=2147483647
int64=2147483647
uint32=2147483647
uint64=2147483647
double=2147483647
# 2^31
type=uint64
int32=invalid
int64=2147483648
uint32=2147483648
uint64=2147483648
double=2147483648
# 2^32-1
type=uint64
int32=invalid
int64=4294967295
uint32=4294967295
uint64=4294967295
double=4294967295
# 2^32
type=uint64
int32=invalid
int64=4294967296
uint32=invalid
uint64=4294967296
double=4294967296
# 2^53-1
type=uint64
int32=invalid
int64=9007199254740991
uint32=invalid
uint64=9007199254740991
double=9007199254740991
# 2^53
type=uint64
int32=invalid
int64=9007199254740992
uint32=invalid
uint64=9007199254740992
double=invalid
# 2^63-1
type=uint64
int32=invalid
int64=9223372036854775807
uint32=invalid
uint64=9223372036854775807
double=invalid
# 2^63-1
type=uint64
int32=invalid
int64=invalid
uint32=invalid
uint64=9223372036854775808
double=invalid
type=double
int32=0
int64=0
uint32=0
uint64=0
double=0
type=double
int32=6
int64=6
uint32=6
uint64=6
double=6
type=double
int32=-6
int64=-6
uint32=invalid
uint64=invalid
double=-6
# -2^31
type=double
int32=-2147483648
int64=-2147483648
uint32=invalid
uint64=invalid
double=-2147483648
# -2^31-1
type=double
int32=invalid
int64=-2147483649
uint32=invalid
uint64=invalid
double=-2147483649
# 2^32-1
type=double
int32=invalid
int64=4294967295
uint32=4294967295
uint64=4294967295
double=4294967295
# 2^32
type=double
int32=invalid
int64=4294967296
uint32=invalid
uint64=4294967296
double=4294967296
# -2^32
type=double
int32=invalid
int64=-4294967296
uint32=invalid
uint64=invalid
double=-4294967296
# 2^53-1
type=double
int32=invalid
int64=9007199254740991
uint32=invalid
uint64=9007199254740991
double=9007199254740991
# -2^53+1
type=double
int32=invalid
int64=-9007199254740991
uint32=invalid
uint64=invalid
double=-9007199254740991
# big
type=double
int32=invalid
int64=invalid
uint32=invalid
uint64=invalid
double=1e100
# big
type=double
int32=invalid
int64=invalid
uint32=invalid
uint64=invalid
double=-1e100
# infinite
type=double
int32=invalid
int64=invalid
uint32=invalid
uint64=invalid
double=inf
# fractional
type=double
int32=invalid
int64=invalid
uint32=invalid
uint64=invalid
double=0.5