Replumbing: Add include/openssl/core.h, initially with core types
authorRichard Levitte <levitte@openssl.org>
Sun, 20 Jan 2019 12:23:30 +0000 (13:23 +0100)
committerRichard Levitte <levitte@openssl.org>
Wed, 27 Feb 2019 17:36:30 +0000 (18:36 +0100)
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8286)

doc/man3/OSSL_PARAM.pod [new file with mode: 0644]
doc/man7/openssl-core.h.pod [new file with mode: 0644]
include/openssl/core.h [new file with mode: 0644]
include/openssl/ossl_typ.h
util/private.num

diff --git a/doc/man3/OSSL_PARAM.pod b/doc/man3/OSSL_PARAM.pod
new file mode 100644 (file)
index 0000000..9d47486
--- /dev/null
@@ -0,0 +1,302 @@
+=pod
+
+=head1 NAME
+
+OSSL_PARAM - a structure to pass or request object parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/core.h>
+
+ typedef struct ossl_param_st OSSL_PARAM;
+ struct ossl_param_st {
+     const char *key;             /* the name of the parameter */
+     unsigned char data_type;     /* declare what kind of content is in buffer */
+     void *buffer;                /* value being passed in or out */
+     size_t buffer_size;          /* buffer size */
+     size_t *return_size;         /* OPTIONAL: address to content size */
+ };
+
+=head1 DESCRIPTION
+
+C<OSSL_PARAM> is a type that allows passing arbitrary data for some
+object between two parties that have no or very little shared
+knowledge about their respective internal structures for that object.
+
+A typical usage example could be an application that wants to set some
+parameters for an object, or wants to find out some parameters of an
+object.
+
+Arrays of this type can be used for two purposes:
+
+=over 4
+
+=item *
+
+Setting parameters for some object.
+The caller sets up the C<OSSL_PARAM> array and calls some function
+(the I<setter>) that has intimate knowledge about the object that can
+take the data from the C<OSSL_PARAM> array and assign them in a
+suitable form for the internal structure of the object.
+
+=item *
+
+Request parameters of some object.
+The caller (the I<requestor>) sets up the C<OSSL_PARAM> array and
+calls some function (the I<responder>) that has intimate knowledge
+about the object, which can take the internal data of the object and
+copy (possibly convert) that to the buffers prepared by the
+I<requestor>.
+
+=back
+
+=head2 C<OSSL_PARAM> fields
+
+=over 4
+
+=item C<key>
+
+The identity of the parameter in the form of a string.
+
+=item C<data_type>
+
+=for comment It's still debated if this field should be present, or if
+the type should always be implied by how it's used.
+Either way, these data types will have to be passed together with the
+names as an array of OSSL_ITEM, for discovery purposes.
+
+The C<data_type> is a value that describes the type and organization of
+the data.
+See L</Supported types> below for a description of the types.
+
+=item C<buffer>
+
+=item C<buffer_size>
+
+C<buffer> is a pointer to the memory where the parameter data is (when
+setting parameters) or shall (when requesting parameters) be stored,
+and C<buffer_size> is its size in bytes.
+The organization of the data depends on the parameter type and flag.
+
+=item C<return_size>
+
+When an array of C<OSSL_PARAM> is used to request data, the
+I<responder> must set this field to indicate the actual size of the
+parameter data.
+In case the C<buffer_size> is too small for the data, the I<responder>
+must still set this field to indicate the minimum buffer size
+required.
+
+=back
+
+B<NOTE:>
+
+The key names and associated types are defined by the entity that
+offers these parameters, i.e. names for parameters provided by the
+OpenSSL libraries are defined by the libraries, and names for
+parameters provided by providers are defined by those providers,
+except for the pointer form of strings (see data type descriptions
+below).
+Entities that want to set or request parameters need to know what
+those keys are and of what type, any functionality between those two
+entities should remain oblivious and just pass the C<OSSL_PARAM> array
+along.
+
+=head2 Supported types
+
+The C<data_type> field can be one of the following types:
+
+=over 4
+
+=item C<OSSL_PARAM_INTEGER>
+
+=item C<OSSL_PARAM_UNSIGNED_INTEGER>
+
+The parameter data is an integer (signed or unsigned) of arbitrary
+length, organized in native form, i.e. most significant byte first on
+Big-Endian systems, and least significant byte first on Little-Endian
+systems.
+
+=item C<OSSL_PARAM_REAL>
+
+=for comment It's still debated if we need this or not.
+
+The parameter data is a floating point value in native form.
+
+=item C<OSSL_PARAM_UTF8_STRING>
+
+The parameter data is a printable string.
+
+=item C<OSSL_PARAM_OCTET_STRING>
+
+The parameter data is an arbitrary string of bytes.
+
+=back
+
+Additionally, this flag can be added to any type:
+
+=over 4
+
+=item C<OSSL_PARAM_POINTER_FLAG>
+
+With this flag, C<buffer> doesn't point directly at the data, but at a
+pointer that points at the data.
+
+This can be used to indicate that constant data is or will be passed,
+and there is therefore no need to copy the data that is passed, just
+the pointer to it.
+
+If an C<OSSL_PARAM> with this flag set is used to set a parameter,
+C<buffer_size> must be set to the size of the data, not the size of
+the pointer to the data.
+
+If this C<OSSL_PARAM> is used in a parameter request, C<buffer_size>
+is not relevant.
+However, the I<responder> will set C<*return_size> to the size of the
+data (again, not the size of the pointer to the data).
+
+Note that the use of this flag is B<fragile> and can only be safely
+used for data that remains constant and in a constant location for a
+long enough duration (such as the life-time of the entity that
+offers these parameters).
+
+=back
+
+For convenience, these types are provided:
+
+=over 4
+
+=item C<OSSL_PARAM_UTF8_STRING_PTR>
+
+=item C<OSSL_PARAM_OCTET_STRING_PTR>
+
+These are combinations of C<OSSL_PARAM_UTF8_STRING> as well as
+C<OSSL_PARAM_OCTET_STRING> with C<OSSL_PARAM_POINTER_FLAG>.
+
+=back
+
+=head1 NOTES
+
+Both when setting and requesting parameters, the functions that are
+called will have to decide what is and what is not an error.
+The recommended behaviour is:
+
+=over 4
+
+=item *
+
+Keys that a I<setter> or I<responder> doesn't recognise should simply
+be ignored.
+That in itself isn't an error.
+
+=item *
+
+If the keys that a called I<setter> recognises form a consistent
+enough set of data, that call should succeed.
+
+=item *
+
+A I<responder> must never change the fields of an C<OSSL_PARAM>, it
+may only change the contents of the buffers that C<buffer> and
+C<return_size> point at.
+
+=item *
+
+If the data type for a key that it's associated with is incorrect,
+the called function may return an error.
+
+The called function may also try to convert the data to a suitable
+form (for example, it's plausible to pass a large number as an octet
+string, so even though a given key is defined as an
+C<OSSL_PARAM_UNSIGNED_INTEGER>, is plausible to pass the value as an
+C<OSSL_PARAM_OCTET_STRING>), but this is in no way mandatory.
+
+=item *
+
+If a I<responder> finds that some buffers are too small for the
+requested data, it must set C<*return_size> for each such
+C<OSSL_PARAM> item to the required size, and eventually return an
+error.
+
+=back
+
+=begin comment RETURN VALUES doesn't make sense for a manual that only
+describes a type, but document checkers still want that section, and
+to have more than just the section title.
+
+=head1 RETURN VALUES
+
+txt
+
+=end comment
+
+=head1 EXAMPLES
+
+A couple of examples to just show how C<OSSL_PARAM> arrays could be
+set up.
+
+=head3 Example 1
+
+This example is for setting parameters on some object:
+
+    #include <openssl/core.h>
+
+    const char *foo = "some string";
+    size_t foo_l = strlen(foo) + 1;
+    const char bar[] = "some other string";
+    const OSSL_PARAM set[] = {
+        { "foo", OSSL_PARAM_UTF8_STRING_PTR, &foo, foo_l, NULL },
+        { "bar", OSSL_PARAM_UTF8_STRING, &bar, sizeof(bar), NULL },
+        { NULL, 0, NULL, 0, NULL }
+    };
+
+=head3 Example 2
+
+This example is for requesting parameters on some object:
+
+    const char *foo = NULL;
+    size_t foo_l;
+    char bar[1024];
+    size_t bar_l;
+    const OSSL_PARAM request[] = {
+        { "foo", OSSL_PARAM_UTF8_STRING_PTR, &foo, 0 /*irrelevant*/, &foo_l },
+        { "bar", OSSL_PARAM_UTF8_STRING, &bar, sizeof(bar), &bar_l },
+        { NULL, 0, NULL, 0, NULL }
+    };
+
+A I<responder> that receives this array (as C<params> in this example)
+could fill in the parameters like this:
+
+    /* const OSSL_PARAM *params */
+
+    int i;
+
+    for (i = 0; params[i].key != NULL; i++) {
+        if (strcmp(params[i].key, "foo") == 0) {
+            *(char **)params[i].buffer = "foo value";
+            *params[i].return_size = 10; /* size of "foo value" */
+        } else if (strcmp(params[i].key, "bar") == 0) {
+            memcpy(params[1].buffer, "bar value", 10);
+            *params[1].return_size = 10; /* size of "bar value" */
+        }
+        /* Ignore stuff we don't know */
+    }
+
+=head1 SEE ALSO
+
+L<openssl-core.h(7)>
+
+=head1 HISTORY
+
+C<OSSL_PARAM> was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man7/openssl-core.h.pod b/doc/man7/openssl-core.h.pod
new file mode 100644 (file)
index 0000000..7fd4dfb
--- /dev/null
@@ -0,0 +1,96 @@
+=pod
+
+=head1 NAME
+
+openssl/core.h - OpenSSL Core types
+
+=head1 SYNOPSIS
+
+ #include <openssl/core.h>
+
+=head1 DESCRIPTION
+
+The <openssl/core.h> header file defines a number of public types that
+are used to communicate between the OpenSSL libraries and
+implementation providers.
+These types are designed to minimise the need for intimate knowledge
+of internal structures between the OpenSSL libraries and the providers.
+
+The types are:
+
+=over 4
+
+=item C<OSSL_DISPATCH>
+
+This type is a tuple of function identity and function pointer.
+Arrays of this type are passed between the OpenSSL libraries and the
+providers to describe what functionality one side provides to the
+other.
+Arrays of this type must be terminated with a tuple having function
+identity zero and function pointer C<NULL>.
+
+The available function identities and corresponding function
+signatures are defined by L<openssl-core_numbers.h(7)>.
+
+Any function identity not recognised by the recipient of this type
+will be ignored.
+This ensures that providers built with one OpenSSL version in mind
+will work together with any other OpenSSL version that supports this
+mechanism.
+
+=item C<OSSL_ITEM>
+
+This type is a tuple of integer and pointer.
+It's a generic type used as a generic descriptor, its exact meaning
+being defined by how it's used.
+Arrays of this type are passed between the OpenSSL libraries and the
+providers, and must be terminated with a tuple where the integer is
+zero and the pointer C<NULL>.
+
+=item C<OSSL_ALGORITHM>
+
+This type is a tuple of an algorithm name (string), a property
+definition (string) and a dispatch table (array of C<OSSL_DISPATCH>).
+Arrays of this type are passed on demand from the providers to the
+OpenSSL libraries to describe what algorithms the providers provide
+implementations of, and with what properties.
+Arrays of this type must be terminated with a tuple having function
+identity zero and function pointer C<NULL>.
+
+The algorithm names and property definitions are defined by the
+providers.
+
+=item C<OSSL_PARAM>
+
+This type is a structure that allows passing arbitrary object data
+between two parties that have no or very little shared knowledge about
+their respective internal structures for that object. 
+It's normally passed in arrays, where the array is terminated with an
+element where all fields are zero (for non-pointers) or C<NULL> (for
+pointers).
+
+These arrays can be used both to set parameters for some object, and
+to request parameters.
+
+C<OSSL_PARAM> is further described in L<OSSL_PARAM(3)>
+
+=back
+
+=head1 SEE ALSO
+
+L<openssl-core_numbers.h(7)>
+
+=head1 HISTORY
+
+The types described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/openssl/core.h b/include/openssl/core.h
new file mode 100644 (file)
index 0000000..98b58be
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2019 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
+ */
+
+#ifndef OSSL_CORE_H
+# define OSSL_CORE_H
+
+# include <stddef.h>
+# include <openssl/ossl_typ.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/*-
+ * Base types
+ * ----------
+ *
+ * These are the types that the OpenSSL core and providers have in common
+ * to communicate data between them.
+ */
+
+/*
+ * Dispatch table element.  function_id numbers are defined further down,
+ * see macros with '_FUNC' in their names.
+ *
+ * An array of these is always terminated by function_id == 0
+ */
+struct ossl_dispatch_st {
+    int function_id;
+    void (*function)(void);
+};
+
+/*
+ * Other items, essentially an int<->pointer map element.
+ *
+ * We make this type distinct from OSSL_DISPATCH to ensure that dispatch
+ * tables remain tables with function pointers only.
+ *
+ * This is used whenever we need to pass things like a table of error reason
+ * codes <-> reason string maps, parameter name <-> parameter type maps, ...
+ *
+ * Usage determines which field works as key if any, rather than field order.
+ *
+ * An array of these is always terminated by id == 0 && ptr == NULL
+ */
+struct ossl_item_st {
+    unsigned int id;
+    void *ptr;
+};
+
+/*
+ * Type to tie together algorithm name, property definition string and
+ * the algorithm implementation in the form of a dispatch table.
+ *
+ * An array of these is always terminated by algorithm_name == NULL
+ */
+struct ossl_algorithm_st {
+    const char *algorithm_name;      /* key */
+    const char *property_definition; /* key */
+    const OSSL_DISPATCH *implementation;
+};
+
+/*
+ * Type to pass object data in a uniform way, without exposing the object
+ * structure.
+ *
+ * An array of these is always terminated by key == NULL
+ */
+struct ossl_param_st {
+    const char *key;             /* the name of the parameter */
+    unsigned int data_type;      /* declare what kind of content is in buffer */
+    void *buffer;                /* value being passed in or out */
+    size_t buffer_size;          /* buffer size */
+    size_t *return_size;         /* OPTIONAL: address to content size */
+};
+
+/* Currently supported OSSL_PARAM data types */
+/*
+ * OSSL_PARAM_INTEGER and OSSL_PARAM_UNSIGNED_INTEGER
+ * are arbitrary length and therefore require an arbitrarily sized buffer,
+ * since they may be used to pass numbers larger than what is natively
+ * available.
+ *
+ * The number must be buffered in native form, i.e. MSB first on B_ENDIAN
+ * systems and LSB first on L_ENDIAN systems.  This means that arbitrary
+ * native integers can be stored in the buffer, just make sure that the
+ * buffer size is correct and the buffer itself is properly aligned (for
+ * example by having the buffer field point at a C integer).
+ */
+# define OSSL_PARAM_INTEGER              1
+# define OSSL_PARAM_UNSIGNED_INTEGER     2
+/*-
+ * OSSL_PARAM_REAL
+ * is a C binary floating point values in native form and alignment.
+ */
+# define OSSL_PARAM_REAL                 3
+/*-
+ * OSSL_PARAM_UTF8_STRING
+ * is a printable string.  Is expteced to be printed as it is.
+ */
+# define OSSL_PARAM_UTF8_STRING          4
+/*-
+ * OSSL_PARAM_OCTET_STRING
+ * is a string of bytes with no further specification.  Is expected to be
+ * printed as a hexdump.
+ */
+# define OSSL_PARAM_OCTET_STRING         5
+
+/*-
+ * Pointer flag
+ *
+ * This flag can be added to any type to signify that the buffer
+ * pointer is set to point at a pointer to the data instead of
+ * pointing directly at the data.
+ *
+ * This is more relevant for parameter requests, where the responding
+ * function doesn't need to copy the data to the provided buffer, but
+ * sets the provided buffer to point at the actual data instead.
+ *
+ * WARNING!  Using these is FRAGILE, as it assumes that the actual
+ * data and its location are constant.
+ */
+# define OSSL_PARAM_POINTER_FLAG    0x80000000UL
+
+/*
+ * Convenience pointer types for strings.
+ */
+# define OSSL_PARAM_UTF8_STRING_PTR                     \
+    (OSSL_PARAM_UTF8_STRING|OSSL_PARAM_POINTER_FLAG)
+# define OSSL_PARAM_OCTET_STRING_PTR                    \
+    (OSSL_PARAM_OCTET_STRING|OSSL_PARAM_POINTER_FLAG)
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
index 44ddfaa..9b97e3d 100644 (file)
@@ -181,6 +181,11 @@ typedef struct ossl_store_search_st OSSL_STORE_SEARCH;
 
 typedef struct openssl_ctx_st OPENSSL_CTX;
 
+typedef struct ossl_dispatch_st OSSL_DISPATCH;
+typedef struct ossl_item_st OSSL_ITEM;
+typedef struct ossl_algorithm_st OSSL_ALGORITHM;
+typedef struct ossl_param_st OSSL_PARAM;
+
 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
     defined(INTMAX_MAX) && defined(UINTMAX_MAX)
 typedef intmax_t ossl_intmax_t;
index c4a2793..d8aba4d 100644 (file)
@@ -32,6 +32,7 @@ GEN_SESSION_CB                          datatype
 OPENSSL_Applink                         external
 OPENSSL_CTX                             datatype
 NAMING_AUTHORITY                        datatype
+OSSL_PARAM                              datatype
 OSSL_STORE_CTX                          datatype
 OSSL_STORE_INFO                         datatype
 OSSL_STORE_LOADER                       datatype