2 Bacula® - The Network Backup Solution
4 Copyright (C) 2005-2010 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * tls.c TLS support functions
31 * Author: Landon Fuller <landonf@threerings.net>
33 * This file was contributed to the Bacula project by Landon Fuller
34 * and Three Rings Design, Inc.
36 * Three Rings Design, Inc. has been granted a perpetual, worldwide,
37 * non-exclusive, no-charge, royalty-free, irrevocable copyright
38 * license to reproduce, prepare derivative works of, publicly
39 * display, publicly perform, sublicense, and distribute the original
40 * work contributed by Three Rings Design, Inc. and its employees to
41 * the Bacula project in source or object form.
43 * If you wish to license contributions from Three Rings Design, Inc,
44 * under an alternate open source license please contact
45 * Landon Fuller <landonf@threerings.net>.
53 #ifdef HAVE_TLS /* Is TLS enabled? */
55 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
57 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
58 #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
60 /* TLS Context Structure */
63 CRYPTO_PEM_PASSWD_CB *pem_callback;
64 const void *pem_userdata;
69 struct TLS_Connection {
74 * OpenSSL certificate verification callback.
75 * OpenSSL has already performed internal certificate verification.
76 * We just report any errors that occured.
78 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
81 X509 *cert = X509_STORE_CTX_get_current_cert(store);
82 int depth = X509_STORE_CTX_get_error_depth(store);
83 int err = X509_STORE_CTX_get_error(store);
87 X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
88 X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
90 Jmsg5(NULL, M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s,"
91 " subject = %s, ERR=%d:%s\n"), depth, issuer,
92 subject, err, X509_verify_cert_error_string(err));
99 /* Dispatch user PEM encryption callbacks */
100 static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
102 TLS_CONTEXT *ctx = (TLS_CONTEXT *)userdata;
103 return (ctx->pem_callback(buf, size, ctx->pem_userdata));
107 * Create a new TLS_CONTEXT instance.
108 * Returns: Pointer to TLS_CONTEXT instance on success
111 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
112 const char *certfile, const char *keyfile,
113 CRYPTO_PEM_PASSWD_CB *pem_callback,
114 const void *pem_userdata, const char *dhfile,
121 ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT));
123 /* Allocate our OpenSSL TLSv1 Context */
124 ctx->openssl = SSL_CTX_new(TLSv1_method());
127 openssl_post_errors(M_FATAL, _("Error initializing SSL context"));
131 /* Set up pem encryption callback */
133 ctx->pem_callback = pem_callback;
134 ctx->pem_userdata = pem_userdata;
136 ctx->pem_callback = crypto_default_pem_callback;
137 ctx->pem_userdata = NULL;
139 SSL_CTX_set_default_passwd_cb(ctx->openssl, tls_pem_callback_dispatch);
140 SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx);
143 * Set certificate verification paths. This requires that at least one
146 if (ca_certfile || ca_certdir) {
147 if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) {
148 openssl_post_errors(M_FATAL, _("Error loading certificate verification stores"));
151 } else if (verify_peer) {
152 /* At least one CA is required for peer verification */
153 Jmsg0(NULL, M_ERROR, 0, _("Either a certificate file or a directory must be"
154 " specified as a verification store\n"));
159 * Load our certificate file, if available. This file may also contain a
160 * private key, though this usage is somewhat unusual.
163 if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
164 openssl_post_errors(M_FATAL, _("Error loading certificate file"));
169 /* Load our private key. */
171 if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
172 openssl_post_errors(M_FATAL, _("Error loading private key"));
177 /* Load Diffie-Hellman Parameters. */
179 if (!(bio = BIO_new_file(dhfile, "r"))) {
180 openssl_post_errors(M_FATAL, _("Unable to open DH parameters file"));
183 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
186 openssl_post_errors(M_FATAL, _("Unable to load DH parameters from specified file"));
189 if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
190 openssl_post_errors(M_FATAL, _("Failed to set TLS Diffie-Hellman parameters"));
194 /* Enable Single-Use DH for Ephemeral Keying */
195 SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
198 if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
199 Jmsg0(NULL, M_ERROR, 0,
200 _("Error setting cipher list, no valid ciphers available\n"));
204 /* Verify Peer Certificate */
206 /* SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */
207 SSL_CTX_set_verify(ctx->openssl,
208 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
209 openssl_verify_peer);
215 /* Clean up after ourselves */
217 SSL_CTX_free(ctx->openssl);
224 * Free TLS_CONTEXT instance
226 void free_tls_context(TLS_CONTEXT *ctx)
228 SSL_CTX_free(ctx->openssl);
232 bool get_tls_require(TLS_CONTEXT *ctx)
234 return ctx->tls_require;
237 bool get_tls_enable(TLS_CONTEXT *ctx)
239 return ctx->tls_enable;
244 * Verifies a list of common names against the certificate
245 * commonName attribute.
246 * Returns: true on success
249 bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list)
251 SSL *ssl = tls->openssl;
254 bool auth_success = false;
257 /* Check if peer provided a certificate */
258 if (!(cert = SSL_get_peer_certificate(ssl))) {
259 Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
263 if ((subject = X509_get_subject_name(cert)) != NULL) {
264 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
266 /* NULL terminate data */
269 /* Try all the CNs in the list */
270 foreach_alist(cn, verify_list) {
271 if (strcasecmp(data, cn) == 0) {
283 * Verifies a peer's hostname against the subjectAltName and commonName
285 * Returns: true on success
288 bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host)
290 SSL *ssl = tls->openssl;
293 bool auth_success = false;
298 X509_NAME_ENTRY *neCN;
301 /* Check if peer provided a certificate */
302 if (!(cert = SSL_get_peer_certificate(ssl))) {
303 Qmsg1(jcr, M_ERROR, 0,
304 _("Peer %s failed to present a TLS certificate\n"), host);
308 /* Check subjectAltName extensions first */
309 if ((extensions = X509_get_ext_count(cert)) > 0) {
310 for (i = 0; i < extensions; i++) {
314 ext = X509_get_ext(cert, i);
315 extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
317 if (strcmp(extname, "subjectAltName") == 0) {
318 #ifdef HAVE_OPENSSLv1
319 const X509V3_EXT_METHOD *method;
321 X509V3_EXT_METHOD *method;
323 STACK_OF(CONF_VALUE) *val;
326 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
327 const unsigned char *ext_value_data;
329 unsigned char *ext_value_data;
332 /* Get x509 extension method structure */
333 if (!(method = X509V3_EXT_get(ext))) {
337 ext_value_data = ext->value->data;
339 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
343 /* Decode ASN1 item in data */
344 extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
345 ASN1_ITEM_ptr(method->it));
349 /* Decode ASN1 item in data */
350 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
354 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
357 /* Iterate through to find the dNSName field(s) */
358 val = method->i2v(method, extstr, NULL);
360 /* dNSName shortname is "DNS" */
361 for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
362 nval = sk_CONF_VALUE_value(val, j);
363 if (strcmp(nval->name, "DNS") == 0) {
364 if (strcasecmp(nval->value, host) == 0) {
374 /* Try verifying against the subject name */
376 if ((subject = X509_get_subject_name(cert)) != NULL) {
377 /* Loop through all CNs */
379 cnLastPos = X509_NAME_get_index_by_NID(subject, NID_commonName, cnLastPos);
380 if (cnLastPos == -1) {
383 neCN = X509_NAME_get_entry(subject, cnLastPos);
384 asn1CN = X509_NAME_ENTRY_get_data(neCN);
385 if (strcasecmp((const char*)asn1CN->data, host) == 0) {
400 * Create a new TLS_CONNECTION instance.
402 * Returns: Pointer to TLS_CONNECTION instance on success
405 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
410 * Create a new BIO and assign the fd.
411 * The caller will remain responsible for closing the associated fd
413 bio = BIO_new(BIO_s_socket());
415 /* Not likely, but never say never */
416 openssl_post_errors(M_FATAL, _("Error creating file descriptor-based BIO"));
417 return NULL; /* Nothing allocated, nothing to clean up */
419 BIO_set_fd(bio, fd, BIO_NOCLOSE);
421 /* Allocate our new tls connection */
422 TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
424 /* Create the SSL object and attach the socket BIO */
425 if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
426 /* Not likely, but never say never */
427 openssl_post_errors(M_FATAL, _("Error creating new SSL object"));
431 SSL_set_bio(tls->openssl, bio, bio);
433 /* Non-blocking partial writes */
434 SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
441 SSL_free(tls->openssl);
447 * Free TLS_CONNECTION instance
449 void free_tls_connection(TLS_CONNECTION *tls)
451 SSL_free(tls->openssl);
455 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
456 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
458 TLS_CONNECTION *tls = bsock->tls;
465 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
467 fdmax = bsock->m_fd + 1;
469 /* Ensure that socket is non-blocking */
470 flags = bsock->set_nonblocking();
473 bsock->timer_start = watchdog_time;
474 bsock->clear_timed_out();
475 bsock->set_killable(false);
479 err = SSL_accept(tls->openssl);
481 err = SSL_connect(tls->openssl);
485 switch (SSL_get_error(tls->openssl, err)) {
489 case SSL_ERROR_ZERO_RETURN:
490 /* TLS connection was cleanly shut down */
491 openssl_post_errors(bsock->get_jcr(), M_FATAL, _("Connect failure"));
494 case SSL_ERROR_WANT_READ:
495 /* If we timeout of a select, this will be unset */
496 FD_SET((unsigned) bsock->m_fd, &fdset);
497 /* Set our timeout */
500 /* Block until we can read */
501 select(fdmax, &fdset, NULL, NULL, &tv);
503 case SSL_ERROR_WANT_WRITE:
504 /* If we timeout of a select, this will be unset */
505 FD_SET((unsigned) bsock->m_fd, &fdset);
506 /* Set our timeout */
509 /* Block until we can write */
510 select(fdmax, NULL, &fdset, NULL, &tv);
513 /* Socket Error Occurred */
514 openssl_post_errors(bsock->get_jcr(), M_FATAL, _("Connect failure"));
519 if (bsock->is_timed_out()) {
525 /* Restore saved flags */
526 bsock->restore_blocking(flags);
528 bsock->timer_start = 0;
529 bsock->set_killable(true);
535 * Initiates a TLS connection with the server.
536 * Returns: true on success
539 bool tls_bsock_connect(BSOCK *bsock)
541 /* SSL_connect(bsock->tls) */
542 return openssl_bsock_session_start(bsock, false);
546 * Listens for a TLS connection from a client.
547 * Returns: true on success
550 bool tls_bsock_accept(BSOCK *bsock)
552 /* SSL_accept(bsock->tls) */
553 return openssl_bsock_session_start(bsock, true);
557 * Shutdown TLS_CONNECTION instance
559 void tls_bsock_shutdown(BSOCK *bsock)
562 * SSL_shutdown must be called twice to fully complete the process -
563 * The first time to initiate the shutdown handshake, and the second to
564 * receive the peer's reply.
566 * In addition, if the underlying socket is blocking, SSL_shutdown()
567 * will not return until the current stage of the shutdown process has
568 * completed or an error has occured. By setting the socket blocking
569 * we can avoid the ugly for()/switch()/select() loop.
575 /* Set socket blocking for shutdown */
576 bsock->set_blocking();
578 tid = start_bsock_timer(bsock, 60 * 2);
579 err = SSL_shutdown(bsock->tls->openssl);
580 stop_bsock_timer(tid);
582 /* Complete shutdown */
583 tid = start_bsock_timer(bsock, 60 * 2);
584 err = SSL_shutdown(bsock->tls->openssl);
585 stop_bsock_timer(tid);
589 switch (SSL_get_error(bsock->tls->openssl, err)) {
592 case SSL_ERROR_ZERO_RETURN:
593 /* TLS connection was shut down on us via a TLS protocol-level closure */
594 openssl_post_errors(bsock->get_jcr(), M_ERROR, _("TLS shutdown failure."));
597 /* Socket Error Occurred */
598 openssl_post_errors(bsock->get_jcr(), M_ERROR, _("TLS shutdown failure."));
603 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
604 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
606 TLS_CONNECTION *tls = bsock->tls;
613 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
615 fdmax = bsock->m_fd + 1;
617 /* Ensure that socket is non-blocking */
618 flags = bsock->set_nonblocking();
621 bsock->timer_start = watchdog_time;
622 bsock->clear_timed_out();
623 bsock->set_killable(false);
629 nwritten = SSL_write(tls->openssl, ptr, nleft);
631 nwritten = SSL_read(tls->openssl, ptr, nleft);
635 switch (SSL_get_error(tls->openssl, nwritten)) {
643 case SSL_ERROR_SYSCALL:
644 if (nwritten == -1) {
645 if (errno == EINTR) {
648 if (errno == EAGAIN) {
649 bmicrosleep(0, 20000); /* try again in 20 ms */
653 openssl_post_errors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure."));
656 case SSL_ERROR_WANT_READ:
657 /* If we timeout on a select, this will be unset */
658 FD_SET((unsigned)bsock->m_fd, &fdset);
661 /* Block until we can read */
662 select(fdmax, &fdset, NULL, NULL, &tv);
665 case SSL_ERROR_WANT_WRITE:
666 /* If we timeout on a select, this will be unset */
667 FD_SET((unsigned)bsock->m_fd, &fdset);
670 /* Block until we can write */
671 select(fdmax, NULL, &fdset, NULL, &tv);
674 case SSL_ERROR_ZERO_RETURN:
675 /* TLS connection was cleanly shut down */
676 /* Fall through wanted */
678 /* Socket Error Occured */
679 openssl_post_errors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure."));
683 /* Everything done? */
688 /* Timeout/Termination, let's take what we can get */
689 if (bsock->is_timed_out() || bsock->is_terminated()) {
695 /* Restore saved flags */
696 bsock->restore_blocking(flags);
699 bsock->timer_start = 0;
700 bsock->set_killable(true);
701 return nbytes - nleft;
705 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes)
707 /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
708 return openssl_bsock_readwrite(bsock, ptr, nbytes, true);
711 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes)
713 /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
714 return openssl_bsock_readwrite(bsock, ptr, nbytes, false);
717 #else /* HAVE_OPENSSL */
718 # error No TLS implementation available.
719 #endif /* !HAVE_OPENSSL */
722 #else /* TLS NOT enabled, dummy routines substituted */
726 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
727 const char *certfile, const char *keyfile,
728 CRYPTO_PEM_PASSWD_CB *pem_callback,
729 const void *pem_userdata, const char *dhfile,
734 void free_tls_context(TLS_CONTEXT *ctx) { }
736 void tls_bsock_shutdown(BSOCK *bsock) { }
738 void free_tls_connection(TLS_CONNECTION *tls) { }
740 bool get_tls_require(TLS_CONTEXT *ctx)
745 bool get_tls_enable(TLS_CONTEXT *ctx)
750 #endif /* HAVE_TLS */