]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tls.c
- Apply Landon's patch for the TLS ANS1 API change.
[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    tv.tv_sec = 10;
470    tv.tv_usec = 0;
471    fdmax = bsock->fd + 1;
472
473    /* Ensure that socket is non-blocking */
474    flags = bnet_set_nonblocking(bsock);
475
476    /* start timer */
477    bsock->timer_start = watchdog_time;
478    bsock->timed_out = 0;
479
480    for (;;) { 
481       if (server) {
482          err = SSL_accept(tls->openssl);
483       } else {
484          err = SSL_connect(tls->openssl);
485       }
486
487       /* Handle errors */
488       switch (SSL_get_error(tls->openssl, err)) {
489            case SSL_ERROR_NONE:
490               stat = true;
491               goto cleanup;
492            case SSL_ERROR_ZERO_RETURN:
493               /* TLS connection was cleanly shut down */
494               openssl_post_errors(M_ERROR, _("Connect failure"));
495               stat = false;
496               goto cleanup;
497            case SSL_ERROR_WANT_READ:
498               /* If we timeout of a select, this will be unset */
499               FD_SET((unsigned) bsock->fd, &fdset);
500               /* Block until we can read */
501               select(fdmax, &fdset, NULL, &fdset, &tv);
502               break;
503            case SSL_ERROR_WANT_WRITE:
504               /* If we timeout of a select, this will be unset */
505               FD_SET((unsigned) bsock->fd, &fdset);
506               /* Block until we can write */
507               select(fdmax, NULL, &fdset, &fdset, &tv);
508               break;
509            default:
510               /* Socket Error Occured */
511               openssl_post_errors(M_ERROR, _("Connect failure"));
512               stat = false;
513               goto cleanup;
514       }
515
516       if (bsock->timed_out) {
517          goto cleanup;
518       }
519    }
520
521 cleanup:
522    /* Restore saved flags */
523    bnet_restore_blocking(bsock, flags);
524    /* Clear timer */
525    bsock->timer_start = 0;
526
527    return stat;
528 }
529
530 /*
531  * Initiates a TLS connection with the server.
532  *  Returns: true on success
533  *           false on failure
534  */
535 bool tls_bsock_connect(BSOCK *bsock)
536 {
537    /* SSL_connect(bsock->tls) */
538    return (openssl_bsock_session_start(bsock, false));
539 }
540
541 /*
542  * Listens for a TLS connection from a client.
543  *  Returns: true on success
544  *           false on failure
545  */
546 bool tls_bsock_accept(BSOCK *bsock)
547 {
548    /* SSL_accept(bsock->tls) */
549    return (openssl_bsock_session_start(bsock, true));
550 }
551
552 /*
553  * Shutdown TLS_CONNECTION instance
554  */
555 void tls_bsock_shutdown (BSOCK *bsock)
556 {
557    /*
558     * SSL_shutdown must be called twice to fully complete the process -
559     * The first time to initiate the shutdown handshake, and the second to
560     * receive the peer's reply.
561     *
562     * However, it is valid to close the SSL connection after the initial
563     * shutdown notification is sent to the peer, without waiting for the
564     * peer's reply, as long as you do not plan to re-use that particular
565     * SSL connection object.
566     *
567     * Because we do not re-use SSL connection objects, I do not bother
568     * calling SSL_shutdown a second time.
569     *
570     * In addition, if the underlying socket is blocking, SSL_shutdown()
571     * will not return until the current stage of the shutdown process has
572     * completed or an error has occured. By setting the socket blocking
573     * we can avoid the ugly for()/switch()/select() loop.
574     */
575    int err;
576    int flags;
577
578    /* Set socket blocking for shutdown */
579    flags = bnet_set_blocking(bsock);
580
581    err = SSL_shutdown(bsock->tls->openssl);
582
583    switch (SSL_get_error(bsock->tls->openssl, err)) {
584       case SSL_ERROR_NONE:
585          break;
586       case SSL_ERROR_ZERO_RETURN:
587          /* TLS connection was shut down on us via a TLS protocol-level closure */
588          openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
589          break;
590       default:
591          /* Socket Error Occured */
592          openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
593          break;
594    }
595
596    /* Restore saved flags */
597    bnet_restore_blocking(bsock, flags);
598 }
599
600 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
601 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
602 {
603    TLS_CONNECTION *tls = bsock->tls;
604    int fdmax, flags;
605    fd_set fdset;
606    struct timeval tv;
607    int nleft = 0;
608    int nwritten = 0;
609
610    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
611    FD_ZERO(&fdset);
612    tv.tv_sec = 10;
613    tv.tv_usec = 0;
614    fdmax = bsock->fd + 1;
615
616    /* Ensure that socket is non-blocking */
617    flags = bnet_set_nonblocking(bsock);
618
619    /* start timer */
620    bsock->timer_start = watchdog_time;
621    bsock->timed_out = 0;
622
623    nleft = nbytes;
624
625    while (nleft > 0) { 
626
627       if (write) {
628          nwritten = SSL_write(tls->openssl, ptr, nleft);
629       } else {
630          nwritten = SSL_read(tls->openssl, ptr, nleft);
631       }
632
633       /* Handle errors */
634       switch (SSL_get_error(tls->openssl, nwritten)) {
635          case SSL_ERROR_NONE:
636             nleft -= nwritten;
637             if (nleft) {
638                ptr += nwritten;
639             }
640             break;
641          case SSL_ERROR_ZERO_RETURN:
642             /* TLS connection was cleanly shut down */
643             openssl_post_errors(M_ERROR, _("TLS read/write failure."));
644             goto cleanup;
645          case SSL_ERROR_WANT_READ:
646             /* If we timeout of a select, this will be unset */
647             FD_SET((unsigned) bsock->fd, &fdset);
648             /* Block until we can read */
649             select(fdmax, &fdset, NULL, &fdset, &tv);
650             break;
651          case SSL_ERROR_WANT_WRITE:
652             /* If we timeout of a select, this will be unset */
653             FD_SET((unsigned) bsock->fd, &fdset);
654             /* Block until we can write */
655             select(fdmax, NULL, &fdset, &fdset, &tv);
656             break;
657          default:
658             /* Socket Error Occured */
659             openssl_post_errors(M_ERROR, _("TLS read/write failure."));
660             goto cleanup;
661       }
662
663       /* Everything done? */
664       if (nleft == 0) {
665          goto cleanup;
666       }
667
668       /* Timeout/Termination, let's take what we can get */
669       if (bsock->timed_out || bsock->terminated) {
670          goto cleanup;
671       }
672    }
673
674 cleanup:
675    /* Restore saved flags */
676    bnet_restore_blocking(bsock, flags);
677
678    /* Clear timer */
679    bsock->timer_start = 0;
680
681    return nbytes - nleft;
682 }
683
684
685 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) {
686    /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
687    return (openssl_bsock_readwrite(bsock, ptr, nbytes, true));
688 }
689
690 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) {
691    /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
692    return (openssl_bsock_readwrite(bsock, ptr, nbytes, false));
693 }
694
695 /*
696  * Return an OpenSSL thread ID
697  *  Returns: thread ID
698  *
699  */
700 static unsigned long get_openssl_thread_id (void)
701 {
702    /* Comparison without use of pthread_equal() is mandated by the OpenSSL API */
703    return ((unsigned long) pthread_self());
704 }
705
706 /*
707  * Allocate a dynamic OpenSSL mutex
708  */
709 static struct CRYPTO_dynlock_value *openssl_create_dynamic_mutex (const char *file, int line)
710 {
711    struct CRYPTO_dynlock_value *dynlock;
712    int stat;
713
714    dynlock = (struct CRYPTO_dynlock_value *) malloc(sizeof(struct CRYPTO_dynlock_value));
715
716    if ((stat = pthread_mutex_init(&dynlock->mutex, NULL)) != 0) {
717       Emsg1(M_ABORT, 0, _("Unable to init mutex: ERR=%s\n"), strerror(stat));
718    }
719
720    return dynlock;
721 }
722
723 static void openssl_update_dynamic_mutex (int mode, struct CRYPTO_dynlock_value *dynlock, const char *file, int line)
724 {
725    if (mode & CRYPTO_LOCK) {
726       P(dynlock->mutex);
727    } else {
728       V(dynlock->mutex);
729    }
730 }
731
732 static void openssl_destroy_dynamic_mutex (struct CRYPTO_dynlock_value *dynlock, const char *file, int line)
733 {
734    int stat;
735
736    if ((stat = pthread_mutex_destroy(&dynlock->mutex)) != 0) {
737       Emsg1(M_ABORT, 0, _("Unable to destroy mutex: ERR=%s\n"), strerror(stat));
738    }
739
740    free(dynlock);
741 }
742
743 /*
744  * (Un)Lock a static OpenSSL mutex
745  */
746 static void openssl_update_static_mutex (int mode, int i, const char *file, int line)
747 {
748    if (mode & CRYPTO_LOCK) {
749       P(mutexes[i]);
750    } else {
751       V(mutexes[i]);
752    }
753 }
754
755 /*
756  * Initialize OpenSSL thread support
757  *  Returns: 0 on success
758  *           errno on failure
759  */
760 static int openssl_init_threads (void)
761 {
762    int i, numlocks;
763    int stat;
764
765
766    /* Set thread ID callback */
767    CRYPTO_set_id_callback(get_openssl_thread_id);
768
769    /* Initialize static locking */
770    numlocks = CRYPTO_num_locks();
771    mutexes = (pthread_mutex_t *) malloc(numlocks * sizeof(pthread_mutex_t));
772    for (i = 0; i < numlocks; i++) {
773       if ((stat = pthread_mutex_init(&mutexes[i], NULL)) != 0) {
774          Emsg1(M_ERROR, 0, _("Unable to init mutex: ERR=%s\n"), strerror(stat));
775          return stat;
776       }
777    }
778
779    /* Set static locking callback */
780    CRYPTO_set_locking_callback(openssl_update_static_mutex);
781
782    /* Initialize dyanmic locking */
783    CRYPTO_set_dynlock_create_callback(openssl_create_dynamic_mutex);
784    CRYPTO_set_dynlock_lock_callback(openssl_update_dynamic_mutex);
785    CRYPTO_set_dynlock_destroy_callback(openssl_destroy_dynamic_mutex);
786
787    return 0;
788 }
789
790 /*
791  * Clean up OpenSSL threading support
792  */
793 static void openssl_cleanup_threads (void)
794 {
795    int i, numlocks;
796    int stat;
797
798    /* Unset thread ID callback */
799    CRYPTO_set_id_callback(NULL);
800   
801    /* Deallocate static lock mutexes */
802    numlocks = CRYPTO_num_locks();
803    for (i = 0; i < numlocks; i++) {
804       if ((stat = pthread_mutex_destroy(&mutexes[i])) != 0) {
805          /* We don't halt execution, reporting the error should be sufficient */
806          Emsg1(M_ERROR, 0, _("Unable to destroy mutex: ERR=%s\n"), strerror(stat));
807       }
808    }
809
810    /* Unset static locking callback */
811    CRYPTO_set_locking_callback(NULL);
812
813    /* Free static lock array */
814    free(mutexes);
815
816    /* Unset dynamic locking callbacks */
817    CRYPTO_set_dynlock_create_callback(NULL);
818    CRYPTO_set_dynlock_lock_callback(NULL);
819    CRYPTO_set_dynlock_destroy_callback(NULL);
820 }
821
822
823 /*
824  * Seed TLS PRNG
825  *  Returns: 1 on success
826  *           0 on failure
827  */
828 static int seed_tls_prng (void)
829 {
830    const char *names[]  = { "/dev/urandom", "/dev/random", NULL };
831    int i;
832
833    // ***FIXME***
834    // Win32 Support
835    // Read saved entropy?
836
837    for (i = 0; names[i]; i++) {
838       if (RAND_load_file(names[i], 1024) != -1) {
839          /* Success */
840          return 1;
841       }
842    }
843
844    /* Fail */
845    return 0;
846 }
847
848 /*
849  * Save TLS Entropy
850  *  Returns: 1 on success
851  *           0 on failure
852  */
853 static int save_tls_prng (void)
854 {
855    // ***FIXME***
856    // Implement PRNG state save
857    return 1;
858 }
859
860 /*
861  * Perform global initialization of TLS
862  * This function is not thread safe.
863  *  Returns: 0 on success
864  *           errno on failure
865  */
866 int init_tls (void)
867 {
868    int stat;
869
870    if ((stat = openssl_init_threads()) != 0) {
871       Emsg1(M_ABORT, 0, _("Unable to init OpenSSL threading: ERR=%s\n"), strerror(stat));
872    }
873
874    /* Load libssl and libcrypto human-readable error strings */
875    SSL_load_error_strings();
876
877    /* Register OpenSSL ciphers */
878    SSL_library_init();
879
880    if (!seed_tls_prng()) {
881       Emsg0(M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
882    }
883
884    tls_initialized = true;
885
886    return stat;
887 }
888
889 /*
890  * Perform global cleanup of TLS
891  * All TLS connections must be closed before calling this function.
892  * This function is not thread safe.
893  *  Returns: 0 on success
894  *           errno on failure
895  */
896 int cleanup_tls (void)
897 {
898    /*
899     * Ensure that we've actually been initialized; Doing this here decreases the
900     * complexity of client's termination/cleanup code.
901     */
902    if (!tls_initialized) {
903       return 0;
904    }
905
906    if (!save_tls_prng()) {
907       Emsg0(M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
908    }
909
910    openssl_cleanup_threads();
911
912    /* Free libssl and libcrypto error strings */
913    ERR_free_strings();
914
915    /* Free memory used by PRNG */
916    RAND_cleanup();
917
918    tls_initialized = false;
919
920    return 0;
921 }
922
923 #else /* HAVE_OPENSSL */
924 # error No TLS implementation available.
925 #endif /* !HAVE_OPENSSL */
926
927 #else
928
929 /* Dummy routines */
930 int init_tls(void) { return 0; }
931 int cleanup_tls (void) { return 0; }
932 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
933                              const char *certfile, const char *keyfile,
934                              TLS_PEM_PASSWD_CB *pem_callback,
935                              const void *pem_userdata, const char *dhfile,
936                              bool verify_peer)
937 {
938    return NULL;
939 }
940 void free_tls_context(TLS_CONTEXT *ctx) { }
941
942 #endif /* HAVE_TLS */