Mercurial > hg > nginx-ranges
comparison src/event/ngx_event_openssl.c @ 578:f3a9e57d2e17
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 11 Mar 2010 21:27:17 +0300 |
parents | da3c99095432 |
children | be4f34123024 |
comparison
equal
deleted
inserted
replaced
539:5f4de8cf0d9d | 578:f3a9e57d2e17 |
---|---|
13 ngx_uint_t engine; /* unsigned engine:1; */ | 13 ngx_uint_t engine; /* unsigned engine:1; */ |
14 } ngx_openssl_conf_t; | 14 } ngx_openssl_conf_t; |
15 | 15 |
16 | 16 |
17 static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); | 17 static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); |
18 static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, | |
19 int ret); | |
18 static void ngx_ssl_handshake_handler(ngx_event_t *ev); | 20 static void ngx_ssl_handshake_handler(ngx_event_t *ev); |
19 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); | 21 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); |
20 static void ngx_ssl_write_handler(ngx_event_t *wev); | 22 static void ngx_ssl_write_handler(ngx_event_t *wev); |
21 static void ngx_ssl_read_handler(ngx_event_t *rev); | 23 static void ngx_ssl_read_handler(ngx_event_t *rev); |
22 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); | 24 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); |
102 SSL_library_init(); | 104 SSL_library_init(); |
103 SSL_load_error_strings(); | 105 SSL_load_error_strings(); |
104 | 106 |
105 ENGINE_load_builtin_engines(); | 107 ENGINE_load_builtin_engines(); |
106 | 108 |
109 OpenSSL_add_all_algorithms(); | |
110 | |
107 ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); | 111 ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); |
108 | 112 |
109 if (ngx_ssl_connection_index == -1) { | 113 if (ngx_ssl_connection_index == -1) { |
110 ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed"); | 114 ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed"); |
111 return NGX_ERROR; | 115 return NGX_ERROR; |
172 if (ngx_ssl_protocols[protocols >> 1] != 0) { | 176 if (ngx_ssl_protocols[protocols >> 1] != 0) { |
173 SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]); | 177 SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]); |
174 } | 178 } |
175 | 179 |
176 SSL_CTX_set_read_ahead(ssl->ctx, 1); | 180 SSL_CTX_set_read_ahead(ssl->ctx, 1); |
181 | |
182 SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback); | |
177 | 183 |
178 return NGX_OK; | 184 return NGX_OK; |
179 } | 185 } |
180 | 186 |
181 | 187 |
345 OPENSSL_free(issuer); | 351 OPENSSL_free(issuer); |
346 } | 352 } |
347 #endif | 353 #endif |
348 | 354 |
349 return 1; | 355 return 1; |
356 } | |
357 | |
358 | |
359 static void | |
360 ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret) | |
361 { | |
362 ngx_connection_t *c; | |
363 | |
364 if (where & SSL_CB_HANDSHAKE_START) { | |
365 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
366 | |
367 if (c->ssl->handshaked) { | |
368 c->ssl->renegotiation = 1; | |
369 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation"); | |
370 } | |
371 } | |
350 } | 372 } |
351 | 373 |
352 | 374 |
353 ngx_int_t | 375 ngx_int_t |
354 ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl) | 376 ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl) |
585 c->recv = ngx_ssl_recv; | 607 c->recv = ngx_ssl_recv; |
586 c->send = ngx_ssl_write; | 608 c->send = ngx_ssl_write; |
587 c->recv_chain = ngx_ssl_recv_chain; | 609 c->recv_chain = ngx_ssl_recv_chain; |
588 c->send_chain = ngx_ssl_send_chain; | 610 c->send_chain = ngx_ssl_send_chain; |
589 | 611 |
612 /* initial handshake done, disable renegotiation (CVE-2009-3555) */ | |
613 if (c->ssl->connection->s3) { | |
614 c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; | |
615 } | |
616 | |
590 return NGX_OK; | 617 return NGX_OK; |
591 } | 618 } |
592 | 619 |
593 sslerr = SSL_get_error(c->ssl->connection, n); | 620 sslerr = SSL_get_error(c->ssl->connection, n); |
594 | 621 |
786 static ngx_int_t | 813 static ngx_int_t |
787 ngx_ssl_handle_recv(ngx_connection_t *c, int n) | 814 ngx_ssl_handle_recv(ngx_connection_t *c, int n) |
788 { | 815 { |
789 int sslerr; | 816 int sslerr; |
790 ngx_err_t err; | 817 ngx_err_t err; |
818 | |
819 if (c->ssl->renegotiation) { | |
820 /* | |
821 * disable renegotiation (CVE-2009-3555): | |
822 * OpenSSL (at least up to 0.9.8l) does not handle disabled | |
823 * renegotiation gracefully, so drop connection here | |
824 */ | |
825 | |
826 ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled"); | |
827 | |
828 c->ssl->no_wait_shutdown = 1; | |
829 c->ssl->no_send_shutdown = 1; | |
830 | |
831 return NGX_ERROR; | |
832 } | |
791 | 833 |
792 if (n > 0) { | 834 if (n > 0) { |
793 | 835 |
794 if (c->ssl->saved_write_handler) { | 836 if (c->ssl->saved_write_handler) { |
795 | 837 |
944 send = 0; | 986 send = 0; |
945 flush = (in == NULL) ? 1 : 0; | 987 flush = (in == NULL) ? 1 : 0; |
946 | 988 |
947 for ( ;; ) { | 989 for ( ;; ) { |
948 | 990 |
949 while (in && buf->last < buf->end) { | 991 while (in && buf->last < buf->end && send < limit) { |
950 if (in->buf->last_buf || in->buf->flush) { | 992 if (in->buf->last_buf || in->buf->flush) { |
951 flush = 1; | 993 flush = 1; |
952 } | 994 } |
953 | 995 |
954 if (ngx_buf_special(in->buf)) { | 996 if (ngx_buf_special(in->buf)) { |
971 "SSL buf copy: %d", size); | 1013 "SSL buf copy: %d", size); |
972 | 1014 |
973 ngx_memcpy(buf->last, in->buf->pos, size); | 1015 ngx_memcpy(buf->last, in->buf->pos, size); |
974 | 1016 |
975 buf->last += size; | 1017 buf->last += size; |
976 | |
977 in->buf->pos += size; | 1018 in->buf->pos += size; |
1019 send += size; | |
978 | 1020 |
979 if (in->buf->pos == in->buf->last) { | 1021 if (in->buf->pos == in->buf->last) { |
980 in = in->next; | 1022 in = in->next; |
981 } | 1023 } |
982 } | 1024 } |
997 c->buffered |= NGX_SSL_BUFFERED; | 1039 c->buffered |= NGX_SSL_BUFFERED; |
998 return in; | 1040 return in; |
999 } | 1041 } |
1000 | 1042 |
1001 buf->pos += n; | 1043 buf->pos += n; |
1002 send += n; | |
1003 c->sent += n; | 1044 c->sent += n; |
1004 | 1045 |
1005 if (n < size) { | 1046 if (n < size) { |
1006 break; | 1047 break; |
1007 } | 1048 } |
1267 | 1308 |
1268 n = ERR_GET_REASON(ERR_peek_error()); | 1309 n = ERR_GET_REASON(ERR_peek_error()); |
1269 | 1310 |
1270 /* handshake failures */ | 1311 /* handshake failures */ |
1271 if (n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ | 1312 if (n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ |
1313 || n == SSL_R_LENGTH_MISMATCH /* 159 */ | |
1272 || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ | 1314 || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ |
1315 || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ | |
1273 || n == SSL_R_NO_SHARED_CIPHER /* 193 */ | 1316 || n == SSL_R_NO_SHARED_CIPHER /* 193 */ |
1317 || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ | |
1274 || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */ | 1318 || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */ |
1275 || n == SSL_R_UNEXPECTED_RECORD /* 245 */ | 1319 || n == SSL_R_UNEXPECTED_RECORD /* 245 */ |
1320 || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */ | |
1321 || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */ | |
1276 || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */ | 1322 || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */ |
1277 || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */ | 1323 || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */ |
1278 || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ | 1324 || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ |
1279 || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */ | 1325 || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */ |
1280 || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */ | 1326 || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */ |
1382 if (builtin_session_cache == NGX_SSL_NO_SCACHE) { | 1428 if (builtin_session_cache == NGX_SSL_NO_SCACHE) { |
1383 SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF); | 1429 SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF); |
1384 return NGX_OK; | 1430 return NGX_OK; |
1385 } | 1431 } |
1386 | 1432 |
1433 SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len); | |
1434 | |
1387 if (builtin_session_cache == NGX_SSL_NONE_SCACHE) { | 1435 if (builtin_session_cache == NGX_SSL_NONE_SCACHE) { |
1388 | 1436 |
1389 /* | 1437 /* |
1390 * If the server explicitly says that it does not support | 1438 * If the server explicitly says that it does not support |
1391 * session reuse (see SSL_SESS_CACHE_OFF above), then | 1439 * session reuse (see SSL_SESS_CACHE_OFF above), then |
1412 if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) { | 1460 if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) { |
1413 cache_mode |= SSL_SESS_CACHE_NO_INTERNAL; | 1461 cache_mode |= SSL_SESS_CACHE_NO_INTERNAL; |
1414 } | 1462 } |
1415 | 1463 |
1416 SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode); | 1464 SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode); |
1417 | |
1418 SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len); | |
1419 | 1465 |
1420 if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) { | 1466 if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) { |
1421 | 1467 |
1422 if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) { | 1468 if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) { |
1423 SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache); | 1469 SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache); |
1586 ngx_memcpy(id, sess->session_id, sess->session_id_length); | 1632 ngx_memcpy(id, sess->session_id, sess->session_id_length); |
1587 | 1633 |
1588 hash = ngx_crc32_short(sess->session_id, sess->session_id_length); | 1634 hash = ngx_crc32_short(sess->session_id, sess->session_id_length); |
1589 | 1635 |
1590 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | 1636 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1591 "http ssl new session: %08XD:%d:%d", | 1637 "ssl new session: %08XD:%d:%d", |
1592 hash, sess->session_id_length, len); | 1638 hash, sess->session_id_length, len); |
1593 | 1639 |
1594 sess_id->node.key = hash; | 1640 sess_id->node.key = hash; |
1595 sess_id->node.data = (u_char) sess->session_id_length; | 1641 sess_id->node.data = (u_char) sess->session_id_length; |
1596 sess_id->id = id; | 1642 sess_id->id = id; |
1649 | 1695 |
1650 hash = ngx_crc32_short(id, (size_t) len); | 1696 hash = ngx_crc32_short(id, (size_t) len); |
1651 *copy = 0; | 1697 *copy = 0; |
1652 | 1698 |
1653 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 1699 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1654 "http ssl get session: %08XD:%d", hash, len); | 1700 "ssl get session: %08XD:%d", hash, len); |
1655 | 1701 |
1656 shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn), | 1702 shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn), |
1657 ngx_ssl_session_cache_index); | 1703 ngx_ssl_session_cache_index); |
1658 | 1704 |
1659 cache = shm_zone->data; | 1705 cache = shm_zone->data; |
1763 len = (size_t) sess->session_id_length; | 1809 len = (size_t) sess->session_id_length; |
1764 | 1810 |
1765 hash = ngx_crc32_short(id, len); | 1811 hash = ngx_crc32_short(id, len); |
1766 | 1812 |
1767 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, | 1813 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, |
1768 "http ssl remove session: %08XD:%uz", hash, len); | 1814 "ssl remove session: %08XD:%uz", hash, len); |
1769 | 1815 |
1770 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | 1816 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
1771 | 1817 |
1772 ngx_shmtx_lock(&shpool->mutex); | 1818 ngx_shmtx_lock(&shpool->mutex); |
1773 | 1819 |
1927 return NGX_OK; | 1973 return NGX_OK; |
1928 } | 1974 } |
1929 | 1975 |
1930 | 1976 |
1931 ngx_int_t | 1977 ngx_int_t |
1978 ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) | |
1979 { | |
1980 int len; | |
1981 u_char *p, *buf; | |
1982 SSL_SESSION *sess; | |
1983 | |
1984 sess = SSL_get0_session(c->ssl->connection); | |
1985 | |
1986 len = i2d_SSL_SESSION(sess, NULL); | |
1987 | |
1988 buf = ngx_alloc(len, c->log); | |
1989 if (buf == NULL) { | |
1990 return NGX_ERROR; | |
1991 } | |
1992 | |
1993 s->len = 2 * len; | |
1994 s->data = ngx_pnalloc(pool, 2 * len); | |
1995 if (s->data == NULL) { | |
1996 ngx_free(buf); | |
1997 return NGX_ERROR; | |
1998 } | |
1999 | |
2000 p = buf; | |
2001 i2d_SSL_SESSION(sess, &p); | |
2002 | |
2003 ngx_hex_dump(s->data, buf, len); | |
2004 | |
2005 ngx_free(buf); | |
2006 | |
2007 return NGX_OK; | |
2008 } | |
2009 | |
2010 | |
2011 ngx_int_t | |
1932 ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) | 2012 ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) |
1933 { | 2013 { |
1934 size_t len; | 2014 size_t len; |
1935 BIO *bio; | 2015 BIO *bio; |
1936 X509 *cert; | 2016 X509 *cert; |
2235 | 2315 |
2236 | 2316 |
2237 static void | 2317 static void |
2238 ngx_openssl_exit(ngx_cycle_t *cycle) | 2318 ngx_openssl_exit(ngx_cycle_t *cycle) |
2239 { | 2319 { |
2320 EVP_cleanup(); | |
2240 ENGINE_cleanup(); | 2321 ENGINE_cleanup(); |
2241 } | 2322 } |