diff options
Diffstat (limited to 'security/nss/lib/ssl/ssl3con.c')
-rw-r--r-- | security/nss/lib/ssl/ssl3con.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 1e2da2e94..e220bdc0f 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -2418,22 +2418,31 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss, SSL3Opaque md5_inner[MAX_MAC_LENGTH]; SSL3Opaque sha_inner[MAX_MAC_LENGTH]; unsigned char s[4]; + unsigned char md5StackBuf[256]; + unsigned char shaStackBuf[512]; + unsigned char *md5StateBuf = NULL; + unsigned char *shaStateBuf = NULL; + unsigned int md5StateLen, shaStateLen; PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) ); isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0); - md5 = PK11_CloneContext(ssl3->hs.md5); - if (md5 == NULL) { + md5StateBuf = PK11_SaveContextAlloc(ssl3->hs.md5, md5StackBuf, + sizeof md5StackBuf, &md5StateLen); + if (md5StateBuf == NULL) { ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); - return SECFailure; + goto loser; } + md5 = ssl3->hs.md5; - sha = PK11_CloneContext(ssl3->hs.sha); - if (sha == NULL) { + shaStateBuf = PK11_SaveContextAlloc(ssl3->hs.sha, shaStackBuf, + sizeof shaStackBuf, &shaStateLen); + if (shaStateBuf == NULL) { ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); goto loser; } + sha = ssl3->hs.sha; if (!isTLS) { /* compute hashes for SSL3. */ @@ -2522,8 +2531,28 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss, rv = SECSuccess; loser: - if (md5) PK11_DestroyContext(md5, PR_TRUE); - if (sha) PK11_DestroyContext(sha, PR_TRUE); + if (md5StateBuf) { + if (PK11_RestoreContext(ssl3->hs.md5, md5StateBuf, md5StateLen) + != SECSuccess) + { + ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); + rv = SECFailure; + } + if (md5StateBuf != md5StackBuf) { + PORT_ZFree(md5StateBuf, md5StateLen); + } + } + if (shaStateBuf) { + if (PK11_RestoreContext(ssl3->hs.sha, shaStateBuf, shaStateLen) + != SECSuccess) + { + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); + rv = SECFailure; + } + if (shaStateBuf != shaStackBuf) { + PORT_ZFree(shaStateBuf, shaStateLen); + } + } return rv; } |