Index: net/third_party/nss/ssl/ssl3gthr.c |
=================================================================== |
--- net/third_party/nss/ssl/ssl3gthr.c (revision 124804) |
+++ net/third_party/nss/ssl/ssl3gthr.c (working copy) |
@@ -36,7 +36,7 @@ |
* the terms of any one of the MPL, the GPL or the LGPL. |
* |
* ***** END LICENSE BLOCK ***** */ |
-/* $Id: ssl3gthr.c,v 1.9.20.1 2010/07/31 04:33:52 wtc%google.com Exp $ */ |
+/* $Id: ssl3gthr.c,v 1.12 2012/02/11 12:57:28 kaie%kuix.de Exp $ */ |
#include "cert.h" |
#include "ssl.h" |
@@ -192,21 +192,53 @@ |
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
do { |
- /* bring in the next sslv3 record. */ |
- rv = ssl3_GatherData(ss, &ss->gs, flags); |
- if (rv <= 0) { |
- return rv; |
+ /* Without this, we may end up wrongly reporting |
+ * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the |
+ * peer while we are waiting to be restarted. |
+ */ |
+ ssl_GetSSL3HandshakeLock(ss); |
+ rv = ss->ssl3.hs.restartTarget == NULL ? SECSuccess : SECFailure; |
+ ssl_ReleaseSSL3HandshakeLock(ss); |
+ if (rv != SECSuccess) { |
+ PORT_SetError(PR_WOULD_BLOCK_ERROR); |
+ return (int) SECFailure; |
} |
- |
- /* decipher it, and handle it if it's a handshake. |
- * If it's application data, ss->gs.buf will not be empty upon return. |
- * If it's a change cipher spec, alert, or handshake message, |
- * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess. |
+ |
+ /* Treat an empty msgState like a NULL msgState. (Most of the time |
+ * when ssl3_HandleHandshake returns SECWouldBlock, it leaves |
+ * behind a non-NULL but zero-length msgState). |
+ * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record |
*/ |
- cText.type = (SSL3ContentType)ss->gs.hdr[0]; |
- cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; |
- cText.buf = &ss->gs.inbuf; |
- rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); |
+ if (ss->ssl3.hs.msgState.buf != NULL) { |
+ if (ss->ssl3.hs.msgState.len == 0) { |
+ ss->ssl3.hs.msgState.buf = NULL; |
+ } |
+ } |
+ |
+ if (ss->ssl3.hs.msgState.buf != NULL) { |
+ /* ssl3_HandleHandshake previously returned SECWouldBlock and the |
+ * as-yet-unprocessed plaintext of that previous handshake record. |
+ * We need to process it now before we overwrite it with the next |
+ * handshake record. |
+ */ |
+ rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); |
+ } else { |
+ /* bring in the next sslv3 record. */ |
+ rv = ssl3_GatherData(ss, &ss->gs, flags); |
+ if (rv <= 0) { |
+ return rv; |
+ } |
+ |
+ /* decipher it, and handle it if it's a handshake. |
+ * If it's application data, ss->gs.buf will not be empty upon return. |
+ * If it's a change cipher spec, alert, or handshake message, |
+ * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess. |
+ */ |
+ cText.type = (SSL3ContentType)ss->gs.hdr[0]; |
+ cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; |
+ cText.buf = &ss->gs.inbuf; |
+ rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); |
+ } |
if (rv < 0) { |
return ss->recvdCloseNotify ? 0 : rv; |
} |