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