summaryrefslogtreecommitdiff
path: root/src/util/gen_pkcs3.c
diff options
context:
space:
mode:
authorPhil Pennock <pdp@exim.org>2016-05-29 02:31:18 -0400
committerPhil Pennock <pdp@exim.org>2016-10-08 19:23:37 -0400
commit317e40ac8b1b816f4a22620a5647c6258de61598 (patch)
tree46f3796e23ecca09e0992b1a25eadaf8d062a466 /src/util/gen_pkcs3.c
parentae5afa61184b6c9b39f58804032b32b42e3ba44e (diff)
DH parameters update, new values & defaultexim-4_88_RC2
* Add three new Exim-specific DH parameter constants; state provenance, but no way for others to verify; this is a signed commit, which is about as much as we can do for the truly paranoid: provide an audit trail. * Add the RFC 7919 DH primes + No TLS feature negotiation, per 7919, but the DH primes can be used if folks so choose * Fixed broken format string in util/gen_pkcs3.c * Tried to make gen_pkcs3.c support q values. + Turns out, q doesn't affect the PEM and that's not a mistake in my initialisation; I've checked with a cryptographer, we're losing some server-side optimizations but not any security properties for our scenario. Fixes: 1895
Diffstat (limited to 'src/util/gen_pkcs3.c')
-rw-r--r--src/util/gen_pkcs3.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/src/util/gen_pkcs3.c b/src/util/gen_pkcs3.c
index 4be2c581e..6a467e07a 100644
--- a/src/util/gen_pkcs3.c
+++ b/src/util/gen_pkcs3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Phil Pennock.
+/* Copyright (C) 2012,2016 Phil Pennock.
* This is distributed as part of Exim and licensed under the GPL.
* See the file "NOTICE" for more details.
*/
@@ -86,7 +86,7 @@ bn_from_text(const char *text)
rc = BN_hex2bn(&b, spaceless);
if (rc != p - spaceless)
- die("BN_hex2bn did not convert entire input; took %d of %z bytes",
+ die("BN_hex2bn did not convert entire input; took %d of %zu bytes",
rc, p - spaceless);
return b;
@@ -134,7 +134,7 @@ emit_c_format_dh(FILE *stream, DH *dh)
break;
}
*nl = '\0';
- fprintf(stream, "\"%s\\n\"\n", p);
+ fprintf(stream, "\"%s\\n\"%s\n", p, (nl == end - 1 ? ";" : ""));
p = nl + 1;
}
}
@@ -143,9 +143,11 @@ emit_c_format_dh(FILE *stream, DH *dh)
void __attribute__((__noreturn__))
usage(FILE *stream, int exitcode)
{
- fprintf(stream, "Usage: %s [-CPcst] <dh_p> <dh_g>\n"
+ fprintf(stream, "Usage: %s [-CPcst] <dh_p> <dh_g> [<dh_q>]\n"
"Both dh_p and dh_g should be hex strings representing the numbers\n"
+"The same applies to the optional dh_q (prime-order subgroup).\n"
"They may contain whitespace.\n"
+"Older values, dh_g is often just '2', not a long string.\n"
"\n"
" -C show C string form of PEM result\n"
" -P do not show PEM\n"
@@ -161,7 +163,7 @@ usage(FILE *stream, int exitcode)
int
main(int argc, char *argv[])
{
- BIGNUM *p, *g;
+ BIGNUM *p, *g, *q;
DH *dh;
int ch;
bool perform_dh_check = false;
@@ -169,6 +171,7 @@ main(int argc, char *argv[])
bool show_numbers = false;
bool show_pem = true;
bool show_text = false;
+ bool given_q = false;
while ((ch = getopt(argc, argv, "CPcsth")) != -1) {
switch (ch) {
@@ -201,25 +204,49 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
- if (argc != 3) {
+ if ((argc < 3) || (argc > 4)) {
fprintf(stderr, "argc: %d\n", argc);
usage(stderr, 1);
}
+ // If we use DH_set0_pqg instead of setting dh fields directly; the q value
+ // is optional and may be NULL.
+ // Just blank them all.
+ p = g = q = NULL;
+
p = bn_from_text(argv[1]);
g = bn_from_text(argv[2]);
+ if (argc >= 4) {
+ q = bn_from_text(argv[3]);
+ given_q = true;
+ }
if (show_numbers) {
printf("p = ");
BN_print_fp(stdout, p);
printf("\ng = ");
BN_print_fp(stdout, g);
+ if (given_q) {
+ printf("\nq = ");
+ BN_print_fp(stdout, q);
+ }
printf("\n");
}
dh = DH_new();
+ // The documented method for setting q appeared in OpenSSL 1.1.0.
+#if OPENSSL_VERSION_NUMBER >= 0x1010000f
+ // NULL okay for q; yes, the optional value is in the middle.
+ if (DH_set0_pqg(dh, p, q, g) != 1) {
+ die_openssl_err("initialising DH pqg values failed");
+ }
+#else
dh->p = p;
dh->g = g;
+ if (given_q) {
+ dh->q = q;
+ }
+#endif
if (perform_dh_check)
our_dh_check(dh);
@@ -234,6 +261,6 @@ main(int argc, char *argv[])
PEM_write_DHparams(stdout, dh);
}
- DH_free(dh); /* should free p & g too */
+ DH_free(dh); /* should free p,g (& q if non-NULL) too */
return 0;
}