Mercurial > hg > nginx
comparison src/event/ngx_event_openssl.c @ 7357:548a63b354a2
SSL: support for TLSv1.3 early data with OpenSSL.
In collaboration with Maxim Dounin.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Fri, 21 Sep 2018 20:49:12 +0300 |
parents | e3ba4026c02d |
children | 8f25a44d9add |
comparison
equal
deleted
inserted
replaced
7356:e3ba4026c02d | 7357:548a63b354a2 |
---|---|
24 static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, | 24 static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, |
25 int ret); | 25 int ret); |
26 static void ngx_ssl_passwords_cleanup(void *data); | 26 static void ngx_ssl_passwords_cleanup(void *data); |
27 static int ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, | 27 static int ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, |
28 ngx_ssl_session_t *sess); | 28 ngx_ssl_session_t *sess); |
29 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
30 static ngx_int_t ngx_ssl_try_early_data(ngx_connection_t *c); | |
31 #endif | |
32 #if (NGX_DEBUG) | |
33 static void ngx_ssl_handshake_log(ngx_connection_t *c); | |
34 #endif | |
29 static void ngx_ssl_handshake_handler(ngx_event_t *ev); | 35 static void ngx_ssl_handshake_handler(ngx_event_t *ev); |
36 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
37 static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, | |
38 size_t size); | |
39 #endif | |
30 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); | 40 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); |
31 static void ngx_ssl_write_handler(ngx_event_t *wev); | 41 static void ngx_ssl_write_handler(ngx_event_t *wev); |
42 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
43 static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data, | |
44 size_t size); | |
45 #endif | |
32 static void ngx_ssl_read_handler(ngx_event_t *rev); | 46 static void ngx_ssl_read_handler(ngx_event_t *rev); |
33 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); | 47 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); |
34 static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, | 48 static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, |
35 ngx_err_t err, char *text); | 49 ngx_err_t err, char *text); |
36 static void ngx_ssl_clear_error(ngx_log_t *log); | 50 static void ngx_ssl_clear_error(ngx_log_t *log); |
338 | 352 |
339 #ifdef SSL_OP_NO_COMPRESSION | 353 #ifdef SSL_OP_NO_COMPRESSION |
340 SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION); | 354 SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION); |
341 #endif | 355 #endif |
342 | 356 |
357 #ifdef SSL_OP_NO_ANTI_REPLAY | |
358 SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY); | |
359 #endif | |
360 | |
343 #ifdef SSL_MODE_RELEASE_BUFFERS | 361 #ifdef SSL_MODE_RELEASE_BUFFERS |
344 SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS); | 362 SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS); |
345 #endif | 363 #endif |
346 | 364 |
347 #ifdef SSL_MODE_NO_AUTO_CHAIN | 365 #ifdef SSL_MODE_NO_AUTO_CHAIN |
1183 | 1201 |
1184 /* BoringSSL */ | 1202 /* BoringSSL */ |
1185 | 1203 |
1186 SSL_CTX_set_early_data_enabled(ssl->ctx, 1); | 1204 SSL_CTX_set_early_data_enabled(ssl->ctx, 1); |
1187 | 1205 |
1206 #elif defined SSL_READ_EARLY_DATA_SUCCESS | |
1207 | |
1208 /* OpenSSL */ | |
1209 | |
1210 SSL_CTX_set_max_early_data(ssl->ctx, NGX_SSL_BUFSIZE); | |
1211 | |
1188 #else | 1212 #else |
1189 ngx_log_error(NGX_LOG_WARN, ssl->log, 0, | 1213 ngx_log_error(NGX_LOG_WARN, ssl->log, 0, |
1190 "\"ssl_early_data\" is not supported on this platform, " | 1214 "\"ssl_early_data\" is not supported on this platform, " |
1191 "ignored"); | 1215 "ignored"); |
1192 #endif | 1216 #endif |
1244 sc->buffer = ((flags & NGX_SSL_BUFFER) != 0); | 1268 sc->buffer = ((flags & NGX_SSL_BUFFER) != 0); |
1245 sc->buffer_size = ssl->buffer_size; | 1269 sc->buffer_size = ssl->buffer_size; |
1246 | 1270 |
1247 sc->session_ctx = ssl->ctx; | 1271 sc->session_ctx = ssl->ctx; |
1248 | 1272 |
1273 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
1274 if (SSL_CTX_get_max_early_data(ssl->ctx)) { | |
1275 sc->try_early_data = 1; | |
1276 } | |
1277 #endif | |
1278 | |
1249 sc->connection = SSL_new(ssl->ctx); | 1279 sc->connection = SSL_new(ssl->ctx); |
1250 | 1280 |
1251 if (sc->connection == NULL) { | 1281 if (sc->connection == NULL) { |
1252 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); | 1282 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); |
1253 return NGX_ERROR; | 1283 return NGX_ERROR; |
1323 ngx_ssl_handshake(ngx_connection_t *c) | 1353 ngx_ssl_handshake(ngx_connection_t *c) |
1324 { | 1354 { |
1325 int n, sslerr; | 1355 int n, sslerr; |
1326 ngx_err_t err; | 1356 ngx_err_t err; |
1327 | 1357 |
1358 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
1359 if (c->ssl->try_early_data) { | |
1360 return ngx_ssl_try_early_data(c); | |
1361 } | |
1362 #endif | |
1363 | |
1328 ngx_ssl_clear_error(c->log); | 1364 ngx_ssl_clear_error(c->log); |
1329 | 1365 |
1330 n = SSL_do_handshake(c->ssl->connection); | 1366 n = SSL_do_handshake(c->ssl->connection); |
1331 | 1367 |
1332 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | 1368 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); |
1340 if (ngx_handle_write_event(c->write, 0) != NGX_OK) { | 1376 if (ngx_handle_write_event(c->write, 0) != NGX_OK) { |
1341 return NGX_ERROR; | 1377 return NGX_ERROR; |
1342 } | 1378 } |
1343 | 1379 |
1344 #if (NGX_DEBUG) | 1380 #if (NGX_DEBUG) |
1345 { | 1381 ngx_ssl_handshake_log(c); |
1346 char buf[129], *s, *d; | |
1347 #if OPENSSL_VERSION_NUMBER >= 0x10000000L | |
1348 const | |
1349 #endif | |
1350 SSL_CIPHER *cipher; | |
1351 | |
1352 cipher = SSL_get_current_cipher(c->ssl->connection); | |
1353 | |
1354 if (cipher) { | |
1355 SSL_CIPHER_description(cipher, &buf[1], 128); | |
1356 | |
1357 for (s = &buf[1], d = buf; *s; s++) { | |
1358 if (*s == ' ' && *d == ' ') { | |
1359 continue; | |
1360 } | |
1361 | |
1362 if (*s == LF || *s == CR) { | |
1363 continue; | |
1364 } | |
1365 | |
1366 *++d = *s; | |
1367 } | |
1368 | |
1369 if (*d != ' ') { | |
1370 d++; | |
1371 } | |
1372 | |
1373 *d = '\0'; | |
1374 | |
1375 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1376 "SSL: %s, cipher: \"%s\"", | |
1377 SSL_get_version(c->ssl->connection), &buf[1]); | |
1378 | |
1379 if (SSL_session_reused(c->ssl->connection)) { | |
1380 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1381 "SSL reused session"); | |
1382 } | |
1383 | |
1384 } else { | |
1385 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1386 "SSL no shared ciphers"); | |
1387 } | |
1388 } | |
1389 #endif | 1382 #endif |
1390 | 1383 |
1391 c->ssl->handshaked = 1; | 1384 c->ssl->handshaked = 1; |
1392 | 1385 |
1393 c->recv = ngx_ssl_recv; | 1386 c->recv = ngx_ssl_recv; |
1466 | 1459 |
1467 return NGX_ERROR; | 1460 return NGX_ERROR; |
1468 } | 1461 } |
1469 | 1462 |
1470 | 1463 |
1464 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
1465 | |
1466 static ngx_int_t | |
1467 ngx_ssl_try_early_data(ngx_connection_t *c) | |
1468 { | |
1469 int n, sslerr; | |
1470 u_char buf; | |
1471 size_t readbytes; | |
1472 ngx_err_t err; | |
1473 | |
1474 ngx_ssl_clear_error(c->log); | |
1475 | |
1476 readbytes = 0; | |
1477 | |
1478 n = SSL_read_early_data(c->ssl->connection, &buf, 1, &readbytes); | |
1479 | |
1480 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1481 "SSL_read_early_data: %d, %uz", n, readbytes); | |
1482 | |
1483 if (n == SSL_READ_EARLY_DATA_FINISH) { | |
1484 c->ssl->try_early_data = 0; | |
1485 return ngx_ssl_handshake(c); | |
1486 } | |
1487 | |
1488 if (n == SSL_READ_EARLY_DATA_SUCCESS) { | |
1489 | |
1490 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | |
1491 return NGX_ERROR; | |
1492 } | |
1493 | |
1494 if (ngx_handle_write_event(c->write, 0) != NGX_OK) { | |
1495 return NGX_ERROR; | |
1496 } | |
1497 | |
1498 #if (NGX_DEBUG) | |
1499 ngx_ssl_handshake_log(c); | |
1500 #endif | |
1501 | |
1502 c->ssl->try_early_data = 0; | |
1503 | |
1504 c->ssl->early_buf = buf; | |
1505 c->ssl->early_preread = 1; | |
1506 | |
1507 c->ssl->handshaked = 1; | |
1508 c->ssl->in_early = 1; | |
1509 | |
1510 c->recv = ngx_ssl_recv; | |
1511 c->send = ngx_ssl_write; | |
1512 c->recv_chain = ngx_ssl_recv_chain; | |
1513 c->send_chain = ngx_ssl_send_chain; | |
1514 | |
1515 return NGX_OK; | |
1516 } | |
1517 | |
1518 /* SSL_READ_EARLY_DATA_ERROR */ | |
1519 | |
1520 sslerr = SSL_get_error(c->ssl->connection, n); | |
1521 | |
1522 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); | |
1523 | |
1524 if (sslerr == SSL_ERROR_WANT_READ) { | |
1525 c->read->ready = 0; | |
1526 c->read->handler = ngx_ssl_handshake_handler; | |
1527 c->write->handler = ngx_ssl_handshake_handler; | |
1528 | |
1529 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | |
1530 return NGX_ERROR; | |
1531 } | |
1532 | |
1533 if (ngx_handle_write_event(c->write, 0) != NGX_OK) { | |
1534 return NGX_ERROR; | |
1535 } | |
1536 | |
1537 return NGX_AGAIN; | |
1538 } | |
1539 | |
1540 if (sslerr == SSL_ERROR_WANT_WRITE) { | |
1541 c->write->ready = 0; | |
1542 c->read->handler = ngx_ssl_handshake_handler; | |
1543 c->write->handler = ngx_ssl_handshake_handler; | |
1544 | |
1545 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | |
1546 return NGX_ERROR; | |
1547 } | |
1548 | |
1549 if (ngx_handle_write_event(c->write, 0) != NGX_OK) { | |
1550 return NGX_ERROR; | |
1551 } | |
1552 | |
1553 return NGX_AGAIN; | |
1554 } | |
1555 | |
1556 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; | |
1557 | |
1558 c->ssl->no_wait_shutdown = 1; | |
1559 c->ssl->no_send_shutdown = 1; | |
1560 c->read->eof = 1; | |
1561 | |
1562 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { | |
1563 ngx_connection_error(c, err, | |
1564 "peer closed connection in SSL handshake"); | |
1565 | |
1566 return NGX_ERROR; | |
1567 } | |
1568 | |
1569 c->read->error = 1; | |
1570 | |
1571 ngx_ssl_connection_error(c, sslerr, err, "SSL_read_early_data() failed"); | |
1572 | |
1573 return NGX_ERROR; | |
1574 } | |
1575 | |
1576 #endif | |
1577 | |
1578 | |
1579 #if (NGX_DEBUG) | |
1580 | |
1581 static void | |
1582 ngx_ssl_handshake_log(ngx_connection_t *c) | |
1583 { | |
1584 char buf[129], *s, *d; | |
1585 #if OPENSSL_VERSION_NUMBER >= 0x10000000L | |
1586 const | |
1587 #endif | |
1588 SSL_CIPHER *cipher; | |
1589 | |
1590 cipher = SSL_get_current_cipher(c->ssl->connection); | |
1591 | |
1592 if (cipher) { | |
1593 SSL_CIPHER_description(cipher, &buf[1], 128); | |
1594 | |
1595 for (s = &buf[1], d = buf; *s; s++) { | |
1596 if (*s == ' ' && *d == ' ') { | |
1597 continue; | |
1598 } | |
1599 | |
1600 if (*s == LF || *s == CR) { | |
1601 continue; | |
1602 } | |
1603 | |
1604 *++d = *s; | |
1605 } | |
1606 | |
1607 if (*d != ' ') { | |
1608 d++; | |
1609 } | |
1610 | |
1611 *d = '\0'; | |
1612 | |
1613 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1614 "SSL: %s, cipher: \"%s\"", | |
1615 SSL_get_version(c->ssl->connection), &buf[1]); | |
1616 | |
1617 if (SSL_session_reused(c->ssl->connection)) { | |
1618 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1619 "SSL reused session"); | |
1620 } | |
1621 | |
1622 } else { | |
1623 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1624 "SSL no shared ciphers"); | |
1625 } | |
1626 } | |
1627 | |
1628 #endif | |
1629 | |
1630 | |
1471 static void | 1631 static void |
1472 ngx_ssl_handshake_handler(ngx_event_t *ev) | 1632 ngx_ssl_handshake_handler(ngx_event_t *ev) |
1473 { | 1633 { |
1474 ngx_connection_t *c; | 1634 ngx_connection_t *c; |
1475 | 1635 |
1553 ssize_t | 1713 ssize_t |
1554 ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) | 1714 ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) |
1555 { | 1715 { |
1556 int n, bytes; | 1716 int n, bytes; |
1557 | 1717 |
1718 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
1719 if (c->ssl->in_early) { | |
1720 return ngx_ssl_recv_early(c, buf, size); | |
1721 } | |
1722 #endif | |
1723 | |
1558 if (c->ssl->last == NGX_ERROR) { | 1724 if (c->ssl->last == NGX_ERROR) { |
1559 c->read->error = 1; | 1725 c->read->error = 1; |
1560 return NGX_ERROR; | 1726 return NGX_ERROR; |
1561 } | 1727 } |
1562 | 1728 |
1624 case NGX_AGAIN: | 1790 case NGX_AGAIN: |
1625 return c->ssl->last; | 1791 return c->ssl->last; |
1626 } | 1792 } |
1627 } | 1793 } |
1628 } | 1794 } |
1795 | |
1796 | |
1797 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
1798 | |
1799 static ssize_t | |
1800 ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, size_t size) | |
1801 { | |
1802 int n, bytes; | |
1803 size_t readbytes; | |
1804 | |
1805 if (c->ssl->last == NGX_ERROR) { | |
1806 c->read->error = 1; | |
1807 return NGX_ERROR; | |
1808 } | |
1809 | |
1810 if (c->ssl->last == NGX_DONE) { | |
1811 c->read->ready = 0; | |
1812 c->read->eof = 1; | |
1813 return 0; | |
1814 } | |
1815 | |
1816 bytes = 0; | |
1817 | |
1818 ngx_ssl_clear_error(c->log); | |
1819 | |
1820 if (c->ssl->early_preread) { | |
1821 | |
1822 if (size == 0) { | |
1823 c->read->ready = 0; | |
1824 c->read->eof = 1; | |
1825 return 0; | |
1826 } | |
1827 | |
1828 *buf = c->ssl->early_buf; | |
1829 | |
1830 c->ssl->early_preread = 0; | |
1831 | |
1832 bytes = 1; | |
1833 size -= 1; | |
1834 buf += 1; | |
1835 } | |
1836 | |
1837 /* | |
1838 * SSL_read_early_data() may return data in parts, so try to read | |
1839 * until SSL_read_early_data() would return no data | |
1840 */ | |
1841 | |
1842 for ( ;; ) { | |
1843 | |
1844 readbytes = 0; | |
1845 | |
1846 n = SSL_read_early_data(c->ssl->connection, buf, size, &readbytes); | |
1847 | |
1848 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1849 "SSL_read_early_data: %d, %uz", n, readbytes); | |
1850 | |
1851 if (n == SSL_READ_EARLY_DATA_SUCCESS) { | |
1852 | |
1853 c->ssl->last = ngx_ssl_handle_recv(c, 1); | |
1854 | |
1855 bytes += readbytes; | |
1856 size -= readbytes; | |
1857 | |
1858 if (size == 0) { | |
1859 c->read->ready = 1; | |
1860 return bytes; | |
1861 } | |
1862 | |
1863 buf += readbytes; | |
1864 | |
1865 continue; | |
1866 } | |
1867 | |
1868 if (n == SSL_READ_EARLY_DATA_FINISH) { | |
1869 | |
1870 c->ssl->last = ngx_ssl_handle_recv(c, 1); | |
1871 c->ssl->in_early = 0; | |
1872 | |
1873 if (bytes) { | |
1874 c->read->ready = 1; | |
1875 return bytes; | |
1876 } | |
1877 | |
1878 return ngx_ssl_recv(c, buf, size); | |
1879 } | |
1880 | |
1881 /* SSL_READ_EARLY_DATA_ERROR */ | |
1882 | |
1883 c->ssl->last = ngx_ssl_handle_recv(c, 0); | |
1884 | |
1885 if (bytes) { | |
1886 if (c->ssl->last != NGX_AGAIN) { | |
1887 c->read->ready = 1; | |
1888 } | |
1889 | |
1890 return bytes; | |
1891 } | |
1892 | |
1893 switch (c->ssl->last) { | |
1894 | |
1895 case NGX_DONE: | |
1896 c->read->ready = 0; | |
1897 c->read->eof = 1; | |
1898 return 0; | |
1899 | |
1900 case NGX_ERROR: | |
1901 c->read->error = 1; | |
1902 | |
1903 /* fall through */ | |
1904 | |
1905 case NGX_AGAIN: | |
1906 return c->ssl->last; | |
1907 } | |
1908 } | |
1909 } | |
1910 | |
1911 #endif | |
1629 | 1912 |
1630 | 1913 |
1631 static ngx_int_t | 1914 static ngx_int_t |
1632 ngx_ssl_handle_recv(ngx_connection_t *c, int n) | 1915 ngx_ssl_handle_recv(ngx_connection_t *c, int n) |
1633 { | 1916 { |
1921 ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) | 2204 ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) |
1922 { | 2205 { |
1923 int n, sslerr; | 2206 int n, sslerr; |
1924 ngx_err_t err; | 2207 ngx_err_t err; |
1925 | 2208 |
2209 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
2210 if (c->ssl->in_early) { | |
2211 return ngx_ssl_write_early(c, data, size); | |
2212 } | |
2213 #endif | |
2214 | |
1926 ngx_ssl_clear_error(c->log); | 2215 ngx_ssl_clear_error(c->log); |
1927 | 2216 |
1928 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size); | 2217 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size); |
1929 | 2218 |
1930 n = SSL_write(c->ssl->connection, data, size); | 2219 n = SSL_write(c->ssl->connection, data, size); |
2006 | 2295 |
2007 ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed"); | 2296 ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed"); |
2008 | 2297 |
2009 return NGX_ERROR; | 2298 return NGX_ERROR; |
2010 } | 2299 } |
2300 | |
2301 | |
2302 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
2303 | |
2304 ssize_t | |
2305 ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size) | |
2306 { | |
2307 int n, sslerr; | |
2308 size_t written; | |
2309 ngx_err_t err; | |
2310 | |
2311 ngx_ssl_clear_error(c->log); | |
2312 | |
2313 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size); | |
2314 | |
2315 written = 0; | |
2316 | |
2317 n = SSL_write_early_data(c->ssl->connection, data, size, &written); | |
2318 | |
2319 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
2320 "SSL_write_early_data: %d, %uz", n, written); | |
2321 | |
2322 if (n > 0) { | |
2323 | |
2324 if (c->ssl->saved_read_handler) { | |
2325 | |
2326 c->read->handler = c->ssl->saved_read_handler; | |
2327 c->ssl->saved_read_handler = NULL; | |
2328 c->read->ready = 1; | |
2329 | |
2330 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | |
2331 return NGX_ERROR; | |
2332 } | |
2333 | |
2334 ngx_post_event(c->read, &ngx_posted_events); | |
2335 } | |
2336 | |
2337 c->sent += written; | |
2338 | |
2339 return written; | |
2340 } | |
2341 | |
2342 sslerr = SSL_get_error(c->ssl->connection, n); | |
2343 | |
2344 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; | |
2345 | |
2346 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); | |
2347 | |
2348 if (sslerr == SSL_ERROR_WANT_WRITE) { | |
2349 | |
2350 if (c->ssl->saved_read_handler) { | |
2351 | |
2352 c->read->handler = c->ssl->saved_read_handler; | |
2353 c->ssl->saved_read_handler = NULL; | |
2354 c->read->ready = 1; | |
2355 | |
2356 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | |
2357 return NGX_ERROR; | |
2358 } | |
2359 | |
2360 ngx_post_event(c->read, &ngx_posted_events); | |
2361 } | |
2362 | |
2363 c->write->ready = 0; | |
2364 return NGX_AGAIN; | |
2365 } | |
2366 | |
2367 if (sslerr == SSL_ERROR_WANT_READ) { | |
2368 | |
2369 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
2370 "SSL_write_early_data: want read"); | |
2371 | |
2372 c->read->ready = 0; | |
2373 | |
2374 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | |
2375 return NGX_ERROR; | |
2376 } | |
2377 | |
2378 /* | |
2379 * we do not set the timer because there is already | |
2380 * the write event timer | |
2381 */ | |
2382 | |
2383 if (c->ssl->saved_read_handler == NULL) { | |
2384 c->ssl->saved_read_handler = c->read->handler; | |
2385 c->read->handler = ngx_ssl_read_handler; | |
2386 } | |
2387 | |
2388 return NGX_AGAIN; | |
2389 } | |
2390 | |
2391 c->ssl->no_wait_shutdown = 1; | |
2392 c->ssl->no_send_shutdown = 1; | |
2393 c->write->error = 1; | |
2394 | |
2395 ngx_ssl_connection_error(c, sslerr, err, "SSL_write_early_data() failed"); | |
2396 | |
2397 return NGX_ERROR; | |
2398 } | |
2399 | |
2400 #endif | |
2011 | 2401 |
2012 | 2402 |
2013 static void | 2403 static void |
2014 ngx_ssl_read_handler(ngx_event_t *rev) | 2404 ngx_ssl_read_handler(ngx_event_t *rev) |
2015 { | 2405 { |
3692 ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) | 4082 ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) |
3693 { | 4083 { |
3694 s->len = 0; | 4084 s->len = 0; |
3695 | 4085 |
3696 #ifdef SSL_ERROR_EARLY_DATA_REJECTED | 4086 #ifdef SSL_ERROR_EARLY_DATA_REJECTED |
4087 | |
4088 /* BoringSSL */ | |
4089 | |
3697 if (SSL_in_early_data(c->ssl->connection)) { | 4090 if (SSL_in_early_data(c->ssl->connection)) { |
3698 ngx_str_set(s, "1"); | 4091 ngx_str_set(s, "1"); |
3699 } | 4092 } |
4093 | |
4094 #elif defined SSL_READ_EARLY_DATA_SUCCESS | |
4095 | |
4096 /* OpenSSL */ | |
4097 | |
4098 if (!SSL_is_init_finished(c->ssl->connection)) { | |
4099 ngx_str_set(s, "1"); | |
4100 } | |
4101 | |
3700 #endif | 4102 #endif |
3701 | 4103 |
3702 return NGX_OK; | 4104 return NGX_OK; |
3703 } | 4105 } |
3704 | 4106 |