1 /*
2  * Copyright (c) 2019, Redis Labs
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *   * Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *   * Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *   * Neither the name of Redis nor the names of its contributors may be used
14  *     to endorse or promote products derived from this software without
15  *     specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 
31 #include "server.h"
32 #include "connhelpers.h"
33 #include "adlist.h"
34 
35 #ifdef USE_OPENSSL
36 
37 #include <openssl/ssl.h>
38 #include <openssl/err.h>
39 #include <openssl/rand.h>
40 #include <openssl/pem.h>
41 
42 #define REDIS_TLS_PROTO_TLSv1       (1<<0)
43 #define REDIS_TLS_PROTO_TLSv1_1     (1<<1)
44 #define REDIS_TLS_PROTO_TLSv1_2     (1<<2)
45 #define REDIS_TLS_PROTO_TLSv1_3     (1<<3)
46 
47 /* Use safe defaults */
48 #ifdef TLS1_3_VERSION
49 #define REDIS_TLS_PROTO_DEFAULT     (REDIS_TLS_PROTO_TLSv1_2|REDIS_TLS_PROTO_TLSv1_3)
50 #else
51 #define REDIS_TLS_PROTO_DEFAULT     (REDIS_TLS_PROTO_TLSv1_2)
52 #endif
53 
54 extern ConnectionType CT_Socket;
55 
56 SSL_CTX *redis_tls_ctx;
57 
parseProtocolsConfig(const char * str)58 static int parseProtocolsConfig(const char *str) {
59     int i, count = 0;
60     int protocols = 0;
61 
62     if (!str) return REDIS_TLS_PROTO_DEFAULT;
63     sds *tokens = sdssplitlen(str, strlen(str), " ", 1, &count);
64 
65     if (!tokens) {
66         serverLog(LL_WARNING, "Invalid tls-protocols configuration string");
67         return -1;
68     }
69     for (i = 0; i < count; i++) {
70         if (!strcasecmp(tokens[i], "tlsv1")) protocols |= REDIS_TLS_PROTO_TLSv1;
71         else if (!strcasecmp(tokens[i], "tlsv1.1")) protocols |= REDIS_TLS_PROTO_TLSv1_1;
72         else if (!strcasecmp(tokens[i], "tlsv1.2")) protocols |= REDIS_TLS_PROTO_TLSv1_2;
73         else if (!strcasecmp(tokens[i], "tlsv1.3")) {
74 #ifdef TLS1_3_VERSION
75             protocols |= REDIS_TLS_PROTO_TLSv1_3;
76 #else
77             serverLog(LL_WARNING, "TLSv1.3 is specified in tls-protocols but not supported by OpenSSL.");
78             protocols = -1;
79             break;
80 #endif
81         } else {
82             serverLog(LL_WARNING, "Invalid tls-protocols specified. "
83                     "Use a combination of 'TLSv1', 'TLSv1.1', 'TLSv1.2' and 'TLSv1.3'.");
84             protocols = -1;
85             break;
86         }
87     }
88     sdsfreesplitres(tokens, count);
89 
90     return protocols;
91 }
92 
93 /* list of connections with pending data already read from the socket, but not
94  * served to the reader yet. */
95 static list *pending_list = NULL;
96 
97 /**
98  * OpenSSL global initialization and locking handling callbacks.
99  * Note that this is only required for OpenSSL < 1.1.0.
100  */
101 
102 #if OPENSSL_VERSION_NUMBER < 0x10100000L
103 #define USE_CRYPTO_LOCKS
104 #endif
105 
106 #ifdef USE_CRYPTO_LOCKS
107 
108 static pthread_mutex_t *openssl_locks;
109 
sslLockingCallback(int mode,int lock_id,const char * f,int line)110 static void sslLockingCallback(int mode, int lock_id, const char *f, int line) {
111     pthread_mutex_t *mt = openssl_locks + lock_id;
112 
113     if (mode & CRYPTO_LOCK) {
114         pthread_mutex_lock(mt);
115     } else {
116         pthread_mutex_unlock(mt);
117     }
118 
119     (void)f;
120     (void)line;
121 }
122 
initCryptoLocks(void)123 static void initCryptoLocks(void) {
124     unsigned i, nlocks;
125     if (CRYPTO_get_locking_callback() != NULL) {
126         /* Someone already set the callback before us. Don't destroy it! */
127         return;
128     }
129     nlocks = CRYPTO_num_locks();
130     openssl_locks = zmalloc(sizeof(*openssl_locks) * nlocks);
131     for (i = 0; i < nlocks; i++) {
132         pthread_mutex_init(openssl_locks + i, NULL);
133     }
134     CRYPTO_set_locking_callback(sslLockingCallback);
135 }
136 #endif /* USE_CRYPTO_LOCKS */
137 
tlsInit(void)138 void tlsInit(void) {
139     ERR_load_crypto_strings();
140     SSL_load_error_strings();
141     SSL_library_init();
142 
143 #ifdef USE_CRYPTO_LOCKS
144     initCryptoLocks();
145 #endif
146 
147     if (!RAND_poll()) {
148         serverLog(LL_WARNING, "OpenSSL: Failed to seed random number generator.");
149     }
150 
151     pending_list = listCreate();
152 }
153 
154 /* Attempt to configure/reconfigure TLS. This operation is atomic and will
155  * leave the SSL_CTX unchanged if fails.
156  */
tlsConfigure(redisTLSContextConfig * ctx_config)157 int tlsConfigure(redisTLSContextConfig *ctx_config) {
158     char errbuf[256];
159     SSL_CTX *ctx = NULL;
160 
161     if (!ctx_config->cert_file) {
162         serverLog(LL_WARNING, "No tls-cert-file configured!");
163         goto error;
164     }
165 
166     if (!ctx_config->key_file) {
167         serverLog(LL_WARNING, "No tls-key-file configured!");
168         goto error;
169     }
170 
171     if (((server.tls_auth_clients != TLS_CLIENT_AUTH_NO) || server.tls_cluster || server.tls_replication) &&
172             !ctx_config->ca_cert_file && !ctx_config->ca_cert_dir) {
173         serverLog(LL_WARNING, "Either tls-ca-cert-file or tls-ca-cert-dir must be specified when tls-cluster, tls-replication or tls-auth-clients are enabled!");
174         goto error;
175     }
176 
177     ctx = SSL_CTX_new(SSLv23_method());
178 
179     SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
180     SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
181 
182 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
183     SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
184 #endif
185 
186     if (ctx_config->session_caching) {
187         SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
188         SSL_CTX_sess_set_cache_size(ctx, ctx_config->session_cache_size);
189         SSL_CTX_set_timeout(ctx, ctx_config->session_cache_timeout);
190         SSL_CTX_set_session_id_context(ctx, (void *) "redis", 5);
191     } else {
192         SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
193     }
194 
195     int protocols = parseProtocolsConfig(ctx_config->protocols);
196     if (protocols == -1) goto error;
197 
198     if (!(protocols & REDIS_TLS_PROTO_TLSv1))
199         SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
200     if (!(protocols & REDIS_TLS_PROTO_TLSv1_1))
201         SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
202 #ifdef SSL_OP_NO_TLSv1_2
203     if (!(protocols & REDIS_TLS_PROTO_TLSv1_2))
204         SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
205 #endif
206 #ifdef SSL_OP_NO_TLSv1_3
207     if (!(protocols & REDIS_TLS_PROTO_TLSv1_3))
208         SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3);
209 #endif
210 
211 #ifdef SSL_OP_NO_COMPRESSION
212     SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
213 #endif
214 
215 #ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
216     SSL_CTX_set_options(ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
217 #endif
218 
219     if (ctx_config->prefer_server_ciphers)
220         SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
221 
222     SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
223     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
224 #if defined(SSL_CTX_set_ecdh_auto)
225     SSL_CTX_set_ecdh_auto(ctx, 1);
226 #endif
227 
228     if (SSL_CTX_use_certificate_chain_file(ctx, ctx_config->cert_file) <= 0) {
229         ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
230         serverLog(LL_WARNING, "Failed to load certificate: %s: %s", ctx_config->cert_file, errbuf);
231         goto error;
232     }
233 
234     if (SSL_CTX_use_PrivateKey_file(ctx, ctx_config->key_file, SSL_FILETYPE_PEM) <= 0) {
235         ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
236         serverLog(LL_WARNING, "Failed to load private key: %s: %s", ctx_config->key_file, errbuf);
237         goto error;
238     }
239 
240     if ((ctx_config->ca_cert_file || ctx_config->ca_cert_dir) &&
241         SSL_CTX_load_verify_locations(ctx, ctx_config->ca_cert_file, ctx_config->ca_cert_dir) <= 0) {
242         ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
243         serverLog(LL_WARNING, "Failed to configure CA certificate(s) file/directory: %s", errbuf);
244         goto error;
245     }
246 
247     if (ctx_config->dh_params_file) {
248         FILE *dhfile = fopen(ctx_config->dh_params_file, "r");
249         DH *dh = NULL;
250         if (!dhfile) {
251             serverLog(LL_WARNING, "Failed to load %s: %s", ctx_config->dh_params_file, strerror(errno));
252             goto error;
253         }
254 
255         dh = PEM_read_DHparams(dhfile, NULL, NULL, NULL);
256         fclose(dhfile);
257         if (!dh) {
258             serverLog(LL_WARNING, "%s: failed to read DH params.", ctx_config->dh_params_file);
259             goto error;
260         }
261 
262         if (SSL_CTX_set_tmp_dh(ctx, dh) <= 0) {
263             ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
264             serverLog(LL_WARNING, "Failed to load DH params file: %s: %s", ctx_config->dh_params_file, errbuf);
265             DH_free(dh);
266             goto error;
267         }
268 
269         DH_free(dh);
270     }
271 
272     if (ctx_config->ciphers && !SSL_CTX_set_cipher_list(ctx, ctx_config->ciphers)) {
273         serverLog(LL_WARNING, "Failed to configure ciphers: %s", ctx_config->ciphers);
274         goto error;
275     }
276 
277 #ifdef TLS1_3_VERSION
278     if (ctx_config->ciphersuites && !SSL_CTX_set_ciphersuites(ctx, ctx_config->ciphersuites)) {
279         serverLog(LL_WARNING, "Failed to configure ciphersuites: %s", ctx_config->ciphersuites);
280         goto error;
281     }
282 #endif
283 
284     SSL_CTX_free(redis_tls_ctx);
285     redis_tls_ctx = ctx;
286 
287     return C_OK;
288 
289 error:
290     if (ctx) SSL_CTX_free(ctx);
291     return C_ERR;
292 }
293 
294 #ifdef TLS_DEBUGGING
295 #define TLSCONN_DEBUG(fmt, ...) \
296     serverLog(LL_DEBUG, "TLSCONN: " fmt, __VA_ARGS__)
297 #else
298 #define TLSCONN_DEBUG(fmt, ...)
299 #endif
300 
301 ConnectionType CT_TLS;
302 
303 /* Normal socket connections have a simple events/handler correlation.
304  *
305  * With TLS connections we need to handle cases where during a logical read
306  * or write operation, the SSL library asks to block for the opposite
307  * socket operation.
308  *
309  * When this happens, we need to do two things:
310  * 1. Make sure we register for the even.
311  * 2. Make sure we know which handler needs to execute when the
312  *    event fires.  That is, if we notify the caller of a write operation
313  *    that it blocks, and SSL asks for a read, we need to trigger the
314  *    write handler again on the next read event.
315  *
316  */
317 
318 typedef enum {
319     WANT_READ = 1,
320     WANT_WRITE
321 } WantIOType;
322 
323 #define TLS_CONN_FLAG_READ_WANT_WRITE   (1<<0)
324 #define TLS_CONN_FLAG_WRITE_WANT_READ   (1<<1)
325 #define TLS_CONN_FLAG_FD_SET            (1<<2)
326 
327 typedef struct tls_connection {
328     connection c;
329     int flags;
330     SSL *ssl;
331     char *ssl_error;
332     listNode *pending_list_node;
333 } tls_connection;
334 
connCreateTLS(void)335 connection *connCreateTLS(void) {
336     tls_connection *conn = zcalloc(sizeof(tls_connection));
337     conn->c.type = &CT_TLS;
338     conn->c.fd = -1;
339     conn->ssl = SSL_new(redis_tls_ctx);
340     return (connection *) conn;
341 }
342 
343 /* Fetch the latest OpenSSL error and store it in the connection */
updateTLSError(tls_connection * conn)344 static void updateTLSError(tls_connection *conn) {
345     conn->c.last_errno = 0;
346     if (conn->ssl_error) zfree(conn->ssl_error);
347     conn->ssl_error = zmalloc(512);
348     ERR_error_string_n(ERR_get_error(), conn->ssl_error, 512);
349 }
350 
351 /* Create a new TLS connection that is already associated with
352  * an accepted underlying file descriptor.
353  *
354  * The socket is not ready for I/O until connAccept() was called and
355  * invoked the connection-level accept handler.
356  *
357  * Callers should use connGetState() and verify the created connection
358  * is not in an error state.
359  */
connCreateAcceptedTLS(int fd,int require_auth)360 connection *connCreateAcceptedTLS(int fd, int require_auth) {
361     tls_connection *conn = (tls_connection *) connCreateTLS();
362     conn->c.fd = fd;
363     conn->c.state = CONN_STATE_ACCEPTING;
364 
365     if (!conn->ssl) {
366         updateTLSError(conn);
367         conn->c.state = CONN_STATE_ERROR;
368         return (connection *) conn;
369     }
370 
371     switch (require_auth) {
372         case TLS_CLIENT_AUTH_NO:
373             SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
374             break;
375         case TLS_CLIENT_AUTH_OPTIONAL:
376             SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, NULL);
377             break;
378         default: /* TLS_CLIENT_AUTH_YES, also fall-secure */
379             SSL_set_verify(conn->ssl, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
380             break;
381     }
382 
383     SSL_set_fd(conn->ssl, conn->c.fd);
384     SSL_set_accept_state(conn->ssl);
385 
386     return (connection *) conn;
387 }
388 
389 static void tlsEventHandler(struct aeEventLoop *el, int fd, void *clientData, int mask);
390 
391 /* Process the return code received from OpenSSL>
392  * Update the want parameter with expected I/O.
393  * Update the connection's error state if a real error has occured.
394  * Returns an SSL error code, or 0 if no further handling is required.
395  */
handleSSLReturnCode(tls_connection * conn,int ret_value,WantIOType * want)396 static int handleSSLReturnCode(tls_connection *conn, int ret_value, WantIOType *want) {
397     if (ret_value <= 0) {
398         int ssl_err = SSL_get_error(conn->ssl, ret_value);
399         switch (ssl_err) {
400             case SSL_ERROR_WANT_WRITE:
401                 *want = WANT_WRITE;
402                 return 0;
403             case SSL_ERROR_WANT_READ:
404                 *want = WANT_READ;
405                 return 0;
406             case SSL_ERROR_SYSCALL:
407                 conn->c.last_errno = errno;
408                 if (conn->ssl_error) zfree(conn->ssl_error);
409                 conn->ssl_error = errno ? zstrdup(strerror(errno)) : NULL;
410                 break;
411             default:
412                 /* Error! */
413                 updateTLSError(conn);
414                 break;
415         }
416 
417         return ssl_err;
418     }
419 
420     return 0;
421 }
422 
registerSSLEvent(tls_connection * conn,WantIOType want)423 void registerSSLEvent(tls_connection *conn, WantIOType want) {
424     int mask = aeGetFileEvents(server.el, conn->c.fd);
425 
426     switch (want) {
427         case WANT_READ:
428             if (mask & AE_WRITABLE) aeDeleteFileEvent(server.el, conn->c.fd, AE_WRITABLE);
429             if (!(mask & AE_READABLE)) aeCreateFileEvent(server.el, conn->c.fd, AE_READABLE,
430                         tlsEventHandler, conn);
431             break;
432         case WANT_WRITE:
433             if (mask & AE_READABLE) aeDeleteFileEvent(server.el, conn->c.fd, AE_READABLE);
434             if (!(mask & AE_WRITABLE)) aeCreateFileEvent(server.el, conn->c.fd, AE_WRITABLE,
435                         tlsEventHandler, conn);
436             break;
437         default:
438             serverAssert(0);
439             break;
440     }
441 }
442 
updateSSLEvent(tls_connection * conn)443 void updateSSLEvent(tls_connection *conn) {
444     int mask = aeGetFileEvents(server.el, conn->c.fd);
445     int need_read = conn->c.read_handler || (conn->flags & TLS_CONN_FLAG_WRITE_WANT_READ);
446     int need_write = conn->c.write_handler || (conn->flags & TLS_CONN_FLAG_READ_WANT_WRITE);
447 
448     if (need_read && !(mask & AE_READABLE))
449         aeCreateFileEvent(server.el, conn->c.fd, AE_READABLE, tlsEventHandler, conn);
450     if (!need_read && (mask & AE_READABLE))
451         aeDeleteFileEvent(server.el, conn->c.fd, AE_READABLE);
452 
453     if (need_write && !(mask & AE_WRITABLE))
454         aeCreateFileEvent(server.el, conn->c.fd, AE_WRITABLE, tlsEventHandler, conn);
455     if (!need_write && (mask & AE_WRITABLE))
456         aeDeleteFileEvent(server.el, conn->c.fd, AE_WRITABLE);
457 }
458 
tlsHandleEvent(tls_connection * conn,int mask)459 static void tlsHandleEvent(tls_connection *conn, int mask) {
460     int ret, conn_error;
461 
462     TLSCONN_DEBUG("tlsEventHandler(): fd=%d, state=%d, mask=%d, r=%d, w=%d, flags=%d",
463             fd, conn->c.state, mask, conn->c.read_handler != NULL, conn->c.write_handler != NULL,
464             conn->flags);
465 
466     ERR_clear_error();
467 
468     switch (conn->c.state) {
469         case CONN_STATE_CONNECTING:
470             conn_error = connGetSocketError((connection *) conn);
471             if (conn_error) {
472                 conn->c.last_errno = conn_error;
473                 conn->c.state = CONN_STATE_ERROR;
474             } else {
475                 if (!(conn->flags & TLS_CONN_FLAG_FD_SET)) {
476                     SSL_set_fd(conn->ssl, conn->c.fd);
477                     conn->flags |= TLS_CONN_FLAG_FD_SET;
478                 }
479                 ret = SSL_connect(conn->ssl);
480                 if (ret <= 0) {
481                     WantIOType want = 0;
482                     if (!handleSSLReturnCode(conn, ret, &want)) {
483                         registerSSLEvent(conn, want);
484 
485                         /* Avoid hitting UpdateSSLEvent, which knows nothing
486                          * of what SSL_connect() wants and instead looks at our
487                          * R/W handlers.
488                          */
489                         return;
490                     }
491 
492                     /* If not handled, it's an error */
493                     conn->c.state = CONN_STATE_ERROR;
494                 } else {
495                     conn->c.state = CONN_STATE_CONNECTED;
496                 }
497             }
498 
499             if (!callHandler((connection *) conn, conn->c.conn_handler)) return;
500             conn->c.conn_handler = NULL;
501             break;
502         case CONN_STATE_ACCEPTING:
503             ret = SSL_accept(conn->ssl);
504             if (ret <= 0) {
505                 WantIOType want = 0;
506                 if (!handleSSLReturnCode(conn, ret, &want)) {
507                     /* Avoid hitting UpdateSSLEvent, which knows nothing
508                      * of what SSL_connect() wants and instead looks at our
509                      * R/W handlers.
510                      */
511                     registerSSLEvent(conn, want);
512                     return;
513                 }
514 
515                 /* If not handled, it's an error */
516                 conn->c.state = CONN_STATE_ERROR;
517             } else {
518                 conn->c.state = CONN_STATE_CONNECTED;
519             }
520 
521             if (!callHandler((connection *) conn, conn->c.conn_handler)) return;
522             conn->c.conn_handler = NULL;
523             break;
524         case CONN_STATE_CONNECTED:
525         {
526             int call_read = ((mask & AE_READABLE) && conn->c.read_handler) ||
527                 ((mask & AE_WRITABLE) && (conn->flags & TLS_CONN_FLAG_READ_WANT_WRITE));
528             int call_write = ((mask & AE_WRITABLE) && conn->c.write_handler) ||
529                 ((mask & AE_READABLE) && (conn->flags & TLS_CONN_FLAG_WRITE_WANT_READ));
530 
531             /* Normally we execute the readable event first, and the writable
532              * event laster. This is useful as sometimes we may be able
533              * to serve the reply of a query immediately after processing the
534              * query.
535              *
536              * However if WRITE_BARRIER is set in the mask, our application is
537              * asking us to do the reverse: never fire the writable event
538              * after the readable. In such a case, we invert the calls.
539              * This is useful when, for instance, we want to do things
540              * in the beforeSleep() hook, like fsynching a file to disk,
541              * before replying to a client. */
542             int invert = conn->c.flags & CONN_FLAG_WRITE_BARRIER;
543 
544             if (!invert && call_read) {
545                 conn->flags &= ~TLS_CONN_FLAG_READ_WANT_WRITE;
546                 if (!callHandler((connection *) conn, conn->c.read_handler)) return;
547             }
548 
549             /* Fire the writable event. */
550             if (call_write) {
551                 conn->flags &= ~TLS_CONN_FLAG_WRITE_WANT_READ;
552                 if (!callHandler((connection *) conn, conn->c.write_handler)) return;
553             }
554 
555             /* If we have to invert the call, fire the readable event now
556              * after the writable one. */
557             if (invert && call_read) {
558                 conn->flags &= ~TLS_CONN_FLAG_READ_WANT_WRITE;
559                 if (!callHandler((connection *) conn, conn->c.read_handler)) return;
560             }
561 
562             /* If SSL has pending that, already read from the socket, we're at
563              * risk of not calling the read handler again, make sure to add it
564              * to a list of pending connection that should be handled anyway. */
565             if ((mask & AE_READABLE)) {
566                 if (SSL_pending(conn->ssl) > 0) {
567                     if (!conn->pending_list_node) {
568                         listAddNodeTail(pending_list, conn);
569                         conn->pending_list_node = listLast(pending_list);
570                     }
571                 } else if (conn->pending_list_node) {
572                     listDelNode(pending_list, conn->pending_list_node);
573                     conn->pending_list_node = NULL;
574                 }
575             }
576 
577             break;
578         }
579         default:
580             break;
581     }
582 
583     updateSSLEvent(conn);
584 }
585 
tlsEventHandler(struct aeEventLoop * el,int fd,void * clientData,int mask)586 static void tlsEventHandler(struct aeEventLoop *el, int fd, void *clientData, int mask) {
587     UNUSED(el);
588     UNUSED(fd);
589     tls_connection *conn = clientData;
590     tlsHandleEvent(conn, mask);
591 }
592 
connTLSClose(connection * conn_)593 static void connTLSClose(connection *conn_) {
594     tls_connection *conn = (tls_connection *) conn_;
595 
596     if (conn->ssl) {
597         SSL_free(conn->ssl);
598         conn->ssl = NULL;
599     }
600 
601     if (conn->ssl_error) {
602         zfree(conn->ssl_error);
603         conn->ssl_error = NULL;
604     }
605 
606     if (conn->pending_list_node) {
607         listDelNode(pending_list, conn->pending_list_node);
608         conn->pending_list_node = NULL;
609     }
610 
611     CT_Socket.close(conn_);
612 }
613 
connTLSAccept(connection * _conn,ConnectionCallbackFunc accept_handler)614 static int connTLSAccept(connection *_conn, ConnectionCallbackFunc accept_handler) {
615     tls_connection *conn = (tls_connection *) _conn;
616     int ret;
617 
618     if (conn->c.state != CONN_STATE_ACCEPTING) return C_ERR;
619     ERR_clear_error();
620 
621     /* Try to accept */
622     conn->c.conn_handler = accept_handler;
623     ret = SSL_accept(conn->ssl);
624 
625     if (ret <= 0) {
626         WantIOType want = 0;
627         if (!handleSSLReturnCode(conn, ret, &want)) {
628             registerSSLEvent(conn, want);   /* We'll fire back */
629             return C_OK;
630         } else {
631             conn->c.state = CONN_STATE_ERROR;
632             return C_ERR;
633         }
634     }
635 
636     conn->c.state = CONN_STATE_CONNECTED;
637     if (!callHandler((connection *) conn, conn->c.conn_handler)) return C_OK;
638     conn->c.conn_handler = NULL;
639 
640     return C_OK;
641 }
642 
connTLSConnect(connection * conn_,const char * addr,int port,const char * src_addr,ConnectionCallbackFunc connect_handler)643 static int connTLSConnect(connection *conn_, const char *addr, int port, const char *src_addr, ConnectionCallbackFunc connect_handler) {
644     tls_connection *conn = (tls_connection *) conn_;
645 
646     if (conn->c.state != CONN_STATE_NONE) return C_ERR;
647     ERR_clear_error();
648 
649     /* Initiate Socket connection first */
650     if (CT_Socket.connect(conn_, addr, port, src_addr, connect_handler) == C_ERR) return C_ERR;
651 
652     /* Return now, once the socket is connected we'll initiate
653      * TLS connection from the event handler.
654      */
655     return C_OK;
656 }
657 
connTLSWrite(connection * conn_,const void * data,size_t data_len)658 static int connTLSWrite(connection *conn_, const void *data, size_t data_len) {
659     tls_connection *conn = (tls_connection *) conn_;
660     int ret, ssl_err;
661 
662     if (conn->c.state != CONN_STATE_CONNECTED) return -1;
663     ERR_clear_error();
664     ret = SSL_write(conn->ssl, data, data_len);
665 
666     if (ret <= 0) {
667         WantIOType want = 0;
668         if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) {
669             if (want == WANT_READ) conn->flags |= TLS_CONN_FLAG_WRITE_WANT_READ;
670             updateSSLEvent(conn);
671             errno = EAGAIN;
672             return -1;
673         } else {
674             if (ssl_err == SSL_ERROR_ZERO_RETURN ||
675                     ((ssl_err == SSL_ERROR_SYSCALL && !errno))) {
676                 conn->c.state = CONN_STATE_CLOSED;
677                 return 0;
678             } else {
679                 conn->c.state = CONN_STATE_ERROR;
680                 return -1;
681             }
682         }
683     }
684 
685     return ret;
686 }
687 
connTLSRead(connection * conn_,void * buf,size_t buf_len)688 static int connTLSRead(connection *conn_, void *buf, size_t buf_len) {
689     tls_connection *conn = (tls_connection *) conn_;
690     int ret;
691     int ssl_err;
692 
693     if (conn->c.state != CONN_STATE_CONNECTED) return -1;
694     ERR_clear_error();
695     ret = SSL_read(conn->ssl, buf, buf_len);
696     if (ret <= 0) {
697         WantIOType want = 0;
698         if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) {
699             if (want == WANT_WRITE) conn->flags |= TLS_CONN_FLAG_READ_WANT_WRITE;
700             updateSSLEvent(conn);
701 
702             errno = EAGAIN;
703             return -1;
704         } else {
705             if (ssl_err == SSL_ERROR_ZERO_RETURN ||
706                     ((ssl_err == SSL_ERROR_SYSCALL) && !errno)) {
707                 conn->c.state = CONN_STATE_CLOSED;
708                 return 0;
709             } else {
710                 conn->c.state = CONN_STATE_ERROR;
711                 return -1;
712             }
713         }
714     }
715 
716     return ret;
717 }
718 
connTLSGetLastError(connection * conn_)719 static const char *connTLSGetLastError(connection *conn_) {
720     tls_connection *conn = (tls_connection *) conn_;
721 
722     if (conn->ssl_error) return conn->ssl_error;
723     return NULL;
724 }
725 
connTLSSetWriteHandler(connection * conn,ConnectionCallbackFunc func,int barrier)726 int connTLSSetWriteHandler(connection *conn, ConnectionCallbackFunc func, int barrier) {
727     conn->write_handler = func;
728     if (barrier)
729         conn->flags |= CONN_FLAG_WRITE_BARRIER;
730     else
731         conn->flags &= ~CONN_FLAG_WRITE_BARRIER;
732     updateSSLEvent((tls_connection *) conn);
733     return C_OK;
734 }
735 
connTLSSetReadHandler(connection * conn,ConnectionCallbackFunc func)736 int connTLSSetReadHandler(connection *conn, ConnectionCallbackFunc func) {
737     conn->read_handler = func;
738     updateSSLEvent((tls_connection *) conn);
739     return C_OK;
740 }
741 
setBlockingTimeout(tls_connection * conn,long long timeout)742 static void setBlockingTimeout(tls_connection *conn, long long timeout) {
743     anetBlock(NULL, conn->c.fd);
744     anetSendTimeout(NULL, conn->c.fd, timeout);
745     anetRecvTimeout(NULL, conn->c.fd, timeout);
746 }
747 
unsetBlockingTimeout(tls_connection * conn)748 static void unsetBlockingTimeout(tls_connection *conn) {
749     anetNonBlock(NULL, conn->c.fd);
750     anetSendTimeout(NULL, conn->c.fd, 0);
751     anetRecvTimeout(NULL, conn->c.fd, 0);
752 }
753 
connTLSBlockingConnect(connection * conn_,const char * addr,int port,long long timeout)754 static int connTLSBlockingConnect(connection *conn_, const char *addr, int port, long long timeout) {
755     tls_connection *conn = (tls_connection *) conn_;
756     int ret;
757 
758     if (conn->c.state != CONN_STATE_NONE) return C_ERR;
759 
760     /* Initiate socket blocking connect first */
761     if (CT_Socket.blocking_connect(conn_, addr, port, timeout) == C_ERR) return C_ERR;
762 
763     /* Initiate TLS connection now.  We set up a send/recv timeout on the socket,
764      * which means the specified timeout will not be enforced accurately. */
765     SSL_set_fd(conn->ssl, conn->c.fd);
766     setBlockingTimeout(conn, timeout);
767 
768     if ((ret = SSL_connect(conn->ssl)) <= 0) {
769         conn->c.state = CONN_STATE_ERROR;
770         return C_ERR;
771     }
772     unsetBlockingTimeout(conn);
773 
774     conn->c.state = CONN_STATE_CONNECTED;
775     return C_OK;
776 }
777 
connTLSSyncWrite(connection * conn_,char * ptr,ssize_t size,long long timeout)778 static ssize_t connTLSSyncWrite(connection *conn_, char *ptr, ssize_t size, long long timeout) {
779     tls_connection *conn = (tls_connection *) conn_;
780 
781     setBlockingTimeout(conn, timeout);
782     SSL_clear_mode(conn->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
783     int ret = SSL_write(conn->ssl, ptr, size);
784     SSL_set_mode(conn->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
785     unsetBlockingTimeout(conn);
786 
787     return ret;
788 }
789 
connTLSSyncRead(connection * conn_,char * ptr,ssize_t size,long long timeout)790 static ssize_t connTLSSyncRead(connection *conn_, char *ptr, ssize_t size, long long timeout) {
791     tls_connection *conn = (tls_connection *) conn_;
792 
793     setBlockingTimeout(conn, timeout);
794     int ret = SSL_read(conn->ssl, ptr, size);
795     unsetBlockingTimeout(conn);
796 
797     return ret;
798 }
799 
connTLSSyncReadLine(connection * conn_,char * ptr,ssize_t size,long long timeout)800 static ssize_t connTLSSyncReadLine(connection *conn_, char *ptr, ssize_t size, long long timeout) {
801     tls_connection *conn = (tls_connection *) conn_;
802     ssize_t nread = 0;
803 
804     setBlockingTimeout(conn, timeout);
805 
806     size--;
807     while(size) {
808         char c;
809 
810         if (SSL_read(conn->ssl,&c,1) <= 0) {
811             nread = -1;
812             goto exit;
813         }
814         if (c == '\n') {
815             *ptr = '\0';
816             if (nread && *(ptr-1) == '\r') *(ptr-1) = '\0';
817             goto exit;
818         } else {
819             *ptr++ = c;
820             *ptr = '\0';
821             nread++;
822         }
823         size--;
824     }
825 exit:
826     unsetBlockingTimeout(conn);
827     return nread;
828 }
829 
connTLSGetType(connection * conn_)830 static int connTLSGetType(connection *conn_) {
831     (void) conn_;
832 
833     return CONN_TYPE_TLS;
834 }
835 
836 ConnectionType CT_TLS = {
837     .ae_handler = tlsEventHandler,
838     .accept = connTLSAccept,
839     .connect = connTLSConnect,
840     .blocking_connect = connTLSBlockingConnect,
841     .read = connTLSRead,
842     .write = connTLSWrite,
843     .close = connTLSClose,
844     .set_write_handler = connTLSSetWriteHandler,
845     .set_read_handler = connTLSSetReadHandler,
846     .get_last_error = connTLSGetLastError,
847     .sync_write = connTLSSyncWrite,
848     .sync_read = connTLSSyncRead,
849     .sync_readline = connTLSSyncReadLine,
850     .get_type = connTLSGetType
851 };
852 
tlsHasPendingData()853 int tlsHasPendingData() {
854     if (!pending_list)
855         return 0;
856     return listLength(pending_list) > 0;
857 }
858 
tlsProcessPendingData()859 int tlsProcessPendingData() {
860     listIter li;
861     listNode *ln;
862 
863     int processed = listLength(pending_list);
864     listRewind(pending_list,&li);
865     while((ln = listNext(&li))) {
866         tls_connection *conn = listNodeValue(ln);
867         tlsHandleEvent(conn, AE_READABLE);
868     }
869     return processed;
870 }
871 
872 /* Fetch the peer certificate used for authentication on the specified
873  * connection and return it as a PEM-encoded sds.
874  */
connTLSGetPeerCert(connection * conn_)875 sds connTLSGetPeerCert(connection *conn_) {
876     tls_connection *conn = (tls_connection *) conn_;
877     if (conn_->type->get_type(conn_) != CONN_TYPE_TLS || !conn->ssl) return NULL;
878 
879     X509 *cert = SSL_get_peer_certificate(conn->ssl);
880     if (!cert) return NULL;
881 
882     BIO *bio = BIO_new(BIO_s_mem());
883     if (bio == NULL || !PEM_write_bio_X509(bio, cert)) {
884         if (bio != NULL) BIO_free(bio);
885         return NULL;
886     }
887 
888     const char *bio_ptr;
889     long long bio_len = BIO_get_mem_data(bio, &bio_ptr);
890     sds cert_pem = sdsnewlen(bio_ptr, bio_len);
891     BIO_free(bio);
892 
893     return cert_pem;
894 }
895 
896 #else   /* USE_OPENSSL */
897 
tlsInit(void)898 void tlsInit(void) {
899 }
900 
tlsConfigure(redisTLSContextConfig * ctx_config)901 int tlsConfigure(redisTLSContextConfig *ctx_config) {
902     UNUSED(ctx_config);
903     return C_OK;
904 }
905 
connCreateTLS(void)906 connection *connCreateTLS(void) {
907     return NULL;
908 }
909 
connCreateAcceptedTLS(int fd,int require_auth)910 connection *connCreateAcceptedTLS(int fd, int require_auth) {
911     UNUSED(fd);
912     UNUSED(require_auth);
913 
914     return NULL;
915 }
916 
tlsHasPendingData()917 int tlsHasPendingData() {
918     return 0;
919 }
920 
tlsProcessPendingData()921 int tlsProcessPendingData() {
922     return 0;
923 }
924 
connTLSGetPeerCert(connection * conn_)925 sds connTLSGetPeerCert(connection *conn_) {
926     (void) conn_;
927     return NULL;
928 }
929 
930 #endif
931