Bug#1010535: cyrus-imapd: FTBFS against openssl 3

2022-05-04 Thread Dan Bungert
I ended up sending a PR to upstream anyhow, even though it was tested against
the source from Debian.  We'll see that they say.

https://github.com/cyrusimap/cyrus-imapd/pull/4075

-Dan



Bug#1010535: cyrus-imapd: FTBFS against openssl 3

2022-05-03 Thread Dan Bungert
Package: cyrus-imapd
Version: 3.6.0~beta2-2
Severity: normal
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu kinetic

Dear Maintainer,

When building against openssl 3 from experimental, cyrus-imapd will fail in
unit test at build time.  This appears to be related to related to the warning
listed at
https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_base_id.html
which suggests using
https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_is_a.html
instead.

In these failing cases, EVP_PKEY_base_id is returning 0, which fails to match
the nid that is being compared against.

I have a patch which converts usage of EVP_PKEY_base_id to EVP_PKEY_is_a, which
allows builds against OpenSSL 3 to pass for both Ubuntu Kinetic and Debian Sid.
Please see attached.  I also updated another usage of EVP_PKEY_base_id which I
believe will be incorrect under OpenSSL 3 but that doesn't seem to be caught by
current tests.

Ordinarly at this point I would forward to upstream, but I prefer to do so
first by reproducing the failures with raw upstream source which is is having
unrelated build problems for me.  So I'm starting this way.

(also filed at https://launchpad.net/bugs/1971469)

-Dan
Description: OpenSSL 3 compatibility fix for EVP_PKEY_base_id usage
 The WARNING section of the EVP_PKEY_base_id manpage in OpenSSL 3 says that
 EVP_PKEY_base_id is "only reliable with EVP_PKEYs that have been assigned an
 internal key with EVP_PKEY_assign_*", and the usage here of base_id seems to
 be without a EVP_PKEY_assign usage.

 This same warning points to EVP_PKEY_is_a, which seems fine for this purpose
 but is part of OpenSSL 3.
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/cyrus-imapd/+bug/1971469
Last-Update: 2022-05-03
--- a/imap/http_jwt.c
+++ b/imap/http_jwt.c
@@ -120,10 +120,15 @@
 EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
 
 if (pkey) {
+#if OPENSSL_VERSION_NUMBER >= 0x3000L
+if (!EVP_PKEY_is_a(pkey, "RSA")) {
+xsyslog(LOG_ERR, "Unsupported public key", NULL);
+#else
 int nid = EVP_PKEY_base_id(pkey);
 if (nid != EVP_PKEY_RSA) {
 xsyslog(LOG_ERR, "Unsupported public key",
 "type=<%s>", OBJ_nid2ln(nid));
+#endif
 EVP_PKEY_free(pkey);
 pkey = NULL;
 }
@@ -318,6 +323,25 @@
 return 1;
 }
 
+static int validate_pkey_type(struct jwt *jwt, EVP_PKEY *pkey)
+{
+if (!jwt->nid)
+return 0;
+
+if (jwt->nid == EVP_PKEY_base_id(pkey))
+return 1;
+
+#if OPENSSL_VERSION_NUMBER >= 0x3000L
+if (jwt->nid == EVP_PKEY_HMAC && EVP_PKEY_is_a(pkey, "HMAC"))
+return 1;
+
+if (jwt->nid == EVP_PKEY_RSA && EVP_PKEY_is_a(pkey, "RSA"))
+return 1;
+#endif
+
+return 0;
+}
+
 static int validate_signature(struct jwt *jwt)
 {
 buf_reset(>buf);
@@ -339,7 +363,7 @@
 EVP_PKEY *pkey = ptrarray_nth(, i);
 EVP_MD_CTX_reset(ctx);
 
-if (jwt->nid != EVP_PKEY_base_id(pkey))
+if (!validate_pkey_type(jwt, pkey))
 continue;
 
 if (jwt->nid == EVP_PKEY_HMAC) {