Author: markt Date: Mon Aug 21 08:22:17 2017 New Revision: 1805606 URL: http://svn.apache.org/viewvc?rev=1805606&view=rev Log: Fix renegotiation to obtain a client certificate from a user agent.
Modified: tomcat/native/trunk/native/src/sslnetwork.c tomcat/native/trunk/xdocs/miscellaneous/changelog.xml Modified: tomcat/native/trunk/native/src/sslnetwork.c URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslnetwork.c?rev=1805606&r1=1805605&r2=1805606&view=diff ============================================================================== --- tomcat/native/trunk/native/src/sslnetwork.c (original) +++ tomcat/native/trunk/native/src/sslnetwork.c Mon Aug 21 08:22:17 2017 @@ -365,13 +365,12 @@ TCN_IMPLEMENT_CALL(jint, SSLSocket, hand * Check for failed client authentication */ if (con->ctx->verify_mode != SSL_VERIFY_NONE && - (vr = SSL_get_verify_result(con->ssl)) != X509_V_OK) { + (vr = SSL_get_verify_result(con->ssl)) != X509_V_OK) { if (SSL_VERIFY_ERROR_IS_OPTIONAL(vr) && - con->ctx->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA) { + con->ctx->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA) { /* TODO: Log optionalNoCA */ - } - else { + } else { /* TODO: Log SSL client authentication failed */ con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; /* TODO: Figure out the correct return value */ @@ -623,7 +622,9 @@ TCN_IMPLEMENT_CALL(jint, SSLSocket, rene tcn_socket_t *s = J2P(sock, tcn_socket_t *); tcn_ssl_conn_t *con; int retVal; + int error = 0; char peekbuf[1]; + apr_interval_time_t timeout; UNREFERENCED_STDARGS; TCN_ASSERT(sock != 0); @@ -633,28 +634,59 @@ TCN_IMPLEMENT_CALL(jint, SSLSocket, rene * handshake to proceed. */ con->reneg_state = RENEG_ALLOW; - retVal = SSL_renegotiate(con->ssl); - if (retVal <= 0) - return APR_EGENERAL; - retVal = SSL_do_handshake(con->ssl); + // Schedule a renegotiation request + retVal = SSL_renegotiate(con->ssl); if (retVal <= 0) return APR_EGENERAL; - if (!SSL_is_init_finished(con->ssl)) { - return APR_EGENERAL; - } - /* Need to trigger renegotiation handshake by reading. + /* Need to trigger the renegotiation handshake by reading. * Peeking 0 bytes actually works. * See: http://marc.info/?t=145493359200002&r=1&w=2 + * + * This will normally return SSL_ERROR_WANT_READ whether the renegotiation + * has been completed or not. Afterwards, need to determine if I/O needs to + * be triggered or not. */ - SSL_peek(con->ssl, peekbuf, 0); + retVal = SSL_peek(con->ssl, peekbuf, 0); + if (retVal < 1) { + error = SSL_get_error(con->ssl, retVal); + } - con->reneg_state = RENEG_REJECT; + apr_socket_timeout_get(con->sock, &timeout); + // If the renegotiation is still pending, then I/O needs to be triggered + while (SSL_renegotiate_pending(con->ssl)) { + // SSL_ERROR_WANT_READ is expected. Anything else is an error. + if (error == SSL_ERROR_WANT_READ) { + retVal = wait_for_io_or_timeout(con, error, timeout); + /* + * Since this is blocking I/O, anything other than APR_SUCCESS is an + * error. + */ + if (retVal != APR_SUCCESS) { + printf("ERROR\n"); + con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; + return retVal; + } + } else { + return APR_EGENERAL; + } - if (!SSL_is_init_finished(con->ssl)) { - return APR_EGENERAL; + // Re-try SSL_peek after I/O + retVal = SSL_peek(con->ssl, peekbuf, 0); + if (retVal < 1) { + error = SSL_get_error(con->ssl, retVal); + } else { + /* + * Reset error to handle case where SSL_Peek returns 0 but + * SSL_renegotiate_pending returns true. This will trigger an error + * to be returned. + */ + error = 0; + } } + + con->reneg_state = RENEG_REJECT; return APR_SUCCESS; } Modified: tomcat/native/trunk/xdocs/miscellaneous/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/native/trunk/xdocs/miscellaneous/changelog.xml?rev=1805606&r1=1805605&r2=1805606&view=diff ============================================================================== --- tomcat/native/trunk/xdocs/miscellaneous/changelog.xml (original) +++ tomcat/native/trunk/xdocs/miscellaneous/changelog.xml Mon Aug 21 08:22:17 2017 @@ -50,6 +50,10 @@ Fix an error not announcing the correct CA list for client certificates during TLS handshake. (rjung) </fix> + <fix> + Fix renegotiation to obtain a client certificate from a user agent. + (markt) + </fix> </changelog> </section> <section name="Changes in 1.2.12"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org