1 /* $Cambridge: exim/src/src/tls-openssl.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2004 */
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);
186 debug_printf("+++verify_callback_called=%d\n", verify_callback_called);
188 if (!verify_callback_called) tls_certificate_verified = TRUE;
189 verify_callback_called = TRUE;
191 return 1; /* accept */
196 /*************************************************
197 * Information callback *
198 *************************************************/
200 /* The SSL library functions call this from time to time to indicate what they
201 are doing. We copy the string to the debugging output when the level is high
213 info_callback(SSL *s, int where, int ret)
217 DEBUG(D_tls) debug_printf("SSL info: %s\n", SSL_state_string_long(s));
222 /*************************************************
223 * Initialize for DH *
224 *************************************************/
226 /* If dhparam is set, expand it, and load up the parameters for DH encryption.
229 dhparam DH parameter file
231 Returns: TRUE if OK (nothing to set up, or setup worked)
235 init_dh(uschar *dhparam)
242 if (!expand_check(dhparam, US"tls_dhparam", &dhexpanded))
245 if (dhexpanded == NULL) return TRUE;
247 if ((bio = BIO_new_file(CS dhexpanded, "r")) == NULL)
249 log_write(0, LOG_MAIN, "DH: could not read %s: %s", dhexpanded,
255 if ((dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL)
257 log_write(0, LOG_MAIN, "DH: could not load params from %s",
263 SSL_CTX_set_tmp_dh(ctx, dh);
265 debug_printf("Diffie-Hellman initialized from %s with %d-bit key\n",
266 dhexpanded, 8*DH_size(dh));
278 /*************************************************
279 * Initialize for TLS *
280 *************************************************/
282 /* Called from both server and client code, to do preliminary initialization of
286 host connected host, if client; NULL if server
287 dhparam DH parameter file
288 certificate certificate file
289 privatekey private key
290 addr address if client; NULL if server (for some randomness)
292 Returns: OK/DEFER/FAIL
296 tls_init(host_item *host, uschar *dhparam, uschar *certificate, uschar *privatekey,
299 SSL_load_error_strings(); /* basic set up */
300 OpenSSL_add_ssl_algorithms();
302 /* Create a context */
304 ctx = SSL_CTX_new((host == NULL)?
305 SSLv23_server_method() : SSLv23_client_method());
307 if (ctx == NULL) return tls_error(US"SSL_CTX_new", host);
309 /* It turns out that we need to seed the random number generator this early in
310 order to get the full complement of ciphers to work. It took me roughly a day
311 of work to discover this by experiment.
313 On systems that have /dev/urandom, SSL may automatically seed itself from
314 there. Otherwise, we have to make something up as best we can. Double check
323 RAND_seed((uschar *)(&r), sizeof(r));
324 RAND_seed((uschar *)big_buffer, big_buffer_size);
325 if (addr != NULL) RAND_seed((uschar *)addr, sizeof(addr));
331 log_write(0, LOG_MAIN, "TLS error on connection from %s: "
332 "unable to seed random number generator",
333 (sender_fullhost != NULL)? sender_fullhost : US"local process");
338 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
339 "unable to seed random number generator",
340 host->name, host->address);
346 /* Set up the information callback, which outputs if debugging is at a suitable
349 if (!(SSL_CTX_set_info_callback(ctx, (void (*)())info_callback)))
350 return tls_error(US"SSL_CTX_set_info_callback", host);
352 /* The following patch was supplied by Robert Roselius */
354 #if OPENSSL_VERSION_NUMBER > 0x00906040L
355 /* Enable client-bug workaround.
356 Versions of OpenSSL as of 0.9.6d include a "CBC countermeasure" feature,
357 which causes problems with some clients (such as the Certicom SSL Plus
358 library used by Eudora). This option, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS,
359 disables the coutermeasure allowing Eudora to connect.
360 Some poppers and MTAs use SSL_OP_ALL, which enables all such bug
362 /* XXX (Silently?) ignore failure here? XXX*/
364 if (!(SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)))
365 return tls_error(US"SSL_CTX_set_option", host);
368 /* Initialize with DH parameters if supplied */
370 if (!init_dh(dhparam)) return DEFER;
372 /* Set up certificate and key */
374 if (certificate != NULL)
377 if (!expand_check(certificate, US"tls_certificate", &expanded))
380 if (expanded != NULL)
382 DEBUG(D_tls) debug_printf("tls_certificate file %s\n", expanded);
383 if (!SSL_CTX_use_certificate_chain_file(ctx, CS expanded))
384 return tls_error(US"SSL_CTX_use_certificate_chain_file", host);
387 if (privatekey != NULL &&
388 !expand_check(privatekey, US"tls_privatekey", &expanded))
391 if (expanded != NULL)
393 DEBUG(D_tls) debug_printf("tls_privatekey file %s\n", expanded);
394 if (!SSL_CTX_use_PrivateKey_file(ctx, CS expanded, SSL_FILETYPE_PEM))
395 return tls_error(US"SSL_CTX_use_PrivateKey_file", host);
399 /* Set up the RSA callback */
401 SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
403 /* Finally, set the timeout, and we are done */
405 SSL_CTX_set_timeout(ctx, ssl_session_timeout);
406 DEBUG(D_tls) debug_printf("Initialized TLS\n");
413 /*************************************************
414 * Get name of cipher in use *
415 *************************************************/
417 /* The answer is left in a static buffer, and tls_cipher is set to point
420 Argument: pointer to an SSL structure for the connection
425 construct_cipher_name(SSL *ssl)
427 static uschar cipherbuf[256];
432 switch (ssl->session->ssl_version)
450 c = SSL_get_current_cipher(ssl);
451 SSL_CIPHER_get_bits(c, &bits);
453 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
454 SSL_CIPHER_get_name(c), bits);
455 tls_cipher = cipherbuf;
457 DEBUG(D_tls) debug_printf("Cipher: %s\n", cipherbuf);
464 /*************************************************
465 * Set up for verifying certificates *
466 *************************************************/
468 /* Called by both client and server startup
471 certs certs file or NULL
473 host NULL in a server; the remote host in a client
474 optional TRUE if called from a server for a host in tls_try_verify_hosts;
475 otherwise passed as FALSE
477 Returns: OK/DEFER/FAIL
481 setup_certs(uschar *certs, uschar *crl, host_item *host, BOOL optional)
483 uschar *expcerts, *expcrl;
485 if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
488 if (expcerts != NULL)
491 if (!SSL_CTX_set_default_verify_paths(ctx))
492 return tls_error(US"SSL_CTX_set_default_verify_paths", host);
494 if (Ustat(expcerts, &statbuf) < 0)
496 log_write(0, LOG_MAIN|LOG_PANIC,
497 "failed to stat %s for certificates", expcerts);
503 if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
504 { file = NULL; dir = expcerts; }
506 { file = expcerts; dir = NULL; }
508 /* If a certificate file is empty, the next function fails with an
509 unhelpful error message. If we skip it, we get the correct behaviour (no
510 certificates are recognized, but the error message is still misleading (it
511 says no certificate was supplied.) But this is better. */
513 if ((file == NULL || statbuf.st_size > 0) &&
514 !SSL_CTX_load_verify_locations(ctx, CS file, CS dir))
515 return tls_error(US"SSL_CTX_load_verify_locations", host);
519 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CS file));
523 /* Handle a certificate revocation list. */
525 #if OPENSSL_VERSION_NUMBER > 0x00907000L
527 if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
528 if (expcrl != NULL && *expcrl != 0)
534 cvstore = SSL_CTX_get_cert_store(ctx); /* cert validation store */
536 crl_bio = BIO_new(BIO_s_file_internal());
539 if (BIO_read_filename(crl_bio, expcrl))
541 crl_x509 = PEM_read_bio_X509_CRL(crl_bio, NULL, NULL, NULL);
543 X509_STORE_add_crl(cvstore, crl_x509);
544 X509_CRL_free(crl_x509);
545 X509_STORE_set_flags(cvstore,
546 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
551 return tls_error(US"BIO_read_filename", host);
554 else return tls_error(US"BIO_new", host);
557 #endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
559 /* If verification is optional, don't fail if no certificate */
561 SSL_CTX_set_verify(ctx,
562 SSL_VERIFY_PEER | (optional? 0 : SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
571 /*************************************************
572 * Start a TLS session in a server *
573 *************************************************/
575 /* This is called when Exim is running as a server, after having received
576 the STARTTLS command. It must respond to that command, and then negotiate
580 require_ciphers allowed ciphers
582 Returns: OK on success
583 DEFER for errors before the start of the negotiation
584 FAIL for errors during the negotation; the server can't
589 tls_server_start(uschar *require_ciphers)
594 /* Check for previous activation */
598 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
599 "connection from %s",
600 (sender_fullhost != NULL)? sender_fullhost : US"local process");
601 smtp_printf("554 Already in TLS\r\n");
605 /* Initialize the SSL library. If it fails, it will already have logged
608 rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL);
609 if (rc != OK) return rc;
611 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
614 /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
615 are separated by underscores. So that I can use either form in my tests, and
616 also for general convenience, we turn underscores into hyphens here. */
618 if (expciphers != NULL)
620 uschar *s = expciphers;
621 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
622 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
623 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
624 return tls_error(US"SSL_CTX_set_cipher_list", NULL);
627 /* If this is a host for which certificate verification is mandatory or
628 optional, set up appropriately. */
630 tls_certificate_verified = FALSE;
631 verify_callback_called = FALSE;
633 if (verify_check_host(&tls_verify_hosts) == OK)
635 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, FALSE);
636 if (rc != OK) return rc;
637 verify_optional = FALSE;
639 else if (verify_check_host(&tls_try_verify_hosts) == OK)
641 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, TRUE);
642 if (rc != OK) return rc;
643 verify_optional = TRUE;
646 /* Prepare for new connection */
648 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", NULL);
651 /* Set context and tell client to go ahead, except in the case of TLS startup
652 on connection, where outputting anything now upsets the clients and tends to
653 make them disconnect. We need to have an explicit fflush() here, to force out
654 the response. Other smtp_printf() calls do not need it, because in non-TLS
655 mode, the fflush() happens when smtp_getc() is called. */
657 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
660 smtp_printf("220 TLS go ahead\r\n");
664 /* Now negotiate the TLS session. We put our own timer on it, since it seems
665 that the OpenSSL library doesn't. */
667 SSL_set_fd(ssl, fileno(smtp_out));
668 SSL_set_accept_state(ssl);
670 DEBUG(D_tls) debug_printf("Calling SSL_accept\n");
672 sigalrm_seen = FALSE;
673 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
674 rc = SSL_accept(ssl);
679 if (sigalrm_seen) Ustrcpy(ssl_errstring, "timed out");
680 else ERR_error_string(ERR_get_error(), ssl_errstring);
681 log_write(0, LOG_MAIN, "TLS error on connection from %s (SSL_accept): %s",
682 (sender_fullhost != NULL)? sender_fullhost : US"local process",
687 DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
689 /* TLS has been set up. Adjust the input functions to read via TLS,
690 and initialize things. */
692 construct_cipher_name(ssl);
697 if (SSL_get_shared_ciphers(ssl, CS buf, sizeof(buf)) != NULL)
698 debug_printf("Shared ciphers: %s\n", buf);
702 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
703 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
704 ssl_xfer_eof = ssl_xfer_error = 0;
706 receive_getc = tls_getc;
707 receive_ungetc = tls_ungetc;
708 receive_feof = tls_feof;
709 receive_ferror = tls_ferror;
711 tls_active = fileno(smtp_out);
719 /*************************************************
720 * Start a TLS session in a client *
721 *************************************************/
723 /* Called from the smtp transport after STARTTLS has been accepted.
726 fd the fd of the connection
727 host connected host (for messages)
728 dhparam DH parameter file
729 certificate certificate file
730 privatekey private key file
731 verify_certs file for certificate verify
732 crl file containing CRL
733 require_ciphers list of allowed ciphers
735 Returns: OK on success
736 FAIL otherwise - note that tls_error() will not give DEFER
737 because this is not a server
741 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
742 uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
743 uschar *require_ciphers, int timeout)
745 static uschar txt[256];
750 rc = tls_init(host, dhparam, certificate, privatekey, addr);
751 if (rc != OK) return rc;
753 tls_certificate_verified = FALSE;
754 verify_callback_called = FALSE;
756 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
759 /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
760 are separated by underscores. So that I can use either form in my tests, and
761 also for general convenience, we turn underscores into hyphens here. */
763 if (expciphers != NULL)
765 uschar *s = expciphers;
766 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
767 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
768 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
769 return tls_error(US"SSL_CTX_set_cipher_list", host);
772 rc = setup_certs(verify_certs, crl, host, FALSE);
773 if (rc != OK) return rc;
775 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", host);
776 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
778 SSL_set_connect_state(ssl);
780 /* There doesn't seem to be a built-in timeout on connection. */
782 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
783 sigalrm_seen = FALSE;
785 rc = SSL_connect(ssl);
792 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
793 "SSL_connect timed out", host->name, host->address);
796 else return tls_error(US"SSL_connect", host);
799 DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
801 server_cert = SSL_get_peer_certificate (ssl);
802 tls_peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
803 CS txt, sizeof(txt));
806 construct_cipher_name(ssl); /* Sets tls_cipher */
816 /*************************************************
817 * TLS version of getc *
818 *************************************************/
820 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
821 it refills the buffer via the SSL reading function.
824 Returns: the next character or EOF
830 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
835 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
836 (long)ssl_xfer_buffer, ssl_xfer_buffer_size);
838 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
839 inbytes = SSL_read(ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size);
840 error = SSL_get_error(ssl, inbytes);
843 /* SSL_ERROR_ZERO_RETURN appears to mean that the SSL session has been
844 closed down, not that the socket itself has been closed down. Revert to
847 if (error == SSL_ERROR_ZERO_RETURN)
849 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
851 receive_getc = smtp_getc;
852 receive_ungetc = smtp_ungetc;
853 receive_feof = smtp_feof;
854 receive_ferror = smtp_ferror;
865 /* Handle genuine errors */
867 else if (error != SSL_ERROR_NONE)
869 DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
874 ssl_xfer_buffer_hwm = inbytes;
875 ssl_xfer_buffer_lwm = 0;
878 /* Something in the buffer; return next uschar */
880 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
885 /*************************************************
886 * Read bytes from TLS channel *
887 *************************************************/
894 Returns: the number of bytes read
895 -1 after a failed read
899 tls_read(uschar *buff, size_t len)
904 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
905 (long)buff, (unsigned int)len);
907 inbytes = SSL_read(ssl, CS buff, len);
908 error = SSL_get_error(ssl, inbytes);
910 if (error == SSL_ERROR_ZERO_RETURN)
912 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
915 else if (error != SSL_ERROR_NONE)
927 /*************************************************
928 * Write bytes down TLS channel *
929 *************************************************/
936 Returns: the number of bytes after a successful write,
937 -1 after a failed write
941 tls_write(const uschar *buff, size_t len)
947 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long)buff, left);
950 DEBUG(D_tls) debug_printf("SSL_write(SSL, %lx, %d)\n", (long)buff, left);
951 outbytes = SSL_write(ssl, CS buff, left);
952 error = SSL_get_error(ssl, outbytes);
953 DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
957 ERR_error_string(ERR_get_error(), ssl_errstring);
958 log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
966 case SSL_ERROR_ZERO_RETURN:
967 log_write(0, LOG_MAIN, "SSL channel closed on write");
971 log_write(0, LOG_MAIN, "SSL_write error %d", error);
980 /*************************************************
981 * Close down a TLS session *
982 *************************************************/
984 /* This is also called from within a delivery subprocess forked from the
985 daemon, to shut down the TLS library, without actually doing a shutdown (which
986 would tamper with the SSL session in the parent process).
988 Arguments: TRUE if SSL_shutdown is to be called
993 tls_close(BOOL shutdown)
995 if (tls_active < 0) return; /* TLS was not active */
999 DEBUG(D_tls) debug_printf("tls_close(): shutting down SSL\n");
1009 /* End of tls-openssl.c */