By now most people working in the tech sector have heard about the bug in Apple’s implementation of SSL/TLS. What you may not know is that the bug has been in the code since 2012 apparently and that the code has been sitting in plain view as part of Apples open source code. And it’s not in some obscure deeply buried file. It’s in a file called sslKeyExchange.c which is only about 2,000 lines long.

http://opensource.apple.com/source/Security/Security-55471/libsecurity_ssl/lib/sslKeyExchange.c

Over the years we’ve been led to believe that security through obscurity is bad, and that the best way to guarantee robust, bulletproof security is to publish everything out in the open so that the eyes of many experts can review it and quickly find holes which will just as quickly get plugged.

So what went wrong? I’ll leave the answer to the open source proponents, but I have another embarrassing question to ask.

The code in question is shown below – a goto fail that completely skips a bunch of stuff.

Shouldn’t the compiler have issued a warning “unreachable code detected”? I see this error all the time when I temporarily put in statements of any kind to step around code during debugging. It’s possible that someone missed the extra goto when looking at the source (although it literally jumps off the page to me), but how is it possible that in a completely critical piece of code like this someone didn’t read the compiler warnings and check out what unreachable code was being skipped?

    if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
        goto fail;
        goto fail;
/* My note - everything between here and the fail label should have been flagged in an unreachable code warning */
    if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
        goto fail;

	err = sslRawVerify(ctx,
                       ctx->peerPubKey,
                       dataToSign,				/* plaintext */
                       dataToSignLen,			/* plaintext length */
                       signature,
                       signatureLen);
	if(err) {
		sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify "
                    "returned %d\n", (int)err);
		goto fail;
	}

fail:
    SSLFreeBuffer(&signedHashes);
    SSLFreeBuffer(&hashCtx);
    return err;

Comments are closed.