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);
234 bool get_tls_require(TLS_CONTEXT *ctx)
236 return ctx->tls_require;
239 bool get_tls_enable(TLS_CONTEXT *ctx)
241 return ctx->tls_enable;
246 * Verifies a list of common names against the certificate
247 * commonName attribute.
248 * Returns: true on success
251 bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list)
253 SSL *ssl = tls->openssl;
256 bool auth_success = false;
259 /* Check if peer provided a certificate */
260 if (!(cert = SSL_get_peer_certificate(ssl))) {
261 Emsg0(M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
265 if ((subject = X509_get_subject_name(cert)) != NULL) {
266 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
268 /* NULL terminate data */
271 /* Try all the CNs in the list */
272 foreach_alist(cn, verify_list) {
273 if (strcasecmp(data, cn) == 0) {
285 * Verifies a peer's hostname against the subjectAltName and commonName
287 * Returns: true on success
290 bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host)
292 SSL *ssl = tls->openssl;
295 bool auth_success = false;
301 /* Check if peer provided a certificate */
302 if (!(cert = SSL_get_peer_certificate(ssl))) {
303 Emsg1(M_ERROR, 0, _("Peer %s failed to present a TLS certificate\n"), host);
307 /* Check subjectAltName extensions first */
308 if ((extensions = X509_get_ext_count(cert)) > 0) {
309 for (i = 0; i < extensions; i++) {
313 ext = X509_get_ext(cert, i);
314 extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
316 if (strcmp(extname, "subjectAltName") == 0) {
317 X509V3_EXT_METHOD *method;
318 STACK_OF(CONF_VALUE) *val;
321 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
322 const unsigned char *ext_value_data;
324 unsigned char *ext_value_data;
327 /* Get x509 extension method structure */
328 if (!(method = X509V3_EXT_get(ext))) {
332 ext_value_data = ext->value->data;
334 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
338 /* Decode ASN1 item in data */
339 extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
340 ASN1_ITEM_ptr(method->it));
344 /* Decode ASN1 item in data */
345 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
349 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
352 /* Iterate through to find the dNSName field(s) */
353 val = method->i2v(method, extstr, NULL);
355 /* dNSName shortname is "DNS" */
356 for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
357 nval = sk_CONF_VALUE_value(val, j);
358 if (strcmp(nval->name, "DNS") == 0) {
359 if (strcasecmp(nval->value, host) == 0) {
369 /* Try verifying against the subject name */
371 if ((subject = X509_get_subject_name(cert)) != NULL) {
372 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
373 /* NULL terminate data */
375 if (strcasecmp(data, host) == 0) {
389 * Create a new TLS_CONNECTION instance.
391 * Returns: Pointer to TLS_CONNECTION instance on success
394 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
399 * Create a new BIO and assign the fd.
400 * The caller will remain responsible for closing the associated fd
402 bio = BIO_new(BIO_s_socket());
404 /* Not likely, but never say never */
405 openssl_post_errors(M_ERROR, _("Error creating file descriptor-based BIO"));
406 return NULL; /* Nothing allocated, nothing to clean up */
408 BIO_set_fd(bio, fd, BIO_NOCLOSE);
410 /* Allocate our new tls connection */
411 TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
413 /* Create the SSL object and attach the socket BIO */
414 if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
415 /* Not likely, but never say never */
416 openssl_post_errors(M_ERROR, _("Error creating new SSL object"));
420 SSL_set_bio(tls->openssl, bio, bio);
422 /* Non-blocking partial writes */
423 SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
430 SSL_free(tls->openssl);
437 * Free TLS_CONNECTION instance
439 void free_tls_connection(TLS_CONNECTION *tls)
441 SSL_free(tls->openssl);
445 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
446 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
448 TLS_CONNECTION *tls = bsock->tls;
455 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
457 fdmax = bsock->m_fd + 1;
459 /* Ensure that socket is non-blocking */
460 flags = bnet_set_nonblocking(bsock);
463 bsock->timer_start = watchdog_time;
464 bsock->m_timed_out = 0;
468 err = SSL_accept(tls->openssl);
470 err = SSL_connect(tls->openssl);
474 switch (SSL_get_error(tls->openssl, err)) {
478 case SSL_ERROR_ZERO_RETURN:
479 /* TLS connection was cleanly shut down */
480 openssl_post_errors(M_ERROR, _("Connect failure"));
483 case SSL_ERROR_WANT_READ:
484 /* If we timeout of a select, this will be unset */
485 FD_SET((unsigned) bsock->m_fd, &fdset);
486 /* Set our timeout */
489 /* Block until we can read */
490 select(fdmax, &fdset, NULL, &fdset, &tv);
492 case SSL_ERROR_WANT_WRITE:
493 /* If we timeout of a select, this will be unset */
494 FD_SET((unsigned) bsock->m_fd, &fdset);
495 /* Set our timeout */
498 /* Block until we can write */
499 select(fdmax, NULL, &fdset, &fdset, &tv);
502 /* Socket Error Occured */
503 openssl_post_errors(M_ERROR, _("Connect failure"));
508 if (bsock->is_timed_out()) {
514 /* Restore saved flags */
515 bnet_restore_blocking(bsock, flags);
517 bsock->timer_start = 0;
523 * Initiates a TLS connection with the server.
524 * Returns: true on success
527 bool tls_bsock_connect(BSOCK *bsock)
529 /* SSL_connect(bsock->tls) */
530 return (openssl_bsock_session_start(bsock, false));
534 * Listens for a TLS connection from a client.
535 * Returns: true on success
538 bool tls_bsock_accept(BSOCK *bsock)
540 /* SSL_accept(bsock->tls) */
541 return (openssl_bsock_session_start(bsock, true));
545 * Shutdown TLS_CONNECTION instance
547 void tls_bsock_shutdown(BSOCK *bsock)
550 * SSL_shutdown must be called twice to fully complete the process -
551 * The first time to initiate the shutdown handshake, and the second to
552 * receive the peer's reply.
554 * However, it is valid to close the SSL connection after the initial
555 * shutdown notification is sent to the peer, without waiting for the
556 * peer's reply, as long as you do not plan to re-use that particular
557 * SSL connection object.
559 * Because we do not re-use SSL connection objects, I do not bother
560 * calling SSL_shutdown a second time.
562 * In addition, if the underlying socket is blocking, SSL_shutdown()
563 * will not return until the current stage of the shutdown process has
564 * completed or an error has occured. By setting the socket blocking
565 * we can avoid the ugly for()/switch()/select() loop.
570 /* Set socket blocking for shutdown */
571 flags = bsock->set_blocking();
573 err = SSL_shutdown(bsock->tls->openssl);
575 switch (SSL_get_error(bsock->tls->openssl, err)) {
578 case SSL_ERROR_ZERO_RETURN:
579 /* TLS connection was shut down on us via a TLS protocol-level closure */
580 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
583 /* Socket Error Occured */
584 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
588 /* Restore saved flags */
589 bsock->restore_blocking(flags);
592 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
593 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
595 TLS_CONNECTION *tls = bsock->tls;
602 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
604 fdmax = bsock->m_fd + 1;
606 /* Ensure that socket is non-blocking */
607 flags = bsock->set_nonblocking();
610 bsock->timer_start = watchdog_time;
611 bsock->m_timed_out = 0;
618 nwritten = SSL_write(tls->openssl, ptr, nleft);
620 nwritten = SSL_read(tls->openssl, ptr, nleft);
624 switch (SSL_get_error(tls->openssl, nwritten)) {
631 case SSL_ERROR_ZERO_RETURN:
632 /* TLS connection was cleanly shut down */
633 openssl_post_errors(M_ERROR, _("TLS read/write failure."));
635 case SSL_ERROR_WANT_READ:
636 /* If we timeout of a select, this will be unset */
637 FD_SET((unsigned) bsock->m_fd, &fdset);
640 /* Block until we can read */
641 select(fdmax, &fdset, NULL, &fdset, &tv);
643 case SSL_ERROR_WANT_WRITE:
644 /* If we timeout of a select, this will be unset */
645 FD_SET((unsigned) bsock->m_fd, &fdset);
648 /* Block until we can write */
649 select(fdmax, NULL, &fdset, &fdset, &tv);
652 /* Socket Error Occured */
653 openssl_post_errors(M_ERROR, _("TLS read/write failure."));
657 /* Everything done? */
662 /* Timeout/Termination, let's take what we can get */
663 if (bsock->is_timed_out() || bsock->is_terminated()) {
669 /* Restore saved flags */
670 bsock->restore_blocking(flags);
673 bsock->timer_start = 0;
675 return nbytes - nleft;
679 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) {
680 /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
681 return (openssl_bsock_readwrite(bsock, ptr, nbytes, true));
684 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) {
685 /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
686 return (openssl_bsock_readwrite(bsock, ptr, nbytes, false));
689 #else /* HAVE_OPENSSL */
690 # error No TLS implementation available.
691 #endif /* !HAVE_OPENSSL */
696 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
697 const char *certfile, const char *keyfile,
698 CRYPTO_PEM_PASSWD_CB *pem_callback,
699 const void *pem_userdata, const char *dhfile,
704 void free_tls_context(TLS_CONTEXT *ctx) { }
706 void tls_bsock_shutdown(BSOCK *bsock) { }
708 void free_tls_connection(TLS_CONNECTION *tls)
712 SSL_free(tls->openssl);
717 bool get_tls_require(TLS_CONTEXT *ctx)
722 bool get_tls_enable(TLS_CONTEXT *ctx)
727 #endif /* HAVE_TLS */