params: add functionality to test if an OSSL_PARAM has been set.
authorPauli <paul.dale@oracle.com>
Tue, 21 Apr 2020 00:49:19 +0000 (10:49 +1000)
committerPauli <paul.dale@oracle.com>
Wed, 22 Apr 2020 03:56:44 +0000 (13:56 +1000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11588)

crypto/params.c
doc/man3/OSSL_PARAM_int.pod
include/openssl/params.h
test/params_api_test.c
test/params_test.c
util/libcrypto.num

index 64d53c50e3a12d3263a3f07a548b42bb48fddb78..1decffdaca40bc03c880e496aa05ed2e6bb56488 100644 (file)
@@ -36,10 +36,21 @@ static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
     res.data_type = data_type;
     res.data = data;
     res.data_size = data_size;
-    res.return_size = 0;
+    res.return_size = OSSL_PARAM_UNMODIFIED;
     return res;
 }
 
+int OSSL_PARAM_modified(const OSSL_PARAM *p)
+{
+    return p != NULL && p->return_size != OSSL_PARAM_UNMODIFIED;
+}
+
+void OSSL_PARAM_set_unmodified(OSSL_PARAM *p)
+{
+    if (p != NULL)
+        p->return_size = OSSL_PARAM_UNMODIFIED;
+}
+
 int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
 {
     switch (sizeof(int)) {
index 99e4fcf088a91e442e40b6bd117ad31ad2d8cffe..c7dbcbcd10d38f99cd8f184d67b1dae5ec2e02a4 100644 (file)
@@ -27,7 +27,7 @@ OSSL_PARAM_set_int64, OSSL_PARAM_set_long, OSSL_PARAM_set_size_t,
 OSSL_PARAM_set_uint, OSSL_PARAM_set_uint32, OSSL_PARAM_set_uint64,
 OSSL_PARAM_set_ulong, OSSL_PARAM_set_BN, OSSL_PARAM_set_utf8_string,
 OSSL_PARAM_set_octet_string, OSSL_PARAM_set_utf8_ptr,
-OSSL_PARAM_set_octet_ptr
+OSSL_PARAM_set_octet_ptr, OSSL_PARAM_UNMODIFIED
 - OSSL_PARAM helpers
 
 =head1 SYNOPSIS
@@ -52,6 +52,8 @@ OSSL_PARAM_set_octet_ptr
  #define OSSL_PARAM_octet_ptr(key, address, size)
  #define OSSL_PARAM_END
 
+ #define OSSL_PARAM_UNMODIFIED
+
  OSSL_PARAM OSSL_PARAM_construct_TYPE(const char *key, TYPE *buf);
  OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
                                     size_t bsize);
@@ -91,6 +93,9 @@ OSSL_PARAM_set_octet_ptr
  int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
                               size_t used_len);
 
+ int OSSL_PARAM_modified(const OSSL_PARAM *p);
+ void OSSL_PARAM_set_unmodified(OSSL_PARAM *p);
+
 =head1 DESCRIPTION
 
 A collection of utility functions that simplify and add type safety to the
@@ -250,6 +255,16 @@ OSSL_PARAM_set_octet_ptr() sets the OCTET string pointer in the parameter
 referenced by B<p> to the values B<val>.
 The length of the OCTET string is provided by B<used_len>.
 
+The OSSL_PARAM_UNMODIFIED macro is used to detect if a parameter was set.  On
+creation, via either the macros or construct calls, the I<return_size> field
+is set to this.  If the parameter is set using the calls defined herein, the
+I<return_size> field is changed.
+
+OSSL_PARAM_modified() queries if the parameter has been set or not using the
+calls defined herein.
+
+OSSL_PARAM_set_unmodified() is used to reset unused indicator.
+
 =head1 RETURN VALUES
 
 OSSL_PARAM_construct_TYPE(), OSSL_PARAM_construct_BN(),
@@ -261,6 +276,8 @@ OSSL_PARAM_locate() and OSSL_PARAM_locate_const() return a pointer to
 the matching OSSL_PARAM object.  They return B<NULL> on error or when
 no object matching B<key> exists in the B<array>.
 
+OSSL_PARAM_modified() returns B<1> if the parameter was set and B<0> otherwise.
+
 All other functions return B<1> on success and B<0> on failure.
 
 =head1 NOTES
index cd0f7846d7e6818eece5e9c18cdfaf8438f4cbfb..441dfbbe0e5b126e1175e1185b783956d53a1f27 100644 (file)
 extern "C" {
 # endif
 
+# define OSSL_PARAM_UNMODIFIED ((size_t)-1)
+
 # define OSSL_PARAM_END \
     { NULL, 0, NULL, 0, 0 }
 
 # define OSSL_PARAM_DEFN(key, type, addr, sz)    \
-    { (key), (type), (addr), (sz), 0 }
+    { (key), (type), (addr), (sz), OSSL_PARAM_UNMODIFIED }
 
 /* Basic parameter types without return sizes */
 # define OSSL_PARAM_int(key, addr) \
@@ -135,6 +137,9 @@ int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
 int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
                              size_t used_len);
 
+int OSSL_PARAM_modified(const OSSL_PARAM *p);
+void OSSL_PARAM_set_unmodified(OSSL_PARAM *p);
+
 # ifdef  __cplusplus
 }
 # endif
index c403f39abdd69f9415807a71ea445e51c2a86fe6..d01044d0eb4a00c179a644a9e6e5773d6ee16258 100644 (file)
@@ -69,6 +69,7 @@ static int test_param_type_extra(OSSL_PARAM *param, const unsigned char *cmp,
     const int sizet = bit32 && sizeof(size_t) > sizeof(int32_t);
     const int signd = param->data_type == OSSL_PARAM_INTEGER;
 
+    OSSL_PARAM_set_unmodified(param);
     if (signd) {
         if ((bit32 && !TEST_true(OSSL_PARAM_get_int32(param, &i32)))
             || !TEST_true(OSSL_PARAM_get_int64(param, &i64)))
@@ -80,6 +81,8 @@ static int test_param_type_extra(OSSL_PARAM *param, const unsigned char *cmp,
             || (sizet && !TEST_true(OSSL_PARAM_get_size_t(param, &s))))
             return 0;
     }
+    if (!TEST_false(OSSL_PARAM_modified(param)))
+        return 0;
 
     /* Check signed types */
     if (bit32) {
@@ -112,6 +115,8 @@ static int test_param_type_extra(OSSL_PARAM *param, const unsigned char *cmp,
                 || !TEST_size_t_eq((size_t)i64, 12345))
                 return 0;
         }
+        if (!TEST_true(OSSL_PARAM_modified(param)))
+            return 0;
     }
     return 1;
 }
index 339a51694f6311052294dff4184a7e6245a587f3..5ed7d36a1ea45d2f96440cad0d9b9c4c1515d5d5 100644 (file)
@@ -467,8 +467,7 @@ static int test_case_variant(OSSL_PARAM *params, const struct provider_dispatch_
         || !TEST_size_t_eq(p->return_size, sizeof(p6_init)) /* "provider" value */
         || !TEST_str_eq(app_p6, p6_init)        /* "provider" value */
         || !TEST_char_eq(foo[0], app_foo_init)  /* Should remain untouched */
-        || !TEST_ptr(p = OSSL_PARAM_locate(params, "foo"))
-        || !TEST_int_eq(p->return_size, 0))
+        || !TEST_ptr(p = OSSL_PARAM_locate(params, "foo")))
         errcnt++;
 
     /*
@@ -519,8 +518,7 @@ static int test_case_variant(OSSL_PARAM *params, const struct provider_dispatch_
                            sizeof(app_p6_init)) /* app value */
         || !TEST_str_eq(app_p6, app_p6_init)    /* app value */
         || !TEST_char_eq(foo[0], app_foo_init)  /* Should remain untouched */
-        || !TEST_ptr(p = OSSL_PARAM_locate(params, "foo"))
-        || !TEST_int_eq(p->return_size, 0))
+        || !TEST_ptr(p = OSSL_PARAM_locate(params, "foo")))
         errcnt++;
 
  fin:
index 76855981b990b492ae52edb808d600d8e5c41c98..dbaea8c716863cc7f10325f29ce9e4eb7b2b400f 100644 (file)
@@ -5077,3 +5077,5 @@ X509_REQ_verify_ex                      ? 3_0_0   EXIST::FUNCTION:
 X509_ALGOR_copy                         ?      3_0_0   EXIST::FUNCTION:
 X509_REQ_set0_signature                 ?      3_0_0   EXIST::FUNCTION:
 X509_REQ_set1_signature_algo            ?      3_0_0   EXIST::FUNCTION:
+OSSL_PARAM_modified                     ?      3_0_0   EXIST::FUNCTION:
+OSSL_PARAM_set_unmodified               ?      3_0_0   EXIST::FUNCTION: