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