]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tls.c
There's no reason to check for exceptional conditions in the select() loop.
[bacula/bacula] / bacula / src / lib / tls.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
5
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
11    in the file LICENSE.
12
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.
17
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
21    02110-1301, USA.
22
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.
27 */
28 /*
29  * tls.c TLS support functions
30  *
31  * Author: Landon Fuller <landonf@threerings.net>
32  *
33  * Version $Id$
34  *
35  * This file was contributed to the Bacula project by Landon Fuller
36  * and Three Rings Design, Inc.
37  *
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.
44  *
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>.
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       Jmsg5(get_jcr_from_tid(), 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       Jmsg0(get_jcr_from_tid(), 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       Jmsg0(get_jcr_from_tid(), M_ERROR, 0,
203              _("Error setting cipher list, no valid ciphers available\n"));
204       goto err;
205    }
206
207    /* Verify Peer Certificate */
208    if (verify_peer) {
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);
213    }
214
215    return ctx;
216
217 err:
218    /* Clean up after ourselves */
219    if(ctx->openssl) {
220       SSL_CTX_free(ctx->openssl);
221    }
222    free(ctx);
223    return NULL;
224 }
225
226 /*
227  * Free TLS_CONTEXT instance
228  */
229 void free_tls_context(TLS_CONTEXT *ctx)
230 {
231    SSL_CTX_free(ctx->openssl);
232    free(ctx);
233 }
234
235 bool get_tls_require(TLS_CONTEXT *ctx) 
236 {
237    return ctx->tls_require;
238 }
239
240 bool get_tls_enable(TLS_CONTEXT *ctx) 
241 {
242    return ctx->tls_enable;
243 }
244
245
246 /*
247  * Verifies a list of common names against the certificate
248  * commonName attribute.
249  *  Returns: true on success
250  *           false on failure
251  */
252 bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list)
253 {
254    SSL *ssl = tls->openssl;
255    X509 *cert;
256    X509_NAME *subject;
257    bool auth_success = false;
258    char data[256];
259
260    /* Check if peer provided a certificate */
261    if (!(cert = SSL_get_peer_certificate(ssl))) {
262       Jmsg0(get_jcr_from_tid(), M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
263       return false;
264    }
265
266    if ((subject = X509_get_subject_name(cert)) != NULL) {
267       if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
268          char *cn;
269          /* NULL terminate data */
270          data[255] = 0;
271
272          /* Try all the CNs in the list */
273          foreach_alist(cn, verify_list) {
274             if (strcasecmp(data, cn) == 0) {
275                auth_success = true;
276             }
277          }
278       }
279    }
280
281    X509_free(cert);
282    return auth_success;
283 }
284
285 /*
286  * Verifies a peer's hostname against the subjectAltName and commonName
287  * attributes.
288  *  Returns: true on success
289  *           false on failure
290  */
291 bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host)
292 {
293    SSL *ssl = tls->openssl;
294    X509 *cert;
295    X509_NAME *subject;
296    bool auth_success = false;
297    int extensions;
298    char data[256];
299    int i, j;
300
301
302    /* Check if peer provided a certificate */
303    if (!(cert = SSL_get_peer_certificate(ssl))) {
304       Jmsg1(get_jcr_from_tid(), M_ERROR, 0, 
305             _("Peer %s failed to present a TLS certificate\n"), host);
306       return false;
307    }
308
309    /* Check subjectAltName extensions first */
310    if ((extensions = X509_get_ext_count(cert)) > 0) {
311       for (i = 0; i < extensions; i++) {
312          X509_EXTENSION *ext;
313          const char *extname;
314
315          ext = X509_get_ext(cert, i);
316          extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
317
318          if (strcmp(extname, "subjectAltName") == 0) {
319             X509V3_EXT_METHOD *method;
320             STACK_OF(CONF_VALUE) *val;
321             CONF_VALUE *nval;
322             void *extstr = NULL;
323 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
324             const unsigned char *ext_value_data;
325 #else
326             unsigned char *ext_value_data;
327 #endif
328
329             /* Get x509 extension method structure */
330             if (!(method = X509V3_EXT_get(ext))) {
331                break;
332             }
333
334             ext_value_data = ext->value->data;
335
336 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
337             if (method->it) {
338                /* New style ASN1 */
339
340                /* Decode ASN1 item in data */
341                extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
342                                       ASN1_ITEM_ptr(method->it));
343             } else {
344                /* Old style ASN1 */
345
346                /* Decode ASN1 item in data */
347                extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
348             }
349
350 #else
351             extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
352 #endif
353
354             /* Iterate through to find the dNSName field(s) */
355             val = method->i2v(method, extstr, NULL);
356
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) {
362                      auth_success = true;
363                      goto success;
364                   }
365                }
366             }
367          }
368       }
369    }
370
371    /* Try verifying against the subject name */
372    if (!auth_success) {
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 */
376             data[255] = 0;
377             if (strcasecmp(data, host) == 0) {
378                auth_success = true;
379             }
380          }
381       }
382    }
383
384 success:
385    X509_free(cert);
386
387    return auth_success;
388 }
389
390 /*
391  * Create a new TLS_CONNECTION instance.
392  *
393  * Returns: Pointer to TLS_CONNECTION instance on success
394  *          NULL on failure;
395  */
396 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
397 {
398    BIO *bio;
399
400    /*
401     * Create a new BIO and assign the fd.
402     * The caller will remain responsible for closing the associated fd
403     */
404    bio = BIO_new(BIO_s_socket());
405    if (!bio) {
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 */
409    }
410    BIO_set_fd(bio, fd, BIO_NOCLOSE);
411
412    /* Allocate our new tls connection */
413    TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
414
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"));
419       goto err;
420    }
421
422    SSL_set_bio(tls->openssl, bio, bio);
423
424    /* Non-blocking partial writes */
425    SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
426
427    return tls;
428
429 err:
430    /* Clean up */
431    BIO_free(bio);
432    SSL_free(tls->openssl);
433    free(tls);
434    return NULL;
435 }
436
437 /*
438  * Free TLS_CONNECTION instance
439  */
440 void free_tls_connection(TLS_CONNECTION *tls)
441 {
442    SSL_free(tls->openssl);
443    free(tls);
444 }
445
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)
448 {
449    TLS_CONNECTION *tls = bsock->tls;
450    int err;
451    int fdmax, flags;
452    int stat = true;
453    fd_set fdset;
454    struct timeval tv;
455
456    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
457    FD_ZERO(&fdset);
458    fdmax = bsock->m_fd + 1;
459
460    /* Ensure that socket is non-blocking */
461    flags = bsock->set_nonblocking();
462
463    /* start timer */
464    bsock->timer_start = watchdog_time;
465    bsock->clear_timed_out();
466
467    for (;;) { 
468       if (server) {
469          err = SSL_accept(tls->openssl);
470       } else {
471          err = SSL_connect(tls->openssl);
472       }
473
474       /* Handle errors */
475       switch (SSL_get_error(tls->openssl, err)) {
476       case SSL_ERROR_NONE:
477          stat = true;
478          goto cleanup;
479       case SSL_ERROR_ZERO_RETURN:
480          /* TLS connection was cleanly shut down */
481          openssl_post_errors(M_ERROR, _("Connect failure"));
482          stat = false;
483          goto cleanup;
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 */
488          tv.tv_sec = 10;
489          tv.tv_usec = 0;
490          /* Block until we can read */
491          select(fdmax, &fdset, NULL, NULL, &tv);
492          break;
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 */
497          tv.tv_sec = 10;
498          tv.tv_usec = 0;
499          /* Block until we can write */
500          select(fdmax, NULL, &fdset, NULL, &tv);
501          break;
502       default:
503          /* Socket Error Occured */
504          openssl_post_errors(M_ERROR, _("Connect failure"));
505          stat = false;
506          goto cleanup;
507       }
508
509       if (bsock->is_timed_out()) {
510          goto cleanup;
511       }
512    }
513
514 cleanup:
515    /* Restore saved flags */
516    bsock->restore_blocking(flags);
517    /* Clear timer */
518    bsock->timer_start = 0;
519
520    return stat;
521 }
522
523 /*
524  * Initiates a TLS connection with the server.
525  *  Returns: true on success
526  *           false on failure
527  */
528 bool tls_bsock_connect(BSOCK *bsock)
529 {
530    /* SSL_connect(bsock->tls) */
531    return openssl_bsock_session_start(bsock, false);
532 }
533
534 /*
535  * Listens for a TLS connection from a client.
536  *  Returns: true on success
537  *           false on failure
538  */
539 bool tls_bsock_accept(BSOCK *bsock)
540 {
541    /* SSL_accept(bsock->tls) */
542    return openssl_bsock_session_start(bsock, true);
543 }
544
545 /*
546  * Shutdown TLS_CONNECTION instance
547  */
548 void tls_bsock_shutdown(BSOCK *bsock)
549 {
550    /*
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.
554     *
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.
559     */
560    int err;
561
562    /* Set socket blocking for shutdown */
563    bsock->set_blocking();
564
565    err = SSL_shutdown(bsock->tls->openssl);
566    if (err == 0) {
567       /* Complete shutdown */
568       err = SSL_shutdown(bsock->tls->openssl);
569    }
570
571    switch (SSL_get_error(bsock->tls->openssl, err)) {
572    case SSL_ERROR_NONE:
573       break;
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."));
577       break;
578    default:
579       /* Socket Error Occurred */
580       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
581       break;
582    }
583 }
584
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)
587 {
588    TLS_CONNECTION *tls = bsock->tls;
589    int fdmax, flags;
590    fd_set fdset;
591    struct timeval tv;
592    int nleft = 0;
593    int nwritten = 0;
594
595    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
596    FD_ZERO(&fdset);
597    fdmax = bsock->m_fd + 1;
598
599    /* Ensure that socket is non-blocking */
600    flags = bsock->set_nonblocking();
601
602    /* start timer */
603    bsock->timer_start = watchdog_time;
604    bsock->clear_timed_out();
605
606    nleft = nbytes;
607
608    while (nleft > 0) { 
609       if (write) {
610          nwritten = SSL_write(tls->openssl, ptr, nleft);
611       } else {
612          nwritten = SSL_read(tls->openssl, ptr, nleft);
613       }
614
615       /* Handle errors */
616       switch (SSL_get_error(tls->openssl, nwritten)) {
617       case SSL_ERROR_NONE:
618          nleft -= nwritten;
619          if (nleft) {
620             ptr += nwritten;
621          }
622          break;
623
624       case SSL_ERROR_WANT_READ:
625       case SSL_ERROR_WANT_WRITE:
626          /* If we timeout on 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 or write */
631          select(fdmax, NULL, &fdset, NULL, &tv);
632          break;
633
634       case SSL_ERROR_ZERO_RETURN:
635          /* TLS connection was cleanly shut down */
636          /* Fall through wanted */
637       default:
638          /* Socket Error Occured */
639          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
640          goto cleanup;
641       }
642
643       /* Everything done? */
644       if (nleft == 0) {
645          goto cleanup;
646       }
647
648       /* Timeout/Termination, let's take what we can get */
649       if (bsock->is_timed_out() || bsock->is_terminated()) {
650          goto cleanup;
651       }
652    }
653
654 cleanup:
655    /* Restore saved flags */
656    bsock->restore_blocking(flags);
657
658    /* Clear timer */
659    bsock->timer_start = 0;
660    return nbytes - nleft;
661 }
662
663
664 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) 
665 {
666    /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
667    return openssl_bsock_readwrite(bsock, ptr, nbytes, true);
668 }
669
670 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) 
671 {
672    /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
673    return openssl_bsock_readwrite(bsock, ptr, nbytes, false);
674 }
675
676 #else /* HAVE_OPENSSL */
677 # error No TLS implementation available.
678 #endif /* !HAVE_OPENSSL */
679
680
681 #else     /* TLS NOT enabled, dummy routines substituted */
682
683
684 /* Dummy routines */
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,
689                              bool verify_peer)
690 {
691    return NULL;
692 }
693 void free_tls_context(TLS_CONTEXT *ctx) { }
694
695 void tls_bsock_shutdown(BSOCK *bsock) { }
696
697 void free_tls_connection(TLS_CONNECTION *tls) { }
698
699 bool get_tls_require(TLS_CONTEXT *ctx) 
700 {
701    return false;
702 }
703
704 bool get_tls_enable(TLS_CONTEXT *ctx) 
705 {
706    return false;
707 }
708
709 #endif /* HAVE_TLS */