]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tls.c
kes Return correct string from authenticate.cpp in bat when connecting
[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, &fdset, &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, &fdset, &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    int flags;
562
563    /* Set socket blocking for shutdown */
564    bsock->set_blocking();
565
566    err = SSL_shutdown(bsock->tls->openssl);
567    if (err = 0) {
568       /* Complete shutdown */
569       err = SSL_shutdown(bsock->tls->openssl);
570    }
571
572    switch (SSL_get_error(bsock->tls->openssl, err)) {
573    case SSL_ERROR_NONE:
574       break;
575    case SSL_ERROR_ZERO_RETURN:
576       /* TLS connection was shut down on us via a TLS protocol-level closure */
577       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
578       break;
579    default:
580       /* Socket Error Occurred */
581       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
582       break;
583    }
584 }
585
586 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
587 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
588 {
589    TLS_CONNECTION *tls = bsock->tls;
590    int fdmax, flags;
591    fd_set fdset;
592    struct timeval tv;
593    int nleft = 0;
594    int nwritten = 0;
595
596    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
597    FD_ZERO(&fdset);
598    fdmax = bsock->m_fd + 1;
599
600    /* Ensure that socket is non-blocking */
601    flags = bsock->set_nonblocking();
602
603    /* start timer */
604    bsock->timer_start = watchdog_time;
605    bsock->clear_timed_out();
606
607    nleft = nbytes;
608
609    while (nleft > 0) { 
610       if (write) {
611          nwritten = SSL_write(tls->openssl, ptr, nleft);
612       } else {
613          nwritten = SSL_read(tls->openssl, ptr, nleft);
614       }
615
616       /* Handle errors */
617       switch (SSL_get_error(tls->openssl, nwritten)) {
618       case SSL_ERROR_NONE:
619          nleft -= nwritten;
620          if (nleft) {
621             ptr += nwritten;
622          }
623          break;
624
625       case SSL_ERROR_WANT_READ:
626       case SSL_ERROR_WANT_WRITE:
627          /* If we timeout on a select, this will be unset */
628          FD_SET((unsigned)bsock->m_fd, &fdset);
629          tv.tv_sec = 10;
630          tv.tv_usec = 0;
631          /* Block until we can read or write */
632          select(fdmax, NULL, &fdset, &fdset, &tv);
633          break;
634
635       case SSL_ERROR_ZERO_RETURN:
636          /* TLS connection was cleanly shut down */
637          /* Fall through wanted */
638       default:
639          /* Socket Error Occured */
640          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
641          goto cleanup;
642       }
643
644       /* Everything done? */
645       if (nleft == 0) {
646          goto cleanup;
647       }
648
649       /* Timeout/Termination, let's take what we can get */
650       if (bsock->is_timed_out() || bsock->is_terminated()) {
651          goto cleanup;
652       }
653    }
654
655 cleanup:
656    /* Restore saved flags */
657    bsock->restore_blocking(flags);
658
659    /* Clear timer */
660    bsock->timer_start = 0;
661    return nbytes - nleft;
662 }
663
664
665 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) 
666 {
667    /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
668    return openssl_bsock_readwrite(bsock, ptr, nbytes, true);
669 }
670
671 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) 
672 {
673    /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
674    return openssl_bsock_readwrite(bsock, ptr, nbytes, false);
675 }
676
677 #else /* HAVE_OPENSSL */
678 # error No TLS implementation available.
679 #endif /* !HAVE_OPENSSL */
680
681
682 #else     /* TLS NOT enabled, dummy routines substituted */
683
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 bool get_tls_require(TLS_CONTEXT *ctx) 
701 {
702    return false;
703 }
704
705 bool get_tls_enable(TLS_CONTEXT *ctx) 
706 {
707    return false;
708 }
709
710 #endif /* HAVE_TLS */