]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tls.c
kes Reduce bat connect timeout from 30 to 15 seconds.
[bacula/bacula] / bacula / src / lib / tls.c
1 /*
2  * tls.c TLS support functions
3  *
4  * Author: Landon Fuller <landonf@threerings.net>
5  *
6  * Version $Id$
7  *
8  * This file was contributed to the Bacula project by Landon Fuller
9  * and Three Rings Design, Inc.
10  *
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.
17  *
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>.
21  */
22 /*
23    Bacula® - The Network Backup Solution
24
25    Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
26
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.
33
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.
38
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
42    02110-1301, USA.
43
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.
48 */
49
50
51 #include "bacula.h"
52 #include <assert.h>
53
54 extern time_t watchdog_time;
55
56 #ifdef HAVE_TLS /* Is TLS enabled? */
57
58 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
59
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"
62
63 /* TLS Context Structure */
64 struct TLS_Context {
65    SSL_CTX *openssl;
66    CRYPTO_PEM_PASSWD_CB *pem_callback;
67    const void *pem_userdata;
68    bool tls_enable;
69    bool tls_require;
70 };
71
72 struct TLS_Connection {
73    SSL *openssl;
74 };
75
76 /*
77  * OpenSSL certificate verification callback.
78  * OpenSSL has already performed internal certificate verification.
79  * We just report any errors that occured.
80  */
81 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
82 {
83    if (!ok) {
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);
87       char issuer[256];
88       char subject[256];
89
90       X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
91       X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
92
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));
96
97    }
98
99    return ok;
100 }
101
102 /* Dispatch user PEM encryption callbacks */
103 static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
104 {
105    TLS_CONTEXT *ctx = (TLS_CONTEXT *) userdata;
106    return (ctx->pem_callback(buf, size, ctx->pem_userdata));
107 }
108
109 /*
110  * Create a new TLS_CONTEXT instance.
111  *  Returns: Pointer to TLS_CONTEXT instance on success
112  *           NULL on failure;
113  */
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,
118                              bool verify_peer)
119 {
120    TLS_CONTEXT *ctx;
121    BIO *bio;
122    DH *dh;
123
124    ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT));
125
126    /* Allocate our OpenSSL TLSv1 Context */
127    ctx->openssl = SSL_CTX_new(TLSv1_method());
128
129    if (!ctx->openssl) {
130       openssl_post_errors(M_ERROR, _("Error initializing SSL context"));
131       goto err;
132    }
133
134    /* Set up pem encryption callback */
135    if (pem_callback) {
136       ctx->pem_callback = pem_callback;
137       ctx->pem_userdata = pem_userdata;
138    } else {
139       ctx->pem_callback = crypto_default_pem_callback;
140       ctx->pem_userdata = NULL;
141    }
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);
144
145    /*
146     * Set certificate verification paths. This requires that at least one
147     * value be non-NULL
148     */
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"));
152          goto err;
153       }
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"));
158       goto err;
159    }
160
161    /*
162     * Load our certificate file, if available. This file may also contain a
163     * private key, though this usage is somewhat unusual.
164     */
165    if (certfile) {
166       if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
167          openssl_post_errors(M_ERROR, _("Error loading certificate file"));
168          goto err;
169       }
170    }
171
172    /* Load our private key. */
173    if (keyfile) {
174       if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
175          openssl_post_errors(M_ERROR, _("Error loading private key"));
176          goto err;
177       }
178    }
179
180    /* Load Diffie-Hellman Parameters. */
181    if (dhfile) {
182       if (!(bio = BIO_new_file(dhfile, "r"))) {
183          openssl_post_errors(M_ERROR, _("Unable to open DH parameters file"));
184          goto err;
185       }
186       dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
187       BIO_free(bio);
188       if (!dh) {
189          openssl_post_errors(M_ERROR, _("Unable to load DH parameters from specified file"));
190          goto err;
191       }
192       if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
193          openssl_post_errors(M_ERROR, _("Failed to set TLS Diffie-Hellman parameters"));
194          DH_free(dh);
195          goto err;
196       }
197       /* Enable Single-Use DH for Ephemeral Keying */
198       SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
199    }
200
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"));
203       goto err;
204    }
205
206    /* Verify Peer Certificate */
207    if (verify_peer) {
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);
212    }
213
214    return ctx;
215
216 err:
217    /* Clean up after ourselves */
218    if(ctx->openssl) {
219       SSL_CTX_free(ctx->openssl);
220    }
221    free(ctx);
222    return NULL;
223 }
224
225 /*
226  * Free TLS_CONTEXT instance
227  */
228 void free_tls_context(TLS_CONTEXT *ctx)
229 {
230    SSL_CTX_free(ctx->openssl);
231    free(ctx);
232 }
233
234 /*
235  * Verifies a list of common names against the certificate
236  * commonName attribute.
237  *  Returns: true on success
238  *           false on failure
239  */
240 bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list)
241 {
242    SSL *ssl = tls->openssl;
243    X509 *cert;
244    X509_NAME *subject;
245    bool auth_success = false;
246    char data[256];
247
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"));
251       return false;
252    }
253
254    if ((subject = X509_get_subject_name(cert)) != NULL) {
255       if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
256          char *cn;
257          /* NULL terminate data */
258          data[255] = 0;
259
260          /* Try all the CNs in the list */
261          foreach_alist(cn, verify_list) {
262             if (strcasecmp(data, cn) == 0) {
263                auth_success = true;
264             }
265          }
266       }
267    }
268
269    X509_free(cert);
270    return auth_success;
271 }
272
273 /*
274  * Verifies a peer's hostname against the subjectAltName and commonName
275  * attributes.
276  *  Returns: true on success
277  *           false on failure
278  */
279 bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host)
280 {
281    SSL *ssl = tls->openssl;
282    X509 *cert;
283    X509_NAME *subject;
284    bool auth_success = false;
285    int extensions;
286    char data[256];
287    int i, j;
288
289
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);
293       return false;
294    }
295
296    /* Check subjectAltName extensions first */
297    if ((extensions = X509_get_ext_count(cert)) > 0) {
298       for (i = 0; i < extensions; i++) {
299          X509_EXTENSION *ext;
300          const char *extname;
301
302          ext = X509_get_ext(cert, i);
303          extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
304
305          if (strcmp(extname, "subjectAltName") == 0) {
306             X509V3_EXT_METHOD *method;
307             STACK_OF(CONF_VALUE) *val;
308             CONF_VALUE *nval;
309             void *extstr = NULL;
310 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
311             const unsigned char *ext_value_data;
312 #else
313             unsigned char *ext_value_data;
314 #endif
315
316             /* Get x509 extension method structure */
317             if (!(method = X509V3_EXT_get(ext))) {
318                break;
319             }
320
321             ext_value_data = ext->value->data;
322
323 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
324             if (method->it) {
325                /* New style ASN1 */
326
327                /* Decode ASN1 item in data */
328                extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
329                                       ASN1_ITEM_ptr(method->it));
330             } else {
331                /* Old style ASN1 */
332
333                /* Decode ASN1 item in data */
334                extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
335             }
336
337 #else
338             extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
339 #endif
340
341             /* Iterate through to find the dNSName field(s) */
342             val = method->i2v(method, extstr, NULL);
343
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) {
349                      auth_success = true;
350                      goto success;
351                   }
352                }
353             }
354          }
355       }
356    }
357
358    /* Try verifying against the subject name */
359    if (!auth_success) {
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 */
363             data[255] = 0;
364             if (strcasecmp(data, host) == 0) {
365                auth_success = true;
366             }
367          }
368       }
369    }
370
371
372 success:
373    X509_free(cert);
374
375    return auth_success;
376 }
377
378 /*
379  * Create a new TLS_CONNECTION instance.
380  *
381  * Returns: Pointer to TLS_CONNECTION instance on success
382  *          NULL on failure;
383  */
384 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
385 {
386    BIO *bio;
387
388    /*
389     * Create a new BIO and assign the fd.
390     * The caller will remain responsible for closing the associated fd
391     */
392    bio = BIO_new(BIO_s_socket());
393    if (!bio) {
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 */
397    }
398    BIO_set_fd(bio, fd, BIO_NOCLOSE);
399
400    /* Allocate our new tls connection */
401    TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
402
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"));
407       goto err;
408    }
409
410    SSL_set_bio(tls->openssl, bio, bio);
411
412    /* Non-blocking partial writes */
413    SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
414
415    return (tls);
416
417 err:
418    /* Clean up */
419    BIO_free(bio);
420    SSL_free(tls->openssl);
421    free(tls);
422
423    return NULL;
424 }
425
426 /*
427  * Free TLS_CONNECTION instance
428  */
429 void free_tls_connection(TLS_CONNECTION *tls)
430 {
431    SSL_free(tls->openssl);
432    free(tls);
433 }
434
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)
437 {
438    TLS_CONNECTION *tls = bsock->tls;
439    int err;
440    int fdmax, flags;
441    int stat = true;
442    fd_set fdset;
443    struct timeval tv;
444
445    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
446    FD_ZERO(&fdset);
447    fdmax = bsock->m_fd + 1;
448
449    /* Ensure that socket is non-blocking */
450    flags = bnet_set_nonblocking(bsock);
451
452    /* start timer */
453    bsock->timer_start = watchdog_time;
454    bsock->m_timed_out = 0;
455
456    for (;;) { 
457       if (server) {
458          err = SSL_accept(tls->openssl);
459       } else {
460          err = SSL_connect(tls->openssl);
461       }
462
463       /* Handle errors */
464       switch (SSL_get_error(tls->openssl, err)) {
465       case SSL_ERROR_NONE:
466          stat = true;
467          goto cleanup;
468       case SSL_ERROR_ZERO_RETURN:
469          /* TLS connection was cleanly shut down */
470          openssl_post_errors(M_ERROR, _("Connect failure"));
471          stat = false;
472          goto cleanup;
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 */
477          tv.tv_sec = 10;
478          tv.tv_usec = 0;
479          /* Block until we can read */
480          select(fdmax, &fdset, NULL, &fdset, &tv);
481          break;
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 */
486          tv.tv_sec = 10;
487          tv.tv_usec = 0;
488          /* Block until we can write */
489          select(fdmax, NULL, &fdset, &fdset, &tv);
490          break;
491       default:
492          /* Socket Error Occured */
493          openssl_post_errors(M_ERROR, _("Connect failure"));
494          stat = false;
495          goto cleanup;
496       }
497
498       if (bsock->is_timed_out()) {
499          goto cleanup;
500       }
501    }
502
503 cleanup:
504    /* Restore saved flags */
505    bnet_restore_blocking(bsock, flags);
506    /* Clear timer */
507    bsock->timer_start = 0;
508
509    return stat;
510 }
511
512 /*
513  * Initiates a TLS connection with the server.
514  *  Returns: true on success
515  *           false on failure
516  */
517 bool tls_bsock_connect(BSOCK *bsock)
518 {
519    /* SSL_connect(bsock->tls) */
520    return (openssl_bsock_session_start(bsock, false));
521 }
522
523 /*
524  * Listens for a TLS connection from a client.
525  *  Returns: true on success
526  *           false on failure
527  */
528 bool tls_bsock_accept(BSOCK *bsock)
529 {
530    /* SSL_accept(bsock->tls) */
531    return (openssl_bsock_session_start(bsock, true));
532 }
533
534 /*
535  * Shutdown TLS_CONNECTION instance
536  */
537 void tls_bsock_shutdown(BSOCK *bsock)
538 {
539    /*
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.
543     *
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.
548     *
549     * Because we do not re-use SSL connection objects, I do not bother
550     * calling SSL_shutdown a second time.
551     *
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.
556     */
557    int err;
558    int flags;
559
560    /* Set socket blocking for shutdown */
561    flags = bsock->set_blocking();
562
563    err = SSL_shutdown(bsock->tls->openssl);
564
565    switch (SSL_get_error(bsock->tls->openssl, err)) {
566       case SSL_ERROR_NONE:
567          break;
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."));
571          break;
572       default:
573          /* Socket Error Occured */
574          openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
575          break;
576    }
577
578    /* Restore saved flags */
579    bsock->restore_blocking(flags);
580 }
581
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)
584 {
585    TLS_CONNECTION *tls = bsock->tls;
586    int fdmax, flags;
587    fd_set fdset;
588    struct timeval tv;
589    int nleft = 0;
590    int nwritten = 0;
591
592    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
593    FD_ZERO(&fdset);
594    fdmax = bsock->m_fd + 1;
595
596    /* Ensure that socket is non-blocking */
597    flags = bsock->set_nonblocking();
598
599    /* start timer */
600    bsock->timer_start = watchdog_time;
601    bsock->m_timed_out = 0;
602
603    nleft = nbytes;
604
605    while (nleft > 0) { 
606
607       if (write) {
608          nwritten = SSL_write(tls->openssl, ptr, nleft);
609       } else {
610          nwritten = SSL_read(tls->openssl, ptr, nleft);
611       }
612
613       /* Handle errors */
614       switch (SSL_get_error(tls->openssl, nwritten)) {
615       case SSL_ERROR_NONE:
616          nleft -= nwritten;
617          if (nleft) {
618             ptr += nwritten;
619          }
620          break;
621       case SSL_ERROR_ZERO_RETURN:
622          /* TLS connection was cleanly shut down */
623          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
624          goto cleanup;
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);
628          tv.tv_sec = 10;
629          tv.tv_usec = 0;
630          /* Block until we can read */
631          select(fdmax, &fdset, NULL, &fdset, &tv);
632          break;
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);
636          tv.tv_sec = 10;
637          tv.tv_usec = 0;
638          /* Block until we can write */
639          select(fdmax, NULL, &fdset, &fdset, &tv);
640          break;
641       default:
642          /* Socket Error Occured */
643          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
644          goto cleanup;
645       }
646
647       /* Everything done? */
648       if (nleft == 0) {
649          goto cleanup;
650       }
651
652       /* Timeout/Termination, let's take what we can get */
653       if (bsock->is_timed_out() || bsock->is_terminated()) {
654          goto cleanup;
655       }
656    }
657
658 cleanup:
659    /* Restore saved flags */
660    bsock->restore_blocking(flags);
661
662    /* Clear timer */
663    bsock->timer_start = 0;
664
665    return nbytes - nleft;
666 }
667
668
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));
672 }
673
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));
677 }
678
679 #else /* HAVE_OPENSSL */
680 # error No TLS implementation available.
681 #endif /* !HAVE_OPENSSL */
682
683 #else
684
685 /* Dummy routines */
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,
690                              bool verify_peer)
691 {
692    return NULL;
693 }
694 void free_tls_context(TLS_CONTEXT *ctx) { }
695
696 void tls_bsock_shutdown(BSOCK *bsock) { }
697
698 void free_tls_connection(TLS_CONNECTION *tls)
699 {
700    if (tls) {
701       if (tls->openssl) {
702          SSL_free(tls->openssl);
703       }
704       free(tls);
705    }
706 }
707
708 #endif /* HAVE_TLS */