Fix compiling problems with OpenSSL 0.9.8e.
[exim.git] / src / src / tls-openssl.c
1 /* $Cambridge: exim/src/src/tls-openssl.c,v 1.11 2007/03/13 09:50:22 ph10 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
66 Returns:    OK/DEFER/FAIL
67 */
68
69 static int
70 tls_error(uschar *prefix, host_item *host)
71 {
72 ERR_error_string(ERR_get_error(), ssl_errstring);
73 if (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   }
80 else
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 /*
95 Arguments:
96   s          SSL connection
97   export     not used
98   keylength  keylength
99
100 Returns:     pointer to generated key
101 */
102
103 static RSA *
104 rsa_callback(SSL *s, int export, int keylength)
105 {
106 RSA *rsa_key;
107 export = export;     /* Shut picky compilers up */
108 DEBUG(D_tls) debug_printf("Generating %d bit RSA key...\n", keylength);
109 rsa_key = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
110 if (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   }
117 return 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
128 callback has the current yes/no state is in "state". If verification succeeded,
129 we set up the tls_peerdn string. If verification failed, what happens depends
130 on whether the client is required to present a verifiable certificate or not.
131
132 If verification is optional, we change the state to yes, but still log the
133 verification error. For some reason (it really would help to have proper
134 documentation of OpenSSL), this callback function then gets called again, this
135 time with state = 1. In fact, that's useful, because we can set up the peerdn
136 value, but we must take care not to set the private verified flag on the second
137 time through.
138
139 Note: this function is not called if the client fails to present a certificate
140 when asked. We get here only if a certificate has been received. Handling of
141 optional verification for this case is done when requesting SSL to verify, by
142 setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the non-optional case.
143
144 Arguments:
145   state      current yes/no state as 1/0
146   x509ctx    certificate information.
147
148 Returns:     1 if verified, 0 if not
149 */
150
151 static int
152 verify_callback(int state, X509_STORE_CTX *x509ctx)
153 {
154 static uschar txt[256];
155
156 X509_NAME_oneline(X509_get_subject_name(x509ctx->current_cert),
157   CS txt, sizeof(txt));
158
159 if (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
173 if (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   }
178 else
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 if (!verify_callback_called) tls_certificate_verified = TRUE;
186 verify_callback_called = TRUE;
187
188 return 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
198 are doing. We copy the string to the debugging output when the level is high
199 enough.
200
201 Arguments:
202   s         the SSL connection
203   where
204   ret
205
206 Returns:    nothing
207 */
208
209 static void
210 info_callback(SSL *s, int where, int ret)
211 {
212 where = where;
213 ret = ret;
214 DEBUG(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
225 Arguments:
226   dhparam   DH parameter file
227
228 Returns:    TRUE if OK (nothing to set up, or setup worked)
229 */
230
231 static BOOL
232 init_dh(uschar *dhparam)
233 {
234 BOOL yield = TRUE;
235 BIO *bio;
236 DH *dh;
237 uschar *dhexpanded;
238
239 if (!expand_check(dhparam, US"tls_dhparam", &dhexpanded))
240   return FALSE;
241
242 if (dhexpanded == NULL) return TRUE;
243
244 if ((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   }
250 else
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
269 return 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
280 the library.
281
282 Arguments:
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
289 Returns:          OK/DEFER/FAIL
290 */
291
292 static int
293 tls_init(host_item *host, uschar *dhparam, uschar *certificate,
294   uschar *privatekey, address_item *addr)
295 {
296 SSL_load_error_strings();          /* basic set up */
297 OpenSSL_add_ssl_algorithms();
298
299 /* Create a context */
300
301 ctx = SSL_CTX_new((host == NULL)?
302   SSLv23_server_method() : SSLv23_client_method());
303
304 if (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
307 order to get the full complement of ciphers to work. It took me roughly a day
308 of work to discover this by experiment.
309
310 On systems that have /dev/urandom, SSL may automatically seed itself from
311 there. Otherwise, we have to make something up as best we can. Double check
312 afterwards. */
313
314 if (!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
344 level. */
345
346 SSL_CTX_set_info_callback(ctx, (void (*)())info_callback);
347
348 /* The following patch was supplied by Robert Roselius */
349
350 #if OPENSSL_VERSION_NUMBER > 0x00906040L
351 /* Enable client-bug workaround.
352    Versions of OpenSSL as of 0.9.6d include a "CBC countermeasure" feature,
353    which causes problems with some clients (such as the Certicom SSL Plus
354    library used by Eudora).  This option, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS,
355    disables the coutermeasure allowing Eudora to connect.
356    Some poppers and MTAs use SSL_OP_ALL, which enables all such bug
357    workarounds. */
358 /* XXX (Silently?) ignore failure here? XXX*/
359
360 if (!(SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)))
361   return tls_error(US"SSL_CTX_set_option", host);
362 #endif
363
364 /* Initialize with DH parameters if supplied */
365
366 if (!init_dh(dhparam)) return DEFER;
367
368 /* Set up certificate and key */
369
370 if (certificate != NULL)
371   {
372   uschar *expanded;
373   if (!expand_check(certificate, US"tls_certificate", &expanded))
374     return DEFER;
375
376   if (expanded != NULL)
377     {
378     DEBUG(D_tls) debug_printf("tls_certificate file %s\n", expanded);
379     if (!SSL_CTX_use_certificate_chain_file(ctx, CS expanded))
380       return tls_error(string_sprintf(
381         "SSL_CTX_use_certificate_chain_file file=%s", expanded), host);
382     }
383
384   if (privatekey != NULL &&
385       !expand_check(privatekey, US"tls_privatekey", &expanded))
386     return DEFER;
387
388   /* If expansion was forced to fail, key_expanded will be NULL. If the result
389   of the expansion is an empty string, ignore it also, and assume the private
390   key is in the same file as the certificate. */
391
392   if (expanded != NULL && *expanded != 0)
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))
396       return tls_error(string_sprintf(
397         "SSL_CTX_use_PrivateKey_file file=%s", expanded), host);
398     }
399   }
400
401 /* Set up the RSA callback */
402
403 SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
404
405 /* Finally, set the timeout, and we are done */
406
407 SSL_CTX_set_timeout(ctx, ssl_session_timeout);
408 DEBUG(D_tls) debug_printf("Initialized TLS\n");
409 return 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
420 to it.
421
422 Argument:   pointer to an SSL structure for the connection
423 Returns:    nothing
424 */
425
426 static void
427 construct_cipher_name(SSL *ssl)
428 {
429 static uschar cipherbuf[256];
430 SSL_CIPHER *c;
431 uschar *ver;
432 int bits;
433
434 switch (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
452 c = SSL_get_current_cipher(ssl);
453 SSL_CIPHER_get_bits(c, &bits);
454
455 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
456   SSL_CIPHER_get_name(c), bits);
457 tls_cipher = cipherbuf;
458
459 DEBUG(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
472 Arguments:
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
479 Returns:        OK/DEFER/FAIL
480 */
481
482 static int
483 setup_certs(uschar *certs, uschar *crl, host_item *host, BOOL optional)
484 {
485 uschar *expcerts, *expcrl;
486
487 if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
488   return DEFER;
489
490 if (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
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
539   if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
540   if (expcrl != NULL && *expcrl != 0)
541     {
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
550       {
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)
555         {
556         file = NULL;
557         dir = expcrl;
558         DEBUG(D_tls) debug_printf("SSL CRL value is a directory %s\n", dir);
559         }
560       else
561         {
562         file = expcrl;
563         dir = NULL;
564         DEBUG(D_tls) debug_printf("SSL CRL value is a file %s\n", file);
565         }
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);
573       }
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
585 return 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
595 the STARTTLS command. It must respond to that command, and then negotiate
596 a TLS session.
597
598 Arguments:
599   require_ciphers   allowed ciphers
600   ------------------------------------------------------
601   require_mac      list of allowed MACs                 ) Not used
602   require_kx       list of allowed key_exchange methods )   for
603   require_proto    list of allowed protocols            ) OpenSSL
604   ------------------------------------------------------
605
606 Returns:            OK on success
607                     DEFER for errors before the start of the negotiation
608                     FAIL for errors during the negotation; the server can't
609                       continue running.
610 */
611
612 int
613 tls_server_start(uschar *require_ciphers, uschar *require_mac,
614   uschar *require_kx, uschar *require_proto)
615 {
616 int rc;
617 uschar *expciphers;
618
619 /* Check for previous activation */
620
621 if (tls_active >= 0)
622   {
623   log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
624     "connection from %s",
625     (sender_fullhost != NULL)? sender_fullhost : US"local process");
626   smtp_printf("554 Already in TLS\r\n");
627   return FAIL;
628   }
629
630 /* Initialize the SSL library. If it fails, it will already have logged
631 the error. */
632
633 rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL);
634 if (rc != OK) return rc;
635
636 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
637   return FAIL;
638
639 /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
640 are separated by underscores. So that I can use either form in my tests, and
641 also for general convenience, we turn underscores into hyphens here. */
642
643 if (expciphers != NULL)
644   {
645   uschar *s = expciphers;
646   while (*s != 0) { if (*s == '_') *s = '-'; s++; }
647   DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
648   if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
649     return tls_error(US"SSL_CTX_set_cipher_list", NULL);
650   }
651
652 /* If this is a host for which certificate verification is mandatory or
653 optional, set up appropriately. */
654
655 tls_certificate_verified = FALSE;
656 verify_callback_called = FALSE;
657
658 if (verify_check_host(&tls_verify_hosts) == OK)
659   {
660   rc = setup_certs(tls_verify_certificates, tls_crl, NULL, FALSE);
661   if (rc != OK) return rc;
662   verify_optional = FALSE;
663   }
664 else if (verify_check_host(&tls_try_verify_hosts) == OK)
665   {
666   rc = setup_certs(tls_verify_certificates, tls_crl, NULL, TRUE);
667   if (rc != OK) return rc;
668   verify_optional = TRUE;
669   }
670
671 /* Prepare for new connection */
672
673 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", NULL);
674 SSL_clear(ssl);
675
676 /* Set context and tell client to go ahead, except in the case of TLS startup
677 on connection, where outputting anything now upsets the clients and tends to
678 make them disconnect. We need to have an explicit fflush() here, to force out
679 the response. Other smtp_printf() calls do not need it, because in non-TLS
680 mode, the fflush() happens when smtp_getc() is called. */
681
682 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
683 if (!tls_on_connect)
684   {
685   smtp_printf("220 TLS go ahead\r\n");
686   fflush(smtp_out);
687   }
688
689 /* Now negotiate the TLS session. We put our own timer on it, since it seems
690 that the OpenSSL library doesn't. */
691
692 SSL_set_wfd(ssl, fileno(smtp_out));
693 SSL_set_rfd(ssl, fileno(smtp_in));
694 SSL_set_accept_state(ssl);
695
696 DEBUG(D_tls) debug_printf("Calling SSL_accept\n");
697
698 sigalrm_seen = FALSE;
699 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
700 rc = SSL_accept(ssl);
701 alarm(0);
702
703 if (rc <= 0)
704   {
705   if (sigalrm_seen) Ustrcpy(ssl_errstring, "timed out");
706     else ERR_error_string(ERR_get_error(), ssl_errstring);
707   log_write(0, LOG_MAIN, "TLS error on connection from %s (SSL_accept): %s",
708     (sender_fullhost != NULL)? sender_fullhost : US"local process",
709     ssl_errstring);
710   return FAIL;
711   }
712
713 DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
714
715 /* TLS has been set up. Adjust the input functions to read via TLS,
716 and initialize things. */
717
718 construct_cipher_name(ssl);
719
720 DEBUG(D_tls)
721   {
722   uschar buf[2048];
723   if (SSL_get_shared_ciphers(ssl, CS buf, sizeof(buf)) != NULL)
724     debug_printf("Shared ciphers: %s\n", buf);
725   }
726
727
728 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
729 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
730 ssl_xfer_eof = ssl_xfer_error = 0;
731
732 receive_getc = tls_getc;
733 receive_ungetc = tls_ungetc;
734 receive_feof = tls_feof;
735 receive_ferror = tls_ferror;
736
737 tls_active = fileno(smtp_out);
738 return OK;
739 }
740
741
742
743
744
745 /*************************************************
746 *    Start a TLS session in a client             *
747 *************************************************/
748
749 /* Called from the smtp transport after STARTTLS has been accepted.
750
751 Argument:
752   fd               the fd of the connection
753   host             connected host (for messages)
754   addr             the first address
755   dhparam          DH parameter file
756   certificate      certificate file
757   privatekey       private key file
758   verify_certs     file for certificate verify
759   crl              file containing CRL
760   require_ciphers  list of allowed ciphers
761   ------------------------------------------------------
762   require_mac      list of allowed MACs                 ) Not used
763   require_kx       list of allowed key_exchange methods )   for
764   require_proto    list of allowed protocols            ) OpenSSL
765   ------------------------------------------------------
766   timeout          startup timeout
767
768 Returns:           OK on success
769                    FAIL otherwise - note that tls_error() will not give DEFER
770                      because this is not a server
771 */
772
773 int
774 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
775   uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
776   uschar *require_ciphers, uschar *require_mac, uschar *require_kx,
777   uschar *require_proto, int timeout)
778 {
779 static uschar txt[256];
780 uschar *expciphers;
781 X509* server_cert;
782 int rc;
783
784 rc = tls_init(host, dhparam, certificate, privatekey, addr);
785 if (rc != OK) return rc;
786
787 tls_certificate_verified = FALSE;
788 verify_callback_called = FALSE;
789
790 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
791   return FAIL;
792
793 /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
794 are separated by underscores. So that I can use either form in my tests, and
795 also for general convenience, we turn underscores into hyphens here. */
796
797 if (expciphers != NULL)
798   {
799   uschar *s = expciphers;
800   while (*s != 0) { if (*s == '_') *s = '-'; s++; }
801   DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
802   if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
803     return tls_error(US"SSL_CTX_set_cipher_list", host);
804   }
805
806 rc = setup_certs(verify_certs, crl, host, FALSE);
807 if (rc != OK) return rc;
808
809 if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", host);
810 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
811 SSL_set_fd(ssl, fd);
812 SSL_set_connect_state(ssl);
813
814 /* There doesn't seem to be a built-in timeout on connection. */
815
816 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
817 sigalrm_seen = FALSE;
818 alarm(timeout);
819 rc = SSL_connect(ssl);
820 alarm(0);
821
822 if (rc <= 0)
823   {
824   if (sigalrm_seen)
825     {
826     log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
827       "SSL_connect timed out", host->name, host->address);
828     return FAIL;
829     }
830   else return tls_error(US"SSL_connect", host);
831   }
832
833 DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
834
835 server_cert = SSL_get_peer_certificate (ssl);
836 tls_peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
837   CS txt, sizeof(txt));
838 tls_peerdn = txt;
839
840 construct_cipher_name(ssl);   /* Sets tls_cipher */
841
842 tls_active = fd;
843 return OK;
844 }
845
846
847
848
849
850 /*************************************************
851 *            TLS version of getc                 *
852 *************************************************/
853
854 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
855 it refills the buffer via the SSL reading function.
856
857 Arguments:  none
858 Returns:    the next character or EOF
859 */
860
861 int
862 tls_getc(void)
863 {
864 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
865   {
866   int error;
867   int inbytes;
868
869   DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
870     (long)ssl_xfer_buffer, ssl_xfer_buffer_size);
871
872   if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
873   inbytes = SSL_read(ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size);
874   error = SSL_get_error(ssl, inbytes);
875   alarm(0);
876
877   /* SSL_ERROR_ZERO_RETURN appears to mean that the SSL session has been
878   closed down, not that the socket itself has been closed down. Revert to
879   non-SSL handling. */
880
881   if (error == SSL_ERROR_ZERO_RETURN)
882     {
883     DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
884
885     receive_getc = smtp_getc;
886     receive_ungetc = smtp_ungetc;
887     receive_feof = smtp_feof;
888     receive_ferror = smtp_ferror;
889
890     SSL_free(ssl);
891     ssl = NULL;
892     tls_active = -1;
893     tls_cipher = NULL;
894     tls_peerdn = NULL;
895
896     return smtp_getc();
897     }
898
899   /* Handle genuine errors */
900
901   else if (error != SSL_ERROR_NONE)
902     {
903     DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
904     ssl_xfer_error = 1;
905     return EOF;
906     }
907
908   ssl_xfer_buffer_hwm = inbytes;
909   ssl_xfer_buffer_lwm = 0;
910   }
911
912 /* Something in the buffer; return next uschar */
913
914 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
915 }
916
917
918
919 /*************************************************
920 *          Read bytes from TLS channel           *
921 *************************************************/
922
923 /*
924 Arguments:
925   buff      buffer of data
926   len       size of buffer
927
928 Returns:    the number of bytes read
929             -1 after a failed read
930 */
931
932 int
933 tls_read(uschar *buff, size_t len)
934 {
935 int inbytes;
936 int error;
937
938 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
939   (long)buff, (unsigned int)len);
940
941 inbytes = SSL_read(ssl, CS buff, len);
942 error = SSL_get_error(ssl, inbytes);
943
944 if (error == SSL_ERROR_ZERO_RETURN)
945   {
946   DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
947   return -1;
948   }
949 else if (error != SSL_ERROR_NONE)
950   {
951   return -1;
952   }
953
954 return inbytes;
955 }
956
957
958
959
960
961 /*************************************************
962 *         Write bytes down TLS channel           *
963 *************************************************/
964
965 /*
966 Arguments:
967   buff      buffer of data
968   len       number of bytes
969
970 Returns:    the number of bytes after a successful write,
971             -1 after a failed write
972 */
973
974 int
975 tls_write(const uschar *buff, size_t len)
976 {
977 int outbytes;
978 int error;
979 int left = len;
980
981 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long)buff, left);
982 while (left > 0)
983   {
984   DEBUG(D_tls) debug_printf("SSL_write(SSL, %lx, %d)\n", (long)buff, left);
985   outbytes = SSL_write(ssl, CS buff, left);
986   error = SSL_get_error(ssl, outbytes);
987   DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
988   switch (error)
989     {
990     case SSL_ERROR_SSL:
991     ERR_error_string(ERR_get_error(), ssl_errstring);
992     log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
993     return -1;
994
995     case SSL_ERROR_NONE:
996     left -= outbytes;
997     buff += outbytes;
998     break;
999
1000     case SSL_ERROR_ZERO_RETURN:
1001     log_write(0, LOG_MAIN, "SSL channel closed on write");
1002     return -1;
1003
1004     default:
1005     log_write(0, LOG_MAIN, "SSL_write error %d", error);
1006     return -1;
1007     }
1008   }
1009 return len;
1010 }
1011
1012
1013
1014 /*************************************************
1015 *         Close down a TLS session               *
1016 *************************************************/
1017
1018 /* This is also called from within a delivery subprocess forked from the
1019 daemon, to shut down the TLS library, without actually doing a shutdown (which
1020 would tamper with the SSL session in the parent process).
1021
1022 Arguments:   TRUE if SSL_shutdown is to be called
1023 Returns:     nothing
1024 */
1025
1026 void
1027 tls_close(BOOL shutdown)
1028 {
1029 if (tls_active < 0) return;  /* TLS was not active */
1030
1031 if (shutdown)
1032   {
1033   DEBUG(D_tls) debug_printf("tls_close(): shutting down SSL\n");
1034   SSL_shutdown(ssl);
1035   }
1036
1037 SSL_free(ssl);
1038 ssl = NULL;
1039
1040 tls_active = -1;
1041 }
1042
1043 /* End of tls-openssl.c */