1 /* $Cambridge: exim/src/src/tls-openssl.c,v 1.10 2007/01/18 15:35:42 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2007 */
8 /* See the file NOTICE for conditions of use and distribution. */
10 /* This module provides the TLS (aka SSL) support for Exim using the OpenSSL
11 library. It is #included into the tls.c file when that library is used. The
12 code herein is based on a patch that was originally contributed by Steve
13 Haslam. It was adapted from stunnel, a GPL program by Michal Trojnara.
15 No cryptographic code is included in Exim. All this module does is to call
16 functions from the OpenSSL library. */
21 #include <openssl/lhash.h>
22 #include <openssl/ssl.h>
23 #include <openssl/err.h>
24 #include <openssl/rand.h>
26 /* Structure for collecting random data for seeding. */
28 typedef struct randstuff {
33 /* Local static variables */
35 static BOOL verify_callback_called = FALSE;
36 static const uschar *sid_ctx = US"exim";
38 static SSL_CTX *ctx = NULL;
39 static SSL *ssl = NULL;
41 static char ssl_errstring[256];
43 static int ssl_session_timeout = 200;
44 static BOOL verify_optional = FALSE;
50 /*************************************************
52 *************************************************/
54 /* Called from lots of places when errors occur before actually starting to do
55 the TLS handshake, that is, while the session is still in clear. Always returns
56 DEFER for a server and FAIL for a client so that most calls can use "return
57 tls_error(...)" to do this processing and then give an appropriate return. A
58 single function is used for both server and client, because it is called from
59 some shared functions.
62 prefix text to include in the logged error
63 host NULL if setting up a server;
64 the connected host if setting up a client
66 Returns: OK/DEFER/FAIL
70 tls_error(uschar *prefix, host_item *host)
72 ERR_error_string(ERR_get_error(), ssl_errstring);
75 log_write(0, LOG_MAIN, "TLS error on connection from %s (%s): %s",
76 (sender_fullhost != NULL)? sender_fullhost : US"local process",
77 prefix, ssl_errstring);
82 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s): %s",
83 host->name, host->address, prefix, ssl_errstring);
90 /*************************************************
91 * Callback to generate RSA key *
92 *************************************************/
100 Returns: pointer to generated key
104 rsa_callback(SSL *s, int export, int keylength)
107 export = export; /* Shut picky compilers up */
108 DEBUG(D_tls) debug_printf("Generating %d bit RSA key...\n", keylength);
109 rsa_key = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
112 ERR_error_string(ERR_get_error(), ssl_errstring);
113 log_write(0, LOG_MAIN|LOG_PANIC, "TLS error (RSA_generate_key): %s",
123 /*************************************************
124 * Callback for verification *
125 *************************************************/
127 /* The SSL library does certificate verification if set up to do so. This
128 callback has the current yes/no state is in "state". If verification succeeded,
129 we set up the tls_peerdn string. If verification failed, what happens depends
130 on whether the client is required to present a verifiable certificate or not.
132 If verification is optional, we change the state to yes, but still log the
133 verification error. For some reason (it really would help to have proper
134 documentation of OpenSSL), this callback function then gets called again, this
135 time with state = 1. In fact, that's useful, because we can set up the peerdn
136 value, but we must take care not to set the private verified flag on the second
139 Note: this function is not called if the client fails to present a certificate
140 when asked. We get here only if a certificate has been received. Handling of
141 optional verification for this case is done when requesting SSL to verify, by
142 setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the non-optional case.
145 state current yes/no state as 1/0
146 x509ctx certificate information.
148 Returns: 1 if verified, 0 if not
152 verify_callback(int state, X509_STORE_CTX *x509ctx)
154 static uschar txt[256];
156 X509_NAME_oneline(X509_get_subject_name(x509ctx->current_cert),
157 CS txt, sizeof(txt));
161 log_write(0, LOG_MAIN, "SSL verify error: depth=%d error=%s cert=%s",
162 x509ctx->error_depth,
163 X509_verify_cert_error_string(x509ctx->error),
165 tls_certificate_verified = FALSE;
166 verify_callback_called = TRUE;
167 if (!verify_optional) return 0; /* reject */
168 DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
169 "tls_try_verify_hosts)\n");
170 return 1; /* accept */
173 if (x509ctx->error_depth != 0)
175 DEBUG(D_tls) debug_printf("SSL verify ok: depth=%d cert=%s\n",
176 x509ctx->error_depth, txt);
180 DEBUG(D_tls) debug_printf("SSL%s peer: %s\n",
181 verify_callback_called? "" : " authenticated", txt);
185 if (!verify_callback_called) tls_certificate_verified = TRUE;
186 verify_callback_called = TRUE;
188 return 1; /* accept */
193 /*************************************************
194 * Information callback *
195 *************************************************/
197 /* The SSL library functions call this from time to time to indicate what they
198 are doing. We copy the string to the debugging output when the level is high
210 info_callback(SSL *s, int where, int ret)
214 DEBUG(D_tls) debug_printf("SSL info: %s\n", SSL_state_string_long(s));
219 /*************************************************
220 * Initialize for DH *
221 *************************************************/
223 /* If dhparam is set, expand it, and load up the parameters for DH encryption.
226 dhparam DH parameter file
228 Returns: TRUE if OK (nothing to set up, or setup worked)
232 init_dh(uschar *dhparam)
239 if (!expand_check(dhparam, US"tls_dhparam", &dhexpanded))
242 if (dhexpanded == NULL) return TRUE;
244 if ((bio = BIO_new_file(CS dhexpanded, "r")) == NULL)
246 log_write(0, LOG_MAIN, "DH: could not read %s: %s", dhexpanded,
252 if ((dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL)
254 log_write(0, LOG_MAIN, "DH: could not load params from %s",
260 SSL_CTX_set_tmp_dh(ctx, dh);
262 debug_printf("Diffie-Hellman initialized from %s with %d-bit key\n",
263 dhexpanded, 8*DH_size(dh));
275 /*************************************************
276 * Initialize for TLS *
277 *************************************************/
279 /* Called from both server and client code, to do preliminary initialization of
283 host connected host, if client; NULL if server
284 dhparam DH parameter file
285 certificate certificate file
286 privatekey private key
287 addr address if client; NULL if server (for some randomness)
289 Returns: OK/DEFER/FAIL
293 tls_init(host_item *host, uschar *dhparam, uschar *certificate,
294 uschar *privatekey, address_item *addr)
296 SSL_load_error_strings(); /* basic set up */
297 OpenSSL_add_ssl_algorithms();
299 /* Create a context */
301 ctx = SSL_CTX_new((host == NULL)?
302 SSLv23_server_method() : SSLv23_client_method());
304 if (ctx == NULL) return tls_error(US"SSL_CTX_new", host);
306 /* It turns out that we need to seed the random number generator this early in
307 order to get the full complement of ciphers to work. It took me roughly a day
308 of work to discover this by experiment.
310 On systems that have /dev/urandom, SSL may automatically seed itself from
311 there. Otherwise, we have to make something up as best we can. Double check
320 RAND_seed((uschar *)(&r), sizeof(r));
321 RAND_seed((uschar *)big_buffer, big_buffer_size);
322 if (addr != NULL) RAND_seed((uschar *)addr, sizeof(addr));
328 log_write(0, LOG_MAIN, "TLS error on connection from %s: "
329 "unable to seed random number generator",
330 (sender_fullhost != NULL)? sender_fullhost : US"local process");
335 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
336 "unable to seed random number generator",
337 host->name, host->address);
343 /* Set up the information callback, which outputs if debugging is at a suitable
346 if (!(SSL_CTX_set_info_callback(ctx, (void (*)())info_callback)))
347 return tls_error(US"SSL_CTX_set_info_callback", host);
349 /* The following patch was supplied by Robert Roselius */
351 #if OPENSSL_VERSION_NUMBER > 0x00906040L
352 /* Enable client-bug workaround.
353 Versions of OpenSSL as of 0.9.6d include a "CBC countermeasure" feature,
354 which causes problems with some clients (such as the Certicom SSL Plus
355 library used by Eudora). This option, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS,
356 disables the coutermeasure allowing Eudora to connect.
357 Some poppers and MTAs use SSL_OP_ALL, which enables all such bug
359 /* XXX (Silently?) ignore failure here? XXX*/
361 if (!(SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)))
362 return tls_error(US"SSL_CTX_set_option", host);
365 /* Initialize with DH parameters if supplied */
367 if (!init_dh(dhparam)) return DEFER;
369 /* Set up certificate and key */
371 if (certificate != NULL)
374 if (!expand_check(certificate, US"tls_certificate", &expanded))
377 if (expanded != NULL)
379 DEBUG(D_tls) debug_printf("tls_certificate file %s\n", expanded);
380 if (!SSL_CTX_use_certificate_chain_file(ctx, CS expanded))
381 return tls_error(string_sprintf(
382 "SSL_CTX_use_certificate_chain_file file=%s", expanded), host);
385 if (privatekey != NULL &&
386 !expand_check(privatekey, US"tls_privatekey", &expanded))
389 /* If expansion was forced to fail, key_expanded will be NULL. If the result
390 of the expansion is an empty string, ignore it also, and assume the private
391 key is in the same file as the certificate. */
393 if (expanded != NULL && *expanded != 0)
395 DEBUG(D_tls) debug_printf("tls_privatekey file %s\n", expanded);
396 if (!SSL_CTX_use_PrivateKey_file(ctx, CS expanded, SSL_FILETYPE_PEM))
397 return tls_error(string_sprintf(
398 "SSL_CTX_use_PrivateKey_file file=%s", expanded), host);
402 /* Set up the RSA callback */
404 SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
406 /* Finally, set the timeout, and we are done */
408 SSL_CTX_set_timeout(ctx, ssl_session_timeout);
409 DEBUG(D_tls) debug_printf("Initialized TLS\n");
416 /*************************************************
417 * Get name of cipher in use *
418 *************************************************/
420 /* The answer is left in a static buffer, and tls_cipher is set to point
423 Argument: pointer to an SSL structure for the connection
428 construct_cipher_name(SSL *ssl)
430 static uschar cipherbuf[256];
435 switch (ssl->session->ssl_version)
453 c = SSL_get_current_cipher(ssl);
454 SSL_CIPHER_get_bits(c, &bits);
456 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
457 SSL_CIPHER_get_name(c), bits);
458 tls_cipher = cipherbuf;
460 DEBUG(D_tls) debug_printf("Cipher: %s\n", cipherbuf);
467 /*************************************************
468 * Set up for verifying certificates *
469 *************************************************/
471 /* Called by both client and server startup
474 certs certs file or NULL
476 host NULL in a server; the remote host in a client
477 optional TRUE if called from a server for a host in tls_try_verify_hosts;
478 otherwise passed as FALSE
480 Returns: OK/DEFER/FAIL
484 setup_certs(uschar *certs, uschar *crl, host_item *host, BOOL optional)
486 uschar *expcerts, *expcrl;
488 if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
491 if (expcerts != NULL)
494 if (!SSL_CTX_set_default_verify_paths(ctx))
495 return tls_error(US"SSL_CTX_set_default_verify_paths", host);
497 if (Ustat(expcerts, &statbuf) < 0)
499 log_write(0, LOG_MAIN|LOG_PANIC,
500 "failed to stat %s for certificates", expcerts);
506 if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
507 { file = NULL; dir = expcerts; }
509 { file = expcerts; dir = NULL; }
511 /* If a certificate file is empty, the next function fails with an
512 unhelpful error message. If we skip it, we get the correct behaviour (no
513 certificates are recognized, but the error message is still misleading (it
514 says no certificate was supplied.) But this is better. */
516 if ((file == NULL || statbuf.st_size > 0) &&
517 !SSL_CTX_load_verify_locations(ctx, CS file, CS dir))
518 return tls_error(US"SSL_CTX_load_verify_locations", host);
522 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CS file));
526 /* Handle a certificate revocation list. */
528 #if OPENSSL_VERSION_NUMBER > 0x00907000L
530 /* This bit of code is now the version supplied by Lars Mainka. (I have
531 * merely reformatted it into the Exim code style.)
533 * "From here I changed the code to add support for multiple crl's
534 * in pem format in one file or to support hashed directory entries in
535 * pem format instead of a file. This method now uses the library function
536 * X509_STORE_load_locations to add the CRL location to the SSL context.
537 * OpenSSL will then handle the verify against CA certs and CRLs by
538 * itself in the verify callback." */
540 if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
541 if (expcrl != NULL && *expcrl != 0)
543 struct stat statbufcrl;
544 if (Ustat(expcrl, &statbufcrl) < 0)
546 log_write(0, LOG_MAIN|LOG_PANIC,
547 "failed to stat %s for certificates revocation lists", expcrl);
552 /* is it a file or directory? */
554 X509_STORE *cvstore = SSL_CTX_get_cert_store(ctx);
555 if ((statbufcrl.st_mode & S_IFMT) == S_IFDIR)
559 DEBUG(D_tls) debug_printf("SSL CRL value is a directory %s\n", dir);
565 DEBUG(D_tls) debug_printf("SSL CRL value is a file %s\n", file);
567 if (X509_STORE_load_locations(cvstore, CS file, CS dir) == 0)
568 return tls_error(US"X509_STORE_load_locations", host);
570 /* setting the flags to check against the complete crl chain */
572 X509_STORE_set_flags(cvstore,
573 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
577 #endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
579 /* If verification is optional, don't fail if no certificate */
581 SSL_CTX_set_verify(ctx,
582 SSL_VERIFY_PEER | (optional? 0 : SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
591 /*************************************************
592 * Start a TLS session in a server *
593 *************************************************/
595 /* This is called when Exim is running as a server, after having received
596 the STARTTLS command. It must respond to that command, and then negotiate
600 require_ciphers allowed ciphers
601 ------------------------------------------------------
602 require_mac list of allowed MACs ) Not used
603 require_kx list of allowed key_exchange methods ) for
604 require_proto list of allowed protocols ) OpenSSL
605 ------------------------------------------------------
607 Returns: OK on success
608 DEFER for errors before the start of the negotiation
609 FAIL for errors during the negotation; the server can't
614 tls_server_start(uschar *require_ciphers, uschar *require_mac,
615 uschar *require_kx, uschar *require_proto)
620 /* Check for previous activation */
624 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
625 "connection from %s",
626 (sender_fullhost != NULL)? sender_fullhost : US"local process");
627 smtp_printf("554 Already in TLS\r\n");
631 /* Initialize the SSL library. If it fails, it will already have logged
634 rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL);
635 if (rc != OK) return rc;
637 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
640 /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
641 are separated by underscores. So that I can use either form in my tests, and
642 also for general convenience, we turn underscores into hyphens here. */
644 if (expciphers != NULL)
646 uschar *s = expciphers;
647 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
648 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
649 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
650 return tls_error(US"SSL_CTX_set_cipher_list", NULL);
653 /* If this is a host for which certificate verification is mandatory or
654 optional, set up appropriately. */
656 tls_certificate_verified = FALSE;
657 verify_callback_called = FALSE;
659 if (verify_check_host(&tls_verify_hosts) == OK)
661 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, FALSE);
662 if (rc != OK) return rc;
663 verify_optional = FALSE;
665 else if (verify_check_host(&tls_try_verify_hosts) == OK)
667 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, TRUE);
668 if (rc != OK) return rc;
669 verify_optional = TRUE;
672 /* Prepare for new connection */
674 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", NULL);
677 /* Set context and tell client to go ahead, except in the case of TLS startup
678 on connection, where outputting anything now upsets the clients and tends to
679 make them disconnect. We need to have an explicit fflush() here, to force out
680 the response. Other smtp_printf() calls do not need it, because in non-TLS
681 mode, the fflush() happens when smtp_getc() is called. */
683 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
686 smtp_printf("220 TLS go ahead\r\n");
690 /* Now negotiate the TLS session. We put our own timer on it, since it seems
691 that the OpenSSL library doesn't. */
693 SSL_set_wfd(ssl, fileno(smtp_out));
694 SSL_set_rfd(ssl, fileno(smtp_in));
695 SSL_set_accept_state(ssl);
697 DEBUG(D_tls) debug_printf("Calling SSL_accept\n");
699 sigalrm_seen = FALSE;
700 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
701 rc = SSL_accept(ssl);
706 if (sigalrm_seen) Ustrcpy(ssl_errstring, "timed out");
707 else ERR_error_string(ERR_get_error(), ssl_errstring);
708 log_write(0, LOG_MAIN, "TLS error on connection from %s (SSL_accept): %s",
709 (sender_fullhost != NULL)? sender_fullhost : US"local process",
714 DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
716 /* TLS has been set up. Adjust the input functions to read via TLS,
717 and initialize things. */
719 construct_cipher_name(ssl);
724 if (SSL_get_shared_ciphers(ssl, CS buf, sizeof(buf)) != NULL)
725 debug_printf("Shared ciphers: %s\n", buf);
729 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
730 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
731 ssl_xfer_eof = ssl_xfer_error = 0;
733 receive_getc = tls_getc;
734 receive_ungetc = tls_ungetc;
735 receive_feof = tls_feof;
736 receive_ferror = tls_ferror;
738 tls_active = fileno(smtp_out);
746 /*************************************************
747 * Start a TLS session in a client *
748 *************************************************/
750 /* Called from the smtp transport after STARTTLS has been accepted.
753 fd the fd of the connection
754 host connected host (for messages)
755 addr the first address
756 dhparam DH parameter file
757 certificate certificate file
758 privatekey private key file
759 verify_certs file for certificate verify
760 crl file containing CRL
761 require_ciphers list of allowed ciphers
762 ------------------------------------------------------
763 require_mac list of allowed MACs ) Not used
764 require_kx list of allowed key_exchange methods ) for
765 require_proto list of allowed protocols ) OpenSSL
766 ------------------------------------------------------
767 timeout startup timeout
769 Returns: OK on success
770 FAIL otherwise - note that tls_error() will not give DEFER
771 because this is not a server
775 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
776 uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
777 uschar *require_ciphers, uschar *require_mac, uschar *require_kx,
778 uschar *require_proto, int timeout)
780 static uschar txt[256];
785 rc = tls_init(host, dhparam, certificate, privatekey, addr);
786 if (rc != OK) return rc;
788 tls_certificate_verified = FALSE;
789 verify_callback_called = FALSE;
791 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
794 /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
795 are separated by underscores. So that I can use either form in my tests, and
796 also for general convenience, we turn underscores into hyphens here. */
798 if (expciphers != NULL)
800 uschar *s = expciphers;
801 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
802 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
803 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
804 return tls_error(US"SSL_CTX_set_cipher_list", host);
807 rc = setup_certs(verify_certs, crl, host, FALSE);
808 if (rc != OK) return rc;
810 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", host);
811 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
813 SSL_set_connect_state(ssl);
815 /* There doesn't seem to be a built-in timeout on connection. */
817 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
818 sigalrm_seen = FALSE;
820 rc = SSL_connect(ssl);
827 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
828 "SSL_connect timed out", host->name, host->address);
831 else return tls_error(US"SSL_connect", host);
834 DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
836 server_cert = SSL_get_peer_certificate (ssl);
837 tls_peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
838 CS txt, sizeof(txt));
841 construct_cipher_name(ssl); /* Sets tls_cipher */
851 /*************************************************
852 * TLS version of getc *
853 *************************************************/
855 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
856 it refills the buffer via the SSL reading function.
859 Returns: the next character or EOF
865 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
870 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
871 (long)ssl_xfer_buffer, ssl_xfer_buffer_size);
873 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
874 inbytes = SSL_read(ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size);
875 error = SSL_get_error(ssl, inbytes);
878 /* SSL_ERROR_ZERO_RETURN appears to mean that the SSL session has been
879 closed down, not that the socket itself has been closed down. Revert to
882 if (error == SSL_ERROR_ZERO_RETURN)
884 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
886 receive_getc = smtp_getc;
887 receive_ungetc = smtp_ungetc;
888 receive_feof = smtp_feof;
889 receive_ferror = smtp_ferror;
900 /* Handle genuine errors */
902 else if (error != SSL_ERROR_NONE)
904 DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
909 ssl_xfer_buffer_hwm = inbytes;
910 ssl_xfer_buffer_lwm = 0;
913 /* Something in the buffer; return next uschar */
915 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
920 /*************************************************
921 * Read bytes from TLS channel *
922 *************************************************/
929 Returns: the number of bytes read
930 -1 after a failed read
934 tls_read(uschar *buff, size_t len)
939 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
940 (long)buff, (unsigned int)len);
942 inbytes = SSL_read(ssl, CS buff, len);
943 error = SSL_get_error(ssl, inbytes);
945 if (error == SSL_ERROR_ZERO_RETURN)
947 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
950 else if (error != SSL_ERROR_NONE)
962 /*************************************************
963 * Write bytes down TLS channel *
964 *************************************************/
971 Returns: the number of bytes after a successful write,
972 -1 after a failed write
976 tls_write(const uschar *buff, size_t len)
982 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long)buff, left);
985 DEBUG(D_tls) debug_printf("SSL_write(SSL, %lx, %d)\n", (long)buff, left);
986 outbytes = SSL_write(ssl, CS buff, left);
987 error = SSL_get_error(ssl, outbytes);
988 DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
992 ERR_error_string(ERR_get_error(), ssl_errstring);
993 log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
1001 case SSL_ERROR_ZERO_RETURN:
1002 log_write(0, LOG_MAIN, "SSL channel closed on write");
1006 log_write(0, LOG_MAIN, "SSL_write error %d", error);
1015 /*************************************************
1016 * Close down a TLS session *
1017 *************************************************/
1019 /* This is also called from within a delivery subprocess forked from the
1020 daemon, to shut down the TLS library, without actually doing a shutdown (which
1021 would tamper with the SSL session in the parent process).
1023 Arguments: TRUE if SSL_shutdown is to be called
1028 tls_close(BOOL shutdown)
1030 if (tls_active < 0) return; /* TLS was not active */
1034 DEBUG(D_tls) debug_printf("tls_close(): shutting down SSL\n");
1044 /* End of tls-openssl.c */