1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2009 */
6 /* See the file NOTICE for conditions of use and distribution. */
8 /* This module provides TLS (aka SSL) support for Exim using the GnuTLS
9 library. It is #included into tls.c when that library is used. The code herein
10 is based on a patch that was contributed by Nikos Mavroyanopoulos.
12 No cryptographic code is included in Exim. All this module does is to call
13 functions from the GnuTLS library. */
16 /* Heading stuff for GnuTLS */
18 #include <gnutls/gnutls.h>
19 #include <gnutls/x509.h>
22 #define UNKNOWN_NAME "unknown"
24 #define PARAM_SIZE 2*1024
27 /* Values for verify_requirment */
29 enum { VERIFY_NONE
, VERIFY_OPTIONAL
, VERIFY_REQUIRED
};
31 /* Local static variables for GNUTLS */
33 static host_item
*client_host
;
35 static gnutls_dh_params dh_params
= NULL
;
37 static gnutls_certificate_server_credentials x509_cred
= NULL
;
38 static gnutls_session tls_session
= NULL
;
40 static char ssl_errstring
[256];
42 static int ssl_session_timeout
= 200;
43 static int verify_requirement
;
45 /* Priorities for TLS algorithms to use. In each case there's a default table,
46 and space into which it can be copied and altered. */
48 static const int default_proto_priority
[16] = {
53 static int proto_priority
[16];
55 static const int default_kx_priority
[16] = {
61 static int kx_priority
[16];
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
,
70 static int cipher_priority
[16];
72 static const int default_mac_priority
[16] = {
77 static int mac_priority
[16];
79 /* These two are currently not changeable. */
81 static const int comp_priority
[16] = { GNUTLS_COMP_NULL
, 0 };
82 static const int cert_type_priority
[16] = { GNUTLS_CRT_X509
, 0 };
84 /* Tables of priority names and equivalent numbers */
86 typedef struct pri_item
{
92 static int tls1_codes
[] = { GNUTLS_TLS1
, 0 };
93 static int ssl3_codes
[] = { GNUTLS_SSL3
, 0 };
95 static pri_item proto_index
[] = {
96 { US
"TLS1", tls1_codes
},
97 { US
"SSL3", ssl3_codes
}
101 static int kx_rsa_codes
[] = { GNUTLS_KX_RSA
,
102 GNUTLS_KX_DHE_RSA
, 0 };
103 static int kx_dhe_codes
[] = { GNUTLS_KX_DHE_DSS
,
104 GNUTLS_KX_DHE_RSA
, 0 };
105 static int kx_dhe_dss_codes
[] = { GNUTLS_KX_DHE_DSS
, 0 };
106 static int kx_dhe_rsa_codes
[] = { GNUTLS_KX_DHE_RSA
, 0 };
108 static pri_item kx_index
[] = {
109 { US
"DHE_DSS", kx_dhe_dss_codes
},
110 { US
"DHE_RSA", kx_dhe_rsa_codes
},
111 { US
"RSA", kx_rsa_codes
},
112 { US
"DHE", kx_dhe_codes
}
116 static int arcfour_128_codes
[] = { GNUTLS_CIPHER_ARCFOUR_128
, 0 };
117 static int arcfour_40_codes
[] = { GNUTLS_CIPHER_ARCFOUR_40
, 0 };
118 static int arcfour_codes
[] = { GNUTLS_CIPHER_ARCFOUR_128
,
119 GNUTLS_CIPHER_ARCFOUR_40
, 0 };
120 static int aes_256_codes
[] = { GNUTLS_CIPHER_AES_256_CBC
, 0 };
121 static int aes_128_codes
[] = { GNUTLS_CIPHER_AES_128_CBC
, 0 };
122 static int aes_codes
[] = { GNUTLS_CIPHER_AES_256_CBC
,
123 GNUTLS_CIPHER_AES_128_CBC
, 0 };
124 static int des3_codes
[] = { GNUTLS_CIPHER_3DES_CBC
, 0 };
126 static pri_item cipher_index
[] = {
127 { US
"ARCFOUR_128", arcfour_128_codes
},
128 { US
"ARCFOUR_40", arcfour_40_codes
},
129 { US
"ARCFOUR", arcfour_codes
},
130 { US
"AES_256", aes_256_codes
},
131 { US
"AES_128", aes_128_codes
},
132 { US
"AES", aes_codes
},
133 { US
"3DES", des3_codes
}
137 static int mac_sha_codes
[] = { GNUTLS_MAC_SHA
, 0 };
138 static int mac_md5_codes
[] = { GNUTLS_MAC_MD5
, 0 };
140 static pri_item mac_index
[] = {
141 { US
"SHA", mac_sha_codes
},
142 { US
"SHA1", mac_sha_codes
},
143 { US
"MD5", mac_md5_codes
}
148 /*************************************************
150 *************************************************/
152 /* Called from lots of places when errors occur before actually starting to do
153 the TLS handshake, that is, while the session is still in clear. Always returns
154 DEFER for a server and FAIL for a client so that most calls can use "return
155 tls_error(...)" to do this processing and then give an appropriate return. A
156 single function is used for both server and client, because it is called from
157 some shared functions.
160 prefix text to include in the logged error
161 host NULL if setting up a server;
162 the connected host if setting up a client
163 msg additional error string (may be NULL)
164 usually obtained from gnutls_strerror()
166 Returns: OK/DEFER/FAIL
170 tls_error(uschar
*prefix
, host_item
*host
, const char *msg
)
174 uschar
*conn_info
= smtp_get_connection_info();
175 if (strncmp(conn_info
, "SMTP ", 5) == 0)
177 log_write(0, LOG_MAIN
, "TLS error on %s (%s)%s%s",
178 conn_info
, prefix
, msg
? ": " : "", msg
? msg
: "");
183 log_write(0, LOG_MAIN
, "TLS error on connection to %s [%s] (%s)%s%s",
184 host
->name
, host
->address
, prefix
, msg
? ": " : "", msg
? msg
: "");
191 /*************************************************
192 * Verify certificate *
193 *************************************************/
195 /* Called after a successful handshake, when certificate verification is
196 required or optional, for both server and client.
199 session GNUTLS session
200 error where to put text giving a reason for failure
206 verify_certificate(gnutls_session session
, const char **error
)
209 uschar
*dn_string
= US
"";
210 const gnutls_datum
*cert
;
211 unsigned int cert_size
= 0;
215 /* Get the peer's certificate. If it sent one, extract it's DN, and then
216 attempt to verify the certificate. If no certificate is supplied, verification
217 is forced to fail. */
219 cert
= gnutls_certificate_get_peers(session
, &cert_size
);
223 gnutls_x509_crt gcert
;
225 gnutls_x509_crt_init(&gcert
);
226 dn_string
= US
"unknown";
228 if (gnutls_x509_crt_import(gcert
, cert
, GNUTLS_X509_FMT_DER
) == 0)
230 size_t bufsize
= sizeof(buff
);
231 if (gnutls_x509_crt_get_dn(gcert
, CS buff
, &bufsize
) >= 0)
232 dn_string
= string_copy_malloc(buff
);
235 verify
= gnutls_certificate_verify_peers(session
);
239 DEBUG(D_tls
) debug_printf("no peer certificate supplied\n");
240 verify
= GNUTLS_CERT_INVALID
;
241 *error
= "not supplied";
244 /* Handle the result of verification. INVALID seems to be set as well
245 as REVOKED, but leave the test for both. */
247 if ((verify
& (GNUTLS_CERT_INVALID
|GNUTLS_CERT_REVOKED
)) != 0)
249 tls_certificate_verified
= FALSE
;
250 if (*error
== NULL
) *error
= ((verify
& GNUTLS_CERT_REVOKED
) != 0)?
251 "revoked" : "invalid";
252 if (verify_requirement
== VERIFY_REQUIRED
)
254 DEBUG(D_tls
) debug_printf("TLS certificate verification failed (%s): "
255 "peerdn=%s\n", *error
, dn_string
);
256 gnutls_alert_send(session
, GNUTLS_AL_FATAL
, GNUTLS_A_BAD_CERTIFICATE
);
257 return FALSE
; /* reject */
259 DEBUG(D_tls
) debug_printf("TLS certificate verify failure (%s) overridden "
260 "(host in tls_try_verify_hosts): peerdn=%s\n", *error
, dn_string
);
264 tls_certificate_verified
= TRUE
;
265 DEBUG(D_tls
) debug_printf("TLS certificate verified: peerdn=%s\n",
269 tls_peerdn
= dn_string
;
270 return TRUE
; /* accept */
275 /*************************************************
276 * Setup up DH parameters *
277 *************************************************/
279 /* Generating the D-H parameters may take a long time. They only need to
280 be re-generated every so often, depending on security policy. What we do is to
281 keep these parameters in a file in the spool directory. If the file does not
282 exist, we generate them. This means that it is easy to cause a regeneration.
284 The new file is written as a temporary file and renamed, so that an incomplete
285 file is never present. If two processes both compute some new parameters, you
286 waste a bit of effort, but it doesn't seem worth messing around with locking to
290 host NULL for server, server for client (for error handling)
292 Returns: OK/DEFER/FAIL
296 init_dh(host_item
*host
)
301 uschar filename
[200];
303 /* Initialize the data structures for holding the parameters */
305 ret
= gnutls_dh_params_init(&dh_params
);
306 if (ret
< 0) return tls_error(US
"init dh_params", host
, gnutls_strerror(ret
));
308 /* Set up the name of the cache file */
310 if (!string_format(filename
, sizeof(filename
), "%s/gnutls-params",
312 return tls_error(US
"overlong filename", host
, NULL
);
314 /* Open the cache file for reading and if successful, read it and set up the
317 fd
= Uopen(filename
, O_RDONLY
, 0);
321 if (fstat(fd
, &statbuf
) < 0)
324 return tls_error(US
"TLS cache stat failed", host
, strerror(errno
));
327 m
.size
= statbuf
.st_size
;
328 m
.data
= malloc(m
.size
);
330 return tls_error(US
"memory allocation failed", host
, strerror(errno
));
332 if (read(fd
, m
.data
, m
.size
) != m
.size
)
333 return tls_error(US
"TLS cache read failed", host
, strerror(errno
));
336 ret
= gnutls_dh_params_import_pkcs3(dh_params
, &m
, GNUTLS_X509_FMT_PEM
);
338 return tls_error(US
"DH params import", host
, gnutls_strerror(ret
));
339 DEBUG(D_tls
) debug_printf("read D-H parameters from file\n");
344 /* If the file does not exist, fall through to compute new data and cache it.
345 If there was any other opening error, it is serious. */
347 else if (errno
== ENOENT
)
351 debug_printf("parameter cache file %s does not exist\n", filename
);
354 return tls_error(string_open_failed(errno
, "%s for reading", filename
),
357 /* If ret < 0, either the cache file does not exist, or the data it contains
358 is not useful. One particular case of this is when upgrading from an older
359 release of Exim in which the data was stored in a different format. We don't
360 try to be clever and support both formats; we just regenerate new data in this
365 uschar tempfilename
[sizeof(filename
) + 10];
367 DEBUG(D_tls
) debug_printf("generating %d bit Diffie-Hellman key...\n",
369 ret
= gnutls_dh_params_generate2(dh_params
, DH_BITS
);
370 if (ret
< 0) return tls_error(US
"D-H key generation", host
, gnutls_strerror(ret
));
372 /* Write the parameters to a file in the spool directory so that we
373 can use them from other Exim processes. */
375 sprintf(CS tempfilename
, "%s-%d", filename
, (int)getpid());
376 fd
= Uopen(tempfilename
, O_WRONLY
|O_CREAT
, 0400);
378 return tls_error(string_open_failed(errno
, "%s for writing", filename
),
380 (void)fchown(fd
, exim_uid
, exim_gid
); /* Probably not necessary */
382 /* export the parameters in a format that can be generated using GNUTLS'
383 * certtool or other programs.
385 * The commands for certtool are:
386 * $ certtool --generate-dh-params --bits 1024 > params
390 m
.data
= malloc(m
.size
);
392 return tls_error(US
"memory allocation failed", host
, strerror(errno
));
395 ret
= gnutls_dh_params_export_pkcs3(dh_params
, GNUTLS_X509_FMT_PEM
, m
.data
,
398 return tls_error(US
"DH params export", host
, gnutls_strerror(ret
));
400 m
.size
= Ustrlen(m
.data
);
402 if (write(fd
, m
.data
, m
.size
) != m
.size
|| write(fd
, "\n", 1) != 1)
403 return tls_error(US
"TLS cache write failed", host
, strerror(errno
));
408 if (rename(CS tempfilename
, CS filename
) < 0)
409 return tls_error(string_sprintf("failed to rename %s as %s",
410 tempfilename
, filename
), host
, strerror(errno
));
412 DEBUG(D_tls
) debug_printf("wrote D-H parameters to file %s\n", filename
);
415 DEBUG(D_tls
) debug_printf("initialized D-H parameters\n");
422 /*************************************************
423 * Initialize for GnuTLS *
424 *************************************************/
426 /* Called from both server and client code. In the case of a server, errors
427 before actual TLS negotiation return DEFER.
430 host connected host, if client; NULL if server
431 certificate certificate file
432 privatekey private key file
436 Returns: OK/DEFER/FAIL
440 tls_init(host_item
*host
, uschar
*certificate
, uschar
*privatekey
, uschar
*cas
,
444 uschar
*cert_expanded
, *key_expanded
, *cas_expanded
, *crl_expanded
;
448 rc
= gnutls_global_init();
449 if (rc
< 0) return tls_error(US
"tls-init", host
, gnutls_strerror(rc
));
451 /* Create D-H parameters, or read them from the cache file. This function does
452 its own SMTP error messaging. */
455 if (rc
!= OK
) return rc
;
457 /* Create the credentials structure */
459 rc
= gnutls_certificate_allocate_credentials(&x509_cred
);
461 return tls_error(US
"certificate_allocate_credentials",
462 host
, gnutls_strerror(rc
));
464 /* This stuff must be done for each session, because different certificates
465 may be required for different sessions. */
467 if (!expand_check(certificate
, US
"tls_certificate", &cert_expanded
))
471 if (privatekey
!= NULL
)
473 if (!expand_check(privatekey
, US
"tls_privatekey", &key_expanded
))
477 /* If expansion was forced to fail, key_expanded will be NULL. If the result of
478 the expansion is an empty string, ignore it also, and assume that the private
479 key is in the same file as the certificate. */
481 if (key_expanded
== NULL
|| *key_expanded
== 0)
482 key_expanded
= cert_expanded
;
484 /* Set the certificate and private keys */
486 if (cert_expanded
!= NULL
)
488 DEBUG(D_tls
) debug_printf("certificate file = %s\nkey file = %s\n",
489 cert_expanded
, key_expanded
);
490 rc
= gnutls_certificate_set_x509_key_file(x509_cred
, CS cert_expanded
,
491 CS key_expanded
, GNUTLS_X509_FMT_PEM
);
494 uschar
*msg
= string_sprintf("cert/key setup: cert=%s key=%s",
495 cert_expanded
, key_expanded
);
496 return tls_error(msg
, host
, gnutls_strerror(rc
));
500 /* A certificate is mandatory in a server, but not in a client */
505 return tls_error(US
"no TLS server certificate is specified", NULL
, NULL
);
506 DEBUG(D_tls
) debug_printf("no TLS client certificate is specified\n");
509 /* Set the trusted CAs file if one is provided, and then add the CRL if one is
510 provided. Experiment shows that, if the certificate file is empty, an unhelpful
511 error message is provided. However, if we just refrain from setting anything up
512 in that case, certificate verification fails, which seems to be the correct
519 if (!expand_check(cas
, US
"tls_verify_certificates", &cas_expanded
))
522 if (stat(CS cas_expanded
, &statbuf
) < 0)
524 log_write(0, LOG_MAIN
|LOG_PANIC
, "could not stat %s "
525 "(tls_verify_certificates): %s", cas_expanded
, strerror(errno
));
529 DEBUG(D_tls
) debug_printf("verify certificates = %s size=" OFF_T_FMT
"\n",
530 cas_expanded
, statbuf
.st_size
);
532 /* If the cert file is empty, there's no point in loading the CRL file. */
534 if (statbuf
.st_size
> 0)
536 rc
= gnutls_certificate_set_x509_trust_file(x509_cred
, CS cas_expanded
,
537 GNUTLS_X509_FMT_PEM
);
538 if (rc
< 0) return tls_error(US
"setup_certs", host
, gnutls_strerror(rc
));
540 if (crl
!= NULL
&& *crl
!= 0)
542 if (!expand_check(crl
, US
"tls_crl", &crl_expanded
))
544 DEBUG(D_tls
) debug_printf("loading CRL file = %s\n", crl_expanded
);
545 rc
= gnutls_certificate_set_x509_crl_file(x509_cred
, CS crl_expanded
,
546 GNUTLS_X509_FMT_PEM
);
547 if (rc
< 0) return tls_error(US
"CRL setup", host
, gnutls_strerror(rc
));
552 /* Associate the parameters with the x509 credentials structure. */
554 gnutls_certificate_set_dh_params(x509_cred
, dh_params
);
556 DEBUG(D_tls
) debug_printf("initialized certificate stuff\n");
563 /*************************************************
564 * Remove from a priority list *
565 *************************************************/
567 /* Cautiously written so that it will remove duplicates if present.
570 list a zero-terminated list
571 remove_list a zero-terminated list to be removed
577 remove_priority(int *list
, int *remove_list
)
579 for (; *remove_list
!= 0; remove_list
++)
584 if (*p
== *remove_list
)
587 do { pp
[0] = pp
[1]; pp
++; } while (*pp
!= 0);
596 /*************************************************
597 * Add to a priority list *
598 *************************************************/
600 /* Cautiously written to check the list size
603 list a zero-terminated list
604 list_max maximum offset in the list
605 add_list a zero-terminated list to be added
607 Returns: TRUE if OK; FALSE if list overflows
611 add_priority(int *list
, int list_max
, int *add_list
)
614 while (list
[next
] != 0) next
++;
615 while (*add_list
!= 0)
617 if (next
>= list_max
) return FALSE
;
618 list
[next
++] = *add_list
++;
626 /*************************************************
627 * Adjust a priority list *
628 *************************************************/
630 /* This function is called to adjust the lists of cipher algorithms, MAC
631 algorithms, key-exchange methods, and protocols.
634 plist the appropriate priority list
635 psize the length of the list
636 s the configuation string
637 index the index of recognized strings
638 isize the length of the index
641 which text for an error message
643 Returns: FALSE if the table overflows, else TRUE
647 set_priority(int *plist
, int psize
, uschar
*s
, pri_item
*index
, int isize
,
654 while ((t
= string_nextinlist(&s
, &sep
, big_buffer
, big_buffer_size
)) != NULL
)
657 BOOL exclude
= t
[0] == '!';
658 if (first
&& !exclude
) plist
[0] = 0;
660 for (i
= 0; i
< isize
; i
++)
662 uschar
*ss
= strstric(t
, index
[i
].name
, FALSE
);
665 uschar
*endss
= ss
+ Ustrlen(index
[i
].name
);
666 if ((ss
== t
|| !isalnum(ss
[-1])) && !isalnum(*endss
))
669 remove_priority(plist
, index
[i
].values
);
672 if (!add_priority(plist
, psize
, index
[i
].values
))
674 log_write(0, LOG_MAIN
|LOG_PANIC
, "GnuTLS init failed: %s "
675 "priority table overflow", which
);
687 debug_printf("adjusted %s priorities:", which
);
688 while (*ptr
!= 0) debug_printf(" %d", *ptr
++);
698 /*************************************************
699 * Initialize a single GNUTLS session *
700 *************************************************/
702 /* Set the algorithm, the db backend, whether to request certificates etc.
704 TLS in Exim was first implemented using OpenSSL. This has a function to which
705 you pass a list of cipher suites that are permitted/not permitted. GnuTLS works
706 differently. It operates using priority lists for the different components of
709 For compatibility of configuration, we scan a list of cipher suites and set
710 priorities therefrom. However, at the moment, we pay attention only to the bulk
714 side one of GNUTLS_SERVER, GNUTLS_CLIENT
715 expciphers expanded ciphers list or NULL
716 expmac expanded MAC list or NULL
717 expkx expanded key-exchange list or NULL
718 expproto expanded protocol list or NULL
720 Returns: a gnutls_session, or NULL if there is a problem
723 static gnutls_session
724 tls_session_init(int side
, uschar
*expciphers
, uschar
*expmac
, uschar
*expkx
,
727 gnutls_session session
;
729 gnutls_init(&session
, side
);
731 /* Initialize the lists of permitted protocols, key-exchange methods, ciphers,
734 memcpy(cipher_priority
, default_cipher_priority
, sizeof(cipher_priority
));
735 memcpy(mac_priority
, default_mac_priority
, sizeof(mac_priority
));
736 memcpy(kx_priority
, default_kx_priority
, sizeof(kx_priority
));
737 memcpy(proto_priority
, default_proto_priority
, sizeof(proto_priority
));
739 /* The names OpenSSL uses in tls_require_ciphers are of the form DES-CBC3-SHA,
740 using hyphen separators. GnuTLS uses underscore separators. So that I can use
741 either form for tls_require_ciphers in my tests, and also for general
742 convenience, we turn hyphens into underscores before scanning the list. */
744 if (expciphers
!= NULL
)
746 uschar
*s
= expciphers
;
747 while (*s
!= 0) { if (*s
== '-') *s
= '_'; s
++; }
750 if ((expciphers
!= NULL
&&
751 !set_priority(cipher_priority
, sizeof(cipher_priority
)/sizeof(int),
752 expciphers
, cipher_index
, sizeof(cipher_index
)/sizeof(pri_item
),
755 !set_priority(mac_priority
, sizeof(mac_priority
)/sizeof(int),
756 expmac
, mac_index
, sizeof(mac_index
)/sizeof(pri_item
),
759 !set_priority(kx_priority
, sizeof(kx_priority
)/sizeof(int),
760 expkx
, kx_index
, sizeof(kx_index
)/sizeof(pri_item
),
761 US
"key-exchange")) ||
763 !set_priority(proto_priority
, sizeof(proto_priority
)/sizeof(int),
764 expproto
, proto_index
, sizeof(proto_index
)/sizeof(pri_item
),
767 gnutls_deinit(session
);
771 /* Define the various priorities */
773 gnutls_cipher_set_priority(session
, cipher_priority
);
774 gnutls_compression_set_priority(session
, comp_priority
);
775 gnutls_kx_set_priority(session
, kx_priority
);
776 gnutls_protocol_set_priority(session
, proto_priority
);
777 gnutls_mac_set_priority(session
, mac_priority
);
779 gnutls_cred_set(session
, GNUTLS_CRD_CERTIFICATE
, x509_cred
);
781 gnutls_dh_set_prime_bits(session
, DH_BITS
);
783 /* Request or demand a certificate of the peer, as configured. This will
784 happen only in a server. */
786 if (verify_requirement
!= VERIFY_NONE
)
787 gnutls_certificate_server_set_request(session
,
788 (verify_requirement
== VERIFY_OPTIONAL
)?
789 GNUTLS_CERT_REQUEST
: GNUTLS_CERT_REQUIRE
);
791 gnutls_db_set_cache_expiration(session
, ssl_session_timeout
);
793 /* Reduce security in favour of increased compatibility, if the admin
794 decides to make that trade-off. */
795 if (gnutls_compat_mode
)
797 #if LIBGNUTLS_VERSION_NUMBER >= 0x020104
798 DEBUG(D_tls
) debug_printf("lowering GnuTLS security, compatibility mode\n");
799 gnutls_session_enable_compatibility_mode(session
);
801 DEBUG(D_tls
) debug_printf("Unable to set gnutls_compat_mode - GnuTLS version too old\n");
805 DEBUG(D_tls
) debug_printf("initialized GnuTLS session\n");
811 /*************************************************
812 * Get name of cipher in use *
813 *************************************************/
815 /* The answer is left in a static buffer, and tls_cipher is set to point
818 Argument: pointer to a GnuTLS session
823 construct_cipher_name(gnutls_session session
)
825 static uschar cipherbuf
[256];
827 int bits
, c
, kx
, mac
;
830 US
gnutls_protocol_get_name(gnutls_protocol_get_version(session
)));
831 if (Ustrncmp(ver
, "TLS ", 4) == 0) ver
[3] = '-'; /* Don't want space */
833 c
= gnutls_cipher_get(session
);
834 bits
= gnutls_cipher_get_key_size(c
);
836 mac
= gnutls_mac_get(session
);
837 kx
= gnutls_kx_get(session
);
839 string_format(cipherbuf
, sizeof(cipherbuf
), "%s:%s:%u", ver
,
840 gnutls_cipher_suite_get_name(kx
, c
, mac
), bits
);
841 tls_cipher
= cipherbuf
;
843 DEBUG(D_tls
) debug_printf("cipher: %s\n", cipherbuf
);
848 /*************************************************
849 * Start a TLS session in a server *
850 *************************************************/
852 /* This is called when Exim is running as a server, after having received
853 the STARTTLS command. It must respond to that command, and then negotiate
857 require_ciphers list of allowed ciphers or NULL
858 require_mac list of allowed MACs or NULL
859 require_kx list of allowed key_exchange methods or NULL
860 require_proto list of allowed protocols or NULL
862 Returns: OK on success
863 DEFER for errors before the start of the negotiation
864 FAIL for errors during the negotation; the server can't
869 tls_server_start(uschar
*require_ciphers
, uschar
*require_mac
,
870 uschar
*require_kx
, uschar
*require_proto
)
874 uschar
*expciphers
= NULL
;
875 uschar
*expmac
= NULL
;
876 uschar
*expkx
= NULL
;
877 uschar
*expproto
= NULL
;
879 /* Check for previous activation */
883 tls_error("STARTTLS received after TLS started", NULL
, "");
884 smtp_printf("554 Already in TLS\r\n");
888 /* Initialize the library. If it fails, it will already have logged the error
889 and sent an SMTP response. */
891 DEBUG(D_tls
) debug_printf("initializing GnuTLS as a server\n");
893 rc
= tls_init(NULL
, tls_certificate
, tls_privatekey
, tls_verify_certificates
,
895 if (rc
!= OK
) return rc
;
897 if (!expand_check(require_ciphers
, US
"tls_require_ciphers", &expciphers
) ||
898 !expand_check(require_mac
, US
"gnutls_require_mac", &expmac
) ||
899 !expand_check(require_kx
, US
"gnutls_require_kx", &expkx
) ||
900 !expand_check(require_proto
, US
"gnutls_require_proto", &expproto
))
903 /* If this is a host for which certificate verification is mandatory or
904 optional, set up appropriately. */
906 tls_certificate_verified
= FALSE
;
907 verify_requirement
= VERIFY_NONE
;
909 if (verify_check_host(&tls_verify_hosts
) == OK
)
910 verify_requirement
= VERIFY_REQUIRED
;
911 else if (verify_check_host(&tls_try_verify_hosts
) == OK
)
912 verify_requirement
= VERIFY_OPTIONAL
;
914 /* Prepare for new connection */
916 tls_session
= tls_session_init(GNUTLS_SERVER
, expciphers
, expmac
, expkx
,
918 if (tls_session
== NULL
)
919 return tls_error(US
"tls_session_init", NULL
,
920 gnutls_strerror(GNUTLS_E_MEMORY_ERROR
));
922 /* Set context and tell client to go ahead, except in the case of TLS startup
923 on connection, where outputting anything now upsets the clients and tends to
924 make them disconnect. We need to have an explicit fflush() here, to force out
925 the response. Other smtp_printf() calls do not need it, because in non-TLS
926 mode, the fflush() happens when smtp_getc() is called. */
930 smtp_printf("220 TLS go ahead\r\n");
934 /* Now negotiate the TLS session. We put our own timer on it, since it seems
935 that the GnuTLS library doesn't. */
937 gnutls_transport_set_ptr2(tls_session
, (gnutls_transport_ptr
)fileno(smtp_in
),
938 (gnutls_transport_ptr
)fileno(smtp_out
));
940 sigalrm_seen
= FALSE
;
941 if (smtp_receive_timeout
> 0) alarm(smtp_receive_timeout
);
942 rc
= gnutls_handshake(tls_session
);
947 tls_error(US
"gnutls_handshake", NULL
,
948 sigalrm_seen
? "timed out" : gnutls_strerror(rc
));
950 /* It seems that, except in the case of a timeout, we have to close the
951 connection right here; otherwise if the other end is running OpenSSL it hangs
952 until the server times out. */
956 (void)fclose(smtp_out
);
957 (void)fclose(smtp_in
);
963 DEBUG(D_tls
) debug_printf("gnutls_handshake was successful\n");
965 if (verify_requirement
!= VERIFY_NONE
&&
966 !verify_certificate(tls_session
, &error
))
968 tls_error(US
"certificate verification failed", NULL
, error
);
972 construct_cipher_name(tls_session
);
974 /* TLS has been set up. Adjust the input functions to read via TLS,
975 and initialize appropriately. */
977 ssl_xfer_buffer
= store_malloc(ssl_xfer_buffer_size
);
978 ssl_xfer_buffer_lwm
= ssl_xfer_buffer_hwm
= 0;
979 ssl_xfer_eof
= ssl_xfer_error
= 0;
981 receive_getc
= tls_getc
;
982 receive_ungetc
= tls_ungetc
;
983 receive_feof
= tls_feof
;
984 receive_ferror
= tls_ferror
;
985 receive_smtp_buffered
= tls_smtp_buffered
;
987 tls_active
= fileno(smtp_out
);
995 /*************************************************
996 * Start a TLS session in a client *
997 *************************************************/
999 /* Called from the smtp transport after STARTTLS has been accepted.
1002 fd the fd of the connection
1003 host connected host (for messages)
1004 addr the first address (not used)
1005 dhparam DH parameter file
1006 certificate certificate file
1007 privatekey private key file
1008 verify_certs file for certificate verify
1009 verify_crl CRL for verify
1010 require_ciphers list of allowed ciphers or NULL
1011 require_mac list of allowed MACs or NULL
1012 require_kx list of allowed key_exchange methods or NULL
1013 require_proto list of allowed protocols or NULL
1014 timeout startup timeout
1016 Returns: OK/DEFER/FAIL (because using common functions),
1017 but for a client, DEFER and FAIL have the same meaning
1021 tls_client_start(int fd
, host_item
*host
, address_item
*addr
, uschar
*dhparam
,
1022 uschar
*certificate
, uschar
*privatekey
, uschar
*verify_certs
,
1023 uschar
*verify_crl
, uschar
*require_ciphers
, uschar
*require_mac
,
1024 uschar
*require_kx
, uschar
*require_proto
, int timeout
)
1026 const gnutls_datum
*server_certs
;
1027 uschar
*expciphers
= NULL
;
1028 uschar
*expmac
= NULL
;
1029 uschar
*expkx
= NULL
;
1030 uschar
*expproto
= NULL
;
1032 unsigned int server_certs_size
;
1035 DEBUG(D_tls
) debug_printf("initializing GnuTLS as a client\n");
1037 verify_requirement
= (verify_certs
== NULL
)? VERIFY_NONE
: VERIFY_REQUIRED
;
1038 rc
= tls_init(host
, certificate
, privatekey
, verify_certs
, verify_crl
);
1039 if (rc
!= OK
) return rc
;
1041 if (!expand_check(require_ciphers
, US
"tls_require_ciphers", &expciphers
) ||
1042 !expand_check(require_mac
, US
"gnutls_require_mac", &expmac
) ||
1043 !expand_check(require_kx
, US
"gnutls_require_kx", &expkx
) ||
1044 !expand_check(require_proto
, US
"gnutls_require_proto", &expproto
))
1047 tls_session
= tls_session_init(GNUTLS_CLIENT
, expciphers
, expmac
, expkx
,
1050 if (tls_session
== NULL
)
1051 return tls_error(US
"tls_session_init", host
,
1052 gnutls_strerror(GNUTLS_E_MEMORY_ERROR
));
1054 gnutls_transport_set_ptr(tls_session
, (gnutls_transport_ptr
)fd
);
1056 /* There doesn't seem to be a built-in timeout on connection. */
1058 sigalrm_seen
= FALSE
;
1060 rc
= gnutls_handshake(tls_session
);
1064 return tls_error(US
"gnutls_handshake", host
,
1065 sigalrm_seen
? "timed out" : gnutls_strerror(rc
));
1067 server_certs
= gnutls_certificate_get_peers(tls_session
, &server_certs_size
);
1069 if (server_certs
!= NULL
)
1072 gnutls_x509_crt gcert
;
1074 gnutls_x509_crt_init(&gcert
);
1075 tls_peerdn
= US
"unknown";
1077 if (gnutls_x509_crt_import(gcert
, server_certs
, GNUTLS_X509_FMT_DER
) == 0)
1079 size_t bufsize
= sizeof(buff
);
1080 if (gnutls_x509_crt_get_dn(gcert
, CS buff
, &bufsize
) >= 0)
1081 tls_peerdn
= string_copy_malloc(buff
);
1085 /* Should we also verify the hostname here? */
1087 if (verify_requirement
!= VERIFY_NONE
&&
1088 !verify_certificate(tls_session
, &error
))
1089 return tls_error(US
"certificate verification failed", host
, error
);
1091 construct_cipher_name(tls_session
); /* Sets tls_cipher */
1098 /*************************************************
1099 * Deal with logging errors during I/O *
1100 *************************************************/
1102 /* We have to get the identity of the peer from saved data.
1105 ec the GnuTLS error code, or 0 if it's a local error
1106 when text identifying read or write
1107 text local error text when ec is 0
1113 record_io_error(int ec
, uschar
*when
, uschar
*text
)
1117 if (ec
== GNUTLS_E_FATAL_ALERT_RECEIVED
)
1118 msg
= string_sprintf("%s: %s", gnutls_strerror(ec
),
1119 gnutls_alert_get_name(gnutls_alert_get(tls_session
)));
1121 msg
= gnutls_strerror(ec
);
1123 tls_error(when
, client_host
, msg
);
1128 /*************************************************
1129 * TLS version of getc *
1130 *************************************************/
1132 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
1133 it refills the buffer via the GnuTLS reading function.
1136 Returns: the next character or EOF
1142 if (ssl_xfer_buffer_lwm
>= ssl_xfer_buffer_hwm
)
1146 DEBUG(D_tls
) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1147 (long) tls_session
, (long) ssl_xfer_buffer
, ssl_xfer_buffer_size
);
1149 if (smtp_receive_timeout
> 0) alarm(smtp_receive_timeout
);
1150 inbytes
= gnutls_record_recv(tls_session
, CS ssl_xfer_buffer
,
1151 ssl_xfer_buffer_size
);
1154 /* A zero-byte return appears to mean that the TLS session has been
1155 closed down, not that the socket itself has been closed down. Revert to
1156 non-TLS handling. */
1160 DEBUG(D_tls
) debug_printf("Got TLS_EOF\n");
1162 receive_getc
= smtp_getc
;
1163 receive_ungetc
= smtp_ungetc
;
1164 receive_feof
= smtp_feof
;
1165 receive_ferror
= smtp_ferror
;
1166 receive_smtp_buffered
= smtp_buffered
;
1168 gnutls_deinit(tls_session
);
1177 /* Handle genuine errors */
1179 else if (inbytes
< 0)
1181 record_io_error(inbytes
, US
"recv", NULL
);
1185 #ifndef DISABLE_DKIM
1186 dkim_exim_verify_feed(ssl_xfer_buffer
, inbytes
);
1188 ssl_xfer_buffer_hwm
= inbytes
;
1189 ssl_xfer_buffer_lwm
= 0;
1193 /* Something in the buffer; return next uschar */
1195 return ssl_xfer_buffer
[ssl_xfer_buffer_lwm
++];
1200 /*************************************************
1201 * Read bytes from TLS channel *
1202 *************************************************/
1209 Returns: the number of bytes read
1210 -1 after a failed read
1214 tls_read(uschar
*buff
, size_t len
)
1218 DEBUG(D_tls
) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1219 (long) tls_session
, (long) buff
, len
);
1221 inbytes
= gnutls_record_recv(tls_session
, CS buff
, len
);
1222 if (inbytes
> 0) return inbytes
;
1225 DEBUG(D_tls
) debug_printf("Got TLS_EOF\n");
1227 else record_io_error(inbytes
, US
"recv", NULL
);
1234 /*************************************************
1235 * Write bytes down TLS channel *
1236 *************************************************/
1243 Returns: the number of bytes after a successful write,
1244 -1 after a failed write
1248 tls_write(const uschar
*buff
, size_t len
)
1253 DEBUG(D_tls
) debug_printf("tls_do_write(%lx, %d)\n", (long) buff
, left
);
1256 DEBUG(D_tls
) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff
,
1258 outbytes
= gnutls_record_send(tls_session
, CS buff
, left
);
1260 DEBUG(D_tls
) debug_printf("outbytes=%d\n", outbytes
);
1263 record_io_error(outbytes
, US
"send", NULL
);
1268 record_io_error(0, US
"send", US
"TLS channel closed on write");
1281 /*************************************************
1282 * Close down a TLS session *
1283 *************************************************/
1285 /* This is also called from within a delivery subprocess forked from the
1286 daemon, to shut down the TLS library, without actually doing a shutdown (which
1287 would tamper with the TLS session in the parent process).
1289 Arguments: TRUE if gnutls_bye is to be called
1294 tls_close(BOOL shutdown
)
1296 if (tls_active
< 0) return; /* TLS was not active */
1300 DEBUG(D_tls
) debug_printf("tls_close(): shutting down TLS\n");
1301 gnutls_bye(tls_session
, GNUTLS_SHUT_WR
);
1304 gnutls_deinit(tls_session
);
1306 gnutls_global_deinit();
1314 /*************************************************
1315 * Report the library versions. *
1316 *************************************************/
1318 /* See a description in tls-openssl.c for an explanation of why this exists.
1320 Arguments: a FILE* to print the results to
1325 tls_version_report(FILE *f
)
1327 fprintf(f
, "Library version: GnuTLS: Compile: %s\n"
1330 gnutls_check_version(NULL
));
1333 /* End of tls-gnu.c */