double fail

Here is what is dubbed the ‘Apple Bug’:

static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
                                 uint8_t *signature, UInt16 signatureLen)
{
	OSStatus        err;
	...

	if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
		goto fail;
	if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
		goto fail;
		goto fail;
	if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
		goto fail;
	...

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

So what is this? If you ask me it looks like a combination of stupid coding conventions,  a merge artifact and not enough coverage in unit tests. 

Coding conventions

A lot of coding conventions will tell you that you should use braces around blocks even if a block is only a single line. Would it have helped? Perhaps. If it would result in code like this:

	if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) {
		goto fail;
		goto fail;
        }

It looks funny but in this case the double fail would be harmless. And a good compiler would have warned about unreachable code.

Merge artifact

Could be. Could even be caused by changes in whitespace – who knows.

Test coverage

This is a conclusion that makes me worry. This kind of error should have surfaced in unit testing this function. 

unit testing and time travel

Sometimes the solution for a thorny problem is easy. If you are writing unit tests for a piece of code that behaves differently before and after a certain point of time you wish you could do time travel with the computer you are using to run the tests. Adjusting the system date often is inconvenient. A lot of processes depend on proper timekeeping by the operating system and often a regular user cannot adjust time for simple lack of authorization. Take my advice and stay away from the system clock.

The solution is to use Joda Time. It has a class called DateTimeUtils with a static method setCurrentMillisFixed that effectively fixes the system time for the Joda Time library to a certain value. Returning to the present is done by calling setCurrentMillisSystem after you are done time traveling

    @Before
    public void before() {
        LocalDate pointInTime = new LocalDate().minusDays(10);
        DateTimeUtils.setCurrentMillisFixed(pointInTime.toDateTime(new LocalTime(0, 0, 0, 0)).getMillis());
    }

    @After
    public void after() {
        DateTimeUtils.setCurrentMillisSystem();
    }

Done.

Enjoy.