comparison src/event/ngx_event_openssl.c @ 7431:294162223c7c

SSL: avoid reading on pending SSL_write_early_data(). If SSL_write_early_data() returned SSL_ERROR_WANT_WRITE, stop further reading using a newly introduced c->ssl->write_blocked flag, as otherwise this would result in SSL error "ssl3_write_bytes:bad length". Eventually, normal reading will be restored by read event posted from successful SSL_write_early_data(). While here, place "SSL_write_early_data: want write" debug on the path.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 18 Dec 2018 15:15:15 +0300
parents 9ca82f273967
children 873150addfeb
comparison
equal deleted inserted replaced
7430:286ae954009d 7431:294162223c7c
1837 bytes = 1; 1837 bytes = 1;
1838 size -= 1; 1838 size -= 1;
1839 buf += 1; 1839 buf += 1;
1840 } 1840 }
1841 1841
1842 if (c->ssl->write_blocked) {
1843 return NGX_AGAIN;
1844 }
1845
1842 /* 1846 /*
1843 * SSL_read_early_data() may return data in parts, so try to read 1847 * SSL_read_early_data() may return data in parts, so try to read
1844 * until SSL_read_early_data() would return no data 1848 * until SSL_read_early_data() would return no data
1845 */ 1849 */
1846 1850
2337 } 2341 }
2338 2342
2339 ngx_post_event(c->read, &ngx_posted_events); 2343 ngx_post_event(c->read, &ngx_posted_events);
2340 } 2344 }
2341 2345
2346 if (c->ssl->write_blocked) {
2347 c->ssl->write_blocked = 0;
2348 ngx_post_event(c->read, &ngx_posted_events);
2349 }
2350
2342 c->sent += written; 2351 c->sent += written;
2343 2352
2344 return written; 2353 return written;
2345 } 2354 }
2346 2355
2349 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; 2358 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
2350 2359
2351 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); 2360 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
2352 2361
2353 if (sslerr == SSL_ERROR_WANT_WRITE) { 2362 if (sslerr == SSL_ERROR_WANT_WRITE) {
2363
2364 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
2365 "SSL_write_early_data: want write");
2354 2366
2355 if (c->ssl->saved_read_handler) { 2367 if (c->ssl->saved_read_handler) {
2356 2368
2357 c->read->handler = c->ssl->saved_read_handler; 2369 c->read->handler = c->ssl->saved_read_handler;
2358 c->ssl->saved_read_handler = NULL; 2370 c->ssl->saved_read_handler = NULL;
2362 return NGX_ERROR; 2374 return NGX_ERROR;
2363 } 2375 }
2364 2376
2365 ngx_post_event(c->read, &ngx_posted_events); 2377 ngx_post_event(c->read, &ngx_posted_events);
2366 } 2378 }
2379
2380 /*
2381 * OpenSSL 1.1.1a fails to handle SSL_read_early_data()
2382 * if an SSL_write_early_data() call blocked on writing,
2383 * see https://github.com/openssl/openssl/issues/7757
2384 */
2385
2386 c->ssl->write_blocked = 1;
2367 2387
2368 c->write->ready = 0; 2388 c->write->ready = 0;
2369 return NGX_AGAIN; 2389 return NGX_AGAIN;
2370 } 2390 }
2371 2391