diff options
author | Richard Levitte <levitte@openssl.org> | 2019-01-20 13:23:30 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2019-02-27 18:36:30 +0100 |
commit | 7753be74a3c90e21d0d29d6131d9e751476f81ec (patch) | |
tree | 16da786941cb215fd154770474f6b1bb56137727 | |
parent | 8d76481b189b7195ef932e0fb8f0e23ab0120771 (diff) |
Replumbing: Add include/openssl/core.h, initially with core types
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8286)
-rw-r--r-- | doc/man3/OSSL_PARAM.pod | 302 | ||||
-rw-r--r-- | doc/man7/openssl-core.h.pod | 96 | ||||
-rw-r--r-- | include/openssl/core.h | 143 | ||||
-rw-r--r-- | include/openssl/ossl_typ.h | 5 | ||||
-rw-r--r-- | util/private.num | 1 |
5 files changed, 547 insertions, 0 deletions
diff --git a/doc/man3/OSSL_PARAM.pod b/doc/man3/OSSL_PARAM.pod new file mode 100644 index 0000000000..9d4748637c --- /dev/null +++ b/doc/man3/OSSL_PARAM.pod @@ -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 index 0000000000..7fd4dfb24e --- /dev/null +++ b/doc/man7/openssl-core.h.pod @@ -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 index 0000000000..98b58bea69 --- /dev/null +++ b/include/openssl/core.h @@ -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 diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h index 44ddfaafd5..9b97e3d3ab 100644 --- a/include/openssl/ossl_typ.h +++ b/include/openssl/ossl_typ.h @@ -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; diff --git a/util/private.num b/util/private.num index c4a2793410..d8aba4d308 100644 --- a/util/private.num +++ b/util/private.num @@ -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 |