summaryrefslogtreecommitdiffstats
path: root/crypto/property
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2021-06-01 20:02:24 +0200
committerPauli <pauli@openssl.org>2021-06-05 20:29:47 +1000
commit6ec3b2cf4992a304b4ab36f7b9e9ff130bd495b7 (patch)
tree348097b950d9bc6de530d93dfe8f0c70cc8bd983 /crypto/property
parent0b3fe363e6188dcb854d480180c9af91cc613f2c (diff)
property: Add functionality to query data from a property definition
This required making some OSSL_PROPERTY types a little less private. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15570)
Diffstat (limited to 'crypto/property')
-rw-r--r--crypto/property/build.info2
-rw-r--r--crypto/property/property_local.h21
-rw-r--r--crypto/property/property_parse.c156
-rw-r--r--crypto/property/property_query.c53
4 files changed, 140 insertions, 92 deletions
diff --git a/crypto/property/build.info b/crypto/property/build.info
index 56f26760c6..dac9ab7a3b 100644
--- a/crypto/property/build.info
+++ b/crypto/property/build.info
@@ -1,5 +1,5 @@
LIBS=../../libcrypto
-$COMMON=property_string.c property_parse.c property.c defn_cache.c
+$COMMON=property_string.c property_parse.c property_query.c property.c defn_cache.c
SOURCE[../../libcrypto]=$COMMON property_err.c
SOURCE[../../providers/libfips.a]=$COMMON
SOURCE[../../providers/liblegacy.a]=$COMMON
diff --git a/crypto/property/property_local.h b/crypto/property/property_local.h
index 8cc3a51270..db1b0a5ee4 100644
--- a/crypto/property/property_local.h
+++ b/crypto/property/property_local.h
@@ -13,6 +13,27 @@
typedef int OSSL_PROPERTY_IDX;
+typedef enum {
+ OSSL_PROPERTY_OPER_EQ, OSSL_PROPERTY_OPER_NE, OSSL_PROPERTY_OVERRIDE
+} OSSL_PROPERTY_OPER;
+
+struct ossl_property_definition_st {
+ OSSL_PROPERTY_IDX name_idx;
+ OSSL_PROPERTY_TYPE type;
+ OSSL_PROPERTY_OPER oper;
+ unsigned int optional : 1;
+ union {
+ int64_t int_val; /* Signed integer */
+ OSSL_PROPERTY_IDX str_val; /* String */
+ } v;
+};
+
+struct ossl_property_list_st {
+ int n;
+ unsigned int has_optional : 1;
+ OSSL_PROPERTY_DEFINITION properties[1];
+};
+
/* Property string functions */
OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s,
int create);
diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c
index 6352def860..149e1956b7 100644
--- a/crypto/property/property_parse.c
+++ b/crypto/property/property_parse.c
@@ -19,35 +19,9 @@
#include "property_local.h"
#include "e_os.h"
-typedef enum {
- PROPERTY_TYPE_STRING, PROPERTY_TYPE_NUMBER,
- PROPERTY_TYPE_VALUE_UNDEFINED
-} PROPERTY_TYPE;
-
-typedef enum {
- PROPERTY_OPER_EQ, PROPERTY_OPER_NE, PROPERTY_OVERRIDE
-} PROPERTY_OPER;
-
-typedef struct {
- OSSL_PROPERTY_IDX name_idx;
- PROPERTY_TYPE type;
- PROPERTY_OPER oper;
- unsigned int optional : 1;
- union {
- int64_t int_val; /* Signed integer */
- OSSL_PROPERTY_IDX str_val; /* String */
- } v;
-} PROPERTY_DEFINITION;
-
-struct ossl_property_list_st {
- int n;
- unsigned int has_optional : 1;
- PROPERTY_DEFINITION properties[1];
-};
-
static OSSL_PROPERTY_IDX ossl_property_true, ossl_property_false;
-DEFINE_STACK_OF(PROPERTY_DEFINITION)
+DEFINE_STACK_OF(OSSL_PROPERTY_DEFINITION)
static const char *skip_space(const char *s)
{
@@ -120,7 +94,7 @@ static int parse_name(OSSL_LIB_CTX *ctx, const char *t[], int create,
return 1;
}
-static int parse_number(const char *t[], PROPERTY_DEFINITION *res)
+static int parse_number(const char *t[], OSSL_PROPERTY_DEFINITION *res)
{
const char *s = *t;
int64_t v = 0;
@@ -136,12 +110,12 @@ static int parse_number(const char *t[], PROPERTY_DEFINITION *res)
return 0;
}
*t = skip_space(s);
- res->type = PROPERTY_TYPE_NUMBER;
+ res->type = OSSL_PROPERTY_TYPE_NUMBER;
res->v.int_val = v;
return 1;
}
-static int parse_hex(const char *t[], PROPERTY_DEFINITION *res)
+static int parse_hex(const char *t[], OSSL_PROPERTY_DEFINITION *res)
{
const char *s = *t;
int64_t v = 0;
@@ -161,12 +135,12 @@ static int parse_hex(const char *t[], PROPERTY_DEFINITION *res)
return 0;
}
*t = skip_space(s);
- res->type = PROPERTY_TYPE_NUMBER;
+ res->type = OSSL_PROPERTY_TYPE_NUMBER;
res->v.int_val = v;
return 1;
}
-static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
+static int parse_oct(const char *t[], OSSL_PROPERTY_DEFINITION *res)
{
const char *s = *t;
int64_t v = 0;
@@ -182,13 +156,13 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
return 0;
}
*t = skip_space(s);
- res->type = PROPERTY_TYPE_NUMBER;
+ res->type = OSSL_PROPERTY_TYPE_NUMBER;
res->v.int_val = v;
return 1;
}
static int parse_string(OSSL_LIB_CTX *ctx, const char *t[], char delim,
- PROPERTY_DEFINITION *res, const int create)
+ OSSL_PROPERTY_DEFINITION *res, const int create)
{
char v[1000];
const char *s = *t;
@@ -214,12 +188,12 @@ static int parse_string(OSSL_LIB_CTX *ctx, const char *t[], char delim,
res->v.str_val = ossl_property_value(ctx, v, create);
}
*t = skip_space(s + 1);
- res->type = PROPERTY_TYPE_STRING;
+ res->type = OSSL_PROPERTY_TYPE_STRING;
return !err;
}
static int parse_unquoted(OSSL_LIB_CTX *ctx, const char *t[],
- PROPERTY_DEFINITION *res, const int create)
+ OSSL_PROPERTY_DEFINITION *res, const int create)
{
char v[1000];
const char *s = *t;
@@ -247,12 +221,12 @@ static int parse_unquoted(OSSL_LIB_CTX *ctx, const char *t[],
res->v.str_val = ossl_property_value(ctx, v, create);
}
*t = skip_space(s);
- res->type = PROPERTY_TYPE_STRING;
+ res->type = OSSL_PROPERTY_TYPE_STRING;
return !err;
}
static int parse_value(OSSL_LIB_CTX *ctx, const char *t[],
- PROPERTY_DEFINITION *res, int create)
+ OSSL_PROPERTY_DEFINITION *res, int create)
{
const char *s = *t;
int r = 0;
@@ -282,11 +256,11 @@ static int parse_value(OSSL_LIB_CTX *ctx, const char *t[],
return r;
}
-static int pd_compare(const PROPERTY_DEFINITION *const *p1,
- const PROPERTY_DEFINITION *const *p2)
+static int pd_compare(const OSSL_PROPERTY_DEFINITION *const *p1,
+ const OSSL_PROPERTY_DEFINITION *const *p2)
{
- const PROPERTY_DEFINITION *pd1 = *p1;
- const PROPERTY_DEFINITION *pd2 = *p2;
+ const OSSL_PROPERTY_DEFINITION *pd1 = *p1;
+ const OSSL_PROPERTY_DEFINITION *pd2 = *p2;
if (pd1->name_idx < pd2->name_idx)
return -1;
@@ -295,7 +269,7 @@ static int pd_compare(const PROPERTY_DEFINITION *const *p1,
return 0;
}
-static void pd_free(PROPERTY_DEFINITION *pd)
+static void pd_free(OSSL_PROPERTY_DEFINITION *pd)
{
OPENSSL_free(pd);
}
@@ -304,21 +278,21 @@ static void pd_free(PROPERTY_DEFINITION *pd)
* Convert a stack of property definitions and queries into a fixed array.
* The items are sorted for efficient query. The stack is not freed.
*/
-static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION)
- *sk)
+static OSSL_PROPERTY_LIST *
+stack_to_property_list(STACK_OF(OSSL_PROPERTY_DEFINITION) *sk)
{
- const int n = sk_PROPERTY_DEFINITION_num(sk);
+ const int n = sk_OSSL_PROPERTY_DEFINITION_num(sk);
OSSL_PROPERTY_LIST *r;
int i;
r = OPENSSL_malloc(sizeof(*r)
+ (n <= 0 ? 0 : n - 1) * sizeof(r->properties[0]));
if (r != NULL) {
- sk_PROPERTY_DEFINITION_sort(sk);
+ sk_OSSL_PROPERTY_DEFINITION_sort(sk);
r->has_optional = 0;
for (i = 0; i < n; i++) {
- r->properties[i] = *sk_PROPERTY_DEFINITION_value(sk, i);
+ r->properties[i] = *sk_OSSL_PROPERTY_DEFINITION_value(sk, i);
r->has_optional |= r->properties[i].optional;
}
r->n = n;
@@ -328,13 +302,13 @@ static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION)
OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn)
{
- PROPERTY_DEFINITION *prop = NULL;
+ OSSL_PROPERTY_DEFINITION *prop = NULL;
OSSL_PROPERTY_LIST *res = NULL;
- STACK_OF(PROPERTY_DEFINITION) *sk;
+ STACK_OF(OSSL_PROPERTY_DEFINITION) *sk;
const char *s = defn;
int done;
- if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
+ if (s == NULL || (sk = sk_OSSL_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
return NULL;
s = skip_space(s);
@@ -349,7 +323,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn)
prop->optional = 0;
if (!parse_name(ctx, &s, 1, &prop->name_idx))
goto err;
- prop->oper = PROPERTY_OPER_EQ;
+ prop->oper = OSSL_PROPERTY_OPER_EQ;
if (prop->name_idx == 0) {
ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED,
"Unknown name HERE-->%s", start);
@@ -363,11 +337,11 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn)
}
} else {
/* A name alone means a true Boolean */
- prop->type = PROPERTY_TYPE_STRING;
+ prop->type = OSSL_PROPERTY_TYPE_STRING;
prop->v.str_val = ossl_property_true;
}
- if (!sk_PROPERTY_DEFINITION_push(sk, prop))
+ if (!sk_OSSL_PROPERTY_DEFINITION_push(sk, prop))
goto err;
prop = NULL;
done = !match_ch(&s, ',');
@@ -381,19 +355,19 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn)
err:
OPENSSL_free(prop);
- sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
+ sk_OSSL_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
return res;
}
OSSL_PROPERTY_LIST *ossl_parse_query(OSSL_LIB_CTX *ctx, const char *s,
int create_values)
{
- STACK_OF(PROPERTY_DEFINITION) *sk;
+ STACK_OF(OSSL_PROPERTY_DEFINITION) *sk;
OSSL_PROPERTY_LIST *res = NULL;
- PROPERTY_DEFINITION *prop = NULL;
+ OSSL_PROPERTY_DEFINITION *prop = NULL;
int done;
- if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
+ if (s == NULL || (sk = sk_OSSL_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
return NULL;
s = skip_space(s);
@@ -405,7 +379,7 @@ OSSL_PROPERTY_LIST *ossl_parse_query(OSSL_LIB_CTX *ctx, const char *s,
memset(&prop->v, 0, sizeof(prop->v));
if (match_ch(&s, '-')) {
- prop->oper = PROPERTY_OVERRIDE;
+ prop->oper = OSSL_PROPERTY_OVERRIDE;
prop->optional = 0;
if (!parse_name(ctx, &s, 1, &prop->name_idx))
goto err;
@@ -416,21 +390,21 @@ OSSL_PROPERTY_LIST *ossl_parse_query(OSSL_LIB_CTX *ctx, const char *s,
goto err;
if (match_ch(&s, '=')) {
- prop->oper = PROPERTY_OPER_EQ;
+ prop->oper = OSSL_PROPERTY_OPER_EQ;
} else if (MATCH(&s, "!=")) {
- prop->oper = PROPERTY_OPER_NE;
+ prop->oper = OSSL_PROPERTY_OPER_NE;
} else {
/* A name alone is a Boolean comparison for true */
- prop->oper = PROPERTY_OPER_EQ;
- prop->type = PROPERTY_TYPE_STRING;
+ prop->oper = OSSL_PROPERTY_OPER_EQ;
+ prop->type = OSSL_PROPERTY_TYPE_STRING;
prop->v.str_val = ossl_property_true;
goto skip_value;
}
if (!parse_value(ctx, &s, prop, create_values))
- prop->type = PROPERTY_TYPE_VALUE_UNDEFINED;
+ prop->type = OSSL_PROPERTY_TYPE_VALUE_UNDEFINED;
skip_value:
- if (!sk_PROPERTY_DEFINITION_push(sk, prop))
+ if (!sk_OSSL_PROPERTY_DEFINITION_push(sk, prop))
goto err;
prop = NULL;
done = !match_ch(&s, ',');
@@ -444,7 +418,7 @@ skip_value:
err:
OPENSSL_free(prop);
- sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
+ sk_OSSL_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
return res;
}
@@ -459,7 +433,7 @@ int ossl_property_is_enabled(OSSL_LIB_CTX *ctx, const char *property_name,
{
int i;
OSSL_PROPERTY_IDX name_id;
- const PROPERTY_DEFINITION *prop = NULL;
+ const OSSL_PROPERTY_DEFINITION *prop = NULL;
if (prop_list == NULL)
return 0;
@@ -471,12 +445,12 @@ int ossl_property_is_enabled(OSSL_LIB_CTX *ctx, const char *property_name,
for (i = 0; i < prop_list->n; ++i) {
if (prop[i].name_idx == name_id) {
/* Do a separate check for override as it does not set type */
- if (prop[i].optional || prop[i].oper == PROPERTY_OVERRIDE)
+ if (prop[i].optional || prop[i].oper == OSSL_PROPERTY_OVERRIDE)
return 0;
- return (prop[i].type == PROPERTY_TYPE_STRING
- && ((prop[i].oper == PROPERTY_OPER_EQ
+ return (prop[i].type == OSSL_PROPERTY_TYPE_STRING
+ && ((prop[i].oper == OSSL_PROPERTY_OPER_EQ
&& prop[i].v.str_val == ossl_property_true)
- || (prop[i].oper == PROPERTY_OPER_NE
+ || (prop[i].oper == OSSL_PROPERTY_OPER_NE
&& prop[i].v.str_val != ossl_property_true)));
}
}
@@ -490,13 +464,13 @@ int ossl_property_is_enabled(OSSL_LIB_CTX *ctx, const char *property_name,
int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
const OSSL_PROPERTY_LIST *defn)
{
- const PROPERTY_DEFINITION *const q = query->properties;
- const PROPERTY_DEFINITION *const d = defn->properties;
+ const OSSL_PROPERTY_DEFINITION *const q = query->properties;
+ const OSSL_PROPERTY_DEFINITION *const d = defn->properties;
int i = 0, j = 0, matches = 0;
- PROPERTY_OPER oper;
+ OSSL_PROPERTY_OPER oper;
while (i < query->n) {
- if ((oper = q[i].oper) == PROPERTY_OVERRIDE) {
+ if ((oper = q[i].oper) == OSSL_PROPERTY_OVERRIDE) {
i++;
continue;
}
@@ -509,8 +483,8 @@ int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
const int eq = q[i].type == d[j].type
&& memcmp(&q[i].v, &d[j].v, sizeof(q[i].v)) == 0;
- if ((eq && oper == PROPERTY_OPER_EQ)
- || (!eq && oper == PROPERTY_OPER_NE))
+ if ((eq && oper == OSSL_PROPERTY_OPER_EQ)
+ || (!eq && oper == OSSL_PROPERTY_OPER_NE))
matches++;
else if (!q[i].optional)
return -1;
@@ -525,15 +499,15 @@ int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
* definition. The former fails for any comparison except inequality,
* the latter is treated as a comparison against the Boolean false.
*/
- if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) {
- if (oper == PROPERTY_OPER_NE)
+ if (q[i].type == OSSL_PROPERTY_TYPE_VALUE_UNDEFINED) {
+ if (oper == OSSL_PROPERTY_OPER_NE)
matches++;
else if (!q[i].optional)
return -1;
- } else if (q[i].type != PROPERTY_TYPE_STRING
- || (oper == PROPERTY_OPER_EQ
+ } else if (q[i].type != OSSL_PROPERTY_TYPE_STRING
+ || (oper == OSSL_PROPERTY_OPER_EQ
&& q[i].v.str_val != ossl_property_false)
- || (oper == PROPERTY_OPER_NE
+ || (oper == OSSL_PROPERTY_OPER_NE
&& q[i].v.str_val == ossl_property_false)) {
if (!q[i].optional)
return -1;
@@ -557,9 +531,9 @@ void ossl_property_free(OSSL_PROPERTY_LIST *p)
OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
const OSSL_PROPERTY_LIST *b)
{
- const PROPERTY_DEFINITION *const ap = a->properties;
- const PROPERTY_DEFINITION *const bp = b->properties;
- const PROPERTY_DEFINITION *copy;
+ const OSSL_PROPERTY_DEFINITION *const ap = a->properties;
+ const OSSL_PROPERTY_DEFINITION *const bp = b->properties;
+ const OSSL_PROPERTY_DEFINITION *copy;
OSSL_PROPERTY_LIST *r;
int i, j, n;
const int t = a->n + b->n;
@@ -689,7 +663,7 @@ size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx,
size_t bufsize)
{
int i;
- const PROPERTY_DEFINITION *prop = NULL;
+ const OSSL_PROPERTY_DEFINITION *prop = NULL;
size_t needed = 0;
const char *val;
@@ -710,7 +684,7 @@ size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx,
if (prop->optional)
put_char('?', &buf, &bufsize, &needed);
- else if (prop->oper == PROPERTY_OVERRIDE)
+ else if (prop->oper == OSSL_PROPERTY_OVERRIDE)
put_char('-', &buf, &bufsize, &needed);
val = ossl_property_name_str(ctx, prop->name_idx);
@@ -719,21 +693,21 @@ size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx,
put_str(val, &buf, &bufsize, &needed);
switch (prop->oper) {
- case PROPERTY_OPER_NE:
+ case OSSL_PROPERTY_OPER_NE:
put_char('!', &buf, &bufsize, &needed);
/* fall through */
- case PROPERTY_OPER_EQ:
+ case OSSL_PROPERTY_OPER_EQ:
put_char('=', &buf, &bufsize, &needed);
/* put value */
switch (prop->type) {
- case PROPERTY_TYPE_STRING:
+ case OSSL_PROPERTY_TYPE_STRING:
val = ossl_property_value_str(ctx, prop->v.str_val);
if (val == NULL)
return 0;
put_str(val, &buf, &bufsize, &needed);
break;
- case PROPERTY_TYPE_NUMBER:
+ case OSSL_PROPERTY_TYPE_NUMBER:
put_num(prop->v.int_val, &buf, &bufsize, &needed);
break;
diff --git a/crypto/property/property_query.c b/crypto/property/property_query.c
new file mode 100644
index 0000000000..dfcb034042
--- /dev/null
+++ b/crypto/property/property_query.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 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 "internal/propertyerr.h"
+#include "internal/property.h"
+#include "property_local.h"
+
+const OSSL_PROPERTY_DEFINITION *
+ossl_property_find_property(const OSSL_PROPERTY_LIST *list,
+ OSSL_LIB_CTX *libctx, const char *name)
+{
+ OSSL_PROPERTY_IDX name_idx;
+ int i;
+
+ if (list == NULL || name == NULL
+ || (name_idx = ossl_property_name(libctx, name, 0)) == 0)
+ return NULL;
+
+ for (i = 0; i < list->n; i++)
+ if (list->properties[i].name_idx == name_idx)
+ return &list->properties[i];
+ return NULL;
+}
+
+OSSL_PROPERTY_TYPE ossl_property_get_type(const OSSL_PROPERTY_DEFINITION *prop)
+{
+ return prop->type;
+}
+
+const char *ossl_property_get_string_value(OSSL_LIB_CTX *libctx,
+ const OSSL_PROPERTY_DEFINITION *prop)
+{
+ const char *value = NULL;
+
+ if (prop != NULL && prop->type == OSSL_PROPERTY_TYPE_STRING)
+ value = ossl_property_value_str(libctx, prop->v.str_val);
+ return value;
+}
+
+int64_t ossl_property_get_number_value(const OSSL_PROPERTY_DEFINITION *prop)
+{
+ int64_t value = 0;
+
+ if (prop != NULL && prop->type == OSSL_PROPERTY_TYPE_NUMBER)
+ value = prop->v.int_val;
+ return value;
+}