Add --with-crypto=gnutls
authorJussi Laako <jussi.laako@linux.intel.com>
Tue, 13 Jun 2017 13:56:21 +0000 (16:56 +0300)
committerAtomic Bot <atomic-devel@projectatomic.io>
Mon, 25 Sep 2017 12:58:54 +0000 (12:58 +0000)
Introduce support for GnuTLS for computing cryptograpic
hashes, similar to the OpenSSL backend.  A reason to do
this is some distributors want to avoid GPLv3, and GPG
pulls that in.

A possible extension of using GnuTLS would be replacing the GPG signing
with `PKCS#7` signatures and `X.509` keys.

We also support `--with-crypto=openssl`, which has the same effect
as `--with-openssl`, and continues to be supported.

Changes by Colin Walters <walters@verbum.org>:

 - Drop libgcrypt option for now
 - Unify buildsystem on --with-crypto

Link: https://mail.gnome.org/archives/ostree-list/2017-June/msg00002.html
Signed-off-by: Jussi Laako <jussi.laako@linux.intel.com>
Closes: #1189
Approved by: cgwalters

.papr.yml
Makefile-libostree.am
configure.ac
src/libotutil/ot-checksum-instream.c

index 4ae345e6ffc76a33f962fd5177fd5aaec038fb37..03489142724f377b2ed5b302bba7ae9061a06a84 100644 (file)
--- a/.papr.yml
+++ b/.papr.yml
@@ -63,6 +63,20 @@ tests:
 
 ---
 
+context: f26-gnutls
+inherit: true
+container:
+    image: registry.fedoraproject.org/fedora:26
+env:
+  CONFIGOPTS: '--with-crypto=gnutls'
+  CI_PKGS: pkgconfig(gnutls)
+
+tests:
+    - ci/build.sh
+    - make check TESTS=tests/test-basic.sh
+
+---
+
 inherit: true
 
 context: f26-experimental-api
index c83569ffc1a5adb1c3f85eb9979c6cda1250997b..ebbe8437cd5dbc7cd94530fa306c8778d54d356d 100644 (file)
@@ -193,11 +193,11 @@ EXTRA_DIST += \
        $(NULL)
 
 libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(builddir)/src/libostree \
-       $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) $(OT_DEP_OPENSSL_CFLAGS) \
+       $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) $(OT_DEP_CRYPTO_CFLAGS) \
        -fvisibility=hidden '-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) extern'
 libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions $(addprefix $(wl_versionscript_arg),$(symbol_files))
 libostree_1_la_LIBADD = libotutil.la libglnx.la libbsdiff.la libostree-kernel-args.la $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) \
-                        $(OT_DEP_LZMA_LIBS) $(OT_DEP_ZLIB_LIBS) $(OT_DEP_OPENSSL_LIBS)
+                        $(OT_DEP_LZMA_LIBS) $(OT_DEP_ZLIB_LIBS) $(OT_DEP_CRYPTO_LIBS)
 libostree_1_la_LIBADD += $(bupsplitpath)
 EXTRA_libostree_1_la_DEPENDENCIES = $(symbol_files)
 
index 27e1a83dd3b18d3c7e22c76f99dbada502c12cb9..2a248bc5b3a9234018182faf794f5a84a4f8bf5f 100644 (file)
@@ -329,15 +329,29 @@ AS_IF([ test x$with_smack = xyes], [
 ])
 AM_CONDITIONAL(USE_SMACK, test $with_smack != no)
 
+dnl crypto
+AC_ARG_WITH(crypto,
+AS_HELP_STRING([--with-crypto], [Choose library for checksums, one of glib, openssl, gnutls (default: glib)]),
+:, with_crypto=glib)
+
+AS_IF([test $with_crypto = glib],
+      [],
+      [test $with_crypto = openssl],
+      [with_openssl=yes],
+      [test $with_crypto = gnutls],
+      [],
+      [AC_MSG_ERROR([Invalid --with-crypto $with_crypto])]
+      )
+
 dnl begin openssl (really just libcrypto right now)
+dnl Note this option is now deprecated in favor of --with-crypto=openssl
 OPENSSL_DEPENDENCY="libcrypto >= 1.0.1"
 AC_ARG_WITH(openssl,
-AS_HELP_STRING([--with-openssl], [Enable use of OpenSSL libcrypto (checksums)]),
-:, with_openssl=no)
-
+AS_HELP_STRING([--with-openssl], [Enable use of OpenSSL libcrypto (checksums)]),with_openssl=$withval,with_openssl=no)
 AS_IF([ test x$with_openssl != xno ], [
-      PKG_CHECK_MODULES(OT_DEP_OPENSSL, $OPENSSL_DEPENDENCY)
+      PKG_CHECK_MODULES(OT_DEP_CRYPTO, $OPENSSL_DEPENDENCY)
       AC_DEFINE([HAVE_OPENSSL], 1, [Define if we have openssl])
+      with_crypto=openssl
       with_openssl=yes
 ], [
       with_openssl=no
@@ -346,6 +360,17 @@ if test x$with_openssl != xno; then OSTREE_FEATURES="$OSTREE_FEATURES openssl";
 AM_CONDITIONAL(USE_OPENSSL, test $with_openssl != no)
 dnl end openssl
 
+dnl begin gnutls; in contrast to openssl this one only
+dnl supports --with-crypto=gnutls
+GNUTLS_DEPENDENCY="gnutls >= 3.5.0"
+AS_IF([ test $with_crypto = gnutls ], [
+      PKG_CHECK_MODULES(OT_DEP_CRYPTO, $GNUTLS_DEPENDENCY)
+      AC_DEFINE([HAVE_GNUTLS], 1, [Define if we have gnutls])
+      OSTREE_FEATURES="$OSTREE_FEATURES gnutls"
+])
+AM_CONDITIONAL(USE_GNUTLS, test $with_crypto = gnutls)
+dnl end gnutls
+
 dnl Avahi dependency for finding repos
 AVAHI_DEPENDENCY="avahi-client >= 0.6.31 avahi-glib >= 0.6.31"
 
@@ -536,7 +561,7 @@ echo "
     HTTP backend:                                 $fetcher_backend
     \"ostree trivial-httpd\":                       $enable_trivial_httpd_cmdline
     SELinux:                                      $with_selinux
-    OpenSSL libcrypto (checksums):                $with_openssl
+    cryptographic checksums:                      $with_crypto
     systemd:                                      $have_libsystemd
     libmount:                                     $with_libmount
     libarchive (parse tar files directly):        $with_libarchive
index 6838c77428646358dc95ea5c8e4a4515674215a4..368a337df5c76746c3ef3520b5c14e2a23945ac6 100644 (file)
 #include "ot-checksum-instream.h"
 #include "ot-checksum-utils.h"
 
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
 #include <openssl/evp.h>
+#elif defined(HAVE_GNUTLS)
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
 #endif
 
 G_DEFINE_TYPE (OtChecksumInstream, ot_checksum_instream, G_TYPE_FILTER_INPUT_STREAM)
 
 struct _OtChecksumInstreamPrivate {
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
   EVP_MD_CTX *checksum;
+#elif defined(HAVE_GNUTLS)
+  gnutls_digest_algorithm_t checksum_type;
+  gnutls_hash_hd_t checksum;
 #else
   GChecksumType checksum_type;
   GChecksum *checksum;
@@ -48,8 +54,10 @@ ot_checksum_instream_finalize (GObject *object)
 {
   OtChecksumInstream *self = (OtChecksumInstream*)object;
 
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
   EVP_MD_CTX_destroy (self->priv->checksum);
+#elif defined(HAVE_GNUTLS)
+  gnutls_hash_deinit (self->priv->checksum, NULL);
 #else
   g_checksum_free (self->priv->checksum);
 #endif
@@ -75,7 +83,7 @@ ot_checksum_instream_init (OtChecksumInstream *self)
   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, OT_TYPE_CHECKSUM_INSTREAM, OtChecksumInstreamPrivate);
 }
 
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
 static const EVP_MD *
 gchecksum_type_to_openssl (GChecksumType checksum_type)
 {
@@ -88,6 +96,18 @@ gchecksum_type_to_openssl (GChecksumType checksum_type)
       g_assert_not_reached ();
     }
 }
+#elif defined(HAVE_GNUTLS)
+static gnutls_digest_algorithm_t
+gchecksum_type_to_gnutls (GChecksumType checksum_type)
+{
+  switch (checksum_type)
+    {
+    case G_CHECKSUM_SHA256:
+      return GNUTLS_DIG_SHA256;
+    default:
+      g_assert_not_reached ();
+    }
+}
 #endif
 
 OtChecksumInstream *
@@ -105,10 +125,13 @@ ot_checksum_instream_new (GInputStream    *base,
   /* For now */
   g_assert (checksum_type == G_CHECKSUM_SHA256);
 
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
   stream->priv->checksum = EVP_MD_CTX_create ();
   g_assert (stream->priv->checksum);
   g_assert (EVP_DigestInit_ex (stream->priv->checksum, gchecksum_type_to_openssl (checksum_type), NULL));
+#elif defined(HAVE_GNUTLS)
+  stream->priv->checksum_type = gchecksum_type_to_gnutls (checksum_type);
+  g_assert (!gnutls_hash_init (&stream->priv->checksum, stream->priv->checksum_type));
 #else
   stream->priv->checksum = g_checksum_new (checksum_type);
   stream->priv->checksum_type = checksum_type;
@@ -135,8 +158,10 @@ ot_checksum_instream_read (GInputStream  *stream,
                              error);
   if (res > 0)
     {
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
       g_assert (EVP_DigestUpdate (self->priv->checksum, buffer, res));
+#elif defined(HAVE_GNUTLS)
+      g_assert (!gnutls_hash (self->priv->checksum, buffer, res));
 #else
       g_checksum_update (self->priv->checksum, buffer, res);
 #endif
@@ -150,11 +175,15 @@ ot_checksum_instream_get_digest (OtChecksumInstream *stream,
                                  guint8          *buffer,
                                  gsize           *digest_len)
 {
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
   unsigned len;
   EVP_DigestFinal_ex (stream->priv->checksum, buffer, &len);
   if (digest_len)
     *digest_len = len;
+#elif defined(HAVE_GNUTLS)
+  gnutls_hash_output (stream->priv->checksum, buffer);
+  if (digest_len)
+    *digest_len = gnutls_hash_get_len (stream->priv->checksum_type);
 #else
   g_checksum_get_digest (stream->priv->checksum, buffer, digest_len);
 #endif
@@ -164,10 +193,14 @@ guint8*
 ot_checksum_instream_dup_digest (OtChecksumInstream *stream,
                                  gsize              *ret_len)
 {
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
   guint len;
   guchar *ret = g_malloc0 (EVP_MAX_MD_SIZE);
   g_assert (EVP_DigestFinal_ex (stream->priv->checksum, ret, &len));
+#elif defined(HAVE_GNUTLS)
+  guint len = gnutls_hash_get_len (stream->priv->checksum_type);
+  guchar *ret = g_malloc0 (len);
+  gnutls_hash_output (stream->priv->checksum, ret);
 #else
   gsize len = g_checksum_type_get_length (stream->priv->checksum_type);
   guchar *ret = g_malloc (len);
@@ -181,13 +214,20 @@ ot_checksum_instream_dup_digest (OtChecksumInstream *stream,
 char *
 ot_checksum_instream_get_string (OtChecksumInstream *stream)
 {
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL)
   unsigned len;
   guint8 csum[EVP_MAX_MD_SIZE];
   g_assert (EVP_DigestFinal_ex (stream->priv->checksum, csum, &len));
   char *buf = g_malloc (len * 2 + 1);
   ot_bin2hex (buf, (guint8*)csum, len);
   return buf;
+#elif defined(HAVE_GNUTLS)
+  gsize len;
+  guint8 *csum = ot_checksum_instream_dup_digest(stream, &len);
+  char *buf = g_malloc0 (len * 2 + 1);
+  ot_bin2hex (buf, csum, len);
+  g_free (csum);
+  return buf;
 #else
   return g_strdup (g_checksum_get_string (stream->priv->checksum));
 #endif