1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10
11
12 typedef struct {
13 ngx_str_t engine;
14 } ngx_openssl_conf_t;
15
16
17 static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
18 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);
20 static void ngx_ssl_write_handler(ngx_event_t *wev);
21 static void ngx_ssl_read_handler(ngx_event_t *rev);
22 static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
23 static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
24 ngx_err_t err, char *text);
25 static void ngx_ssl_clear_error(ngx_log_t *log);
26
27 static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone,
28 void *data);
29 static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
30 ngx_ssl_session_t *sess);
31 static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
32 u_char *id, int len, int *copy);
33 static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
34 static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
35 ngx_slab_pool_t *shpool, ngx_uint_t n);
36 static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
37 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
38
39 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
40 static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf);
41 static void ngx_openssl_exit(ngx_cycle_t *cycle);
42
43 #if !(NGX_SSL_ENGINE)
44 static char *ngx_openssl_noengine(ngx_conf_t *cf, ngx_command_t *cmd,
45 void *conf);
46 #endif
47
48
49 static ngx_command_t ngx_openssl_commands[] = {
50
51 { ngx_string("ssl_engine"),
52 NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
53 #if (NGX_SSL_ENGINE)
54 ngx_conf_set_str_slot,
55 #else
56 ngx_openssl_noengine,
57 #endif
58 0,
59 offsetof(ngx_openssl_conf_t, engine),
60 NULL },
61
62 ngx_null_command
63 };
64
65
66 static ngx_core_module_t ngx_openssl_module_ctx = {
67 ngx_string("openssl"),
68 ngx_openssl_create_conf,
69 ngx_openssl_init_conf
70 };
71
72
73 ngx_module_t ngx_openssl_module = {
74 NGX_MODULE_V1,
75 &ngx_openssl_module_ctx, /* module context */
76 ngx_openssl_commands, /* module directives */
77 NGX_CORE_MODULE, /* module type */
78 NULL, /* init master */
79 NULL, /* init module */
80 NULL, /* init process */
81 NULL, /* init thread */
82 NULL, /* exit thread */
83 NULL, /* exit process */
84 ngx_openssl_exit, /* exit master */
85 NGX_MODULE_V1_PADDING
86 };
87
88
89 static long ngx_ssl_protocols[] = {
90 SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1,
91 SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1,
92 SSL_OP_NO_SSLv2|SSL_OP_NO_TLSv1,
93 SSL_OP_NO_TLSv1,
94 SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3,
95 SSL_OP_NO_SSLv3,
96 SSL_OP_NO_SSLv2,
97 0,
98 };
99
100
101 int ngx_ssl_connection_index;
102 int ngx_ssl_server_conf_index;
103 int ngx_ssl_session_cache_index;
104
105
106 ngx_int_t
107 ngx_ssl_init(ngx_log_t *log)
108 {
109 #if OPENSSL_VERSION_NUMBER >= 0x00907000
110 OPENSSL_config(NULL);
111 #endif
112
113 SSL_library_init();
114 SSL_load_error_strings();
115
116 #if (NGX_SSL_ENGINE)
117 ENGINE_load_builtin_engines();
118 #endif
119
120 ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
121
122 if (ngx_ssl_connection_index == -1) {
123 ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed");
124 return NGX_ERROR;
125 }
126
127 ngx_ssl_server_conf_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
128 NULL);
129 if (ngx_ssl_server_conf_index == -1) {
130 ngx_ssl_error(NGX_LOG_ALERT, log, 0,
131 "SSL_CTX_get_ex_new_index() failed");
132 return NGX_ERROR;
133 }
134
135 ngx_ssl_session_cache_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
136 NULL);
137 if (ngx_ssl_session_cache_index == -1) {
138 ngx_ssl_error(NGX_LOG_ALERT, log, 0,
139 "SSL_CTX_get_ex_new_index() failed");
140 return NGX_ERROR;
141 }
142
143 return NGX_OK;
144 }
145
146
147 ngx_int_t
148 ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
149 {
150 ssl->ctx = SSL_CTX_new(SSLv23_method());
151
152 if (ssl->ctx == NULL) {
153 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed");
154 return NGX_ERROR;
155 }
156
157 if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_server_conf_index, data) == 0) {
158 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
159 "SSL_CTX_set_ex_data() failed");
160 return NGX_ERROR;
161 }
162
163 /* client side options */
164
165 SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
166 SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
167 SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
168
169 /* server side options */
170
171 SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
172 SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
173
174 /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */
175 SSL_CTX_set_options(ssl->ctx, SSL_OP_MSIE_SSLV2_RSA_PADDING);
176
177 SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
178 SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
179 SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
180
181 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
182 SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
183 #endif
184
185
186 if (ngx_ssl_protocols[protocols >> 1] != 0) {
187 SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]);
188 }
189
190 /*
191 * we need this option because in ngx_ssl_send_chain()
192 * we may switch to a buffered write and may copy leftover part of
193 * previously unbuffered data to our internal buffer
194 */
195 SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
196
197 SSL_CTX_set_read_ahead(ssl->ctx, 1);
198
199 return NGX_OK;
200 }
201
202
203 ngx_int_t
204 ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
205 ngx_str_t *key)
206 {
207 if (ngx_conf_full_name(cf->cycle, cert, 1) == NGX_ERROR) {
208 return NGX_ERROR;
209 }
210
211 if (SSL_CTX_use_certificate_chain_file(ssl->ctx, (char *) cert->data)
212 == 0)
213 {
214 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
215 "SSL_CTX_use_certificate_chain_file(\"%s\") failed",
216 cert->data);
217 return NGX_ERROR;
218 }
219
220 if (ngx_conf_full_name(cf->cycle, key, 1) == NGX_ERROR) {
221 return NGX_ERROR;
222 }
223
224 if (SSL_CTX_use_PrivateKey_file(ssl->ctx, (char *) key->data,
225 SSL_FILETYPE_PEM)
226 == 0)
227 {
228 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
229 "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key->data);
230 return NGX_ERROR;
231 }
232
233 return NGX_OK;
234 }
235
236
237 ngx_int_t
238 ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
239 ngx_int_t depth)
240 {
241 STACK_OF(X509_NAME) *list;
242
243 SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_http_ssl_verify_callback);
244
245 SSL_CTX_set_verify_depth(ssl->ctx, depth);
246
247 if (cert->len == 0) {
248 return NGX_OK;
249 }
250
251 if (ngx_conf_full_name(cf->cycle, cert, 1) == NGX_ERROR) {
252 return NGX_ERROR;
253 }
254
255 if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL)
256 == 0)
257 {
258 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
259 "SSL_CTX_load_verify_locations(\"%s\") failed",
260 cert->data);
261 return NGX_ERROR;
262 }
263
264 list = SSL_load_client_CA_file((char *) cert->data);
265
266 if (list == NULL) {
267 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
268 "SSL_load_client_CA_file(\"%s\") failed", cert->data);
269 return NGX_ERROR;
270 }
271
272 /*
273 * before 0.9.7h and 0.9.8 SSL_load_client_CA_file()
274 * always leaved an error in the error queue
275 */
276
277 ERR_clear_error();
278
279 SSL_CTX_set_client_CA_list(ssl->ctx, list);
280
281 return NGX_OK;
282 }
283
284
285 static int
286 ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
287 {
288 char *subject, *issuer;
289 int err, depth;
290 X509 *cert;
291 X509_NAME *name;
292 ngx_connection_t *c;
293 ngx_ssl_conn_t *ssl_conn;
294
295 ssl_conn = X509_STORE_CTX_get_ex_data(x509_store,
296 SSL_get_ex_data_X509_STORE_CTX_idx());
297
298 c = ngx_ssl_get_connection(ssl_conn);
299
300 cert = X509_STORE_CTX_get_current_cert(x509_store);
301 err = X509_STORE_CTX_get_error(x509_store);
302 depth = X509_STORE_CTX_get_error_depth(x509_store);
303
304 name = X509_get_subject_name(cert);
305 subject = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
306
307 name = X509_get_issuer_name(cert);
308 issuer = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
309
310 ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
311 "verify:%d, error:%d, depth:%d, "
312 "subject:\"%s\",issuer: \"%s\"",
313 ok, err, depth, subject, issuer);
314
315 return 1;
316 }
317
318
319 ngx_int_t
320 ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl)
321 {
322 RSA *key;
323
324 if (SSL_CTX_need_tmp_RSA(ssl->ctx) == 0) {
325 return NGX_OK;
326 }
327
328 key = RSA_generate_key(512, RSA_F4, NULL, NULL);
329
330 if (key) {
331 SSL_CTX_set_tmp_rsa(ssl->ctx, key);
332
333 RSA_free(key);
334
335 return NGX_OK;
336 }
337
338 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "RSA_generate_key(512) failed");
339
340 return NGX_ERROR;
341 }
342
343
344 ngx_int_t
345 ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
346 {
347 ngx_ssl_connection_t *sc;
348
349 sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t));
350 if (sc == NULL) {
351 return NGX_ERROR;
352 }
353
354 sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
355
356 sc->connection = SSL_new(ssl->ctx);
357
358 if (sc->connection == NULL) {
359 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed");
360 return NGX_ERROR;
361 }
362
363 if (SSL_set_fd(sc->connection, c->fd) == 0) {
364 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed");
365 return NGX_ERROR;
366 }
367
368 if (flags & NGX_SSL_CLIENT) {
369 SSL_set_connect_state(sc->connection);
370
371 } else {
372 SSL_set_accept_state(sc->connection);
373 }
374
375 if (SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) == 0) {
376 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed");
377 return NGX_ERROR;
378 }
379
380 c->ssl = sc;
381
382 return NGX_OK;
383 }
384
385
386 ngx_int_t
387 ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
388 {
389 if (session) {
390 if (SSL_set_session(c->ssl->connection, session) == 0) {
391 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_session() failed");
392 return NGX_ERROR;
393 }
394 }
395
396 return NGX_OK;
397 }
398
399
400 ngx_int_t
401 ngx_ssl_handshake(ngx_connection_t *c)
402 {
403 int n, sslerr;
404 ngx_err_t err;
405
406 ngx_ssl_clear_error(c->log);
407
408 n = SSL_do_handshake(c->ssl->connection);
409
410 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
411
412 if (n == 1) {
413
414 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
415 return NGX_ERROR;
416 }
417
418 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
419 return NGX_ERROR;
420 }
421
422 #if (NGX_DEBUG)
423 {
424 char buf[129], *s, *d;
425 SSL_CIPHER *cipher;
426
427 cipher = SSL_get_current_cipher(c->ssl->connection);
428
429 if (cipher) {
430 SSL_CIPHER_description(cipher, &buf[1], 128);
431
432 for (s = &buf[1], d = buf; *s; s++) {
433 if (*s == ' ' && *d == ' ') {
434 continue;
435 }
436
437 if (*s == LF || *s == CR) {
438 continue;
439 }
440
441 *++d = *s;
442 }
443
444 if (*d != ' ') {
445 d++;
446 }
447
448 *d = '\0';
449
450 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
451 "SSL: %s, cipher: \"%s\"",
452 SSL_get_version(c->ssl->connection), &buf[1]);
453
454 if (SSL_session_reused(c->ssl->connection)) {
455 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
456 "SSL reused session");
457 }
458
459 } else {
460 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
461 "SSL no shared ciphers");
462 }
463 }
464 #endif
465
466 c->ssl->handshaked = 1;
467
468 c->recv = ngx_ssl_recv;
469 c->send = ngx_ssl_write;
470 c->recv_chain = ngx_ssl_recv_chain;
471 c->send_chain = ngx_ssl_send_chain;
472
473 return NGX_OK;
474 }
475
476 sslerr = SSL_get_error(c->ssl->connection, n);
477
478 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
479
480 if (sslerr == SSL_ERROR_WANT_READ) {
481 c->read->ready = 0;
482 c->read->handler = ngx_ssl_handshake_handler;
483 c->write->handler = ngx_ssl_handshake_handler;
484
485 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
486 return NGX_ERROR;
487 }
488
489 return NGX_AGAIN;
490 }
491
492 if (sslerr == SSL_ERROR_WANT_WRITE) {
493 c->write->ready = 0;
494 c->read->handler = ngx_ssl_handshake_handler;
495 c->write->handler = ngx_ssl_handshake_handler;
496
497 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
498 return NGX_ERROR;
499 }
500
501 return NGX_AGAIN;
502 }
503
504 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
505
506 c->ssl->no_wait_shutdown = 1;
507 c->ssl->no_send_shutdown = 1;
508 c->read->eof = 1;
509
510 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
511 ngx_log_error(NGX_LOG_INFO, c->log, err,
512 "peer closed connection in SSL handshake");
513
514 return NGX_ERROR;
515 }
516
517 c->read->error = 1;
518
519 ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed");
520
521 return NGX_ERROR;
522 }
523
524
525 static void
526 ngx_ssl_handshake_handler(ngx_event_t *ev)
527 {
528 ngx_connection_t *c;
529
530 c = ev->data;
531
532 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
533 "SSL handshake handler: %d", ev->write);
534
535 if (ev->timedout) {
536 c->ssl->handler(c);
537 return;
538 }
539
540 if (ngx_ssl_handshake(c) == NGX_AGAIN) {
541 return;
542 }
543
544 c->ssl->handler(c);
545 }
546
547
548 ssize_t
549 ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl)
550 {
551 u_char *last;
552 ssize_t n, bytes;
553 ngx_buf_t *b;
554
555 bytes = 0;
556
557 b = cl->buf;
558 last = b->last;
559
560 for ( ;; ) {
561
562 n = ngx_ssl_recv(c, last, b->end - last);
563
564 if (n > 0) {
565 last += n;
566 bytes += n;
567
568 if (last == b->end) {
569 cl = cl->next;
570
571 if (cl == NULL) {
572 return bytes;
573 }
574
575 b = cl->buf;
576 last = b->last;
577 }
578
579 continue;
580 }
581
582 if (bytes) {
583 return bytes;
584 }
585
586 return n;
587 }
588 }
589
590
591 ssize_t
592 ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
593 {
594 int n, bytes;
595
596 if (c->ssl->last == NGX_ERROR) {
597 c->read->error = 1;
598 return NGX_ERROR;
599 }
600
601 if (c->ssl->last == NGX_DONE) {
602 c->read->ready = 0;
603 c->read->eof = 1;
604 return 0;
605 }
606
607 bytes = 0;
608
609 ngx_ssl_clear_error(c->log);
610
611 /*
612 * SSL_read() may return data in parts, so try to read
613 * until SSL_read() would return no data
614 */
615
616 for ( ;; ) {
617
618 n = SSL_read(c->ssl->connection, buf, size);
619
620 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n);
621
622 if (n > 0) {
623 bytes += n;
624 }
625
626 c->ssl->last = ngx_ssl_handle_recv(c, n);
627
628 if (c->ssl->last == NGX_OK) {
629
630 size -= n;
631
632 if (size == 0) {
633 return bytes;
634 }
635
636 buf += n;
637
638 continue;
639 }
640
641 if (bytes) {
642 return bytes;
643 }
644
645 switch (c->ssl->last) {
646
647 case NGX_DONE:
648 c->read->ready = 0;
649 c->read->eof = 1;
650 return 0;
651
652 case NGX_ERROR:
653 c->read->error = 1;
654
655 /* fall thruogh */
656
657 case NGX_AGAIN:
658 return c->ssl->last;
659 }
660 }
661 }
662
663
664 static ngx_int_t
665 ngx_ssl_handle_recv(ngx_connection_t *c, int n)
666 {
667 int sslerr;
668 ngx_err_t err;
669
670 if (n > 0) {
671
672 if (c->ssl->saved_write_handler) {
673
674 c->write->handler = c->ssl->saved_write_handler;
675 c->ssl->saved_write_handler = NULL;
676 c->write->ready = 1;
677
678 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
679 return NGX_ERROR;
680 }
681
682 ngx_post_event(c->write, &ngx_posted_events);
683 }
684
685 return NGX_OK;
686 }
687
688 sslerr = SSL_get_error(c->ssl->connection, n);
689
690 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
691
692 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
693
694 if (sslerr == SSL_ERROR_WANT_READ) {
695 c->read->ready = 0;
696 return NGX_AGAIN;
697 }
698
699 if (sslerr == SSL_ERROR_WANT_WRITE) {
700
701 ngx_log_error(NGX_LOG_INFO, c->log, 0,
702 "peer started SSL renegotiation");
703
704 c->write->ready = 0;
705
706 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
707 return NGX_ERROR;
708 }
709
710 /*
711 * we do not set the timer because there is already the read event timer
712 */
713
714 if (c->ssl->saved_write_handler == NULL) {
715 c->ssl->saved_write_handler = c->write->handler;
716 c->write->handler = ngx_ssl_write_handler;
717 }
718
719 return NGX_AGAIN;
720 }
721
722 c->ssl->no_wait_shutdown = 1;
723 c->ssl->no_send_shutdown = 1;
724
725 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
726 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
727 "peer shutdown SSL cleanly");
728 return NGX_DONE;
729 }
730
731 ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed");
732
733 return NGX_ERROR;
734 }
735
736
737 static void
738 ngx_ssl_write_handler(ngx_event_t *wev)
739 {
740 ngx_connection_t *c;
741
742 c = wev->data;
743
744 c->read->handler(c->read);
745 }
746
747
748 /*
749 * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
750 * before the SSL_write() call to decrease a SSL overhead.
751 *
752 * Besides for protocols such as HTTP it is possible to always buffer
753 * the output to decrease a SSL overhead some more.
754 */
755
756 ngx_chain_t *
757 ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
758 {
759 int n;
760 ngx_uint_t flush;
761 ssize_t send, size;
762 ngx_buf_t *buf;
763
764 if (!c->ssl->buffer
765 || (in && in->next == NULL && !(c->buffered & NGX_SSL_BUFFERED)))
766 {
767 /*
768 * we avoid a buffer copy if
769 * we do not need to buffer the output
770 * or the incoming buf is a single and our buffer is empty
771 */
772
773 while (in) {
774 if (ngx_buf_special(in->buf)) {
775 in = in->next;
776 continue;
777 }
778
779 n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos);
780
781 if (n == NGX_ERROR) {
782 return NGX_CHAIN_ERROR;
783 }
784
785 if (n == NGX_AGAIN) {
786 c->buffered |= NGX_SSL_BUFFERED;
787 return in;
788 }
789
790 in->buf->pos += n;
791
792 if (in->buf->pos == in->buf->last) {
793 in = in->next;
794 }
795 }
796
797 return in;
798 }
799
800
801 /* the maximum limit size is the maximum uint32_t value - the page size */
802
803 if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize)) {
804 limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
805 }
806
807 buf = c->ssl->buf;
808
809 if (buf == NULL) {
810 buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE);
811 if (buf == NULL) {
812 return NGX_CHAIN_ERROR;
813 }
814
815 c->ssl->buf = buf;
816 }
817
818 if (buf->start == NULL) {
819 buf->start = ngx_palloc(c->pool, NGX_SSL_BUFSIZE);
820 if (buf->start == NULL) {
821 return NGX_CHAIN_ERROR;
822 }
823
824 buf->pos = buf->start;
825 buf->last = buf->start;
826 buf->end = buf->start + NGX_SSL_BUFSIZE;
827 }
828
829 send = 0;
830 flush = (in == NULL) ? 1 : 0;
831
832 for ( ;; ) {
833
834 while (in && buf->last < buf->end) {
835 if (in->buf->last_buf || in->buf->flush) {
836 flush = 1;
837 }
838
839 if (ngx_buf_special(in->buf)) {
840 in = in->next;
841 continue;
842 }
843
844 size = in->buf->last - in->buf->pos;
845
846 if (size > buf->end - buf->last) {
847 size = buf->end - buf->last;
848 }
849
850 if (send + size > limit) {
851 size = (ssize_t) (limit - send);
852 flush = 1;
853 }
854
855 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
856 "SSL buf copy: %d", size);
857
858 ngx_memcpy(buf->last, in->buf->pos, size);
859
860 buf->last += size;
861
862 in->buf->pos += size;
863
864 if (in->buf->pos == in->buf->last) {
865 in = in->next;
866 }
867 }
868
869 size = buf->last - buf->pos;
870
871 if (!flush && buf->last < buf->end && c->ssl->buffer) {
872 break;
873 }
874
875 n = ngx_ssl_write(c, buf->pos, size);
876
877 if (n == NGX_ERROR) {
878 return NGX_CHAIN_ERROR;
879 }
880
881 if (n == NGX_AGAIN) {
882 c->buffered |= NGX_SSL_BUFFERED;
883 return in;
884 }
885
886 buf->pos += n;
887 send += n;
888 c->sent += n;
889
890 if (n < size) {
891 break;
892 }
893
894 if (buf->pos == buf->last) {
895 buf->pos = buf->start;
896 buf->last = buf->start;
897 }
898
899 if (in == NULL || send == limit) {
900 break;
901 }
902 }
903
904 if (buf->pos < buf->last) {
905 c->buffered |= NGX_SSL_BUFFERED;
906
907 } else {
908 c->buffered &= ~NGX_SSL_BUFFERED;
909 }
910
911 return in;
912 }
913
914
915 ssize_t
916 ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
917 {
918 int n, sslerr;
919 ngx_err_t err;
920
921 ngx_ssl_clear_error(c->log);
922
923 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
924
925 n = SSL_write(c->ssl->connection, data, size);
926
927 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
928
929 if (n > 0) {
930
931 if (c->ssl->saved_read_handler) {
932
933 c->read->handler = c->ssl->saved_read_handler;
934 c->ssl->saved_read_handler = NULL;
935 c->read->ready = 1;
936
937 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
938 return NGX_ERROR;
939 }
940
941 ngx_post_event(c->read, &ngx_posted_events);
942 }
943
944 return n;
945 }
946
947 sslerr = SSL_get_error(c->ssl->connection, n);
948
949 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
950
951 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
952
953 if (sslerr == SSL_ERROR_WANT_WRITE) {
954 c->write->ready = 0;
955 return NGX_AGAIN;
956 }
957
958 if (sslerr == SSL_ERROR_WANT_READ) {
959
960 ngx_log_error(NGX_LOG_INFO, c->log, 0,
961 "peer started SSL renegotiation");
962
963 c->read->ready = 0;
964
965 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
966 return NGX_ERROR;
967 }
968
969 /*
970 * we do not set the timer because there is already
971 * the write event timer
972 */
973
974 if (c->ssl->saved_read_handler == NULL) {
975 c->ssl->saved_read_handler = c->read->handler;
976 c->read->handler = ngx_ssl_read_handler;
977 }
978
979 return NGX_AGAIN;
980 }
981
982 c->ssl->no_wait_shutdown = 1;
983 c->ssl->no_send_shutdown = 1;
984 c->write->error = 1;
985
986 ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed");
987
988 return NGX_ERROR;
989 }
990
991
992 static void
993 ngx_ssl_read_handler(ngx_event_t *rev)
994 {
995 ngx_connection_t *c;
996
997 c = rev->data;
998
999 c->write->handler(c->write);
1000 }
1001
1002
1003 void
1004 ngx_ssl_free_buffer(ngx_connection_t *c)
1005 {
1006 if (c->ssl->buf && c->ssl->buf->start) {
1007 if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) {
1008 c->ssl->buf->start = NULL;
1009 }
1010 }
1011 }
1012
1013
1014 ngx_int_t
1015 ngx_ssl_shutdown(ngx_connection_t *c)
1016 {
1017 int n, sslerr, mode;
1018 ngx_err_t err;
1019
1020 if (c->timedout) {
1021 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
1022
1023 } else {
1024 mode = SSL_get_shutdown(c->ssl->connection);
1025
1026 if (c->ssl->no_wait_shutdown) {
1027 mode |= SSL_RECEIVED_SHUTDOWN;
1028 }
1029
1030 if (c->ssl->no_send_shutdown) {
1031 mode |= SSL_SENT_SHUTDOWN;
1032 }
1033 }
1034
1035 SSL_set_shutdown(c->ssl->connection, mode);
1036
1037 ngx_ssl_clear_error(c->log);
1038
1039 n = SSL_shutdown(c->ssl->connection);
1040
1041 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
1042
1043 sslerr = 0;
1044
1045 /* SSL_shutdown() never returns -1, on error it returns 0 */
1046
1047 if (n != 1 && ERR_peek_error()) {
1048 sslerr = SSL_get_error(c->ssl->connection, n);
1049
1050 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
1051 "SSL_get_error: %d", sslerr);
1052 }
1053
1054 if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
1055 SSL_free(c->ssl->connection);
1056 c->ssl = NULL;
1057
1058 return NGX_OK;
1059 }
1060
1061 if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
1062 c->read->handler = ngx_ssl_shutdown_handler;
1063 c->write->handler = ngx_ssl_shutdown_handler;
1064
1065 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
1066 return NGX_ERROR;
1067 }
1068
1069 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
1070 return NGX_ERROR;
1071 }
1072
1073 if (sslerr == SSL_ERROR_WANT_READ) {
1074 ngx_add_timer(c->read, 30000);
1075 }
1076
1077 return NGX_AGAIN;
1078 }
1079
1080 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
1081
1082 ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
1083
1084 SSL_free(c->ssl->connection);
1085 c->ssl = NULL;
1086
1087 return NGX_ERROR;
1088 }
1089
1090
1091 static void
1092 ngx_ssl_shutdown_handler(ngx_event_t *ev)
1093 {
1094 ngx_connection_t *c;
1095 ngx_connection_handler_pt handler;
1096
1097 c = ev->data;
1098 handler = c->ssl->handler;
1099
1100 if (ev->timedout) {
1101 c->timedout = 1;
1102 }
1103
1104 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "SSL shutdown handler");
1105
1106 if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
1107 return;
1108 }
1109
1110 handler(c);
1111 }
1112
1113
1114 static void
1115 ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
1116 char *text)
1117 {
1118 int n;
1119 ngx_uint_t level;
1120
1121 level = NGX_LOG_CRIT;
1122
1123 if (sslerr == SSL_ERROR_SYSCALL) {
1124
1125 if (err == NGX_ECONNRESET
1126 || err == NGX_EPIPE
1127 || err == NGX_ENOTCONN
1128 #if !(NGX_CRIT_ETIMEDOUT)
1129 || err == NGX_ETIMEDOUT
1130 #endif
1131 || err == NGX_ECONNREFUSED
1132 || err == NGX_ENETDOWN
1133 || err == NGX_ENETUNREACH
1134 || err == NGX_EHOSTDOWN
1135 || err == NGX_EHOSTUNREACH)
1136 {
1137 switch (c->log_error) {
1138
1139 case NGX_ERROR_IGNORE_ECONNRESET:
1140 case NGX_ERROR_INFO:
1141 level = NGX_LOG_INFO;
1142 break;
1143
1144 case NGX_ERROR_ERR:
1145 level = NGX_LOG_ERR;
1146 break;
1147
1148 default:
1149 break;
1150 }
1151 }
1152
1153 } else if (sslerr == SSL_ERROR_SSL) {
1154
1155 n = ERR_GET_REASON(ERR_pe