by jfarmer on 3/23/22, 8:08 PM with 48 comments
by tptacek on 3/23/22, 8:33 PM
I was super excited to dive in an find the RSA code so I could preen about Bleichenbacher's vulnerability, but she neatly sidestepped that by doing ECDH. Then I thought, well, maybe it's P-curve ECDH and I can preen about invalid curve attacks on static-ephemeral ECDH. But nope, X25519! My point here, apart from making fun of myself for being the kind of person who would write this stuff on a message board, is TLS 1.3 is pretty solid.
The "block thing" that's kind of weird is, I assume, the TLS Record Layer. TLS runs (ordinarily) over TCP, which provides a non-demarcated stream of bytes. TLS breaks that stream up into records, and runs its handshake messages over one type of record, (say) HTTPS over another, and "alerts" over a third. The Record Layer also interacts, I think, with TLS's misbegotten compression system?
In the same vein as this project (but with different goals) is Trevor Perrin's tlslite, which is implemented in pure Python: https://github.com/trevp/tlslite
by syncsynchalt on 3/24/22, 12:50 AM
Readers, i made a "squee" noise just now. Glad it was useful, this is exactly the sort of thing I wrote it for. <3
by userbinator on 3/24/22, 2:53 AM
I only looked at the TLS 1.3 RFC for a few small things.
As someone who has written implementations of various widely-considered-nontrivial things (mostly image and video codecs, some crypto -- but not TLS, although upon seeing this article, that may change...) for self-educational purposes, I strongly recommend that the official standard be the first thing you look at and refer to during the process. It will clarify a lot of doubts, and in the case of TLS, the RFCs are relatively readable as far as standards go.
I’m not sure why the blocks have the size they do (maybe it’s so that each one will fit inside a TCP packet ???), but in theory I think they could be up to 65535 bytes, since their size field is 2 bytes.
That's due to either MTU or server-side write fragmentation, and the limit is 16K(+overhead). It is a stream to the application layer, but the record-layer protocol breaks it up into chunks of smaller limited size to allow for the integrity checks.
I assume a real TLS implementation would use a thread pool or coroutines or something to manage this.
That's a very strange assumption. Depending on the API, the ones I've used will either just read in a loop until the length is fulfilled or an error occurs; or return an "incomplete message" error meaning that the caller is the one to continue reading. Getting a partial read from a TCP socket is a very common "trap for young players" --- if you don't keep it in mind, you'll write code that appears to work on localhost or inside a fast LAN, but fails intermittently and sometimes mysteriously over the Internet or when there's more latency. You can never assume message boundaries when using TCP.
by profmonocle on 3/23/22, 10:14 PM
by drewg123 on 3/23/22, 10:50 PM
This drove me crazy when I was working on kTLS in FreeBSD. When I worked on other features (like getting checksum offload right in NIC firmware) there were easy tricks I could use for debugging, like sending a stream of all zeros. For crypto, it was basically back to first principals and code examination..
by silisili on 3/24/22, 1:11 AM
To break it down and write a small implementation showing the steps is seriously both impressive and extremely generous. Kudos!
by tialaramex on 3/23/22, 10:32 PM
> elliptic curve “multiplication”, where n * P means “add P to itself n times”
Not very smoothly described but this is all multiplication meant for the natural numbers you learned in primary school too! Why is 7 x 7 = 49? Because if you start with zero and add 7, seven times, you get 49. Try it. This is an important and re-usable insight, it's part of a larger beautiful framework of mathematics and I believe is much better instructed via modern teaching of arithmetic in schools than "rote learning" of times tables did for my parents.
by tedunangst on 3/23/22, 10:44 PM
HTTP headers include Content-Length, so you should know when you get a truncated response, but TLS is supposed to be more general purpose, so it includes its own crypto secure end of connection indicator.
by travisgriggs on 3/24/22, 2:39 AM
> This was pretty annoying to get working because I kept passing the wrong arguments to things.
I think this sentiment shows up twice in fact in the article.
I’m not sure what language the listings are in, but it looked static-type-ish.
Are there things the current batch of safety focused languages do to mitigate these types of ordering errors?
In Kotlin, Python, and Swift, we make it a practice to always use the keywords in calls if there are multiple arguments of the same type (e.g. two or more ints). I wish I could figure out how to configure any of their linters to enforce it better.
Despite its late bound unsafe nature, this was just never an error I made (argument ordering) back when I used to do a lot of Smalltalk with its interwoven keyword syntax.
by olliej on 3/24/22, 4:51 AM