diff --git a/configure.ac b/configure.ac index 723d2719cd..5eb7367e3c 100644 --- a/configure.ac +++ b/configure.ac @@ -311,7 +311,6 @@ AS_IF([test x$with_ed25519_libsodium != xno], [ AS_IF([ test x$have_libsodium = xno ], [ AC_MSG_ERROR([Need LIBSODIUM version $LIBSODIUM_DEPENDENCY or later]) ]) - OSTREE_FEATURES="$OSTREE_FEATURES sign-ed25519" ], with_ed25519_libsodium=no ) AM_CONDITIONAL(USE_LIBSODIUM, test "x$have_libsodium" = xyes) @@ -450,6 +449,11 @@ if test x$with_openssl != xno; then OSTREE_FEATURES="$OSTREE_FEATURES openssl"; AM_CONDITIONAL(USE_OPENSSL, test $with_openssl != no) dnl end openssl +if test x$with_openssl != xno || test x$with_ed25519_libsodium != xno; then + AC_DEFINE([HAVE_ED25519], 1, [Define if ed25519 is supported ]) + OSTREE_FEATURES="$OSTREE_FEATURES sign-ed25519" +fi + dnl begin gnutls; in contrast to openssl this one only dnl supports --with-crypto=gnutls GNUTLS_DEPENDENCY="gnutls >= 3.5.0" @@ -684,6 +688,7 @@ echo " systemd: $with_libsystemd libmount: $with_libmount libsodium (ed25519 signatures): $with_ed25519_libsodium + openssl (ed25519 signatures): $with_openssl libarchive (parse tar files directly): $with_libarchive static deltas: yes (always enabled now) O_TMPFILE: $enable_otmpfile diff --git a/src/libostree/ostree-sign-ed25519.c b/src/libostree/ostree-sign-ed25519.c index 7751ddbd10..6ff132600b 100644 --- a/src/libostree/ostree-sign-ed25519.c +++ b/src/libostree/ostree-sign-ed25519.c @@ -26,8 +26,17 @@ #include "ostree-sign-ed25519.h" #include #include + #ifdef HAVE_LIBSODIUM #include +#define USE_LIBSODIUM +#else + +#if defined(HAVE_OPENSSL) +#include +#define USE_OPENSSL +#endif + #endif #undef G_LOG_DOMAIN @@ -99,12 +108,13 @@ _ostree_sign_ed25519_init (OstreeSignEd25519 *self) self->public_keys = NULL; self->revoked_keys = NULL; -#ifdef HAVE_LIBSODIUM +#if defined(USE_LIBSODIUM) if (sodium_init () < 0) self->state = ED25519_FAILED_INITIALIZATION; +#elif defined(USE_OPENSSL) #else self->state = ED25519_NOT_SUPPORTED; -#endif /* HAVE_LIBSODIUM */ +#endif } static gboolean @@ -117,7 +127,7 @@ _ostree_sign_ed25519_is_initialized (OstreeSignEd25519 *self, GError **error) case ED25519_NOT_SUPPORTED: return glnx_throw (error, "ed25519: engine is not supported"); case ED25519_FAILED_INITIALIZATION: - return glnx_throw (error, "ed25519: libsodium library isn't initialized properly"); + return glnx_throw (error, "ed25519: crypto library isn't initialized properly"); } return TRUE; @@ -131,31 +141,46 @@ ostree_sign_ed25519_data (OstreeSign *self, GBytes *data, GBytes **signature, g_assert (OSTREE_IS_SIGN (self)); OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); -#ifdef HAVE_LIBSODIUM - guchar *sig = NULL; -#endif - if (!_ostree_sign_ed25519_is_initialized (sign, error)) return FALSE; if (sign->secret_key == NULL) return glnx_throw (error, "Not able to sign: secret key is not set"); -#ifdef HAVE_LIBSODIUM unsigned long long sig_size = 0; + g_autofree guchar *sig = g_malloc0 (OSTREE_SIGN_ED25519_SIG_SIZE); - sig = g_malloc0 (crypto_sign_BYTES); - +#if defined(USE_LIBSODIUM) if (crypto_sign_detached (sig, &sig_size, g_bytes_get_data (data, NULL), g_bytes_get_size (data), sign->secret_key)) + sig_size = 0; +#elif defined(USE_OPENSSL) + EVP_MD_CTX *ctx = EVP_MD_CTX_new (); + if (!ctx) + return glnx_throw (error, "openssl: failed to allocate context"); + EVP_PKEY *pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, sign->secret_key, + OSTREE_SIGN_ED25519_SEED_SIZE); + if (!pkey) { - return glnx_throw (error, "Not able to sign: fail to sign the object"); + EVP_MD_CTX_free (ctx); + return glnx_throw (error, "openssl: Failed to initialize ed5519 key"); } - *signature = g_bytes_new_take (sig, sig_size); + size_t len; + if (EVP_DigestSignInit (ctx, NULL, NULL, NULL, pkey) + && EVP_DigestSign (ctx, sig, &len, g_bytes_get_data (data, NULL), g_bytes_get_size (data))) + sig_size = len; + + EVP_PKEY_free (pkey); + EVP_MD_CTX_free (ctx); + +#endif + + if (sig_size == 0) + return glnx_throw (error, "Failed to sign"); + + *signature = g_bytes_new_take (g_steal_pointer (&sig), sig_size); return TRUE; -#endif /* HAVE_LIBSODIUM */ - return FALSE; } static gint @@ -207,6 +232,7 @@ ostree_sign_ed25519_data_verify (OstreeSign *self, GBytes *data, GVariant *signa { g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i); g_autoptr (GBytes) signature = g_variant_get_data_as_bytes (child); + gboolean valid = FALSE; if (g_bytes_get_size (signature) != OSTREE_SIGN_ED25519_SIG_SIZE) return glnx_throw ( @@ -230,10 +256,33 @@ ostree_sign_ed25519_data_verify (OstreeSign *self, GBytes *data, GVariant *signa continue; } - if (crypto_sign_verify_detached ((guchar *)g_variant_get_data (child), - g_bytes_get_data (data, NULL), g_bytes_get_size (data), - public_key->data) - != 0) +#if defined(USE_LIBSODIUM) + valid = crypto_sign_verify_detached ((guchar *)g_variant_get_data (child), + g_bytes_get_data (data, NULL), + g_bytes_get_size (data), public_key->data) + == 0; +#elif defined(USE_OPENSSL) + EVP_MD_CTX *ctx = EVP_MD_CTX_new (); + if (!ctx) + return glnx_throw (error, "openssl: failed to allocate context"); + EVP_PKEY *pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, public_key->data, + OSTREE_SIGN_ED25519_PUBKEY_SIZE); + if (!pkey) + { + EVP_MD_CTX_free (ctx); + return glnx_throw (error, "openssl: Failed to initialize ed5519 key"); + } + + valid = EVP_DigestVerifyInit (ctx, NULL, NULL, NULL, pkey) != 0 + && EVP_DigestVerify (ctx, g_bytes_get_data (signature, NULL), + g_bytes_get_size (signature), g_bytes_get_data (data, NULL), + g_bytes_get_size (data)) + != 0; + + EVP_PKEY_free (pkey); + EVP_MD_CTX_free (ctx); +#endif + if (!valid) { /* Incorrect signature! */ if (invalid_signatures == NULL) diff --git a/src/libostree/ostree-sign.c b/src/libostree/ostree-sign.c index be333a3070..d76271bca7 100644 --- a/src/libostree/ostree-sign.c +++ b/src/libostree/ostree-sign.c @@ -40,11 +40,9 @@ #include "ostree-autocleanups.h" #include "ostree-core.h" #include "ostree-sign-dummy.h" +#include "ostree-sign-ed25519.h" #include "ostree-sign-private.h" #include "ostree-sign.h" -#ifdef HAVE_LIBSODIUM -#include "ostree-sign-ed25519.h" -#endif #include "ostree-autocleanups.h" #include "ostree-repo-private.h" @@ -59,7 +57,7 @@ typedef struct } _sign_type; _sign_type sign_types[] = { -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) { OSTREE_SIGN_NAME_ED25519, 0 }, #endif { "dummy", 0 } @@ -67,7 +65,7 @@ _sign_type sign_types[] = { enum { -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) SIGN_ED25519, #endif SIGN_DUMMY @@ -535,7 +533,7 @@ ostree_sign_get_by_name (const gchar *name, GError **error) OstreeSign *sign = NULL; /* Get types if not initialized yet */ -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) if (sign_types[SIGN_ED25519].type == 0) sign_types[SIGN_ED25519].type = OSTREE_TYPE_SIGN_ED25519; #endif diff --git a/src/ostree/ot-builtin-sign.c b/src/ostree/ot-builtin-sign.c index cd331a486e..f51fc51e60 100644 --- a/src/ostree/ot-builtin-sign.c +++ b/src/ostree/ot-builtin-sign.c @@ -48,7 +48,7 @@ static GOptionEntry options[] { "verify", 0, 0, G_OPTION_ARG_NONE, &opt_verify, "Verify signatures", NULL }, { "sign-type", 's', 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME" }, -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_filename, "Read key(s) from file", "NAME" }, { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, "Redefine system-wide directories with public and revoked keys for verification", diff --git a/src/ostree/ot-builtin-static-delta.c b/src/ostree/ot-builtin-static-delta.c index a10040bdd1..ba9a2f2c4a 100644 --- a/src/ostree/ot-builtin-static-delta.c +++ b/src/ostree/ot-builtin-static-delta.c @@ -105,7 +105,7 @@ static GOptionEntry generate_options[] = { { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Sign the delta with", "KEY_ID" }, { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME" }, -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME" }, #endif { NULL } @@ -114,7 +114,7 @@ static GOptionEntry generate_options[] = { static GOptionEntry apply_offline_options[] = { { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME" }, -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME" }, { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, "Redefine system-wide directories with public and revoked keys for verification", "NAME" }, @@ -127,7 +127,7 @@ static GOptionEntry list_options[] = { { NULL } }; static GOptionEntry verify_options[] = { { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME" }, -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME" }, { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, "Redefine system-wide directories with public and revoked keys for verification", "NAME" }, @@ -513,7 +513,7 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc return FALSE; } -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) /* Initialize crypto system */ opt_sign_name = opt_sign_name ?: OSTREE_SIGN_NAME_ED25519; #endif