---
name: "libressl-RSA_get_ex_new_index"
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-RSA_get_ex_new_index"
---

# libressl-RSA\_get\_ex\_new\_index(3)

add application specific data to RSA objects

## NAME

**RSA\_get\_ex\_new\_index**, **RSA\_set\_ex\_data**, **RSA\_get\_ex\_data** – add application specific data to RSA objects

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#include \<openssl/rsa.h\>**

*int*\

**RSA\_get\_ex\_new\_index**(*long argl*, *void \*argp*, *CRYPTO\_EX\_new \*new\_func*, *CRYPTO\_EX\_dup \*dup\_func*, *CRYPTO\_EX\_free \*free\_func*);

*int*\

**RSA\_set\_ex\_data**(*RSA \*rsa*, *int idx*, *void \*data*);

*void* *\**\

**RSA\_get\_ex\_data**(*RSA \*rsa*, *int idx*);

## DESCRIPTION

The following parent objects can have application specific data called “ex\_data” attached to them: *BIO*, *DH*, *DSA*, *EC\_KEY*, *RSA*, *SSL*, *SSL\_CTX*, *SSL\_SESSION*, *UI*, *X509*, *X509\_STORE*, and *X509\_STORE\_CTX*. The present manual page documents the related API functions taking the *RSA* object type as an example. The functions for the other object types work in exactly the same way: just replace the string "RSA" with the name of the respective object type throughout the rest of this manual page.

By default, each individual *RSA* object can store one *void* *\** pointing to application specific data. That specific pointer is identified by an *idx* argument of 0.

**RSA\_get\_ex\_new\_index**() reserves the next consecutive *idx* argument, enabling storage of one additional *void* *\** per *RSA* object. It is typically called at program startup. It can be called more than once if some *RSA* objects need to store more than two application specific pointers. Reserving an additional index for one parent object type, for example for *RSA*, does not change the numbers of indices that can be used with any other parent object type.

It is strongly recommended to always pass three NULL pointers for the arguments *new\_func*, *dup\_func*, and *free\_func*. When following this recommendation, the arguments *argl* and *argp* are ignored; conventionally, passing 0 and NULL is recommended. Because using them is discouraged, the three function callback types are only documented in the low-level CRYPTO\_EX\_new(3) manual page.

**RSA\_set\_ex\_data**() stores the *data* pointer as application specific data at the given *idx* in the given *rsa* object. The meaning of the data pointed to is up to the application. The caller retains ownership of the *data* and is responsible for freeing it when neither the caller nor the *rsa* object need it any longer. Any other pointer that was previously stored at the same *idx* in the same *rsa* object is silently overwritten. Passing a NULL pointer for the *data* argument is valid and indicates that no application specific data currently needs to be stored at the given *idx*.

**RSA\_get\_ex\_data**() retrieves the last pointer that was stored using **RSA\_set\_ex\_data**() at the given *idx* in the given *rsa* object.

## RETURN VALUES

**RSA\_get\_ex\_new\_index**() returns a new index equal to or greater than 1 or -1 if memory allocation fails.

**RSA\_set\_ex\_data**() returns 1 on success or 0 if memory allocation fails.

**RSA\_get\_ex\_data**() returns the application specific data or NULL if *rsa* does not contain application specific data at the given *idx*.

## ERRORS

After failure of **RSA\_get\_ex\_new\_index**() or **RSA\_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.

**RSA\_get\_ex\_data**() does not distinguish success from failure. Consequently, after **RSA\_get\_ex\_data**() returns NULL, ERR\_get\_error(3) returns 0 unless there is still an earlier error in the queue.

## SEE ALSO

BIO\_set\_ex\_data(3), CRYPTO\_set\_ex\_data(3), DH\_set\_ex\_data(3), DSA\_set\_ex\_data(3), RSA\_new(3), SSL\_CTX\_set\_ex\_data(3), SSL\_SESSION\_set\_ex\_data(3), SSL\_set\_ex\_data(3), X509\_STORE\_CTX\_set\_ex\_data(3), X509\_STORE\_set\_ex\_data(3)

## HISTORY

These functions first appeared in SSLeay 0.9.0 and have been available since OpenBSD 2.4.

## CAVEATS

A relatively small minority of application programs attempt to change the API contract such that **RSA\_set\_ex\_data**() transfers ownership of the *data* to the *rsa* object. They do this by providing a *free\_func* that calls [free(3)](/free/3.md) or higher-level **\*\_free**() functions on the *data* and sometimes also attempt additional cleanup work as a side effect.

This practice is discouraged for several reasons:

1. Due to a massive design mistake in the low-level API function CRYPTO\_free\_ex\_data(3), this practice creates a possibility that RSA\_free(3) may fail due to memory allocation failure, consequently leaking the memory containing the application specific data and silently skipping any additional cleanup work the *free\_func* was supposed to do, leaving the application in an undetectably inconsistent state. Arguably, leaking additional memory while trying to free some is most unfortunate especially when the program is already starved for memory.

2. This practice introduces a risk of use-after-free and double-free bugs in case the *rsa* object gets destructed while a caller of **RSA\_set\_ex\_data**() or **RSA\_get\_ex\_data**() still holds a *data* pointer. No such risk exists when no *free\_func* is installed.

3. Attempting additional cleanup work in *free\_func* is an even worse idea because *free\_func* is unable to report any issues it might detect while doing that work. Instead, if any additional cleanup work is needed, it is recommended that the calling code takes care of that before calling RSA\_free(3).

Even fewer application programs install a *new\_func* that allocates memory and stores a pointer to it in the *rsa* object by calling CRYPTO\_set\_ex\_data(3). That is useless because *new\_func* does not have access to any useful information it could store in such memory and because the default return value of NULL from **RSA\_get\_ex\_data**() is sufficient to indicate that no application specific data has been stored yet. In addition, allocating memory in *new\_func* is also inadvisable because it introduces an additional responsibility for callers of **RSA\_set\_ex\_data**() to always call **RSA\_get\_ex\_data**() first, even when it is the first time the application wants to set application specific data in a particular *rsa* object, and to either modify whatever **RSA\_get\_ex\_data**() returns or to free it before calling **RSA\_set\_ex\_data**(). If that is forgotten, a memory leak results.

Consequently, allocating any required memory is better left to the application code that calls **RSA\_set\_ex\_data**().

Installing a *dup\_func* is often seen in combination with installing a *free\_func*, for obvious reasons. It is rarely useful because for most parent object types that support ex\_data, including for *RSA*, the library does not provide a copying API function in the first place, and even where copying functions exist, they tend to be fragile and error-prone. When a new object is needed, it is usually advisable to construct it from scratch whenever possible, rather than attempting a copy operation.

On top of that, if *dup\_func* fails, for example because of a memory allocation failure, the failure is neither reported nor detectable in any way, leaving the new parent object with incomplete data and potentially in an inconsistent state.

## BUGS

If **RSA\_set\_ex\_data**() fails, recovery is very difficult. In particular, calling RSA\_free(3) on the parent *rsa* object right afterwards is likely to also hit a memory allocation failure, leaking all memory internally allocated by all earlier calls of **RSA\_set\_ex\_data**() on *rsa* rather than freeing that memory. In order to recover, the application program would have to free a sufficient amount of *other* memory before calling RSA\_free(3), which will rarely be feasible. Consequently, after a failure of **RSA\_set\_ex\_data**(), terminating the program is likely the only reasonable option.

If **RSA\_set\_ex\_data**() is called with an *idx* argument greater than the last one previously returned from **RSA\_get\_ex\_new\_index**(), it may still succeed, and though that is not guaranteed by the API, retrieving the *data* from such a bogus *idx* may even be possible with **RSA\_get\_ex\_data**(), hiding the bug in the application program that caused passing the bogus *idx* to **RSA\_set\_ex\_data**() in the first place.

If the bogus *idx* argument is large, **RSA\_set\_ex\_data**() may uselessly allocate a large amount of memory. Calling RSA\_free(3) on the parent *rsa* object is the only way to recover that memory.

If the bogus *idx* argument is very large, **RSA\_set\_ex\_data**() is likely to cause a significant delay before eventually failing due to memory exhaustion. It is likely to return without releasing the memory already allocated, causing any subsequent attempt to allocate memory for other purposes to fail, too. In this situation, what was said above about failure of **RSA\_set\_ex\_data**() applies, so terminating the program is likely the only reasonable option.
