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