35e7de9
--- neon-0.30.2/src/ne_openssl.c.openssl11
35e7de9
+++ neon-0.30.2/src/ne_openssl.c
35e7de9
@@ -574,6 +574,9 @@
35e7de9
         /* enable workarounds for buggy SSL server implementations */
35e7de9
         SSL_CTX_set_options(ctx->ctx, SSL_OP_ALL);
35e7de9
         SSL_CTX_set_verify(ctx->ctx, SSL_VERIFY_PEER, verify_callback);
35e7de9
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L
35e7de9
+        SSL_CTX_set_post_handshake_auth(ctx->ctx, 1);
35e7de9
+#endif
35e7de9
     } else if (mode == NE_SSL_CTX_SERVER) {
35e7de9
         ctx->ctx = SSL_CTX_new(SSLv23_server_method());
35e7de9
         SSL_CTX_set_session_cache_mode(ctx->ctx, SSL_SESS_CACHE_CLIENT);
35e7de9
@@ -1130,7 +1133,10 @@
35e7de9
     return 0;
35e7de9
 }
35e7de9
 
35e7de9
-#ifdef NE_HAVE_TS_SSL
35e7de9
+#if defined(NE_HAVE_TS_SSL) && OPENSSL_VERSION_NUMBER < 0x10101000L
35e7de9
+/* For OpenSSL 1.1.1 locking callbacks are no longer need at all. */
35e7de9
+#define WITH_OPENSSL_LOCKING (1)
35e7de9
+
35e7de9
 /* Implementation of locking callbacks to make OpenSSL thread-safe.
35e7de9
  * If the OpenSSL API was better designed, this wouldn't be necessary.
35e7de9
  * In OpenSSL releases without CRYPTO_set_idptr_callback, it's not
35e7de9
@@ -1184,8 +1190,6 @@
35e7de9
     }
35e7de9
 }
35e7de9
 
35e7de9
-#endif
35e7de9
-
35e7de9
 /* ID_CALLBACK_IS_{NEON,OTHER} evaluate as true if the currently
35e7de9
  * registered OpenSSL ID callback is the neon function (_NEON), or has
35e7de9
  * been overwritten by some other app (_OTHER). */
35e7de9
@@ -1196,6 +1200,8 @@
35e7de9
 #define ID_CALLBACK_IS_OTHER (CRYPTO_get_id_callback() != NULL)
35e7de9
 #define ID_CALLBACK_IS_NEON (CRYPTO_get_id_callback() == thread_id_neon)
35e7de9
 #endif
35e7de9
+        
35e7de9
+#endif /* NE_HAVE_TS_SSL && OPENSSL_VERSION_NUMBER < 1.1.1 */
35e7de9
 
35e7de9
 int ne__ssl_init(void)
35e7de9
 {
35e7de9
@@ -1205,7 +1211,7 @@
35e7de9
     SSL_library_init();
35e7de9
     OpenSSL_add_all_algorithms();
35e7de9
 
35e7de9
-#ifdef NE_HAVE_TS_SSL
35e7de9
+#ifdef WITH_OPENSSL_LOCKING
35e7de9
     /* If some other library has already come along and set up the
35e7de9
      * thread-safety callbacks, then it must be presumed that the
35e7de9
      * other library will have a longer lifetime in the process than
35e7de9
@@ -1252,7 +1258,7 @@
35e7de9
     /* Cannot call ERR_free_strings() etc here in case any other code
35e7de9
      * in the process using OpenSSL. */
35e7de9
 
35e7de9
-#ifdef NE_HAVE_TS_SSL
35e7de9
+#ifdef WITH_OPENSSL_LOCKING
35e7de9
     /* Only unregister the callbacks if some *other* library has not
35e7de9
      * come along in the mean-time and trampled over the callbacks
35e7de9
      * installed by neon. */
35e7de9
--- neon-0.30.2/src/ne_pkcs11.c.openssl11
35e7de9
+++ neon-0.30.2/src/ne_pkcs11.c
35e7de9
@@ -113,13 +113,13 @@
35e7de9
         return 0;
35e7de9
     }
35e7de9
 
35e7de9
-    if (padding != RSA_PKCS1_PADDING) {
35e7de9
+    if (padding != RSA_PKCS1_PADDING && padding != RSA_NO_PADDING) {
35e7de9
         NE_DEBUG(NE_DBG_SSL, "pk11: Cannot sign, unknown padding mode '%d'.\n", padding);
35e7de9
         RSAerr(PK11_RSA_ERR,ERR_R_RSA_LIB);
35e7de9
         return 0;
35e7de9
     }        
35e7de9
 
35e7de9
-    mech.mechanism = CKM_RSA_PKCS;
35e7de9
+    mech.mechanism = padding == RSA_PKCS1_PADDING ? CKM_RSA_PKCS : CKM_RSA_X_509;
35e7de9
     mech.parameter = NULL;
35e7de9
     mech.parameter_len = 0;
35e7de9
 
35e7de9
--- neon-0.30.2/src/ne_request.c.openssl11
35e7de9
+++ neon-0.30.2/src/ne_request.c
35e7de9
@@ -940,6 +940,12 @@
35e7de9
     }
35e7de9
 }
35e7de9
 
35e7de9
+#ifdef NE_HAVE_SSL
35e7de9
+#define SSL_CC_REQUESTED(_r) (_r->session->ssl_cc_requested)
35e7de9
+#else
35e7de9
+#define SSL_CC_REQUESTED(_r) (0)
35e7de9
+#endif
35e7de9
+
35e7de9
 /* Read and parse response status-line into 'status'.  'retry' is non-zero
35e7de9
  * if an NE_RETRY should be returned if an EOF is received. */
35e7de9
 static int read_status_line(ne_request *req, ne_status *status, int retry)
35e7de9
@@ -949,8 +955,11 @@
35e7de9
 
35e7de9
     ret = ne_sock_readline(req->session->socket, buffer, sizeof req->respbuf);
35e7de9
     if (ret <= 0) {
35e7de9
-	int aret = aborted(req, _("Could not read status line"), ret);
35e7de9
-	return RETRY_RET(retry, ret, aret);
35e7de9
+        const char *errstr = SSL_CC_REQUESTED(req)
35e7de9
+            ? _("Could not read status line (TLS client certificate was requested)")
35e7de9
+            : _("Could not read status line");
35e7de9
+        int aret = aborted(req, errstr, ret);
35e7de9
+        return RETRY_RET(retry, ret, aret);
35e7de9
     }
35e7de9
     
35e7de9
     NE_DEBUG(NE_DBG_HTTP, "[status-line] < %s", buffer);
35e7de9
--- neon-0.30.2/src/ne_socket.c.openssl11
35e7de9
+++ neon-0.30.2/src/ne_socket.c
35e7de9
@@ -179,6 +179,9 @@
35e7de9
 /* Socket read timeout */
35e7de9
 #define SOCKET_READ_TIMEOUT 120
35e7de9
 
35e7de9
+/* Internal read retry value */
35e7de9
+#define NE_SOCK_RETRY (-6)
35e7de9
+    
35e7de9
 /* Critical I/O functions on a socket: useful abstraction for easily
35e7de9
  * handling SSL I/O alongside raw socket I/O. */
35e7de9
 struct iofns {
35e7de9
@@ -599,13 +602,50 @@
35e7de9
 
35e7de9
 static const struct iofns iofns_raw = { read_raw, write_raw, readable_raw, writev_raw };
35e7de9
 
35e7de9
+static int error_ossl(ne_socket *sock, int sret);
35e7de9
+
35e7de9
 #ifdef HAVE_OPENSSL
35e7de9
 /* OpenSSL I/O function implementations. */
35e7de9
 static int readable_ossl(ne_socket *sock, int secs)
35e7de9
 {
35e7de9
+#if OPENSSL_VERSION_NUMBER < 0x10101000L
35e7de9
+    /* Sufficient for TLSv1.2 and earlier. */
35e7de9
     if (SSL_pending(sock->ssl))
35e7de9
 	return 0;
35e7de9
     return readable_raw(sock, secs);
35e7de9
+#else
35e7de9
+    /* TLSv1.3 sends a lot more handshake data so the presence of data
35e7de9
+     * on the socket - i.e. poll() returning 1, is an insufficient
35e7de9
+     * test for app-data readability. */
35e7de9
+    char pending;
35e7de9
+    int ret;
35e7de9
+    size_t bytes;
35e7de9
+
35e7de9
+    /* Loop while no app data is pending, each time attempting a one
35e7de9
+     * byte peek, and retrying the poll if that fails due to absence
35e7de9
+     * of app data. */
35e7de9
+    while (!SSL_pending(sock->ssl)) {
35e7de9
+	ret = readable_raw(sock, secs);
35e7de9
+	if (ret == NE_SOCK_TIMEOUT) {
35e7de9
+	    return ret;
35e7de9
+	}
35e7de9
+        
35e7de9
+	ret = SSL_peek_ex(sock->ssl, &pending, 1, &bytes);
35e7de9
+	if (ret) {
35e7de9
+            /* App data definitely available. */
35e7de9
+	    break;
35e7de9
+	}
35e7de9
+	else {
35e7de9
+            /* If this gave SSL_ERROR_WANT_READ, loop and probably
35e7de9
+             * block again, else some other error happened. */
35e7de9
+            ret = error_ossl(sock, ret);
35e7de9
+            if (ret != NE_SOCK_RETRY)
35e7de9
+                return ret;
35e7de9
+	}
35e7de9
+    }
35e7de9
+
35e7de9
+    return 0;
35e7de9
+#endif /* OPENSSL_VERSION_NUMBER < 1.1.1 */
35e7de9
 }
35e7de9
 
35e7de9
 /* SSL error handling, according to SSL_get_error(3). */
35e7de9
@@ -618,6 +658,10 @@
35e7de9
 	set_error(sock, _("Connection closed"));
35e7de9
         return NE_SOCK_CLOSED;
35e7de9
     }
35e7de9
+    else if (errnum == SSL_ERROR_WANT_READ) {
35e7de9
+        set_error(sock, _("Retry operation"));
35e7de9
+        return NE_SOCK_RETRY;
35e7de9
+    }
35e7de9
     
35e7de9
     /* for all other errors, look at the OpenSSL error stack */
35e7de9
     err = ERR_get_error();
35e7de9
@@ -656,13 +700,15 @@
35e7de9
 {
35e7de9
     int ret;
35e7de9
 
35e7de9
-    ret = readable_ossl(sock, sock->rdtimeout);
35e7de9
-    if (ret) return ret;
35e7de9
-    
35e7de9
-    ret = SSL_read(sock->ssl, buffer, CAST2INT(len));
35e7de9
-    if (ret <= 0)
35e7de9
-	ret = error_ossl(sock, ret);
35e7de9
-
35e7de9
+    do {
35e7de9
+        ret = readable_ossl(sock, sock->rdtimeout);
35e7de9
+        if (ret) return ret;
35e7de9
+        
35e7de9
+        ret = SSL_read(sock->ssl, buffer, CAST2INT(len));
35e7de9
+        if (ret <= 0)
35e7de9
+            ret = error_ossl(sock, ret);
35e7de9
+    } while (ret == NE_SOCK_RETRY);
35e7de9
+        
35e7de9
     return ret;
35e7de9
 }
35e7de9
 
35e7de9
@@ -1761,7 +1807,11 @@
35e7de9
     }
35e7de9
     
35e7de9
     SSL_set_app_data(ssl, userdata);
35e7de9
+#if OPENSSL_VERSION_NUMBER < 0x10101000L
35e7de9
     SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
35e7de9
+#else
35e7de9
+    SSL_clear_mode(ssl, SSL_MODE_AUTO_RETRY);
35e7de9
+#endif    
35e7de9
     SSL_set_fd(ssl, sock->fd);
35e7de9
     sock->ops = &iofns_ssl;
35e7de9
 
35e7de9
@@ -1923,12 +1973,13 @@
35e7de9
 {
35e7de9
     int ret;
35e7de9
 
35e7de9
-    /* Per API description - for an SSL connection, simply send the
35e7de9
-     * close_notify but do not wait for the peer's response. */
35e7de9
+    /* Complete a bidirectional shutdown for SSL/TLS. */
35e7de9
 #if defined(HAVE_OPENSSL)
35e7de9
     if (sock->ssl) {
35e7de9
-        SSL_shutdown(sock->ssl);
35e7de9
-	SSL_free(sock->ssl);
35e7de9
+        if (SSL_shutdown(sock->ssl) == 0) {
35e7de9
+            SSL_shutdown(sock->ssl);
35e7de9
+        }
35e7de9
+        SSL_free(sock->ssl);
35e7de9
     }
35e7de9
 #elif defined(HAVE_GNUTLS)
35e7de9
     if (sock->ssl) {