Skip to content

Instantly share code, notes, and snippets.

@JensAyton
Forked from davepeck/oops.c
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JensAyton/9161071 to your computer and use it in GitHub Desktop.
Save JensAyton/9161071 to your computer and use it in GitHub Desktop.
One example of cleanup without using goto. (This isn't an opinion on what Apple “should have” done, it’s just an answer to a specific question on Twitter. It would have done nothing to avoid the actual bug.) I also removed the unused variable “signedHashes”.
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
SSLBuffer hashCtx;
hashCtx.date = 0;
OSStatus err = SSLVerifySignedServerKeyExchangeInner(ctx, isRsa, signedParams, signature, signatureLen, &hashCtx);
SSLFreeBuffer(hashCtx);
return err;
}
static OSStatus
SSLVerifySignedServerKeyExchangeInner(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen, SSLBuffer *hashCtx)
{
OSStatus err;
SSLBuffer hashOut, clientRandom, serverRandom;
uint8_t hashes[SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN];
uint8_t *dataToSign;
size_t dataToSignLen;
hashCtx.data = 0;
clientRandom.data = ctx->clientRandom;
clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
serverRandom.data = ctx->serverRandom;
serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
if(isRsa) {
/* skip this if signing with DSA */
dataToSign = hashes;
dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN;
hashOut.data = hashes;
hashOut.length = SSL_MD5_DIGEST_LEN;
if ((err = ReadyHash(&SSLHashMD5, hashCtx)) != 0)
return err;
if ((err = SSLHashMD5.update(hashCtx, &clientRandom)) != 0)
return err;
if ((err = SSLHashMD5.update(hashCtx, &serverRandom)) != 0)
return err;
if ((err = SSLHashMD5.update(hashCtx, &signedParams)) != 0)
return err;
if ((err = SSLHashMD5.final(hashCtx, &hashOut)) != 0)
return err;
}
else {
/* DSA, ECDSA - just use the SHA1 hash */
dataToSign = &hashes[SSL_MD5_DIGEST_LEN];
dataToSignLen = SSL_SHA1_DIGEST_LEN;
}
hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
hashOut.length = SSL_SHA1_DIGEST_LEN;
if ((err = SSLFreeBuffer(hashCtx)) != 0)
return err;
if ((err = ReadyHash(&SSLHashSHA1, hashCtx)) != 0)
return err;
if ((err = SSLHashSHA1.update(hashCtx, &clientRandom)) != 0)
return err;
if ((err = SSLHashSHA1.update(hashCtx, &serverRandom)) != 0)
return err;
if ((err = SSLHashSHA1.update(hashCtx, &signedParams)) != 0)
return err;
if ((err = SSLHashSHA1.final(hashCtx, &hashOut)) != 0)
return err;
err = sslRawVerify(ctx,
ctx->peerPubKey,
dataToSign, /* plaintext */
dataToSignLen, /* plaintext length */
signature,
signatureLen);
if(err) {
sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify "
"returned %d\n", (int)err);
}
return err;
}
@JensAyton
Copy link
Author

It’s worth noting that in this particular case, this approach adds no value except removing a keyword some people don’t like (which was the immediate goal). The code flow is no more or less clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment