comparison src/event/ngx_event_openssl.c @ 7653:8409f9df6219

SSL: client certificate validation with OCSP (ticket #1534). OCSP validation for client certificates is enabled by the "ssl_ocsp" directive. OCSP responder can be optionally specified by "ssl_ocsp_responder". When session is reused, peer chain is not available for validation. If the verified chain contains certificates from the peer chain not available at the server, validation will fail.
author Roman Arutyunyan <arut@nginx.com>
date Fri, 22 May 2020 17:30:12 +0300
parents f1720934c45b
children 699f6e55bbb4 7995cd199b52
comparison
equal deleted inserted replaced
7652:7cffd81015e7 7653:8409f9df6219
128 128
129 int ngx_ssl_connection_index; 129 int ngx_ssl_connection_index;
130 int ngx_ssl_server_conf_index; 130 int ngx_ssl_server_conf_index;
131 int ngx_ssl_session_cache_index; 131 int ngx_ssl_session_cache_index;
132 int ngx_ssl_session_ticket_keys_index; 132 int ngx_ssl_session_ticket_keys_index;
133 int ngx_ssl_ocsp_index;
133 int ngx_ssl_certificate_index; 134 int ngx_ssl_certificate_index;
134 int ngx_ssl_next_certificate_index; 135 int ngx_ssl_next_certificate_index;
135 int ngx_ssl_certificate_name_index; 136 int ngx_ssl_certificate_name_index;
136 int ngx_ssl_stapling_index; 137 int ngx_ssl_stapling_index;
137 138
206 } 207 }
207 208
208 ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, 209 ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
209 NULL, NULL); 210 NULL, NULL);
210 if (ngx_ssl_session_ticket_keys_index == -1) { 211 if (ngx_ssl_session_ticket_keys_index == -1) {
212 ngx_ssl_error(NGX_LOG_ALERT, log, 0,
213 "SSL_CTX_get_ex_new_index() failed");
214 return NGX_ERROR;
215 }
216
217 ngx_ssl_ocsp_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
218 if (ngx_ssl_ocsp_index == -1) {
211 ngx_ssl_error(NGX_LOG_ALERT, log, 0, 219 ngx_ssl_error(NGX_LOG_ALERT, log, 0,
212 "SSL_CTX_get_ex_new_index() failed"); 220 "SSL_CTX_get_ex_new_index() failed");
213 return NGX_ERROR; 221 return NGX_ERROR;
214 } 222 }
215 223
1592 ngx_int_t 1600 ngx_int_t
1593 ngx_ssl_handshake(ngx_connection_t *c) 1601 ngx_ssl_handshake(ngx_connection_t *c)
1594 { 1602 {
1595 int n, sslerr; 1603 int n, sslerr;
1596 ngx_err_t err; 1604 ngx_err_t err;
1605 ngx_int_t rc;
1597 1606
1598 #ifdef SSL_READ_EARLY_DATA_SUCCESS 1607 #ifdef SSL_READ_EARLY_DATA_SUCCESS
1599 if (c->ssl->try_early_data) { 1608 if (c->ssl->try_early_data) {
1600 return ngx_ssl_try_early_data(c); 1609 return ngx_ssl_try_early_data(c);
1601 } 1610 }
1602 #endif 1611 #endif
1603 1612
1613 if (c->ssl->in_ocsp) {
1614 return ngx_ssl_ocsp_validate(c);
1615 }
1616
1604 ngx_ssl_clear_error(c->log); 1617 ngx_ssl_clear_error(c->log);
1605 1618
1606 n = SSL_do_handshake(c->ssl->connection); 1619 n = SSL_do_handshake(c->ssl->connection);
1607 1620
1608 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); 1621 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
1618 } 1631 }
1619 1632
1620 #if (NGX_DEBUG) 1633 #if (NGX_DEBUG)
1621 ngx_ssl_handshake_log(c); 1634 ngx_ssl_handshake_log(c);
1622 #endif 1635 #endif
1623
1624 c->ssl->handshaked = 1;
1625 1636
1626 c->recv = ngx_ssl_recv; 1637 c->recv = ngx_ssl_recv;
1627 c->send = ngx_ssl_write; 1638 c->send = ngx_ssl_write;
1628 c->recv_chain = ngx_ssl_recv_chain; 1639 c->recv_chain = ngx_ssl_recv_chain;
1629 c->send_chain = ngx_ssl_send_chain; 1640 c->send_chain = ngx_ssl_send_chain;
1639 1650
1640 #endif 1651 #endif
1641 #endif 1652 #endif
1642 #endif 1653 #endif
1643 1654
1655 rc = ngx_ssl_ocsp_validate(c);
1656
1657 if (rc == NGX_ERROR) {
1658 return NGX_ERROR;
1659 }
1660
1661 if (rc == NGX_AGAIN) {
1662 c->read->handler = ngx_ssl_handshake_handler;
1663 c->write->handler = ngx_ssl_handshake_handler;
1664 return NGX_AGAIN;
1665 }
1666
1667 c->ssl->handshaked = 1;
1668
1644 return NGX_OK; 1669 return NGX_OK;
1645 } 1670 }
1646 1671
1647 sslerr = SSL_get_error(c->ssl->connection, n); 1672 sslerr = SSL_get_error(c->ssl->connection, n);
1648 1673
1708 { 1733 {
1709 int n, sslerr; 1734 int n, sslerr;
1710 u_char buf; 1735 u_char buf;
1711 size_t readbytes; 1736 size_t readbytes;
1712 ngx_err_t err; 1737 ngx_err_t err;
1738 ngx_int_t rc;
1713 1739
1714 ngx_ssl_clear_error(c->log); 1740 ngx_ssl_clear_error(c->log);
1715 1741
1716 readbytes = 0; 1742 readbytes = 0;
1717 1743
1742 c->ssl->try_early_data = 0; 1768 c->ssl->try_early_data = 0;
1743 1769
1744 c->ssl->early_buf = buf; 1770 c->ssl->early_buf = buf;
1745 c->ssl->early_preread = 1; 1771 c->ssl->early_preread = 1;
1746 1772
1747 c->ssl->handshaked = 1;
1748 c->ssl->in_early = 1; 1773 c->ssl->in_early = 1;
1749 1774
1750 c->recv = ngx_ssl_recv; 1775 c->recv = ngx_ssl_recv;
1751 c->send = ngx_ssl_write; 1776 c->send = ngx_ssl_write;
1752 c->recv_chain = ngx_ssl_recv_chain; 1777 c->recv_chain = ngx_ssl_recv_chain;
1753 c->send_chain = ngx_ssl_send_chain; 1778 c->send_chain = ngx_ssl_send_chain;
1779
1780 rc = ngx_ssl_ocsp_validate(c);
1781
1782 if (rc == NGX_ERROR) {
1783 return NGX_ERROR;
1784 }
1785
1786 if (rc == NGX_AGAIN) {
1787 c->read->handler = ngx_ssl_handshake_handler;
1788 c->write->handler = ngx_ssl_handshake_handler;
1789 return NGX_AGAIN;
1790 }
1791
1792 c->ssl->handshaked = 1;
1754 1793
1755 return NGX_OK; 1794 return NGX_OK;
1756 } 1795 }
1757 1796
1758 /* SSL_READ_EARLY_DATA_ERROR */ 1797 /* SSL_READ_EARLY_DATA_ERROR */
2732 ngx_int_t 2771 ngx_int_t
2733 ngx_ssl_shutdown(ngx_connection_t *c) 2772 ngx_ssl_shutdown(ngx_connection_t *c)
2734 { 2773 {
2735 int n, sslerr, mode; 2774 int n, sslerr, mode;
2736 ngx_err_t err; 2775 ngx_err_t err;
2776
2777 ngx_ssl_ocsp_cleanup(c);
2737 2778
2738 if (SSL_in_init(c->ssl->connection)) { 2779 if (SSL_in_init(c->ssl->connection)) {
2739 /* 2780 /*
2740 * OpenSSL 1.0.2f complains if SSL_shutdown() is called during 2781 * OpenSSL 1.0.2f complains if SSL_shutdown() is called during
2741 * an SSL handshake, while previous versions always return 0. 2782 * an SSL handshake, while previous versions always return 0.
4892 X509_free(cert); 4933 X509_free(cert);
4893 4934
4894 rc = SSL_get_verify_result(c->ssl->connection); 4935 rc = SSL_get_verify_result(c->ssl->connection);
4895 4936
4896 if (rc == X509_V_OK) { 4937 if (rc == X509_V_OK) {
4897 ngx_str_set(s, "SUCCESS"); 4938 if (ngx_ssl_ocsp_get_status(c, &str) == NGX_OK) {
4898 return NGX_OK; 4939 ngx_str_set(s, "SUCCESS");
4899 } 4940 return NGX_OK;
4900 4941 }
4901 str = X509_verify_cert_error_string(rc); 4942
4943 } else {
4944 str = X509_verify_cert_error_string(rc);
4945 }
4902 4946
4903 s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str)); 4947 s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str));
4904 if (s->data == NULL) { 4948 if (s->data == NULL) {
4905 return NGX_ERROR; 4949 return NGX_ERROR;
4906 } 4950 }