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 >= 0x30000000L + 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 >= 0x30000000L + 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(&jwt->buf); @@ -339,7 +363,7 @@ EVP_PKEY *pkey = ptrarray_nth(&pkeys, 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) {