2 Bacula® - The Network Backup Solution
4 Copyright (C) 2005-2007 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 two of the GNU 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 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 John Walker.
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>
35 * This file was contributed to the Bacula project by Landon Fuller
36 * and Three Rings Design, Inc.
38 * Three Rings Design, Inc. has been granted a perpetual, worldwide,
39 * non-exclusive, no-charge, royalty-free, irrevocable copyright
40 * license to reproduce, prepare derivative works of, publicly
41 * display, publicly perform, sublicense, and distribute the original
42 * work contributed by Three Rings Design, Inc. and its employees to
43 * the Bacula project in source or object form.
45 * If you wish to license contributions from Three Rings Design, Inc,
46 * under an alternate open source license please contact
47 * Landon Fuller <landonf@threerings.net>.
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 Jmsg5(NULL, 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 Jmsg0(NULL, 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 Jmsg0(NULL, M_ERROR, 0,
203 _("Error setting cipher list, no valid ciphers available\n"));
207 /* Verify Peer Certificate */
209 /* SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */
210 SSL_CTX_set_verify(ctx->openssl,
211 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
212 openssl_verify_peer);
218 /* Clean up after ourselves */
220 SSL_CTX_free(ctx->openssl);
227 * Free TLS_CONTEXT instance
229 void free_tls_context(TLS_CONTEXT *ctx)
231 SSL_CTX_free(ctx->openssl);
235 bool get_tls_require(TLS_CONTEXT *ctx)
237 return ctx->tls_require;
240 bool get_tls_enable(TLS_CONTEXT *ctx)
242 return ctx->tls_enable;
247 * Verifies a list of common names against the certificate
248 * commonName attribute.
249 * Returns: true on success
252 bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list)
254 SSL *ssl = tls->openssl;
257 bool auth_success = false;
260 /* Check if peer provided a certificate */
261 if (!(cert = SSL_get_peer_certificate(ssl))) {
262 Jmsg0(NULL, M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
266 if ((subject = X509_get_subject_name(cert)) != NULL) {
267 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
269 /* NULL terminate data */
272 /* Try all the CNs in the list */
273 foreach_alist(cn, verify_list) {
274 if (strcasecmp(data, cn) == 0) {
286 * Verifies a peer's hostname against the subjectAltName and commonName
288 * Returns: true on success
291 bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host)
293 SSL *ssl = tls->openssl;
296 bool auth_success = false;
302 /* Check if peer provided a certificate */
303 if (!(cert = SSL_get_peer_certificate(ssl))) {
304 Jmsg1(NULL, M_ERROR, 0,
305 _("Peer %s failed to present a TLS certificate\n"), host);
309 /* Check subjectAltName extensions first */
310 if ((extensions = X509_get_ext_count(cert)) > 0) {
311 for (i = 0; i < extensions; i++) {
315 ext = X509_get_ext(cert, i);
316 extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
318 if (strcmp(extname, "subjectAltName") == 0) {
319 X509V3_EXT_METHOD *method;
320 STACK_OF(CONF_VALUE) *val;
323 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
324 const unsigned char *ext_value_data;
326 unsigned char *ext_value_data;
329 /* Get x509 extension method structure */
330 if (!(method = X509V3_EXT_get(ext))) {
334 ext_value_data = ext->value->data;
336 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
340 /* Decode ASN1 item in data */
341 extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
342 ASN1_ITEM_ptr(method->it));
346 /* Decode ASN1 item in data */
347 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
351 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
354 /* Iterate through to find the dNSName field(s) */
355 val = method->i2v(method, extstr, NULL);
357 /* dNSName shortname is "DNS" */
358 for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
359 nval = sk_CONF_VALUE_value(val, j);
360 if (strcmp(nval->name, "DNS") == 0) {
361 if (strcasecmp(nval->value, host) == 0) {
371 /* Try verifying against the subject name */
373 if ((subject = X509_get_subject_name(cert)) != NULL) {
374 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
375 /* NULL terminate data */
377 if (strcasecmp(data, host) == 0) {
391 * Create a new TLS_CONNECTION instance.
393 * Returns: Pointer to TLS_CONNECTION instance on success
396 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
401 * Create a new BIO and assign the fd.
402 * The caller will remain responsible for closing the associated fd
404 bio = BIO_new(BIO_s_socket());
406 /* Not likely, but never say never */
407 openssl_post_errors(M_ERROR, _("Error creating file descriptor-based BIO"));
408 return NULL; /* Nothing allocated, nothing to clean up */
410 BIO_set_fd(bio, fd, BIO_NOCLOSE);
412 /* Allocate our new tls connection */
413 TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
415 /* Create the SSL object and attach the socket BIO */
416 if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
417 /* Not likely, but never say never */
418 openssl_post_errors(M_ERROR, _("Error creating new SSL object"));
422 SSL_set_bio(tls->openssl, bio, bio);
424 /* Non-blocking partial writes */
425 SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
432 SSL_free(tls->openssl);
438 * Free TLS_CONNECTION instance
440 void free_tls_connection(TLS_CONNECTION *tls)
442 SSL_free(tls->openssl);
446 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
447 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
449 TLS_CONNECTION *tls = bsock->tls;
456 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
458 fdmax = bsock->m_fd + 1;
460 /* Ensure that socket is non-blocking */
461 flags = bsock->set_nonblocking();
464 bsock->timer_start = watchdog_time;
465 bsock->clear_timed_out();
469 err = SSL_accept(tls->openssl);
471 err = SSL_connect(tls->openssl);
475 switch (SSL_get_error(tls->openssl, err)) {
479 case SSL_ERROR_ZERO_RETURN:
480 /* TLS connection was cleanly shut down */
481 openssl_post_errors(M_ERROR, _("Connect failure"));
484 case SSL_ERROR_WANT_READ:
485 /* If we timeout of a select, this will be unset */
486 FD_SET((unsigned) bsock->m_fd, &fdset);
487 /* Set our timeout */
490 /* Block until we can read */
491 select(fdmax, &fdset, NULL, NULL, &tv);
493 case SSL_ERROR_WANT_WRITE:
494 /* If we timeout of a select, this will be unset */
495 FD_SET((unsigned) bsock->m_fd, &fdset);
496 /* Set our timeout */
499 /* Block until we can write */
500 select(fdmax, NULL, &fdset, NULL, &tv);
503 /* Socket Error Occured */
504 openssl_post_errors(M_ERROR, _("Connect failure"));
509 if (bsock->is_timed_out()) {
515 /* Restore saved flags */
516 bsock->restore_blocking(flags);
518 bsock->timer_start = 0;
524 * Initiates a TLS connection with the server.
525 * Returns: true on success
528 bool tls_bsock_connect(BSOCK *bsock)
530 /* SSL_connect(bsock->tls) */
531 return openssl_bsock_session_start(bsock, false);
535 * Listens for a TLS connection from a client.
536 * Returns: true on success
539 bool tls_bsock_accept(BSOCK *bsock)
541 /* SSL_accept(bsock->tls) */
542 return openssl_bsock_session_start(bsock, true);
546 * Shutdown TLS_CONNECTION instance
548 void tls_bsock_shutdown(BSOCK *bsock)
551 * SSL_shutdown must be called twice to fully complete the process -
552 * The first time to initiate the shutdown handshake, and the second to
553 * receive the peer's reply.
555 * In addition, if the underlying socket is blocking, SSL_shutdown()
556 * will not return until the current stage of the shutdown process has
557 * completed or an error has occured. By setting the socket blocking
558 * we can avoid the ugly for()/switch()/select() loop.
562 /* Set socket blocking for shutdown */
563 bsock->set_blocking();
565 err = SSL_shutdown(bsock->tls->openssl);
567 /* Complete shutdown */
568 err = SSL_shutdown(bsock->tls->openssl);
571 switch (SSL_get_error(bsock->tls->openssl, err)) {
574 case SSL_ERROR_ZERO_RETURN:
575 /* TLS connection was shut down on us via a TLS protocol-level closure */
576 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
579 /* Socket Error Occurred */
580 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
585 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
586 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
588 TLS_CONNECTION *tls = bsock->tls;
595 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
597 fdmax = bsock->m_fd + 1;
599 /* Ensure that socket is non-blocking */
600 flags = bsock->set_nonblocking();
603 bsock->timer_start = watchdog_time;
604 bsock->clear_timed_out();
610 nwritten = SSL_write(tls->openssl, ptr, nleft);
612 nwritten = SSL_read(tls->openssl, ptr, nleft);
616 switch (SSL_get_error(tls->openssl, nwritten)) {
624 case SSL_ERROR_WANT_READ:
625 /* If we timeout on a select, this will be unset */
626 FD_SET((unsigned)bsock->m_fd, &fdset);
629 /* Block until we can read */
630 select(fdmax, &fdset, NULL, NULL, &tv);
633 case SSL_ERROR_WANT_WRITE:
634 /* If we timeout on 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, NULL, &tv);
642 case SSL_ERROR_ZERO_RETURN:
643 /* TLS connection was cleanly shut down */
644 /* Fall through wanted */
646 /* Socket Error Occured */
647 openssl_post_errors(M_ERROR, _("TLS read/write failure."));
651 /* Everything done? */
656 /* Timeout/Termination, let's take what we can get */
657 if (bsock->is_timed_out() || bsock->is_terminated()) {
663 /* Restore saved flags */
664 bsock->restore_blocking(flags);
667 bsock->timer_start = 0;
668 return nbytes - nleft;
672 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes)
674 /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
675 return openssl_bsock_readwrite(bsock, ptr, nbytes, true);
678 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes)
680 /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
681 return openssl_bsock_readwrite(bsock, ptr, nbytes, false);
684 #else /* HAVE_OPENSSL */
685 # error No TLS implementation available.
686 #endif /* !HAVE_OPENSSL */
689 #else /* TLS NOT enabled, dummy routines substituted */
693 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
694 const char *certfile, const char *keyfile,
695 CRYPTO_PEM_PASSWD_CB *pem_callback,
696 const void *pem_userdata, const char *dhfile,
701 void free_tls_context(TLS_CONTEXT *ctx) { }
703 void tls_bsock_shutdown(BSOCK *bsock) { }
705 void free_tls_connection(TLS_CONNECTION *tls) { }
707 bool get_tls_require(TLS_CONTEXT *ctx)
712 bool get_tls_enable(TLS_CONTEXT *ctx)
717 #endif /* HAVE_TLS */