[openssl] master update

Dr. Paul Dale pauli at openssl.org
Sat Oct 9 13:30:00 UTC 2021


The branch master has been updated
       via  78de5a94d8e2b0a27ae026de29c195e944a49c6d (commit)
       via  747d142318c5c9ecd80de3f061f54d7af4189039 (commit)
       via  8e61832ed7f59c15da003aa86aeaa4e5f44df711 (commit)
      from  0ce0c455862ed29bd7f2acdbddbe8d0b1783c1c9 (commit)


- Log -----------------------------------------------------------------
commit 78de5a94d8e2b0a27ae026de29c195e944a49c6d
Author: Pauli <pauli at openssl.org>
Date:   Thu Sep 30 11:39:41 2021 +1000

    doc: document that property names are unique
    
    Both queries and definitions only support each individual name appearing once.
    It is an error to have a name appear more than once.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16716)

commit 747d142318c5c9ecd80de3f061f54d7af4189039
Author: Pauli <pauli at openssl.org>
Date:   Thu Sep 30 11:35:32 2021 +1000

    test: add failure testing for property parsing
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16716)

commit 8e61832ed7f59c15da003aa86aeaa4e5f44df711
Author: Pauli <pauli at openssl.org>
Date:   Thu Sep 30 11:33:37 2021 +1000

    property: produce error if a name is duplicated
    
    Neither queries nor definitions handle duplicated property names well.
    Make having such an error.
    
    Fixes #16715
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16716)

-----------------------------------------------------------------------

Summary of changes:
 crypto/property/property_parse.c | 20 ++++++++++++++---
 doc/man7/property.pod            |  4 +++-
 test/property_test.c             | 47 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c
index 21228b4a39..3673fd7b05 100644
--- a/crypto/property/property_parse.c
+++ b/crypto/property/property_parse.c
@@ -277,12 +277,16 @@ static void pd_free(OSSL_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.
+ * This function also checks for duplicated names and returns an error if
+ * any exist.
  */
 static OSSL_PROPERTY_LIST *
-stack_to_property_list(STACK_OF(OSSL_PROPERTY_DEFINITION) *sk)
+stack_to_property_list(OSSL_LIB_CTX *ctx,
+                       STACK_OF(OSSL_PROPERTY_DEFINITION) *sk)
 {
     const int n = sk_OSSL_PROPERTY_DEFINITION_num(sk);
     OSSL_PROPERTY_LIST *r;
+    OSSL_PROPERTY_IDX prev_name_idx = 0;
     int i;
 
     r = OPENSSL_malloc(sizeof(*r)
@@ -294,6 +298,16 @@ stack_to_property_list(STACK_OF(OSSL_PROPERTY_DEFINITION) *sk)
         for (i = 0; i < n; i++) {
             r->properties[i] = *sk_OSSL_PROPERTY_DEFINITION_value(sk, i);
             r->has_optional |= r->properties[i].optional;
+
+            /* Check for duplicated names */
+            if (i > 0 && r->properties[i].name_idx == prev_name_idx) {
+                OPENSSL_free(r);
+                ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED,
+                               "Duplicated name `%s'",
+                               ossl_property_name_str(ctx, prev_name_idx));
+                return NULL;
+            }
+            prev_name_idx = r->properties[i].name_idx;
         }
         r->num_properties = n;
     }
@@ -351,7 +365,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn)
                        "HERE-->%s", s);
         goto err;
     }
-    res = stack_to_property_list(sk);
+    res = stack_to_property_list(ctx, sk);
 
 err:
     OPENSSL_free(prop);
@@ -414,7 +428,7 @@ skip_value:
                        "HERE-->%s", s);
         goto err;
     }
-    res = stack_to_property_list(sk);
+    res = stack_to_property_list(ctx, sk);
 
 err:
     OPENSSL_free(prop);
diff --git a/doc/man7/property.pod b/doc/man7/property.pod
index a75f262246..109336ba47 100644
--- a/doc/man7/property.pod
+++ b/doc/man7/property.pod
@@ -41,7 +41,8 @@ property names like
 
 A I<property> is a I<name=value> pair.
 A I<property definition> is a sequence of comma separated properties.
-There can be any number of properties in a definition.
+There can be any number of properties in a definition, however each name must
+be unique.
 For example: "" defines an empty property definition (i.e., no restriction);
 "my.foo=bar" defines a property named I<my.foo> which has a string value I<bar>
 and "iteration.count=3" defines a property named I<iteration.count> which
@@ -68,6 +69,7 @@ Matching such clauses is not a requirement, but any additional optional
 match counts in favor of the algorithm.
 More details about that in the B<Lookups> section.
 A I<property query> is a sequence of comma separated property query clauses.
+It is an error if a property name appears in more than one query clause.
 The full syntax for property queries appears below, but the available syntactic
 features are:
 
diff --git a/test/property_test.c b/test/property_test.c
index 6cc8eec138..c23ddb0f99 100644
--- a/test/property_test.c
+++ b/test/property_test.c
@@ -145,6 +145,52 @@ static int test_property_query_value_create(void)
     return r;
 }
 
+static const struct {
+    int query;
+    const char *ps;
+} parse_error_tests[] = {
+    { 0, "n=1, n=1" },          /* duplicate name */
+    { 0, "n=1, a=hi, n=1" },    /* duplicate name */
+    { 1, "n=1, a=bye, ?n=0" },  /* duplicate name */
+    { 0, "a=abc,#@!, n=1" },    /* non-ASCII character located */
+    { 1, "a='Hello" },          /* Unterminated string */
+    { 0, "a=\"World" },         /* Unterminated string */
+    { 1, "a=2, n=012345678" },  /* Bad octal digit */
+    { 0, "n=0x28FG, a=3" },     /* Bad hex digit */
+    { 0, "n=145d, a=2" },       /* Bad decimal digit */
+    { 1, "@='hello'" },         /* Invalid name */
+    { 1, "n0123456789012345678901234567890123456789"
+         "0123456789012345678901234567890123456789"
+         "0123456789012345678901234567890123456789"
+         "0123456789012345678901234567890123456789=yes" }, /* Name too long */
+    { 0, ".n=3" },              /* Invalid name */
+    { 1, "fnord.fnord.=3" }     /* Invalid name */
+};
+
+static int test_property_parse_error(int n)
+{
+    OSSL_METHOD_STORE *store;
+    OSSL_PROPERTY_LIST *p = NULL;
+    int r = 0;
+    const char *ps;
+
+    if (!TEST_ptr(store = ossl_method_store_new(NULL))
+        || !add_property_names("a", "n", NULL))
+        goto err;
+    ps = parse_error_tests[n].ps;
+    if (parse_error_tests[n].query) {
+        if (!TEST_ptr_null(p = ossl_parse_query(NULL, ps, 1)))
+            goto err;
+    } else if (!TEST_ptr_null(p = ossl_parse_property(NULL, ps))) {
+        goto err;
+    }
+    r = 1;
+ err:
+    ossl_property_free(p);
+    ossl_method_store_free(store);
+    return r;
+}
+
 static const struct {
     const char *q_global;
     const char *q_local;
@@ -493,6 +539,7 @@ int setup_tests(void)
     ADD_TEST(test_property_string);
     ADD_TEST(test_property_query_value_create);
     ADD_ALL_TESTS(test_property_parse, OSSL_NELEM(parser_tests));
+    ADD_ALL_TESTS(test_property_parse_error, OSSL_NELEM(parse_error_tests));
     ADD_ALL_TESTS(test_property_merge, OSSL_NELEM(merge_tests));
     ADD_TEST(test_property_defn_cache);
     ADD_ALL_TESTS(test_definition_compares, OSSL_NELEM(definition_tests));


More information about the openssl-commits mailing list