On Fri, Mar 20, 2009 at 3:42 PM, David Schwartz <dav...@webmaster.com> wrote:
>> > be aware that SSL BIO's (and (SSL*) sessions!) are 'threadsafe'
>> > in the sense that OpenSSL *assumes* a (SSL *) or
>> > /any/ BIO remains inside a single thread from the moment it
>> > becomes 'active', i.e. is set up / is going to do some work.
>
> This is completely incorrect. It's totaly nonsense.

Hnn. Yes, this was an utterly stupid thing to say, where I should have
said this:

> [...] OpenSSL is completely thread safe so long as two
> threads do not try to directly manipulate the same object at the same time.
>
> DS

(with emphasis on the 'at the same time'), hence, as David continues:

> This is 100% perfectly fine. You must provide your own locks to synchronize
> access to the SSL session object, unlike a TCP connection where the kernel
> provides them.

Mea culpa for the confusion this caused over the weekend.


(And risking continuing my stupidity, I'd note with that 'locks around
SSL session object', it's not just the SSL session object, it also
includes all the BIOs used by such an SSL session object. Indeed, the
comment in ssltest.c is a hint (but again, imprecise, as it lacks
those words 'at the same time').

When you draw a picture of the whole thing to view all the interfaces
to other components from the perspective of an SSL* session object,
there's:
1- heap management (CRYPTO_malloc/free/...)
2- EVP for crypto/hashes/etc.
3- BIOs for 'backend' I/O (socket I/O, ...: the I/O transferring all
the encrypted data, i.e the data which is meant to travel on insecure
lines)
4- SSLread/SSLwrite/..: the 'front end' I/O, i.e. the 'plaintext data'
as it will be transferred from/to your application layer(s).
5- support code in ssl/* and crypto/* (safestack, lhash-based session
pool, SSL_CTX reference, ...)

In a scenario where a single SSL object can be accessed by multiple
threads, the question is: is it safe?
Well, inspecting those interconnections, one by one, here's the result:
1- fully thread safe for any definition of those words (CRYPTO_malloc
et al use locks to create 'critical sections' in the code flow as
needed)
2- only uses locks where 'global state' items, such as the engines, is
concerned. That's fine as it's an internal-to-internal (or whatever
the correct English wording is here) interface, i.e. you do not
'enter' or 'exit' the SSL instance through any of these: they get
called, they do some work, and return, without any outside
'influence', apart from those chunks which are already critical
sectioned through locking (CRYPTO_r/w_lock() et al)
3- do not use locks (apart from the BIO reference counting). This
means you can pass a BIO between threads, but must provide your own
locking around read/write/etc. BIO state altering operations when you
wish to _access_ the BIO from multiple threads. (This was what I
wanted to mention originally: when you share an SSL instance among
threads, you _implicitly_ share all the SSL_set_BIO(...)-BIOs attached
to that SSL instance among those threads as well: that means the 'area
to protect' through critical section is larger than just those SSL_*()
API calls. This is also what is pointed at by the ssltest.c comment
about the BIO pair.
4- no locking, same caveat as the BIOs "is completely thread safe so
long as two threads do not try to directly manipulate the same object
at the same time". SSL code _does_ use locking, but does so for #5:
5- full locking, so fully threadsafe in this regard: multiple SSL
and/or SSL_CTX instances can be used simultaneously in multiple
threads and do their stuff, e.g. accessing SSL session cache (one of
the SSL 'global states' which require such locking-based thread
protection). This, of course, assumes one SSL instance is used by one
thread at a time only, or it's #4.


This all boils down to (and pardon possibly shoddy wording in the
above items; for the full nitpick, review the source code) this as
#3+#4 are the multithread risks (semi-quoting Davis Schwartz again) :


[SSL, SSL_CTX and BIO use] is completely thread safe so long as two
threads do not try to directly manipulate the same object at the same
time.

Added notes here:
a) using an SSL object also means using it's attached BIO instance(s)
(API: SSL_set_bio(one or two BIOs,,,)) so the code area to cordon off
using locks (the critical section) _includes_ those BIOs: it's not
enough to put a lock around SSLread/write, you also need that lock
around that BIO pair at the backend (or the two BIO_s_mem() buffered
BIOs...)
b) using an SSL object also means you are _possibly_ (read)-accessing
it's related SSL_CTX (fetching callbacks, config parameters, that sort
of thing) so you should not edit/change the SSL_CTX while having live
SSL sessions which were derived from it (unless 'you know what you are
doing')

Here, the important bit is note (a).


That's the story. (In my book, SSL/BIOs are 'thread aware', not
'thread safe' as is CRYPTO_malloc et al, but me lacking to provide a
very strict an unambiguous definition of those two phrases, they - and
their alleged differences - are completely useless. I hope this longer
text has no mistakes lurking in it and explains sufficiently what is
important.)



Prodding at festering spots in the text is appreciated.


-- 
Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web:    http://www.hobbelt.com/
        http://www.hebbut.net/
mail:   g...@hobbelt.com
mobile: +31-6-11 120 978
--------------------------------------------------
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to