DKIM Doc update
[exim.git] / src / src / tls-openssl.c
CommitLineData
a0475b69 1/* $Cambridge: exim/src/src/tls-openssl.c,v 1.16 2009/10/16 08:34:50 tom Exp $ */
059ec3d9
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
184e8823 7/* Copyright (c) University of Cambridge 1995 - 2007 */
059ec3d9
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10/* This module provides the TLS (aka SSL) support for Exim using the OpenSSL
11library. It is #included into the tls.c file when that library is used. The
12code herein is based on a patch that was originally contributed by Steve
13Haslam. It was adapted from stunnel, a GPL program by Michal Trojnara.
14
15No cryptographic code is included in Exim. All this module does is to call
16functions from the OpenSSL library. */
17
18
19/* Heading stuff */
20
21#include <openssl/lhash.h>
22#include <openssl/ssl.h>
23#include <openssl/err.h>
24#include <openssl/rand.h>
25
26/* Structure for collecting random data for seeding. */
27
28typedef struct randstuff {
29 time_t t;
30 pid_t p;
31} randstuff;
32
33/* Local static variables */
34
35static BOOL verify_callback_called = FALSE;
36static const uschar *sid_ctx = US"exim";
37
38static SSL_CTX *ctx = NULL;
39static SSL *ssl = NULL;
40
41static char ssl_errstring[256];
42
43static int ssl_session_timeout = 200;
44static BOOL verify_optional = FALSE;
45
46
47
48
49
50/*************************************************
51* Handle TLS error *
52*************************************************/
53
54/* Called from lots of places when errors occur before actually starting to do
55the TLS handshake, that is, while the session is still in clear. Always returns
56DEFER for a server and FAIL for a client so that most calls can use "return
57tls_error(...)" to do this processing and then give an appropriate return. A
58single function is used for both server and client, because it is called from
59some shared functions.
60
61Argument:
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
7199e1ee 65 msg error message or NULL if we should ask OpenSSL
059ec3d9
PH
66
67Returns: OK/DEFER/FAIL
68*/
69
70static int
7199e1ee 71tls_error(uschar *prefix, host_item *host, uschar *msg)
059ec3d9 72{
7199e1ee
TF
73if (msg == NULL)
74 {
75 ERR_error_string(ERR_get_error(), ssl_errstring);
76 msg = ssl_errstring;
77 }
78
059ec3d9
PH
79if (host == NULL)
80 {
7199e1ee
TF
81 uschar *conn_info = smtp_get_connection_info();
82 if (strncmp(conn_info, "SMTP ", 5) == 0)
83 conn_info += 5;
84 log_write(0, LOG_MAIN, "TLS error on %s (%s): %s",
85 conn_info, prefix, msg);
059ec3d9
PH
86 return DEFER;
87 }
88else
89 {
90 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s): %s",
7199e1ee 91 host->name, host->address, prefix, msg);
059ec3d9
PH
92 return FAIL;
93 }
94}
95
96
97
98/*************************************************
99* Callback to generate RSA key *
100*************************************************/
101
102/*
103Arguments:
104 s SSL connection
105 export not used
106 keylength keylength
107
108Returns: pointer to generated key
109*/
110
111static RSA *
112rsa_callback(SSL *s, int export, int keylength)
113{
114RSA *rsa_key;
115export = export; /* Shut picky compilers up */
116DEBUG(D_tls) debug_printf("Generating %d bit RSA key...\n", keylength);
117rsa_key = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
118if (rsa_key == NULL)
119 {
120 ERR_error_string(ERR_get_error(), ssl_errstring);
121 log_write(0, LOG_MAIN|LOG_PANIC, "TLS error (RSA_generate_key): %s",
122 ssl_errstring);
123 return NULL;
124 }
125return rsa_key;
126}
127
128
129
130
131/*************************************************
132* Callback for verification *
133*************************************************/
134
135/* The SSL library does certificate verification if set up to do so. This
136callback has the current yes/no state is in "state". If verification succeeded,
137we set up the tls_peerdn string. If verification failed, what happens depends
138on whether the client is required to present a verifiable certificate or not.
139
140If verification is optional, we change the state to yes, but still log the
141verification error. For some reason (it really would help to have proper
142documentation of OpenSSL), this callback function then gets called again, this
143time with state = 1. In fact, that's useful, because we can set up the peerdn
144value, but we must take care not to set the private verified flag on the second
145time through.
146
147Note: this function is not called if the client fails to present a certificate
148when asked. We get here only if a certificate has been received. Handling of
149optional verification for this case is done when requesting SSL to verify, by
150setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the non-optional case.
151
152Arguments:
153 state current yes/no state as 1/0
154 x509ctx certificate information.
155
156Returns: 1 if verified, 0 if not
157*/
158
159static int
160verify_callback(int state, X509_STORE_CTX *x509ctx)
161{
162static uschar txt[256];
163
164X509_NAME_oneline(X509_get_subject_name(x509ctx->current_cert),
165 CS txt, sizeof(txt));
166
167if (state == 0)
168 {
169 log_write(0, LOG_MAIN, "SSL verify error: depth=%d error=%s cert=%s",
170 x509ctx->error_depth,
171 X509_verify_cert_error_string(x509ctx->error),
172 txt);
173 tls_certificate_verified = FALSE;
174 verify_callback_called = TRUE;
175 if (!verify_optional) return 0; /* reject */
176 DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
177 "tls_try_verify_hosts)\n");
178 return 1; /* accept */
179 }
180
181if (x509ctx->error_depth != 0)
182 {
183 DEBUG(D_tls) debug_printf("SSL verify ok: depth=%d cert=%s\n",
184 x509ctx->error_depth, txt);
185 }
186else
187 {
188 DEBUG(D_tls) debug_printf("SSL%s peer: %s\n",
189 verify_callback_called? "" : " authenticated", txt);
190 tls_peerdn = txt;
191 }
192
059ec3d9
PH
193if (!verify_callback_called) tls_certificate_verified = TRUE;
194verify_callback_called = TRUE;
195
196return 1; /* accept */
197}
198
199
200
201/*************************************************
202* Information callback *
203*************************************************/
204
205/* The SSL library functions call this from time to time to indicate what they
206are doing. We copy the string to the debugging output when the level is high
207enough.
208
209Arguments:
210 s the SSL connection
211 where
212 ret
213
214Returns: nothing
215*/
216
217static void
218info_callback(SSL *s, int where, int ret)
219{
220where = where;
221ret = ret;
222DEBUG(D_tls) debug_printf("SSL info: %s\n", SSL_state_string_long(s));
223}
224
225
226
227/*************************************************
228* Initialize for DH *
229*************************************************/
230
231/* If dhparam is set, expand it, and load up the parameters for DH encryption.
232
233Arguments:
234 dhparam DH parameter file
7199e1ee 235 host connected host, if client; NULL if server
059ec3d9
PH
236
237Returns: TRUE if OK (nothing to set up, or setup worked)
238*/
239
240static BOOL
7199e1ee 241init_dh(uschar *dhparam, host_item *host)
059ec3d9
PH
242{
243BOOL yield = TRUE;
244BIO *bio;
245DH *dh;
246uschar *dhexpanded;
247
248if (!expand_check(dhparam, US"tls_dhparam", &dhexpanded))
249 return FALSE;
250
251if (dhexpanded == NULL) return TRUE;
252
253if ((bio = BIO_new_file(CS dhexpanded, "r")) == NULL)
254 {
7199e1ee
TF
255 tls_error(string_sprintf("could not read dhparams file %s", dhexpanded),
256 host, strerror(errno));
059ec3d9
PH
257 yield = FALSE;
258 }
259else
260 {
261 if ((dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL)
262 {
7199e1ee
TF
263 tls_error(string_sprintf("could not read dhparams file %s", dhexpanded),
264 host, NULL);
059ec3d9
PH
265 yield = FALSE;
266 }
267 else
268 {
269 SSL_CTX_set_tmp_dh(ctx, dh);
270 DEBUG(D_tls)
271 debug_printf("Diffie-Hellman initialized from %s with %d-bit key\n",
272 dhexpanded, 8*DH_size(dh));
273 DH_free(dh);
274 }
275 BIO_free(bio);
276 }
277
278return yield;
279}
280
281
282
283
284/*************************************************
285* Initialize for TLS *
286*************************************************/
287
288/* Called from both server and client code, to do preliminary initialization of
289the library.
290
291Arguments:
292 host connected host, if client; NULL if server
293 dhparam DH parameter file
294 certificate certificate file
295 privatekey private key
296 addr address if client; NULL if server (for some randomness)
297
298Returns: OK/DEFER/FAIL
299*/
300
301static int
c91535f3
PH
302tls_init(host_item *host, uschar *dhparam, uschar *certificate,
303 uschar *privatekey, address_item *addr)
059ec3d9
PH
304{
305SSL_load_error_strings(); /* basic set up */
306OpenSSL_add_ssl_algorithms();
307
a0475b69
TK
308/* SHA256 is becoming ever moar popular. This makes sure it gets added to the
309list of available digests. */
310EVP_add_digest(EVP_sha256());
311
059ec3d9
PH
312/* Create a context */
313
314ctx = SSL_CTX_new((host == NULL)?
315 SSLv23_server_method() : SSLv23_client_method());
316
7199e1ee 317if (ctx == NULL) return tls_error(US"SSL_CTX_new", host, NULL);
059ec3d9
PH
318
319/* It turns out that we need to seed the random number generator this early in
320order to get the full complement of ciphers to work. It took me roughly a day
321of work to discover this by experiment.
322
323On systems that have /dev/urandom, SSL may automatically seed itself from
324there. Otherwise, we have to make something up as best we can. Double check
325afterwards. */
326
327if (!RAND_status())
328 {
329 randstuff r;
330 r.t = time(NULL);
331 r.p = getpid();
332
333 RAND_seed((uschar *)(&r), sizeof(r));
334 RAND_seed((uschar *)big_buffer, big_buffer_size);
335 if (addr != NULL) RAND_seed((uschar *)addr, sizeof(addr));
336
337 if (!RAND_status())
7199e1ee
TF
338 return tls_error(US"RAND_status", host,
339 "unable to seed random number generator");
059ec3d9
PH
340 }
341
342/* Set up the information callback, which outputs if debugging is at a suitable
343level. */
344
58c01c94 345SSL_CTX_set_info_callback(ctx, (void (*)())info_callback);
059ec3d9
PH
346
347/* The following patch was supplied by Robert Roselius */
348
349#if OPENSSL_VERSION_NUMBER > 0x00906040L
350/* Enable client-bug workaround.
351 Versions of OpenSSL as of 0.9.6d include a "CBC countermeasure" feature,
352 which causes problems with some clients (such as the Certicom SSL Plus
353 library used by Eudora). This option, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS,
354 disables the coutermeasure allowing Eudora to connect.
355 Some poppers and MTAs use SSL_OP_ALL, which enables all such bug
356 workarounds. */
357/* XXX (Silently?) ignore failure here? XXX*/
358
359if (!(SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)))
7199e1ee 360 return tls_error(US"SSL_CTX_set_option", host, NULL);
059ec3d9
PH
361#endif
362
363/* Initialize with DH parameters if supplied */
364
7199e1ee 365if (!init_dh(dhparam, host)) return DEFER;
059ec3d9
PH
366
367/* Set up certificate and key */
368
369if (certificate != NULL)
370 {
371 uschar *expanded;
372 if (!expand_check(certificate, US"tls_certificate", &expanded))
373 return DEFER;
374
375 if (expanded != NULL)
376 {
377 DEBUG(D_tls) debug_printf("tls_certificate file %s\n", expanded);
378 if (!SSL_CTX_use_certificate_chain_file(ctx, CS expanded))
d6453af2 379 return tls_error(string_sprintf(
7199e1ee 380 "SSL_CTX_use_certificate_chain_file file=%s", expanded), host, NULL);
059ec3d9
PH
381 }
382
383 if (privatekey != NULL &&
384 !expand_check(privatekey, US"tls_privatekey", &expanded))
385 return DEFER;
386
c91535f3
PH
387 /* If expansion was forced to fail, key_expanded will be NULL. If the result
388 of the expansion is an empty string, ignore it also, and assume the private
389 key is in the same file as the certificate. */
390
391 if (expanded != NULL && *expanded != 0)
059ec3d9
PH
392 {
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))
d6453af2 395 return tls_error(string_sprintf(
7199e1ee 396 "SSL_CTX_use_PrivateKey_file file=%s", expanded), host, NULL);
059ec3d9
PH
397 }
398 }
399
400/* Set up the RSA callback */
401
402SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
403
404/* Finally, set the timeout, and we are done */
405
406SSL_CTX_set_timeout(ctx, ssl_session_timeout);
407DEBUG(D_tls) debug_printf("Initialized TLS\n");
408return OK;
409}
410
411
412
413
414/*************************************************
415* Get name of cipher in use *
416*************************************************/
417
418/* The answer is left in a static buffer, and tls_cipher is set to point
419to it.
420
421Argument: pointer to an SSL structure for the connection
422Returns: nothing
423*/
424
425static void
426construct_cipher_name(SSL *ssl)
427{
428static uschar cipherbuf[256];
429SSL_CIPHER *c;
430uschar *ver;
431int bits;
432
433switch (ssl->session->ssl_version)
434 {
435 case SSL2_VERSION:
436 ver = US"SSLv2";
437 break;
438
439 case SSL3_VERSION:
440 ver = US"SSLv3";
441 break;
442
443 case TLS1_VERSION:
444 ver = US"TLSv1";
445 break;
446
447 default:
448 ver = US"UNKNOWN";
449 }
450
451c = SSL_get_current_cipher(ssl);
452SSL_CIPHER_get_bits(c, &bits);
453
454string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
455 SSL_CIPHER_get_name(c), bits);
456tls_cipher = cipherbuf;
457
458DEBUG(D_tls) debug_printf("Cipher: %s\n", cipherbuf);
459}
460
461
462
463
464
465/*************************************************
466* Set up for verifying certificates *
467*************************************************/
468
469/* Called by both client and server startup
470
471Arguments:
472 certs certs file or NULL
473 crl CRL file or NULL
474 host NULL in a server; the remote host in a client
475 optional TRUE if called from a server for a host in tls_try_verify_hosts;
476 otherwise passed as FALSE
477
478Returns: OK/DEFER/FAIL
479*/
480
481static int
482setup_certs(uschar *certs, uschar *crl, host_item *host, BOOL optional)
483{
484uschar *expcerts, *expcrl;
485
486if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
487 return DEFER;
488
489if (expcerts != NULL)
490 {
491 struct stat statbuf;
492 if (!SSL_CTX_set_default_verify_paths(ctx))
7199e1ee 493 return tls_error(US"SSL_CTX_set_default_verify_paths", host, NULL);
059ec3d9
PH
494
495 if (Ustat(expcerts, &statbuf) < 0)
496 {
497 log_write(0, LOG_MAIN|LOG_PANIC,
498 "failed to stat %s for certificates", expcerts);
499 return DEFER;
500 }
501 else
502 {
503 uschar *file, *dir;
504 if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
505 { file = NULL; dir = expcerts; }
506 else
507 { file = expcerts; dir = NULL; }
508
509 /* If a certificate file is empty, the next function fails with an
510 unhelpful error message. If we skip it, we get the correct behaviour (no
511 certificates are recognized, but the error message is still misleading (it
512 says no certificate was supplied.) But this is better. */
513
514 if ((file == NULL || statbuf.st_size > 0) &&
515 !SSL_CTX_load_verify_locations(ctx, CS file, CS dir))
7199e1ee 516 return tls_error(US"SSL_CTX_load_verify_locations", host, NULL);
059ec3d9
PH
517
518 if (file != NULL)
519 {
520 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CS file));
521 }
522 }
523
524 /* Handle a certificate revocation list. */
525
526 #if OPENSSL_VERSION_NUMBER > 0x00907000L
527
8b417f2c
PH
528 /* This bit of code is now the version supplied by Lars Mainka. (I have
529 * merely reformatted it into the Exim code style.)
530
531 * "From here I changed the code to add support for multiple crl's
532 * in pem format in one file or to support hashed directory entries in
533 * pem format instead of a file. This method now uses the library function
534 * X509_STORE_load_locations to add the CRL location to the SSL context.
535 * OpenSSL will then handle the verify against CA certs and CRLs by
536 * itself in the verify callback." */
537
059ec3d9
PH
538 if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
539 if (expcrl != NULL && *expcrl != 0)
540 {
8b417f2c
PH
541 struct stat statbufcrl;
542 if (Ustat(expcrl, &statbufcrl) < 0)
543 {
544 log_write(0, LOG_MAIN|LOG_PANIC,
545 "failed to stat %s for certificates revocation lists", expcrl);
546 return DEFER;
547 }
548 else
059ec3d9 549 {
8b417f2c
PH
550 /* is it a file or directory? */
551 uschar *file, *dir;
552 X509_STORE *cvstore = SSL_CTX_get_cert_store(ctx);
553 if ((statbufcrl.st_mode & S_IFMT) == S_IFDIR)
059ec3d9 554 {
8b417f2c
PH
555 file = NULL;
556 dir = expcrl;
557 DEBUG(D_tls) debug_printf("SSL CRL value is a directory %s\n", dir);
059ec3d9
PH
558 }
559 else
560 {
8b417f2c
PH
561 file = expcrl;
562 dir = NULL;
563 DEBUG(D_tls) debug_printf("SSL CRL value is a file %s\n", file);
059ec3d9 564 }
8b417f2c 565 if (X509_STORE_load_locations(cvstore, CS file, CS dir) == 0)
7199e1ee 566 return tls_error(US"X509_STORE_load_locations", host, NULL);
8b417f2c
PH
567
568 /* setting the flags to check against the complete crl chain */
569
570 X509_STORE_set_flags(cvstore,
571 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
059ec3d9 572 }
059ec3d9
PH
573 }
574
575 #endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
576
577 /* If verification is optional, don't fail if no certificate */
578
579 SSL_CTX_set_verify(ctx,
580 SSL_VERIFY_PEER | (optional? 0 : SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
581 verify_callback);
582 }
583
584return OK;
585}
586
587
588
589/*************************************************
590* Start a TLS session in a server *
591*************************************************/
592
593/* This is called when Exim is running as a server, after having received
594the STARTTLS command. It must respond to that command, and then negotiate
595a TLS session.
596
597Arguments:
598 require_ciphers allowed ciphers
83da1223
PH
599 ------------------------------------------------------
600 require_mac list of allowed MACs ) Not used
601 require_kx list of allowed key_exchange methods ) for
602 require_proto list of allowed protocols ) OpenSSL
603 ------------------------------------------------------
059ec3d9
PH
604
605Returns: OK on success
606 DEFER for errors before the start of the negotiation
607 FAIL for errors during the negotation; the server can't
608 continue running.
609*/
610
611int
83da1223
PH
612tls_server_start(uschar *require_ciphers, uschar *require_mac,
613 uschar *require_kx, uschar *require_proto)
059ec3d9
PH
614{
615int rc;
616uschar *expciphers;
617
618/* Check for previous activation */
619
620if (tls_active >= 0)
621 {
7199e1ee 622 tls_error("STARTTLS received after TLS started", NULL, "");
059ec3d9
PH
623 smtp_printf("554 Already in TLS\r\n");
624 return FAIL;
625 }
626
627/* Initialize the SSL library. If it fails, it will already have logged
628the error. */
629
630rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL);
631if (rc != OK) return rc;
632
633if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
634 return FAIL;
635
636/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
637are separated by underscores. So that I can use either form in my tests, and
638also for general convenience, we turn underscores into hyphens here. */
639
640if (expciphers != NULL)
641 {
642 uschar *s = expciphers;
643 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
644 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
645 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
7199e1ee 646 return tls_error(US"SSL_CTX_set_cipher_list", NULL, NULL);
059ec3d9
PH
647 }
648
649/* If this is a host for which certificate verification is mandatory or
650optional, set up appropriately. */
651
652tls_certificate_verified = FALSE;
653verify_callback_called = FALSE;
654
655if (verify_check_host(&tls_verify_hosts) == OK)
656 {
657 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, FALSE);
658 if (rc != OK) return rc;
659 verify_optional = FALSE;
660 }
661else if (verify_check_host(&tls_try_verify_hosts) == OK)
662 {
663 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, TRUE);
664 if (rc != OK) return rc;
665 verify_optional = TRUE;
666 }
667
668/* Prepare for new connection */
669
7199e1ee 670if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", NULL, NULL);
059ec3d9
PH
671SSL_clear(ssl);
672
673/* Set context and tell client to go ahead, except in the case of TLS startup
674on connection, where outputting anything now upsets the clients and tends to
675make them disconnect. We need to have an explicit fflush() here, to force out
676the response. Other smtp_printf() calls do not need it, because in non-TLS
677mode, the fflush() happens when smtp_getc() is called. */
678
679SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
680if (!tls_on_connect)
681 {
682 smtp_printf("220 TLS go ahead\r\n");
683 fflush(smtp_out);
684 }
685
686/* Now negotiate the TLS session. We put our own timer on it, since it seems
687that the OpenSSL library doesn't. */
688
56f5d9bd
PH
689SSL_set_wfd(ssl, fileno(smtp_out));
690SSL_set_rfd(ssl, fileno(smtp_in));
059ec3d9
PH
691SSL_set_accept_state(ssl);
692
693DEBUG(D_tls) debug_printf("Calling SSL_accept\n");
694
695sigalrm_seen = FALSE;
696if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
697rc = SSL_accept(ssl);
698alarm(0);
699
700if (rc <= 0)
701 {
7199e1ee 702 tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : NULL);
059ec3d9
PH
703 return FAIL;
704 }
705
706DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
707
708/* TLS has been set up. Adjust the input functions to read via TLS,
709and initialize things. */
710
711construct_cipher_name(ssl);
712
713DEBUG(D_tls)
714 {
715 uschar buf[2048];
716 if (SSL_get_shared_ciphers(ssl, CS buf, sizeof(buf)) != NULL)
717 debug_printf("Shared ciphers: %s\n", buf);
718 }
719
720
721ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
722ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
723ssl_xfer_eof = ssl_xfer_error = 0;
724
725receive_getc = tls_getc;
726receive_ungetc = tls_ungetc;
727receive_feof = tls_feof;
728receive_ferror = tls_ferror;
58eb016e 729receive_smtp_buffered = tls_smtp_buffered;
059ec3d9
PH
730
731tls_active = fileno(smtp_out);
732return OK;
733}
734
735
736
737
738
739/*************************************************
740* Start a TLS session in a client *
741*************************************************/
742
743/* Called from the smtp transport after STARTTLS has been accepted.
744
745Argument:
746 fd the fd of the connection
747 host connected host (for messages)
83da1223 748 addr the first address
059ec3d9
PH
749 dhparam DH parameter file
750 certificate certificate file
751 privatekey private key file
752 verify_certs file for certificate verify
753 crl file containing CRL
754 require_ciphers list of allowed ciphers
83da1223
PH
755 ------------------------------------------------------
756 require_mac list of allowed MACs ) Not used
757 require_kx list of allowed key_exchange methods ) for
758 require_proto list of allowed protocols ) OpenSSL
759 ------------------------------------------------------
760 timeout startup timeout
059ec3d9
PH
761
762Returns: OK on success
763 FAIL otherwise - note that tls_error() will not give DEFER
764 because this is not a server
765*/
766
767int
768tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
769 uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
83da1223
PH
770 uschar *require_ciphers, uschar *require_mac, uschar *require_kx,
771 uschar *require_proto, int timeout)
059ec3d9
PH
772{
773static uschar txt[256];
774uschar *expciphers;
775X509* server_cert;
776int rc;
777
778rc = tls_init(host, dhparam, certificate, privatekey, addr);
779if (rc != OK) return rc;
780
781tls_certificate_verified = FALSE;
782verify_callback_called = FALSE;
783
784if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
785 return FAIL;
786
787/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
788are separated by underscores. So that I can use either form in my tests, and
789also for general convenience, we turn underscores into hyphens here. */
790
791if (expciphers != NULL)
792 {
793 uschar *s = expciphers;
794 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
795 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
796 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
7199e1ee 797 return tls_error(US"SSL_CTX_set_cipher_list", host, NULL);
059ec3d9
PH
798 }
799
800rc = setup_certs(verify_certs, crl, host, FALSE);
801if (rc != OK) return rc;
802
7199e1ee 803if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", host, NULL);
059ec3d9
PH
804SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
805SSL_set_fd(ssl, fd);
806SSL_set_connect_state(ssl);
807
808/* There doesn't seem to be a built-in timeout on connection. */
809
810DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
811sigalrm_seen = FALSE;
812alarm(timeout);
813rc = SSL_connect(ssl);
814alarm(0);
815
816if (rc <= 0)
7199e1ee 817 return tls_error(US"SSL_connect", host, sigalrm_seen ? US"timed out" : NULL);
059ec3d9
PH
818
819DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
820
821server_cert = SSL_get_peer_certificate (ssl);
822tls_peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
823 CS txt, sizeof(txt));
824tls_peerdn = txt;
825
826construct_cipher_name(ssl); /* Sets tls_cipher */
827
828tls_active = fd;
829return OK;
830}
831
832
833
834
835
836/*************************************************
837* TLS version of getc *
838*************************************************/
839
840/* This gets the next byte from the TLS input buffer. If the buffer is empty,
841it refills the buffer via the SSL reading function.
842
843Arguments: none
844Returns: the next character or EOF
845*/
846
847int
848tls_getc(void)
849{
850if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
851 {
852 int error;
853 int inbytes;
854
855 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
856 (long)ssl_xfer_buffer, ssl_xfer_buffer_size);
857
858 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
859 inbytes = SSL_read(ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size);
860 error = SSL_get_error(ssl, inbytes);
861 alarm(0);
862
863 /* SSL_ERROR_ZERO_RETURN appears to mean that the SSL session has been
864 closed down, not that the socket itself has been closed down. Revert to
865 non-SSL handling. */
866
867 if (error == SSL_ERROR_ZERO_RETURN)
868 {
869 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
870
871 receive_getc = smtp_getc;
872 receive_ungetc = smtp_ungetc;
873 receive_feof = smtp_feof;
874 receive_ferror = smtp_ferror;
58eb016e 875 receive_smtp_buffered = smtp_buffered;
059ec3d9
PH
876
877 SSL_free(ssl);
878 ssl = NULL;
879 tls_active = -1;
880 tls_cipher = NULL;
881 tls_peerdn = NULL;
882
883 return smtp_getc();
884 }
885
886 /* Handle genuine errors */
887
888 else if (error != SSL_ERROR_NONE)
889 {
890 DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
891 ssl_xfer_error = 1;
892 return EOF;
893 }
80a47a2c
TK
894#ifndef DISABLE_DKIM
895 dkim_exim_verify_feed(ssl_xfer_buffer, inbytes);
896#endif
059ec3d9
PH
897 ssl_xfer_buffer_hwm = inbytes;
898 ssl_xfer_buffer_lwm = 0;
899 }
900
901/* Something in the buffer; return next uschar */
902
903return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
904}
905
906
907
908/*************************************************
909* Read bytes from TLS channel *
910*************************************************/
911
912/*
913Arguments:
914 buff buffer of data
915 len size of buffer
916
917Returns: the number of bytes read
918 -1 after a failed read
919*/
920
921int
922tls_read(uschar *buff, size_t len)
923{
924int inbytes;
925int error;
926
927DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
928 (long)buff, (unsigned int)len);
929
930inbytes = SSL_read(ssl, CS buff, len);
931error = SSL_get_error(ssl, inbytes);
932
933if (error == SSL_ERROR_ZERO_RETURN)
934 {
935 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
936 return -1;
937 }
938else if (error != SSL_ERROR_NONE)
939 {
940 return -1;
941 }
942
943return inbytes;
944}
945
946
947
948
949
950/*************************************************
951* Write bytes down TLS channel *
952*************************************************/
953
954/*
955Arguments:
956 buff buffer of data
957 len number of bytes
958
959Returns: the number of bytes after a successful write,
960 -1 after a failed write
961*/
962
963int
964tls_write(const uschar *buff, size_t len)
965{
966int outbytes;
967int error;
968int left = len;
969
970DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long)buff, left);
971while (left > 0)
972 {
973 DEBUG(D_tls) debug_printf("SSL_write(SSL, %lx, %d)\n", (long)buff, left);
974 outbytes = SSL_write(ssl, CS buff, left);
975 error = SSL_get_error(ssl, outbytes);
976 DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
977 switch (error)
978 {
979 case SSL_ERROR_SSL:
980 ERR_error_string(ERR_get_error(), ssl_errstring);
981 log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
982 return -1;
983
984 case SSL_ERROR_NONE:
985 left -= outbytes;
986 buff += outbytes;
987 break;
988
989 case SSL_ERROR_ZERO_RETURN:
990 log_write(0, LOG_MAIN, "SSL channel closed on write");
991 return -1;
992
993 default:
994 log_write(0, LOG_MAIN, "SSL_write error %d", error);
995 return -1;
996 }
997 }
998return len;
999}
1000
1001
1002
1003/*************************************************
1004* Close down a TLS session *
1005*************************************************/
1006
1007/* This is also called from within a delivery subprocess forked from the
1008daemon, to shut down the TLS library, without actually doing a shutdown (which
1009would tamper with the SSL session in the parent process).
1010
1011Arguments: TRUE if SSL_shutdown is to be called
1012Returns: nothing
1013*/
1014
1015void
1016tls_close(BOOL shutdown)
1017{
1018if (tls_active < 0) return; /* TLS was not active */
1019
1020if (shutdown)
1021 {
1022 DEBUG(D_tls) debug_printf("tls_close(): shutting down SSL\n");
1023 SSL_shutdown(ssl);
1024 }
1025
1026SSL_free(ssl);
1027ssl = NULL;
1028
1029tls_active = -1;
1030}
1031
36f12725
NM
1032
1033
1034
1035/*************************************************
1036* Report the library versions. *
1037*************************************************/
1038
1039/* There have historically been some issues with binary compatibility in
1040OpenSSL libraries; if Exim (like many other applications) is built against
1041one version of OpenSSL but the run-time linker picks up another version,
1042it can result in serious failures, including crashing with a SIGSEGV. So
1043report the version found by the compiler and the run-time version.
1044
1045Arguments: a FILE* to print the results to
1046Returns: nothing
1047*/
1048
1049void
1050tls_version_report(FILE *f)
1051{
1052fprintf(f, "OpenSSL compile-time version: %s\n", OPENSSL_VERSION_TEXT);
1053fprintf(f, "OpenSSL runtime version: %s\n", SSLeay_version(SSLEAY_VERSION));
1054}
1055
059ec3d9 1056/* End of tls-openssl.c */