summaryrefslogtreecommitdiffstats
path: root/crypto/property/property_string.c
diff options
context:
space:
mode:
authorPauli <paul.dale@oracle.com>2018-11-16 11:44:30 +1000
committerPauli <paul.dale@oracle.com>2019-02-18 13:28:14 +1000
commit1bdbdaffdc66be457a40f33640b523aaf21138c6 (patch)
tree23bd17995698f4f14780fc9b9a3dad589f2ea96a /crypto/property/property_string.c
parente3ac3654892246d7492f1012897e42ad7efd13ce (diff)
Properties for implementation selection.
Properties are a sequence of comma separated name=value pairs. A name without a corresponding value is assumed to be a Boolean and have the true value 'yes'. Values are either strings or numbers. Strings can be quoted either _"_ or _'_ or unquoted (with restrictions). There are no escape characters inside strings. Number are either decimal digits or '0x' followed by hexidecimal digits. Numbers are represented internally as signed sixty four bit values. Queries on properties are a sequence comma separated conditional tests. These take the form of name=value (equality test), name!=value (inequality test) or name (Boolean test for truth). Queries can be parsed, compared against a definition or merged pairwise. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8224)
Diffstat (limited to 'crypto/property/property_string.c')
-rw-r--r--crypto/property/property_string.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/crypto/property/property_string.c b/crypto/property/property_string.c
new file mode 100644
index 0000000000..7f6e30effb
--- /dev/null
+++ b/crypto/property/property_string.c
@@ -0,0 +1,137 @@
+/*
+ * 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 <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include "internal/lhash.h"
+#include "property_lcl.h"
+
+/*
+ * Property strings are a consolidation of all strings seen by the property
+ * subsystem. There are two name spaces to keep property names separate from
+ * property values (numeric values are not expected to be cached however).
+ * They allow a rapid conversion from a string to a unique index and any
+ * subsequent string comparison can be done via an integer compare.
+ *
+ * This implementation uses OpenSSL's standard hash table. There are more
+ * space and time efficient algorithms if this becomes a bottleneck.
+ */
+
+typedef struct {
+ const char *s;
+ OSSL_PROPERTY_IDX idx;
+ char body[1];
+} PROPERTY_STRING;
+
+DEFINE_LHASH_OF(PROPERTY_STRING);
+typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE;
+
+static PROP_TABLE *prop_names;
+static PROP_TABLE *prop_values;
+static OSSL_PROPERTY_IDX prop_name_idx = 0;
+static OSSL_PROPERTY_IDX prop_value_idx = 0;
+
+static unsigned long property_hash(const PROPERTY_STRING *a)
+{
+ return OPENSSL_LH_strhash(a->s);
+}
+
+static int property_cmp(const PROPERTY_STRING *a, const PROPERTY_STRING *b)
+{
+ return strcmp(a->s, b->s);
+}
+
+static void property_free(PROPERTY_STRING *ps)
+{
+ OPENSSL_free(ps);
+}
+
+static void property_table_free(PROP_TABLE **pt)
+{
+ PROP_TABLE *t = *pt;
+
+ if (t != NULL) {
+ lh_PROPERTY_STRING_doall(t, &property_free);
+ lh_PROPERTY_STRING_free(t);
+ *pt = NULL;
+ }
+}
+
+static PROPERTY_STRING *new_property_string(const char *s,
+ OSSL_PROPERTY_IDX *pidx)
+{
+ const size_t l = strlen(s);
+ PROPERTY_STRING *ps = OPENSSL_malloc(sizeof(*ps) + l);
+
+ if (ps != NULL) {
+ memcpy(ps->body, s, l + 1);
+ ps->s = ps->body;
+ ps->idx = ++*pidx;
+ if (ps->idx == 0) {
+ OPENSSL_free(ps);
+ return NULL;
+ }
+ }
+ return ps;
+}
+
+static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t,
+ OSSL_PROPERTY_IDX *pidx,
+ const char *s)
+{
+ PROPERTY_STRING p, *ps, *ps_new;
+
+ p.s = s;
+ ps = lh_PROPERTY_STRING_retrieve(t, &p);
+ if (ps == NULL && pidx != NULL)
+ if ((ps_new = new_property_string(s, pidx)) != NULL) {
+ lh_PROPERTY_STRING_insert(t, ps_new);
+ if (lh_PROPERTY_STRING_error(t)) {
+ property_free(ps_new);
+ return 0;
+ }
+ ps = ps_new;
+ }
+ return ps != NULL ? ps->idx : 0;
+}
+
+OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create)
+{
+ return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s);
+}
+
+OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create)
+{
+ return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s);
+}
+
+int ossl_property_string_init(void)
+{
+ prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
+ if (prop_names == NULL)
+ return 0;
+
+ prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
+ if (prop_values == NULL)
+ goto err;
+ return 1;
+
+err:
+ ossl_property_string_cleanup();
+ return 0;
+}
+
+void ossl_property_string_cleanup(void)
+{
+ property_table_free(&prop_names);
+ property_table_free(&prop_values);
+ prop_name_idx = prop_value_idx = 0;
+}