OPENSSL-THREADS(7SSL)
β¨ openssl-threads β the vibe check on thread safety π
okay bestie, so this is the openssl-threads page from the OpenSSL manual, section 7 (that's the "misc" girlies), and it's literally the whole tea on what's safe to do with OpenSSL when more than one thread is running around doing its little thing. grab a snack, we're going in π
πΈ NAME πΈ
openssl-threads β the big-picture overview of thread safety in OpenSSL. no cap.
π DESCRIPTION π
First things first, let's define the word, because it's doing a LOT of work here. In this page, thread-safe means: an object or a function can be used by multiple threads at the exact same time. that's it, that's the definition, periodt.
OpenSSL can be built with or without threads support. The most important reason that support exists is so OpenSSL itself can use a single, consistent API β you can see that in the "EXAMPLES" section of CRYPTO_THREAD_run_once(3). Multi-platform applications can also use this API, which is highkey iconic of them.
But listen, and this is the part everyone skips: being configured for threads support does NOT mean every OpenSSL object is thread-safe. To emphasize (because it matters): most objects are not safe for simultaneous use. Any exceptions to that get documented on the specific manual pages, and some general high-level guidance lives right here. π
One major use of the OpenSSL thread API is to implement reference counting. So many objects inside OpenSSL are reference-counted, which means resources aren't released until the last reference is removed. References often get bumped automatically β like when an X509 certificate object gets added into an X509_STORE trust store. There's usually an object_up_ref() function you can call to increase the reference count. And the classic tragedy? Failing to match object_up_ref() calls with the right number of object_free() calls is a common source of memory leaks when a program exits. π we've all been there.
Now, the set/get girlies. Lots of objects have set and get APIs to set attributes on the object:
- A
"set0"passes ownership from the caller to the object. - A
"get0"returns a pointer, but the attribute ownership stays with the object, and a reference to it is returned. - A
"set1"or"get1"function does not change ownership. Instead it updates the attribute's reference count so the object is shared between the caller and the object β and the caller must free the returned attribute when they're done.
Functions that involve attributes which have reference counts themselves, but are named with just "set" or "get", are historical β and the documentation has to state how the references are handled. Get methods are often thread-safe, as long as the ownership requirements are met and shared objects aren't modified. Set methods, or modifying shared objects? Generally not thread-safe, as discussed below. π
Objects are thread-safe as long as the APIs you're invoking don't modify the object β in that case the parameter is usually marked in the API as "const". Not all parameters get marked this way, though. And heads up: a "const" declaration does not mean immutable. For example, X509_cmp(3) takes pointers to "const" objects, but the implementation uses a C cast to remove that so it can lock objects, generate and cache a DER encoding, and so on. sneaky but valid π
Another instance of thread-safety is when updates to an object's internal state β cached values, for instance β are done with locks. One example of that is the reference counting APIs described above. π
In all cases, however, it's generally not safe for one thread to mutate an object (like setting elements of a private or public key) while another thread is using that object (like verifying a signature). just don't do it babes.
The same APIs can usually be used simultaneously on different objects without any interference. For example, two threads can calculate a signature using two different EVP_PKEY_CTX objects. cooperation, not competition β¨
For implicit global state or singletons, thread-safety depends on the facility:
CRYPTO_secure_malloc(3)and the related APIs have their own lock.CRYPTO_malloc(3)assumes the underlying platform allocation will do any necessary locking.- Some APIs, such as
NCONF_load(3)and related, do no locking at all β this can be considered a bug. π
A separate (though related) issue: modifying "factory" objects when other objects have already been created from them. For example, an SSL_CTX object created by SSL_CTX_new(3) is used to create per-connection SSL objects by calling SSL_new(3). In this specific case β and probably for factory methods in general β it is not safe to modify the factory object after it's been used to create other objects. she's retired, leave her alone π
π¦ THREAD CANCELLATION π¦
Thread safety does not imply cancellation safety. Unless a specific function documents otherwise, OpenSSL does not guarantee that an in-progress call can be abandoned safely by thread cancellation or forced termination. An interruption can leave locks held, resources unreleased, or shared state inconsistent β which makes later use or cleanup unsafe. messy AND dangerous, we hate to see it.
Deferred cancellation can take effect at a cancellation point reached directly, or through a callback, BIO, provider, or other pluggable implementation. Automatic thread-local cleanup and OPENSSL_thread_stop(3), when they run, do not unwind the interrupted call. okay so it just... leaves it there. π
Applications should act on cancellation only between OpenSSL calls. On POSIX systems, applications using pthread cancellation should disable cancellation with pthread_setcancelstate() before entering OpenSSL, and restore it only after OpenSSL returns at a point that's safe for cancellation. Callbacks invoked by OpenSSL must not re-enable it. And ngl, disabling cancellation does not make a blocking call return on a cancellation request β if your app needs prompt cancellation, use nonblocking operation where available. plan accordingly bestie.
The same restriction applies to other non-local exits which abandon an OpenSSL call in progress β including direct thread exit, long jumps, and language exceptions. so like, don't.
π«Ά SEE ALSO π«Ά
CRYPTO_THREAD_run_once(3)OPENSSL_thread_stop(3)openssl-quic-concurrency(7)- local system threads documentation
π BUGS π
This page is admittedly very incomplete. yeah. she's a work in progress, we move. π
π COPYRIGHT π
Copyright 2021-2026 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 <https://www.openssl.org/source/license.html>.
and that's the whole page bestie!! π this was OpenSSL 4.0.3, dated 2026-09-29, filed under OPENSSL-THREADS(7SSL) β stay safe out there, don't share your objects between threads, and hydrate!! ππ
π¦ where this page comes from
- ubuntu stonking: openssl 4.0.3-1ubuntu1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms