babelouest / rhonabwy

Javascript Object Signing and Encryption (JOSE) library - JWK, JWKS, JWS, JWE and JWT
https://babelouest.github.io/rhonabwy/
GNU Lesser General Public License v2.1
45 stars 21 forks source link

Fix conditional compile on EC, RSA features. #23

Open drok opened 1 year ago

drok commented 1 year ago

The conditional compilation macros used to match encryption modes supported by the rhonabwy JWT library to those available from the (system-installed) GnuTLS library were wrong on some distributions. This topic seeks to rectify them, to enable rhonabwy to be built correctly on oldies but goodies like CentOS-7, and even 6. Without it, elliptic curve functionality is disabled when building with GnuTLS 3.5.0, even though it is available. On the other hand, this library fails to build on GnuTLS 3.4+ prior to 3.6, because some rsa export feature is not yet available on these versions, while rhonabwy assumes it is.

Elliptic curve features (GNUTLS_PK_EC) were introduced in GnuTLS at 3.5.0 (GnuTLS/gnutls@d417c2e).

The function gnutls_pubkey_export_rsa_raw2 was introduced in GnuTLS at 3.6.0 (GnuTLS/gnutls@02b1713).

Previously, the jwk function used the GNUTLS_VERSION_NUMBER define to conditionally compile related features, but it got the versions wrong. Eg, it coded that gnutls_pubkey_export_rsa_raw2 was available in 3.4+, and that GNUTLS_PK_EC was not available until 3.6.

Using version numbers to infer whether a feature is available is error-prone, not only because it's easy to mix up the numbers, but also because in various distributions, distro maintainers are free to tag their package with any version number they like, and sometimes they backport individual bug fixes or features, such that a seemingly old library package nonetheless includes up-to-date features.

In general, it is a best practice to identify the presence/absence of features in dependencies, because the version number offers no guarantees.

This commit replaces ifdefs like "#if GNUTLS_VERSION_NUMBER >= 0x030600" with:

The GNUTLS_PK_EC macro was introduced in commit GnuTLS/gnutls@d417c2e (at the same time as the related elliptic curve implementation), so using it is correct.

The GNUTLS_SIGN_CB_FLAG_RSA_DIGESTINFO macro, on the other hand, was introduced a few commits after the function gnutls_pubkey_export_rsa_raw2 was added at commit GnuTLS/gnutls@02b1713. Commit GnuTLS/gnutls@02b1713 does not introduce any new pre-processor define which can be used as a conditional variable. However, The RSA_DIGESTINFO is someone related to the gnutls_pubkey_export_rsa_raw2() function, and it was introduced before version 3.6.0. Although the macro does not identify the feature exactly, it is close enough,

Practically, the rhonabwy fails to compile on Ubuntu 16.04 where GnuTLS 3.4.10 is the latest available, due to missing gnutls_pubkey_export_rsa_raw2 (which was assumed to exist per version numbers).

This commit fixes detection of elliptic curve encryption and RSA export support.

Future work on this topic: I'm not convinced that the RSA exporting feature was not available until GnuTLS 3.6. and I plan to do some more work to fully understand what versions provide what capabilities. In my application, I'm limited to using GnuTLS 3.3.29 (CentOS 7), which is some motivation to understand what JWE features are truly available with this lib.