1.\" $OpenBSD: RSA_get_ex_new_index.3,v 1.13 2023/11/19 21:08:04 tb Exp $ 2.\" 3.\" Copyright (c) 2023 Ingo Schwarze <schwarze@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: November 19 2023 $ 18.Dt RSA_GET_EX_NEW_INDEX 3 19.Os 20.Sh NAME 21.Nm RSA_get_ex_new_index , 22.Nm RSA_set_ex_data , 23.Nm RSA_get_ex_data 24.Nd add application specific data to RSA objects 25.Sh SYNOPSIS 26.In openssl/rsa.h 27.Ft int 28.Fo RSA_get_ex_new_index 29.Fa "long argl" 30.Fa "void *argp" 31.Fa "CRYPTO_EX_new *new_func" 32.Fa "CRYPTO_EX_dup *dup_func" 33.Fa "CRYPTO_EX_free *free_func" 34.Fc 35.Ft int 36.Fo RSA_set_ex_data 37.Fa "RSA *rsa" 38.Fa "int idx" 39.Fa "void *data" 40.Fc 41.Ft void * 42.Fo RSA_get_ex_data 43.Fa "RSA *rsa" 44.Fa "int idx" 45.Fc 46.Sh DESCRIPTION 47The following parent objects can have application specific data called 48.Dq ex_data 49attached to them: 50.Vt BIO , DH , DSA , EC_KEY , RSA , 51.Vt SSL , SSL_CTX , SSL_SESSION , UI , X509 , X509_STORE , 52and 53.Vt X509_STORE_CTX . 54.\" CRYPTO_EX_INDEX_APP and CRYPTO_EX_INDEX_UI_METHOD are unused. 55The present manual page documents the related API functions taking the 56.Vt RSA 57object type as an example. 58The functions for the other object types work in exactly the same way: 59just replace the string 60.Qq RSA 61with the name of the respective object type 62throughout the rest of this manual page. 63.Pp 64By default, each individual 65.Vt RSA 66object can store one 67.Vt void * 68pointing to application specific data. 69That specific pointer is identified by an 70.Fa idx 71argument of 0. 72.Pp 73.Fn RSA_get_ex_new_index 74reserves the next consecutive 75.Fa idx 76argument, enabling storage of one additional 77.Vt void * 78per 79.Vt RSA 80object. 81It is typically called at program startup. 82It can be called more than once if some 83.Vt RSA 84objects need to store more than two application specific pointers. 85Reserving an additional index for one parent object type, for example for 86.Vt RSA , 87does not change the numbers of indices that can be used 88with any other parent object type. 89.Pp 90It is strongly recommended to always pass three 91.Dv NULL 92pointers for the arguments 93.Fa new_func , 94.Fa dup_func , 95and 96.Fa free_func . 97When following this recommendation, the arguments 98.Fa argl 99and 100.Fa argp 101are ignored; conventionally, passing 0 and 102.Dv NULL 103is recommended. 104Because using them is discouraged, the three function callback types 105are only documented in the low-level 106.Xr CRYPTO_EX_new 3 107manual page. 108.Pp 109.Fn RSA_set_ex_data 110stores the 111.Fa data 112pointer as application specific data at the given 113.Fa idx 114in the given 115.Fa rsa 116object. 117The meaning of the data pointed to is up to the application. 118The caller retains ownership of the 119.Fa data 120and is responsible for freeing it when neither the caller nor the 121.Fa rsa 122object need it any longer. 123Any other pointer that was previously stored at the same 124.Fa idx 125in the same 126.Fa rsa 127object is silently overwritten. 128Passing a 129.Dv NULL 130pointer for the 131.Fa data 132argument is valid and indicates that no application specific data 133currently needs to be stored at the given 134.Fa idx . 135.Pp 136.Fn RSA_get_ex_data 137retrieves the last pointer that was stored using 138.Fn RSA_set_ex_data 139at the given 140.Fa idx 141in the given 142.Fa rsa 143object. 144.Sh RETURN VALUES 145.Fn RSA_get_ex_new_index 146returns a new index equal to or greater than 1 147or \-1 if memory allocation fails. 148.Pp 149.Fn RSA_set_ex_data 150returns 1 on success or 0 if memory allocation fails. 151.Pp 152.Fn RSA_get_ex_data 153returns the application specific data or 154.Dv NULL 155if 156.Fa rsa 157does not contain application specific data at the given 158.Fa idx . 159.Sh ERRORS 160After failure of 161.Fn RSA_get_ex_new_index 162or 163.Fn RSA_set_ex_data , 164the following diagnostic can be retrieved with 165.Xr ERR_get_error 3 , 166.Xr ERR_GET_REASON 3 , 167and 168.Xr ERR_reason_error_string 3 : 169.Bl -tag -width Ds 170.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" 171Memory allocation failed. 172.El 173.Pp 174In a few unusual failure cases, 175.Xr ERR_get_error 3 176may report different errors caused by 177.Xr OPENSSL_init_crypto 3 178or even none at all. 179.Pp 180.Fn RSA_get_ex_data 181does not distinguish success from failure. 182Consequently, after 183.Fn RSA_get_ex_data 184returns 185.Dv NULL , 186.Xr ERR_get_error 3 187returns 0 unless there is still an earlier error in the queue. 188.Sh SEE ALSO 189.Xr BIO_set_ex_data 3 , 190.Xr CRYPTO_set_ex_data 3 , 191.Xr DH_set_ex_data 3 , 192.Xr DSA_set_ex_data 3 , 193.Xr RSA_new 3 , 194.Xr SSL_CTX_set_ex_data 3 , 195.Xr SSL_SESSION_set_ex_data 3 , 196.Xr SSL_set_ex_data 3 , 197.Xr X509_STORE_CTX_set_ex_data 3 , 198.Xr X509_STORE_set_ex_data 3 199.Sh HISTORY 200These functions first appeared in SSLeay 0.9.0 201and have been available since 202.Ox 2.4 . 203.Sh CAVEATS 204A relatively small minority of application programs 205attempt to change the API contract such that 206.Fn RSA_set_ex_data 207transfers ownership of the 208.Fa data 209to the 210.Fa rsa 211object. 212They do this by providing a 213.Fa free_func 214that calls 215.Xr free 3 216or higher-level 217.Fn *_free 218functions on the 219.Fa data 220and sometimes also attempt additional cleanup work as a side effect. 221.Pp 222This practice is discouraged for several reasons: 223.Bl -enum 224.It 225Due to a massive design mistake in the low-level API function 226.Xr CRYPTO_free_ex_data 3 , 227this practice creates a possibility that 228.Xr RSA_free 3 229may fail due to memory allocation failure, consequently leaking the 230memory containing the application specific data and silently skipping 231any additional cleanup work the 232.Fa free_func 233was supposed to do, leaving the application in an undetectably 234inconsistent state. 235Arguably, leaking additional memory while trying to free some 236is most unfortunate especially when the program 237is already starved for memory. 238.It 239This practice introduces a risk of use-after-free and double-free 240bugs in case the 241.Fa rsa 242object gets destructed while a caller of 243.Fn RSA_set_ex_data 244or 245.Fn RSA_get_ex_data 246still holds a 247.Fa data 248pointer. 249No such risk exists when no 250.Fa free_func 251is installed. 252.It 253Attempting additional cleanup work in 254.Fa free_func 255is an even worse idea because 256.Fa free_func 257is unable to report any issues it might detect while doing that work. 258Instead, if any additional cleanup work is needed, it is recommended 259that the calling code takes care of that before calling 260.Xr RSA_free 3 . 261.El 262.Pp 263Even fewer application programs install a 264.Fa new_func 265that allocates memory and stores a pointer to it in the 266.Fa rsa 267object by calling 268.Xr CRYPTO_set_ex_data 3 . 269That is useless because 270.Fa new_func 271does not have access to any useful information it could store in such memory 272and because the default return value of 273.Dv NULL 274from 275.Fn RSA_get_ex_data 276is sufficient to indicate 277that no application specific data has been stored yet. 278In addition, allocating memory in 279.Fa new_func 280is also inadvisable because it introduces an additional responsibility 281for callers of 282.Fn RSA_set_ex_data 283to always call 284.Fn RSA_get_ex_data 285first, even when it is the first time the application wants to set 286application specific data in a particular 287.Fa rsa 288object, and to either modify whatever 289.Fn RSA_get_ex_data 290returns or to free it before calling 291.Fn RSA_set_ex_data . 292If that is forgotten, a memory leak results. 293.Pp 294Consequently, allocating any required memory 295is better left to the application code that calls 296.Fn RSA_set_ex_data . 297.Pp 298Installing a 299.Fa dup_func 300is often seen in combination with installing a 301.Fa free_func , 302for obvious reasons. 303It is rarely useful because for most parent object types 304that support ex_data, including for 305.Vt RSA , 306the library does not provide a copying API function in the first place, and 307even where copying functions exist, they tend to be fragile and error-prone. 308When a new object is needed, it is usually advisable to construct it from 309scratch whenever possible, rather than attempting a copy operation. 310.Pp 311On top of that, if 312.Fa dup_func 313fails, for example because of a memory allocation failure, the 314failure is neither reported nor detectable in any way, leaving the 315new parent object with incomplete data and potentially in an 316inconsistent state. 317.Sh BUGS 318If 319.Fn RSA_set_ex_data 320fails, recovery is very difficult. 321In particular, calling 322.Xr RSA_free 3 323on the parent 324.Fa rsa 325object right afterwards is likely to also hit a memory allocation 326failure, leaking all memory internally allocated by all earlier calls of 327.Fn RSA_set_ex_data 328on 329.Fa rsa 330rather than freeing that memory. 331In order to recover, the application program 332would have to free a sufficient amount of 333.Em other 334memory before calling 335.Xr RSA_free 3 , 336which will rarely be feasible. 337Consequently, after a failure of 338.Fn RSA_set_ex_data , 339terminating the program is likely the only reasonable option. 340.Pp 341If 342.Fn RSA_set_ex_data 343is called with an 344.Fa idx 345argument greater than the last one previously returned from 346.Fn RSA_get_ex_new_index , 347it may still succeed, and though that is not guaranteed by the API, 348retrieving the 349.Fa data 350from such a bogus 351.Fa idx 352may even be possible with 353.Fn RSA_get_ex_data , 354hiding the bug in the application program that caused passing the bogus 355.Fa idx 356to 357.Fn RSA_set_ex_data 358in the first place. 359.Pp 360If the bogus 361.Fa idx 362argument is large, 363.Fn RSA_set_ex_data 364may uselessly allocate a large amount of memory. 365Calling 366.Xr RSA_free 3 367on the parent 368.Fa rsa 369object is the only way to recover that memory. 370.Pp 371If the bogus 372.Fa idx 373argument is very large, 374.Fn RSA_set_ex_data 375is likely to cause a significant delay before eventually failing 376due to memory exhaustion. 377It is likely to return without releasing the memory already 378allocated, causing any subsequent attempt to allocate memory 379for other purposes to fail, too. 380In this situation, what was said above about failure of 381.Fn RSA_set_ex_data 382applies, so terminating the program is likely the only reasonable option. 383