ossl_recv: check for an OpenSSL error, don't assume
authorDaniel Stenberg <daniel@haxx.se>
Sun, 23 Jun 2013 08:31:04 +0000 (10:31 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 23 Jun 2013 10:05:21 +0000 (12:05 +0200)
When we recently started to treat a zero return code from SSL_read() as
an error we also got false positives - which primarily looks to be
because the OpenSSL documentation is wrong and a zero return code is not
at all an error case in many situations.

Now ossl_recv() will check with ERR_get_error() to see if there is a
stored error and only then consider it to be a true error if SSL_read()
returned zero.

Bug: http://curl.haxx.se/bug/view.cgi?id=1249
Reported-by: Nach M. S.
Patch-by: Nach M. S.
lib/ssluse.c

index 1bb7327..b9560e5 100644 (file)
@@ -2608,13 +2608,19 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
       *curlcode = CURLE_AGAIN;
       return -1;
     default:
-      /* openssl/ssl.h says "look at error stack/return value/errno" */
+      /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
+         value/errno" */
+      /* http://www.openssl.org/docs/crypto/ERR_get_error.html */
       sslerror = ERR_get_error();
-      failf(conn->data, "SSL read: %s, errno %d",
-            ERR_error_string(sslerror, error_buffer),
-            SOCKERRNO);
-      *curlcode = CURLE_RECV_ERROR;
-      return -1;
+      if((nread < 0) || sslerror) {
+        /* If the return code was negative or there actually is an error in the
+           queue */
+        failf(conn->data, "SSL read: %s, errno %d",
+              ERR_error_string(sslerror, error_buffer),
+              SOCKERRNO);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1;
+      }
     }
   }
   return nread;