diff options
author | Phil Pennock <pdp@exim.org> | 2012-05-27 09:14:39 -0400 |
---|---|---|
committer | Phil Pennock <pdp@exim.org> | 2012-05-27 09:14:39 -0400 |
commit | a799883d8ad340d935db4d729a31c02cb8a1d977 (patch) | |
tree | 3ceb2a5d711c3430aba48a47cfed59c73d6ddda9 /src | |
parent | cae6e576b589efbe9e22cd65e5f890b21ce84f02 (diff) |
For DH, use standard primes from RFCs
Diffstat (limited to 'src')
-rw-r--r-- | src/OS/Makefile-Base | 3 | ||||
-rw-r--r-- | src/README.UPDATING | 15 | ||||
-rwxr-xr-x | src/scripts/MakeLinks | 1 | ||||
-rw-r--r-- | src/src/functions.h | 4 | ||||
-rw-r--r-- | src/src/std-crypto.c | 521 | ||||
-rw-r--r-- | src/src/tls-gnu.c | 59 | ||||
-rw-r--r-- | src/src/tls-openssl.c | 88 | ||||
-rw-r--r-- | src/util/gen_pkcs3.c | 229 |
8 files changed, 882 insertions, 38 deletions
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index de387e027..281294558 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -312,7 +312,7 @@ OBJ_EXIM = acl.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \ os.o parse.o queue.o \ rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o \ route.o search.o sieve.o smtp_in.o smtp_out.o spool_in.o spool_out.o \ - store.o string.o tls.o tod.o transport.o tree.o verify.o \ + std-crypto.o store.o string.o tls.o tod.o transport.o tree.o verify.o \ $(OBJ_LOOKUPS) \ local_scan.o $(EXIM_PERL) $(OBJ_WITH_CONTENT_SCAN) \ $(OBJ_WITH_OLD_DEMIME) $(OBJ_EXPERIMENTAL) @@ -575,6 +575,7 @@ smtp_in.o: $(HDRS) smtp_in.c smtp_out.o: $(HDRS) smtp_out.c spool_in.o: $(HDRS) spool_in.c spool_out.o: $(HDRS) spool_out.c +std-crypto.o: $(HDRS) std-crypto.c store.o: $(HDRS) store.c string.o: $(HDRS) string.c tls.o: $(HDRS) tls.c tls-gnu.c tls-openssl.c diff --git a/src/README.UPDATING b/src/README.UPDATING index a15bd418e..6a820bc7c 100644 --- a/src/README.UPDATING +++ b/src/README.UPDATING @@ -142,6 +142,21 @@ Exim version 4.80 fail completely. (The check is not done as root, to ensure that problems here are not made worse by the check). + * The "tls_dhparam" option has been updated, so that it can now specify a + path or an identifier for a standard DH prime from one of a few RFCs. + The default for OpenSSL is no longer to not use DH but instead to use + one of these standard primes. The default for GnuTLS is no longer to use + a file in the spool directory, but to use that same standard prime. + The option is now used by GnuTLS too. If it points to a path, then + GnuTLS will use that path, instead of a file in the spool directory; + GnuTLS will attempt to create it if it does not exist. + + To preserve the previous behaviour of generating files in the spool + directory, set "tls_dhparam = historic". Since prior releases of Exim + ignored tls_dhparam when using GnuTLS, this can safely be done before + the upgrade. + + Exim version 4.77 ----------------- diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index 166a25f88..62d248a3c 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -228,6 +228,7 @@ ln -s ../src/smtp_in.c smtp_in.c ln -s ../src/smtp_out.c smtp_out.c ln -s ../src/spool_in.c spool_in.c ln -s ../src/spool_out.c spool_out.c +ln -s ../src/std-crypto.c std-crypto.c ln -s ../src/store.c store.c ln -s ../src/string.c string.c ln -s ../src/tls.c tls.c diff --git a/src/src/functions.h b/src/src/functions.h index 160f5133e..29e7db2bd 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -21,6 +21,10 @@ extern uschar *init_perl(uschar *); #ifdef SUPPORT_TLS +extern const char * + std_dh_prime_default(void); +extern const char * + std_dh_prime_named(const uschar *); extern int tls_client_start(int, host_item *, address_item *, uschar *, uschar *, uschar *, uschar *, uschar *, uschar *, uschar *, int); diff --git a/src/src/std-crypto.c b/src/src/std-crypto.c new file mode 100644 index 000000000..3f0fec897 --- /dev/null +++ b/src/src/std-crypto.c @@ -0,0 +1,521 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) Phil Pennock 2012 + * But almost everything here is fixed published constants from RFCs, so also: + * Copyright (C) The Internet Society (2003) + * Copyright (C) The IETF Trust (2008) + * Most of the text in RFC referencing comments is copy/paste from RFC, + * as is undoubtedly the intention. + * The constants are generated from that text using util/gen_pkcs3.c invoked + * with the -C option. + */ + +/* See the file NOTICE for conditions of use and distribution. */ + +#include "exim.h" + +#ifndef SUPPORT_TLS +static void dummy(int x) { dummy(x-1); } +#else + +/* The IETF defines standard primes as "Modular Exponential (MODP) Groups" for +use in IKE in RFC 2409 and 3526, and then some more, "for Use with IETF +Standards" in RFC 5114. These have been thoroughly reviewed as meeting +certain eligibility criteria, which is more than can be said for primes +generated quickly on no particular criteria. + +Any prime used in TLS is disclosed publicly, and if the security of your +session depends upon the prime being secret, then one of three situations +holds: + (1) the prime is too small + (2) the prime is flawed, use one of these instead + (3) you know of fundamental cryptanalytic breaks not currently publicly known + to the cryptographic community. +*/ + +/* RFC 2409 MODP IKE_id=1 generator=2 bits=768 + The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } + Its hexadecimal value is + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 + E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_1_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MGYCYQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5siUUoI\n" +"eY40BN3vlRmzzTpDGzArCm3yXxQ3T+E1bW1RwkXkhbV2Yl5+xvRMQummOjYg////\n" +"//////8CAQI=\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 2409 MODP IKE_id=2 generator=2 bits=1024 + The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. + Its hexadecimal value is + + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 + E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 + FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_2_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR\n" +"Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL\n" +"/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 2409; id=3 and id=4 are EC2N, not yet supported here */ + +/* RFC 3526 MODP IKE_id=5 generator=2 bits=1536 + The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } + Its hexadecimal value is: + + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 + E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D + C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F + 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D + 670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_5_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIHHAoHBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR\n" +"Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL\n" +"/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7ORbPcIAfLihY78FmNpINhxV05pp\n" +"Fj+o/STPX4NlXSPco62WHGLzViCFUrue1SkHcJaWbWcMNU5KvJgE8XRsCMojcyf/\n" +"/////////wIBAg==\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 3526 MODP IKE_id=14 generator=2 bits=2048 + This prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } + Its hexadecimal value is: + + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 + E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D + C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F + 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D + 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B + E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 + DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 + 15728E5A 8AACAA68 FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_14_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" +"IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" +"awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" +"mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" +"fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" +"5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 3526 MODP IKE_id=15 generator=2 bits=3072 + This prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } + Its hexadecimal value is: + + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 + E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D + C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F + 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D + 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B + E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 + DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 + 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 + ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 + ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B + F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C + BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 + 43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_15_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIIBiAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" +"IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" +"awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" +"mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" +"fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" +"5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM\n" +"fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq\n" +"ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqTrS\n" +"yv//////////AgEC\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 3526 MODP IKE_id=16 generator=2 bits=4096 + This prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } + Its hexadecimal value is: + + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 + E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D + C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F + 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D + 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B + E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 + DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 + 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 + ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 + ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B + F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C + BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 + 43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 + 88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA + 2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6 + 287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED + 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9 + 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199 + FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_16_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIICCAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" +"IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" +"awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" +"mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" +"fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" +"5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM\n" +"fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq\n" +"ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI\n" +"ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O\n" +"+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI\n" +"HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQI=\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 3526 MODP IKE_id=17 generator=2 bits=6144 + This prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } + Its hexadecimal value is: + + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 + 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B + 302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 + A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 + 49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 + FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D + 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C + 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718 + 3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D + 04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D + B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 + 1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C + BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC + E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26 + 99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB + 04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2 + 233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 + D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492 + 36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406 + AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918 + DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151 + 2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03 + F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F + BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA + CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B + B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632 + 387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E + 6DCC4024 FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_17_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIIDCAKCAwEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" +"IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" +"awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" +"mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" +"fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" +"5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM\n" +"fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq\n" +"ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI\n" +"ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O\n" +"+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI\n" +"HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG\n" +"3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU\n" +"7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId\n" +"A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha\n" +"xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/\n" +"8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebcxA\n" +"JP//////////AgEC\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 3526 MODP IKE_id=18 generator=2 bits=8192 + This prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } + Its hexadecimal value is: + + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 + E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D + C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F + 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D + 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B + E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 + DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 + 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 + ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 + ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B + F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C + BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 + 43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 + 88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA + 2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6 + 287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED + 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9 + 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492 + 36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD + F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831 + 179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B + DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF + 5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6 + D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3 + 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA + CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 + 06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C + DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE + 12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4 + 38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300 + 741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568 + 3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9 + 22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B + 4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A + 062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36 + 4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1 + B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92 + 4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47 + 9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71 + 60C980DD 98EDD3DF FFFFFFFF FFFFFFFF +*/ +static const char dh_ike_18_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIIECAKCBAEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" +"IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" +"awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" +"mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" +"fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" +"5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM\n" +"fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq\n" +"ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI\n" +"ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O\n" +"+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI\n" +"HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG\n" +"3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU\n" +"7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId\n" +"A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha\n" +"xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/\n" +"8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebb4R\n" +"WXSjkm8S/uXkOHd8tqky34zYvsTQc7kxujvIMraNndMAdB+nv4r8R+0ldvaTa6Qk\n" +"ZjqrY5xa5PVoNCO0dCvxyXgjjxbL451lLeP9uL78hIrZIiIuBKQDfAcT61eoGiPw\n" +"xzRz/GRs6jBrS8vIhi+Dhd36nUt/osCH6HloMwPtW906Bis89bOieKZtKhP4P0T4\n" +"Ld8xDuB0q2o2RZfomaAlXcFk8xzFCEaFHfmrSBld7X6hsdUQvX7nTXP682vDHs+i\n" +"aDWQRvTrh5+SQAlDi0gcbNeImgAu1e44K8kZDab8Am5HlVjkR1Z36aqeMFDidlaU\n" +"38gfVuiAuW5xYMmA3Zjt09///////////wIBAg==\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 5114 IKE_id=22 +2.1. 1024-bit MODP Group with 160-bit Prime Order Subgroup + + The hexadecimal value of the prime is: + + p = B10B8F96 A080E01D DE92DE5E AE5D54EC 52C99FBC FB06A3C6 + 9A6A9DCA 52D23B61 6073E286 75A23D18 9838EF1E 2EE652C0 + 13ECB4AE A9061123 24975C3C D49B83BF ACCBDD7D 90C4BD70 + 98488E9C 219A7372 4EFFD6FA E5644738 FAA31A4F F55BCCC0 + A151AF5F 0DC8B4BD 45BF37DF 365C1A65 E68CFDA7 6D4DA708 + DF1FB2BC 2E4A4371 + + The hexadecimal value of the generator is: + + g = A4D1CBD5 C3FD3412 6765A442 EFB99905 F8104DD2 58AC507F + D6406CFF 14266D31 266FEA1E 5C41564B 777E690F 5504F213 + 160217B4 B01B886A 5E91547F 9E2749F4 D7FBD7D3 B9A92EE1 + 909D0D22 63F80A76 A6A24C08 7A091F53 1DBF0A01 69B6A28A + D662A4D1 8E73AFA3 2D779D59 18D08BC8 858F4DCE F97C2A24 + 855E6EEB 22B3B2E5 + + The generator generates a prime-order subgroup of size: + + q = F518AA87 81A8DF27 8ABA4E7D 64B7CB9D 49462353 +*/ +static const char dh_ike_22_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIIBCAKBgQCxC4+WoIDgHd6S3l6uXVTsUsmfvPsGo8aaap3KUtI7YWBz4oZ1oj0Y\n" +"mDjvHi7mUsAT7LSuqQYRIySXXDzUm4O/rMvdfZDEvXCYSI6cIZpzck7/1vrlZEc4\n" +"+qMaT/VbzMChUa9fDci0vUW/N982XBpl5oz9p21NpwjfH7K8LkpDcQKBgQCk0cvV\n" +"w/00EmdlpELvuZkF+BBN0lisUH/WQGz/FCZtMSZv6h5cQVZLd35pD1UE8hMWAhe0\n" +"sBuIal6RVH+eJ0n01/vX07mpLuGQnQ0iY/gKdqaiTAh6CR9THb8KAWm2oorWYqTR\n" +"jnOvoy13nVkY0IvIhY9Nzvl8KiSFXm7rIrOy5Q==\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 5114 IKE_id=23 +2.2. 2048-bit MODP Group with 224-bit Prime Order Subgroup + + The hexadecimal value of the prime is: + + p = AD107E1E 9123A9D0 D660FAA7 9559C51F A20D64E5 683B9FD1 + B54B1597 B61D0A75 E6FA141D F95A56DB AF9A3C40 7BA1DF15 + EB3D688A 309C180E 1DE6B85A 1274A0A6 6D3F8152 AD6AC212 + 9037C9ED EFDA4DF8 D91E8FEF 55B7394B 7AD5B7D0 B6C12207 + C9F98D11 ED34DBF6 C6BA0B2C 8BBC27BE 6A00E0A0 B9C49708 + B3BF8A31 70918836 81286130 BC8985DB 1602E714 415D9330 + 278273C7 DE31EFDC 7310F712 1FD5A074 15987D9A DC0A486D + CDF93ACC 44328387 315D75E1 98C641A4 80CD86A1 B9E587E8 + BE60E69C C928B2B9 C52172E4 13042E9B 23F10B0E 16E79763 + C9B53DCF 4BA80A29 E3FB73C1 6B8E75B9 7EF363E2 FFA31F71 + CF9DE538 4E71B81C 0AC4DFFE 0C10E64F + + The hexadecimal value of the generator is: + + g = AC4032EF 4F2D9AE3 9DF30B5C 8FFDAC50 6CDEBE7B 89998CAF + 74866A08 CFE4FFE3 A6824A4E 10B9A6F0 DD921F01 A70C4AFA + AB739D77 00C29F52 C57DB17C 620A8652 BE5E9001 A8D66AD7 + C1766910 1999024A F4D02727 5AC1348B B8A762D0 521BC98A + E2471504 22EA1ED4 09939D54 DA7460CD B5F6C6B2 50717CBE + F180EB34 118E98D1 19529A45 D6F83456 6E3025E3 16A330EF + BB77A86F 0C1AB15B 051AE3D4 28C8F8AC B70A8137 150B8EEB + 10E183ED D19963DD D9E263E4 770589EF 6AA21E7F 5F2FF381 + B539CCE3 409D13CD 566AFBB4 8D6C0191 81E1BCFE 94B30269 + EDFE72FE 9B6AA4BD 7B5A0F1C 71CFFF4C 19C418E1 F6EC0179 + 81BC087F 2A7065B3 84B890D3 191F2BFA + + The generator generates a prime-order subgroup of size: + + q = 801C0D34 C58D93FE 99717710 1F80535A 4738CEBC BF389A99 + B36371EB +*/ +static const char dh_ike_23_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIICCgKCAQEArRB+HpEjqdDWYPqnlVnFH6INZOVoO5/RtUsVl7YdCnXm+hQd+VpW\n" +"26+aPEB7od8V6z1oijCcGA4d5rhaEnSgpm0/gVKtasISkDfJ7e/aTfjZHo/vVbc5\n" +"S3rVt9C2wSIHyfmNEe002/bGugssi7wnvmoA4KC5xJcIs7+KMXCRiDaBKGEwvImF\n" +"2xYC5xRBXZMwJ4Jzx94x79xzEPcSH9WgdBWYfZrcCkhtzfk6zEQyg4cxXXXhmMZB\n" +"pIDNhqG55YfovmDmnMkosrnFIXLkEwQumyPxCw4W55djybU9z0uoCinj+3PBa451\n" +"uX7zY+L/ox9xz53lOE5xuBwKxN/+DBDmTwKCAQEArEAy708tmuOd8wtcj/2sUGze\n" +"vnuJmYyvdIZqCM/k/+OmgkpOELmm8N2SHwGnDEr6q3OddwDCn1LFfbF8YgqGUr5e\n" +"kAGo1mrXwXZpEBmZAkr00CcnWsE0i7inYtBSG8mK4kcVBCLqHtQJk51U2nRgzbX2\n" +"xrJQcXy+8YDrNBGOmNEZUppF1vg0Vm4wJeMWozDvu3eobwwasVsFGuPUKMj4rLcK\n" +"gTcVC47rEOGD7dGZY93Z4mPkdwWJ72qiHn9fL/OBtTnM40CdE81Wavu0jWwBkYHh\n" +"vP6UswJp7f5y/ptqpL17Wg8ccc//TBnEGOH27AF5gbwIfypwZbOEuJDTGR8r+g==\n" +"-----END DH PARAMETERS-----\n"; + +/* RFC 5114 IKE_id=24 +2.3. 2048-bit MODP Group with 256-bit Prime Order Subgroup + + The hexadecimal value of the prime is: + + p = 87A8E61D B4B6663C FFBBD19C 65195999 8CEEF608 660DD0F2 + 5D2CEED4 435E3B00 E00DF8F1 D61957D4 FAF7DF45 61B2AA30 + 16C3D911 34096FAA 3BF4296D 830E9A7C 209E0C64 97517ABD + 5A8A9D30 6BCF67ED 91F9E672 5B4758C0 22E0B1EF 4275BF7B + 6C5BFC11 D45F9088 B941F54E B1E59BB8 BC39A0BF 12307F5C + 4FDB70C5 81B23F76 B63ACAE1 CAA6B790 2D525267 35488A0E + F13C6D9A 51BFA4AB 3AD83477 96524D8E F6A167B5 A41825D9 + 67E144E5 14056425 1CCACB83 E6B486F6 B3CA3F79 71506026 + C0B857F6 89962856 DED4010A BD0BE621 C3A3960A 54E710C3 + 75F26375 D7014103 A4B54330 C198AF12 6116D227 6E11715F + 693877FA D7EF09CA DB094AE9 1E1A1597 + + The hexadecimal value of the generator is: + + g = 3FB32C9B 73134D0B 2E775066 60EDBD48 4CA7B18F 21EF2054 + 07F4793A 1A0BA125 10DBC150 77BE463F FF4FED4A AC0BB555 + BE3A6C1B 0C6B47B1 BC3773BF 7E8C6F62 901228F8 C28CBB18 + A55AE313 41000A65 0196F931 C77A57F2 DDF463E5 E9EC144B + 777DE62A AAB8A862 8AC376D2 82D6ED38 64E67982 428EBC83 + 1D14348F 6F2F9193 B5045AF2 767164E1 DFC967C1 FB3F2E55 + A4BD1BFF E83B9C80 D052B985 D182EA0A DB2A3B73 13D3FE14 + C8484B1E 052588B9 B7D2BBD2 DF016199 ECD06E15 57CD0915 + B3353BBB 64E0EC37 7FD02837 0DF92B52 C7891428 CDC67EB6 + 184B523D 1DB246C3 2F630784 90F00EF8 D647D148 D4795451 + 5E2327CF EF98C582 664B4C0F 6CC41659 + + The generator generates a prime-order subgroup of size: + + q = 8CF83642 A709A097 B4479976 40129DA2 99B1A47D 1EB3750B + A308B0FE 64F5FBD3 +*/ +static const char dh_ike_24_pem[] = +"-----BEGIN DH PARAMETERS-----\n" +"MIICCQKCAQEAh6jmHbS2Zjz/u9GcZRlZmYzu9ghmDdDyXSzu1ENeOwDgDfjx1hlX\n" +"1Pr330VhsqowFsPZETQJb6o79Cltgw6afCCeDGSXUXq9WoqdMGvPZ+2R+eZyW0dY\n" +"wCLgse9Cdb97bFv8EdRfkIi5QfVOseWbuLw5oL8SMH9cT9twxYGyP3a2Osrhyqa3\n" +"kC1SUmc1SIoO8TxtmlG/pKs62DR3llJNjvahZ7WkGCXZZ+FE5RQFZCUcysuD5rSG\n" +"9rPKP3lxUGAmwLhX9omWKFbe1AEKvQvmIcOjlgpU5xDDdfJjddcBQQOktUMwwZiv\n" +"EmEW0iduEXFfaTh3+tfvCcrbCUrpHhoVlwKCAQA/syybcxNNCy53UGZg7b1ITKex\n" +"jyHvIFQH9Hk6GguhJRDbwVB3vkY//0/tSqwLtVW+OmwbDGtHsbw3c79+jG9ikBIo\n" +"+MKMuxilWuMTQQAKZQGW+THHelfy3fRj5ensFEt3feYqqrioYorDdtKC1u04ZOZ5\n" +"gkKOvIMdFDSPby+Rk7UEWvJ2cWTh38lnwfs/LlWkvRv/6DucgNBSuYXRguoK2yo7\n" +"cxPT/hTISEseBSWIubfSu9LfAWGZ7NBuFVfNCRWzNTu7ZODsN3/QKDcN+StSx4kU\n" +"KM3GfrYYS1I9HbJGwy9jB4SQ8A741kfRSNR5VFFeIyfP75jFgmZLTA9sxBZZ\n" +"-----END DH PARAMETERS-----\n"; + + +/* ========================================================================= */ + +struct dh_constant { + const char *label; + const char *pem; +}; + +/* KEEP SORTED ALPHABETICALLY; + * duplicate PEM are okay, if we want aliases, but names must be alphabetical */ +static struct dh_constant dh_constants[] = { + { "default", dh_ike_23_pem }, + { "ike1", dh_ike_1_pem }, + { "ike14", dh_ike_14_pem }, + { "ike15", dh_ike_15_pem }, + { "ike16", dh_ike_16_pem }, + { "ike17", dh_ike_17_pem }, + { "ike18", dh_ike_18_pem }, + { "ike2", dh_ike_2_pem }, + { "ike22", dh_ike_22_pem }, + { "ike23", dh_ike_23_pem }, + { "ike24", dh_ike_24_pem }, + { "ike5", dh_ike_5_pem }, +}; +static const int dh_constants_count = + sizeof(dh_constants) / sizeof(struct dh_constant); + + +/* A policy decision; in absence of any other data, use a 2048 bit prime, + * pick the first one from the latest RFC providing such. */ +const char * +std_dh_prime_default(void) +{ + return dh_ike_23_pem; +} + + +const char * +std_dh_prime_named(const uschar *name) +{ + int first, last; + char *search_name = CS string_copylc(US name); + + first = 0; + last = dh_constants_count; + while (last > first) { + int middle = (first + last)/2; + int c = strcmp(search_name, dh_constants[middle].label); + if (c == 0) + return dh_constants[middle].pem; + else if (c > 0) + first = middle + 1; + else + last = middle; + } + return NULL; +} + +#endif /* SUPPORT_TLS */ +/* EOF */ diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index e2fcb3338..7aab309e6 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -358,9 +358,6 @@ file is never present. If two processes both compute some new parameters, you waste a bit of effort, but it doesn't seem worth messing around with locking to prevent this. -Argument: - host NULL for server, server for client (for error handling) - Returns: OK/DEFER/FAIL */ @@ -370,8 +367,12 @@ init_server_dh(void) int fd, rc; unsigned int dh_bits; gnutls_datum m; -uschar filename[PATH_MAX]; +uschar filename_buf[PATH_MAX]; +uschar *filename = NULL; size_t sz; +uschar *exp_tls_dhparam; +BOOL use_file_in_spool = FALSE; +BOOL use_fixed_file = FALSE; host_item *host = NULL; /* dummy for macros */ DEBUG(D_tls) debug_printf("Initialising GnuTLS server params.\n"); @@ -379,6 +380,46 @@ DEBUG(D_tls) debug_printf("Initialising GnuTLS server params.\n"); rc = gnutls_dh_params_init(&dh_server_params); exim_gnutls_err_check(US"gnutls_dh_params_init"); +m.data = NULL; +m.size = 0; + +if (!expand_check(tls_dhparam, US"tls_dhparam", &exp_tls_dhparam)) + return DEFER; + +if (!exp_tls_dhparam) + { + DEBUG(D_tls) debug_printf("Loading default hard-coded DH params\n"); + m.data = US std_dh_prime_default(); + m.size = Ustrlen(m.data); + } +else if (Ustrcmp(exp_tls_dhparam, "historic") == 0) + use_file_in_spool = TRUE; +else if (Ustrcmp(exp_tls_dhparam, "none") == 0) + { + DEBUG(D_tls) debug_printf("Requested no DH parameters.\n"); + return OK; + } +else if (exp_tls_dhparam[0] != '/') + { + m.data = US std_dh_prime_named(exp_tls_dhparam); + if (m.data == NULL) + return tls_error(US"No standard prime named", CS exp_tls_dhparam, NULL); + m.size = Ustrlen(m.data); + } +else + { + use_fixed_file = TRUE; + filename = exp_tls_dhparam; + } + +if (m.data) + { + rc = gnutls_dh_params_import_pkcs3(dh_server_params, &m, GNUTLS_X509_FMT_PEM); + exim_gnutls_err_check(US"gnutls_dh_params_import_pkcs3"); + DEBUG(D_tls) debug_printf("Loaded fixed standard D-H parameters\n"); + return OK; + } + #ifdef HAVE_GNUTLS_SEC_PARAM_CONSTANTS /* If you change this constant, also change dh_param_fn_ext so that we can use a different filename and ensure we have sufficient bits. */ @@ -404,9 +445,13 @@ if (dh_bits > tls_dh_max_bits) dh_bits = tls_dh_max_bits; } -if (!string_format(filename, sizeof(filename), - "%s/gnutls-params-%d", spool_directory, dh_bits)) - return tls_error(US"overlong filename", NULL, NULL); +if (use_file_in_spool) + { + if (!string_format(filename_buf, sizeof(filename_buf), + "%s/gnutls-params-%d", spool_directory, dh_bits)) + return tls_error(US"overlong filename", NULL, NULL); + filename = filename_buf; + } /* Open the cache file for reading and if successful, read it and set up the parameters. */ diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index ebc5a6255..43b79634e 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -275,60 +275,85 @@ DEBUG(D_tls) debug_printf("SSL info: %s\n", SSL_state_string_long(s)); /* If dhparam is set, expand it, and load up the parameters for DH encryption. Arguments: - dhparam DH parameter file + dhparam DH parameter file or fixed parameter identity string host connected host, if client; NULL if server Returns: TRUE if OK (nothing to set up, or setup worked) */ static BOOL -init_dh(uschar *dhparam, host_item *host) +init_dh(SSL_CTX *sctx, uschar *dhparam, host_item *host) { -BOOL yield = TRUE; BIO *bio; DH *dh; uschar *dhexpanded; +const char *pem; if (!expand_check(dhparam, US"tls_dhparam", &dhexpanded)) return FALSE; -if (dhexpanded == NULL) return TRUE; - -if ((bio = BIO_new_file(CS dhexpanded, "r")) == NULL) +if (dhexpanded == NULL || *dhexpanded == '\0') { - tls_error(string_sprintf("could not read dhparams file %s", dhexpanded), - host, (uschar *)strerror(errno)); - yield = FALSE; + bio = BIO_new_mem_buf(CS std_dh_prime_default(), -1); } -else +else if (dhexpanded[0] == '/') { - if ((dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL) + bio = BIO_new_file(CS dhexpanded, "r"); + if (bio == NULL) { tls_error(string_sprintf("could not read dhparams file %s", dhexpanded), - host, NULL); - yield = FALSE; + host, US strerror(errno)); + return FALSE; } - else + } +else + { + if (Ustrcmp(dhexpanded, "none") == 0) { - if ((8*DH_size(dh)) > tls_dh_max_bits) - { - DEBUG(D_tls) - debug_printf("dhparams file %d bits, is > tls_dh_max_bits limit of %d", - 8*DH_size(dh), tls_dh_max_bits); - } - else - { - SSL_CTX_set_tmp_dh(ctx, dh); - DEBUG(D_tls) - debug_printf("Diffie-Hellman initialized from %s with %d-bit key\n", - dhexpanded, 8*DH_size(dh)); - } - DH_free(dh); + DEBUG(D_tls) debug_printf("Requested no DH parameters.\n"); + return TRUE; + } + + pem = std_dh_prime_named(dhexpanded); + if (!pem) + { + tls_error(string_sprintf("Unknown standard DH prime \"%s\"", dhexpanded), + host, US strerror(errno)); + return FALSE; } + bio = BIO_new_mem_buf(CS pem, -1); + } + +dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); +if (dh == NULL) + { BIO_free(bio); + tls_error(string_sprintf("Could not read tls_dhparams \"%s\"", dhexpanded), + host, NULL); + return FALSE; } -return yield; +/* Even if it is larger, we silently return success rather than cause things + * to fail out, so that a too-large DH will not knock out all TLS; it's a + * debatable choice. */ +if ((8*DH_size(dh)) > tls_dh_max_bits) + { + DEBUG(D_tls) + debug_printf("dhparams file %d bits, is > tls_dh_max_bits limit of %d", + 8*DH_size(dh), tls_dh_max_bits); + } +else + { + SSL_CTX_set_tmp_dh(sctx, dh); + DEBUG(D_tls) + debug_printf("Diffie-Hellman initialized from %s with %d-bit prime\n", + dhexpanded ? dhexpanded : US"default", 8*DH_size(dh)); + } + +DH_free(dh); +BIO_free(bio); + +return TRUE; } @@ -619,6 +644,9 @@ OCSP information. */ rc = tls_expand_session_files(ctx_sni, cbinfo); if (rc != OK) return SSL_TLSEXT_ERR_NOACK; +rc = init_dh(ctx_sni, cbinfo->dhparam, NULL); +if (rc != OK) return SSL_TLSEXT_ERR_NOACK; + DEBUG(D_tls) debug_printf("Switching SSL context.\n"); SSL_set_SSL_CTX(s, ctx_sni); @@ -779,7 +807,7 @@ else /* Initialize with DH parameters if supplied */ -if (!init_dh(dhparam, host)) return DEFER; +if (!init_dh(ctx, dhparam, host)) return DEFER; /* Set up certificate and key (and perhaps OCSP info) */ diff --git a/src/util/gen_pkcs3.c b/src/util/gen_pkcs3.c new file mode 100644 index 000000000..ae7e7610a --- /dev/null +++ b/src/util/gen_pkcs3.c @@ -0,0 +1,229 @@ +/* Copyright (C) 2012 Phil Pennock. + * This is distributed as part of Exim and licensed under the GPL. + * See the file "NOTICE" for more details. + */ + +/* Build with: + * c99 $(pkg-config --cflags openssl) gen_pkcs3.c $(pkg-config --libs openssl) + */ + +#include <ctype.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <openssl/bio.h> +#include <openssl/bn.h> +#include <openssl/dh.h> +#include <openssl/err.h> +#include <openssl/pem.h> + +extern const char *__progname; + + +void __attribute__((__noreturn__)) __attribute__((__format__(printf, 1, 2))) +die(const char *fmt, ...) +{ + va_list ap; + + fflush(NULL); + fprintf(stderr, "%s: ", __progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + fflush(stderr); + exit(1); +} + + +void __attribute__((__noreturn__)) +die_openssl_err(const char *msg) +{ + char err_string[250]; + unsigned long e; + + ERR_error_string_n(ERR_get_error(), err_string, sizeof(err_string)); + die("%s: %s", msg, err_string); +} + + +static BIGNUM * +bn_from_text(const char *text) +{ + BIGNUM *b; + char *p, *spaceless; + const char *q, *end; + size_t len; + int rc; + + len = strlen(text); + spaceless = malloc(len); + if (!spaceless) + die("malloc(%zu) failed: %s", len, strerror(errno)); + + for (p = spaceless, q = text, end = text + len; + q < end; + ++q) { + if (!isspace(*q)) + *p++ = *q; + } + + b = NULL; + rc = BN_hex2bn(&b, spaceless); + + if (rc != p - spaceless) + die("BN_hex2bn did not convert entire input; took %d of %z bytes", + rc, p - spaceless); + + return b; +} + + +static void +our_dh_check(DH *dh) +{ + int rc, errflags = 0; + + rc = DH_check(dh, &errflags); + if (!rc) die_openssl_err("DH_check() could not be performed");; + + /* We ignore DH_UNABLE_TO_CHECK_GENERATOR because some of the invocations + * deliberately provide generators other than 2 or 5. */ + + if (errflags & DH_CHECK_P_NOT_SAFE_PRIME) + die("DH_check(): p not a safe prime"); + if (errflags & DH_NOT_SUITABLE_GENERATOR) + die("DH_check(): g not suitable as generator"); +} + + +static void +emit_c_format_dh(FILE *stream, DH *dh) +{ + BIO *bio; + long length; + char *data, *end, *p, *nl; + + bio = BIO_new(BIO_s_mem()); + PEM_write_bio_DHparams(bio, dh); + length = BIO_get_mem_data(bio, &data); + if (!length) + die("no data in memory BIO to format for printing"); + if (length < 0) + die("grr, negative length memory not supported"); + end = data + length; + + for (p = data; p < end; /**/) { + nl = strchr(p, '\n'); + if (!nl) { + fprintf(stream, "\"%s\\n\"\n/* missing final newline */\n", p); + break; + } + *nl = '\0'; + fprintf(stream, "\"%s\\n\"\n", p); + p = nl + 1; + } +} + + +void __attribute__((__noreturn__)) +usage(FILE *stream, int exitcode) +{ + fprintf(stream, "Usage: %s [-CPcst] <dh_p> <dh_g>\n" +"Both dh_p and dh_g should be hex strings representing the numbers\n" +"They may contain whitespace.\n" +"\n" +" -C show C string form of PEM result\n" +" -P do not show PEM\n" +" -c run OpenSSL DH_check() on the DH object\n" +" -s show the parsed p and g\n" +" -t show text form of certificate\n" + + , __progname); + exit(exitcode); +} + + +int +main(int argc, char *argv[]) +{ + BIGNUM *p, *g; + DH *dh; + int ch; + bool perform_dh_check = false; + bool show_c_form = false; + bool show_numbers = false; + bool show_pem = true; + bool show_text = false; + + while ((ch = getopt(argc, argv, "CPcsth")) != -1) { + switch (ch) { + case 'C': + show_c_form = true; + break; + case 'P': + show_pem = false; + break; + case 'c': + perform_dh_check = true; + break; + case 's': + show_numbers = true; + break; + case 't': + show_text = true; + break; + + case 'h': + usage(stdout, 0); + case '?': + die("Unknown option or missing argument -%c", optopt); + default: + die("Unhandled option -%c", ch); + } + } + + optind -= 1; + argc -= optind; + argv += optind; + + if (argc != 3) { + fprintf(stderr, "argc: %d\n", argc); + usage(stderr, 1); + } + + p = bn_from_text(argv[1]); + g = bn_from_text(argv[2]); + + if (show_numbers) { + printf("p = "); + BN_print_fp(stdout, p); + printf("\ng = "); + BN_print_fp(stdout, g); + printf("\n"); + } + + dh = DH_new(); + dh->p = p; + dh->g = g; + + if (perform_dh_check) + our_dh_check(dh); + + if (show_text) + DHparams_print_fp(stdout, dh); + + if (show_pem) { + if (show_c_form) + emit_c_format_dh(stdout, dh); + else + PEM_write_DHparams(stdout, dh); + } + + DH_free(dh); /* should free p & g too */ + return 0; +} |