diff options
author | Richard Levitte <levitte@openssl.org> | 2021-06-01 20:02:24 +0200 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-06-05 20:29:47 +1000 |
commit | 6ec3b2cf4992a304b4ab36f7b9e9ff130bd495b7 (patch) | |
tree | 348097b950d9bc6de530d93dfe8f0c70cc8bd983 /crypto/property | |
parent | 0b3fe363e6188dcb854d480180c9af91cc613f2c (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.info | 2 | ||||
-rw-r--r-- | crypto/property/property_local.h | 21 | ||||
-rw-r--r-- | crypto/property/property_parse.c | 156 | ||||
-rw-r--r-- | crypto/property/property_query.c | 53 |
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; +} |