The renegotiation callback was called only when the first Application
Data arrived, instead of when the renegotiation took place.
This happened because SSL_read() returns -1 and sets the error to
SSL_ERROR_WANT_READ when a renegotiation happens instead of reading
data [0].
I also added a commented out aggressive assert that I won't enable yet
because I don't feel I understand SSL_ERROR_WANT_READ enough.
[0]: Look at documentation of SSL_read(), SSL_get_error() and
SSL_CTX_set_mode() (SSL_MODE_AUTO_RETRY section).
Introduce tor_tls_state_changed_callback(), which handles every SSL
state change.
The new function tor_tls_got_server_hello() is called every time we
send a ServerHello during a v2 handshake, and plays the role of the
previous tor_tls_server_info_callback() function.
Right now we can take the digests only of an RSA key, and only expect to
take the digests of an RSA key. The old tor_cert_get_id_digests() would
return a good set of digests for an RSA key, and an all-zero one for a
non-RSA key. This behavior is too error-prone: it carries the risk that
we will someday check two non-RSA keys for equality and conclude that
they must be equal because they both have the same (zero) "digest".
Instead, let's have tor_cert_get_id_digests() return NULL for keys we
can't handle, and make its callers explicitly test for NULL.
Our keys and x.509 certs are proliferating here. Previously we had:
An ID cert (using the main ID key), self-signed
A link cert (using a shorter-term link key), signed by the ID key
Once proposal 176 and 179 are done, we will also have:
Optionally, a presentation cert (using the link key),
signed by whomever.
An authentication cert (using a shorter-term ID key), signed by
the ID key.
These new keys are managed as part of the tls context infrastructure,
since you want to rotate them under exactly the same circumstances,
and since they need X509 certificates.
Also remove a few other related warnings that could occur during the ssl
handshake. We do this because the relay operator can't do anything about
them, and they aren't their fault.
- We were reporting the _bottom_ N failing states, not the top N.
- With bufferevents enabled, we logged all TLS states as being "in
bufferevent", which isn't actually informative.
- When we had nothing to report, we reported nothing too loudly.
- Also, we needed documentation.
This code lets us record the state of any outgoing OR connection
that fails before it becomes open, so we can notice if they're all
dying in the same SSL state or the same OR handshake state.
More work is still needed:
- We need documentation
- We need to actually call the code that reports the failure when
we realize that we're having a hard time connecting out or
making circuits.
- We need to periodically clear out all this data -- perhaps,
whenever we build a circuit successfully?
- We'll eventually want to expose it to controllers, perhaps.
Partial implementation of feature 3116.
SSL_*_app_data uses ex_data index 0, which will be the first one allocated
by SSL_get_ex_new_index. Thus, if we ever started using the ex_data feature
for some other purpose, or a library linked to Tor ever started using
OpenSSL's ex_data feature, Tor would break in spectacular and mysterious
ways. Using the SSL_*_ex_data functions directly now may save us from
that particular form of breakage in the future.
But I would not be surprised if using OpenSSL's ex_data functions at all
(directly or not) comes back to bite us on our backends quite hard. The
specified behaviour of dup_func in the man page is stupid, and
crypto/ex_data.c is a horrific mess.
Our regular DH parameters that we use for circuit and rendezvous
crypto are unchanged. This is yet another small step on the path of
protocol fingerprinting resistance.
(Backport from 0.2.2's 5ed73e3807)
Our regular DH parameters that we use for circuit and rendezvous
crypto are unchanged. This is yet another small step on the path of
protocol fingerprinting resistance.
We need filtering bufferevent_openssl so that we can wrap around
IOCP bufferevents on Windows. This patch adds a temporary option to
turn on filtering mode, so that we can test it out on non-IOCP
systems to make sure it hasn't got any surprising bugs.
It also fixes some allocation/teardown errors in using
bufferevent_openssl as a filter.
First start of a fix for bug2001, but my test network still isn't
working: the client and the server send each other VERSIONS cells,
but never notice that they got them.
* Make tor_tls_context_new internal to tortls.c, and return the new
tor_tls_context_t from it.
* Add a public tor_tls_context_init wrapper function to replace it.
This requires the latest Git version of Libevent as of 24 March 2010.
In the future, we'll just say it requires Libevent 2.0.5-alpha or
later.
Since Libevent doesn't yet support hierarchical rate limit groups,
there isn't yet support for tracking relayed-bytes separately when
using the bufferevent system. If a future version does add support
for hierarchical buckets, we can add that back in.
This should make us conflict less with system files named "log.h".
Yes, we shouldn't have been conflicting with those anyway, but some
people's compilers act very oddly.
The actual change was done with one "git mv", by editing
Makefile.am, and running
find . -name '*.[ch]' | xargs perl -i -pe 'if (/^#include.*\Wlog.h/) {s/log.h/torlog.h/; }'
Our code assumed that any version of OpenSSL before 0.9.8l could not
possibly require SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION. This is
so... except that many vendors have backported the flag from later
versions of openssl when they backported the RFC5476 renegotiation
feature.
The new behavior is particularly annoying to detect. Previously,
leaving SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION unset meant that
clients would fail to renegotiate. People noticed that one fast!
Now, OpenSSL's RFC5476 support means that clients will happily talk to
any servers there are, but servers won't accept renegotiation requests
from unpatched clients unless SSL_OP_ALLOW_etc is set. More fun:
servers send back a "no renegotiation for you!" error, which unpatched
clients respond to by stalling, and generally producing no useful
error message.
This might not be _the_ cause of bug 1346, but it is quite likely _a_
cause for bug 1346.
This time, set the SSL3_FLAGS_ALLOW_UNSAFE_RENEGOTIATION flag on every
version before OpenSSL 0.9.8l. I can confirm that the option value (0x0010)
wasn't reused until OpenSSL 1.0.0beta3.
In brief: you mustn't use the SSL3_FLAG solution with anything but 0.9.8l,
and you mustn't use the SSL_OP solution with anything before 0.9.8m, and
you get in _real_ trouble if you try to set the flag in 1.0.0beta, since
they use it for something different.
For the ugly version, see my long comment in tortls.c
We need to do this because Apple doesn't update its dev-tools headers
when it updates its libraries in a security patch. On the bright
side, this might get us out of shipping a statically linked OpenSSL on
OSX.
May fix bug 1225.
[backported]
We need to do this because Apple doesn't update its dev-tools headers
when it updates its libraries in a security patch. On the bright
side, this might get us out of shipping a statically linked OpenSSL on
OSX.
May fix bug 1225.
We were checking for msg==NULL, but not lib or proc. This case can
only occur if we have an error whose string we somehow haven't loaded,
but it's worth coding defensively here.
Spotted by rieo on IRC.
Some *_free functions threw asserts when passed NULL. Now all of them
accept NULL as input and perform no action when called that way.
This gains us consistence for our free functions, and allows some
code simplifications where an explicit null check is no longer necessary.
It turns out that OpenSSL 0.9.8m is likely to take a completely
different approach for reenabling renegotiation than OpenSSL 0.9.8l
did, so we need to work with both. :p Fixes bug 1158.
(patch by coderman; commit message by nickm)
To fix a major security problem related to incorrect use of
SSL/TLS renegotiation, OpenSSL has turned off renegotiation by
default. We are not affected by this security problem, however,
since we do renegotiation right. (Specifically, we never treat a
renegotiated credential as authenticating previous communication.)
Nevertheless, OpenSSL's new behavior requires us to explicitly
turn renegotiation back on in order to get our protocol working
again.
Amusingly, this is not so simple as "set the flag when you create
the SSL object" , since calling connect or accept seems to clear
the flags.
For belt-and-suspenders purposes, we clear the flag once the Tor
handshake is done. There's no way to exploit a second handshake
either, but we might as well not allow it.
The big change is to add a function to display the current SSL handshake
state, and to log it everywhere reasonable. (A failure in
SSL23_ST_CR_SRVR_HELLO_A is different from one in
SSL3_ST_CR_SESSION_TICKET_A.)
This patch also adds a new log domain for OR handshaking, so you can pull out
all the handshake log messages without having to run at debug for everything.
For example, you'd just say "log notice-err [handshake]debug-err file
tor.log".
The subversion $Id$ fields made every commit force a rebuild of
whatever file got committed. They were not actually useful for
telling the version of Tor files in the wild.
svn:r17867
Implement code to manually force the OpenSSL client cipher list to match the one recommended in proposal 124, *even if* we do not know all those ciphers. This is a bit of a kludge, but it is at least decently well commented.
svn:r15173
Make dumpstats() log the size and fullness of openssl-internal buffers, so I can test my hypothesis that many of them are empty, and my alternative hypothesis that many of them are mostly empty, against the null hypothesis that we really need to be burning 32K per open OR connection on this.
svn:r14350
Fix for bug 614: always look at the network BIO for the SSL object, not at the buffering BIO (if one exists because we are renegotiating or something). Bugfix on 0.1.2.x, oddly enough, though it should be impossible to trigger the problem there. Backport candidate. See comments in tortls.c for detailed implementation note.
svn:r13975
<weasel> tortls.c:634: warning: passing arg 1 of `SSL_get_session' discards
qualifiers from pointer target type
Nick, see if you like this patch.
svn:r13690
Fix all remaining shorten-64-to-32 errors in src/common. Some were genuine problems. Many were compatibility errors with libraries (openssl, zlib) that like predate size_t. Partial backport candidate.
svn:r13665
Answer one xxx020 item; move 7 other ones to a new "XXX020rc" category: they should get fixed before we cut a release candidate. arma: please review these to see whether you have fixes/answers for any. Please check out the other 14 XXX020s to see if any look critical for the release candidate.
svn:r13640
Re-tune mempool parametes based on testing on peacetime: use smaller chuncks, free them a little more aggressively, and try very hard to concentrate allocations on fuller chunks. Also, lots of new documentation.
svn:r13484
The SSL portion of the revised handshake now seems to work: I just finally got a client and a server to negotiate versions. Now to make sure certificate verification is really happening, connections are getting opened, etc.
svn:r13409
Add a reverse mapping from SSL to tor_tls_t*: we need this in order to do a couple of things the sensible way from inside callbacks. Also, add a couple of missing cases in connection_or.c
svn:r13040
Aaand, do the code to enable the client side of the new TLS handshake. There are some loose ends that need tying up in connection_or, and a lot of half-baked code to remove, and some special cases to test for, and lots and lots of testing to do, but that is what weekends are for.
svn:r12721
Add support to get a callback invoked when the client renegotiate a connection. Also, make clients renegotiate. (not enabled yet, until they detect that the server acted like a v2 server)
svn:r12623
Start getting freaky with openssl callbacks in tortls.c: detect client ciphers, and if the list doesn't look like the list current Tors use, present only a single cert do not ask for a client cert. Also, support for client-side renegotiation. None of this is enabled unless you define V2_HANDSHAKE_SERVER.
svn:r12622
Make TLS contexts reference-counted, and add a reference from TLS objects to their corresponding context. This lets us reliably get the certificates for a given TLS connection, even if we have rotated TLS contexts.
svn:r12383
New code (disabled for now) to use the SSL context's cert store instead of using its "extra chain cert" list to get our identity certificate sent. This is a little close to what OpenSSL expects people to do, and it has the advantage that we should be able to keep the id cert from being sent by setting the NO_CHAIN_CERT bit. I have tried turning new code on, and it seemed to work fine.
svn:r12086
Cheesy attempt to break some censorware. Not a long-term fix, but it will be intersting to watch the epidemiology of the workarounds as the censors apply them.
svn:r10975
Implement proposal 106: stop requiring clients to have certificates, and stop checking for nicknames in certificates. [See proposal 106 for rationale.] Also improve messages when checking TLS handshake, to re-resolve bug 382.
svn:r9568
Removing the last DOCDOC comment hurt so much that I had to use Doxygen to identify undocumented macros and comments, and add 150 more DOCDOCs to point out where they were. Oops. Hey, kids! Fixing some of these could be your first Tor patch!
svn:r9477
Tidy up ORCONN reason patch from Mike Perry. Changes: make some of the handling of TLS error codes less error prone. Enforce house style wrt spaces. Make it compile with --enable-gcc-warnings. Only set or_conn->tls_error in the case of an actual error. Add a changelog entry.
svn:r9355
"read this if you don't understand the code and want some help."
which is not the same as "hey, you think you understand this code,
but you don't."
svn:r9307
Count TLS bytes accurately: previously, we counted only the number of bytes read or transmitted via tls, not the number of extra bytes used to do so. This has been a lonstanding wart. The fix "Works for me".
svn:r9207
Try to appease some warnings with newer gccs that believe that ignoring a return value is okay, but casting a return value and then ignoring it is a sign of madness.
svn:r8312