2 * tls.c TLS support functions
4 * Author: Landon Fuller <landonf@threerings.net>
8 * This file was contributed to the Bacula project by Landon Fuller
9 * and Three Rings Design, Inc.
11 * Three Rings Design, Inc. has been granted a perpetual, worldwide,
12 * non-exclusive, no-charge, royalty-free, irrevocable copyright
13 * license to reproduce, prepare derivative works of, publicly
14 * display, publicly perform, sublicense, and distribute the original
15 * work contributed by Three Rings Design, Inc. and its employees to
16 * the Bacula project in source or object form.
18 * If you wish to license contributions from Three Rings Design, Inc,
19 * under an alternate open source license please contact
20 * Landon Fuller <landonf@threerings.net>.
23 Bacula® - The Network Backup Solution
25 Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
27 The main author of Bacula is Kern Sibbald, with contributions from
28 many others, a complete list can be found in the file AUTHORS.
29 This program is Free Software; you can redistribute it and/or
30 modify it under the terms of version two of the GNU General Public
31 License as published by the Free Software Foundation plus additions
32 that are listed in the file LICENSE.
34 This program is distributed in the hope that it will be useful, but
35 WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37 General Public License for more details.
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
44 Bacula® is a registered trademark of John Walker.
45 The licensor of Bacula is the Free Software Foundation Europe
46 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
47 Switzerland, email:ftf@fsfeurope.org.
54 extern time_t watchdog_time;
56 #ifdef HAVE_TLS /* Is TLS enabled? */
58 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
60 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
61 #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
63 /* TLS Context Structure */
66 CRYPTO_PEM_PASSWD_CB *pem_callback;
67 const void *pem_userdata;
72 struct TLS_Connection {
77 * OpenSSL certificate verification callback.
78 * OpenSSL has already performed internal certificate verification.
79 * We just report any errors that occured.
81 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
84 X509 *cert = X509_STORE_CTX_get_current_cert(store);
85 int depth = X509_STORE_CTX_get_error_depth(store);
86 int err = X509_STORE_CTX_get_error(store);
90 X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
91 X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
93 Emsg5(M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s,"
94 " subject = %s, ERR=%d:%s\n"), depth, issuer,
95 subject, err, X509_verify_cert_error_string(err));
102 /* Dispatch user PEM encryption callbacks */
103 static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
105 TLS_CONTEXT *ctx = (TLS_CONTEXT *) userdata;
106 return (ctx->pem_callback(buf, size, ctx->pem_userdata));
110 * Create a new TLS_CONTEXT instance.
111 * Returns: Pointer to TLS_CONTEXT instance on success
114 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
115 const char *certfile, const char *keyfile,
116 CRYPTO_PEM_PASSWD_CB *pem_callback,
117 const void *pem_userdata, const char *dhfile,
124 ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT));
126 /* Allocate our OpenSSL TLSv1 Context */
127 ctx->openssl = SSL_CTX_new(TLSv1_method());
130 openssl_post_errors(M_ERROR, _("Error initializing SSL context"));
134 /* Set up pem encryption callback */
136 ctx->pem_callback = pem_callback;
137 ctx->pem_userdata = pem_userdata;
139 ctx->pem_callback = crypto_default_pem_callback;
140 ctx->pem_userdata = NULL;
142 SSL_CTX_set_default_passwd_cb(ctx->openssl, tls_pem_callback_dispatch);
143 SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx);
146 * Set certificate verification paths. This requires that at least one
149 if (ca_certfile || ca_certdir) {
150 if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) {
151 openssl_post_errors(M_ERROR, _("Error loading certificate verification stores"));
154 } else if (verify_peer) {
155 /* At least one CA is required for peer verification */
156 Emsg0(M_ERROR, 0, _("Either a certificate file or a directory must be"
157 " specified as a verification store\n"));
162 * Load our certificate file, if available. This file may also contain a
163 * private key, though this usage is somewhat unusual.
166 if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
167 openssl_post_errors(M_ERROR, _("Error loading certificate file"));
172 /* Load our private key. */
174 if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
175 openssl_post_errors(M_ERROR, _("Error loading private key"));
180 /* Load Diffie-Hellman Parameters. */
182 if (!(bio = BIO_new_file(dhfile, "r"))) {
183 openssl_post_errors(M_ERROR, _("Unable to open DH parameters file"));
186 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
189 openssl_post_errors(M_ERROR, _("Unable to load DH parameters from specified file"));
192 if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
193 openssl_post_errors(M_ERROR, _("Failed to set TLS Diffie-Hellman parameters"));
197 /* Enable Single-Use DH for Ephemeral Keying */
198 SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
201 if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
202 Emsg0(M_ERROR, 0, _("Error setting cipher list, no valid ciphers available\n"));
206 /* Verify Peer Certificate */
208 /* SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */
209 SSL_CTX_set_verify(ctx->openssl,
210 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
211 openssl_verify_peer);
217 /* Clean up after ourselves */
219 SSL_CTX_free(ctx->openssl);
226 * Free TLS_CONTEXT instance
228 void free_tls_context(TLS_CONTEXT *ctx)
230 SSL_CTX_free(ctx->openssl);
235 * Verifies a list of common names against the certificate
236 * commonName attribute.
237 * Returns: true on success
240 bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list)
242 SSL *ssl = tls->openssl;
245 bool auth_success = false;
248 /* Check if peer provided a certificate */
249 if (!(cert = SSL_get_peer_certificate(ssl))) {
250 Emsg0(M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
254 if ((subject = X509_get_subject_name(cert)) != NULL) {
255 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
257 /* NULL terminate data */
260 /* Try all the CNs in the list */
261 foreach_alist(cn, verify_list) {
262 if (strcasecmp(data, cn) == 0) {
274 * Verifies a peer's hostname against the subjectAltName and commonName
276 * Returns: true on success
279 bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host)
281 SSL *ssl = tls->openssl;
284 bool auth_success = false;
290 /* Check if peer provided a certificate */
291 if (!(cert = SSL_get_peer_certificate(ssl))) {
292 Emsg1(M_ERROR, 0, _("Peer %s failed to present a TLS certificate\n"), host);
296 /* Check subjectAltName extensions first */
297 if ((extensions = X509_get_ext_count(cert)) > 0) {
298 for (i = 0; i < extensions; i++) {
302 ext = X509_get_ext(cert, i);
303 extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
305 if (strcmp(extname, "subjectAltName") == 0) {
306 X509V3_EXT_METHOD *method;
307 STACK_OF(CONF_VALUE) *val;
310 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
311 const unsigned char *ext_value_data;
313 unsigned char *ext_value_data;
316 /* Get x509 extension method structure */
317 if (!(method = X509V3_EXT_get(ext))) {
321 ext_value_data = ext->value->data;
323 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
327 /* Decode ASN1 item in data */
328 extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
329 ASN1_ITEM_ptr(method->it));
333 /* Decode ASN1 item in data */
334 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
338 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
341 /* Iterate through to find the dNSName field(s) */
342 val = method->i2v(method, extstr, NULL);
344 /* dNSName shortname is "DNS" */
345 for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
346 nval = sk_CONF_VALUE_value(val, j);
347 if (strcmp(nval->name, "DNS") == 0) {
348 if (strcasecmp(nval->value, host) == 0) {
358 /* Try verifying against the subject name */
360 if ((subject = X509_get_subject_name(cert)) != NULL) {
361 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
362 /* NULL terminate data */
364 if (strcasecmp(data, host) == 0) {
379 * Create a new TLS_CONNECTION instance.
381 * Returns: Pointer to TLS_CONNECTION instance on success
384 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
389 * Create a new BIO and assign the fd.
390 * The caller will remain responsible for closing the associated fd
392 bio = BIO_new(BIO_s_socket());
394 /* Not likely, but never say never */
395 openssl_post_errors(M_ERROR, _("Error creating file descriptor-based BIO"));
396 return NULL; /* Nothing allocated, nothing to clean up */
398 BIO_set_fd(bio, fd, BIO_NOCLOSE);
400 /* Allocate our new tls connection */
401 TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
403 /* Create the SSL object and attach the socket BIO */
404 if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
405 /* Not likely, but never say never */
406 openssl_post_errors(M_ERROR, _("Error creating new SSL object"));
410 SSL_set_bio(tls->openssl, bio, bio);
412 /* Non-blocking partial writes */
413 SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
420 SSL_free(tls->openssl);
427 * Free TLS_CONNECTION instance
429 void free_tls_connection(TLS_CONNECTION *tls)
431 SSL_free(tls->openssl);
435 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
436 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
438 TLS_CONNECTION *tls = bsock->tls;
445 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
447 fdmax = bsock->m_fd + 1;
449 /* Ensure that socket is non-blocking */
450 flags = bnet_set_nonblocking(bsock);
453 bsock->timer_start = watchdog_time;
454 bsock->m_timed_out = 0;
458 err = SSL_accept(tls->openssl);
460 err = SSL_connect(tls->openssl);
464 switch (SSL_get_error(tls->openssl, err)) {
468 case SSL_ERROR_ZERO_RETURN:
469 /* TLS connection was cleanly shut down */
470 openssl_post_errors(M_ERROR, _("Connect failure"));
473 case SSL_ERROR_WANT_READ:
474 /* If we timeout of a select, this will be unset */
475 FD_SET((unsigned) bsock->m_fd, &fdset);
476 /* Set our timeout */
479 /* Block until we can read */
480 select(fdmax, &fdset, NULL, &fdset, &tv);
482 case SSL_ERROR_WANT_WRITE:
483 /* If we timeout of a select, this will be unset */
484 FD_SET((unsigned) bsock->m_fd, &fdset);
485 /* Set our timeout */
488 /* Block until we can write */
489 select(fdmax, NULL, &fdset, &fdset, &tv);
492 /* Socket Error Occured */
493 openssl_post_errors(M_ERROR, _("Connect failure"));
498 if (bsock->is_timed_out()) {
504 /* Restore saved flags */
505 bnet_restore_blocking(bsock, flags);
507 bsock->timer_start = 0;
513 * Initiates a TLS connection with the server.
514 * Returns: true on success
517 bool tls_bsock_connect(BSOCK *bsock)
519 /* SSL_connect(bsock->tls) */
520 return (openssl_bsock_session_start(bsock, false));
524 * Listens for a TLS connection from a client.
525 * Returns: true on success
528 bool tls_bsock_accept(BSOCK *bsock)
530 /* SSL_accept(bsock->tls) */
531 return (openssl_bsock_session_start(bsock, true));
535 * Shutdown TLS_CONNECTION instance
537 void tls_bsock_shutdown(BSOCK *bsock)
540 * SSL_shutdown must be called twice to fully complete the process -
541 * The first time to initiate the shutdown handshake, and the second to
542 * receive the peer's reply.
544 * However, it is valid to close the SSL connection after the initial
545 * shutdown notification is sent to the peer, without waiting for the
546 * peer's reply, as long as you do not plan to re-use that particular
547 * SSL connection object.
549 * Because we do not re-use SSL connection objects, I do not bother
550 * calling SSL_shutdown a second time.
552 * In addition, if the underlying socket is blocking, SSL_shutdown()
553 * will not return until the current stage of the shutdown process has
554 * completed or an error has occured. By setting the socket blocking
555 * we can avoid the ugly for()/switch()/select() loop.
560 /* Set socket blocking for shutdown */
561 flags = bsock->set_blocking();
563 err = SSL_shutdown(bsock->tls->openssl);
565 switch (SSL_get_error(bsock->tls->openssl, err)) {
568 case SSL_ERROR_ZERO_RETURN:
569 /* TLS connection was shut down on us via a TLS protocol-level closure */
570 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
573 /* Socket Error Occured */
574 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
578 /* Restore saved flags */
579 bsock->restore_blocking(flags);
582 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
583 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
585 TLS_CONNECTION *tls = bsock->tls;
592 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
594 fdmax = bsock->m_fd + 1;
596 /* Ensure that socket is non-blocking */
597 flags = bsock->set_nonblocking();
600 bsock->timer_start = watchdog_time;
601 bsock->m_timed_out = 0;
608 nwritten = SSL_write(tls->openssl, ptr, nleft);
610 nwritten = SSL_read(tls->openssl, ptr, nleft);
614 switch (SSL_get_error(tls->openssl, nwritten)) {
621 case SSL_ERROR_ZERO_RETURN:
622 /* TLS connection was cleanly shut down */
623 openssl_post_errors(M_ERROR, _("TLS read/write failure."));
625 case SSL_ERROR_WANT_READ:
626 /* If we timeout of a select, this will be unset */
627 FD_SET((unsigned) bsock->m_fd, &fdset);
630 /* Block until we can read */
631 select(fdmax, &fdset, NULL, &fdset, &tv);
633 case SSL_ERROR_WANT_WRITE:
634 /* If we timeout of a select, this will be unset */
635 FD_SET((unsigned) bsock->m_fd, &fdset);
638 /* Block until we can write */
639 select(fdmax, NULL, &fdset, &fdset, &tv);
642 /* Socket Error Occured */
643 openssl_post_errors(M_ERROR, _("TLS read/write failure."));
647 /* Everything done? */
652 /* Timeout/Termination, let's take what we can get */
653 if (bsock->is_timed_out() || bsock->is_terminated()) {
659 /* Restore saved flags */
660 bsock->restore_blocking(flags);
663 bsock->timer_start = 0;
665 return nbytes - nleft;
669 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) {
670 /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
671 return (openssl_bsock_readwrite(bsock, ptr, nbytes, true));
674 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) {
675 /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
676 return (openssl_bsock_readwrite(bsock, ptr, nbytes, false));
679 #else /* HAVE_OPENSSL */
680 # error No TLS implementation available.
681 #endif /* !HAVE_OPENSSL */
686 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
687 const char *certfile, const char *keyfile,
688 CRYPTO_PEM_PASSWD_CB *pem_callback,
689 const void *pem_userdata, const char *dhfile,
694 void free_tls_context(TLS_CONTEXT *ctx) { }
696 #endif /* HAVE_TLS */