Manual Page Result
0
Command: CRYPTO_set_ex_data | Section: 3 | Source: OpenBSD | File: CRYPTO_set_ex_data.3
CRYPTO_SET_EX_DATA(3) FreeBSD Library Functions Manual CRYPTO_SET_EX_DATA(3)
NAME
CRYPTO_get_ex_new_index, CRYPTO_EX_new, CRYPTO_EX_free, CRYPTO_EX_dup,
CRYPTO_new_ex_data, CRYPTO_set_ex_data, CRYPTO_get_ex_data,
CRYPTO_free_ex_data - low-level functions for application specific data
SYNOPSIS
#include <openssl/crypto.h>
int
CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
typedef int
CRYPTO_EX_new(void *parent, void *data, CRYPTO_EX_DATA *ad, int idx,
long argl, void *argp);
typedef void
CRYPTO_EX_free(void *parent, void *data, CRYPTO_EX_DATA *ad, int idx,
long argl, void *argp);
typedef int
CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
void *datap, int idx, long argl, void *argp);
int
CRYPTO_new_ex_data(int class_index, void *parent, CRYPTO_EX_DATA *ad);
int
CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *data);
void *
CRYPTO_get_ex_data(CRYPTO_EX_DATA *ad, int idx);
void
CRYPTO_free_ex_data(int class_index, void *parent, CRYPTO_EX_DATA *ad);
DESCRIPTION
The library implements the functions documented in the
RSA_get_ex_new_index(3) manual page and similar functions for other
parent object types using the functions documented in the present manual
page. Application programs almost never need to call the functions
documented here directly.
CRYPTO_get_ex_new_index() behaves in the same way as
RSA_get_ex_new_index(3) except that the parent object type that the new
idx is reserved for is not part of the function name but instead
specified by the additional class_index argument receiving one of the
CRYPTO_EX_INDEX_* constants defined in <openssl/crypto.h>. The
recommendation given in RSA_get_ex_new_index(3) to set the argl argument
to 0 and the last four arguments all to NULL applies. The library passes
the argl and argp arguments through to the callback functions for the
respective idx, but ignores them otherwise.
If a function pointer is passed for the new_func argument, that function
is called for the returned idx whenever a new parent object is allocated
with RSA_new(3) or a similar function.
If a function pointer is passed for the free_func argument, that function
is called for the returned idx when a parent object is freed with
RSA_free(3) or a similar function.
The arguments of new_func and free_func are as follows:
parent the parent object that contains the data
data the data previously set by CRYPTO_set_ex_data() at idx in parent
ad the CRYPTO_EX_DATA subobject of the parent object
idx return value of CRYPTO_get_ex_new_index() that set this callback
argl the argl passed to CRYPTO_get_ex_new_index() for this idx
argp the argp passed to CRYPTO_get_ex_new_index() for this idx
If a function pointer is passed for the dup_func, that function is
supposed to be called for the returned idx whenever a parent object of
the respective type is copied. Actually, the only functions doing that
are BIO_dup_chain(3), EC_KEY_copy(3), and SSL_dup(3), and the TLS 1.3
network stack does it internally when duplicating a SSL_SESSION object
after receiving a new session ticket message. Most other object types
supporting ex_data do not support copying in the first place, whereas
DSA_dup_DH(3) and X509_dup(3) simply ignore dup_func.
The arguments of dup_func are as follows:
to the CRYPTO_EX_DATA subobject of the new parent object
from the CRYPTO_EX_DATA subobject of the original parent object
datap a pointer to a copy of the pointer to the original ex_data
idx return value of CRYPTO_get_ex_new_index() that set this callback
argl the argl passed to CRYPTO_get_ex_new_index() for this idx
argp the argp passed to CRYPTO_get_ex_new_index() for this idx
Inside dup_func, the data pointer contained in the original parent object
being copied can be accessed by casting and dereferencing datap, for
example:
char *orig_data = *(char **)datap;
If the original data is copied, for example in a manner similar to
char *new_data;
if ((new_data = strdup(orig_data)) == NULL)
return 0;
then the pointer to the newly allocated memory needs to be passed back to
the caller in the datap argument, for example:
*(char **)datap = new_data;
return 1;
Calling CRYPTO_set_ex_data(to, idx, new_data) from inside dup_func has no
effect because the code calling dup_func unconditionally calls
CRYPTO_set_ex_data(to, idx, *datap) after dup_func returns successfully.
Consequently, if dup_func does not change *datap, the new parent object
ends up containing a pointer to the same memory as the original parent
object and any memory allocated in dup_func is leaked.
When multiple callback functions are called, they are called in
increasing order of their idx value.
CRYPTO_new_ex_data() is an internal function that initializes the ad
subobject of the parent object, with the type of the parent object
specified by the class_index argument. Initialization includes calling
the respective new_func callbacks for all reserved idx values that have
such callbacks configured. Despite its name, CRYPTO_new_ex_data() does
not create a new object but requires that ad points to an already
allocated but still uninitialized object.
CRYPTO_set_ex_data() and CRYPTO_get_ex_data() behave in the same way as
RSA_set_ex_data(3) and RSA_get_ex_data(3), respectively, except that they
do not accept a pointer to the parent object but instead require a
pointer to the CRYPTO_EX_DATA subobject of that parent object.
CRYPTO_free_ex_data() is an internal function that frees any memory used
inside the ad subobject of the parent object, with the type of the parent
object specified by the class_index argument. This includes calling the
respective free_func callbacks for all reserved idx values that have such
callbacks configured. Despite its name, CRYPTO_free_ex_data() does not
free ad itself.
RETURN VALUES
CRYPTO_get_ex_new_index() returns a new index equal to or greater than 1
or -1 if memory allocation fails.
CRYPTO_EX_new() and CRYPTO_EX_dup() functions are supposed to return 1 on
success or 0 on failure.
CRYPTO_new_ex_data() and CRYPTO_set_ex_data() return 1 on success or 0 if
memory allocation fails.
CRYPTO_get_ex_data() returns the application specific data or NULL if the
parent object that contains ad does not contain application specific data
at the given idx.
ERRORS
After failure of CRYPTO_get_ex_new_index(), CRYPTO_new_ex_data(), or
CRYPTO_set_ex_data(), the following diagnostic can be retrieved with
ERR_get_error(3), ERR_GET_REASON(3), and ERR_reason_error_string(3):
ERR_R_MALLOC_FAILURE "malloc failure"
Memory allocation failed.
In a few unusual failure cases, ERR_get_error(3) may report different
errors caused by OPENSSL_init_crypto(3) or even none at all.
Even though it cannot indicate failure, CRYPTO_free_ex_data() may
occasionally also set an error code that can be retrieved with
ERR_get_error(3).
CRYPTO_get_ex_data() does not distinguish success from failure.
Consequently, after CRYPTO_get_ex_data() returns NULL, ERR_get_error(3)
returns 0 unless there is still an earlier error in the queue.
SEE ALSO
BIO_get_ex_new_index(3), DH_get_ex_new_index(3), DSA_get_ex_new_index(3),
RSA_get_ex_new_index(3), SSL_CTX_get_ex_new_index(3),
SSL_get_ex_new_index(3), SSL_SESSION_get_ex_new_index(3),
X509_STORE_CTX_get_ex_new_index(3), X509_STORE_get_ex_new_index(3)
HISTORY
CRYPTO_get_ex_new_index(), CRYPTO_new_ex_data(), CRYPTO_set_ex_data(),
CRYPTO_get_ex_data(), and CRYPTO_free_ex_data() first appeared in SSLeay
0.9.0 and have been available since OpenBSD 2.4.
CRYPTO_EX_new(), CRYPTO_EX_free(), and CRYPTO_EX_dup() first appeared in
OpenSSL 0.9.5 and have been available since OpenBSD 2.7.
CAVEATS
If an program installs callback functions, the last call to
CRYPTO_get_ex_new_index() installing a function of a certain type for a
certain class_index needs to be complete before the first object of that
class_index can be created, freed, or copied, respectively. Otherwise,
incomplete initialization or cleanup will result.
At the time new_func is called, the parent object is only partially
initialized, so trying to access any data in it is strongly discouraged.
The data argument is typically NULL in new_func.
At the time free_func is called, the parent object is already mostly
deconstructed and part of its content may have been cleared and freed.
Consequently, trying to access any data in parent is strongly
discouraged. According to the OpenSSL API documentation, the library
code calling free_func would even be permitted to pass a NULL pointer for
the parent argument.
CRYPTO_set_ex_data() and CRYPTO_get_ex_data() cannot reasonably be used
outside the callback functions because no API function provides access to
any pointers of the type CRYPTO_EX_DATA *.
Inside new_func, calling CRYPTO_get_ex_data() makes no sense because it
always returns NULL, and calling CRYPTO_set_ex_data() makes no sense
because new_func does not have access to any meaningful data it could
store, and the absence of application specific data at any given idx is
already sufficiently indicated by the default return value NULL of
CRYPTO_get_ex_data(), RSA_get_ex_data(3), and similar functions.
Inside free_func, calling CRYPTO_get_ex_data() makes no sense because the
return value is already available in data, and calling
CRYPTO_set_ex_data() makes no sense because the parent object, including
any ex_data contained in it, is already being deconstructed and will no
longer exist by the time application code regains control.
Inside dup_func, calling CRYPTO_get_ex_data() makes no sense because the
return value for from is already available as *datap, and the return
value for to is NULL. Calling CRYPTO_set_ex_data() makes no sense
because changing from would cause an undesirable side effect in this
context and trying to change to is ineffective as explained above.
Consequently, application code can never use CRYPTO_set_ex_data() or
CRYPTO_get_ex_data() in a meaningful way.
The fact that the functions documented in the present manual page are
part of the public API might create the impression that application
programs could add ex_data support to additional object types not
offering it by default. However, for built-in object types not offering
ex_support, this is not possible because such objects do not contain the
required CRYPTO_EX_DATA subobject.
It is theoretically possible to add ex_data support to an application-
defined object type by adding a CRYPTO_EX_DATA field to the struct
declaration, a call to CRYPTO_new_ex_data() to the object constructor,
and a call to CRYPTO_free_ex_data() to the object destructor. The
OpenSSL documentation mentions that the constant CRYPTO_EX_INDEX_APP is
reserved for this very purpose. However, doing this would hardly be
useful. It is much more straightforward to just add all the required
data fields to the struct declaration itself.
BUGS
If new_func or dup_func fails, the failure is silently ignored by the
library, potentially resulting in an incompletely initialized object.
The application program cannot detect this kind of failure.
FreeBSD 14.1-RELEASE-p8 September 18, 2023 FreeBSD 14.1-RELEASE-p8