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