]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tls.c
This commit was manufactured by cvs2svn to create tag
[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  * Copyright (C) 2005 Kern Sibbald
9  *
10  * This file was contributed to the Bacula project by Landon Fuller
11  * and Three Rings Design, Inc.
12  *
13  * Three Rings Design, Inc. has been granted a perpetual, worldwide,
14  * non-exclusive, no-charge, royalty-free, irrevocable copyright
15  * license to reproduce, prepare derivative works of, publicly
16  * display, publicly perform, sublicense, and distribute the original
17  * work contributed by Three Rings Design, Inc. and its employees to
18  * the Bacula project in source or object form.
19  *
20  * If you wish to license contributions from Three Rings Design, Inc,
21  * under an alternate open source license please contact
22  * Landon Fuller <landonf@threerings.net>.
23  */
24 /*
25    Copyright (C) 2005 Kern Sibbald
26
27    This program is free software; you can redistribute it and/or
28    modify it under the terms of the GNU General Public License
29    version 2 as amended with additional clauses defined in the
30    file LICENSE in the main source directory.
31
32    This program is distributed in the hope that it will be useful,
33    but WITHOUT ANY WARRANTY; without even the implied warranty of
34    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
35    the file LICENSE for additional details.
36
37  */
38
39 #include "bacula.h"
40 #include <assert.h>
41
42 extern time_t watchdog_time;
43
44 #ifdef HAVE_TLS /* Is TLS enabled? */
45
46 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
47
48 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
49 #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
50
51 /* Array of mutexes for use with OpenSSL static locking */
52 static pthread_mutex_t *mutexes;
53
54 /* OpenSSL dynamic locking structure */
55 struct CRYPTO_dynlock_value {
56    pthread_mutex_t mutex;
57 };
58
59 /* Are we initialized? */
60 static int tls_initialized = false;
61
62 /* TLS Context Structure */
63 struct TLS_Context {
64    SSL_CTX *openssl;
65    TLS_PEM_PASSWD_CB *pem_callback;
66    const void *pem_userdata;
67 };
68
69 struct TLS_Connection {
70    SSL *openssl;
71 };
72
73 /* post all per-thread openssl errors */
74 static void openssl_post_errors(int code, const char *errstring)
75 {
76    char buf[512];
77    unsigned long sslerr;
78
79    /* Pop errors off of the per-thread queue */
80    while((sslerr = ERR_get_error()) != 0) {
81       /* Acquire the human readable string */
82       ERR_error_string_n(sslerr, (char *) &buf, sizeof(buf));
83       Emsg2(M_ERROR, 0, "%s: ERR=%s\n", errstring, buf);
84    }
85 }
86
87 /*
88  * OpenSSL certificate verification callback.
89  * OpenSSL has already performed internal certificate verification.
90  * We just report any errors that occured.
91  */
92 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
93 {
94
95    if (!ok) {
96       X509 *cert = X509_STORE_CTX_get_current_cert(store);
97       int depth = X509_STORE_CTX_get_error_depth(store);
98       int err = X509_STORE_CTX_get_error(store);
99       char issuer[256];
100       char subject[256];
101
102       X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
103       X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
104
105       Emsg5(M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s,"
106                           " subject = %s, ERR=%d:%s\n"), depth, issuer,
107                           subject, err, X509_verify_cert_error_string(err));
108
109    }
110
111    return ok;
112 }
113
114 /*
115  * Default PEM encryption passphrase callback.
116  * Returns an empty password.
117  */
118 static int tls_default_pem_callback(char *buf, int size, const void *userdata)
119 {
120    bstrncpy(buf, "", size);
121    return (strlen(buf));
122 }
123
124 /* Dispatch user PEM encryption callbacks */
125 static int openssl_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
126 {
127    TLS_CONTEXT *ctx = (TLS_CONTEXT *) userdata;
128    return (ctx->pem_callback(buf, size, ctx->pem_userdata));
129 }
130
131 /*
132  * Create a new TLS_CONTEXT instance.
133  *  Returns: Pointer to TLS_CONTEXT instance on success
134  *           NULL on failure;
135  */
136 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
137                              const char *certfile, const char *keyfile,
138                              TLS_PEM_PASSWD_CB *pem_callback,
139                              const void *pem_userdata, const char *dhfile,
140                              bool verify_peer)
141 {
142    TLS_CONTEXT *ctx;
143    BIO *bio;
144    DH *dh;
145
146    ctx = (TLS_CONTEXT *) malloc(sizeof(TLS_CONTEXT));
147
148    /* Allocate our OpenSSL TLSv1 Context */
149    ctx->openssl = SSL_CTX_new(TLSv1_method());
150
151    if (!ctx->openssl) {
152       openssl_post_errors(M_ERROR, _("Error initializing SSL context"));
153       goto err;
154    }
155
156    /* Set up pem encryption callback */
157    if (pem_callback) {
158       ctx->pem_callback = pem_callback;
159       ctx->pem_userdata = pem_userdata;
160    } else {
161       ctx->pem_callback = tls_default_pem_callback;
162       ctx->pem_userdata = NULL;
163    }
164    SSL_CTX_set_default_passwd_cb(ctx->openssl, openssl_pem_callback_dispatch);
165    SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx);
166
167    /*
168     * Set certificate verification paths. This requires that at least one
169     * value be non-NULL
170     */
171    if (ca_certfile || ca_certdir) {
172       if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) {
173          openssl_post_errors(M_ERROR, _("Error loading certificate verification stores"));
174          goto err;
175       }
176    } else if (verify_peer) {
177       /* At least one CA is required for peer verification */
178       Emsg0(M_ERROR, 0, _("Either a certificate file or a directory must be"
179                          " specified as a verification store\n"));
180       goto err;
181    }
182
183    /*
184     * Load our certificate file, if available. This file may also contain a
185     * private key, though this usage is somewhat unusual.
186     */
187    if (certfile) {
188       if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
189          openssl_post_errors(M_ERROR, _("Error loading certificate file"));
190          goto err;
191       }
192    }
193
194    /* Load our private key. */
195    if (keyfile) {
196       if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
197          openssl_post_errors(M_ERROR, _("Error loading private key"));
198          goto err;
199       }
200    }
201
202    /* Load Diffie-Hellman Parameters. */
203    if (dhfile) {
204       if (!(bio = BIO_new_file(dhfile, "r"))) {
205          openssl_post_errors(M_ERROR, _("Unable to open DH parameters file"));
206          goto err;
207       }
208       dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
209       BIO_free(bio);
210       if (!dh) {
211          openssl_post_errors(M_ERROR, _("Unable to load DH parameters from specified file"));
212          goto err;
213       }
214       if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
215          openssl_post_errors(M_ERROR, _("Failed to set TLS Diffie-Hellman parameters"));
216          DH_free(dh);
217          goto err;
218       }
219       /* Enable Single-Use DH for Ephemeral Keying */
220       SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
221    }
222
223    if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
224       Emsg0(M_ERROR, 0, _("Error setting cipher list, no valid ciphers available\n"));
225       goto err;
226    }
227
228    /* Verify Peer Certificate */
229    if (verify_peer) {
230            /* SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */
231            SSL_CTX_set_verify(ctx->openssl,
232                               SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
233                               openssl_verify_peer);
234    }
235
236    return ctx;
237
238 err:
239    /* Clean up after ourselves */
240    if(ctx->openssl) {
241       SSL_CTX_free(ctx->openssl);
242    }
243    free(ctx);
244    return NULL;
245 }
246
247 /*
248  * Free TLS_CONTEXT instance
249  */
250 void free_tls_context(TLS_CONTEXT *ctx)
251 {
252    SSL_CTX_free(ctx->openssl);
253    free(ctx);
254 }
255
256 /*
257  * Verifies a list of common names against the certificate
258  * commonName attribute.
259  *  Returns: true on success
260  *           false on failure
261  */
262 bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list)
263 {
264    SSL *ssl = tls->openssl;
265    X509 *cert;
266    X509_NAME *subject;
267    int auth_success = false;
268    char data[256];
269
270    /* Check if peer provided a certificate */
271    if (!(cert = SSL_get_peer_certificate(ssl))) {
272       Emsg0(M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
273       return false;
274    }
275
276    if ((subject = X509_get_subject_name(cert)) != NULL) {
277       if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
278          char *cn;
279          /* NULL terminate data */
280          data[255] = 0;
281
282          /* Try all the CNs in the list */
283          foreach_alist(cn, verify_list) {
284             if (strcasecmp(data, cn) == 0) {
285                auth_success = true;
286             }
287          }
288       }
289    }
290
291    X509_free(cert);
292    return auth_success;
293 }
294
295 /*
296  * Verifies a peer's hostname against the subjectAltName and commonName
297  * attributes.
298  *  Returns: true on success
299  *           false on failure
300  */
301 bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host)
302 {
303    SSL *ssl = tls->openssl;
304    X509 *cert;
305    X509_NAME *subject;
306    int auth_success = false;
307    int extensions;
308    char data[256];
309    int i, j;
310
311
312    /* Check if peer provided a certificate */
313    if (!(cert = SSL_get_peer_certificate(ssl))) {
314       Emsg1(M_ERROR, 0, _("Peer %s failed to present a TLS certificate\n"), host);
315       return false;
316    }
317
318    /* Check subjectAltName extensions first */
319    if ((extensions = X509_get_ext_count(cert)) > 0) {
320       for (i = 0; i < extensions; i++) {
321          X509_EXTENSION *ext;
322          const char *extname;
323
324          ext = X509_get_ext(cert, i);
325          extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
326
327          if (strcmp(extname, "subjectAltName") == 0) {
328             X509V3_EXT_METHOD *method;
329             STACK_OF(CONF_VALUE) *val;
330             CONF_VALUE *nval;
331             void *extstr = NULL;
332 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
333             const unsigned char *ext_value_data;
334 #else
335             unsigned char *ext_value_data;
336 #endif
337
338             /* Get x509 extension method structure */
339             if (!(method = X509V3_EXT_get(ext))) {
340                break;
341             }
342
343             ext_value_data = ext->value->data;
344
345 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
346             if (method->it) {
347                /* New style ASN1 */
348
349                /* Decode ASN1 item in data */
350                extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
351                                       ASN1_ITEM_ptr(method->it));
352             } else {
353                /* Old style ASN1 */
354
355                /* Decode ASN1 item in data */
356                extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
357             }
358
359 #else
360             extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
361 #endif
362
363             /* Iterate through to find the dNSName field(s) */
364             val = method->i2v(method, extstr, NULL);
365
366             /* dNSName shortname is "DNS" */
367             for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
368                nval = sk_CONF_VALUE_value(val, j);
369                if (strcmp(nval->name, "DNS") == 0) {
370                   if (strcasecmp(nval->name, host) == 0) {
371                      auth_success = true;
372                      goto success;
373                   }
374                }
375             }
376          }
377       }
378    }
379
380    /* Try verifying against the subject name */
381    if (!auth_success) {
382       if ((subject = X509_get_subject_name(cert)) != NULL) {
383          if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
384             /* NULL terminate data */
385             data[255] = 0;
386             if (strcasecmp(data, host) == 0) {
387                auth_success = true;
388             }
389          }
390       }
391    }
392
393
394 success:
395    X509_free(cert);
396
397    return auth_success;
398 }
399
400 /*
401  * Create a new TLS_CONNECTION instance.
402  *
403  * Returns: Pointer to TLS_CONNECTION instance on success
404  *          NULL on failure;
405  */
406 TLS_CONNECTION *new_tls_connection (TLS_CONTEXT *ctx, int fd)
407 {
408    BIO *bio;
409
410    /*
411     * Create a new BIO and assign the fd.
412     * The caller will remain responsible for closing the associated fd
413     */
414    bio = BIO_new(BIO_s_socket());
415    if (!bio) {
416       /* Not likely, but never say never */
417       openssl_post_errors(M_ERROR, _("Error creating file descriptor-based BIO"));
418       return NULL; /* Nothing allocated, nothing to clean up */
419    }
420    BIO_set_fd(bio, fd, BIO_NOCLOSE);
421
422    /* Allocate our new tls connection */
423    TLS_CONNECTION *tls = (TLS_CONNECTION *) malloc(sizeof(TLS_CONNECTION));
424
425    /* Create the SSL object and attach the socket BIO */
426    if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
427       /* Not likely, but never say never */
428       openssl_post_errors(M_ERROR, _("Error creating new SSL object"));
429       goto err;
430    }
431
432    SSL_set_bio(tls->openssl, bio, bio);
433
434    /* Non-blocking partial writes */
435    SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
436
437    return (tls);
438
439 err:
440    /* Clean up */
441    BIO_free(bio);
442    SSL_free(tls->openssl);
443    free(tls);
444
445    return NULL;
446 }
447
448 /*
449  * Free TLS_CONNECTION instance
450  */
451 void free_tls_connection (TLS_CONNECTION *tls)
452 {
453    SSL_free(tls->openssl);
454    free(tls);
455 }
456
457 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
458 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
459 {
460    TLS_CONNECTION *tls = bsock->tls;
461    int err;
462    int fdmax, flags;
463    int stat = true;
464    fd_set fdset;
465    struct timeval tv;
466
467    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
468    FD_ZERO(&fdset);
469    fdmax = bsock->fd + 1;
470
471    /* Ensure that socket is non-blocking */
472    flags = bnet_set_nonblocking(bsock);
473
474    /* start timer */
475    bsock->timer_start = watchdog_time;
476    bsock->timed_out = 0;
477
478    for (;;) { 
479       if (server) {
480          err = SSL_accept(tls->openssl);
481       } else {
482          err = SSL_connect(tls->openssl);
483       }
484
485       /* Handle errors */
486       switch (SSL_get_error(tls->openssl, err)) {
487       case SSL_ERROR_NONE:
488          stat = true;
489          goto cleanup;
490       case SSL_ERROR_ZERO_RETURN:
491          /* TLS connection was cleanly shut down */
492          openssl_post_errors(M_ERROR, _("Connect failure"));
493          stat = false;
494          goto cleanup;
495       case SSL_ERROR_WANT_READ:
496          /* If we timeout of a select, this will be unset */
497          FD_SET((unsigned) bsock->fd, &fdset);
498          /* Set our timeout */
499          tv.tv_sec = 10;
500          tv.tv_usec = 0;
501          /* Block until we can read */
502          select(fdmax, &fdset, NULL, &fdset, &tv);
503          break;
504       case SSL_ERROR_WANT_WRITE:
505          /* If we timeout of a select, this will be unset */
506          FD_SET((unsigned) bsock->fd, &fdset);
507          /* Set our timeout */
508          tv.tv_sec = 10;
509          tv.tv_usec = 0;
510          /* Block until we can write */
511          select(fdmax, NULL, &fdset, &fdset, &tv);
512          break;
513       default:
514          /* Socket Error Occured */
515          openssl_post_errors(M_ERROR, _("Connect failure"));
516          stat = false;
517          goto cleanup;
518       }
519
520       if (bsock->timed_out) {
521          goto cleanup;
522       }
523    }
524
525 cleanup:
526    /* Restore saved flags */
527    bnet_restore_blocking(bsock, flags);
528    /* Clear timer */
529    bsock->timer_start = 0;
530
531    return stat;
532 }
533
534 /*
535  * Initiates a TLS connection with the server.
536  *  Returns: true on success
537  *           false on failure
538  */
539 bool tls_bsock_connect(BSOCK *bsock)
540 {
541    /* SSL_connect(bsock->tls) */
542    return (openssl_bsock_session_start(bsock, false));
543 }
544
545 /*
546  * Listens for a TLS connection from a client.
547  *  Returns: true on success
548  *           false on failure
549  */
550 bool tls_bsock_accept(BSOCK *bsock)
551 {
552    /* SSL_accept(bsock->tls) */
553    return (openssl_bsock_session_start(bsock, true));
554 }
555
556 /*
557  * Shutdown TLS_CONNECTION instance
558  */
559 void tls_bsock_shutdown (BSOCK *bsock)
560 {
561    /*
562     * SSL_shutdown must be called twice to fully complete the process -
563     * The first time to initiate the shutdown handshake, and the second to
564     * receive the peer's reply.
565     *
566     * However, it is valid to close the SSL connection after the initial
567     * shutdown notification is sent to the peer, without waiting for the
568     * peer's reply, as long as you do not plan to re-use that particular
569     * SSL connection object.
570     *
571     * Because we do not re-use SSL connection objects, I do not bother
572     * calling SSL_shutdown a second time.
573     *
574     * In addition, if the underlying socket is blocking, SSL_shutdown()
575     * will not return until the current stage of the shutdown process has
576     * completed or an error has occured. By setting the socket blocking
577     * we can avoid the ugly for()/switch()/select() loop.
578     */
579    int err;
580    int flags;
581
582    /* Set socket blocking for shutdown */
583    flags = bnet_set_blocking(bsock);
584
585    err = SSL_shutdown(bsock->tls->openssl);
586
587    switch (SSL_get_error(bsock->tls->openssl, err)) {
588       case SSL_ERROR_NONE:
589          break;
590       case SSL_ERROR_ZERO_RETURN:
591          /* TLS connection was shut down on us via a TLS protocol-level closure */
592          openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
593          break;
594       default:
595          /* Socket Error Occured */
596          openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
597          break;
598    }
599
600    /* Restore saved flags */
601    bnet_restore_blocking(bsock, flags);
602 }
603
604 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
605 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
606 {
607    TLS_CONNECTION *tls = bsock->tls;
608    int fdmax, flags;
609    fd_set fdset;
610    struct timeval tv;
611    int nleft = 0;
612    int nwritten = 0;
613
614    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
615    FD_ZERO(&fdset);
616    fdmax = bsock->fd + 1;
617
618    /* Ensure that socket is non-blocking */
619    flags = bnet_set_nonblocking(bsock);
620
621    /* start timer */
622    bsock->timer_start = watchdog_time;
623    bsock->timed_out = 0;
624
625    nleft = nbytes;
626
627    while (nleft > 0) { 
628
629       if (write) {
630          nwritten = SSL_write(tls->openssl, ptr, nleft);
631       } else {
632          nwritten = SSL_read(tls->openssl, ptr, nleft);
633       }
634
635       /* Handle errors */
636       switch (SSL_get_error(tls->openssl, nwritten)) {
637       case SSL_ERROR_NONE:
638          nleft -= nwritten;
639          if (nleft) {
640             ptr += nwritten;
641          }
642          break;
643       case SSL_ERROR_ZERO_RETURN:
644          /* TLS connection was cleanly shut down */
645          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
646          goto cleanup;
647       case SSL_ERROR_WANT_READ:
648          /* If we timeout of a select, this will be unset */
649          FD_SET((unsigned) bsock->fd, &fdset);
650          tv.tv_sec = 10;
651          tv.tv_usec = 0;
652          /* Block until we can read */
653          select(fdmax, &fdset, NULL, &fdset, &tv);
654          break;
655       case SSL_ERROR_WANT_WRITE:
656          /* If we timeout of a select, this will be unset */
657          FD_SET((unsigned) bsock->fd, &fdset);
658          tv.tv_sec = 10;
659          tv.tv_usec = 0;
660          /* Block until we can write */
661          select(fdmax, NULL, &fdset, &fdset, &tv);
662          break;
663       default:
664          /* Socket Error Occured */
665          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
666          goto cleanup;
667       }
668
669       /* Everything done? */
670       if (nleft == 0) {
671          goto cleanup;
672       }
673
674       /* Timeout/Termination, let's take what we can get */
675       if (bsock->timed_out || bsock->terminated) {
676          goto cleanup;
677       }
678    }
679
680 cleanup:
681    /* Restore saved flags */
682    bnet_restore_blocking(bsock, flags);
683
684    /* Clear timer */
685    bsock->timer_start = 0;
686
687    return nbytes - nleft;
688 }
689
690
691 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) {
692    /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
693    return (openssl_bsock_readwrite(bsock, ptr, nbytes, true));
694 }
695
696 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) {
697    /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
698    return (openssl_bsock_readwrite(bsock, ptr, nbytes, false));
699 }
700
701 /*
702  * Return an OpenSSL thread ID
703  *  Returns: thread ID
704  *
705  */
706 static unsigned long get_openssl_thread_id (void)
707 {
708    /* Comparison without use of pthread_equal() is mandated by the OpenSSL API */
709    return ((unsigned long) pthread_self());
710 }
711
712 /*
713  * Allocate a dynamic OpenSSL mutex
714  */
715 static struct CRYPTO_dynlock_value *openssl_create_dynamic_mutex (const char *file, int line)
716 {
717    struct CRYPTO_dynlock_value *dynlock;
718    int stat;
719
720    dynlock = (struct CRYPTO_dynlock_value *) malloc(sizeof(struct CRYPTO_dynlock_value));
721
722    if ((stat = pthread_mutex_init(&dynlock->mutex, NULL)) != 0) {
723       Emsg1(M_ABORT, 0, _("Unable to init mutex: ERR=%s\n"), strerror(stat));
724    }
725
726    return dynlock;
727 }
728
729 static void openssl_update_dynamic_mutex (int mode, struct CRYPTO_dynlock_value *dynlock, const char *file, int line)
730 {
731    if (mode & CRYPTO_LOCK) {
732       P(dynlock->mutex);
733    } else {
734       V(dynlock->mutex);
735    }
736 }
737
738 static void openssl_destroy_dynamic_mutex (struct CRYPTO_dynlock_value *dynlock, const char *file, int line)
739 {
740    int stat;
741
742    if ((stat = pthread_mutex_destroy(&dynlock->mutex)) != 0) {
743       Emsg1(M_ABORT, 0, _("Unable to destroy mutex: ERR=%s\n"), strerror(stat));
744    }
745
746    free(dynlock);
747 }
748
749 /*
750  * (Un)Lock a static OpenSSL mutex
751  */
752 static void openssl_update_static_mutex (int mode, int i, const char *file, int line)
753 {
754    if (mode & CRYPTO_LOCK) {
755       P(mutexes[i]);
756    } else {
757       V(mutexes[i]);
758    }
759 }
760
761 /*
762  * Initialize OpenSSL thread support
763  *  Returns: 0 on success
764  *           errno on failure
765  */
766 static int openssl_init_threads (void)
767 {
768    int i, numlocks;
769    int stat;
770
771
772    /* Set thread ID callback */
773    CRYPTO_set_id_callback(get_openssl_thread_id);
774
775    /* Initialize static locking */
776    numlocks = CRYPTO_num_locks();
777    mutexes = (pthread_mutex_t *) malloc(numlocks * sizeof(pthread_mutex_t));
778    for (i = 0; i < numlocks; i++) {
779       if ((stat = pthread_mutex_init(&mutexes[i], NULL)) != 0) {
780          Emsg1(M_ERROR, 0, _("Unable to init mutex: ERR=%s\n"), strerror(stat));
781          return stat;
782       }
783    }
784
785    /* Set static locking callback */
786    CRYPTO_set_locking_callback(openssl_update_static_mutex);
787
788    /* Initialize dyanmic locking */
789    CRYPTO_set_dynlock_create_callback(openssl_create_dynamic_mutex);
790    CRYPTO_set_dynlock_lock_callback(openssl_update_dynamic_mutex);
791    CRYPTO_set_dynlock_destroy_callback(openssl_destroy_dynamic_mutex);
792
793    return 0;
794 }
795
796 /*
797  * Clean up OpenSSL threading support
798  */
799 static void openssl_cleanup_threads (void)
800 {
801    int i, numlocks;
802    int stat;
803
804    /* Unset thread ID callback */
805    CRYPTO_set_id_callback(NULL);
806   
807    /* Deallocate static lock mutexes */
808    numlocks = CRYPTO_num_locks();
809    for (i = 0; i < numlocks; i++) {
810       if ((stat = pthread_mutex_destroy(&mutexes[i])) != 0) {
811          /* We don't halt execution, reporting the error should be sufficient */
812          Emsg1(M_ERROR, 0, _("Unable to destroy mutex: ERR=%s\n"), strerror(stat));
813       }
814    }
815
816    /* Unset static locking callback */
817    CRYPTO_set_locking_callback(NULL);
818
819    /* Free static lock array */
820    free(mutexes);
821
822    /* Unset dynamic locking callbacks */
823    CRYPTO_set_dynlock_create_callback(NULL);
824    CRYPTO_set_dynlock_lock_callback(NULL);
825    CRYPTO_set_dynlock_destroy_callback(NULL);
826 }
827
828
829 /*
830  * Seed TLS PRNG
831  *  Returns: 1 on success
832  *           0 on failure
833  */
834 static int seed_tls_prng (void)
835 {
836    const char *names[]  = { "/dev/urandom", "/dev/random", NULL };
837    int i;
838
839    // ***FIXME***
840    // Win32 Support
841    // Read saved entropy?
842
843    for (i = 0; names[i]; i++) {
844       if (RAND_load_file(names[i], 1024) != -1) {
845          /* Success */
846          return 1;
847       }
848    }
849
850    /* Fail */
851    return 0;
852 }
853
854 /*
855  * Save TLS Entropy
856  *  Returns: 1 on success
857  *           0 on failure
858  */
859 static int save_tls_prng (void)
860 {
861    // ***FIXME***
862    // Implement PRNG state save
863    return 1;
864 }
865
866 /*
867  * Perform global initialization of TLS
868  * This function is not thread safe.
869  *  Returns: 0 on success
870  *           errno on failure
871  */
872 int init_tls (void)
873 {
874    int stat;
875
876    if ((stat = openssl_init_threads()) != 0) {
877       Emsg1(M_ABORT, 0, _("Unable to init OpenSSL threading: ERR=%s\n"), strerror(stat));
878    }
879
880    /* Load libssl and libcrypto human-readable error strings */
881    SSL_load_error_strings();
882
883    /* Register OpenSSL ciphers */
884    SSL_library_init();
885
886    if (!seed_tls_prng()) {
887       Emsg0(M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
888    }
889
890    tls_initialized = true;
891
892    return stat;
893 }
894
895 /*
896  * Perform global cleanup of TLS
897  * All TLS connections must be closed before calling this function.
898  * This function is not thread safe.
899  *  Returns: 0 on success
900  *           errno on failure
901  */
902 int cleanup_tls (void)
903 {
904    /*
905     * Ensure that we've actually been initialized; Doing this here decreases the
906     * complexity of client's termination/cleanup code.
907     */
908    if (!tls_initialized) {
909       return 0;
910    }
911
912    if (!save_tls_prng()) {
913       Emsg0(M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
914    }
915
916    openssl_cleanup_threads();
917
918    /* Free libssl and libcrypto error strings */
919    ERR_free_strings();
920
921    /* Free memory used by PRNG */
922    RAND_cleanup();
923
924    tls_initialized = false;
925
926    return 0;
927 }
928
929 #else /* HAVE_OPENSSL */
930 # error No TLS implementation available.
931 #endif /* !HAVE_OPENSSL */
932
933 #else
934
935 /* Dummy routines */
936 int init_tls(void) { return 0; }
937 int cleanup_tls (void) { return 0; }
938 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
939                              const char *certfile, const char *keyfile,
940                              TLS_PEM_PASSWD_CB *pem_callback,
941                              const void *pem_userdata, const char *dhfile,
942                              bool verify_peer)
943 {
944    return NULL;
945 }
946 void free_tls_context(TLS_CONTEXT *ctx) { }
947
948 #endif /* HAVE_TLS */