---
name: "libressl-CRYPTO_set_ex_data"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-CRYPTO_set_ex_data"
---

# libressl-CRYPTO\_set\_ex\_data(3)

low-level functions for application specific data

## 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**, **CRYPTO\_cleanup\_all\_ex\_data** – low-level functions for application specific data

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#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*);

*void*\

**CRYPTO\_cleanup\_all\_ex\_data**(*void*);

## 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.

**CRYPTO\_cleanup\_all\_ex\_data**() is deprecated and has no effect. It is retained for source and binary compatibility only. Application programs should not call it after individual operations, from individual library components, or during process shutdown. No replacement call is needed.

In particular, OPENSSL\_cleanup(3) is not a replacement for **CRYPTO\_cleanup\_all\_ex\_data**(). It tears down process-wide library state and is only intended for final shutdown after all threads using libcrypto have stopped.

## 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.

**CRYPTO\_cleanup\_all\_ex\_data**() first appeared in OpenSSL 0.9.7 and has been available since OpenBSD 3.2.

## CAVEATS

If a 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.
