summaryrefslogtreecommitdiffstats
path: root/crypto/property
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-05-07 16:42:53 +0100
committerMatt Caswell <matt@openssl.org>2021-05-20 09:28:38 +0100
commite2ed740ec4dcfd32723d849a146bfc126b95d16c (patch)
tree6b8d1e59a96b14cd7e8170c0f6ee2d260584eb04 /crypto/property
parent87e4e9c473dd3305cb98b37c672edff8ddb436de (diff)
Implement the ability to convert a PROPERTY_LIST to a string
We have the ability to parse a string into a PROPERTY_LIST already. Now we have the ability to go the other way. Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15242)
Diffstat (limited to 'crypto/property')
-rw-r--r--crypto/property/property_local.h2
-rw-r--r--crypto/property/property_parse.c130
-rw-r--r--crypto/property/property_string.c44
3 files changed, 176 insertions, 0 deletions
diff --git a/crypto/property/property_local.h b/crypto/property/property_local.h
index c744a5d3c3..8cc3a51270 100644
--- a/crypto/property/property_local.h
+++ b/crypto/property/property_local.h
@@ -16,8 +16,10 @@ typedef int OSSL_PROPERTY_IDX;
/* Property string functions */
OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s,
int create);
+const char *ossl_property_name_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx);
OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s,
int create);
+const char *ossl_property_value_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx);
/* Property list functions */
void ossl_property_free(OSSL_PROPERTY_LIST *p);
diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c
index dfae76518f..aab8cbe8a4 100644
--- a/crypto/property/property_parse.c
+++ b/crypto/property/property_parse.c
@@ -616,3 +616,133 @@ int ossl_property_parse_init(OSSL_LIB_CTX *ctx)
err:
return 0;
}
+
+static void put_char(char ch, char **buf, size_t *remain, size_t *needed)
+{
+ if (*remain == 0) {
+ ++*needed;
+ return;
+ }
+ if(*remain == 1)
+ **buf = '\0';
+ else
+ **buf = ch;
+ ++*buf;
+ ++*needed;
+ --*remain;
+}
+
+static void put_str(const char *str, char **buf, size_t *remain, size_t *needed)
+{
+ size_t olen, len;
+
+ len = olen = strlen(str);
+ *needed += len;
+
+ if (*remain == 0)
+ return;
+
+ if(*remain < len + 1)
+ len = *remain - 1;
+
+ if(len > 0) {
+ strncpy(*buf, str, len);
+ *buf += len;
+ *remain -= len;
+ }
+
+ if(len < olen && *remain == 1) {
+ **buf = '\0';
+ ++*buf;
+ --*remain;
+ }
+}
+
+static void put_num(int val, char **buf, size_t *remain, size_t *needed)
+{
+ int tmpval = val;
+ size_t len = 1;
+
+ for (; tmpval > 9; len++, tmpval /= 10);
+
+ *needed += len;
+
+ if (*remain == 0)
+ return;
+
+ BIO_snprintf(*buf, *remain, "%d", val);
+ if (*remain < len) {
+ *buf += *remain;
+ *remain = 0;
+ } else {
+ *buf += len;
+ *remain -= len;
+ }
+}
+
+size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx,
+ const OSSL_PROPERTY_LIST *list, char *buf,
+ size_t bufsize)
+{
+ int i;
+ const PROPERTY_DEFINITION *prop = NULL;
+ size_t needed = 0;
+ const char *val;
+
+ if (list == NULL) {
+ if (bufsize > 0)
+ *buf = '\0';
+ return 1;
+ }
+ if (list->n != 0)
+ prop = &list->properties[list->n - 1];
+ for (i = 0; i < list->n; i++, prop--) {
+ /* Skip invalid names */
+ if (prop->name_idx == 0)
+ continue;
+
+ if (needed > 0)
+ put_char(',', &buf, &bufsize, &needed);
+
+ if (prop->optional)
+ put_char('?', &buf, &bufsize, &needed);
+ else if (prop->oper == PROPERTY_OVERRIDE)
+ put_char('-', &buf, &bufsize, &needed);
+
+ val = ossl_property_name_str(ctx, prop->name_idx);
+ if (val == NULL)
+ return 0;
+ put_str(val, &buf, &bufsize, &needed);
+
+ switch (prop->oper) {
+ case PROPERTY_OPER_NE:
+ put_char('!', &buf, &bufsize, &needed);
+ /* fall through */
+ case PROPERTY_OPER_EQ:
+ put_char('=', &buf, &bufsize, &needed);
+ /* put value */
+ switch (prop->type) {
+ case 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:
+ put_num(prop->v.int_val, &buf, &bufsize, &needed);
+ break;
+
+ default:
+ return 0;
+ }
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+
+ put_char('\0', &buf, &bufsize, &needed);
+ return needed;
+}
diff --git a/crypto/property/property_string.c b/crypto/property/property_string.c
index 9eb55cb461..06f58496db 100644
--- a/crypto/property/property_string.c
+++ b/crypto/property/property_string.c
@@ -162,6 +162,45 @@ OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s,
s);
}
+struct find_str_st {
+ const char *str;
+ OSSL_PROPERTY_IDX idx;
+};
+
+static void find_str_fn(PROPERTY_STRING *prop, void *vfindstr)
+{
+ struct find_str_st *findstr = vfindstr;
+
+ if (prop->idx == findstr->idx)
+ findstr->str = prop->s;
+}
+
+static const char *ossl_property_str(int name, OSSL_LIB_CTX *ctx,
+ OSSL_PROPERTY_IDX idx)
+{
+ struct find_str_st findstr;
+ PROPERTY_STRING_DATA *propdata
+ = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX,
+ &property_string_data_method);
+
+ if (propdata == NULL)
+ return NULL;
+
+ findstr.str = NULL;
+ findstr.idx = idx;
+
+ lh_PROPERTY_STRING_doall_arg(name ? propdata->prop_names
+ : propdata->prop_values,
+ find_str_fn, &findstr);
+
+ return findstr.str;
+}
+
+const char *ossl_property_name_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx)
+{
+ return ossl_property_str(1, ctx, idx);
+}
+
OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s,
int create)
{
@@ -175,3 +214,8 @@ OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s,
create ? &propdata->prop_value_idx : NULL,
s);
}
+
+const char *ossl_property_value_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx)
+{
+ return ossl_property_str(0, ctx, idx);
+}