From feb3d2202f72bc6f78c81f1d2ad62e39ef596bc7 Mon Sep 17 00:00:00 2001 From: Jim Garlick Date: Sun, 1 Oct 2023 18:33:08 -0700 Subject: [PATCH 1/3] libzmqutil: fix compile with libzmq-4.1.5 Problem: libzmqutil/cert does not compile with libzmq 4.1.5 because zmq_curve_public(3) is missing. Relax the check that the public and private key are cryptographically paired when that function is unavailable. If a bad cert is contstructed, it will still fail at runtime. Update unit test. --- src/common/libzmqutil/cert.c | 10 ++++++---- src/common/libzmqutil/test/cert.c | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/common/libzmqutil/cert.c b/src/common/libzmqutil/cert.c index 31f6b29530d6..b4d039ffde52 100644 --- a/src/common/libzmqutil/cert.c +++ b/src/common/libzmqutil/cert.c @@ -103,11 +103,13 @@ struct cert *cert_create (void) // assumes both keys are valid static bool valid_keypair (struct cert *cert) { +#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION(4,2,1)) char pub[TXTSIZE]; - if (zmq_curve_public (pub, cert->secret_txt) == 0 - && streq (pub, cert->public_txt)) - return true; - return false; + if (zmq_curve_public (pub, cert->secret_txt) < 0 + || !streq (pub, cert->public_txt)) + return false; +#endif + return true; } struct cert *cert_create_from (const char *public_txt, const char *secret_txt) diff --git a/src/common/libzmqutil/test/cert.c b/src/common/libzmqutil/test/cert.c index dc1eeb82e509..042868f9272d 100644 --- a/src/common/libzmqutil/test/cert.c +++ b/src/common/libzmqutil/test/cert.c @@ -13,6 +13,7 @@ #endif #include #include +#include #include "tap.h" #include "ccan/str/str.h" @@ -160,6 +161,7 @@ static struct test_vec badvec[] = { " public-key = \"" PAIR1_PUB PAIR1_PUB "\"\n" " secret-key = \"" PAIR1_SEC "\"\n" }, +#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION(4,2,1)) { .name = "cert with mismatched keypair", .input = @@ -168,6 +170,7 @@ static struct test_vec badvec[] = { " public-key = \"" "YYFE.@650VuUqRGygAtG.RC$A Date: Sun, 1 Oct 2023 18:37:16 -0700 Subject: [PATCH 2/3] libzmqutil: check for valid Z85 Problem: unit tests of invalid Z85 key detection are failing in libzmq-4.1.5. Apparently zmq_z85_decode(3) does not validate Z85 input in the older libzmq. Add validation to the cert class. --- src/common/libzmqutil/cert.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/common/libzmqutil/cert.c b/src/common/libzmqutil/cert.c index b4d039ffde52..8ad9f1088ef5 100644 --- a/src/common/libzmqutil/cert.c +++ b/src/common/libzmqutil/cert.c @@ -100,6 +100,22 @@ struct cert *cert_create (void) return NULL; } +static int copy_z85_key (char *dst, const char *src, int size) +{ + const char *xtra = ".-:+=^!/*?&<>()[]{}@%$#"; + const char *cp = src; + + if (!cp || strlen (cp) != size - 1) + return -1; + while (*cp) { + if (!isalnum (*cp) && !strchr (xtra, *cp)) + return -1; + cp++; + } + (void)strlcpy (dst, src, size); + return 0; +} + // assumes both keys are valid static bool valid_keypair (struct cert *cert) { @@ -119,18 +135,14 @@ struct cert *cert_create_from (const char *public_txt, const char *secret_txt) if (!(cert = cert_create_empty ())) return NULL; if (public_txt) { - if (strlen (public_txt) != TXTSIZE - 1) - goto inval; - strcpy (cert->public_txt, public_txt); - if (!zmq_z85_decode (cert->public_key, cert->public_txt)) + if (copy_z85_key (cert->public_txt, public_txt, TXTSIZE) < 0 + || !zmq_z85_decode (cert->public_key, cert->public_txt)) goto inval; cert->public_valid = true; } if (secret_txt) { - if (strlen (secret_txt) != TXTSIZE - 1) - goto inval; - strcpy (cert->secret_txt, secret_txt); - if (!zmq_z85_decode (cert->secret_key, cert->secret_txt)) + if (copy_z85_key (cert->secret_txt, secret_txt, TXTSIZE) < 0 + || !zmq_z85_decode (cert->secret_key, cert->secret_txt)) goto inval; cert->secret_valid = true; } @@ -336,13 +348,13 @@ static int parse_curve (struct cert *cert, char *s) if (parse_keyval (s, &key, &val) < 0) return -1; if (streq (key, "public-key")) { - if (strlcpy (cert->public_txt, val, TXTSIZE) >= TXTSIZE + if (copy_z85_key (cert->public_txt, val, TXTSIZE) < 0 || !zmq_z85_decode (cert->public_key, cert->public_txt)) goto error; cert->public_valid = true; } else if (streq (key, "secret-key")) { - if (strlcpy (cert->secret_txt, val, TXTSIZE) >= TXTSIZE + if (copy_z85_key (cert->secret_txt, val, TXTSIZE) < 0 || !zmq_z85_decode (cert->secret_key, cert->secret_txt)) goto error; cert->secret_valid = true; From 4bf68535a22c8291dccd9aaf4673236e83b234de Mon Sep 17 00:00:00 2001 From: Jim Garlick Date: Sun, 1 Oct 2023 19:11:04 -0700 Subject: [PATCH 3/3] testsuite: fix whitespace Problem: cert unit test has a random line break Drop unintended newline. --- src/common/libzmqutil/test/cert.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/libzmqutil/test/cert.c b/src/common/libzmqutil/test/cert.c index 042868f9272d..f8b1d1cfeca5 100644 --- a/src/common/libzmqutil/test/cert.c +++ b/src/common/libzmqutil/test/cert.c @@ -353,8 +353,7 @@ void test_inval (void) if (!(cert = cert_create ())) BAIL_OUT ("could not create cert"); - if (!(cpub = cert_create_from (cert_public_txt (cert), - NULL))) + if (!(cpub = cert_create_from (cert_public_txt (cert), NULL))) BAIL_OUT ("could not create cert"); errno = 0;