xref: /unit/src/nxt_openssl.c (revision 771:f349b2d68e75)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 #include <openssl/ssl.h>
9 #include <openssl/conf.h>
10 #include <openssl/err.h>
11 
12 
13 typedef struct {
14     SSL            *session;
15     nxt_conn_t     *conn;
16 
17     int            ssl_error;
18     uint8_t        times;      /* 2 bits */
19     uint8_t        handshake;  /* 1 bit  */
20 
21     nxt_buf_mem_t  buffer;
22 } nxt_openssl_conn_t;
23 
24 
25 typedef enum {
26     NXT_OPENSSL_HANDSHAKE = 0,
27     NXT_OPENSSL_READ,
28     NXT_OPENSSL_WRITE,
29     NXT_OPENSSL_SHUTDOWN,
30 } nxt_openssl_io_t;
31 
32 
33 static nxt_int_t nxt_openssl_library_init(nxt_task_t *task);
34 static void nxt_openssl_library_free(nxt_task_t *task);
35 #if OPENSSL_VERSION_NUMBER < 0x10100004L
36 static nxt_int_t nxt_openssl_locks_init(void);
37 static void nxt_openssl_lock(int mode, int type, const char *file, int line);
38 static unsigned long nxt_openssl_thread_id(void);
39 static void nxt_openssl_locks_free(void);
40 #endif
41 static nxt_int_t nxt_openssl_server_init(nxt_task_t *task,
42     nxt_tls_conf_t *conf);
43 static void nxt_openssl_server_free(nxt_task_t *task, nxt_tls_conf_t *conf);
44 static void nxt_openssl_conn_init(nxt_task_t *task, nxt_tls_conf_t *conf,
45     nxt_conn_t *c);
46 static void nxt_openssl_conn_handshake(nxt_task_t *task, void *obj, void *data);
47 static ssize_t nxt_openssl_conn_io_recvbuf(nxt_conn_t *c, nxt_buf_t *b);
48 static ssize_t nxt_openssl_conn_io_sendbuf(nxt_task_t *task, nxt_sendbuf_t *sb);
49 static ssize_t nxt_openssl_conn_io_send(nxt_task_t *task, nxt_sendbuf_t *sb,
50     void *buf, size_t size);
51 static void nxt_openssl_conn_io_shutdown(nxt_task_t *task, void *obj,
52     void *data);
53 static nxt_int_t nxt_openssl_conn_test_error(nxt_task_t *task, nxt_conn_t *c,
54     int ret, nxt_err_t sys_err, nxt_openssl_io_t io);
55 static void nxt_cdecl nxt_openssl_conn_error(nxt_task_t *task,
56     nxt_err_t err, const char *fmt, ...);
57 static nxt_uint_t nxt_openssl_log_error_level(nxt_err_t err);
58 
59 
60 const nxt_tls_lib_t  nxt_openssl_lib = {
61     .library_init = nxt_openssl_library_init,
62     .library_free = nxt_openssl_library_free,
63 
64     .server_init = nxt_openssl_server_init,
65     .server_free = nxt_openssl_server_free,
66 };
67 
68 
69 static nxt_conn_io_t  nxt_openssl_conn_io = {
70     .read = nxt_conn_io_read,
71     .recvbuf = nxt_openssl_conn_io_recvbuf,
72 
73     .write = nxt_conn_io_write,
74     .sendbuf = nxt_openssl_conn_io_sendbuf,
75 
76     .shutdown = nxt_openssl_conn_io_shutdown,
77 };
78 
79 
80 static long  nxt_openssl_version;
81 static int   nxt_openssl_connection_index;
82 
83 
84 static nxt_int_t
85 nxt_openssl_library_init(nxt_task_t *task)
86 {
87     int  index;
88 
89     if (nxt_fast_path(nxt_openssl_version != 0)) {
90         return NXT_OK;
91     }
92 
93 #if OPENSSL_VERSION_NUMBER >= 0x10100003L
94 
95     OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
96 
97 #else
98     {
99         nxt_int_t  ret;
100 
101         SSL_load_error_strings();
102 
103         OPENSSL_config(NULL);
104 
105         /*
106          * SSL_library_init(3):
107          *
108          *   SSL_library_init() always returns "1",
109          *   so it is safe to discard the return value.
110          */
111         (void) SSL_library_init();
112 
113         ret = nxt_openssl_locks_init();
114         if (nxt_slow_path(ret != NXT_OK)) {
115             return ret;
116         }
117     }
118 
119 #endif
120 
121     nxt_openssl_version = SSLeay();
122 
123     nxt_log(task, NXT_LOG_INFO, "%s, %xl",
124             SSLeay_version(SSLEAY_VERSION), nxt_openssl_version);
125 
126 #ifndef SSL_OP_NO_COMPRESSION
127     {
128         /*
129          * Disable gzip compression in OpenSSL prior to 1.0.0
130          * version, this saves about 522K per connection.
131          */
132         int                 n;
133         STACK_OF(SSL_COMP)  *ssl_comp_methods;
134 
135         ssl_comp_methods = SSL_COMP_get_compression_methods();
136 
137         for (n = sk_SSL_COMP_num(ssl_comp_methods); n != 0; n--) {
138             (void) sk_SSL_COMP_pop(ssl_comp_methods);
139         }
140     }
141 #endif
142 
143     index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
144 
145     if (index == -1) {
146         nxt_openssl_log_error(task, NXT_LOG_ALERT,
147                               "SSL_get_ex_new_index() failed");
148         return NXT_ERROR;
149     }
150 
151     nxt_openssl_connection_index = index;
152 
153     return NXT_OK;
154 }
155 
156 
157 #if OPENSSL_VERSION_NUMBER >= 0x10100003L
158 
159 static void
160 nxt_openssl_library_free(nxt_task_t *task)
161 {
162 }
163 
164 #else
165 
166 static nxt_thread_mutex_t  *nxt_openssl_locks;
167 
168 static nxt_int_t
169 nxt_openssl_locks_init(void)
170 {
171     int        i, n;
172     nxt_int_t  ret;
173 
174     n = CRYPTO_num_locks();
175 
176     nxt_openssl_locks = OPENSSL_malloc(n * sizeof(nxt_thread_mutex_t));
177     if (nxt_slow_path(nxt_openssl_locks == NULL)) {
178         return NXT_ERROR;
179     }
180 
181     for (i = 0; i < n; i++) {
182         ret = nxt_thread_mutex_create(&nxt_openssl_locks[i]);
183         if (nxt_slow_path(ret != NXT_OK)) {
184             return ret;
185         }
186     }
187 
188     CRYPTO_set_locking_callback(nxt_openssl_lock);
189 
190     CRYPTO_set_id_callback(nxt_openssl_thread_id);
191 
192     return NXT_OK;
193 }
194 
195 
196 static void
197 nxt_openssl_lock(int mode, int type, const char *file, int line)
198 {
199     nxt_thread_mutex_t  *lock;
200 
201     lock = &nxt_openssl_locks[type];
202 
203     if ((mode & CRYPTO_LOCK) != 0) {
204         (void) nxt_thread_mutex_lock(lock);
205 
206     } else {
207         (void) nxt_thread_mutex_unlock(lock);
208     }
209 }
210 
211 
212 static u_long
213 nxt_openssl_thread_id(void)
214 {
215     return (u_long) nxt_thread_handle();
216 }
217 
218 
219 static void
220 nxt_openssl_library_free(nxt_task_t *task)
221 {
222     nxt_openssl_locks_free();
223 }
224 
225 
226 static void
227 nxt_openssl_locks_free(void)
228 {
229     int  i, n;
230 
231     n = CRYPTO_num_locks();
232 
233     CRYPTO_set_locking_callback(NULL);
234 
235     for (i = 0; i < n; i++) {
236         nxt_thread_mutex_destroy(&nxt_openssl_locks[i]);
237     }
238 
239     OPENSSL_free(nxt_openssl_locks);
240 }
241 
242 #endif
243 
244 
245 static nxt_int_t
246 nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf)
247 {
248     SSL_CTX              *ctx;
249     const char           *certificate, *key, *ciphers, *ca_certificate;
250     STACK_OF(X509_NAME)  *list;
251 
252     ctx = SSL_CTX_new(SSLv23_server_method());
253     if (ctx == NULL) {
254         nxt_openssl_log_error(task, NXT_LOG_ALERT, "SSL_CTX_new() failed");
255         return NXT_ERROR;
256     }
257 
258     conf->ctx = ctx;
259     conf->conn_init = nxt_openssl_conn_init;
260 
261 #ifdef SSL_OP_NO_RENEGOTIATION
262     /* Renegration is not currently supported. */
263     SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
264 #endif
265 
266 #ifdef SSL_OP_NO_COMPRESSION
267     /*
268      * Disable gzip compression in OpenSSL 1.0.0,
269      * this saves about 522K per connection.
270      */
271     SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
272 #endif
273 
274 #ifdef SSL_MODE_RELEASE_BUFFERS
275 
276     if (nxt_openssl_version >= 10001078) {
277         /*
278          * Allow to release read and write buffers in OpenSSL 1.0.0,
279          * this saves about 34K per idle connection.  It is not safe
280          * before OpenSSL 1.0.1h (CVE-2010-5298).
281          */
282         SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
283     }
284 
285 #endif
286 
287     certificate = conf->certificate;
288 
289     if (SSL_CTX_use_certificate_chain_file(ctx, certificate) == 0) {
290         nxt_openssl_log_error(task, NXT_LOG_ALERT,
291                               "SSL_CTX_use_certificate_file(\"%s\") failed",
292                               certificate);
293         goto fail;
294     }
295 
296     key = conf->certificate_key;
297 
298     if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) == 0) {
299         nxt_openssl_log_error(task, NXT_LOG_ALERT,
300                               "SSL_CTX_use_PrivateKey_file(\"%s\") failed",
301                               key);
302         goto fail;
303     }
304 
305     ciphers = (conf->ciphers != NULL) ? conf->ciphers : "HIGH:!aNULL:!MD5";
306 
307     if (SSL_CTX_set_cipher_list(ctx, ciphers) == 0) {
308         nxt_openssl_log_error(task, NXT_LOG_ALERT,
309                               "SSL_CTX_set_cipher_list(\"%s\") failed",
310                               ciphers);
311         goto fail;
312     }
313 
314     SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
315 
316     if (conf->ca_certificate != NULL) {
317 
318         /* TODO: verify callback */
319         SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
320 
321         /* TODO: verify depth */
322         SSL_CTX_set_verify_depth(ctx, 1);
323 
324         ca_certificate = conf->ca_certificate;
325 
326         if (SSL_CTX_load_verify_locations(ctx, ca_certificate, NULL) == 0) {
327             nxt_openssl_log_error(task, NXT_LOG_ALERT,
328                               "SSL_CTX_load_verify_locations(\"%s\") failed",
329                               ca_certificate);
330             goto fail;
331         }
332 
333         list = SSL_load_client_CA_file(ca_certificate);
334 
335         if (list == NULL) {
336             nxt_openssl_log_error(task, NXT_LOG_ALERT,
337                               "SSL_load_client_CA_file(\"%s\") failed",
338                               ca_certificate);
339             goto fail;
340         }
341 
342         /*
343          * SSL_load_client_CA_file() in OpenSSL prior to 0.9.7h and
344          * 0.9.8 versions always leaves an error in the error queue.
345          */
346         ERR_clear_error();
347 
348         SSL_CTX_set_client_CA_list(ctx, list);
349     }
350 
351     return NXT_OK;
352 
353 fail:
354 
355     SSL_CTX_free(ctx);
356 
357     return NXT_ERROR;
358 }
359 
360 
361 static void
362 nxt_openssl_server_free(nxt_task_t *task, nxt_tls_conf_t *conf)
363 {
364     SSL_CTX_free(conf->ctx);
365 }
366 
367 
368 static void
369 nxt_openssl_conn_init(nxt_task_t *task, nxt_tls_conf_t *conf, nxt_conn_t *c)
370 {
371     int                 ret;
372     SSL                 *s;
373     SSL_CTX             *ctx;
374     nxt_openssl_conn_t  *tls;
375 
376     nxt_log_debug(c->socket.log, "openssl conn init");
377 
378     tls = nxt_mp_zget(c->mem_pool, sizeof(nxt_openssl_conn_t));
379     if (tls == NULL) {
380         goto fail;
381     }
382 
383     c->u.tls = tls;
384     nxt_buf_mem_set_size(&tls->buffer, conf->buffer_size);
385 
386     ctx = conf->ctx;
387 
388     s = SSL_new(ctx);
389     if (s == NULL) {
390         nxt_openssl_log_error(task, NXT_LOG_ALERT, "SSL_new() failed");
391         goto fail;
392     }
393 
394     tls->session = s;
395     tls->conn = c;
396 
397     ret = SSL_set_fd(s, c->socket.fd);
398 
399     if (ret == 0) {
400         nxt_openssl_log_error(task, NXT_LOG_ALERT, "SSL_set_fd(%d) failed",
401                               c->socket.fd);
402         goto fail;
403     }
404 
405     SSL_set_accept_state(s);
406 
407     if (SSL_set_ex_data(s, nxt_openssl_connection_index, c) == 0) {
408         nxt_openssl_log_error(task, NXT_LOG_ALERT, "SSL_set_ex_data() failed");
409         goto fail;
410     }
411 
412     c->io = &nxt_openssl_conn_io;
413     c->sendfile = NXT_CONN_SENDFILE_OFF;
414 
415     nxt_openssl_conn_handshake(task, c, c->socket.data);
416     return;
417 
418 fail:
419 
420     nxt_work_queue_add(c->read_work_queue, c->read_state->error_handler,
421                        task, c, c->socket.data);
422 }
423 
424 
425 nxt_inline void
426 nxt_openssl_conn_free(nxt_task_t *task, nxt_openssl_conn_t *tls)
427 {
428     nxt_debug(task, "openssl conn free");
429 
430     nxt_free(tls->buffer.start);
431 
432     SSL_free(tls->session);
433 }
434 
435 
436 static void
437 nxt_openssl_conn_handshake(nxt_task_t *task, void *obj, void *data)
438 {
439     int                     ret;
440     nxt_int_t               n;
441     nxt_err_t               err;
442     nxt_conn_t              *c;
443     nxt_work_queue_t        *wq;
444     nxt_work_handler_t      handler;
445     nxt_openssl_conn_t      *tls;
446     const nxt_conn_state_t  *state;
447 
448     c = obj;
449     tls = c->u.tls;
450 
451     nxt_debug(task, "openssl conn handshake: %d", tls->times);
452 
453     /* "tls->times == 1" is suitable to run SSL_do_handshake() in job. */
454 
455     ret = SSL_do_handshake(tls->session);
456 
457     err = (ret <= 0) ? nxt_socket_errno : 0;
458 
459     nxt_thread_time_debug_update(task->thread);
460 
461     nxt_debug(task, "SSL_do_handshake(%d): %d err:%d", c->socket.fd, ret, err);
462 
463     state = (c->read_state != NULL) ? c->read_state : c->write_state;
464 
465     if (ret > 0) {
466         /* ret == 1, the handshake was successfully completed. */
467         tls->handshake = 1;
468 
469         if (c->read_state != NULL) {
470             if (state->io_read_handler != NULL || c->read != NULL) {
471                 nxt_conn_read(task->thread->engine, c);
472                 return;
473             }
474 
475         } else {
476             if (c->write != NULL) {
477                 nxt_conn_write(task->thread->engine, c);
478                 return;
479             }
480         }
481 
482         handler = state->ready_handler;
483 
484     } else {
485         c->socket.read_handler = nxt_openssl_conn_handshake;
486         c->socket.write_handler = nxt_openssl_conn_handshake;
487 
488         n = nxt_openssl_conn_test_error(task, c, ret, err,
489                                         NXT_OPENSSL_HANDSHAKE);
490         switch (n) {
491 
492         case NXT_AGAIN:
493             if (tls->ssl_error == SSL_ERROR_WANT_READ && tls->times < 2) {
494                 tls->times++;
495             }
496 
497             return;
498 
499         case 0:
500             handler = state->close_handler;
501             break;
502 
503         default:
504         case NXT_ERROR:
505             c->socket.error = err;
506             nxt_openssl_conn_error(task, err, "SSL_do_handshake(%d) failed",
507                                    c->socket.fd);
508 
509             handler = state->error_handler;
510             break;
511         }
512     }
513 
514     wq = (c->read_state != NULL) ? c->read_work_queue : c->write_work_queue;
515 
516     nxt_work_queue_add(wq, handler, task, c, data);
517 }
518 
519 
520 static ssize_t
521 nxt_openssl_conn_io_recvbuf(nxt_conn_t *c, nxt_buf_t *b)
522 {
523     int                 ret;
524     size_t              size;
525     nxt_int_t           n;
526     nxt_err_t           err;
527     nxt_openssl_conn_t  *tls;
528 
529     tls = c->u.tls;
530     size = b->mem.end - b->mem.free;
531 
532     ret = SSL_read(tls->session, b->mem.free, size);
533 
534     err = (ret <= 0) ? nxt_socket_errno : 0;
535 
536     nxt_debug(c->socket.task, "SSL_read(%d, %p, %uz): %d err:%d",
537               c->socket.fd, b->mem.free, size, ret, err);
538 
539     if (ret > 0) {
540         if ((size_t) ret < size) {
541             c->socket.read_ready = 0;
542         }
543 
544         return ret;
545     }
546 
547     n = nxt_openssl_conn_test_error(c->socket.task, c, ret, err,
548                                     NXT_OPENSSL_READ);
549     if (n == NXT_ERROR) {
550         c->socket.error = err;
551         nxt_openssl_conn_error(c->socket.task, err,
552                                "SSL_read(%d, %p, %uz) failed",
553                                c->socket.fd, b->mem.free, size);
554     }
555 
556     return n;
557 }
558 
559 
560 static ssize_t
561 nxt_openssl_conn_io_sendbuf(nxt_task_t *task, nxt_sendbuf_t *sb)
562 {
563     nxt_uint_t    niov;
564     struct iovec  iov;
565 
566     niov = nxt_sendbuf_mem_coalesce0(task, sb, &iov, 1);
567 
568     if (niov == 0 && sb->sync) {
569         return 0;
570     }
571 
572     return nxt_openssl_conn_io_send(task, sb, iov.iov_base, iov.iov_len);
573 }
574 
575 
576 static ssize_t
577 nxt_openssl_conn_io_send(nxt_task_t *task, nxt_sendbuf_t *sb, void *buf,
578     size_t size)
579 {
580     int                 ret;
581     nxt_err_t           err;
582     nxt_int_t           n;
583     nxt_conn_t          *c;
584     nxt_openssl_conn_t  *tls;
585 
586     tls = sb->tls;
587 
588     ret = SSL_write(tls->session, buf, size);
589 
590     if (ret <= 0) {
591         err = nxt_socket_errno;
592         sb->error = err;
593 
594     } else {
595         err = 0;
596     }
597 
598     nxt_debug(task, "SSL_write(%d, %p, %uz): %d err:%d",
599               sb->socket, buf, size, ret, err);
600 
601     if (ret > 0) {
602         return ret;
603     }
604 
605     c = tls->conn;
606     c->socket.write_ready = sb->ready;
607     c->socket.error = sb->error;
608 
609     n = nxt_openssl_conn_test_error(task, c, ret, err, NXT_OPENSSL_WRITE);
610 
611     sb->ready = c->socket.write_ready;
612     sb->error = c->socket.error;
613 
614     if (n == NXT_ERROR) {
615         sb->error = err;
616         nxt_openssl_conn_error(task, err, "SSL_write(%d, %p, %uz) failed",
617                                sb->socket, buf, size);
618     }
619 
620     return n;
621 }
622 
623 
624 static void
625 nxt_openssl_conn_io_shutdown(nxt_task_t *task, void *obj, void *data)
626 {
627     int                 ret, mode;
628     SSL                 *s;
629     nxt_err_t           err;
630     nxt_int_t           n;
631     nxt_bool_t          quiet, once;
632     nxt_conn_t          *c;
633     nxt_openssl_conn_t  *tls;
634     nxt_work_handler_t  handler;
635 
636     c = obj;
637 
638     nxt_debug(task, "openssl conn shutdown");
639 
640     c->read_state = NULL;
641     tls = c->u.tls;
642     s = tls->session;
643 
644     if (s == NULL || !tls->handshake) {
645         handler = c->write_state->ready_handler;
646         goto done;
647     }
648 
649     mode = SSL_get_shutdown(s);
650 
651     if (c->socket.timedout || c->socket.error != 0) {
652         quiet = 1;
653 
654     } else if (c->socket.closed && !(mode & SSL_RECEIVED_SHUTDOWN)) {
655         quiet = 1;
656 
657     } else {
658         quiet = 0;
659     }
660 
661     SSL_set_quiet_shutdown(s, quiet);
662 
663     once = 1;
664 
665     for ( ;; ) {
666         SSL_set_shutdown(s, mode);
667 
668         ret = SSL_shutdown(s);
669 
670         err = (ret <= 0) ? nxt_socket_errno : 0;
671 
672         nxt_debug(task, "SSL_shutdown(%d, %d, %b): %d err:%d",
673                   c->socket.fd, mode, quiet, ret, err);
674 
675         if (ret > 0) {
676             /* ret == 1, the shutdown was successfully completed. */
677             handler = c->write_state->ready_handler;
678             goto done;
679         }
680 
681         if (ret == 0) {
682             /*
683              * If SSL_shutdown() returns 0 then it should be called
684              * again.  The second SSL_shutdown() call should return
685              * -1/SSL_ERROR_WANT_READ or -1/SSL_ERROR_WANT_WRITE.
686              * OpenSSL prior to 0.9.8m version however never returns
687              * -1 at all.  Fortunately, OpenSSL preserves internally
688              * correct status available via SSL_get_error(-1).
689              */
690             if (once) {
691                 once = 0;
692                 mode = SSL_get_shutdown(s);
693                 continue;
694             }
695 
696             ret = -1;
697         }
698 
699         /* ret == -1 */
700 
701         break;
702     }
703 
704     c->socket.read_handler = nxt_openssl_conn_io_shutdown;
705     c->socket.write_handler = nxt_openssl_conn_io_shutdown;
706     c->socket.error_handler = c->write_state->error_handler;
707 
708     n = nxt_openssl_conn_test_error(task, c, ret, err, NXT_OPENSSL_SHUTDOWN);
709 
710     switch (n) {
711 
712     case 0:
713         handler = c->write_state->close_handler;
714         break;
715 
716     case NXT_AGAIN:
717         nxt_timer_add(task->thread->engine, &c->read_timer, 5000);
718         return;
719 
720     default:
721     case NXT_ERROR:
722         c->socket.error = err;
723         nxt_openssl_conn_error(task, err, "SSL_shutdown(%d) failed",
724                                c->socket.fd);
725         handler = c->write_state->error_handler;
726     }
727 
728 done:
729 
730     nxt_openssl_conn_free(task, tls);
731 
732     nxt_work_queue_add(c->write_work_queue, handler, task, c, data);
733 }
734 
735 
736 static nxt_int_t
737 nxt_openssl_conn_test_error(nxt_task_t *task, nxt_conn_t *c, int ret,
738     nxt_err_t sys_err, nxt_openssl_io_t io)
739 {
740     u_long              lib_err;
741     nxt_openssl_conn_t  *tls;
742 
743     tls = c->u.tls;
744 
745     tls->ssl_error = SSL_get_error(tls->session, ret);
746 
747     nxt_debug(task, "SSL_get_error(): %d", tls->ssl_error);
748 
749     switch (tls->ssl_error) {
750 
751     case SSL_ERROR_WANT_READ:
752 
753         if (io != NXT_OPENSSL_READ) {
754             nxt_fd_event_block_write(task->thread->engine, &c->socket);
755 
756             c->socket.read_ready = 0;
757 
758             if (nxt_fd_event_is_disabled(c->socket.read)) {
759                 nxt_fd_event_enable_read(task->thread->engine, &c->socket);
760             }
761         }
762 
763         return NXT_AGAIN;
764 
765     case SSL_ERROR_WANT_WRITE:
766 
767         if (io != NXT_OPENSSL_WRITE) {
768             nxt_fd_event_block_read(task->thread->engine, &c->socket);
769 
770             c->socket.write_ready = 0;
771 
772             if (nxt_fd_event_is_disabled(c->socket.write)) {
773                 nxt_fd_event_enable_write(task->thread->engine, &c->socket);
774             }
775         }
776 
777         return NXT_AGAIN;
778 
779     case SSL_ERROR_SYSCALL:
780         lib_err = ERR_peek_error();
781 
782         nxt_debug(task, "ERR_peek_error(): %l", lib_err);
783 
784         if (sys_err != 0 || lib_err != 0) {
785             return NXT_ERROR;
786         }
787 
788         /* A connection was just closed. */
789         c->socket.closed = 1;
790         return 0;
791 
792     case SSL_ERROR_ZERO_RETURN:
793         /* A "close notify" alert. */
794         return 0;
795 
796     default: /* SSL_ERROR_SSL, etc. */
797         c->socket.error = 1000;  /* Nonexistent errno code. */
798         return NXT_ERROR;
799     }
800 }
801 
802 
803 static void nxt_cdecl
804 nxt_openssl_conn_error(nxt_task_t *task, nxt_err_t err, const char *fmt, ...)
805 {
806     u_char      *p, *end;
807     va_list     args;
808     nxt_uint_t  level;
809     u_char      msg[NXT_MAX_ERROR_STR];
810 
811     level = nxt_openssl_log_error_level(err);
812 
813     if (nxt_log_level_enough(task->log, level)) {
814 
815         end = msg + sizeof(msg);
816 
817         va_start(args, fmt);
818         p = nxt_vsprintf(msg, end, fmt, args);
819         va_end(args);
820 
821         if (err != 0) {
822             p = nxt_sprintf(p, end, " %E", err);
823         }
824 
825         p = nxt_openssl_copy_error(p, end);
826 
827         nxt_log(task, level, "%*s", p - msg, msg);
828 
829     } else {
830         ERR_clear_error();
831     }
832 }
833 
834 
835 static nxt_uint_t
836 nxt_openssl_log_error_level(nxt_err_t err)
837 {
838     switch (ERR_GET_REASON(ERR_peek_error())) {
839 
840     case 0:
841         return nxt_socket_error_level(err);
842 
843     case SSL_R_BAD_CHANGE_CIPHER_SPEC:                    /*  103 */
844     case SSL_R_BLOCK_CIPHER_PAD_IS_WRONG:                 /*  129 */
845     case SSL_R_DIGEST_CHECK_FAILED:                       /*  149 */
846     case SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST:             /*  151 */
847     case SSL_R_EXCESSIVE_MESSAGE_SIZE:                    /*  152 */
848     case SSL_R_LENGTH_MISMATCH:                           /*  159 */
849 #ifdef SSL_R_NO_CIPHERS_PASSED
850     case SSL_R_NO_CIPHERS_PASSED:                         /*  182 */
851 #endif
852     case SSL_R_NO_CIPHERS_SPECIFIED:                      /*  183 */
853     case SSL_R_NO_COMPRESSION_SPECIFIED:                  /*  187 */
854     case SSL_R_NO_SHARED_CIPHER:                          /*  193 */
855     case SSL_R_RECORD_LENGTH_MISMATCH:                    /*  213 */
856 #ifdef SSL_R_PARSE_TLSEXT
857     case SSL_R_PARSE_TLSEXT:                              /*  227 */
858 #endif
859     case SSL_R_UNEXPECTED_MESSAGE:                        /*  244 */
860     case SSL_R_UNEXPECTED_RECORD:                         /*  245 */
861     case SSL_R_UNKNOWN_ALERT_TYPE:                        /*  246 */
862     case SSL_R_UNKNOWN_PROTOCOL:                          /*  252 */
863     case SSL_R_WRONG_VERSION_NUMBER:                      /*  267 */
864     case SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC:       /*  281 */
865 #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG
866     case SSL_R_RENEGOTIATE_EXT_TOO_LONG:                  /*  335 */
867     case SSL_R_RENEGOTIATION_ENCODING_ERR:                /*  336 */
868     case SSL_R_RENEGOTIATION_MISMATCH:                    /*  337 */
869 #endif
870 #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
871     case SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED:      /*  338 */
872 #endif
873 #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
874     case SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING:          /*  345 */
875 #endif
876     case 1000:/* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
877     case SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE:            /* 1010 */
878     case SSL_R_SSLV3_ALERT_BAD_RECORD_MAC:                /* 1020 */
879     case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:             /* 1021 */
880     case SSL_R_TLSV1_ALERT_RECORD_OVERFLOW:               /* 1022 */
881     case SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE:         /* 1030 */
882     case SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE:             /* 1040 */
883     case SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER:             /* 1047 */
884         break;
885 
886     case SSL_R_SSLV3_ALERT_NO_CERTIFICATE:                /* 1041 */
887     case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:               /* 1042 */
888     case SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE:       /* 1043 */
889     case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:           /* 1044 */
890     case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:           /* 1045 */
891     case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:           /* 1046 */
892     case SSL_R_TLSV1_ALERT_UNKNOWN_CA:                    /* 1048 */
893     case SSL_R_TLSV1_ALERT_ACCESS_DENIED:                 /* 1049 */
894     case SSL_R_TLSV1_ALERT_DECODE_ERROR:                  /* 1050 */
895     case SSL_R_TLSV1_ALERT_DECRYPT_ERROR:                 /* 1051 */
896     case SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION:            /* 1060 */
897     case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:              /* 1070 */
898     case SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY:         /* 1071 */
899     case SSL_R_TLSV1_ALERT_INTERNAL_ERROR:                /* 1080 */
900     case SSL_R_TLSV1_ALERT_USER_CANCELLED:                /* 1090 */
901     case SSL_R_TLSV1_ALERT_NO_RENEGOTIATION:              /* 1100 */
902         return NXT_LOG_ERR;
903 
904     default:
905         return NXT_LOG_ALERT;
906     }
907 
908     return NXT_LOG_INFO;
909 }
910 
911 
912 void nxt_cdecl
913 nxt_openssl_log_error(nxt_task_t *task, nxt_uint_t level, const char *fmt, ...)
914 {
915     u_char   *p, *end;
916     va_list  args;
917     u_char   msg[NXT_MAX_ERROR_STR];
918 
919     end = msg + sizeof(msg);
920 
921     va_start(args, fmt);
922     p = nxt_vsprintf(msg, end, fmt, args);
923     va_end(args);
924 
925     p = nxt_openssl_copy_error(p, end);
926 
927     nxt_log(task, level, "%*s", p - msg, msg);
928 }
929 
930 
931 u_char *
932 nxt_openssl_copy_error(u_char *p, u_char *end)
933 {
934     int         flags;
935     u_long      err;
936     nxt_bool_t  clear;
937     const char  *data, *delimiter;
938 
939     err = ERR_peek_error();
940     if (err == 0) {
941         return p;
942     }
943 
944     /* Log the most relevant error message ... */
945     data = ERR_reason_error_string(err);
946 
947     p = nxt_sprintf(p, end, " (%d: %s) (OpenSSL: ", ERR_GET_REASON(err), data);
948 
949     /*
950      * ... followed by all queued cumbersome OpenSSL error messages
951      * and drain the error queue.
952      */
953     delimiter = "";
954     clear = 0;
955 
956     for ( ;; ) {
957         err = ERR_get_error_line_data(NULL, NULL, &data, &flags);
958         if (err == 0) {
959             break;
960         }
961 
962         p = nxt_sprintf(p, end, "%s", delimiter);
963 
964         ERR_error_string_n(err, (char *) p, end - p);
965 
966         while (p < end && *p != '\0') {
967             p++;
968         }
969 
970         if ((flags & ERR_TXT_STRING) != 0) {
971             p = nxt_sprintf(p, end, ":%s", data);
972         }
973 
974         clear |= ((flags & ERR_TXT_MALLOCED) != 0);
975 
976         delimiter = "; ";
977     }
978 
979     /* Deallocate additional data. */
980 
981     if (clear) {
982         ERR_clear_error();
983     }
984 
985     if (p < end) {
986         *p++ = ')';
987     }
988 
989     return p;
990 }
991