1 #include "memcached.h"
2 
3 #ifdef TLS
4 
5 #include "tls.h"
6 #include <string.h>
7 #include <sysexits.h>
8 #include <sys/param.h>
9 #include <openssl/err.h>
10 
11 #ifndef MAXPATHLEN
12 #define MAXPATHLEN 4096
13 #endif
14 
15 static pthread_mutex_t ssl_ctx_lock = PTHREAD_MUTEX_INITIALIZER;
16 
17 const unsigned ERROR_MSG_SIZE = 64;
18 const size_t SSL_ERROR_MSG_SIZE = 256;
19 
SSL_LOCK()20 void SSL_LOCK() {
21     pthread_mutex_lock(&(ssl_ctx_lock));
22 }
23 
SSL_UNLOCK(void)24 void SSL_UNLOCK(void) {
25     pthread_mutex_unlock(&(ssl_ctx_lock));
26 }
27 
28 /*
29  * Reads decrypted data from the underlying BIO read buffers,
30  * which reads from the socket.
31  */
ssl_read(conn * c,void * buf,size_t count)32 ssize_t ssl_read(conn *c, void *buf, size_t count) {
33     assert (c != NULL);
34     /* TODO : document the state machine interactions for SSL_read with
35         non-blocking sockets/ SSL re-negotiations
36     */
37     return SSL_read(c->ssl, buf, count);
38 }
39 
40 /*
41  * SSL sendmsg implementation. Perform a SSL_write.
42  */
ssl_sendmsg(conn * c,struct msghdr * msg,int flags)43 ssize_t ssl_sendmsg(conn *c, struct msghdr *msg, int flags) {
44     assert (c != NULL);
45     size_t buf_remain = settings.ssl_wbuf_size;
46     size_t bytes = 0;
47     size_t to_copy;
48     int i;
49 
50     // ssl_wbuf is pointing to the buffer allocated in the worker thread.
51     assert(c->ssl_wbuf);
52     // TODO: allocate a fix buffer in crawler/logger if they start using
53     // the sendmsg method. Also, set c->ssl_wbuf  when the side thread
54     // start owning the connection and reset the pointer in
55     // conn_worker_readd.
56     // Currently this connection would not be served by a different thread
57     // than the one it's assigned.
58     assert(pthread_equal(c->thread->thread_id, pthread_self()) != 0);
59 
60     char *bp = c->ssl_wbuf;
61     for (i = 0; i < msg->msg_iovlen; i++) {
62         size_t len = msg->msg_iov[i].iov_len;
63         to_copy = len < buf_remain ? len : buf_remain;
64 
65         memcpy(bp + bytes, (void*)msg->msg_iov[i].iov_base, to_copy);
66         buf_remain -= to_copy;
67         bytes += to_copy;
68         if (buf_remain == 0)
69             break;
70     }
71     /* TODO : document the state machine interactions for SSL_write with
72         non-blocking sockets/ SSL re-negotiations
73     */
74     return SSL_write(c->ssl, c->ssl_wbuf, bytes);
75 }
76 
77 /*
78  * Writes data to the underlying BIO write buffers,
79  * which encrypt and write them to the socket.
80  */
ssl_write(conn * c,void * buf,size_t count)81 ssize_t ssl_write(conn *c, void *buf, size_t count) {
82     assert (c != NULL);
83     return SSL_write(c->ssl, buf, count);
84 }
85 
86 /*
87  * Prints an SSL error into the buff, if there's any.
88  */
print_ssl_error(char * buff,size_t len)89 static void print_ssl_error(char *buff, size_t len) {
90     unsigned long err;
91     if ((err = ERR_get_error()) != 0) {
92         ERR_error_string_n(err, buff, len);
93     }
94 }
95 
96 /*
97  * Loads server certificates to the SSL context and validate them.
98  * @return whether certificates are successfully loaded and verified or not.
99  * @param error_msg contains the error when unsuccessful.
100  */
load_server_certificates(char ** errmsg)101 static bool load_server_certificates(char **errmsg) {
102     bool success = false;
103 
104     const size_t CRLF_NULLCHAR_LEN = 3;
105     char *error_msg = malloc(MAXPATHLEN + ERROR_MSG_SIZE +
106         SSL_ERROR_MSG_SIZE);
107     size_t errmax = MAXPATHLEN + ERROR_MSG_SIZE + SSL_ERROR_MSG_SIZE -
108         CRLF_NULLCHAR_LEN;
109 
110     if (error_msg == NULL) {
111         *errmsg = NULL;
112         return false;
113     }
114 
115     if (settings.ssl_ctx == NULL) {
116         snprintf(error_msg, errmax, "Error TLS not enabled\r\n");
117         *errmsg = error_msg;
118         return false;
119     }
120 
121     char *ssl_err_msg = malloc(SSL_ERROR_MSG_SIZE);
122     if (ssl_err_msg == NULL) {
123         free(error_msg);
124         *errmsg = NULL;
125         return false;
126     }
127     bzero(ssl_err_msg, SSL_ERROR_MSG_SIZE);
128     size_t err_msg_size = 0;
129 
130     SSL_LOCK();
131     if (!SSL_CTX_use_certificate_chain_file(settings.ssl_ctx,
132         settings.ssl_chain_cert)) {
133         print_ssl_error(ssl_err_msg, SSL_ERROR_MSG_SIZE);
134         err_msg_size = snprintf(error_msg, errmax, "Error loading the certificate chain: "
135             "%s : %s", settings.ssl_chain_cert, ssl_err_msg);
136     } else if (!SSL_CTX_use_PrivateKey_file(settings.ssl_ctx, settings.ssl_key,
137                                         settings.ssl_keyformat)) {
138         print_ssl_error(ssl_err_msg, SSL_ERROR_MSG_SIZE);
139         err_msg_size = snprintf(error_msg, errmax, "Error loading the key: %s : %s",
140             settings.ssl_key, ssl_err_msg);
141     } else if (!SSL_CTX_check_private_key(settings.ssl_ctx)) {
142         print_ssl_error(ssl_err_msg, SSL_ERROR_MSG_SIZE);
143         err_msg_size = snprintf(error_msg, errmax, "Error validating the certificate: %s",
144             ssl_err_msg);
145     } else if (settings.ssl_ca_cert) {
146         if (!SSL_CTX_load_verify_locations(settings.ssl_ctx,
147           settings.ssl_ca_cert, NULL)) {
148             print_ssl_error(ssl_err_msg, SSL_ERROR_MSG_SIZE);
149             err_msg_size = snprintf(error_msg, errmax,
150               "Error loading the CA certificate: %s : %s",
151               settings.ssl_ca_cert, ssl_err_msg);
152         } else {
153             SSL_CTX_set_client_CA_list(settings.ssl_ctx,
154               SSL_load_client_CA_file(settings.ssl_ca_cert));
155             success = true;
156         }
157     } else {
158         success = true;
159     }
160     SSL_UNLOCK();
161     free(ssl_err_msg);
162     if (success) {
163         settings.ssl_last_cert_refresh_time = current_time;
164         free(error_msg);
165     } else {
166         *errmsg = error_msg;
167         error_msg += (err_msg_size >= errmax ? errmax - 1: err_msg_size);
168         snprintf(error_msg, CRLF_NULLCHAR_LEN, "\r\n");
169         // Print if there are more errors and drain the queue.
170         ERR_print_errors_fp(stderr);
171     }
172     return success;
173 }
174 
175 /*
176  * Verify SSL settings and initiates the SSL context.
177  */
ssl_init(void)178 int ssl_init(void) {
179     assert(settings.ssl_enabled);
180 
181     // SSL context for the process. All connections will share one
182     // process level context.
183     settings.ssl_ctx = SSL_CTX_new(TLS_server_method());
184 
185     SSL_CTX_set_min_proto_version(settings.ssl_ctx, settings.ssl_min_version);
186 
187     // The server certificate, private key and validations.
188     char *error_msg;
189     if (!load_server_certificates(&error_msg)) {
190         fprintf(stderr, "%s", error_msg);
191         free(error_msg);
192         exit(EX_USAGE);
193     }
194 
195     // The verification mode of client certificate, default is SSL_VERIFY_PEER.
196     SSL_CTX_set_verify(settings.ssl_ctx, settings.ssl_verify_mode, NULL);
197     if (settings.ssl_ciphers && !SSL_CTX_set_cipher_list(settings.ssl_ctx,
198                                                     settings.ssl_ciphers)) {
199         fprintf(stderr, "Error setting the provided cipher(s): %s\n",
200                 settings.ssl_ciphers);
201         exit(EX_USAGE);
202     }
203 
204     // Optional session caching; default disabled.
205     if (settings.ssl_session_cache) {
206         SSL_CTX_sess_set_new_cb(settings.ssl_ctx, ssl_new_session_callback);
207         SSL_CTX_set_session_cache_mode(settings.ssl_ctx, SSL_SESS_CACHE_SERVER);
208         SSL_CTX_set_session_id_context(settings.ssl_ctx,
209                                        (const unsigned char *) SESSION_ID_CONTEXT,
210                                        strlen(SESSION_ID_CONTEXT));
211     } else {
212         SSL_CTX_set_session_cache_mode(settings.ssl_ctx, SSL_SESS_CACHE_OFF);
213     }
214 
215     return 0;
216 }
217 
218 /*
219  * This method is registered with each SSL connection and abort the SSL session
220  * if a client initiates a renegotiation.
221  * TODO : Proper way to do this is to set SSL_OP_NO_RENEGOTIATION
222  *       using the SSL_CTX_set_options but that option only available in
223  *       openssl 1.1.0h or above.
224  */
ssl_callback(const SSL * s,int where,int ret)225 void ssl_callback(const SSL *s, int where, int ret) {
226     SSL* ssl = (SSL*)s;
227     if (SSL_in_before(ssl)) {
228         fprintf(stderr, "%d: SSL renegotiation is not supported, "
229                 "closing the connection\n", SSL_get_fd(ssl));
230         SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
231         return;
232     }
233 }
234 
235 /*
236  * This method is invoked with every new successfully negotiated SSL session,
237  * when server-side session caching is enabled. Note that this method is not
238  * invoked when a session is reused.
239  */
ssl_new_session_callback(SSL * s,SSL_SESSION * sess)240 int ssl_new_session_callback(SSL *s, SSL_SESSION *sess) {
241     STATS_LOCK();
242     stats.ssl_new_sessions++;
243     STATS_UNLOCK();
244 
245     return 0;
246 }
247 
refresh_certs(char ** errmsg)248 bool refresh_certs(char **errmsg) {
249     return load_server_certificates(errmsg);
250 }
251 
ssl_proto_text(int version)252 const char *ssl_proto_text(int version) {
253     switch (version) {
254         case TLS1_VERSION:
255             return "tlsv1.0";
256         case TLS1_1_VERSION:
257             return "tlsv1.1";
258         case TLS1_2_VERSION:
259             return "tlsv1.2";
260 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
261         case TLS1_3_VERSION:
262             return "tlsv1.3";
263 #endif
264         default:
265             return "unknown";
266     }
267 }
268 #endif
269