Installed PCRE release 7.0.
[exim.git] / src / src / tls-openssl.c
CommitLineData
83da1223 1/* $Cambridge: exim/src/src/tls-openssl.c,v 1.10 2007/01/18 15:35:42 ph10 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
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
c91535f3
PH
293tls_init(host_item *host, uschar *dhparam, uschar *certificate,
294 uschar *privatekey, address_item *addr)
059ec3d9
PH
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
c91535f3
PH
389 /* If expansion was forced to fail, key_expanded will be NULL. If the result
390 of the expansion is an empty string, ignore it also, and assume the private
391 key is in the same file as the certificate. */
392
393 if (expanded != NULL && *expanded != 0)
059ec3d9
PH
394 {
395 DEBUG(D_tls) debug_printf("tls_privatekey file %s\n", expanded);
396 if (!SSL_CTX_use_PrivateKey_file(ctx, CS expanded, SSL_FILETYPE_PEM))
d6453af2
PH
397 return tls_error(string_sprintf(
398 "SSL_CTX_use_PrivateKey_file file=%s", expanded), host);
059ec3d9
PH
399 }
400 }
401
402/* Set up the RSA callback */
403
404SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
405
406/* Finally, set the timeout, and we are done */
407
408SSL_CTX_set_timeout(ctx, ssl_session_timeout);
409DEBUG(D_tls) debug_printf("Initialized TLS\n");
410return OK;
411}
412
413
414
415
416/*************************************************
417* Get name of cipher in use *
418*************************************************/
419
420/* The answer is left in a static buffer, and tls_cipher is set to point
421to it.
422
423Argument: pointer to an SSL structure for the connection
424Returns: nothing
425*/
426
427static void
428construct_cipher_name(SSL *ssl)
429{
430static uschar cipherbuf[256];
431SSL_CIPHER *c;
432uschar *ver;
433int bits;
434
435switch (ssl->session->ssl_version)
436 {
437 case SSL2_VERSION:
438 ver = US"SSLv2";
439 break;
440
441 case SSL3_VERSION:
442 ver = US"SSLv3";
443 break;
444
445 case TLS1_VERSION:
446 ver = US"TLSv1";
447 break;
448
449 default:
450 ver = US"UNKNOWN";
451 }
452
453c = SSL_get_current_cipher(ssl);
454SSL_CIPHER_get_bits(c, &bits);
455
456string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
457 SSL_CIPHER_get_name(c), bits);
458tls_cipher = cipherbuf;
459
460DEBUG(D_tls) debug_printf("Cipher: %s\n", cipherbuf);
461}
462
463
464
465
466
467/*************************************************
468* Set up for verifying certificates *
469*************************************************/
470
471/* Called by both client and server startup
472
473Arguments:
474 certs certs file or NULL
475 crl CRL file or NULL
476 host NULL in a server; the remote host in a client
477 optional TRUE if called from a server for a host in tls_try_verify_hosts;
478 otherwise passed as FALSE
479
480Returns: OK/DEFER/FAIL
481*/
482
483static int
484setup_certs(uschar *certs, uschar *crl, host_item *host, BOOL optional)
485{
486uschar *expcerts, *expcrl;
487
488if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
489 return DEFER;
490
491if (expcerts != NULL)
492 {
493 struct stat statbuf;
494 if (!SSL_CTX_set_default_verify_paths(ctx))
495 return tls_error(US"SSL_CTX_set_default_verify_paths", host);
496
497 if (Ustat(expcerts, &statbuf) < 0)
498 {
499 log_write(0, LOG_MAIN|LOG_PANIC,
500 "failed to stat %s for certificates", expcerts);
501 return DEFER;
502 }
503 else
504 {
505 uschar *file, *dir;
506 if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
507 { file = NULL; dir = expcerts; }
508 else
509 { file = expcerts; dir = NULL; }
510
511 /* If a certificate file is empty, the next function fails with an
512 unhelpful error message. If we skip it, we get the correct behaviour (no
513 certificates are recognized, but the error message is still misleading (it
514 says no certificate was supplied.) But this is better. */
515
516 if ((file == NULL || statbuf.st_size > 0) &&
517 !SSL_CTX_load_verify_locations(ctx, CS file, CS dir))
518 return tls_error(US"SSL_CTX_load_verify_locations", host);
519
520 if (file != NULL)
521 {
522 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CS file));
523 }
524 }
525
526 /* Handle a certificate revocation list. */
527
528 #if OPENSSL_VERSION_NUMBER > 0x00907000L
529
8b417f2c
PH
530 /* This bit of code is now the version supplied by Lars Mainka. (I have
531 * merely reformatted it into the Exim code style.)
532
533 * "From here I changed the code to add support for multiple crl's
534 * in pem format in one file or to support hashed directory entries in
535 * pem format instead of a file. This method now uses the library function
536 * X509_STORE_load_locations to add the CRL location to the SSL context.
537 * OpenSSL will then handle the verify against CA certs and CRLs by
538 * itself in the verify callback." */
539
059ec3d9
PH
540 if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
541 if (expcrl != NULL && *expcrl != 0)
542 {
8b417f2c
PH
543 struct stat statbufcrl;
544 if (Ustat(expcrl, &statbufcrl) < 0)
545 {
546 log_write(0, LOG_MAIN|LOG_PANIC,
547 "failed to stat %s for certificates revocation lists", expcrl);
548 return DEFER;
549 }
550 else
059ec3d9 551 {
8b417f2c
PH
552 /* is it a file or directory? */
553 uschar *file, *dir;
554 X509_STORE *cvstore = SSL_CTX_get_cert_store(ctx);
555 if ((statbufcrl.st_mode & S_IFMT) == S_IFDIR)
059ec3d9 556 {
8b417f2c
PH
557 file = NULL;
558 dir = expcrl;
559 DEBUG(D_tls) debug_printf("SSL CRL value is a directory %s\n", dir);
059ec3d9
PH
560 }
561 else
562 {
8b417f2c
PH
563 file = expcrl;
564 dir = NULL;
565 DEBUG(D_tls) debug_printf("SSL CRL value is a file %s\n", file);
059ec3d9 566 }
8b417f2c
PH
567 if (X509_STORE_load_locations(cvstore, CS file, CS dir) == 0)
568 return tls_error(US"X509_STORE_load_locations", host);
569
570 /* setting the flags to check against the complete crl chain */
571
572 X509_STORE_set_flags(cvstore,
573 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
059ec3d9 574 }
059ec3d9
PH
575 }
576
577 #endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
578
579 /* If verification is optional, don't fail if no certificate */
580
581 SSL_CTX_set_verify(ctx,
582 SSL_VERIFY_PEER | (optional? 0 : SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
583 verify_callback);
584 }
585
586return OK;
587}
588
589
590
591/*************************************************
592* Start a TLS session in a server *
593*************************************************/
594
595/* This is called when Exim is running as a server, after having received
596the STARTTLS command. It must respond to that command, and then negotiate
597a TLS session.
598
599Arguments:
600 require_ciphers allowed ciphers
83da1223
PH
601 ------------------------------------------------------
602 require_mac list of allowed MACs ) Not used
603 require_kx list of allowed key_exchange methods ) for
604 require_proto list of allowed protocols ) OpenSSL
605 ------------------------------------------------------
059ec3d9
PH
606
607Returns: OK on success
608 DEFER for errors before the start of the negotiation
609 FAIL for errors during the negotation; the server can't
610 continue running.
611*/
612
613int
83da1223
PH
614tls_server_start(uschar *require_ciphers, uschar *require_mac,
615 uschar *require_kx, uschar *require_proto)
059ec3d9
PH
616{
617int rc;
618uschar *expciphers;
619
620/* Check for previous activation */
621
622if (tls_active >= 0)
623 {
624 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
625 "connection from %s",
626 (sender_fullhost != NULL)? sender_fullhost : US"local process");
627 smtp_printf("554 Already in TLS\r\n");
628 return FAIL;
629 }
630
631/* Initialize the SSL library. If it fails, it will already have logged
632the error. */
633
634rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL);
635if (rc != OK) return rc;
636
637if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
638 return FAIL;
639
640/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
641are separated by underscores. So that I can use either form in my tests, and
642also for general convenience, we turn underscores into hyphens here. */
643
644if (expciphers != NULL)
645 {
646 uschar *s = expciphers;
647 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
648 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
649 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
650 return tls_error(US"SSL_CTX_set_cipher_list", NULL);
651 }
652
653/* If this is a host for which certificate verification is mandatory or
654optional, set up appropriately. */
655
656tls_certificate_verified = FALSE;
657verify_callback_called = FALSE;
658
659if (verify_check_host(&tls_verify_hosts) == OK)
660 {
661 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, FALSE);
662 if (rc != OK) return rc;
663 verify_optional = FALSE;
664 }
665else if (verify_check_host(&tls_try_verify_hosts) == OK)
666 {
667 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, TRUE);
668 if (rc != OK) return rc;
669 verify_optional = TRUE;
670 }
671
672/* Prepare for new connection */
673
674if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", NULL);
675SSL_clear(ssl);
676
677/* Set context and tell client to go ahead, except in the case of TLS startup
678on connection, where outputting anything now upsets the clients and tends to
679make them disconnect. We need to have an explicit fflush() here, to force out
680the response. Other smtp_printf() calls do not need it, because in non-TLS
681mode, the fflush() happens when smtp_getc() is called. */
682
683SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
684if (!tls_on_connect)
685 {
686 smtp_printf("220 TLS go ahead\r\n");
687 fflush(smtp_out);
688 }
689
690/* Now negotiate the TLS session. We put our own timer on it, since it seems
691that the OpenSSL library doesn't. */
692
56f5d9bd
PH
693SSL_set_wfd(ssl, fileno(smtp_out));
694SSL_set_rfd(ssl, fileno(smtp_in));
059ec3d9
PH
695SSL_set_accept_state(ssl);
696
697DEBUG(D_tls) debug_printf("Calling SSL_accept\n");
698
699sigalrm_seen = FALSE;
700if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
701rc = SSL_accept(ssl);
702alarm(0);
703
704if (rc <= 0)
705 {
706 if (sigalrm_seen) Ustrcpy(ssl_errstring, "timed out");
707 else ERR_error_string(ERR_get_error(), ssl_errstring);
708 log_write(0, LOG_MAIN, "TLS error on connection from %s (SSL_accept): %s",
709 (sender_fullhost != NULL)? sender_fullhost : US"local process",
710 ssl_errstring);
711 return FAIL;
712 }
713
714DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
715
716/* TLS has been set up. Adjust the input functions to read via TLS,
717and initialize things. */
718
719construct_cipher_name(ssl);
720
721DEBUG(D_tls)
722 {
723 uschar buf[2048];
724 if (SSL_get_shared_ciphers(ssl, CS buf, sizeof(buf)) != NULL)
725 debug_printf("Shared ciphers: %s\n", buf);
726 }
727
728
729ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
730ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
731ssl_xfer_eof = ssl_xfer_error = 0;
732
733receive_getc = tls_getc;
734receive_ungetc = tls_ungetc;
735receive_feof = tls_feof;
736receive_ferror = tls_ferror;
737
738tls_active = fileno(smtp_out);
739return OK;
740}
741
742
743
744
745
746/*************************************************
747* Start a TLS session in a client *
748*************************************************/
749
750/* Called from the smtp transport after STARTTLS has been accepted.
751
752Argument:
753 fd the fd of the connection
754 host connected host (for messages)
83da1223 755 addr the first address
059ec3d9
PH
756 dhparam DH parameter file
757 certificate certificate file
758 privatekey private key file
759 verify_certs file for certificate verify
760 crl file containing CRL
761 require_ciphers list of allowed ciphers
83da1223
PH
762 ------------------------------------------------------
763 require_mac list of allowed MACs ) Not used
764 require_kx list of allowed key_exchange methods ) for
765 require_proto list of allowed protocols ) OpenSSL
766 ------------------------------------------------------
767 timeout startup timeout
059ec3d9
PH
768
769Returns: OK on success
770 FAIL otherwise - note that tls_error() will not give DEFER
771 because this is not a server
772*/
773
774int
775tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
776 uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
83da1223
PH
777 uschar *require_ciphers, uschar *require_mac, uschar *require_kx,
778 uschar *require_proto, int timeout)
059ec3d9
PH
779{
780static uschar txt[256];
781uschar *expciphers;
782X509* server_cert;
783int rc;
784
785rc = tls_init(host, dhparam, certificate, privatekey, addr);
786if (rc != OK) return rc;
787
788tls_certificate_verified = FALSE;
789verify_callback_called = FALSE;
790
791if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
792 return FAIL;
793
794/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
795are separated by underscores. So that I can use either form in my tests, and
796also for general convenience, we turn underscores into hyphens here. */
797
798if (expciphers != NULL)
799 {
800 uschar *s = expciphers;
801 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
802 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
803 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
804 return tls_error(US"SSL_CTX_set_cipher_list", host);
805 }
806
807rc = setup_certs(verify_certs, crl, host, FALSE);
808if (rc != OK) return rc;
809
810if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", host);
811SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
812SSL_set_fd(ssl, fd);
813SSL_set_connect_state(ssl);
814
815/* There doesn't seem to be a built-in timeout on connection. */
816
817DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
818sigalrm_seen = FALSE;
819alarm(timeout);
820rc = SSL_connect(ssl);
821alarm(0);
822
823if (rc <= 0)
824 {
825 if (sigalrm_seen)
826 {
827 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
828 "SSL_connect timed out", host->name, host->address);
829 return FAIL;
830 }
831 else return tls_error(US"SSL_connect", host);
832 }
833
834DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
835
836server_cert = SSL_get_peer_certificate (ssl);
837tls_peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
838 CS txt, sizeof(txt));
839tls_peerdn = txt;
840
841construct_cipher_name(ssl); /* Sets tls_cipher */
842
843tls_active = fd;
844return OK;
845}
846
847
848
849
850
851/*************************************************
852* TLS version of getc *
853*************************************************/
854
855/* This gets the next byte from the TLS input buffer. If the buffer is empty,
856it refills the buffer via the SSL reading function.
857
858Arguments: none
859Returns: the next character or EOF
860*/
861
862int
863tls_getc(void)
864{
865if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
866 {
867 int error;
868 int inbytes;
869
870 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
871 (long)ssl_xfer_buffer, ssl_xfer_buffer_size);
872
873 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
874 inbytes = SSL_read(ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size);
875 error = SSL_get_error(ssl, inbytes);
876 alarm(0);
877
878 /* SSL_ERROR_ZERO_RETURN appears to mean that the SSL session has been
879 closed down, not that the socket itself has been closed down. Revert to
880 non-SSL handling. */
881
882 if (error == SSL_ERROR_ZERO_RETURN)
883 {
884 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
885
886 receive_getc = smtp_getc;
887 receive_ungetc = smtp_ungetc;
888 receive_feof = smtp_feof;
889 receive_ferror = smtp_ferror;
890
891 SSL_free(ssl);
892 ssl = NULL;
893 tls_active = -1;
894 tls_cipher = NULL;
895 tls_peerdn = NULL;
896
897 return smtp_getc();
898 }
899
900 /* Handle genuine errors */
901
902 else if (error != SSL_ERROR_NONE)
903 {
904 DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
905 ssl_xfer_error = 1;
906 return EOF;
907 }
908
909 ssl_xfer_buffer_hwm = inbytes;
910 ssl_xfer_buffer_lwm = 0;
911 }
912
913/* Something in the buffer; return next uschar */
914
915return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
916}
917
918
919
920/*************************************************
921* Read bytes from TLS channel *
922*************************************************/
923
924/*
925Arguments:
926 buff buffer of data
927 len size of buffer
928
929Returns: the number of bytes read
930 -1 after a failed read
931*/
932
933int
934tls_read(uschar *buff, size_t len)
935{
936int inbytes;
937int error;
938
939DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
940 (long)buff, (unsigned int)len);
941
942inbytes = SSL_read(ssl, CS buff, len);
943error = SSL_get_error(ssl, inbytes);
944
945if (error == SSL_ERROR_ZERO_RETURN)
946 {
947 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
948 return -1;
949 }
950else if (error != SSL_ERROR_NONE)
951 {
952 return -1;
953 }
954
955return inbytes;
956}
957
958
959
960
961
962/*************************************************
963* Write bytes down TLS channel *
964*************************************************/
965
966/*
967Arguments:
968 buff buffer of data
969 len number of bytes
970
971Returns: the number of bytes after a successful write,
972 -1 after a failed write
973*/
974
975int
976tls_write(const uschar *buff, size_t len)
977{
978int outbytes;
979int error;
980int left = len;
981
982DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long)buff, left);
983while (left > 0)
984 {
985 DEBUG(D_tls) debug_printf("SSL_write(SSL, %lx, %d)\n", (long)buff, left);
986 outbytes = SSL_write(ssl, CS buff, left);
987 error = SSL_get_error(ssl, outbytes);
988 DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
989 switch (error)
990 {
991 case SSL_ERROR_SSL:
992 ERR_error_string(ERR_get_error(), ssl_errstring);
993 log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
994 return -1;
995
996 case SSL_ERROR_NONE:
997 left -= outbytes;
998 buff += outbytes;
999 break;
1000
1001 case SSL_ERROR_ZERO_RETURN:
1002 log_write(0, LOG_MAIN, "SSL channel closed on write");
1003 return -1;
1004
1005 default:
1006 log_write(0, LOG_MAIN, "SSL_write error %d", error);
1007 return -1;
1008 }
1009 }
1010return len;
1011}
1012
1013
1014
1015/*************************************************
1016* Close down a TLS session *
1017*************************************************/
1018
1019/* This is also called from within a delivery subprocess forked from the
1020daemon, to shut down the TLS library, without actually doing a shutdown (which
1021would tamper with the SSL session in the parent process).
1022
1023Arguments: TRUE if SSL_shutdown is to be called
1024Returns: nothing
1025*/
1026
1027void
1028tls_close(BOOL shutdown)
1029{
1030if (tls_active < 0) return; /* TLS was not active */
1031
1032if (shutdown)
1033 {
1034 DEBUG(D_tls) debug_printf("tls_close(): shutting down SSL\n");
1035 SSL_shutdown(ssl);
1036 }
1037
1038SSL_free(ssl);
1039ssl = NULL;
1040
1041tls_active = -1;
1042}
1043
1044/* End of tls-openssl.c */