]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tls.c
Merge branch 'master' into mvw/1361
[bacula/bacula] / bacula / src / lib / tls.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2005-2008 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 Kern Sibbald.
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
55 #ifdef HAVE_TLS /* Is TLS enabled? */
56
57 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
58
59 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
60 #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
61
62 /* TLS Context Structure */
63 struct TLS_Context {
64    SSL_CTX *openssl;
65    CRYPTO_PEM_PASSWD_CB *pem_callback;
66    const void *pem_userdata;
67    bool tls_enable;
68    bool tls_require;
69 };
70
71 struct TLS_Connection {
72    SSL *openssl;
73 };
74
75 /*
76  * OpenSSL certificate verification callback.
77  * OpenSSL has already performed internal certificate verification.
78  * We just report any errors that occured.
79  */
80 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
81 {
82    if (!ok) {
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);
86       char issuer[256];
87       char subject[256];
88
89       X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
90       X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
91
92       Jmsg5(NULL, 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));
95
96    }
97
98    return ok;
99 }
100
101 /* Dispatch user PEM encryption callbacks */
102 static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
103 {
104    TLS_CONTEXT *ctx = (TLS_CONTEXT *)userdata;
105    return (ctx->pem_callback(buf, size, ctx->pem_userdata));
106 }
107
108 /*
109  * Create a new TLS_CONTEXT instance.
110  *  Returns: Pointer to TLS_CONTEXT instance on success
111  *           NULL on failure;
112  */
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,
117                              bool verify_peer)
118 {
119    TLS_CONTEXT *ctx;
120    BIO *bio;
121    DH *dh;
122
123    ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT));
124
125    /* Allocate our OpenSSL TLSv1 Context */
126    ctx->openssl = SSL_CTX_new(TLSv1_method());
127
128    if (!ctx->openssl) {
129       openssl_post_errors(M_ERROR, _("Error initializing SSL context"));
130       goto err;
131    }
132
133    /* Set up pem encryption callback */
134    if (pem_callback) {
135       ctx->pem_callback = pem_callback;
136       ctx->pem_userdata = pem_userdata;
137    } else {
138       ctx->pem_callback = crypto_default_pem_callback;
139       ctx->pem_userdata = NULL;
140    }
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);
143
144    /*
145     * Set certificate verification paths. This requires that at least one
146     * value be non-NULL
147     */
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"));
151          goto err;
152       }
153    } else if (verify_peer) {
154       /* At least one CA is required for peer verification */
155       Jmsg0(NULL, M_ERROR, 0, _("Either a certificate file or a directory must be"
156                          " specified as a verification store\n"));
157       goto err;
158    }
159
160    /*
161     * Load our certificate file, if available. This file may also contain a
162     * private key, though this usage is somewhat unusual.
163     */
164    if (certfile) {
165       if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
166          openssl_post_errors(M_ERROR, _("Error loading certificate file"));
167          goto err;
168       }
169    }
170
171    /* Load our private key. */
172    if (keyfile) {
173       if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
174          openssl_post_errors(M_ERROR, _("Error loading private key"));
175          goto err;
176       }
177    }
178
179    /* Load Diffie-Hellman Parameters. */
180    if (dhfile) {
181       if (!(bio = BIO_new_file(dhfile, "r"))) {
182          openssl_post_errors(M_ERROR, _("Unable to open DH parameters file"));
183          goto err;
184       }
185       dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
186       BIO_free(bio);
187       if (!dh) {
188          openssl_post_errors(M_ERROR, _("Unable to load DH parameters from specified file"));
189          goto err;
190       }
191       if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
192          openssl_post_errors(M_ERROR, _("Failed to set TLS Diffie-Hellman parameters"));
193          DH_free(dh);
194          goto err;
195       }
196       /* Enable Single-Use DH for Ephemeral Keying */
197       SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
198    }
199
200    if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
201       Jmsg0(NULL, M_ERROR, 0,
202              _("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 bool get_tls_require(TLS_CONTEXT *ctx) 
235 {
236    return ctx->tls_require;
237 }
238
239 bool get_tls_enable(TLS_CONTEXT *ctx) 
240 {
241    return ctx->tls_enable;
242 }
243
244
245 /*
246  * Verifies a list of common names against the certificate
247  * commonName attribute.
248  *  Returns: true on success
249  *           false on failure
250  */
251 bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list)
252 {
253    SSL *ssl = tls->openssl;
254    X509 *cert;
255    X509_NAME *subject;
256    bool auth_success = false;
257    char data[256];
258
259    /* Check if peer provided a certificate */
260    if (!(cert = SSL_get_peer_certificate(ssl))) {
261       Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
262       return false;
263    }
264
265    if ((subject = X509_get_subject_name(cert)) != NULL) {
266       if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
267          char *cn;
268          /* NULL terminate data */
269          data[255] = 0;
270
271          /* Try all the CNs in the list */
272          foreach_alist(cn, verify_list) {
273             if (strcasecmp(data, cn) == 0) {
274                auth_success = true;
275             }
276          }
277       }
278    }
279
280    X509_free(cert);
281    return auth_success;
282 }
283
284 /*
285  * Verifies a peer's hostname against the subjectAltName and commonName
286  * attributes.
287  *  Returns: true on success
288  *           false on failure
289  */
290 bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host)
291 {
292    SSL *ssl = tls->openssl;
293    X509 *cert;
294    X509_NAME *subject;
295    bool auth_success = false;
296    int extensions;
297    char data[256];
298    int i, j;
299
300
301    /* Check if peer provided a certificate */
302    if (!(cert = SSL_get_peer_certificate(ssl))) {
303       Qmsg1(jcr, M_ERROR, 0, 
304             _("Peer %s failed to present a TLS certificate\n"), host);
305       return false;
306    }
307
308    /* Check subjectAltName extensions first */
309    if ((extensions = X509_get_ext_count(cert)) > 0) {
310       for (i = 0; i < extensions; i++) {
311          X509_EXTENSION *ext;
312          const char *extname;
313
314          ext = X509_get_ext(cert, i);
315          extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
316
317          if (strcmp(extname, "subjectAltName") == 0) {
318             X509V3_EXT_METHOD *method;
319             STACK_OF(CONF_VALUE) *val;
320             CONF_VALUE *nval;
321             void *extstr = NULL;
322 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
323             const unsigned char *ext_value_data;
324 #else
325             unsigned char *ext_value_data;
326 #endif
327
328             /* Get x509 extension method structure */
329             if (!(method = X509V3_EXT_get(ext))) {
330                break;
331             }
332
333             ext_value_data = ext->value->data;
334
335 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
336             if (method->it) {
337                /* New style ASN1 */
338
339                /* Decode ASN1 item in data */
340                extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
341                                       ASN1_ITEM_ptr(method->it));
342             } else {
343                /* Old style ASN1 */
344
345                /* Decode ASN1 item in data */
346                extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
347             }
348
349 #else
350             extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
351 #endif
352
353             /* Iterate through to find the dNSName field(s) */
354             val = method->i2v(method, extstr, NULL);
355
356             /* dNSName shortname is "DNS" */
357             for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
358                nval = sk_CONF_VALUE_value(val, j);
359                if (strcmp(nval->name, "DNS") == 0) {
360                   if (strcasecmp(nval->value, host) == 0) {
361                      auth_success = true;
362                      goto success;
363                   }
364                }
365             }
366          }
367       }
368    }
369
370    /* Try verifying against the subject name */
371    if (!auth_success) {
372       if ((subject = X509_get_subject_name(cert)) != NULL) {
373          if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
374             /* NULL terminate data */
375             data[255] = 0;
376             if (strcasecmp(data, host) == 0) {
377                auth_success = true;
378             }
379          }
380       }
381    }
382
383 success:
384    X509_free(cert);
385
386    return auth_success;
387 }
388
389 /*
390  * Create a new TLS_CONNECTION instance.
391  *
392  * Returns: Pointer to TLS_CONNECTION instance on success
393  *          NULL on failure;
394  */
395 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
396 {
397    BIO *bio;
398
399    /*
400     * Create a new BIO and assign the fd.
401     * The caller will remain responsible for closing the associated fd
402     */
403    bio = BIO_new(BIO_s_socket());
404    if (!bio) {
405       /* Not likely, but never say never */
406       openssl_post_errors(M_ERROR, _("Error creating file descriptor-based BIO"));
407       return NULL; /* Nothing allocated, nothing to clean up */
408    }
409    BIO_set_fd(bio, fd, BIO_NOCLOSE);
410
411    /* Allocate our new tls connection */
412    TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
413
414    /* Create the SSL object and attach the socket BIO */
415    if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
416       /* Not likely, but never say never */
417       openssl_post_errors(M_ERROR, _("Error creating new SSL object"));
418       goto err;
419    }
420
421    SSL_set_bio(tls->openssl, bio, bio);
422
423    /* Non-blocking partial writes */
424    SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
425
426    return tls;
427
428 err:
429    /* Clean up */
430    BIO_free(bio);
431    SSL_free(tls->openssl);
432    free(tls);
433    return NULL;
434 }
435
436 /*
437  * Free TLS_CONNECTION instance
438  */
439 void free_tls_connection(TLS_CONNECTION *tls)
440 {
441    SSL_free(tls->openssl);
442    free(tls);
443 }
444
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)
447 {
448    TLS_CONNECTION *tls = bsock->tls;
449    int err;
450    int fdmax, flags;
451    int stat = true;
452    fd_set fdset;
453    struct timeval tv;
454
455    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
456    FD_ZERO(&fdset);
457    fdmax = bsock->m_fd + 1;
458
459    /* Ensure that socket is non-blocking */
460    flags = bsock->set_nonblocking();
461
462    /* start timer */
463    bsock->timer_start = watchdog_time;
464    bsock->clear_timed_out();
465
466    for (;;) { 
467       if (server) {
468          err = SSL_accept(tls->openssl);
469       } else {
470          err = SSL_connect(tls->openssl);
471       }
472
473       /* Handle errors */
474       switch (SSL_get_error(tls->openssl, err)) {
475       case SSL_ERROR_NONE:
476          stat = true;
477          goto cleanup;
478       case SSL_ERROR_ZERO_RETURN:
479          /* TLS connection was cleanly shut down */
480          openssl_post_errors(M_ERROR, _("Connect failure"));
481          stat = false;
482          goto cleanup;
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 */
487          tv.tv_sec = 10;
488          tv.tv_usec = 0;
489          /* Block until we can read */
490          select(fdmax, &fdset, NULL, NULL, &tv);
491          break;
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 */
496          tv.tv_sec = 10;
497          tv.tv_usec = 0;
498          /* Block until we can write */
499          select(fdmax, NULL, &fdset, NULL, &tv);
500          break;
501       default:
502          /* Socket Error Occurred */
503          openssl_post_errors(M_ERROR, _("Connect failure"));
504          stat = false;
505          goto cleanup;
506       }
507
508       if (bsock->is_timed_out()) {
509          goto cleanup;
510       }
511    }
512
513 cleanup:
514    /* Restore saved flags */
515    bsock->restore_blocking(flags);
516    /* Clear timer */
517    bsock->timer_start = 0;
518
519    return stat;
520 }
521
522 /*
523  * Initiates a TLS connection with the server.
524  *  Returns: true on success
525  *           false on failure
526  */
527 bool tls_bsock_connect(BSOCK *bsock)
528 {
529    /* SSL_connect(bsock->tls) */
530    return openssl_bsock_session_start(bsock, false);
531 }
532
533 /*
534  * Listens for a TLS connection from a client.
535  *  Returns: true on success
536  *           false on failure
537  */
538 bool tls_bsock_accept(BSOCK *bsock)
539 {
540    /* SSL_accept(bsock->tls) */
541    return openssl_bsock_session_start(bsock, true);
542 }
543
544 /*
545  * Shutdown TLS_CONNECTION instance
546  */
547 void tls_bsock_shutdown(BSOCK *bsock)
548 {
549    /*
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.
553     *
554     * In addition, if the underlying socket is blocking, SSL_shutdown()
555     * will not return until the current stage of the shutdown process has
556     * completed or an error has occured. By setting the socket blocking
557     * we can avoid the ugly for()/switch()/select() loop.
558     */
559    int err;
560
561    /* Set socket blocking for shutdown */
562    bsock->set_blocking();
563
564    err = SSL_shutdown(bsock->tls->openssl);
565    if (err == 0) {
566       /* Complete shutdown */
567       err = SSL_shutdown(bsock->tls->openssl);
568    }
569
570    switch (SSL_get_error(bsock->tls->openssl, err)) {
571    case SSL_ERROR_NONE:
572       break;
573    case SSL_ERROR_ZERO_RETURN:
574       /* TLS connection was shut down on us via a TLS protocol-level closure */
575       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
576       break;
577    default:
578       /* Socket Error Occurred */
579       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
580       break;
581    }
582 }
583
584 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
585 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
586 {
587    TLS_CONNECTION *tls = bsock->tls;
588    int fdmax, flags;
589    fd_set fdset;
590    struct timeval tv;
591    int nleft = 0;
592    int nwritten = 0;
593
594    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
595    FD_ZERO(&fdset);
596    fdmax = bsock->m_fd + 1;
597
598    /* Ensure that socket is non-blocking */
599    flags = bsock->set_nonblocking();
600
601    /* start timer */
602    bsock->timer_start = watchdog_time;
603    bsock->clear_timed_out();
604
605    nleft = nbytes;
606
607    while (nleft > 0) { 
608       if (write) {
609          nwritten = SSL_write(tls->openssl, ptr, nleft);
610       } else {
611          nwritten = SSL_read(tls->openssl, ptr, nleft);
612       }
613
614       /* Handle errors */
615       switch (SSL_get_error(tls->openssl, nwritten)) {
616       case SSL_ERROR_NONE:
617          nleft -= nwritten;
618          if (nleft) {
619             ptr += nwritten;
620          }
621          break;
622
623       case SSL_ERROR_WANT_READ:
624          /* If we timeout on a select, this will be unset */
625          FD_SET((unsigned)bsock->m_fd, &fdset);
626          tv.tv_sec = 10;
627          tv.tv_usec = 0;
628          /* Block until we can read */
629          select(fdmax, &fdset, NULL, NULL, &tv);
630          break;
631
632       case SSL_ERROR_WANT_WRITE:
633          /* If we timeout on a select, this will be unset */
634          FD_SET((unsigned)bsock->m_fd, &fdset);
635          tv.tv_sec = 10;
636          tv.tv_usec = 0;
637          /* Block until we can write */
638          select(fdmax, NULL, &fdset, NULL, &tv);
639          break;
640
641       case SSL_ERROR_ZERO_RETURN:
642          /* TLS connection was cleanly shut down */
643          /* Fall through wanted */
644       default:
645          /* Socket Error Occured */
646          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
647          goto cleanup;
648       }
649
650       /* Everything done? */
651       if (nleft == 0) {
652          goto cleanup;
653       }
654
655       /* Timeout/Termination, let's take what we can get */
656       if (bsock->is_timed_out() || bsock->is_terminated()) {
657          goto cleanup;
658       }
659    }
660
661 cleanup:
662    /* Restore saved flags */
663    bsock->restore_blocking(flags);
664
665    /* Clear timer */
666    bsock->timer_start = 0;
667    return nbytes - nleft;
668 }
669
670
671 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) 
672 {
673    /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
674    return openssl_bsock_readwrite(bsock, ptr, nbytes, true);
675 }
676
677 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) 
678 {
679    /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
680    return openssl_bsock_readwrite(bsock, ptr, nbytes, false);
681 }
682
683 #else /* HAVE_OPENSSL */
684 # error No TLS implementation available.
685 #endif /* !HAVE_OPENSSL */
686
687
688 #else     /* TLS NOT enabled, dummy routines substituted */
689
690
691 /* Dummy routines */
692 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
693                              const char *certfile, const char *keyfile,
694                              CRYPTO_PEM_PASSWD_CB *pem_callback,
695                              const void *pem_userdata, const char *dhfile,
696                              bool verify_peer)
697 {
698    return NULL;
699 }
700 void free_tls_context(TLS_CONTEXT *ctx) { }
701
702 void tls_bsock_shutdown(BSOCK *bsock) { }
703
704 void free_tls_connection(TLS_CONNECTION *tls) { }
705
706 bool get_tls_require(TLS_CONTEXT *ctx) 
707 {
708    return false;
709 }
710
711 bool get_tls_enable(TLS_CONTEXT *ctx) 
712 {
713    return false;
714 }
715
716 #endif /* HAVE_TLS */