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-2006 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;
70 struct TLS_Connection {
75 * OpenSSL certificate verification callback.
76 * OpenSSL has already performed internal certificate verification.
77 * We just report any errors that occured.
79 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
83 X509 *cert = X509_STORE_CTX_get_current_cert(store);
84 int depth = X509_STORE_CTX_get_error_depth(store);
85 int err = X509_STORE_CTX_get_error(store);
89 X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
90 X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
92 Emsg5(M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s,"
93 " subject = %s, ERR=%d:%s\n"), depth, issuer,
94 subject, err, X509_verify_cert_error_string(err));
101 /* Dispatch user PEM encryption callbacks */
102 static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
104 TLS_CONTEXT *ctx = (TLS_CONTEXT *) userdata;
105 return (ctx->pem_callback(buf, size, ctx->pem_userdata));
109 * Create a new TLS_CONTEXT instance.
110 * Returns: Pointer to TLS_CONTEXT instance on success
113 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
114 const char *certfile, const char *keyfile,
115 CRYPTO_PEM_PASSWD_CB *pem_callback,
116 const void *pem_userdata, const char *dhfile,
123 ctx = (TLS_CONTEXT *) malloc(sizeof(TLS_CONTEXT));
125 /* Allocate our OpenSSL TLSv1 Context */
126 ctx->openssl = SSL_CTX_new(TLSv1_method());
129 openssl_post_errors(M_ERROR, _("Error initializing SSL context"));
133 /* Set up pem encryption callback */
135 ctx->pem_callback = pem_callback;
136 ctx->pem_userdata = pem_userdata;
138 ctx->pem_callback = crypto_default_pem_callback;
139 ctx->pem_userdata = NULL;
141 SSL_CTX_set_default_passwd_cb(ctx->openssl, tls_pem_callback_dispatch);
142 SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx);
145 * Set certificate verification paths. This requires that at least one
148 if (ca_certfile || ca_certdir) {
149 if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) {
150 openssl_post_errors(M_ERROR, _("Error loading certificate verification stores"));
153 } else if (verify_peer) {
154 /* At least one CA is required for peer verification */
155 Emsg0(M_ERROR, 0, _("Either a certificate file or a directory must be"
156 " specified as a verification store\n"));
161 * Load our certificate file, if available. This file may also contain a
162 * private key, though this usage is somewhat unusual.
165 if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
166 openssl_post_errors(M_ERROR, _("Error loading certificate file"));
171 /* Load our private key. */
173 if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
174 openssl_post_errors(M_ERROR, _("Error loading private key"));
179 /* Load Diffie-Hellman Parameters. */
181 if (!(bio = BIO_new_file(dhfile, "r"))) {
182 openssl_post_errors(M_ERROR, _("Unable to open DH parameters file"));
185 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
188 openssl_post_errors(M_ERROR, _("Unable to load DH parameters from specified file"));
191 if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
192 openssl_post_errors(M_ERROR, _("Failed to set TLS Diffie-Hellman parameters"));
196 /* Enable Single-Use DH for Ephemeral Keying */
197 SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
200 if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
201 Emsg0(M_ERROR, 0, _("Error setting cipher list, no valid ciphers available\n"));
205 /* Verify Peer Certificate */
207 /* SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */
208 SSL_CTX_set_verify(ctx->openssl,
209 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
210 openssl_verify_peer);
216 /* Clean up after ourselves */
218 SSL_CTX_free(ctx->openssl);
225 * Free TLS_CONTEXT instance
227 void free_tls_context(TLS_CONTEXT *ctx)
229 SSL_CTX_free(ctx->openssl);
234 * Verifies a list of common names against the certificate
235 * commonName attribute.
236 * Returns: true on success
239 bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list)
241 SSL *ssl = tls->openssl;
244 int auth_success = false;
247 /* Check if peer provided a certificate */
248 if (!(cert = SSL_get_peer_certificate(ssl))) {
249 Emsg0(M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
253 if ((subject = X509_get_subject_name(cert)) != NULL) {
254 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
256 /* NULL terminate data */
259 /* Try all the CNs in the list */
260 foreach_alist(cn, verify_list) {
261 if (strcasecmp(data, cn) == 0) {
273 * Verifies a peer's hostname against the subjectAltName and commonName
275 * Returns: true on success
278 bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host)
280 SSL *ssl = tls->openssl;
283 int auth_success = false;
289 /* Check if peer provided a certificate */
290 if (!(cert = SSL_get_peer_certificate(ssl))) {
291 Emsg1(M_ERROR, 0, _("Peer %s failed to present a TLS certificate\n"), host);
295 /* Check subjectAltName extensions first */
296 if ((extensions = X509_get_ext_count(cert)) > 0) {
297 for (i = 0; i < extensions; i++) {
301 ext = X509_get_ext(cert, i);
302 extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
304 if (strcmp(extname, "subjectAltName") == 0) {
305 X509V3_EXT_METHOD *method;
306 STACK_OF(CONF_VALUE) *val;
309 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
310 const unsigned char *ext_value_data;
312 unsigned char *ext_value_data;
315 /* Get x509 extension method structure */
316 if (!(method = X509V3_EXT_get(ext))) {
320 ext_value_data = ext->value->data;
322 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
326 /* Decode ASN1 item in data */
327 extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
328 ASN1_ITEM_ptr(method->it));
332 /* Decode ASN1 item in data */
333 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
337 extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
340 /* Iterate through to find the dNSName field(s) */
341 val = method->i2v(method, extstr, NULL);
343 /* dNSName shortname is "DNS" */
344 for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
345 nval = sk_CONF_VALUE_value(val, j);
346 if (strcmp(nval->name, "DNS") == 0) {
347 if (strcasecmp(nval->value, host) == 0) {
357 /* Try verifying against the subject name */
359 if ((subject = X509_get_subject_name(cert)) != NULL) {
360 if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
361 /* NULL terminate data */
363 if (strcasecmp(data, host) == 0) {
378 * Create a new TLS_CONNECTION instance.
380 * Returns: Pointer to TLS_CONNECTION instance on success
383 TLS_CONNECTION *new_tls_connection (TLS_CONTEXT *ctx, int fd)
388 * Create a new BIO and assign the fd.
389 * The caller will remain responsible for closing the associated fd
391 bio = BIO_new(BIO_s_socket());
393 /* Not likely, but never say never */
394 openssl_post_errors(M_ERROR, _("Error creating file descriptor-based BIO"));
395 return NULL; /* Nothing allocated, nothing to clean up */
397 BIO_set_fd(bio, fd, BIO_NOCLOSE);
399 /* Allocate our new tls connection */
400 TLS_CONNECTION *tls = (TLS_CONNECTION *) malloc(sizeof(TLS_CONNECTION));
402 /* Create the SSL object and attach the socket BIO */
403 if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
404 /* Not likely, but never say never */
405 openssl_post_errors(M_ERROR, _("Error creating new SSL object"));
409 SSL_set_bio(tls->openssl, bio, bio);
411 /* Non-blocking partial writes */
412 SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
419 SSL_free(tls->openssl);
426 * Free TLS_CONNECTION instance
428 void free_tls_connection (TLS_CONNECTION *tls)
430 SSL_free(tls->openssl);
434 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
435 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
437 TLS_CONNECTION *tls = bsock->tls;
444 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
446 fdmax = bsock->fd + 1;
448 /* Ensure that socket is non-blocking */
449 flags = bnet_set_nonblocking(bsock);
452 bsock->timer_start = watchdog_time;
453 bsock->timed_out = 0;
457 err = SSL_accept(tls->openssl);
459 err = SSL_connect(tls->openssl);
463 switch (SSL_get_error(tls->openssl, err)) {
467 case SSL_ERROR_ZERO_RETURN:
468 /* TLS connection was cleanly shut down */
469 openssl_post_errors(M_ERROR, _("Connect failure"));
472 case SSL_ERROR_WANT_READ:
473 /* If we timeout of a select, this will be unset */
474 FD_SET((unsigned) bsock->fd, &fdset);
475 /* Set our timeout */
478 /* Block until we can read */
479 select(fdmax, &fdset, NULL, &fdset, &tv);
481 case SSL_ERROR_WANT_WRITE:
482 /* If we timeout of a select, this will be unset */
483 FD_SET((unsigned) bsock->fd, &fdset);
484 /* Set our timeout */
487 /* Block until we can write */
488 select(fdmax, NULL, &fdset, &fdset, &tv);
491 /* Socket Error Occured */
492 openssl_post_errors(M_ERROR, _("Connect failure"));
497 if (bsock->timed_out) {
503 /* Restore saved flags */
504 bnet_restore_blocking(bsock, flags);
506 bsock->timer_start = 0;
512 * Initiates a TLS connection with the server.
513 * Returns: true on success
516 bool tls_bsock_connect(BSOCK *bsock)
518 /* SSL_connect(bsock->tls) */
519 return (openssl_bsock_session_start(bsock, false));
523 * Listens for a TLS connection from a client.
524 * Returns: true on success
527 bool tls_bsock_accept(BSOCK *bsock)
529 /* SSL_accept(bsock->tls) */
530 return (openssl_bsock_session_start(bsock, true));
534 * Shutdown TLS_CONNECTION instance
536 void tls_bsock_shutdown (BSOCK *bsock)
539 * SSL_shutdown must be called twice to fully complete the process -
540 * The first time to initiate the shutdown handshake, and the second to
541 * receive the peer's reply.
543 * However, it is valid to close the SSL connection after the initial
544 * shutdown notification is sent to the peer, without waiting for the
545 * peer's reply, as long as you do not plan to re-use that particular
546 * SSL connection object.
548 * Because we do not re-use SSL connection objects, I do not bother
549 * calling SSL_shutdown a second time.
551 * In addition, if the underlying socket is blocking, SSL_shutdown()
552 * will not return until the current stage of the shutdown process has
553 * completed or an error has occured. By setting the socket blocking
554 * we can avoid the ugly for()/switch()/select() loop.
559 /* Set socket blocking for shutdown */
560 flags = bnet_set_blocking(bsock);
562 err = SSL_shutdown(bsock->tls->openssl);
564 switch (SSL_get_error(bsock->tls->openssl, err)) {
567 case SSL_ERROR_ZERO_RETURN:
568 /* TLS connection was shut down on us via a TLS protocol-level closure */
569 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
572 /* Socket Error Occured */
573 openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
577 /* Restore saved flags */
578 bnet_restore_blocking(bsock, flags);
581 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
582 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
584 TLS_CONNECTION *tls = bsock->tls;
591 /* Zero the fdset, we'll set our fd prior to each invocation of select() */
593 fdmax = bsock->fd + 1;
595 /* Ensure that socket is non-blocking */
596 flags = bnet_set_nonblocking(bsock);
599 bsock->timer_start = watchdog_time;
600 bsock->timed_out = 0;
607 nwritten = SSL_write(tls->openssl, ptr, nleft);
609 nwritten = SSL_read(tls->openssl, ptr, nleft);
613 switch (SSL_get_error(tls->openssl, nwritten)) {
620 case SSL_ERROR_ZERO_RETURN:
621 /* TLS connection was cleanly shut down */
622 openssl_post_errors(M_ERROR, _("TLS read/write failure."));
624 case SSL_ERROR_WANT_READ:
625 /* If we timeout of a select, this will be unset */
626 FD_SET((unsigned) bsock->fd, &fdset);
629 /* Block until we can read */
630 select(fdmax, &fdset, NULL, &fdset, &tv);
632 case SSL_ERROR_WANT_WRITE:
633 /* If we timeout of a select, this will be unset */
634 FD_SET((unsigned) bsock->fd, &fdset);
637 /* Block until we can write */
638 select(fdmax, NULL, &fdset, &fdset, &tv);
641 /* Socket Error Occured */
642 openssl_post_errors(M_ERROR, _("TLS read/write failure."));
646 /* Everything done? */
651 /* Timeout/Termination, let's take what we can get */
652 if (bsock->timed_out || bsock->terminated) {
658 /* Restore saved flags */
659 bnet_restore_blocking(bsock, flags);
662 bsock->timer_start = 0;
664 return nbytes - nleft;
668 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) {
669 /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
670 return (openssl_bsock_readwrite(bsock, ptr, nbytes, true));
673 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) {
674 /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
675 return (openssl_bsock_readwrite(bsock, ptr, nbytes, false));
678 #else /* HAVE_OPENSSL */
679 # error No TLS implementation available.
680 #endif /* !HAVE_OPENSSL */
685 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
686 const char *certfile, const char *keyfile,
687 CRYPTO_PEM_PASSWD_CB *pem_callback,
688 const void *pem_userdata, const char *dhfile,
693 void free_tls_context(TLS_CONTEXT *ctx) { }
695 #endif /* HAVE_TLS */