OpenSSL: Make sure sha256 digest is available
[exim.git] / src / src / tls-openssl.c
1 /* $Cambridge: exim/src/src/tls-openssl.c,v 1.16 2009/10/16 08:34:50 tom Exp $ */
2
3 /*************************************************
4 *     Exim - an Internet mail transport agent    *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2007 */
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
11 library. It is #included into the tls.c file when that library is used. The
12 code herein is based on a patch that was originally contributed by Steve
13 Haslam. It was adapted from stunnel, a GPL program by Michal Trojnara.
14
15 No cryptographic code is included in Exim. All this module does is to call
16 functions 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
28 typedef struct randstuff {
29   time_t t;
30   pid_t  p;
31 } randstuff;
32
33 /* Local static variables */
34
35 static BOOL verify_callback_called = FALSE;
36 static const uschar *sid_ctx = US"exim";
37
38 static SSL_CTX *ctx = NULL;
39 static SSL *ssl = NULL;
40
41 static char ssl_errstring[256];
42
43 static int  ssl_session_timeout = 200;
44 static 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
55 the TLS handshake, that is, while the session is still in clear. Always returns
56 DEFER for a server and FAIL for a client so that most calls can use "return
57 tls_error(...)" to do this processing and then give an appropriate return. A
58 single function is used for both server and client, because it is called from
59 some shared functions.
60
61 Argument:
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   msg       error message or NULL if we should ask OpenSSL
66
67 Returns:    OK/DEFER/FAIL
68 */
69
70 static int
71 tls_error(uschar *prefix, host_item *host, uschar *msg)
72 {
73 if (msg == NULL)
74   {
75   ERR_error_string(ERR_get_error(), ssl_errstring);
76   msg = ssl_errstring;
77   }
78
79 if (host == NULL)
80   {
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);
86   return DEFER;
87   }
88 else
89   {
90   log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s): %s",
91     host->name, host->address, prefix, msg);
92   return FAIL;
93   }
94 }
95
96
97
98 /*************************************************
99 *        Callback to generate RSA key            *
100 *************************************************/
101
102 /*
103 Arguments:
104   s          SSL connection
105   export     not used
106   keylength  keylength
107
108 Returns:     pointer to generated key
109 */
110
111 static RSA *
112 rsa_callback(SSL *s, int export, int keylength)
113 {
114 RSA *rsa_key;
115 export = export;     /* Shut picky compilers up */
116 DEBUG(D_tls) debug_printf("Generating %d bit RSA key...\n", keylength);
117 rsa_key = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
118 if (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   }
125 return 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
136 callback has the current yes/no state is in "state". If verification succeeded,
137 we set up the tls_peerdn string. If verification failed, what happens depends
138 on whether the client is required to present a verifiable certificate or not.
139
140 If verification is optional, we change the state to yes, but still log the
141 verification error. For some reason (it really would help to have proper
142 documentation of OpenSSL), this callback function then gets called again, this
143 time with state = 1. In fact, that's useful, because we can set up the peerdn
144 value, but we must take care not to set the private verified flag on the second
145 time through.
146
147 Note: this function is not called if the client fails to present a certificate
148 when asked. We get here only if a certificate has been received. Handling of
149 optional verification for this case is done when requesting SSL to verify, by
150 setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the non-optional case.
151
152 Arguments:
153   state      current yes/no state as 1/0
154   x509ctx    certificate information.
155
156 Returns:     1 if verified, 0 if not
157 */
158
159 static int
160 verify_callback(int state, X509_STORE_CTX *x509ctx)
161 {
162 static uschar txt[256];
163
164 X509_NAME_oneline(X509_get_subject_name(x509ctx->current_cert),
165   CS txt, sizeof(txt));
166
167 if (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
181 if (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   }
186 else
187   {
188   DEBUG(D_tls) debug_printf("SSL%s peer: %s\n",
189     verify_callback_called? "" : " authenticated", txt);
190   tls_peerdn = txt;
191   }
192
193 if (!verify_callback_called) tls_certificate_verified = TRUE;
194 verify_callback_called = TRUE;
195
196 return 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
206 are doing. We copy the string to the debugging output when the level is high
207 enough.
208
209 Arguments:
210   s         the SSL connection
211   where
212   ret
213
214 Returns:    nothing
215 */
216
217 static void
218 info_callback(SSL *s, int where, int ret)
219 {
220 where = where;
221 ret = ret;
222 DEBUG(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
233 Arguments:
234   dhparam   DH parameter file
235   host      connected host, if client; NULL if server
236
237 Returns:    TRUE if OK (nothing to set up, or setup worked)
238 */
239
240 static BOOL
241 init_dh(uschar *dhparam, host_item *host)
242 {
243 BOOL yield = TRUE;
244 BIO *bio;
245 DH *dh;
246 uschar *dhexpanded;
247
248 if (!expand_check(dhparam, US"tls_dhparam", &dhexpanded))
249   return FALSE;
250
251 if (dhexpanded == NULL) return TRUE;
252
253 if ((bio = BIO_new_file(CS dhexpanded, "r")) == NULL)
254   {
255   tls_error(string_sprintf("could not read dhparams file %s", dhexpanded),
256     host, strerror(errno));
257   yield = FALSE;
258   }
259 else
260   {
261   if ((dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL)
262     {
263     tls_error(string_sprintf("could not read dhparams file %s", dhexpanded),
264       host, NULL);
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
278 return 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
289 the library.
290
291 Arguments:
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
298 Returns:          OK/DEFER/FAIL
299 */
300
301 static int
302 tls_init(host_item *host, uschar *dhparam, uschar *certificate,
303   uschar *privatekey, address_item *addr)
304 {
305 SSL_load_error_strings();          /* basic set up */
306 OpenSSL_add_ssl_algorithms();
307
308 /* SHA256 is becoming ever moar popular. This makes sure it gets added to the
309 list of available digests. */
310 EVP_add_digest(EVP_sha256());
311
312 /* Create a context */
313
314 ctx = SSL_CTX_new((host == NULL)?
315   SSLv23_server_method() : SSLv23_client_method());
316
317 if (ctx == NULL) return tls_error(US"SSL_CTX_new", host, NULL);
318
319 /* It turns out that we need to seed the random number generator this early in
320 order to get the full complement of ciphers to work. It took me roughly a day
321 of work to discover this by experiment.
322
323 On systems that have /dev/urandom, SSL may automatically seed itself from
324 there. Otherwise, we have to make something up as best we can. Double check
325 afterwards. */
326
327 if (!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())
338     return tls_error(US"RAND_status", host,
339       "unable to seed random number generator");
340   }
341
342 /* Set up the information callback, which outputs if debugging is at a suitable
343 level. */
344
345 SSL_CTX_set_info_callback(ctx, (void (*)())info_callback);
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
359 if (!(SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)))
360   return tls_error(US"SSL_CTX_set_option", host, NULL);
361 #endif
362
363 /* Initialize with DH parameters if supplied */
364
365 if (!init_dh(dhparam, host)) return DEFER;
366
367 /* Set up certificate and key */
368
369 if (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))
379       return tls_error(string_sprintf(
380         "SSL_CTX_use_certificate_chain_file file=%s", expanded), host, NULL);
381     }
382
383   if (privatekey != NULL &&
384       !expand_check(privatekey, US"tls_privatekey", &expanded))
385     return DEFER;
386
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)
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))
395       return tls_error(string_sprintf(
396         "SSL_CTX_use_PrivateKey_file file=%s", expanded), host, NULL);
397     }
398   }
399
400 /* Set up the RSA callback */
401
402 SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
403
404 /* Finally, set the timeout, and we are done */
405
406 SSL_CTX_set_timeout(ctx, ssl_session_timeout);
407 DEBUG(D_tls) debug_printf("Initialized TLS\n");
408 return 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
419 to it.
420
421 Argument:   pointer to an SSL structure for the connection
422 Returns:    nothing
423 */
424
425 static void
426 construct_cipher_name(SSL *ssl)
427 {
428 static uschar cipherbuf[256];
429 SSL_CIPHER *c;
430 uschar *ver;
431 int bits;
432
433 switch (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
451 c = SSL_get_current_cipher(ssl);
452 SSL_CIPHER_get_bits(c, &bits);
453
454 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
455   SSL_CIPHER_get_name(c), bits);
456 tls_cipher = cipherbuf;
457
458 DEBUG(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
471 Arguments:
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
478 Returns:        OK/DEFER/FAIL
479 */
480
481 static int
482 setup_certs(uschar *certs, uschar *crl, host_item *host, BOOL optional)
483 {
484 uschar *expcerts, *expcrl;
485
486 if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
487   return DEFER;
488
489 if (expcerts != NULL)
490   {
491   struct stat statbuf;
492   if (!SSL_CTX_set_default_verify_paths(ctx))
493     return tls_error(US"SSL_CTX_set_default_verify_paths", host, NULL);
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))
516       return tls_error(US"SSL_CTX_load_verify_locations", host, NULL);
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
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
538   if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
539   if (expcrl != NULL && *expcrl != 0)
540     {
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
549       {
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)
554         {
555         file = NULL;
556         dir = expcrl;
557         DEBUG(D_tls) debug_printf("SSL CRL value is a directory %s\n", dir);
558         }
559       else
560         {
561         file = expcrl;
562         dir = NULL;
563         DEBUG(D_tls) debug_printf("SSL CRL value is a file %s\n", file);
564         }
565       if (X509_STORE_load_locations(cvstore, CS file, CS dir) == 0)
566         return tls_error(US"X509_STORE_load_locations", host, NULL);
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);
572       }
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
584 return 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
594 the STARTTLS command. It must respond to that command, and then negotiate
595 a TLS session.
596
597 Arguments:
598   require_ciphers   allowed ciphers
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   ------------------------------------------------------
604
605 Returns:            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
611 int
612 tls_server_start(uschar *require_ciphers, uschar *require_mac,
613   uschar *require_kx, uschar *require_proto)
614 {
615 int rc;
616 uschar *expciphers;
617
618 /* Check for previous activation */
619
620 if (tls_active >= 0)
621   {
622   tls_error("STARTTLS received after TLS started", NULL, "");
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
628 the error. */
629
630 rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL);
631 if (rc != OK) return rc;
632
633 if (!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
637 are separated by underscores. So that I can use either form in my tests, and
638 also for general convenience, we turn underscores into hyphens here. */
639
640 if (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))
646     return tls_error(US"SSL_CTX_set_cipher_list", NULL, NULL);
647   }
648
649 /* If this is a host for which certificate verification is mandatory or
650 optional, set up appropriately. */
651
652 tls_certificate_verified = FALSE;
653 verify_callback_called = FALSE;
654
655 if (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   }
661 else 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
670 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", NULL, NULL);
671 SSL_clear(ssl);
672
673 /* Set context and tell client to go ahead, except in the case of TLS startup
674 on connection, where outputting anything now upsets the clients and tends to
675 make them disconnect. We need to have an explicit fflush() here, to force out
676 the response. Other smtp_printf() calls do not need it, because in non-TLS
677 mode, the fflush() happens when smtp_getc() is called. */
678
679 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
680 if (!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
687 that the OpenSSL library doesn't. */
688
689 SSL_set_wfd(ssl, fileno(smtp_out));
690 SSL_set_rfd(ssl, fileno(smtp_in));
691 SSL_set_accept_state(ssl);
692
693 DEBUG(D_tls) debug_printf("Calling SSL_accept\n");
694
695 sigalrm_seen = FALSE;
696 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
697 rc = SSL_accept(ssl);
698 alarm(0);
699
700 if (rc <= 0)
701   {
702   tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : NULL);
703   return FAIL;
704   }
705
706 DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
707
708 /* TLS has been set up. Adjust the input functions to read via TLS,
709 and initialize things. */
710
711 construct_cipher_name(ssl);
712
713 DEBUG(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
721 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
722 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
723 ssl_xfer_eof = ssl_xfer_error = 0;
724
725 receive_getc = tls_getc;
726 receive_ungetc = tls_ungetc;
727 receive_feof = tls_feof;
728 receive_ferror = tls_ferror;
729 receive_smtp_buffered = tls_smtp_buffered;
730
731 tls_active = fileno(smtp_out);
732 return 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
745 Argument:
746   fd               the fd of the connection
747   host             connected host (for messages)
748   addr             the first address
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
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
761
762 Returns:           OK on success
763                    FAIL otherwise - note that tls_error() will not give DEFER
764                      because this is not a server
765 */
766
767 int
768 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
769   uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
770   uschar *require_ciphers, uschar *require_mac, uschar *require_kx,
771   uschar *require_proto, int timeout)
772 {
773 static uschar txt[256];
774 uschar *expciphers;
775 X509* server_cert;
776 int rc;
777
778 rc = tls_init(host, dhparam, certificate, privatekey, addr);
779 if (rc != OK) return rc;
780
781 tls_certificate_verified = FALSE;
782 verify_callback_called = FALSE;
783
784 if (!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
788 are separated by underscores. So that I can use either form in my tests, and
789 also for general convenience, we turn underscores into hyphens here. */
790
791 if (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))
797     return tls_error(US"SSL_CTX_set_cipher_list", host, NULL);
798   }
799
800 rc = setup_certs(verify_certs, crl, host, FALSE);
801 if (rc != OK) return rc;
802
803 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", host, NULL);
804 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
805 SSL_set_fd(ssl, fd);
806 SSL_set_connect_state(ssl);
807
808 /* There doesn't seem to be a built-in timeout on connection. */
809
810 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
811 sigalrm_seen = FALSE;
812 alarm(timeout);
813 rc = SSL_connect(ssl);
814 alarm(0);
815
816 if (rc <= 0)
817   return tls_error(US"SSL_connect", host, sigalrm_seen ? US"timed out" : NULL);
818
819 DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
820
821 server_cert = SSL_get_peer_certificate (ssl);
822 tls_peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
823   CS txt, sizeof(txt));
824 tls_peerdn = txt;
825
826 construct_cipher_name(ssl);   /* Sets tls_cipher */
827
828 tls_active = fd;
829 return 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,
841 it refills the buffer via the SSL reading function.
842
843 Arguments:  none
844 Returns:    the next character or EOF
845 */
846
847 int
848 tls_getc(void)
849 {
850 if (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;
875     receive_smtp_buffered = smtp_buffered;
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     }
894 #ifndef DISABLE_DKIM
895   dkim_exim_verify_feed(ssl_xfer_buffer, inbytes);
896 #endif
897   ssl_xfer_buffer_hwm = inbytes;
898   ssl_xfer_buffer_lwm = 0;
899   }
900
901 /* Something in the buffer; return next uschar */
902
903 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
904 }
905
906
907
908 /*************************************************
909 *          Read bytes from TLS channel           *
910 *************************************************/
911
912 /*
913 Arguments:
914   buff      buffer of data
915   len       size of buffer
916
917 Returns:    the number of bytes read
918             -1 after a failed read
919 */
920
921 int
922 tls_read(uschar *buff, size_t len)
923 {
924 int inbytes;
925 int error;
926
927 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
928   (long)buff, (unsigned int)len);
929
930 inbytes = SSL_read(ssl, CS buff, len);
931 error = SSL_get_error(ssl, inbytes);
932
933 if (error == SSL_ERROR_ZERO_RETURN)
934   {
935   DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
936   return -1;
937   }
938 else if (error != SSL_ERROR_NONE)
939   {
940   return -1;
941   }
942
943 return inbytes;
944 }
945
946
947
948
949
950 /*************************************************
951 *         Write bytes down TLS channel           *
952 *************************************************/
953
954 /*
955 Arguments:
956   buff      buffer of data
957   len       number of bytes
958
959 Returns:    the number of bytes after a successful write,
960             -1 after a failed write
961 */
962
963 int
964 tls_write(const uschar *buff, size_t len)
965 {
966 int outbytes;
967 int error;
968 int left = len;
969
970 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long)buff, left);
971 while (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   }
998 return 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
1008 daemon, to shut down the TLS library, without actually doing a shutdown (which
1009 would tamper with the SSL session in the parent process).
1010
1011 Arguments:   TRUE if SSL_shutdown is to be called
1012 Returns:     nothing
1013 */
1014
1015 void
1016 tls_close(BOOL shutdown)
1017 {
1018 if (tls_active < 0) return;  /* TLS was not active */
1019
1020 if (shutdown)
1021   {
1022   DEBUG(D_tls) debug_printf("tls_close(): shutting down SSL\n");
1023   SSL_shutdown(ssl);
1024   }
1025
1026 SSL_free(ssl);
1027 ssl = NULL;
1028
1029 tls_active = -1;
1030 }
1031
1032
1033
1034
1035 /*************************************************
1036 *         Report the library versions.           *
1037 *************************************************/
1038
1039 /* There have historically been some issues with binary compatibility in
1040 OpenSSL libraries; if Exim (like many other applications) is built against
1041 one version of OpenSSL but the run-time linker picks up another version,
1042 it can result in serious failures, including crashing with a SIGSEGV.  So
1043 report the version found by the compiler and the run-time version.
1044
1045 Arguments:   a FILE* to print the results to
1046 Returns:     nothing
1047 */
1048
1049 void
1050 tls_version_report(FILE *f)
1051 {
1052 fprintf(f, "OpenSSL compile-time version: %s\n", OPENSSL_VERSION_TEXT);
1053 fprintf(f, "OpenSSL runtime version: %s\n", SSLeay_version(SSLEAY_VERSION));
1054 }
1055
1056 /* End of tls-openssl.c */