Add --with-crypto=gnutls

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
This commit is contained in:
Jussi Laako 2017-06-13 16:56:21 +03:00 committed by Atomic Bot
parent ee5ecf33a5
commit f91acf5226
4 changed files with 95 additions and 16 deletions

View File

@ -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 inherit: true
context: f26-experimental-api context: f26-experimental-api

View File

@ -193,11 +193,11 @@ EXTRA_DIST += \
$(NULL) $(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 \ 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' -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_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) \ 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) libostree_1_la_LIBADD += $(bupsplitpath)
EXTRA_libostree_1_la_DEPENDENCIES = $(symbol_files) EXTRA_libostree_1_la_DEPENDENCIES = $(symbol_files)

View File

@ -329,15 +329,29 @@ AS_IF([ test x$with_smack = xyes], [
]) ])
AM_CONDITIONAL(USE_SMACK, test $with_smack != no) 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 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" OPENSSL_DEPENDENCY="libcrypto >= 1.0.1"
AC_ARG_WITH(openssl, AC_ARG_WITH(openssl,
AS_HELP_STRING([--with-openssl], [Enable use of OpenSSL libcrypto (checksums)]), AS_HELP_STRING([--with-openssl], [Enable use of OpenSSL libcrypto (checksums)]),with_openssl=$withval,with_openssl=no)
:, with_openssl=no)
AS_IF([ test x$with_openssl != xno ], [ 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]) AC_DEFINE([HAVE_OPENSSL], 1, [Define if we have openssl])
with_crypto=openssl
with_openssl=yes with_openssl=yes
], [ ], [
with_openssl=no 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) AM_CONDITIONAL(USE_OPENSSL, test $with_openssl != no)
dnl end openssl 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 dnl Avahi dependency for finding repos
AVAHI_DEPENDENCY="avahi-client >= 0.6.31 avahi-glib >= 0.6.31" AVAHI_DEPENDENCY="avahi-client >= 0.6.31 avahi-glib >= 0.6.31"
@ -536,7 +561,7 @@ echo "
HTTP backend: $fetcher_backend HTTP backend: $fetcher_backend
\"ostree trivial-httpd\": $enable_trivial_httpd_cmdline \"ostree trivial-httpd\": $enable_trivial_httpd_cmdline
SELinux: $with_selinux SELinux: $with_selinux
OpenSSL libcrypto (checksums): $with_openssl cryptographic checksums: $with_crypto
systemd: $have_libsystemd systemd: $have_libsystemd
libmount: $with_libmount libmount: $with_libmount
libarchive (parse tar files directly): $with_libarchive libarchive (parse tar files directly): $with_libarchive

View File

@ -22,15 +22,21 @@
#include "ot-checksum-instream.h" #include "ot-checksum-instream.h"
#include "ot-checksum-utils.h" #include "ot-checksum-utils.h"
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
#include <openssl/evp.h> #include <openssl/evp.h>
#elif defined(HAVE_GNUTLS)
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#endif #endif
G_DEFINE_TYPE (OtChecksumInstream, ot_checksum_instream, G_TYPE_FILTER_INPUT_STREAM) G_DEFINE_TYPE (OtChecksumInstream, ot_checksum_instream, G_TYPE_FILTER_INPUT_STREAM)
struct _OtChecksumInstreamPrivate { struct _OtChecksumInstreamPrivate {
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
EVP_MD_CTX *checksum; EVP_MD_CTX *checksum;
#elif defined(HAVE_GNUTLS)
gnutls_digest_algorithm_t checksum_type;
gnutls_hash_hd_t checksum;
#else #else
GChecksumType checksum_type; GChecksumType checksum_type;
GChecksum *checksum; GChecksum *checksum;
@ -48,8 +54,10 @@ ot_checksum_instream_finalize (GObject *object)
{ {
OtChecksumInstream *self = (OtChecksumInstream*)object; OtChecksumInstream *self = (OtChecksumInstream*)object;
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
EVP_MD_CTX_destroy (self->priv->checksum); EVP_MD_CTX_destroy (self->priv->checksum);
#elif defined(HAVE_GNUTLS)
gnutls_hash_deinit (self->priv->checksum, NULL);
#else #else
g_checksum_free (self->priv->checksum); g_checksum_free (self->priv->checksum);
#endif #endif
@ -75,7 +83,7 @@ ot_checksum_instream_init (OtChecksumInstream *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, OT_TYPE_CHECKSUM_INSTREAM, OtChecksumInstreamPrivate); self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, OT_TYPE_CHECKSUM_INSTREAM, OtChecksumInstreamPrivate);
} }
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
static const EVP_MD * static const EVP_MD *
gchecksum_type_to_openssl (GChecksumType checksum_type) gchecksum_type_to_openssl (GChecksumType checksum_type)
{ {
@ -88,6 +96,18 @@ gchecksum_type_to_openssl (GChecksumType checksum_type)
g_assert_not_reached (); 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 #endif
OtChecksumInstream * OtChecksumInstream *
@ -105,10 +125,13 @@ ot_checksum_instream_new (GInputStream *base,
/* For now */ /* For now */
g_assert (checksum_type == G_CHECKSUM_SHA256); g_assert (checksum_type == G_CHECKSUM_SHA256);
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
stream->priv->checksum = EVP_MD_CTX_create (); stream->priv->checksum = EVP_MD_CTX_create ();
g_assert (stream->priv->checksum); g_assert (stream->priv->checksum);
g_assert (EVP_DigestInit_ex (stream->priv->checksum, gchecksum_type_to_openssl (checksum_type), NULL)); 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 #else
stream->priv->checksum = g_checksum_new (checksum_type); stream->priv->checksum = g_checksum_new (checksum_type);
stream->priv->checksum_type = checksum_type; stream->priv->checksum_type = checksum_type;
@ -135,8 +158,10 @@ ot_checksum_instream_read (GInputStream *stream,
error); error);
if (res > 0) if (res > 0)
{ {
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
g_assert (EVP_DigestUpdate (self->priv->checksum, buffer, res)); g_assert (EVP_DigestUpdate (self->priv->checksum, buffer, res));
#elif defined(HAVE_GNUTLS)
g_assert (!gnutls_hash (self->priv->checksum, buffer, res));
#else #else
g_checksum_update (self->priv->checksum, buffer, res); g_checksum_update (self->priv->checksum, buffer, res);
#endif #endif
@ -150,11 +175,15 @@ ot_checksum_instream_get_digest (OtChecksumInstream *stream,
guint8 *buffer, guint8 *buffer,
gsize *digest_len) gsize *digest_len)
{ {
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
unsigned len; unsigned len;
EVP_DigestFinal_ex (stream->priv->checksum, buffer, &len); EVP_DigestFinal_ex (stream->priv->checksum, buffer, &len);
if (digest_len) if (digest_len)
*digest_len = 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 #else
g_checksum_get_digest (stream->priv->checksum, buffer, digest_len); g_checksum_get_digest (stream->priv->checksum, buffer, digest_len);
#endif #endif
@ -164,10 +193,14 @@ guint8*
ot_checksum_instream_dup_digest (OtChecksumInstream *stream, ot_checksum_instream_dup_digest (OtChecksumInstream *stream,
gsize *ret_len) gsize *ret_len)
{ {
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
guint len; guint len;
guchar *ret = g_malloc0 (EVP_MAX_MD_SIZE); guchar *ret = g_malloc0 (EVP_MAX_MD_SIZE);
g_assert (EVP_DigestFinal_ex (stream->priv->checksum, ret, &len)); 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 #else
gsize len = g_checksum_type_get_length (stream->priv->checksum_type); gsize len = g_checksum_type_get_length (stream->priv->checksum_type);
guchar *ret = g_malloc (len); guchar *ret = g_malloc (len);
@ -181,13 +214,20 @@ ot_checksum_instream_dup_digest (OtChecksumInstream *stream,
char * char *
ot_checksum_instream_get_string (OtChecksumInstream *stream) ot_checksum_instream_get_string (OtChecksumInstream *stream)
{ {
#ifdef HAVE_OPENSSL #if defined(HAVE_OPENSSL)
unsigned len; unsigned len;
guint8 csum[EVP_MAX_MD_SIZE]; guint8 csum[EVP_MAX_MD_SIZE];
g_assert (EVP_DigestFinal_ex (stream->priv->checksum, csum, &len)); g_assert (EVP_DigestFinal_ex (stream->priv->checksum, csum, &len));
char *buf = g_malloc (len * 2 + 1); char *buf = g_malloc (len * 2 + 1);
ot_bin2hex (buf, (guint8*)csum, len); ot_bin2hex (buf, (guint8*)csum, len);
return buf; 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 #else
return g_strdup (g_checksum_get_string (stream->priv->checksum)); return g_strdup (g_checksum_get_string (stream->priv->checksum));
#endif #endif