summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Jung <rjung@apache.org>2016-02-12 01:44:22 +0100
committerRainer Jung <rjung@apache.org>2016-02-12 01:44:22 +0100
commit4741048ff3cc7064de54820e2f7569141c3d1134 (patch)
treeb9e49d8ffbc8cfaad5a349033ea4707779b47c42
parentFix compile error: (diff)
downloadapache2-4741048ff3cc7064de54820e2f7569141c3d1134.tar.xz
apache2-4741048ff3cc7064de54820e2f7569141c3d1134.zip
Support for OpenSSL 1.1.0:
- further improvements for renegotiation No more test suite failures for reneg, but still using not so nice polling. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1729927 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--modules/ssl/ssl_engine_kernel.c20
-rw-r--r--modules/ssl/ssl_private.h17
2 files changed, 29 insertions, 8 deletions
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index f1550a7814..39388183b8 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -1040,16 +1040,20 @@ int ssl_hook_Access(request_rec *r)
/* XXX: Polling is bad, alternatives? */
for (i = 0; i < SSL_HANDSHAKE_MAX_POLLS; i++) {
has_buffered_data(r);
- if (sslconn->ssl == NULL || SSL_is_init_finished(ssl)) {
+ if (sslconn->ssl == NULL ||
+ sslconn->reneg_state == RENEG_DONE ||
+ sslconn->reneg_state == RENEG_ALLOW) {
break;
}
apr_sleep(SSL_HANDSHAKE_POLL_MS);
}
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, APLOGNO()
"Renegotiation loop %d iterations, "
+ "reneg_state=%d, "
"in_init=%d, init_finished=%d, "
"state=%s, sslconn->ssl=%s, peer_certs=%s",
- i, SSL_in_init(ssl), SSL_is_init_finished(ssl),
+ i, sslconn->reneg_state,
+ SSL_in_init(ssl), SSL_is_init_finished(ssl),
SSL_state_string_long(ssl),
sslconn->ssl != NULL ? "yes" : "no",
SSL_get_peer_certificate(ssl) != NULL ? "yes" : "no");
@@ -2142,6 +2146,18 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
}
#endif
}
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ else if ((where & SSL_CB_HANDSHAKE_START) && scr->reneg_state == RENEG_ALLOW) {
+ scr->reneg_state = RENEG_STARTED;
+ }
+ else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_STARTED) {
+ scr->reneg_state = RENEG_DONE;
+ }
+ else if ((where & SSL_CB_ALERT) &&
+ (scr->reneg_state == RENEG_ALLOW || scr->reneg_state == RENEG_STARTED)) {
+ scr->reneg_state = RENEG_ALERT;
+ }
+#endif
/* If the first handshake is complete, change state to reject any
* subsequent client-initiated renegotiation. */
else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_INIT) {
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index d70d625d13..967cf4c546 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -444,12 +444,17 @@ typedef struct {
* partial fix for CVE-2009-3555. */
enum {
RENEG_INIT = 0, /* Before initial handshake */
- RENEG_REJECT, /* After initial handshake; any client-initiated
- * renegotiation should be rejected */
- RENEG_ALLOW, /* A server-initiated renegotiation is taking
- * place (as dictated by configuration) */
- RENEG_ABORT /* Renegotiation initiated by client, abort the
- * connection */
+ RENEG_REJECT, /* After initial handshake; any client-initiated
+ * renegotiation should be rejected */
+ RENEG_ALLOW, /* A server-initiated renegotiation is taking
+ * place (as dictated by configuration) */
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ RENEG_STARTED, /* A renegotiation has started after RENEG_ALLOW */
+ RENEG_DONE, /* A renegotiation has finished after RENEG_STARTED */
+ RENEG_ALERT, /* A renegotiation has finished with an SSL Alert */
+#endif
+ RENEG_ABORT /* Renegotiation initiated by client, abort the
+ * connection */
} reneg_state;
server_rec *server;