JSON: add iterative conditions for arrays
[exim.git] / doc / doc-txt / GnuTLS-FAQ.txt
CommitLineData
51fb80db
PP
1Using Exim 4.80+ with GnuTLS
2============================
3
4(1) I'm having problems building with GnuTLS 1, why?
5(2) What changed? Why?
6(3) I'm seeing:
7 "(gnutls_handshake): A TLS packet with unexpected length was received"
8 Why?
51701a1d 9(4) What's the deal with MD5? (And SHA-1?)
51fb80db
PP
10(5) What happened to gnutls_require_kx / gnutls_require_mac /
11 gnutls_require_protocols?
12(6) What's the deal with tls_dh_max_bits? What's DH?
13(7) What's a Priority String?
14(8) How do I use tls_require_ciphers?
15(9) How do I test STARTTLS support?
16
17
18
19(1): I'm having problems building with GnuTLS 1, why?
20-----------------------------------------------------
21
22GnuTLS's library interface has changed and Exim uses the more current
23interface. Since GnuTLS is security critical code, you should probably update
24to a supported release.
25
26If updating GnuTLS is not an option, then build Exim against OpenSSL instead.
27
28If neither is an option, then you might build Exim with the rule
29"SUPPORT_TLS=yes" commented out in "Local/Makefile", so that your Exim build
30no longer has TLS support.
31
32If you need to keep TLS support, and you can't use OpenSSL, then you'll have
33to update the GnuTLS you have installed. Sorry.
34
35We've tested the build of Exim back as far as GnuTLS 2.8.x; most development
36work is done with 2.12 and tested on 2.10 and 3.x.
37
38If you have to pick a version to upgrade to, use GnuTLS 3.x if available. The
39GnuTLS developers took advantage of the version bump to add an error code
40return value which makes debugging some problems a lot easier.
41
42
43
44(2): What changed? Why?
45------------------------
46
47The GnuTLS provider integration in Exim was overhauled, rewritten but with
48some copy/paste, because building Exim against more current releases of GnuTLS
49was issuing deprecation warnings from the compiler.
50
51When a library provider marks up the include files so that some function calls
52will cause the compiler/linker to emit deprecation warnings, it's time to pay
53serious attention. A future release might not work at all. Using the new
54APIs may mean that Exim will *stop* working with older releases of GnuTLS.
55The GnuTLS support in Exim was overhauled in Exim 4.80. In prior releases,
56Exim hard-coded a lot of algorithms and constrained what could happen. In
57Exim 4.79, we added to the hard-coded list just enough to let TLSv1.1 and
58TLSv1.2 be negotiated, but not actually support the mandatory algorithms of
59those protocol versions. When Exim's GnuTLS integration was originally
60written, there was no other choice than to make Exim responsible for a lot of
61this. In the meantime, GnuTLS has improved.
62
63With the rewrite, we started using the current API and leaving a lot more
64responsibility for TLS decisions to the library.
65
66The GnuTLS developers added "priority strings" (see Q7), which provide an
67interface exposed to the configuration file for a lot of the tuning.
68
69The GnuTLS policy is to no longer support MD5 in certificates. Exim had
70previously been immune to this policy, but no longer. See Q4.
71
72
73
74(3): I'm seeing "A TLS packet with unexpected length was received". Why?
75-------------------------------------------------------------------------
76
77The most likely reason is that the client dropped the connection during
78handshake, because their library disliked some aspect of the negotiation.
79
80In GnuTLS 2, an EOF on the connection is reported with an error code for
81packets being too large, and the above is the string returned by the library
82for that error code. In GnuTLS 3, there's a specific error code for EOF and
83the diagnostic will be less confusing.
84
85Most likely cause is an MD5 hash used in a certificate. See Q4 below.
86Alternatively, the client dislikes the size of the Diffie-Hellman prime
87offered by the server; if lowering the value of the "tls_dh_max_bits" Exim
88option fixes the problem, this was the cause. See Q6.
89
90
91
51701a1d
PP
92(4): What's the deal with MD5? (And SHA-1?)
93--------------------------------------------
51fb80db
PP
94
95MD5 is a hash algorithm. Hash algorithms are used to reduce a lot of data
96down to a fairly short value, which is supposed to be extremely hard to
97manipulate to get a value of someone's choosing. Signatures, used to attest
98to identity or integrity, rely upon this manipulation being effectively
99impossible, because the signature is the result of math upon the hash result.
100Without hash algorithms, signatures would be longer than the text being
101signed.
102
103MD5 was once very popular. It still is far too popular. Real world attacks
104have been proven possible against MD5. Including an attack against PKI
105(Public Key Infrastructure) certificates used for SSL/TLS. In that attack,
8d68e115
PP
106the attackers got a certificate for one identity but were able to then publish
107a certificate with the same signature but a different identity. This
108undermines the whole purpose of having certificates.
51fb80db
PP
109
110So GnuTLS stopped trusting any certificate with an MD5-based hash used in it.
111The world has been hurriedly moving away from MD5 in certificates for a while.
112If you still have such a certificate, you should move too.
113
114If you paid someone for your certificate, they should be willing to reissue
115the certificate with a different algorithm, for no extra money. If they try
116to charge money to replace their defective product, buy from someone else
117instead. Part of the reason for paying money on a recurring basis is to cover
118the ongoing costs of proving a trust relationship, such as providing
119revocation protocols. This is just another of those ongoing costs you have
120already paid for.
121
51701a1d
PP
122The same has happened to SHA-1: there are real-world collision attacks against
123SHA-1, so SHA-1 is mostly defunct in certificates. GnuTLS no longer supports
124its use in TLS certificates.
125
51fb80db
PP
126
127
128(5): ... gnutls_require_kx / gnutls_require_mac / gnutls_require_protocols?
129---------------------------------------------------------------------------
130
131These Exim options were used to provide fine-grained control over the TLS
132negotiation performed by GnuTLS. They required explicit protocol knowledge
133from Exim, which vastly limited what GnuTLS could do and involved the Exim
134maintainers in decisions which aren't part of their professional areas of
135expertise. The need for Exim to be able to do this went away when GnuTLS
136introduced Priority Strings (see Q7).
137
138If you were using these options before, then you're already an expert user and
139should be able to easily craft a priority string to accomplish your goals.
140Set the Exim "tls_require_ciphers" value accordingly. There is a main section
141option of this name, used for Exim receiving inbound connections, and an SMTP
142driver transport option of this name, used for Exim establishing outbound
143connections.
144
145
146
147(6): What's the deal with tls_dh_max_bits? What's DH?
148------------------------------------------------------
149
a799883d
PP
150You can avoid all of the tls_dh_max_bits issues if you leave "tls_dhparam"
151unset, so that you get one of the standard built-in primes used for DH.
152
153
51fb80db
PP
154DH, Diffie-Hellman (or Diffie-Hellman-Merkle, or something naming Williamson)
155is the common name for a way for two parties to a communication stream to
156exchange some private random data so that both end up with a shared secret
8d68e115 157which no eavesdropper can get. It does not provide for proof of the identity
51fb80db
PP
158of either party, so on its own is subject to man-in-the-middle attacks, but is
159often combined with systems which do provide such proof, improving them by
160separating the session key (the shared secret) from the long-term identity,
161and so protecting past communications from a break of the long-term identity.
162
163To do this, the server sends to the client a very large prime number; this is
164in the clear, an attacker can see it. This is not a problem; it's so not a
165problem, that there are standard named primes which applications can use, and
8d68e115 166which Exim now supports.
51fb80db
PP
167
168The size of the prime number affects how difficult it is to break apart the
169shared secret and decrypt the data. As time passes, the size required to
170provide protection against an adversary climbs: computers get more powerful,
171mathematical advances are made, and so on.
172
173Estimates of the size needed are published as recommendations by various
174groups; a good summary of sizes currently recommended, for various
175cryptographic primitives, is available at:
176
177 http://www.keylength.com/en/3/
178
179The GnuTLS folks think the ECRYPT II advice is good. They know far more of
180such matters than the Exim folks, we just say "er, what they said".
181
182One of the new pieces of the GnuTLS API is a means for an application to ask
183it for guidance and advice on how large some numbers should be. This is not
8d68e115 184entirely internal to GnuTLS, since generating the numbers is slow, an
51fb80db
PP
185application might want to use a standard prime, etc. So, in an attempt to get
186away from being involved in cryptographic policy, and to get rid of a
187hard-coded "1024" in Exim's source-code, we switched to asking GnuTLS how many
8d68e115
PP
188bits should be in the prime number generated for use for Diffie-Hellman. We
189then give this number straight back to GnuTLS when generating a DH prime.
190We can ask for various sizes, and did not expose this to the administrator but
191instead just asked for "NORMAL" protection.
51fb80db
PP
192Literally:
193
194 dh_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_NORMAL);
195
196This API is only available as of GnuTLS 2.12. Prior to that release, we stuck
197with the old value, for compatibility, so "1024" is still hard-coded.
198Reviewing the page above, you'll see that this is described as "Short-term
199protection against medium organizations, medium-term protection against small
200organizations."
201
202So if you are using an old release of GnuTLS, you can either add to
203Local/Makefile a different value of "EXIM_SERVER_DH_BITS_PRE2_12" or accept
204that your protection might not be adequate to your needs. We advise updating
205to a more current GnuTLS release and rebuilding Exim against that.
206
207Unfortunately, some TLS libraries have the client side bound how large a DH
208prime they will accept from the server. The larger the number, the more
209computation required to work with it and the slower that things get. So they
210pick what they believe to be reasonable upper bounds, and then typically
211forget about it for several years.
212
213Worse, in TLS the DH negotiation happens after a ciphersuite has been chosen,
214so if the client dislikes the value then a different ciphersuite avoiding DH
215can not be negotiated! The client typically drops the connection, resulting
216in errors to the user and errors in the Exim logs. With GnuTLS 3, you'll see
217the EOF (End-Of-File) error message in Exim's logs, reported as being part of
218"gnutls_handshake", but with GnuTLS 2 you'll see a log message about a packet
219with an unexpected size. Unless the client software is written intelligently
220enough to be able to adapt and reconnect forbidding DH, the client will never
221be able to negotiate TLS.
222
223This time around, we discovered that the NSS library used by various Mozilla
224products, Chrome, etc, and most particularly by the Thunderbird mail client,
225has the lowest cap. In fact, prior to recent updates, their upper limit was
226lower than the value returned by GnuTLS for "NORMAL". The most recent NSS
227library release raises this, but the most recent Thunderbird release still has
228the old limit.
229
230So Exim had to get involved in cryptography policy decisions again. We added
231the "tls_dh_max_bits" global option, to set a number used in both OpenSSL and
232GnuTLS bindings for Exim. In GnuTLS, it clamps the value returned by
233gnutls_sec_param_to_pk_bits(), so that if the returned value is larger than
234tls_dh_max_bits then tls_dh_max_bits would be used instead.
235
236Our policy decision was to default the value of tls_dh_max_bits to the maximum
237supported in the most recent Thunderbird release, and to make this an
238administrator-available option so that administrators can choose to trade off
239security versus compatibility by raising it.
240
241A future release of Exim may even let the administrator tell GnuTLS to ask for
242more or less than "NORMAL".
243
201f5254
PP
244To add to the fun, the size of the prime returned by GnuTLS when we call
245gnutls_dh_params_generate2() is not limited to be the requested size. GnuTLS
246has a tendency to overshoot. 2237 bit primes are common when 2236 is
247requested, and higher still have been observed. Further, there is no API to
248ask how large the prime bundled up inside the parameter is; the most we can do
249is ask how large the DH prime used in an active TLS session is. Since we're
250not able to use GnuTLS API calls (and exporting to PKCS3 and then calling
251OpenSSL routines would be undiplomatic, plus add a library dependency), we're
252left with no way to actually know the size of the freshly generated DH prime.
253
254Thus we check if the the value returned is at least 10 more than the minimum
255we'll accept as a client (EXIM_CLIENT_DH_MIN_BITS, see below, defaults to
bba74fc6 2561024) and if it is, we subtract 10. Then we reluctantly deploy a strategy
201f5254
PP
257called "hope". This is not guaranteed to be successful; in the first code
258pass on this logic, we subtracted 3, asked for 2233 bits and got 2240 in the
259first test.
260
261If you see Thunderbird clients still failing, then as a user who can see into
262Exim's spool directory, run:
263
264$ openssl dhparam -noout -text -in /path/to/spool/gnutls-params-2236 | head
265
266Ideally, the first line will read "PKCS#3 DH Parameters: (2236 bit)". If the
267count is more than 2236, then remove the file and let Exim regenerate it, or
268generate one yourself and move it into place. Ideally use "openssl dhparam"
269to generate it, and then wait a very long time; at least this way, the size
a799883d
PP
270will be correct.
271
272The use of "hope" as a strategy was felt to be unacceptable as a default, so
273late in the RC series for 4.80, the whole issue was side-stepped. The primes
274used for DH are publicly revealed; moreover, there are selection criteria for
275what makes a "good" DH prime. As it happens, there are *standard* primes
276which can be used, and are specified to be used for certain protocols. So
277these primes were built into Exim, and by default exim now uses a 2048 bit
278prime from section 2.2 of RFC 5114.
201f5254
PP
279
280
51fb80db
PP
281A TLS client does not get to choose the DH prime used, but can choose a
282minimum acceptable value. For Exim, this is a compile-time constant called
bba74fc6 283"EXIM_CLIENT_DH_MIN_BITS" of 1024, which can be overruled in "Local/Makefile".
51fb80db
PP
284
285
286
287(7): What's a Priority String?
288------------------------------
289
290A priority string is a way for a user of GnuTLS to tell GnuTLS how it should
291make decisions about what to do in TLS; it includes which algorithms to make
292available for various roles, what compatibility trade-offs to make, which
293features to enable or disable.
294
295It is exposed to the Mail Administrator in Exim's configuration file as the
296"tls_require_ciphers" option, which exists as a main section option for use in
297Exim as a server, accepting connections, and as an option on Transports using
298the SMTP driver, for use in Exim as a client. The main section option is
299*not* the default for the transport option, they are entirely independent.
300For both, the default value used by Exim is the string "NORMAL". (This is not
301the same NORMAL as for DH prime bit size selection in Q6, but a different
302NORMAL.) See Q8.
303
304The current documentation, for the most recent release of GnuTLS, is available
305online at:
306
42bfef1e 307 http://www.gnutls.org/manual/html_node/Priority-Strings.html
51fb80db
PP
308
309Beware that if you are not using the most recent GnuTLS release then this
310documentation will be wrong for you! You should find the "info" documentation
311which came with GnuTLS to review the available options. It's under "The TLS
312Handshake Protocol".
313
314$ pinfo --node="Priority Strings" gnutls
315
316(This author is unable to persuade the "info" command-line tool to jump
317straight to the required node, but "pinfo" works.)
318
319To trade off some security for more compatibility, you might set a value of
320"NORMAL:%COMPAT". See the documentation for more, including lowering security
321even further for more security, forcing clients to use the server's protocol
322suite, and ways to force selection of particular algorithms.
323
324
325
326(8): How do I use tls_require_ciphers?
327--------------------------------------
328
329This is the name of two options in Exim. One is a main section option, used
330by Exim as a server when a client initiates SSL/TLS negotiation, the other is
331an option on transports which use "driver = smtp", used when Exim initiates
332SSL/TLS as a client talking to a remote server.
333
334The option is expanded and so can take advantage of any variables which have
335been set. This includes the IP address of the remote side, the port upon
336which a connection was accepted (when a server), and more. Currently it does
337not have access to $tls_sni, whether as a client or as a server.
338
339This example, for the main section's option, will let the library defaults be
340permitted on the MX port, where there's probably no identity verification
341anyway, and lowers security further by increasing compatibility; but this ups
342the ante on the submission ports where the administrator might have some
343influence on the choice of clients used:
344
345tls_require_ciphers = ${if =={$received_port}{25}\
346 {NORMAL:%COMPAT}\
347 {SECURE128}}
348
349Note that during Exim start-up, when this option is sanity-checked, there will
350be no value of $received_port. In the above example, the checked value will
351thus be "SECURE128". Be careful to ensure that it always expands safely.
352
353
354
355(9): How do I test STARTTLS support?
356------------------------------------
357
358The best command-line client for debugging specifically SSL/TLS which this
359author has encountered is part of the GnuTLS suite, and is called
360"gnutls-cli". It's best because it's the only interactive tool which lets the
361user start TLS handshake exactly when they wish, so can choose to use the
362STARTTLS command.
363
364$ gnutls-cli --starttls --crlf --port 587 mail.example.org
365
366After EHLO, to see the capabilities, enter STARTTLS, wait for the response,
367then send EOF. Typically that's done by typing Ctrl-D at the start of a line.
368The "gnutls-cli" tool will take over, set up TLS (or fail) and by the time it
369returns to await more user input, you're using a secure connection and should
370type your second EHLO.
371
372The "--x509cafile" option may be helpful for checking certificates and
373"--priority" to pass a priority string to the client tool for configuring it.
374
375The --crlf is for strict protocol correctness, but Exim doesn't really need
376it, so "gnutls-cli -s -p 587 mail.example.org" is shorter.
377
378
379For debugging SMTP as a whole, we recommend swaks, "Swiss Army Knife SMTP", by
380John Jetmore (one of the Exim Maintainers). This has some TLS tuning options;
381it can be found at:
382
383 http://www.jetmore.org/john/code/swaks/
384
385
386For OpenSSL, the "openssl s_client" command helps; you can either set up Exim
387with a listening port which is SSL-on-connect or tell s_client to use
388STARTTLS.
389
390For the former, use the "tls_on_connect_ports" option and the
391"daemon_smtp_ports" option. Most clients for SSL-on-connect use the port
392which was briefly registered with IANA for this purpose, 465. So you would
393set something like:
394
395 daemon_smtp_ports = 25 : 465 : 587
396 tls_on_connect_ports = 465
397
398To use s_client with STARTTLS support, use "-starttls smtp" on the
399command-line. Beware that older versions of OpenSSL did not wait for the SMTP
400banner before sending EHLO, which will fall afoul of the protocol
401synchronisation checks in Exim (used to trip up pump-and-dump spammers); also
402you will not get control of the session until TLS is established. That said,
403this tool provides more tuning hooks for adjusting how TLS will be set up than
404most.
405
406*BEWARE* that by default, s_client will take any line starting with a capital
407letter "R" to be a request to initiate TLS renegotiation with the server and
408the line will not be sent. This may trip up "RCPT TO:<someone@example.org>"
409lines in SMTP. SMTP is not case-sensitive, so type "rcpt to" instead.
410Alternatively, invoke s_client with the "-ign_eof" option to disable this
411R-filtering and a few other features.
412
413
414# END OF FAQ