“goto fail”: Apple’s SSL Bug and an unanswered Question

In February 2014 a bug in Apple’s SSL implementation was patched. It affected Apple mobile products that run iOS 6 and iOS 7 as well as desktop products that run OS X 10.9 (Maverick).
iOS 6 was launched in September 2012, so this problem was out in the wild for quite a while.

The flaw compromised SSL-based HTTPS connections that use specifically Diffie-Hellman (D-H) key exchange during the initial handshake phase.
In D-H both client and server exchange public keys, which are used by each side to calculate a common session key. In order to deter a man-in-the-middle attack the server digitally signs its public key before sending it to the client. The client in turn validates the signature before accepting the public key.
And exactly this did not happen… the client simply accepted the public key regardless.

Figure 1: The SSL Bug (Courtesy of http://opensource.apple.com)

Figure 1: The SSL Bug (Courtesy of http://opensource.apple.com)

In a potential attack scenario a vulnerable client and a man-in the middle (MITM) share an open internet connection, for example via a public access point. The client initiates a secure (HTTPS) connection to some remote server. The MITM intercepts the signed public key of the server during the handshake and sends his own public key (complemented with some dummy signature) to the client, therefore creating two separate “secure” connections to both ends. This allows him to decode (and encode) all messages coming from both sides.

In all fairness SSL and TLS implementations are very complicated pieces of code – the affected source file has about 2000 lines of code – and are probably only fully understood by a handful of people. And of course coding errors happen… even to large and well-established companies that have mature development, testing and QA frameworks / organisational structures.

However, the bug manifests itself in a duplicated line of code (“goto fail;” in Figure 1), which translates into the following code structure:

If (condition)
                goto fail
else
                goto fail

<more_code>
fail:

The code behind <more_code> (e.g. the outstanding validation of the server’s signature) can never be executed, it is unreachable code.

And this is a blatantly obvious bug. Any software professional with some C programming skills should have seen this in a code review.
And you don’t even need to know anything about SSL or the functionality of the code to realise that there is something fundamentally wrong here.
Even a modern C compiler will give a warning, if it detects unreachable code.
But still, this problem was never discovered pre-deployment.

And I wonder why. How could this happen to such a crucial piece of code?

Speak Your Mind

*