[pacman-dev] [PATCH][WIP] Allow replacing libcrypto with libnettle in pacman
Add a --with-nettle configure option that directs pacman to use the libnettle hashing functions. Only one of the --with-libssl and --with-nettle configure options can be specified. Signed-off-by: Allan McRae <allan@archlinux.org> --- I did not write this - it is based heavily off a patch submitted to flyspray. I will change the author information once it is provided. Current caveats: 1) openssl is still used in makepkg. This was also addressed in the original patch, but needs work 2) to use libnettle, you need to use --with-nettle --without-libssl due to setting openssl usage to be the default. I'm not sure how I should address that. configure.ac | 38 ++++++++++++++++++++++++++++++-------- lib/libalpm/Makefile.am | 6 ++++-- lib/libalpm/libalpm.pc.in | 2 +- lib/libalpm/util.c | 41 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index f6b87e5..625ba68 100644 --- a/configure.ac +++ b/configure.ac @@ -120,10 +120,15 @@ AC_ARG_WITH(ldconfig, [set the full path to ldconfig]), [LDCONFIG=$withval], [LDCONFIG=/sbin/ldconfig]) -# Help line for using OpenSSL +# Help line for using OpenSSL (enabled by default) AC_ARG_WITH(openssl, - AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations instead of internal routines]), - [], [with_openssl=check]) + AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations @<:@default=yes@:>@]), + [], [with_openssl=yes]) + +# Help line for using nettle (disabled by default) +AC_ARG_WITH(nettle, + AS_HELP_STRING([--with-nettle], [use nettle crypto implementations @<:@default=no@:>@]), + [], [with_nettle=no]) # Help line for using gpgme AC_ARG_WITH(gpgme, @@ -218,9 +223,19 @@ AC_CHECK_LIB([m], [fabs], , PKG_CHECK_MODULES(LIBARCHIVE, [libarchive >= 2.8.0], , AC_MSG_ERROR([*** libarchive >= 2.8.0 is needed to compile pacman!])) +# Check if at least one crypto backend is selected +AS_IF([test "x$with_openssl" == "xno" -a "x$with_nettle" == "xno"], + [AC_MSG_ERROR([*** pacman requires at least one crypto library to be available])] +) + +# Check if exactly one crypto backend is selected +AS_IF([test "x$with_openssl" == "xyes" -a "x$with_nettle" == "xyes"], + [AC_MSG_ERROR([*** --with-openssl and --with-nettle are mutually exclusive.])] +) + # Check for OpenSSL have_openssl=no -if test "x$with_openssl" != "xno"; then +if test "x$with_openssl" == "xyes"; then PKG_CHECK_MODULES(LIBSSL, [libcrypto], [AC_DEFINE(HAVE_LIBSSL, 1, [Define if libcrypto is available]) have_openssl=yes], have_openssl=no) if test "x$have_openssl" = xno -a "x$with_openssl" = xyes; then @@ -229,10 +244,16 @@ if test "x$with_openssl" != "xno"; then fi AM_CONDITIONAL(HAVE_LIBSSL, [test "$have_openssl" = "yes"]) -# Ensure one library for generating checksums is present -if test "$have_openssl" != "yes"; then - AC_MSG_ERROR([*** no library for checksum generation found]) +# Check for nettle +have_nettle=no +if test "x$with_nettle" == "xyes"; then + PKG_CHECK_MODULES(NETTLE, [nettle], + [AC_DEFINE(HAVE_LIBNETTLE, 1, [Define whether to use nettle]) have_nettle=yes], have_nettle=no) + if test "x$have_nettle" = xno -a "x$with_nettle" = xyes; then + AC_MSG_ERROR([*** nettle support requested but libraries not found]) + fi fi +AM_CONDITIONAL(HAVE_LIBNETTLE, [test "$have_nettle" = "yes"]) # Check for libcurl have_libcurl=no @@ -542,7 +563,7 @@ ${PACKAGE_NAME}: compiler : ${CC} preprocessor flags : ${CPPFLAGS} compiler flags : ${WARNING_CFLAGS} ${CFLAGS} - library flags : ${LIBS} ${LIBSSL_LIBS} ${LIBARCHIVE_LIBS} ${LIBCURL_LIBS} ${GPGME_LIBS} + library flags : ${LIBS} ${LIBSSL_LIBS} ${NETTLE_LIBS} ${LIBARCHIVE_LIBS} ${LIBCURL_LIBS} ${GPGME_LIBS} linker flags : ${LDFLAGS} Architecture : ${CARCH} @@ -569,6 +590,7 @@ ${PACKAGE_NAME}: Use libcurl : ${have_libcurl} Use GPGME : ${have_gpgme} Use OpenSSL : ${have_openssl} + Use nettle : ${have_nettle} Run make in doc/ dir : ${wantdoc} ${asciidoc} Doxygen support : ${usedoxygen} debug support : ${debug} diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 945a612..f4f20e6 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -65,13 +65,15 @@ libalpm_la_CFLAGS = \ $(GPGME_CFLAGS) \ $(LIBARCHIVE_CFLAGS) \ $(LIBCURL_CFLAGS) \ - $(LIBSSL_CFLAGS) + $(LIBSSL_CFLAGS) \ + $(NETTLE_CFLAGS) libalpm_la_LIBADD = \ $(LTLIBINTL) \ $(GPGME_LIBS) \ $(LIBARCHIVE_LIBS) \ $(LIBCURL_LIBS) \ - $(LIBSSL_LIBS) + $(LIBSSL_LIBS) \ + $(NETTLE_LIBS) # vim:set noet: diff --git a/lib/libalpm/libalpm.pc.in b/lib/libalpm/libalpm.pc.in index e4be174..e1d74ef 100644 --- a/lib/libalpm/libalpm.pc.in +++ b/lib/libalpm/libalpm.pc.in @@ -9,4 +9,4 @@ URL: http://www.archlinux.org/pacman/ Version: @LIB_VERSION@ Cflags: -I${includedir} @LFS_CFLAGS@ Libs: -L${libdir} -lalpm -Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@ +Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @NETTLE_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 7ef4bf3..d0b9097 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -42,6 +42,11 @@ #include <openssl/sha.h> #endif +#ifdef HAVE_LIBNETTLE +#include <nettle/md5.h> +#include <nettle/sha2.h> +#endif + /* libalpm */ #include "util.h" #include "log.h" @@ -856,7 +861,7 @@ const char *_alpm_filecache_setup(alpm_handle_t *handle) return cachedir; } -#ifdef HAVE_LIBSSL +#if defined HAVE_LIBSSL || defined HAVE_LIBNETTLE /** Compute the MD5 message digest of a file. * @param path file path of file to compute MD5 digest of * @param output string to hold computed MD5 digest @@ -864,7 +869,11 @@ const char *_alpm_filecache_setup(alpm_handle_t *handle) */ static int md5_file(const char *path, unsigned char output[16]) { +#if HAVE_LIBSSL MD5_CTX ctx; +#else /* HAVE_LIBNETTLE */ + struct md5_ctx ctx; +#endif unsigned char *buf; ssize_t n; int fd; @@ -877,13 +886,21 @@ static int md5_file(const char *path, unsigned char output[16]) return 1; } +#if HAVE_LIBSSL MD5_Init(&ctx); +#else /* HAVE_LIBNETTLE */ + md5_init(&ctx); +#endif while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) { if(n < 0) { continue; } +#if HAVE_LIBSSL MD5_Update(&ctx, buf, n); +#else /* HAVE_LIBNETTLE */ + md5_update(&ctx, n, buf); +#endif } close(fd); @@ -893,7 +910,11 @@ static int md5_file(const char *path, unsigned char output[16]) return 2; } +#if HAVE_LIBSSL MD5_Final(output, &ctx); +#else /* HAVE_LIBNETTLE */ + md5_digest(&ctx, MD5_DIGEST_SIZE, output); +#endif return 0; } @@ -904,7 +925,11 @@ static int md5_file(const char *path, unsigned char output[16]) */ static int sha256_file(const char *path, unsigned char output[32]) { +#if HAVE_LIBSSL SHA256_CTX ctx; +#else /* HAVE_LIBNETTLE */ + struct sha256_ctx ctx; +#endif unsigned char *buf; ssize_t n; int fd; @@ -917,13 +942,21 @@ static int sha256_file(const char *path, unsigned char output[32]) return 1; } +#if HAVE_LIBSSL SHA256_Init(&ctx); +#else /* HAVE_LIBNETTLE */ + sha256_init(&ctx); +#endif while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) { if(n < 0) { continue; } +#if HAVE_LIBSSL SHA256_Update(&ctx, buf, n); +#else /* HAVE_LIBNETTLE */ + sha256_update(&ctx, n, buf); +#endif } close(fd); @@ -933,10 +966,14 @@ static int sha256_file(const char *path, unsigned char output[32]) return 2; } +#if HAVE_LIBSSL SHA256_Final(output, &ctx); +#else /* HAVE_LIBNETTLE */ + sha256_digest(&ctx, SHA256_DIGEST_SIZE, output); +#endif return 0; } -#endif +#endif /* HAVE_LIBSSL || HAVE_LIBNETTLE */ /** Create a string representing bytes in hexadecimal. * @param bytes the bytes to represent in hexadecimal -- 2.10.0
On Tue, Oct 11, 2016 at 09:57:34PM +1000, Allan McRae wrote:
Add a --with-nettle configure option that directs pacman to use the libnettle hashing functions. Only one of the --with-libssl and --with-nettle configure options can be specified.
Signed-off-by: Allan McRae <allan@archlinux.org> ---
I did not write this - it is based heavily off a patch submitted to flyspray. I will change the author information once it is provided.
Current caveats: 1) openssl is still used in makepkg. This was also addressed in the original patch, but needs work 2) to use libnettle, you need to use --with-nettle --without-libssl due to setting openssl usage to be the default. I'm not sure how I should address that.
configure.ac | 38 ++++++++++++++++++++++++++++++-------- lib/libalpm/Makefile.am | 6 ++++-- lib/libalpm/libalpm.pc.in | 2 +- lib/libalpm/util.c | 41 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 74 insertions(+), 13 deletions(-)
diff --git a/configure.ac b/configure.ac index f6b87e5..625ba68 100644 --- a/configure.ac +++ b/configure.ac @@ -120,10 +120,15 @@ AC_ARG_WITH(ldconfig, [set the full path to ldconfig]), [LDCONFIG=$withval], [LDCONFIG=/sbin/ldconfig])
-# Help line for using OpenSSL +# Help line for using OpenSSL (enabled by default) AC_ARG_WITH(openssl, - AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations instead of internal routines]), - [], [with_openssl=check]) + AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations @<:@default=yes@:>@]), + [], [with_openssl=yes]) + +# Help line for using nettle (disabled by default) +AC_ARG_WITH(nettle, + AS_HELP_STRING([--with-nettle], [use nettle crypto implementations @<:@default=no@:>@]), + [], [with_nettle=no])
# Help line for using gpgme AC_ARG_WITH(gpgme, @@ -218,9 +223,19 @@ AC_CHECK_LIB([m], [fabs], , PKG_CHECK_MODULES(LIBARCHIVE, [libarchive >= 2.8.0], , AC_MSG_ERROR([*** libarchive >= 2.8.0 is needed to compile pacman!]))
+# Check if at least one crypto backend is selected +AS_IF([test "x$with_openssl" == "xno" -a "x$with_nettle" == "xno"], + [AC_MSG_ERROR([*** pacman requires at least one crypto library to be available])] +) + +# Check if exactly one crypto backend is selected +AS_IF([test "x$with_openssl" == "xyes" -a "x$with_nettle" == "xyes"], + [AC_MSG_ERROR([*** --with-openssl and --with-nettle are mutually exclusive.])] +) + # Check for OpenSSL have_openssl=no -if test "x$with_openssl" != "xno"; then +if test "x$with_openssl" == "xyes"; then PKG_CHECK_MODULES(LIBSSL, [libcrypto], [AC_DEFINE(HAVE_LIBSSL, 1, [Define if libcrypto is available]) have_openssl=yes], have_openssl=no) if test "x$have_openssl" = xno -a "x$with_openssl" = xyes; then @@ -229,10 +244,16 @@ if test "x$with_openssl" != "xno"; then fi AM_CONDITIONAL(HAVE_LIBSSL, [test "$have_openssl" = "yes"])
-# Ensure one library for generating checksums is present -if test "$have_openssl" != "yes"; then - AC_MSG_ERROR([*** no library for checksum generation found]) +# Check for nettle +have_nettle=no +if test "x$with_nettle" == "xyes"; then + PKG_CHECK_MODULES(NETTLE, [nettle], + [AC_DEFINE(HAVE_LIBNETTLE, 1, [Define whether to use nettle]) have_nettle=yes], have_nettle=no) + if test "x$have_nettle" = xno -a "x$with_nettle" = xyes; then + AC_MSG_ERROR([*** nettle support requested but libraries not found]) + fi fi +AM_CONDITIONAL(HAVE_LIBNETTLE, [test "$have_nettle" = "yes"])
# Check for libcurl have_libcurl=no @@ -542,7 +563,7 @@ ${PACKAGE_NAME}: compiler : ${CC} preprocessor flags : ${CPPFLAGS} compiler flags : ${WARNING_CFLAGS} ${CFLAGS} - library flags : ${LIBS} ${LIBSSL_LIBS} ${LIBARCHIVE_LIBS} ${LIBCURL_LIBS} ${GPGME_LIBS} + library flags : ${LIBS} ${LIBSSL_LIBS} ${NETTLE_LIBS} ${LIBARCHIVE_LIBS} ${LIBCURL_LIBS} ${GPGME_LIBS} linker flags : ${LDFLAGS}
Architecture : ${CARCH} @@ -569,6 +590,7 @@ ${PACKAGE_NAME}: Use libcurl : ${have_libcurl} Use GPGME : ${have_gpgme} Use OpenSSL : ${have_openssl} + Use nettle : ${have_nettle} Run make in doc/ dir : ${wantdoc} ${asciidoc} Doxygen support : ${usedoxygen} debug support : ${debug} diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 945a612..f4f20e6 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -65,13 +65,15 @@ libalpm_la_CFLAGS = \ $(GPGME_CFLAGS) \ $(LIBARCHIVE_CFLAGS) \ $(LIBCURL_CFLAGS) \ - $(LIBSSL_CFLAGS) + $(LIBSSL_CFLAGS) \ + $(NETTLE_CFLAGS)
libalpm_la_LIBADD = \ $(LTLIBINTL) \ $(GPGME_LIBS) \ $(LIBARCHIVE_LIBS) \ $(LIBCURL_LIBS) \ - $(LIBSSL_LIBS) + $(LIBSSL_LIBS) \ + $(NETTLE_LIBS)
# vim:set noet: diff --git a/lib/libalpm/libalpm.pc.in b/lib/libalpm/libalpm.pc.in index e4be174..e1d74ef 100644 --- a/lib/libalpm/libalpm.pc.in +++ b/lib/libalpm/libalpm.pc.in @@ -9,4 +9,4 @@ URL: http://www.archlinux.org/pacman/ Version: @LIB_VERSION@ Cflags: -I${includedir} @LFS_CFLAGS@ Libs: -L${libdir} -lalpm -Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@ +Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @NETTLE_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 7ef4bf3..d0b9097 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -42,6 +42,11 @@ #include <openssl/sha.h> #endif
+#ifdef HAVE_LIBNETTLE +#include <nettle/md5.h> +#include <nettle/sha2.h> +#endif + /* libalpm */ #include "util.h" #include "log.h" @@ -856,7 +861,7 @@ const char *_alpm_filecache_setup(alpm_handle_t *handle) return cachedir; }
-#ifdef HAVE_LIBSSL +#if defined HAVE_LIBSSL || defined HAVE_LIBNETTLE /** Compute the MD5 message digest of a file. * @param path file path of file to compute MD5 digest of * @param output string to hold computed MD5 digest @@ -864,7 +869,11 @@ const char *_alpm_filecache_setup(alpm_handle_t *handle) */ static int md5_file(const char *path, unsigned char output[16]) { +#if HAVE_LIBSSL MD5_CTX ctx; +#else /* HAVE_LIBNETTLE */
Seems naive... perhaps elif HAVE_LIBNETTLE and make the else case an #error since it's unexpected ?
+ struct md5_ctx ctx; +#endif unsigned char *buf; ssize_t n; int fd; @@ -877,13 +886,21 @@ static int md5_file(const char *path, unsigned char output[16]) return 1; }
+#if HAVE_LIBSSL MD5_Init(&ctx); +#else /* HAVE_LIBNETTLE */ + md5_init(&ctx); +#endif
while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) { if(n < 0) { continue; } +#if HAVE_LIBSSL MD5_Update(&ctx, buf, n); +#else /* HAVE_LIBNETTLE */ + md5_update(&ctx, n, buf); +#endif }
close(fd); @@ -893,7 +910,11 @@ static int md5_file(const char *path, unsigned char output[16]) return 2; }
+#if HAVE_LIBSSL MD5_Final(output, &ctx); +#else /* HAVE_LIBNETTLE */ + md5_digest(&ctx, MD5_DIGEST_SIZE, output); +#endif return 0; }
@@ -904,7 +925,11 @@ static int md5_file(const char *path, unsigned char output[16]) */ static int sha256_file(const char *path, unsigned char output[32]) { +#if HAVE_LIBSSL SHA256_CTX ctx; +#else /* HAVE_LIBNETTLE */ + struct sha256_ctx ctx; +#endif unsigned char *buf; ssize_t n; int fd; @@ -917,13 +942,21 @@ static int sha256_file(const char *path, unsigned char output[32]) return 1; }
+#if HAVE_LIBSSL SHA256_Init(&ctx); +#else /* HAVE_LIBNETTLE */ + sha256_init(&ctx); +#endif
while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) { if(n < 0) { continue; } +#if HAVE_LIBSSL SHA256_Update(&ctx, buf, n); +#else /* HAVE_LIBNETTLE */ + sha256_update(&ctx, n, buf); +#endif }
close(fd); @@ -933,10 +966,14 @@ static int sha256_file(const char *path, unsigned char output[32]) return 2; }
+#if HAVE_LIBSSL SHA256_Final(output, &ctx); +#else /* HAVE_LIBNETTLE */ + sha256_digest(&ctx, SHA256_DIGEST_SIZE, output); +#endif return 0; } -#endif +#endif /* HAVE_LIBSSL || HAVE_LIBNETTLE */
/** Create a string representing bytes in hexadecimal. * @param bytes the bytes to represent in hexadecimal -- 2.10.0
On 11/10/16 23:32, Dave Reisner wrote:
+#if HAVE_LIBSSL
MD5_CTX ctx; +#else /* HAVE_LIBNETTLE */ Seems naive... perhaps elif HAVE_LIBNETTLE and make the else case an #error since it's unexpected ?
The whole block is surrounded by: #if defined HAVE_LIBSSL || defined HAVE_LIBNETTLE so that makes this less naive.
participants (2)
-
Allan McRae
-
Dave Reisner