375 lines
12 KiB
Plaintext
375 lines
12 KiB
Plaintext
=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 data */
|
|
void *data; /* value being passed in or out */
|
|
size_t data_size; /* data size */
|
|
size_t return_size; /* returned size */
|
|
};
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
B<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 the following purposes:
|
|
|
|
=over 4
|
|
|
|
=item * Setting parameters for some object
|
|
|
|
The caller sets up the B<OSSL_PARAM> array and calls some function
|
|
(the I<setter>) that has intimate knowledge about the object that can
|
|
take the data from the B<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<requester>) sets up the B<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 memory prepared by the
|
|
I<requester> and pointed at with the B<OSSL_PARAM> I<data>.
|
|
|
|
=item * Request parameter descriptors
|
|
|
|
The caller gets an array of constant B<OSSL_PARAM>, which describe
|
|
available parameters and some of their properties; name, data type and
|
|
expected data size.
|
|
For a detailed description of each field for this use, see the field
|
|
descriptions below.
|
|
|
|
The caller may then use the information from this descriptor array to
|
|
build up its own B<OSSL_PARAM> array to pass down to a I<setter> or
|
|
I<responder>.
|
|
|
|
=back
|
|
|
|
Normally, the order of the an B<OSSL_PARAM> array is not relevant.
|
|
However, if the I<responder> can handle multiple elements with the
|
|
same key, those elements must be handled in the order they are in.
|
|
|
|
An B<OSSL_PARAM> array must have a terminating element, where I<key>
|
|
is NULL. The usual full terminating template is:
|
|
|
|
{ NULL, 0, NULL, 0, 0 }
|
|
|
|
This can also be specified using L<OSSL_PARAM_END(3)>.
|
|
|
|
=head2 Functional support
|
|
|
|
Libcrypto offers a limited set of helper functions to handle
|
|
B<OSSL_PARAM> items and arrays, please see L<OSSL_PARAM_get_int(3)>.
|
|
Developers are free to extend or replace those as they see fit.
|
|
|
|
=head2 B<OSSL_PARAM> fields
|
|
|
|
=over 4
|
|
|
|
=item I<key>
|
|
|
|
The identity of the parameter in the form of a string.
|
|
|
|
In an B<OSSL_PARAM> array, an item with this field set to NULL is
|
|
considered a terminating item.
|
|
|
|
=item I<data_type>
|
|
|
|
The I<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 I<data>
|
|
|
|
=item I<data_size>
|
|
|
|
I<data> is a pointer to the memory where the parameter data is (when
|
|
setting parameters) or shall (when requesting parameters) be stored,
|
|
and I<data_size> is its size in bytes.
|
|
The organization of the data depends on the parameter type and flag.
|
|
|
|
The I<data_size> needs special attention with the parameter type
|
|
B<OSSL_PARAM_UTF8_STRING> in relation to C strings. When setting
|
|
parameters, the size should be set to the length of the string, not
|
|
counting the terminating NUL byte. When requesting parameters, the
|
|
size should be set to the size of the buffer to be populated, which
|
|
should accommodate enough space for a terminating NUL byte.
|
|
|
|
When I<requesting parameters>, it's acceptable for I<data> to be NULL.
|
|
This can be used by the I<requester> to figure out dynamically exactly
|
|
how much buffer space is needed to store the parameter data.
|
|
In this case, I<data_size> is ignored.
|
|
|
|
When the B<OSSL_PARAM> is used as a parameter descriptor, I<data>
|
|
should be ignored.
|
|
If I<data_size> is zero, it means that an arbitrary data size is
|
|
accepted, otherwise it specifies the maximum size allowed.
|
|
|
|
=item I<return_size>
|
|
|
|
When an array of B<OSSL_PARAM> is used to request data, the
|
|
I<responder> must set this field to indicate size of the parameter
|
|
data, including padding as the case may be.
|
|
In case the I<data_size> is an unsuitable size for the data, the
|
|
I<responder> must still set this field to indicate the minimum data
|
|
size required.
|
|
(further notes on this in L</NOTES> below).
|
|
|
|
When the B<OSSL_PARAM> is used as a parameter descriptor,
|
|
I<return_size> should be ignored.
|
|
|
|
=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 B<OSSL_PARAM> array
|
|
along.
|
|
|
|
=head2 Supported types
|
|
|
|
The I<data_type> field can be one of the following types:
|
|
|
|
=over 4
|
|
|
|
=item B<OSSL_PARAM_INTEGER>
|
|
|
|
=item B<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 B<OSSL_PARAM_REAL>
|
|
|
|
The parameter data is a floating point value in native form.
|
|
|
|
=item B<OSSL_PARAM_UTF8_STRING>
|
|
|
|
The parameter data is a printable string.
|
|
|
|
=item B<OSSL_PARAM_OCTET_STRING>
|
|
|
|
The parameter data is an arbitrary string of bytes.
|
|
|
|
=item B<OSSL_PARAM_UTF8_PTR>
|
|
|
|
The parameter data is a pointer to a printable string.
|
|
|
|
The difference between this and B<OSSL_PARAM_UTF8_STRING> is that I<data>
|
|
doesn't point directly at the data, but to a pointer that points to the data.
|
|
|
|
If there is any uncertainty about which to use, B<OSSL_PARAM_UTF8_STRING> is
|
|
almost certainly the correct choice.
|
|
|
|
This is 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.
|
|
|
|
I<data_size> must be set to the size of the data, not the size of the
|
|
pointer to the data.
|
|
If this is used in a parameter request,
|
|
I<data_size> is not relevant. However, the I<responder> will set
|
|
I<return_size> to the size of the data.
|
|
|
|
Note that the use of this type 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).
|
|
|
|
=item B<OSSL_PARAM_OCTET_PTR>
|
|
|
|
The parameter data is a pointer to an arbitrary string of bytes.
|
|
|
|
The difference between this and B<OSSL_PARAM_OCTET_STRING> is that
|
|
I<data> doesn't point directly at the data, but to a pointer that
|
|
points to the data.
|
|
|
|
If there is any uncertainty about which to use, B<OSSL_PARAM_OCTET_STRING> is
|
|
almost certainly the correct choice.
|
|
|
|
This is 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.
|
|
|
|
I<data_size> must be set to the size of the data, not the size of the
|
|
pointer to the data.
|
|
If this is used in a parameter request,
|
|
I<data_size> is not relevant. However, the I<responder> will set
|
|
I<return_size> to the size of the data.
|
|
|
|
Note that the use of this type 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
|
|
|
|
=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 *
|
|
|
|
Apart from the I<return_size>, a I<responder> must never change the fields
|
|
of an B<OSSL_PARAM>.
|
|
To return a value, it should change the contents of the memory that
|
|
I<data> points 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
|
|
B<OSSL_PARAM_UNSIGNED_INTEGER>, is plausible to pass the value as an
|
|
B<OSSL_PARAM_OCTET_STRING>), but this is in no way mandatory.
|
|
|
|
=item *
|
|
|
|
If I<data> for a B<OSSL_PARAM_OCTET_STRING> or a
|
|
B<OSSL_PARAM_UTF8_STRING> is NULL, the I<responder> should
|
|
set I<return_size> to the size of the item to be returned
|
|
and return success. Later the responder will be called again
|
|
with I<data> pointing at the place for the value to be put.
|
|
|
|
=item *
|
|
|
|
If a I<responder> finds that some data sizes are too small for the
|
|
requested data, it must set I<return_size> for each such
|
|
B<OSSL_PARAM> item to the minimum required size, and eventually return
|
|
an error.
|
|
|
|
=item *
|
|
|
|
For the integer type parameters (B<OSSL_PARAM_UNSIGNED_INTEGER> and
|
|
B<OSSL_PARAM_INTEGER>), a I<responder> may choose to return an error
|
|
if the I<data_size> isn't a suitable size (even if I<data_size> is
|
|
bigger than needed). If the I<responder> finds the size suitable, it
|
|
must fill all I<data_size> bytes and ensure correct padding for the
|
|
native endianness, and set I<return_size> to the same value as
|
|
I<data_size>.
|
|
|
|
=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 B<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);
|
|
const char bar[] = "some other string";
|
|
OSSL_PARAM set[] = {
|
|
{ "foo", OSSL_PARAM_UTF8_PTR, &foo, foo_l, 0 },
|
|
{ "bar", OSSL_PARAM_UTF8_STRING, (void *)&bar, sizeof(bar) - 1, 0 },
|
|
{ NULL, 0, NULL, 0, 0 }
|
|
};
|
|
|
|
=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;
|
|
OSSL_PARAM request[] = {
|
|
{ "foo", OSSL_PARAM_UTF8_PTR, &foo, 0 /*irrelevant*/, 0 },
|
|
{ "bar", OSSL_PARAM_UTF8_STRING, &bar, sizeof(bar), 0 },
|
|
{ NULL, 0, NULL, 0, 0 }
|
|
};
|
|
|
|
A I<responder> that receives this array (as I<params> in this example)
|
|
could fill in the parameters like this:
|
|
|
|
/* OSSL_PARAM *params */
|
|
|
|
int i;
|
|
|
|
for (i = 0; params[i].key != NULL; i++) {
|
|
if (strcmp(params[i].key, "foo") == 0) {
|
|
*(char **)params[i].data = "foo value";
|
|
params[i].return_size = 9; /* length of "foo value" string */
|
|
} else if (strcmp(params[i].key, "bar") == 0) {
|
|
memcpy(params[i].data, "bar value", 10);
|
|
params[i].return_size = 9; /* length of "bar value" string */
|
|
}
|
|
/* Ignore stuff we don't know */
|
|
}
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<openssl-core.h(7)>, L<OSSL_PARAM_get_int(3)>, L<OSSL_PARAM_dup(3)>
|
|
|
|
=head1 HISTORY
|
|
|
|
B<OSSL_PARAM> was added in OpenSSL 3.0.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2019-2023 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
|