exipick version 20060216.1
[exim.git] / src / src / tls-gnu.c
1 /* $Cambridge: exim/src/src/tls-gnu.c,v 1.12 2006/02/14 14:12:07 ph10 Exp $ */
2
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2006 */
8 /* See the file NOTICE for conditions of use and distribution. */
9
10 /* This module provides TLS (aka SSL) support for Exim using the GnuTLS
11 library. It is #included into tls.c when that library is used. The code herein
12 is based on a patch that was contributed by Nikos Mavroyanopoulos.
13
14 No cryptographic code is included in Exim. All this module does is to call
15 functions from the GnuTLS library. */
16
17
18 /* Heading stuff for GnuTLS */
19
20 #include <gnutls/gnutls.h>
21 #include <gnutls/x509.h>
22
23
24 #define UNKNOWN_NAME "unknown"
25 #define DH_BITS 768
26 #define RSA_BITS 512
27 #define PARAM_SIZE 2*1024
28
29
30 /* Values for verify_requirment and initialized */
31
32 enum { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED };
33 enum { INITIALIZED_NOT, INITIALIZED_SERVER, INITIALIZED_CLIENT };
34
35 /* Local static variables for GNUTLS */
36
37 static BOOL initialized = INITIALIZED_NOT;
38 static host_item *client_host;
39
40 static gnutls_rsa_params rsa_params = NULL;
41 static gnutls_dh_params dh_params = NULL;
42
43 static gnutls_certificate_server_credentials x509_cred = NULL;
44 static gnutls_session tls_session = NULL;
45
46 static char ssl_errstring[256];
47
48 static int ssl_session_timeout = 200;
49 static int verify_requirement;
50
51 /* Priorities for TLS algorithms to use. At present, only the cipher priority
52 vector can be altered. */
53
54 static const int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
55
56 static const int kx_priority[16] = {
57 GNUTLS_KX_RSA,
58 GNUTLS_KX_DHE_DSS,
59 GNUTLS_KX_DHE_RSA,
60 GNUTLS_KX_RSA_EXPORT,
61 0 };
62
63 static int default_cipher_priority[16] = {
64 GNUTLS_CIPHER_AES_256_CBC,
65 GNUTLS_CIPHER_AES_128_CBC,
66 GNUTLS_CIPHER_3DES_CBC,
67 GNUTLS_CIPHER_ARCFOUR_128,
68 0 };
69
70 static int cipher_priority[16];
71
72 static const int mac_priority[16] = {
73 GNUTLS_MAC_SHA,
74 GNUTLS_MAC_MD5,
75 0 };
76
77 static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
78 static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
79
80 /* Tables of cipher names and equivalent numbers */
81
82 typedef struct pri_item {
83 uschar *name;
84 int *values;
85 } pri_item;
86
87 static int arcfour_128_codes[] = { GNUTLS_CIPHER_ARCFOUR_128, 0 };
88 static int arcfour_40_codes[] = { GNUTLS_CIPHER_ARCFOUR_40, 0 };
89 static int arcfour_codes[] = { GNUTLS_CIPHER_ARCFOUR_128,
90 GNUTLS_CIPHER_ARCFOUR_40, 0 };
91 static int aes_256_codes[] = { GNUTLS_CIPHER_AES_256_CBC, 0 };
92 static int aes_128_codes[] = { GNUTLS_CIPHER_AES_128_CBC, 0 };
93 static int aes_codes[] = { GNUTLS_CIPHER_AES_256_CBC,
94 GNUTLS_CIPHER_AES_128_CBC, 0 };
95 static int des3_codes[] = { GNUTLS_CIPHER_3DES_CBC, 0 };
96
97 static pri_item cipher_index[] = {
98 { US"ARCFOUR_128", arcfour_128_codes },
99 { US"ARCFOUR_40", arcfour_40_codes },
100 { US"ARCFOUR", arcfour_codes },
101 { US"AES_256", aes_256_codes },
102 { US"AES_128", aes_128_codes },
103 { US"AES", aes_codes },
104 { US"3DES", des3_codes }
105 };
106
107
108
109 /*************************************************
110 * Handle TLS error *
111 *************************************************/
112
113 /* Called from lots of places when errors occur before actually starting to do
114 the TLS handshake, that is, while the session is still in clear. Always returns
115 DEFER for a server and FAIL for a client so that most calls can use "return
116 tls_error(...)" to do this processing and then give an appropriate return. A
117 single function is used for both server and client, because it is called from
118 some shared functions.
119
120 Argument:
121 prefix text to include in the logged error
122 host NULL if setting up a server;
123 the connected host if setting up a client
124 err a GnuTLS error number, or 0 if local error
125
126 Returns: OK/DEFER/FAIL
127 */
128
129 static int
130 tls_error(uschar *prefix, host_item *host, int err)
131 {
132 uschar *errtext = US"";
133 if (err != 0) errtext = string_sprintf(": %s", gnutls_strerror(err));
134 if (host == NULL)
135 {
136 log_write(0, LOG_MAIN, "TLS error on connection from %s (%s)%s",
137 (sender_fullhost != NULL)? sender_fullhost : US "local process",
138 prefix, errtext);
139 return DEFER;
140 }
141 else
142 {
143 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s",
144 host->name, host->address, prefix, errtext);
145 return FAIL;
146 }
147 }
148
149
150
151 /*************************************************
152 * Verify certificate *
153 *************************************************/
154
155 /* Called after a successful handshake, when certificate verification is
156 required or optional, for both server and client.
157
158 Arguments:
159 session GNUTLS session
160 error where to put text giving a reason for failure
161
162 Returns: TRUE/FALSE
163 */
164
165 static BOOL
166 verify_certificate(gnutls_session session, uschar **error)
167 {
168 int verify;
169 uschar *dn_string = US"";
170 const gnutls_datum *cert;
171 unsigned int cert_size = 0;
172
173 *error = NULL;
174
175 /* Get the peer's certificate. If it sent one, extract it's DN, and then
176 attempt to verify the certificate. If no certificate is supplied, verification
177 is forced to fail. */
178
179 cert = gnutls_certificate_get_peers(session, &cert_size);
180 if (cert != NULL)
181 {
182 uschar buff[1024];
183 gnutls_x509_crt gcert;
184
185 gnutls_x509_crt_init(&gcert);
186 dn_string = US"unknown";
187
188 if (gnutls_x509_crt_import(gcert, cert, GNUTLS_X509_FMT_DER) == 0)
189 {
190 size_t bufsize = sizeof(buff);
191 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
192 dn_string = string_copy_malloc(buff);
193 }
194
195 verify = gnutls_certificate_verify_peers(session);
196 }
197 else
198 {
199 DEBUG(D_tls) debug_printf("no peer certificate supplied\n");
200 verify = GNUTLS_CERT_INVALID;
201 *error = US"not supplied";
202 }
203
204 /* Handle the result of verification. INVALID seems to be set as well
205 as REVOKED, but leave the test for both. */
206
207 if ((verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
208 {
209 tls_certificate_verified = FALSE;
210 if (*error == NULL) *error = ((verify & GNUTLS_CERT_REVOKED) != 0)?
211 US"revoked" : US"invalid";
212 if (verify_requirement == VERIFY_REQUIRED)
213 {
214 DEBUG(D_tls) debug_printf("TLS certificate verification failed (%s): "
215 "peerdn=%s\n", *error, dn_string);
216 gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
217 return FALSE; /* reject */
218 }
219 DEBUG(D_tls) debug_printf("TLS certificate verify failure (%s) overridden "
220 "(host in tls_try_verify_hosts): peerdn=%s\n", *error, dn_string);
221 }
222 else
223 {
224 tls_certificate_verified = TRUE;
225 DEBUG(D_tls) debug_printf("TLS certificate verified: peerdn=%s\n",
226 dn_string);
227 }
228
229 tls_peerdn = dn_string;
230 return TRUE; /* accept */
231 }
232
233
234
235 /*************************************************
236 * Setup up RSA and DH parameters *
237 *************************************************/
238
239 /* Generating the RSA and D-H parameters takes a long time. They only need to
240 be re-generated every so often, depending on security policy. What we do is to
241 keep these parameters in a file in the spool directory. If the file does not
242 exist, we generate them. This means that it is easy to cause a regeneration.
243
244 The new file is written as a temporary file and renamed, so that an incomplete
245 file is never present. If two processes both compute some new parameters, you
246 waste a bit of effort, but it doesn't seem worth messing around with locking to
247 prevent this.
248
249 Argument:
250 host NULL for server, server for client (for error handling)
251
252 Returns: OK/DEFER/FAIL
253 */
254
255 static int
256 init_rsa_dh(host_item *host)
257 {
258 int fd;
259 int ret;
260 gnutls_datum m;
261 uschar filename[200];
262
263 /* Initialize the data structures for holding the parameters */
264
265 ret = gnutls_rsa_params_init(&rsa_params);
266 if (ret < 0) return tls_error(US"init rsa_params", host, ret);
267
268 ret = gnutls_dh_params_init(&dh_params);
269 if (ret < 0) return tls_error(US"init dh_params", host, ret);
270
271 /* Set up the name of the cache file */
272
273 if (!string_format(filename, sizeof(filename), "%s/gnutls-params",
274 spool_directory))
275 return tls_error(US"overlong filename", host, 0);
276
277 /* Open the cache file for reading and if successful, read it and set up the
278 parameters. If we can't set up the RSA parameters, assume that we are dealing
279 with an old-style cache file that is in another format, and fall through to
280 compute new values. However, if we correctly get RSA parameters, a failure to
281 set up D-H parameters is treated as an error. */
282
283 fd = Uopen(filename, O_RDONLY, 0);
284 if (fd >= 0)
285 {
286 struct stat statbuf;
287 if (fstat(fd, &statbuf) < 0)
288 {
289 (void)close(fd);
290 return tls_error(US"TLS cache stat failed", host, 0);
291 }
292
293 m.size = statbuf.st_size;
294 m.data = malloc(m.size);
295 if (m.data == NULL)
296 return tls_error(US"memory allocation failed", host, 0);
297 if (read(fd, m.data, m.size) != m.size)
298 return tls_error(US"TLS cache read failed", host, 0);
299 (void)close(fd);
300
301 ret = gnutls_rsa_params_import_pkcs1(rsa_params, &m, GNUTLS_X509_FMT_PEM);
302
303 if (ret < 0)
304 {
305 DEBUG(D_tls)
306 debug_printf("RSA params import failed: assume old-style cache file\n");
307 }
308 else
309 {
310 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
311 if (ret < 0)
312 return tls_error(US"DH params import", host, ret);
313 DEBUG(D_tls) debug_printf("read RSA and D-H parameters from file\n");
314 }
315
316 free(m.data);
317 }
318
319 /* If the file does not exist, fall through to compute new data and cache it.
320 If there was any other opening error, it is serious. */
321
322 else if (errno == ENOENT)
323 {
324 ret = -1;
325 DEBUG(D_tls)
326 debug_printf("parameter cache file %s does not exist\n", filename);
327 }
328 else
329 return tls_error(string_open_failed(errno, "%s for reading", filename),
330 host, 0);
331
332 /* If ret < 0, either the cache file does not exist, or the data it contains
333 is not useful. One particular case of this is when upgrading from an older
334 release of Exim in which the data was stored in a different format. We don't
335 try to be clever and support both formats; we just regenerate new data in this
336 case. */
337
338 if (ret < 0)
339 {
340 uschar tempfilename[sizeof(filename) + 10];
341
342 DEBUG(D_tls) debug_printf("generating %d bit RSA key...\n", RSA_BITS);
343 ret = gnutls_rsa_params_generate2(rsa_params, RSA_BITS);
344 if (ret < 0) return tls_error(US"RSA key generation", host, ret);
345
346 DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n",
347 DH_BITS);
348 ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
349 if (ret < 0) return tls_error(US"D-H key generation", host, ret);
350
351 /* Write the parameters to a file in the spool directory so that we
352 can use them from other Exim processes. */
353
354 sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
355 fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
356 if (fd < 0)
357 return tls_error(string_open_failed(errno, "%s for writing", filename),
358 host, 0);
359 (void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
360
361 /* export the parameters in a format that can be generated using GNUTLS'
362 * certtool or other programs.
363 *
364 * The commands for certtool are:
365 * $ certtool --generate-privkey --bits 512 >params
366 * $ echo "" >>params
367 * $ certtool --generate-dh-params --bits 1024 >> params
368 */
369
370 m.size = PARAM_SIZE;
371 m.data = malloc(m.size);
372 if (m.data == NULL)
373 return tls_error(US"memory allocation failed", host, 0);
374
375 ret = gnutls_rsa_params_export_pkcs1(rsa_params, GNUTLS_X509_FMT_PEM,
376 m.data, &m.size);
377 if (ret < 0) return tls_error(US"RSA params export", host, ret);
378
379 /* Do not write the null termination byte. */
380
381 m.size = Ustrlen(m.data);
382 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
383 return tls_error(US"TLS cache write failed", host, 0);
384
385 m.size = PARAM_SIZE;
386 ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data,
387 &m.size);
388 if (ret < 0) return tls_error(US"DH params export", host, ret);
389
390 m.size = Ustrlen(m.data);
391 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
392 return tls_error(US"TLS cache write failed", host, 0);
393
394 free(m.data);
395 (void)close(fd);
396
397 if (rename(CS tempfilename, CS filename) < 0)
398 return tls_error(string_sprintf("failed to rename %s as %s: %s",
399 tempfilename, filename, strerror(errno)), host, 0);
400
401 DEBUG(D_tls) debug_printf("wrote RSA and D-H parameters to file %s\n",
402 filename);
403 }
404
405 DEBUG(D_tls) debug_printf("initialized RSA and D-H parameters\n");
406 return OK;
407 }
408
409
410
411
412 /*************************************************
413 * Initialize for GnuTLS *
414 *************************************************/
415
416 /* Called from both server and client code. In the case of a server, errors
417 before actual TLS negotiation return DEFER.
418
419 Arguments:
420 host connected host, if client; NULL if server
421 certificate certificate file
422 privatekey private key file
423 cas CA certs file
424 crl CRL file
425
426 Returns: OK/DEFER/FAIL
427 */
428
429 static int
430 tls_init(host_item *host, uschar *certificate, uschar *privatekey, uschar *cas,
431 uschar *crl)
432 {
433 int rc;
434 uschar *cert_expanded, *key_expanded, *cas_expanded, *crl_expanded;
435
436 initialized = (host == NULL)? INITIALIZED_SERVER : INITIALIZED_CLIENT;
437
438 rc = gnutls_global_init();
439 if (rc < 0) return tls_error(US"tls-init", host, rc);
440
441 /* Create RSA and D-H parameters, or read them from the cache file. This
442 function does its own SMTP error messaging. */
443
444 rc = init_rsa_dh(host);
445 if (rc != OK) return rc;
446
447 /* Create the credentials structure */
448
449 rc = gnutls_certificate_allocate_credentials(&x509_cred);
450 if (rc < 0) return tls_error(US"certificate_allocate_credentials", host, rc);
451
452 /* This stuff must be done for each session, because different certificates
453 may be required for different sessions. */
454
455 if (!expand_check(certificate, US"tls_certificate", &cert_expanded))
456 return DEFER;
457
458 key_expanded = NULL;
459 if (privatekey != NULL)
460 {
461 if (!expand_check(privatekey, US"tls_privatekey", &key_expanded))
462 return DEFER;
463 }
464
465 /* If expansion was forced to fail, key_expanded will be NULL. If the result of
466 the expansion is an empty string, ignore it also, and assume that the private
467 key is in the same file as the certificate. */
468
469 if (key_expanded == NULL || *key_expanded == 0)
470 key_expanded = cert_expanded;
471
472 /* Set the certificate and private keys */
473
474 if (cert_expanded != NULL)
475 {
476 DEBUG(D_tls) debug_printf("certificate file = %s\nkey file = %s\n",
477 cert_expanded, key_expanded);
478 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS cert_expanded,
479 CS key_expanded, GNUTLS_X509_FMT_PEM);
480 if (rc < 0)
481 {
482 uschar *msg = string_sprintf("cert/key setup: cert=%s key=%s",
483 cert_expanded, key_expanded);
484 return tls_error(msg, host, rc);
485 }
486 }
487
488 /* A certificate is mandatory in a server, but not in a client */
489
490 else
491 {
492 if (host == NULL)
493 return tls_error(US"no TLS server certificate is specified", host, 0);
494 DEBUG(D_tls) debug_printf("no TLS client certificate is specified\n");
495 }
496
497 /* Set the trusted CAs file if one is provided, and then add the CRL if one is
498 provided. Experiment shows that, if the certificate file is empty, an unhelpful
499 error message is provided. However, if we just refrain from setting anything up
500 in that case, certificate verification fails, which seems to be the correct
501 behaviour. */
502
503 if (cas != NULL)
504 {
505 struct stat statbuf;
506
507 if (!expand_check(cas, US"tls_verify_certificates", &cas_expanded))
508 return DEFER;
509
510 if (stat(CS cas_expanded, &statbuf) < 0)
511 {
512 log_write(0, LOG_MAIN|LOG_PANIC, "could not stat %s "
513 "(tls_verify_certificates): %s", cas_expanded, strerror(errno));
514 return DEFER;
515 }
516
517 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
518 cas_expanded, statbuf.st_size);
519
520 /* If the cert file is empty, there's no point in loading the CRL file. */
521
522 if (statbuf.st_size > 0)
523 {
524 rc = gnutls_certificate_set_x509_trust_file(x509_cred, CS cas_expanded,
525 GNUTLS_X509_FMT_PEM);
526 if (rc < 0) return tls_error(US"setup_certs", host, rc);
527
528 if (crl != NULL && *crl != 0)
529 {
530 if (!expand_check(crl, US"tls_crl", &crl_expanded))
531 return DEFER;
532 DEBUG(D_tls) debug_printf("loading CRL file = %s\n", crl_expanded);
533 rc = gnutls_certificate_set_x509_crl_file(x509_cred, CS crl_expanded,
534 GNUTLS_X509_FMT_PEM);
535 if (rc < 0) return tls_error(US"CRL setup", host, rc);
536 }
537 }
538 }
539
540 /* Associate the parameters with the x509 credentials structure. */
541
542 gnutls_certificate_set_dh_params(x509_cred, dh_params);
543 gnutls_certificate_set_rsa_export_params(x509_cred, rsa_params);
544
545 DEBUG(D_tls) debug_printf("initialized certificate stuff\n");
546 return OK;
547 }
548
549
550
551
552 /*************************************************
553 * Remove ciphers from priority list *
554 *************************************************/
555
556 /* Cautiously written so that it will remove duplicates if present.
557
558 Arguments:
559 list a zero-terminated list
560 remove_list a zero-terminated list to be removed
561
562 Returns: nothing
563 */
564
565 static void
566 remove_ciphers(int *list, int *remove_list)
567 {
568 for (; *remove_list != 0; remove_list++)
569 {
570 int *p = list;
571 while (*p != 0)
572 {
573 if (*p == *remove_list)
574 {
575 int *pp = p;
576 do { pp[0] = pp[1]; pp++; } while (*pp != 0);
577 }
578 else p++;
579 }
580 }
581 }
582
583
584
585 /*************************************************
586 * Add ciphers to priority list *
587 *************************************************/
588
589 /* Cautiously written to check the list size
590
591 Arguments:
592 list a zero-terminated list
593 list_max maximum offset in the list
594 add_list a zero-terminated list to be added
595
596 Returns: TRUE if OK; FALSE if list overflows
597 */
598
599 static BOOL
600 add_ciphers(int *list, int list_max, int *add_list)
601 {
602 int next = 0;
603 while (list[next] != 0) next++;
604 while (*add_list != 0)
605 {
606 if (next >= list_max) return FALSE;
607 list[next++] = *add_list++;
608 }
609 list[next] = 0;
610 return TRUE;
611 }
612
613
614
615 /*************************************************
616 * Initialize a single GNUTLS session *
617 *************************************************/
618
619 /* Set the algorithm, the db backend, whether to request certificates etc.
620
621 TLS in Exim was first implemented using OpenSSL. This has a function to which
622 you pass a list of cipher suites that are permitted/not permitted. GnuTLS works
623 differently. It operates using priority lists for the different components of
624 cipher suites.
625
626 For compatibility of configuration, we scan a list of cipher suites and set
627 priorities therefrom. However, at the moment, we pay attention only to the bulk
628 cipher.
629
630 Arguments:
631 side one of GNUTLS_SERVER, GNUTLS_CLIENT
632 expciphers expanded ciphers list
633
634 Returns: a gnutls_session, or NULL if there is a problem
635 */
636
637 static gnutls_session
638 tls_session_init(int side, uschar *expciphers)
639 {
640 gnutls_session session;
641
642 gnutls_init(&session, side);
643
644 /* Handle the list of permitted ciphers */
645
646 memcpy(cipher_priority, default_cipher_priority, sizeof(cipher_priority));
647
648 if (expciphers != NULL)
649 {
650 int sep = 0;
651 BOOL first = TRUE;
652 uschar *cipher;
653
654 /* The names OpenSSL uses are of the form DES-CBC3-SHA, using hyphen
655 separators. GnuTLS uses underscore separators. So that I can use either form
656 in my tests, and also for general convenience, we turn hyphens into
657 underscores before scanning the list. */
658
659 uschar *s = expciphers;
660 while (*s != 0) { if (*s == '-') *s = '_'; s++; }
661
662 while ((cipher = string_nextinlist(&expciphers, &sep, big_buffer,
663 big_buffer_size)) != NULL)
664 {
665 int i;
666 BOOL exclude = cipher[0] == '!';
667 if (first && !exclude) cipher_priority[0] = 0;
668 first = FALSE;
669
670 for (i = 0; i < sizeof(cipher_index)/sizeof(pri_item); i++)
671 {
672 uschar *ss = strstric(cipher, cipher_index[i].name, FALSE);
673 if (ss != NULL)
674 {
675 uschar *endss = ss + Ustrlen(cipher_index[i].name);
676 if ((ss == cipher || !isalnum(ss[-1])) && !isalnum(*endss))
677 {
678 if (exclude)
679 remove_ciphers(cipher_priority, cipher_index[i].values);
680 else
681 {
682 if (!add_ciphers(cipher_priority,
683 sizeof(cipher_priority)/sizeof(pri_item),
684 cipher_index[i].values))
685 {
686 log_write(0, LOG_MAIN|LOG_PANIC, "GnuTLS init failed: cipher "
687 "priority table overflow");
688 gnutls_deinit(session);
689 return NULL;
690 }
691 }
692 }
693 }
694 }
695 }
696
697 DEBUG(D_tls)
698 {
699 int *ptr = cipher_priority;
700 debug_printf("adjusted cipher priorities:");
701 while (*ptr != 0) debug_printf(" %d", *ptr++);
702 debug_printf("\n");
703 }
704 }
705
706 /* Define the various priorities */
707
708 gnutls_cipher_set_priority(session, cipher_priority);
709 gnutls_compression_set_priority(session, comp_priority);
710 gnutls_kx_set_priority(session, kx_priority);
711 gnutls_protocol_set_priority(session, protocol_priority);
712 gnutls_mac_set_priority(session, mac_priority);
713
714 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
715
716 gnutls_dh_set_prime_bits(session, DH_BITS);
717
718 /* Request or demand a certificate of the peer, as configured. This will
719 happen only in a server. */
720
721 if (verify_requirement != VERIFY_NONE)
722 gnutls_certificate_server_set_request(session,
723 (verify_requirement == VERIFY_OPTIONAL)?
724 GNUTLS_CERT_REQUEST : GNUTLS_CERT_REQUIRE);
725
726 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
727
728 DEBUG(D_tls) debug_printf("initialized GnuTLS session\n");
729 return session;
730 }
731
732
733
734 /*************************************************
735 * Get name of cipher in use *
736 *************************************************/
737
738 /* The answer is left in a static buffer, and tls_cipher is set to point
739 to it.
740
741 Argument: pointer to a GnuTLS session
742 Returns: nothing
743 */
744
745 static void
746 construct_cipher_name(gnutls_session session)
747 {
748 static uschar cipherbuf[256];
749 uschar *ver;
750 int bits, c, kx, mac;
751
752 ver = string_copy(
753 US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
754 if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
755
756 c = gnutls_cipher_get(session);
757 bits = gnutls_cipher_get_key_size(c);
758
759 mac = gnutls_mac_get(session);
760 kx = gnutls_kx_get(session);
761
762 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
763 gnutls_cipher_suite_get_name(kx, c, mac), bits);
764 tls_cipher = cipherbuf;
765
766 DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
767 }
768
769
770
771 /*************************************************
772 * Start a TLS session in a server *
773 *************************************************/
774
775 /* This is called when Exim is running as a server, after having received
776 the STARTTLS command. It must respond to that command, and then negotiate
777 a TLS session.
778
779 Arguments:
780 require_ciphers list of allowed ciphers
781
782 Returns: OK on success
783 DEFER for errors before the start of the negotiation
784 FAIL for errors during the negotation; the server can't
785 continue running.
786 */
787
788 int
789 tls_server_start(uschar *require_ciphers)
790 {
791 int rc;
792 uschar *error;
793 uschar *expciphers = NULL;
794
795 /* Check for previous activation */
796
797 if (tls_active >= 0)
798 {
799 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
800 "connection from %s",
801 (sender_fullhost != NULL)? sender_fullhost : US"local process");
802 smtp_printf("554 Already in TLS\r\n");
803 return FAIL;
804 }
805
806 /* Initialize the library. If it fails, it will already have logged the error
807 and sent an SMTP response. */
808
809 DEBUG(D_tls) debug_printf("initializing GnuTLS as a server\n");
810
811 rc = tls_init(NULL, tls_certificate, tls_privatekey, tls_verify_certificates,
812 tls_crl);
813 if (rc != OK) return rc;
814
815 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
816 return FAIL;
817
818 /* If this is a host for which certificate verification is mandatory or
819 optional, set up appropriately. */
820
821 tls_certificate_verified = FALSE;
822 verify_requirement = VERIFY_NONE;
823
824 if (verify_check_host(&tls_verify_hosts) == OK)
825 verify_requirement = VERIFY_REQUIRED;
826 else if (verify_check_host(&tls_try_verify_hosts) == OK)
827 verify_requirement = VERIFY_OPTIONAL;
828
829 /* Prepare for new connection */
830
831 tls_session = tls_session_init(GNUTLS_SERVER, expciphers);
832 if (tls_session == NULL)
833 return tls_error(US"tls_session_init", NULL, GNUTLS_E_MEMORY_ERROR);
834
835 /* Set context and tell client to go ahead, except in the case of TLS startup
836 on connection, where outputting anything now upsets the clients and tends to
837 make them disconnect. We need to have an explicit fflush() here, to force out
838 the response. Other smtp_printf() calls do not need it, because in non-TLS
839 mode, the fflush() happens when smtp_getc() is called. */
840
841 if (!tls_on_connect)
842 {
843 smtp_printf("220 TLS go ahead\r\n");
844 fflush(smtp_out);
845 }
846
847 /* Now negotiate the TLS session. We put our own timer on it, since it seems
848 that the GnuTLS library doesn't. */
849
850 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fileno(smtp_out));
851
852 sigalrm_seen = FALSE;
853 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
854 rc = gnutls_handshake(tls_session);
855 alarm(0);
856
857 if (rc < 0)
858 {
859 if (sigalrm_seen)
860 Ustrcpy(ssl_errstring, "timed out");
861 else
862 Ustrcpy(ssl_errstring, gnutls_strerror(rc));
863 log_write(0, LOG_MAIN,
864 "TLS error on connection from %s (gnutls_handshake): %s",
865 (sender_fullhost != NULL)? sender_fullhost : US"local process",
866 ssl_errstring);
867
868 /* It seems that, except in the case of a timeout, we have to close the
869 connection right here; otherwise if the other end is running OpenSSL it hangs
870 until the server times out. */
871
872 if (!sigalrm_seen)
873 {
874 (void)fclose(smtp_out);
875 (void)fclose(smtp_in);
876 }
877
878 return FAIL;
879 }
880
881 DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
882
883 if (verify_requirement != VERIFY_NONE &&
884 !verify_certificate(tls_session, &error))
885 {
886 log_write(0, LOG_MAIN,
887 "TLS error on connection from %s: certificate verification failed (%s)",
888 (sender_fullhost != NULL)? sender_fullhost : US"local process", error);
889 return FAIL;
890 }
891
892 construct_cipher_name(tls_session);
893
894 /* TLS has been set up. Adjust the input functions to read via TLS,
895 and initialize appropriately. */
896
897 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
898 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
899 ssl_xfer_eof = ssl_xfer_error = 0;
900
901 receive_getc = tls_getc;
902 receive_ungetc = tls_ungetc;
903 receive_feof = tls_feof;
904 receive_ferror = tls_ferror;
905
906 tls_active = fileno(smtp_out);
907
908 return OK;
909 }
910
911
912
913
914 /*************************************************
915 * Start a TLS session in a client *
916 *************************************************/
917
918 /* Called from the smtp transport after STARTTLS has been accepted.
919
920 Arguments:
921 fd the fd of the connection
922 host connected host (for messages)
923 addr
924 dhparam DH parameter file
925 certificate certificate file
926 privatekey private key file
927 verify_certs file for certificate verify
928 verify_crl CRL for verify
929 require_ciphers list of allowed ciphers
930 timeout startup timeout
931
932 Returns: OK/DEFER/FAIL (because using common functions),
933 but for a client, DEFER and FAIL have the same meaning
934 */
935
936 int
937 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
938 uschar *certificate, uschar *privatekey, uschar *verify_certs,
939 uschar *verify_crl, uschar *require_ciphers, int timeout)
940 {
941 const gnutls_datum *server_certs;
942 uschar *expciphers = NULL;
943 uschar *error;
944 unsigned int server_certs_size;
945 int rc;
946
947 DEBUG(D_tls) debug_printf("initializing GnuTLS as a client\n");
948
949 client_host = host;
950 verify_requirement = (verify_certs == NULL)? VERIFY_NONE : VERIFY_REQUIRED;
951 rc = tls_init(host, certificate, privatekey, verify_certs, verify_crl);
952 if (rc != OK) return rc;
953
954 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
955 return FAIL;
956
957 tls_session = tls_session_init(GNUTLS_CLIENT, expciphers);
958 if (tls_session == NULL)
959 return tls_error(US "tls_session_init", host, GNUTLS_E_MEMORY_ERROR);
960
961 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fd);
962
963 /* There doesn't seem to be a built-in timeout on connection. */
964
965 sigalrm_seen = FALSE;
966 alarm(timeout);
967 rc = gnutls_handshake(tls_session);
968 alarm(0);
969
970 if (rc < 0)
971 {
972 if (sigalrm_seen)
973 {
974 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
975 "gnutls_handshake timed out", host->name, host->address);
976 return FAIL;
977 }
978 else return tls_error(US "gnutls_handshake", host, rc);
979 }
980
981 server_certs = gnutls_certificate_get_peers(tls_session, &server_certs_size);
982
983 if (server_certs != NULL)
984 {
985 uschar buff[1024];
986 gnutls_x509_crt gcert;
987
988 gnutls_x509_crt_init(&gcert);
989 tls_peerdn = US"unknown";
990
991 if (gnutls_x509_crt_import(gcert, server_certs, GNUTLS_X509_FMT_DER) == 0)
992 {
993 size_t bufsize = sizeof(buff);
994 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
995 tls_peerdn = string_copy_malloc(buff);
996 }
997 }
998
999 /* Should we also verify the hostname here? */
1000
1001 if (verify_requirement != VERIFY_NONE &&
1002 !verify_certificate(tls_session, &error))
1003 {
1004 log_write(0, LOG_MAIN,
1005 "TLS error on connection to %s [%s]: certificate verification failed (%s)",
1006 host->name, host->address, error);
1007 return FAIL;
1008 }
1009
1010 construct_cipher_name(tls_session); /* Sets tls_cipher */
1011 tls_active = fd;
1012 return OK;
1013 }
1014
1015
1016
1017 /*************************************************
1018 * Deal with logging errors during I/O *
1019 *************************************************/
1020
1021 /* We have to get the identity of the peer from saved data.
1022
1023 Argument:
1024 ec the GnuTLS error code, or 0 if it's a local error
1025 when text identifying read or write
1026 text local error text when ec is 0
1027
1028 Returns: nothing
1029 */
1030
1031 static void
1032 record_io_error(int ec, uschar *when, uschar *text)
1033 {
1034 uschar *additional = US"";
1035
1036 if (ec == GNUTLS_E_FATAL_ALERT_RECEIVED)
1037 additional = string_sprintf(": %s",
1038 gnutls_alert_get_name(gnutls_alert_get(tls_session)));
1039
1040 if (initialized == INITIALIZED_SERVER)
1041 log_write(0, LOG_MAIN, "TLS %s error on connection from %s: %s%s", when,
1042 (sender_fullhost != NULL)? sender_fullhost : US "local process",
1043 (ec == 0)? text : US gnutls_strerror(ec), additional);
1044
1045 else
1046 log_write(0, LOG_MAIN, "TLS %s error on connection to %s [%s]: %s%s", when,
1047 client_host->name, client_host->address,
1048 (ec == 0)? text : US gnutls_strerror(ec), additional);
1049 }
1050
1051
1052
1053 /*************************************************
1054 * TLS version of getc *
1055 *************************************************/
1056
1057 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
1058 it refills the buffer via the GnuTLS reading function.
1059
1060 Arguments: none
1061 Returns: the next character or EOF
1062 */
1063
1064 int
1065 tls_getc(void)
1066 {
1067 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
1068 {
1069 int inbytes;
1070
1071 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1072 (long) tls_session, (long) ssl_xfer_buffer, ssl_xfer_buffer_size);
1073
1074 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
1075 inbytes = gnutls_record_recv(tls_session, CS ssl_xfer_buffer,
1076 ssl_xfer_buffer_size);
1077 alarm(0);
1078
1079 /* A zero-byte return appears to mean that the TLS session has been
1080 closed down, not that the socket itself has been closed down. Revert to
1081 non-TLS handling. */
1082
1083 if (inbytes == 0)
1084 {
1085 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1086
1087 receive_getc = smtp_getc;
1088 receive_ungetc = smtp_ungetc;
1089 receive_feof = smtp_feof;
1090 receive_ferror = smtp_ferror;
1091
1092 gnutls_deinit(tls_session);
1093 tls_session = NULL;
1094 tls_active = -1;
1095 tls_cipher = NULL;
1096 tls_peerdn = NULL;
1097
1098 return smtp_getc();
1099 }
1100
1101 /* Handle genuine errors */
1102
1103 else if (inbytes < 0)
1104 {
1105 record_io_error(inbytes, US"recv", NULL);
1106 ssl_xfer_error = 1;
1107 return EOF;
1108 }
1109
1110 ssl_xfer_buffer_hwm = inbytes;
1111 ssl_xfer_buffer_lwm = 0;
1112 }
1113
1114
1115 /* Something in the buffer; return next uschar */
1116
1117 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
1118 }
1119
1120
1121
1122 /*************************************************
1123 * Read bytes from TLS channel *
1124 *************************************************/
1125
1126 /*
1127 Arguments:
1128 buff buffer of data
1129 len size of buffer
1130
1131 Returns: the number of bytes read
1132 -1 after a failed read
1133 */
1134
1135 int
1136 tls_read(uschar *buff, size_t len)
1137 {
1138 int inbytes;
1139
1140 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1141 (long) tls_session, (long) buff, len);
1142
1143 inbytes = gnutls_record_recv(tls_session, CS buff, len);
1144 if (inbytes > 0) return inbytes;
1145 if (inbytes == 0)
1146 {
1147 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1148 }
1149 else record_io_error(inbytes, US"recv", NULL);
1150
1151 return -1;
1152 }
1153
1154
1155
1156 /*************************************************
1157 * Write bytes down TLS channel *
1158 *************************************************/
1159
1160 /*
1161 Arguments:
1162 buff buffer of data
1163 len number of bytes
1164
1165 Returns: the number of bytes after a successful write,
1166 -1 after a failed write
1167 */
1168
1169 int
1170 tls_write(const uschar *buff, size_t len)
1171 {
1172 int outbytes;
1173 int left = len;
1174
1175 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
1176 while (left > 0)
1177 {
1178 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
1179 left);
1180 outbytes = gnutls_record_send(tls_session, CS buff, left);
1181
1182 DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
1183 if (outbytes < 0)
1184 {
1185 record_io_error(outbytes, US"send", NULL);
1186 return -1;
1187 }
1188 if (outbytes == 0)
1189 {
1190 record_io_error(0, US"send", US"TLS channel closed on write");
1191 return -1;
1192 }
1193
1194 left -= outbytes;
1195 buff += outbytes;
1196 }
1197
1198 return len;
1199 }
1200
1201
1202
1203 /*************************************************
1204 * Close down a TLS session *
1205 *************************************************/
1206
1207 /* This is also called from within a delivery subprocess forked from the
1208 daemon, to shut down the TLS library, without actually doing a shutdown (which
1209 would tamper with the TLS session in the parent process).
1210
1211 Arguments: TRUE if gnutls_bye is to be called
1212 Returns: nothing
1213 */
1214
1215 void
1216 tls_close(BOOL shutdown)
1217 {
1218 if (tls_active < 0) return; /* TLS was not active */
1219
1220 if (shutdown)
1221 {
1222 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1223 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
1224 }
1225
1226 gnutls_deinit(tls_session);
1227 tls_session = NULL;
1228 gnutls_global_deinit();
1229
1230 tls_active = -1;
1231 }
1232
1233 /* End of tls-gnu.c */