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