1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * tls.c TLS support functions
21  *
22  * Author: Landon Fuller <landonf@threerings.net>
23  *
24  * This file was contributed to the Bacula project by Landon Fuller
25  * and Three Rings Design, Inc.
26  *
27  * Three Rings Design, Inc. has been granted a perpetual, worldwide,
28  * non-exclusive, no-charge, royalty-free, irrevocable copyright
29  * license to reproduce, prepare derivative works of, publicly
30  * display, publicly perform, sublicense, and distribute the original
31  * work contributed by Three Rings Design, Inc. and its employees to
32  * the Bacula project in source or object form.
33  *
34  * If you wish to license contributions from Three Rings Design, Inc,
35  * under an alternate open source license please contact
36  * Landon Fuller <landonf@threerings.net>.
37  */
38 
39 
40 #include "bacula.h"
41 #include <assert.h>
42 
43 
44 #ifdef HAVE_TLS /* Is TLS enabled? */
45 
46 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
47 
48 #include "openssl-compat.h"
49 
50 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
51 #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
52 
53 /* TLS Context Structure */
54 struct TLS_Context {
55    SSL_CTX *openssl;
56    CRYPTO_PEM_PASSWD_CB *pem_callback;
57    const void *pem_userdata;
58    bool tls_enable;
59    bool tls_require;
60 };
61 
62 struct TLS_Connection {
63    SSL *openssl;
64    pthread_mutex_t wlock;  /* make openssl_bsock_readwrite() atomic when writing */
65    pthread_mutex_t rwlock; /* only one SSL_read() or SSL_write() at a time */
66 };
67 
68 /*
69  * OpenSSL certificate verification callback.
70  * OpenSSL has already performed internal certificate verification.
71  * We just report any errors that occured.
72  */
openssl_verify_peer(int ok,X509_STORE_CTX * store)73 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
74 {
75    if (!ok) {
76       X509 *cert = X509_STORE_CTX_get_current_cert(store);
77       int depth = X509_STORE_CTX_get_error_depth(store);
78       int err = X509_STORE_CTX_get_error(store);
79       char issuer[256];
80       char subject[256];
81 
82       if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
83           err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)
84       {
85          /* It seems that the error can be also
86           * 24 X509_V_ERR_INVALID_CA: invalid CA certificate
87           * But it's not very specific...
88           */
89          Jmsg0(NULL, M_ERROR, 0, _("CA certificate is self signed. With OpenSSL 1.1, enforce basicConstraints = CA:true in the certificate creation to avoid this issue\n"));
90       }
91       X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
92       X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
93 
94       Jmsg5(NULL, M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s,"
95             " subject = %s, ERR=%d:%s\n"), depth, issuer,
96               subject, err, X509_verify_cert_error_string(err));
97 
98    }
99 
100    return ok;
101 }
102 
103 /* Dispatch user PEM encryption callbacks */
tls_pem_callback_dispatch(char * buf,int size,int rwflag,void * userdata)104 static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
105 {
106    TLS_CONTEXT *ctx = (TLS_CONTEXT *)userdata;
107    return (ctx->pem_callback(buf, size, ctx->pem_userdata));
108 }
109 
110 /*
111  * Create a new TLS_CONTEXT instance.
112  *  Returns: Pointer to TLS_CONTEXT instance on success
113  *           NULL on failure;
114  */
new_tls_context(const char * ca_certfile,const char * ca_certdir,const char * certfile,const char * keyfile,CRYPTO_PEM_PASSWD_CB * pem_callback,const void * pem_userdata,const char * dhfile,bool verify_peer)115 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
116                              const char *certfile, const char *keyfile,
117                              CRYPTO_PEM_PASSWD_CB *pem_callback,
118                              const void *pem_userdata, const char *dhfile,
119                              bool verify_peer)
120 {
121    TLS_CONTEXT *ctx;
122    BIO *bio;
123    DH *dh;
124 
125    ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT));
126 
127    /* Allocate our OpenSSL TLS Context */
128 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
129    /* Allows SSLv3, TLSv1, TLSv1.1 and TLSv1.2 protocols */
130    ctx->openssl = SSL_CTX_new(TLS_method());
131 
132 #else
133    /* Allows most all protocols */
134    ctx->openssl = SSL_CTX_new(SSLv23_method());
135 
136 #endif
137 
138    /* Use SSL_OP_ALL to turn on all "rather harmless" workarounds that
139     * OpenSSL offers
140     */
141    SSL_CTX_set_options(ctx->openssl, SSL_OP_ALL);
142 
143    /* Now disable old broken SSLv3 and SSLv2 protocols */
144    SSL_CTX_set_options(ctx->openssl, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
145 
146    if (!ctx->openssl) {
147       openssl_post_errors(M_FATAL, _("Error initializing SSL context"));
148       goto err;
149    }
150 
151    /* Set up pem encryption callback */
152    if (pem_callback) {
153       ctx->pem_callback = pem_callback;
154       ctx->pem_userdata = pem_userdata;
155    } else {
156       ctx->pem_callback = crypto_default_pem_callback;
157       ctx->pem_userdata = NULL;
158    }
159    SSL_CTX_set_default_passwd_cb(ctx->openssl, tls_pem_callback_dispatch);
160    SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx);
161 
162    /*
163     * Set certificate verification paths. This requires that at least one
164     * value be non-NULL
165     */
166    if (ca_certfile || ca_certdir) {
167       if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) {
168          openssl_post_errors(M_FATAL, _("Error loading certificate verification stores"));
169          goto err;
170       }
171    } else if (verify_peer) {
172       /* At least one CA is required for peer verification */
173       Jmsg0(NULL, M_ERROR, 0, _("Either a certificate file or a directory must be"
174                          " specified as a verification store\n"));
175       goto err;
176    }
177 
178    /*
179     * Load our certificate file, if available. This file may also contain a
180     * private key, though this usage is somewhat unusual.
181     */
182    if (certfile) {
183       if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
184          openssl_post_errors(M_FATAL, _("Error loading certificate file"));
185          goto err;
186       }
187    }
188 
189    /* Load our private key. */
190    if (keyfile) {
191       if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
192          openssl_post_errors(M_FATAL, _("Error loading private key"));
193          goto err;
194       }
195    }
196 
197    /* Load Diffie-Hellman Parameters. */
198    if (dhfile) {
199       if (!(bio = BIO_new_file(dhfile, "r"))) {
200          openssl_post_errors(M_FATAL, _("Unable to open DH parameters file"));
201          goto err;
202       }
203       dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
204       BIO_free(bio);
205       if (!dh) {
206          openssl_post_errors(M_FATAL, _("Unable to load DH parameters from specified file"));
207          goto err;
208       }
209       if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
210          openssl_post_errors(M_FATAL, _("Failed to set TLS Diffie-Hellman parameters"));
211          DH_free(dh);
212          goto err;
213       }
214       /* Enable Single-Use DH for Ephemeral Keying */
215       SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
216    }
217 
218    if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
219       Jmsg0(NULL, M_ERROR, 0,
220              _("Error setting cipher list, no valid ciphers available\n"));
221       goto err;
222    }
223 
224    /* Verify Peer Certificate */
225    if (verify_peer) {
226       /* SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */
227       SSL_CTX_set_verify(ctx->openssl,
228                          SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
229                          openssl_verify_peer);
230    }
231    return ctx;
232 
233 err:
234    /* Clean up after ourselves */
235    if(ctx->openssl) {
236       SSL_CTX_free(ctx->openssl);
237    }
238    free(ctx);
239    return NULL;
240 }
241 
242 /*
243  * Free TLS_CONTEXT instance
244  */
free_tls_context(TLS_CONTEXT * ctx)245 void free_tls_context(TLS_CONTEXT *ctx)
246 {
247    SSL_CTX_free(ctx->openssl);
248    free(ctx);
249 }
250 
get_tls_require(TLS_CONTEXT * ctx)251 bool get_tls_require(TLS_CONTEXT *ctx)
252 {
253    return ctx->tls_require;
254 }
255 
get_tls_enable(TLS_CONTEXT * ctx)256 bool get_tls_enable(TLS_CONTEXT *ctx)
257 {
258    return ctx->tls_enable;
259 }
260 
261 
262 /*
263  * Verifies a list of common names against the certificate
264  * commonName attribute.
265  *  Returns: true on success
266  *           false on failure
267  */
tls_postconnect_verify_cn(JCR * jcr,TLS_CONNECTION * tls,alist * verify_list)268 bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list)
269 {
270    SSL *ssl = tls->openssl;
271    X509 *cert;
272    X509_NAME *subject;
273    bool auth_success = false;
274    char data[256];
275 
276    /* Check if peer provided a certificate */
277    if (!(cert = SSL_get_peer_certificate(ssl))) {
278       Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
279       return false;
280    }
281 
282    if ((subject = X509_get_subject_name(cert)) != NULL) {
283       if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
284          char *cn;
285          /* NULL terminate data */
286          data[255] = 0;
287 
288          /* Try all the CNs in the list */
289          foreach_alist(cn, verify_list) {
290             if (strcasecmp(data, cn) == 0) {
291                auth_success = true;
292             }
293          }
294       }
295    }
296 
297    X509_free(cert);
298    return auth_success;
299 }
300 
301 /*
302  * Verifies a peer's hostname against the subjectAltName and commonName
303  * attributes.
304  *  Returns: true on success
305  *           false on failure
306  */
tls_postconnect_verify_host(JCR * jcr,TLS_CONNECTION * tls,const char * host)307 bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host)
308 {
309    SSL *ssl = tls->openssl;
310    X509 *cert;
311    X509_NAME *subject;
312    bool auth_success = false;
313    int extensions;
314    int i, j;
315    const char *pval, *phost;
316 
317    int cnLastPos = -1;
318    X509_NAME_ENTRY *neCN;
319    ASN1_STRING *asn1CN;
320 
321    /* Check if peer provided a certificate */
322    if (!(cert = SSL_get_peer_certificate(ssl))) {
323       Qmsg1(jcr, M_ERROR, 0,
324             _("Peer %s failed to present a TLS certificate\n"), host);
325       Dmsg1(250, _("Peer %s failed to present a TLS certificate\n"), host);
326       return false;
327    }
328 
329    /* Check subjectAltName extensions first */
330    if ((extensions = X509_get_ext_count(cert)) > 0) {
331       for (i = 0; i < extensions; i++) {
332          X509_EXTENSION *ext;
333          const char *extname;
334 
335          ext = X509_get_ext(cert, i);
336          extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
337 
338          if (strcmp(extname, "subjectAltName") == 0) {
339 #ifdef HAVE_OPENSSLv1
340             const X509V3_EXT_METHOD *method;
341 #else
342             X509V3_EXT_METHOD *method;
343 #endif
344             STACK_OF(CONF_VALUE) *val;
345             CONF_VALUE *nval;
346             void *extstr = NULL;
347             const unsigned char *ext_value_data;
348             const ASN1_STRING *asn1_ext_val;
349 
350             /* Get x509 extension method structure */
351             if (!(method = X509V3_EXT_get(ext))) {
352                break;
353             }
354 
355             asn1_ext_val = X509_EXTENSION_get_data(ext);
356             ext_value_data = ASN1_STRING_get0_data(asn1_ext_val);
357 
358             if (method->it) {
359                /* New style ASN1 */
360 
361                /* Decode ASN1 item in data */
362                extstr = ASN1_item_d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val),
363                                       ASN1_ITEM_ptr(method->it));
364             } else {
365                /* Old style ASN1 */
366 
367                /* Decode ASN1 item in data */
368                extstr = method->d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val));
369             }
370 
371             /* Iterate through to find the dNSName field(s) */
372             val = method->i2v(method, extstr, NULL);
373 
374             /* dNSName shortname is "DNS" */
375             Dmsg0(250, "Check DNS name\n");
376             for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
377                nval = sk_CONF_VALUE_value(val, j);
378                if (strcmp(nval->name, "DNS") == 0) {
379                   if (strncasecmp(nval->value, "*.", 2) == 0) {
380                      Dmsg0(250, "Wildcard Certificate\n");
381                      pval = strstr(nval->value, ".");
382                      phost = strstr(host, ".");
383                      if (pval && phost && (strcasecmp(pval, phost) == 0)) {
384                         auth_success = true;
385                         goto success;
386                      }
387                   } else if (strcasecmp(nval->value, host) == 0) {
388                      auth_success = true;
389                      goto success;
390                   }
391                   Dmsg2(250, "No DNS name match. Host=%s cert=%s\n", host, nval->value);
392                }
393             }
394          }
395       }
396    }
397 
398    /* Try verifying against the subject name */
399    if (!auth_success) {
400       Dmsg0(250, "Check subject name name\n");
401       if ((subject = X509_get_subject_name(cert)) != NULL) {
402          /* Loop through all CNs */
403          for (;;) {
404             cnLastPos = X509_NAME_get_index_by_NID(subject, NID_commonName, cnLastPos);
405             if (cnLastPos == -1) {
406                break;
407             }
408             neCN = X509_NAME_get_entry(subject, cnLastPos);
409             asn1CN = X509_NAME_ENTRY_get_data(neCN);
410             if (strncasecmp((const char*)asn1CN->data, "*.", 2) == 0) {
411                /* wildcard certificate */
412                Dmsg0(250, "Wildcard Certificate\n");
413                pval = strstr((const char*)asn1CN->data, ".");
414                phost = strstr(host, ".");
415                if (pval && phost && (strcasecmp(pval, phost) == 0)) {
416                   auth_success = true;
417                   goto success;
418                }
419             } else if (strcasecmp((const char*)asn1CN->data, host) == 0) {
420                auth_success = true;
421                break;
422             }
423             Dmsg2(250, "No subject name match. Host=%s cert=%s\n", host, (const char*)asn1CN->data);
424          }
425       }
426    }
427 
428 success:
429    X509_free(cert);
430    return auth_success;
431 }
432 
433 /*
434  * Create a new TLS_CONNECTION instance.
435  *
436  * Returns: Pointer to TLS_CONNECTION instance on success
437  *          NULL on failure;
438  */
new_tls_connection(TLS_CONTEXT * ctx,int fd)439 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
440 {
441    BIO *bio;
442 
443    /*
444     * Create a new BIO and assign the fd.
445     * The caller will remain responsible for closing the associated fd
446     */
447    bio = BIO_new(BIO_s_socket());
448    if (!bio) {
449       /* Not likely, but never say never */
450       openssl_post_errors(M_FATAL, _("Error creating file descriptor-based BIO"));
451       return NULL; /* Nothing allocated, nothing to clean up */
452    }
453    BIO_set_fd(bio, fd, BIO_NOCLOSE);
454 
455    /* Allocate our new tls connection */
456    TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
457 
458    /* Create the SSL object and attach the socket BIO */
459    if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
460       /* Not likely, but never say never */
461       openssl_post_errors(M_FATAL, _("Error creating new SSL object"));
462       goto err;
463    }
464 
465    SSL_set_bio(tls->openssl, bio, bio);
466 
467    /* Non-blocking partial writes */
468    SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
469 
470    pthread_mutex_init(&tls->wlock, NULL);
471    pthread_mutex_init(&tls->rwlock, NULL);
472 
473    return tls;
474 
475 err:
476    /* Clean up */
477    BIO_free(bio);
478    SSL_free(tls->openssl);
479    free(tls);
480    return NULL;
481 }
482 
483 /*
484  * Free TLS_CONNECTION instance
485  */
free_tls_connection(TLS_CONNECTION * tls)486 void free_tls_connection(TLS_CONNECTION *tls)
487 {
488    if (tls) {
489       pthread_mutex_destroy(&tls->rwlock);
490       pthread_mutex_destroy(&tls->wlock);
491       SSL_free(tls->openssl);
492       free(tls);
493    }
494 }
495 
496 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
openssl_bsock_session_start(BSOCK * bsock,bool server)497 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
498 {
499    TLS_CONNECTION *tls = bsock->tls;
500    int err;
501    int flags;
502    int stat = true;
503 
504    /* Ensure that socket is non-blocking */
505    flags = bsock->set_nonblocking();
506 
507    /* start timer */
508    bsock->timer_start = watchdog_time;
509    bsock->clear_timed_out();
510    bsock->set_killable(false);
511 
512    for (;;) {
513       if (server) {
514          err = SSL_accept(tls->openssl);
515       } else {
516          err = SSL_connect(tls->openssl);
517       }
518 
519       /* Handle errors */
520       switch (SSL_get_error(tls->openssl, err)) {
521       case SSL_ERROR_NONE:
522          stat = true;
523          goto cleanup;
524       case SSL_ERROR_ZERO_RETURN:
525          /* TLS connection was cleanly shut down */
526          openssl_post_errors(bsock->get_jcr(), M_FATAL, _("Connect failure"));
527          stat = false;
528          goto cleanup;
529       case SSL_ERROR_WANT_READ:
530          /* Block until we can read */
531          fd_wait_data(bsock->m_fd, WAIT_READ, 10, 0);
532          break;
533       case SSL_ERROR_WANT_WRITE:
534          /* Block until we can write */
535          fd_wait_data(bsock->m_fd, WAIT_WRITE, 10, 0);
536          break;
537       default:
538          /* Socket Error Occurred */
539          openssl_post_errors(bsock->get_jcr(), M_FATAL, _("Connect failure"));
540          stat = false;
541          goto cleanup;
542       }
543 
544       if (bsock->is_timed_out()) {
545          goto cleanup;
546       }
547    }
548 
549 cleanup:
550    /* Restore saved flags */
551    bsock->restore_blocking(flags);
552    /* Clear timer */
553    bsock->timer_start = 0;
554    bsock->set_killable(true);
555 
556    return stat;
557 }
558 
559 /*
560  * Initiates a TLS connection with the server.
561  *  Returns: true on success
562  *           false on failure
563  */
tls_bsock_connect(BSOCK * bsock)564 bool tls_bsock_connect(BSOCK *bsock)
565 {
566    /* SSL_connect(bsock->tls) */
567    return openssl_bsock_session_start(bsock, false);
568 }
569 
570 /*
571  * Listens for a TLS connection from a client.
572  *  Returns: true on success
573  *           false on failure
574  */
tls_bsock_accept(BSOCK * bsock)575 bool tls_bsock_accept(BSOCK *bsock)
576 {
577    /* SSL_accept(bsock->tls) */
578    return openssl_bsock_session_start(bsock, true);
579 }
580 
581 /*
582  * Shutdown TLS_CONNECTION instance
583  */
tls_bsock_shutdown(BSOCKCORE * bsock)584 void tls_bsock_shutdown(BSOCKCORE *bsock)
585 {
586    /*
587     * SSL_shutdown must be called twice to fully complete the process -
588     * The first time to initiate the shutdown handshake, and the second to
589     * receive the peer's reply.
590     *
591     * In addition, if the underlying socket is blocking, SSL_shutdown()
592     * will not return until the current stage of the shutdown process has
593     * completed or an error has occured. By setting the socket blocking
594     * we can avoid the ugly for()/switch()/select() loop.
595     */
596    int err;
597 
598    btimer_t *tid;
599 
600    /* Set socket blocking for shutdown */
601    bsock->set_blocking();
602 
603    tid = start_bsock_timer(bsock, 60 * 2);
604    err = SSL_shutdown(bsock->tls->openssl);
605    stop_bsock_timer(tid);
606    if (err == 0) {
607       /* Complete shutdown */
608       tid = start_bsock_timer(bsock, 60 * 2);
609       err = SSL_shutdown(bsock->tls->openssl);
610       stop_bsock_timer(tid);
611    }
612 
613 
614    switch (SSL_get_error(bsock->tls->openssl, err)) {
615    case SSL_ERROR_NONE:
616       break;
617    case SSL_ERROR_ZERO_RETURN:
618       /* TLS connection was shut down on us via a TLS protocol-level closure */
619       openssl_post_errors(bsock->get_jcr(), M_ERROR, _("TLS shutdown failure."));
620       break;
621    default:
622       /* Socket Error Occurred */
623       openssl_post_errors(bsock->get_jcr(), M_ERROR, _("TLS shutdown failure."));
624       break;
625    }
626 }
627 
628 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
openssl_bsock_readwrite(BSOCK * bsock,char * ptr,int nbytes,bool write)629 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
630 {
631    TLS_CONNECTION *tls = bsock->tls;
632    int nleft = 0;
633    int nwritten = 0;
634 
635 
636    /* start timer */
637    bsock->timer_start = watchdog_time;
638    bsock->clear_timed_out();
639    bsock->set_killable(false);
640 
641    nleft = nbytes;
642 
643    if (write) {
644       pthread_mutex_lock(&tls->wlock);
645    }
646    while (nleft > 0) {
647 
648       pthread_mutex_lock(&tls->rwlock);
649       /* Ensure that socket is non-blocking */
650       int flags = bsock->set_nonblocking();
651       int ssl_error = SSL_ERROR_NONE;
652       while (nleft > 0 && ssl_error == SSL_ERROR_NONE) {
653          if (write) {
654             nwritten = SSL_write(tls->openssl, ptr, nleft);
655          } else {
656             nwritten = SSL_read(tls->openssl, ptr, nleft);
657          }
658          if (nwritten > 0) {
659             nleft -= nwritten;
660             if (nleft) {
661                ptr += nwritten;
662             }
663          } else {
664             ssl_error = SSL_get_error(tls->openssl, nwritten);
665          }
666       }
667       /* Restore saved flags */
668       bsock->restore_blocking(flags);
669       pthread_mutex_unlock(&tls->rwlock);
670 
671       /* Handle errors */
672       switch (ssl_error) {
673       case SSL_ERROR_NONE:
674          ASSERT2(nleft == 0, "the buffer should be empty");
675          break;
676 
677       case SSL_ERROR_SYSCALL:
678          if (nwritten == -1) {
679             if (errno == EINTR) {
680                continue;
681             }
682             if (errno == EAGAIN) {
683                bmicrosleep(0, 20000); /* try again in 20 ms */
684                continue;
685             }
686          }
687          openssl_post_errors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure."));
688          goto cleanup;
689 
690       case SSL_ERROR_WANT_READ:
691          /* Block until we can read */
692          fd_wait_data(bsock->m_fd, WAIT_READ, 10, 0);
693          break;
694 
695       case SSL_ERROR_WANT_WRITE:
696          /* Block until we can read */
697          fd_wait_data(bsock->m_fd, WAIT_WRITE, 10, 0);
698          break;
699 
700       case SSL_ERROR_ZERO_RETURN:
701          /* TLS connection was cleanly shut down */
702          /* Fall through wanted */
703       default:
704          /* Socket Error Occured */
705          openssl_post_errors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure."));
706          goto cleanup;
707       }
708 
709       /* Everything done? */
710       if (nleft == 0) {
711          goto cleanup;
712       }
713 
714       /* Timeout/Termination, let's take what we can get */
715       if (bsock->is_timed_out() || bsock->is_terminated()) {
716          goto cleanup;
717       }
718    }
719 
720 cleanup:
721    if (write) {
722       pthread_mutex_unlock(&tls->wlock);
723    }
724 
725    /* Clear timer */
726    bsock->timer_start = 0;
727    bsock->set_killable(true);
728    return nbytes - nleft;
729 }
730 
731 
tls_bsock_writen(BSOCK * bsock,char * ptr,int32_t nbytes)732 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes)
733 {
734    /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
735    return openssl_bsock_readwrite(bsock, ptr, nbytes, true);
736 }
737 
tls_bsock_readn(BSOCK * bsock,char * ptr,int32_t nbytes)738 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes)
739 {
740    /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
741    return openssl_bsock_readwrite(bsock, ptr, nbytes, false);
742 }
743 
744 /* test if 4 bytes can be read without "blocking" */
tls_bsock_probe(BSOCKCORE * bsock)745 bool tls_bsock_probe(BSOCKCORE *bsock)
746 {
747    int32_t pktsiz;
748    return SSL_peek(bsock->tls->openssl, &pktsiz, sizeof(pktsiz))==sizeof(pktsiz);
749 }
750 
751 #else /* HAVE_OPENSSL */
752 # error No TLS implementation available.
753 #endif /* !HAVE_OPENSSL */
754 
755 
756 #else     /* TLS NOT enabled, dummy routines substituted */
757 
758 
759 /* Dummy routines */
new_tls_context(const char * ca_certfile,const char * ca_certdir,const char * certfile,const char * keyfile,CRYPTO_PEM_PASSWD_CB * pem_callback,const void * pem_userdata,const char * dhfile,bool verify_peer)760 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
761                              const char *certfile, const char *keyfile,
762                              CRYPTO_PEM_PASSWD_CB *pem_callback,
763                              const void *pem_userdata, const char *dhfile,
764                              bool verify_peer)
765 {
766    return NULL;
767 }
free_tls_context(TLS_CONTEXT * ctx)768 void free_tls_context(TLS_CONTEXT *ctx) { }
769 
tls_bsock_shutdown(BSOCKCORE * bsock)770 void tls_bsock_shutdown(BSOCKCORE *bsock) { }
771 
free_tls_connection(TLS_CONNECTION * tls)772 void free_tls_connection(TLS_CONNECTION *tls) { }
773 
get_tls_require(TLS_CONTEXT * ctx)774 bool get_tls_require(TLS_CONTEXT *ctx)
775 {
776    return false;
777 }
778 
get_tls_enable(TLS_CONTEXT * ctx)779 bool get_tls_enable(TLS_CONTEXT *ctx)
780 {
781    return false;
782 }
783 
784 #endif /* HAVE_TLS */
785