Apple于最近放出了iOS 7.0.6固件升级,修复了SSL连接验证时的BUG。用升级后的ios系统打开漏洞测试页面https://www.imperialviolet.org:1266已经无法打开。页面提示无法建立安全链接。自此,据说被苹果遗忘了18个月的重大BUG被成功修复。但目前MACOS的这个BUG仍未修复,使用Safari浏览器打开上文的BUG的测试页面会出现下面的提示,但使用firefox或Chrome打开页面却不会成功。
Safari打开页面的情况
Chrome打开页面的情况
Firefox打开页面的情况
该漏洞出现的原因是因为位于http://opensource.apple.com/source/Security/Security-55471/libsecurity_ssl/lib/sslKeyExchange.c中的一处SSLHashSHA1判断下方多出了一个goto语句导致了执行SSLVerifySignedServerKeyExchange函数时必定跳转到fail标号处,会return err并触发BUG。
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, UInt16 signatureLen) { OSStatus err; SSLBuffer hashOut, hashCtx, clientRandom, serverRandom; uint8_t hashes[SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN]; SSLBuffer signedHashes; uint8_t *dataToSign; size_t dataToSignLen; signedHashes.data = 0; 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) goto fail; if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashMD5.update(&hashCtx, &signedParams)) != 0) goto fail; if ((err = SSLHashMD5.final(&hashCtx, &hashOut)) != 0) goto fail; } 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) goto fail; if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; // 多出来的goto fail 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; }
原文:http://blog.csdn.net/firedom/article/details/19937975