[PATCH 0/4] Initial support for asignify signatures
libasignify provides a simple API for checking ed25519 signatures of blake2 file digests. See: https://github.com/vstakhov/asignify These changes add support into libalpm, a new configuration option for the location of trusted public keys that libasignify uses, and modify the build to support only one signature method, gpgme or asignify. A future patch will be needed to add appropriate asignify signing commands to makepkg. Jeremy Huntwork (4): libalpm: Add support for asignify signatures Add a configuration option for asignify's key dir Add documentation for the AsignifyDir option Update meson for asignify doc/pacman.conf.5.asciidoc | 8 +++++ etc/pacman.conf.in | 1 + lib/libalpm/alpm.c | 2 +- lib/libalpm/alpm.h | 19 +++++++++++ lib/libalpm/be_package.c | 22 ++++++++++--- lib/libalpm/be_sync.c | 2 +- lib/libalpm/error.c | 8 ++--- lib/libalpm/handle.c | 23 ++++++++++++-- lib/libalpm/handle.h | 1 + lib/libalpm/signing.c | 65 ++++++++++++++++++++++++++++++++++++++ lib/libalpm/signing.h | 1 + meson.build | 33 +++++++++++++------ meson_options.txt | 4 +-- src/pacman/conf.c | 16 ++++++++++ src/pacman/conf.h | 2 ++ src/pacman/pacman.c | 40 ++++++++++++++++++----- test/pacman/meson.build | 2 +- 17 files changed, 216 insertions(+), 33 deletions(-) -- 2.34.1
Provide an alternative way to validate package and repository signatures using libasignify. See: https://github.com/vstakhov/asignify Signed-off-by: Jeremy Huntwork <jeremy@merelinux.org> --- lib/libalpm/alpm.c | 2 +- lib/libalpm/alpm.h | 19 ++++++++++++ lib/libalpm/be_package.c | 22 +++++++++++--- lib/libalpm/be_sync.c | 2 +- lib/libalpm/error.c | 8 ++--- lib/libalpm/handle.c | 23 ++++++++++++-- lib/libalpm/handle.h | 1 + lib/libalpm/signing.c | 65 ++++++++++++++++++++++++++++++++++++++++ lib/libalpm/signing.h | 1 + 9 files changed, 130 insertions(+), 13 deletions(-) diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 5b326ab0..d1261660 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -137,7 +137,7 @@ int SYMEXPORT alpm_capabilities(void) #ifdef HAVE_LIBCURL | ALPM_CAPABILITY_DOWNLOADER #endif -#ifdef HAVE_LIBGPGME +#if defined(HAVE_LIBGPGME) || defined(HAVE_LIBASIGNIFY) | ALPM_CAPABILITY_SIGNATURES #endif | 0; diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 7f3fc8d5..aaa0acb9 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -1833,6 +1833,25 @@ int alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir); /* End of gpdir accessors */ /** @} */ +/** @name Accessors to asignify's trusted public keys directory + * + * This controls where libalpm will store asignify's public keys. + * @{ + */ + +/** Returns the path to libalpm's asignify trusted public keys directory. + * @param handle the context handle + * @return the path to libalpms's trusted public keys directory + */ +const char *alpm_option_get_asignifydir(alpm_handle_t *handle); + +/** Sets the path to libalpm's asignify trusted public keys directory. + * @param handle the context handle + * @param asignifydir the asignifydir to set + */ +int alpm_option_set_asignifydir(alpm_handle_t *handle, const char *asignifydir); +/* End of asignifydir accessors */ +/** @} */ /** @name Accessors for use syslog * diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 5ca2865c..db6341d6 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -342,12 +342,23 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, handle->pm_errno = ALPM_ERR_PKG_MISSING_SIG; return -1; } +#ifdef HAVE_LIBGPGME if(_alpm_check_pgp_helper(handle, pkgfile, sig, level & ALPM_SIG_PACKAGE_OPTIONAL, level & ALPM_SIG_PACKAGE_MARGINAL_OK, level & ALPM_SIG_PACKAGE_UNKNOWN_OK, sigdata)) { handle->pm_errno = ALPM_ERR_PKG_INVALID_SIG; return -1; } +#endif +#ifdef HAVE_LIBASIGNIFY + if (sigdata) { + _alpm_log(handle, ALPM_LOG_DEBUG, "sigdata is unused with libasignify\n"); + } + if(_alpm_check_asignify_helper(handle, pkgfile)) { + handle->pm_errno = ALPM_ERR_PKG_INVALID_SIG; + return -1; + } +#endif if(validation && has_sig) { *validation |= ALPM_PKG_VALIDATION_SIGNATURE; } @@ -722,8 +733,6 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful { int validation = 0; char *sigpath; - alpm_pkg_t *pkg_temp; - char *packager; CHECK_HANDLE(handle, return -1); ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1)); @@ -731,8 +740,6 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful sigpath = _alpm_sigpath(handle, filename); if(sigpath && !_alpm_access(handle, NULL, sigpath, R_OK)) { if(level & ALPM_SIG_PACKAGE) { - alpm_list_t *keys = NULL; - int fail = 0; unsigned char *sig = NULL; int len = read_sigfile(sigpath, &sig); @@ -743,6 +750,12 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful return -1; } +#ifdef HAVE_LIBGPGME + alpm_list_t *keys = NULL; + int fail = 0; + alpm_pkg_t *pkg_temp; + char *packager; + if(alpm_extract_keyid(handle, filename, sig, len, &keys) == 0) { alpm_list_t *k; for(k = keys; k; k = k->next) { @@ -771,6 +784,7 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful free(sigpath); return -1; } +#endif } } free(sigpath); diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index ede25985..81654902 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -697,7 +697,7 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, _alpm_log(handle, ALPM_LOG_DEBUG, "registering sync database '%s'\n", treename); -#ifndef HAVE_LIBGPGME +#if !defined(HAVE_LIBGPGME) || !defined(HAVE_LIBASIGNIFY) if(level != 0 && level != ALPM_SIG_USE_DEFAULT) { RET_ERR(handle, ALPM_ERR_MISSING_CAPABILITY_SIGNATURES, NULL); } diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 644a6577..78b44418 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -71,7 +71,7 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err) case ALPM_ERR_DB_INVALID: return _("invalid or corrupted database"); case ALPM_ERR_DB_INVALID_SIG: - return _("invalid or corrupted database (PGP signature)"); + return _("invalid or corrupted database (signature)"); case ALPM_ERR_DB_VERSION: return _("database is incorrect version"); case ALPM_ERR_DB_WRITE: @@ -114,7 +114,7 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err) case ALPM_ERR_PKG_INVALID_CHECKSUM: return _("invalid or corrupted package (checksum)"); case ALPM_ERR_PKG_INVALID_SIG: - return _("invalid or corrupted package (PGP signature)"); + return _("invalid or corrupted package (signature)"); case ALPM_ERR_PKG_MISSING_SIG: return _("package missing required signature"); case ALPM_ERR_PKG_OPEN: @@ -127,9 +127,9 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err) return _("package architecture is not valid"); /* Signatures */ case ALPM_ERR_SIG_MISSING: - return _("missing PGP signature"); + return _("missing signature"); case ALPM_ERR_SIG_INVALID: - return _("invalid PGP signature"); + return _("invalid signature"); /* Dependencies */ case ALPM_ERR_UNSATISFIED_DEPS: return _("could not satisfy dependencies"); diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 101d4a78..4b588e58 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -270,6 +270,12 @@ const char SYMEXPORT *alpm_option_get_gpgdir(alpm_handle_t *handle) return handle->gpgdir; } +const char SYMEXPORT *alpm_option_get_asignifydir(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->asignifydir; +} + int SYMEXPORT alpm_option_get_usesyslog(alpm_handle_t *handle) { CHECK_HANDLE(handle, return -1); @@ -573,6 +579,17 @@ int SYMEXPORT alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir) return 0; } +int SYMEXPORT alpm_option_set_asignifydir(alpm_handle_t *handle, const char *asignifydir) +{ + int err; + CHECK_HANDLE(handle, return -1); + if((err = _alpm_set_directory_option(asignifydir, &(handle->asignifydir), 0))) { + RET_ERR(handle, err, -1); + } + _alpm_log(handle, ALPM_LOG_DEBUG, "option 'asignifydir' = %s\n", handle->asignifydir); + return 0; +} + int SYMEXPORT alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog) { CHECK_HANDLE(handle, return -1); @@ -829,7 +846,7 @@ int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle, if(level == ALPM_SIG_USE_DEFAULT) { RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1); } -#ifdef HAVE_LIBGPGME +#if defined(HAVE_LIBGPGME) || defined(HAVE_LIBASIGNIFY) handle->siglevel = level; #else if(level != 0) { @@ -849,7 +866,7 @@ int SYMEXPORT alpm_option_set_local_file_siglevel(alpm_handle_t *handle, int level) { CHECK_HANDLE(handle, return -1); -#ifdef HAVE_LIBGPGME +#if defined(HAVE_LIBGPGME) || defined(HAVE_LIBASIGNIFY) handle->localfilesiglevel = level; #else if(level != 0 && level != ALPM_SIG_USE_DEFAULT) { @@ -873,7 +890,7 @@ int SYMEXPORT alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, int level) { CHECK_HANDLE(handle, return -1); -#ifdef HAVE_LIBGPGME +#if defined(HAVE_LIBGPGME) || defined(HAVE_LIBASIGNIFY) handle->remotefilesiglevel = level; #else if(level != 0 && level != ALPM_SIG_USE_DEFAULT) { diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index e1af117d..22b0689d 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -91,6 +91,7 @@ struct _alpm_handle_t { char *logfile; /* Name of the log file */ char *lockfile; /* Name of the lock file */ char *gpgdir; /* Directory where GnuPG files are stored */ + char *asignifydir; /* Directory where asignify trusted public keys are stored */ alpm_list_t *cachedirs; /* Paths to pacman cache directories */ alpm_list_t *hookdirs; /* Paths to hook directories */ alpm_list_t *overwrite_files; /* Paths that may be overwritten */ diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index 66cc3923..aa4ba19f 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -26,6 +26,11 @@ #include <gpgme.h> #endif +#ifdef HAVE_LIBASIGNIFY +#include <asignify.h> +#include <dirent.h> +#endif + /* libalpm */ #include "signing.h" #include "package.h" @@ -810,6 +815,66 @@ char *_alpm_sigpath(alpm_handle_t *handle, const char *path) return sigpath; } +#ifdef HAVE_LIBASIGNIFY +/** + * Helper for checking the asignify signature for the given file path. + * @param handle the context handle + * @param path the full path to a file + * @return 0 on success, -1 on error (consult pm_errno or sigdata) + */ +int _alpm_check_asignify_helper(alpm_handle_t *handle, const char *path) +{ + int ret = 0; + struct dirent *entry; + struct stat statbuf; + + char *sigpath = _alpm_sigpath(handle, path); + asignify_verify_t *vrf = asignify_verify_init(); + + DIR *ad = opendir(handle->asignifydir); + if(ad == NULL) { + _alpm_log(handle, ALPM_LOG_DEBUG, "cannot open directory: %s\n", handle->asignifydir); + return -1; + } + + while((entry = readdir(ad)) != NULL) { + char *fullpath = malloc(strlen(handle->asignifydir) + strlen(entry->d_name) + 2); + if (fullpath == NULL) { + _alpm_log(handle, ALPM_LOG_DEBUG, "malloc error\n"); + return -1; + } + sprintf(fullpath, "%s/%s", handle->asignifydir, entry->d_name); + stat(fullpath, &statbuf); + if (S_ISREG(statbuf.st_mode)) { + if (!asignify_verify_load_pubkey(vrf, fullpath)) { + /* Don't return here because there may be multiple public keys to load. */ + _alpm_log(handle, ALPM_LOG_DEBUG, "cannot load public key file: %s\n", fullpath); + } + } + free(fullpath); + } + + if (!asignify_verify_load_signature(vrf, sigpath)) { + _alpm_log(handle, ALPM_LOG_DEBUG, "cannot load signature\n"); + ret = -1; + goto asignify_cleanup; + } + + if (!asignify_verify_file(vrf, path)) { + _alpm_log(handle, ALPM_LOG_DEBUG, "signature is not valid\n"); + ret = -1; + goto asignify_cleanup; + } + + _alpm_log(handle, ALPM_LOG_DEBUG, "signature is valid\n"); + +asignify_cleanup: + free(sigpath); + asignify_verify_free(vrf); + return ret; +} +#endif + /** * Helper for checking the PGP signature for the given file path. * This wraps #_alpm_gpgme_checksig in a slightly friendlier manner to simplify diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h index 112b2a1f..a7f75ad7 100644 --- a/lib/libalpm/signing.h +++ b/lib/libalpm/signing.h @@ -25,6 +25,7 @@ char *_alpm_sigpath(alpm_handle_t *handle, const char *path); int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, const char *base64_sig, alpm_siglist_t *result); +int _alpm_check_asignify_helper(alpm_handle_t *handle, const char *path); int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path, const char *base64_sig, int optional, int marginal, int unknown, alpm_siglist_t **sigdata); -- 2.34.1
Following the pattern used by gpgdir, set asignifydir to the location where libasignify will look for and load public keys. Since the intent is to only support one signature method at a time, wrap the `--gpgdir` and `--asignifydir` flags in ifdef blocks. Signed-off-by: Jeremy Huntwork <jeremy@merelinux.org> --- src/pacman/conf.c | 16 ++++++++++++++++ src/pacman/conf.h | 2 ++ src/pacman/pacman.c | 40 ++++++++++++++++++++++++++++++++-------- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 7d0bc2f8..7fe9107b 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -155,6 +155,7 @@ int config_free(config_t *oldconfig) free(oldconfig->dbpath); free(oldconfig->logfile); free(oldconfig->gpgdir); + free(oldconfig->asignifydir); FREELIST(oldconfig->hookdirs); FREELIST(oldconfig->cachedirs); free(oldconfig->xfercommand); @@ -663,6 +664,11 @@ static int _parse_options(const char *key, char *value, config->gpgdir = strdup(value); pm_printf(ALPM_LOG_DEBUG, "config: gpgdir: %s\n", value); } + } else if(strcmp(key, "AsignifyDir") == 0) { + if(!config->asignifydir) { + config->asignifydir = strdup(value); + pm_printf(ALPM_LOG_DEBUG, "config: asignifydir: %s\n", value); + } } else if(strcmp(key, "LogFile") == 0) { if(!config->logfile) { config->logfile = strdup(value); @@ -871,6 +877,15 @@ static int setup_libalpm(void) return ret; } + /* Set asignify's trusted keys directory. This is not relative to rootdir, even if + * rootdir is defined. Reasoning: asignifydir contains configuration data. */ + ret = alpm_option_set_asignifydir(handle, config->asignifydir); + if(ret != 0) { + pm_printf(ALPM_LOG_ERROR, _("problem setting asignifydir '%s' (%s)\n"), + config->asignifydir, alpm_strerror(alpm_errno(handle))); + return ret; + } + /* Set user hook directory. This is not relative to rootdir, even if * rootdir is defined. Reasoning: hookdir contains configuration data. */ /* add hook directories 1-by-1 to avoid overwriting the system directory */ @@ -1152,6 +1167,7 @@ int setdefaults(config_t *c) SETDEFAULT(c->logfile, strdup(LOGFILE)); SETDEFAULT(c->gpgdir, strdup(GPGDIR)); + SETDEFAULT(c->asignifydir, strdup(ASIGNIFYDIR)); SETDEFAULT(c->cachedirs, alpm_list_add(NULL, strdup(CACHEDIR))); SETDEFAULT(c->hookdirs, alpm_list_add(NULL, strdup(HOOKDIR))); SETDEFAULT(c->cleanmethod, PM_CLEAN_KEEPINST); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index a7162983..fb919b76 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -66,6 +66,7 @@ typedef struct __config_t { char *dbpath; char *logfile; char *gpgdir; + char *asignifydir; char *sysroot; alpm_list_t *hookdirs; alpm_list_t *cachedirs; @@ -173,6 +174,7 @@ enum { OP_ARCH, OP_PRINTFORMAT, OP_GPGDIR, + OP_ASIGNIFYDIR, OP_DBONLY, OP_FORCE, OP_OVERWRITE_FILES, diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index e7f4a10d..a3a2e2f6 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -220,7 +220,13 @@ static void usage(int op, const char * const myname) addlist(_(" --color <when> colorize the output\n")); addlist(_(" --config <path> set an alternate configuration file\n")); addlist(_(" --debug display debug messages\n")); +#ifdef HAVE_LIBGPGME addlist(_(" --gpgdir <path> set an alternate home directory for GnuPG\n")); +#endif +#ifdef HAVE_LIBASIGNIFY + addlist(_(" --asignifydir <path>\n" + " set an alternate directory for asignify's trusted public keys\n")); +#endif addlist(_(" --logfile <path> set an alternate log file\n")); addlist(_(" --noconfirm do not ask for any confirmation\n")); addlist(_(" --confirm always ask for confirmation\n")); @@ -428,10 +434,18 @@ static int parsearg_global(int opt) /* progress bars get wonky with debug on, shut them off */ config->noprogressbar = 1; break; +#ifdef HAVE_LIBGPGME case OP_GPGDIR: free(config->gpgdir); config->gpgdir = strdup(optarg); break; +#endif +#ifdef HAVE_LIBASIGNIFY + case OP_ASIGNIFYDIR: + free(config->asignifydir); + config->asignifydir = strdup(optarg); + break; +#endif case OP_HOOKDIR: config->hookdirs = alpm_list_add(config->hookdirs, strdup(optarg)); break; @@ -944,7 +958,12 @@ static int parseargs(int argc, char *argv[]) {"asexplicit", no_argument, 0, OP_ASEXPLICIT}, {"arch", required_argument, 0, OP_ARCH}, {"print-format", required_argument, 0, OP_PRINTFORMAT}, +#ifdef HAVE_LIBGPGME {"gpgdir", required_argument, 0, OP_GPGDIR}, +#endif +#ifdef HAVE_LIBASIGNIFY + {"asignifydir", required_argument, 0, OP_ASIGNIFYDIR}, +#endif {"dbonly", no_argument, 0, OP_DBONLY}, {"color", required_argument, 0, OP_COLOR}, {"disable-download-timeout", no_argument, 0, OP_DISABLEDLTIMEOUT}, @@ -1217,22 +1236,27 @@ int main(int argc, char *argv[]) if(config->verbose > 0) { alpm_list_t *j; - printf("Root : %s\n", alpm_option_get_root(config->handle)); - printf("Conf File : %s\n", config->configfile); - printf("DB Path : %s\n", alpm_option_get_dbpath(config->handle)); - printf("Cache Dirs: "); + printf("Root : %s\n", alpm_option_get_root(config->handle)); + printf("Conf File : %s\n", config->configfile); + printf("DB Path : %s\n", alpm_option_get_dbpath(config->handle)); + printf("Cache Dirs : "); for(j = alpm_option_get_cachedirs(config->handle); j; j = alpm_list_next(j)) { printf("%s ", (const char *)j->data); } printf("\n"); - printf("Hook Dirs : "); + printf("Hook Dirs : "); for(j = alpm_option_get_hookdirs(config->handle); j; j = alpm_list_next(j)) { printf("%s ", (const char *)j->data); } printf("\n"); - printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle)); - printf("Log File : %s\n", alpm_option_get_logfile(config->handle)); - printf("GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle)); + printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle)); + printf("Log File : %s\n", alpm_option_get_logfile(config->handle)); +#ifdef HAVE_LIBGPGME + printf("GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle)); +#endif +#ifdef HAVE_LIBASIGNIFY + printf("Asignify Dir: %s\n", alpm_option_get_asignifydir(config->handle)); +#endif list_display("Targets :", pm_targets, 0); } -- 2.34.1
Signed-off-by: Jeremy Huntwork <jeremy@merelinux.org> --- doc/pacman.conf.5.asciidoc | 8 ++++++++ etc/pacman.conf.in | 1 + 2 files changed, 9 insertions(+) diff --git a/doc/pacman.conf.5.asciidoc b/doc/pacman.conf.5.asciidoc index 77a3907f..36517b9f 100644 --- a/doc/pacman.conf.5.asciidoc +++ b/doc/pacman.conf.5.asciidoc @@ -89,6 +89,14 @@ Options *NOTE*: this is an absolute path, the root path is not automatically prepended. +*AsignifyDir =* /path/to/asignify/dir:: + Overrides the default location of the directory containing trusted asignify + public keys. The default is +{sysconfdir}/pacman.d/asignify/+. + For packages and repositories signed with asignify, install the appropriate + public key counterparts here. + *NOTE*: this is an absolute path, the root path is not automatically + prepended. + *LogFile =* /path/to/log/file:: Overrides the default location of the pacman log file. The default is +{localstatedir}/log/pacman.log+. This is an absolute path and the root directory diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in index 1799efc7..cc93060a 100644 --- a/etc/pacman.conf.in +++ b/etc/pacman.conf.in @@ -14,6 +14,7 @@ #CacheDir = @localstatedir@/cache/pacman/pkg/ #LogFile = @localstatedir@/log/pacman.log #GPGDir = @sysconfdir@/pacman.d/gnupg/ +#AsignifyDir = @sysconfdir@/pacman.d/asignify/ #HookDir = @sysconfdir@/pacman.d/hooks/ HoldPkg = pacman glibc #XferCommand = /usr/bin/curl -L -C - -f -o %o %u -- 2.34.1
Change the meson configuration so that only one signature method, either gpgme or asignify, is supported at build time. Signed-off-by: Jeremy Huntwork <jeremy@merelinux.org> --- meson.build | 33 ++++++++++++++++++++++++--------- meson_options.txt | 4 ++-- test/pacman/meson.build | 2 +- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index 76b9d2aa..112a2cc5 100644 --- a/meson.build +++ b/meson.build @@ -70,6 +70,7 @@ conf.set_quoted('SYSHOOKDIR', join_paths(DATAROOTDIR, 'libalpm/hooks/')) conf.set_quoted('CONFFILE', join_paths(SYSCONFDIR, 'pacman.conf')) conf.set_quoted('DBPATH', join_paths(LOCALSTATEDIR, 'lib/pacman/')) conf.set_quoted('GPGDIR', join_paths(SYSCONFDIR, 'pacman.d/gnupg/')) +conf.set_quoted('ASIGNIFYDIR', join_paths(SYSCONFDIR, 'pacman.d/asignify/')) conf.set_quoted('LOGFILE', join_paths(LOCALSTATEDIR, 'log/pacman.log')) conf.set_quoted('CACHEDIR', join_paths(LOCALSTATEDIR, 'cache/pacman/pkg/')) conf.set_quoted('HOOKDIR', join_paths(SYSCONFDIR, 'pacman.d/hooks/')) @@ -97,13 +98,24 @@ libcurl = dependency('libcurl', static : get_option('buildstatic')) conf.set('HAVE_LIBCURL', libcurl.found()) -needed_gpgme_version = '>=1.3.0' -gpgme = dependency('gpgme', - version : needed_gpgme_version, - required : get_option('gpgme'), - static : get_option('buildstatic'), - not_found_message : 'gpgme @0@ is needed for GPG signature support'.format(needed_gpgme_version)) -conf.set('HAVE_LIBGPGME', gpgme.found()) +want_signature = get_option('signature') +if want_signature == 'gpgme' + needed_gpgme_version = '>=1.3.0' + gpgme = dependency('gpgme', + version : needed_gpgme_version, + static : get_option('buildstatic'), + not_found_message : 'gpgme @0@ is needed for GPG signature support'.format(needed_gpgme_version)) + signature_provider = gpgme + conf.set10('HAVE_LIBGPGME', gpgme.found()) +elif want_signature == 'asignify' + libasignify = dependency('libasignify', + static : get_option('buildstatic'), + not_found_message : 'libasignify is needed for asignify signature support') + signature_provider = libasignify + conf.set10('HAVE_LIBASIGNIFY', libasignify.found()) +else + error('unhandled signature value @0@'.format(want_signature)) +endif want_crypto = get_option('crypto') if want_crypto == 'openssl' @@ -305,7 +317,7 @@ libcommon = static_library( gnu_symbol_visibility : 'hidden', install : false) -alpm_deps = [crypto_provider, libarchive, libcurl, libintl, gpgme] +alpm_deps = [crypto_provider, signature_provider, libarchive, libcurl, libintl] libalpm_a = static_library( 'alpm_objlib', @@ -454,7 +466,10 @@ message('\n '.join([ ' Build docs : @0@'.format(build_doc), ' debug build : @0@'.format(get_option('buildtype') == 'debug'), ' Use libcurl : @0@'.format(conf.get('HAVE_LIBCURL')), - ' Use GPGME : @0@'.format(conf.get('HAVE_LIBGPGME')), + ' Use libasignify : @0@'.format(conf.has('HAVE_LIBASIGNIFY') and + conf.get('HAVE_LIBASIGNIFY') == 1), + ' Use GPGME : @0@'.format(conf.has('HAVE_LIBGPGME') and + conf.get('HAVE_LIBGPGME') == 1), ' Use OpenSSL : @0@'.format(conf.has('HAVE_LIBSSL') and conf.get('HAVE_LIBSSL') == 1), ' Use nettle : @0@'.format(conf.has('HAVE_LIBNETTLE') and diff --git a/meson_options.txt b/meson_options.txt index 4d8cc300..01d3d2c5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -45,8 +45,8 @@ option('curl', type : 'feature', value : 'auto', option('crypto', type : 'combo', choices : ['openssl', 'nettle'], description : 'select crypto implementation') -option('gpgme', type : 'feature', value : 'auto', - description : 'use GPGME for PGP signature verification') +option('signature', type : 'combo', choices : ['asignify', 'gpgme'], + description : 'select signature verification implementation') option('i18n', type : 'boolean', value : true, description : 'enable localization of pacman, libalpm and scripts') diff --git a/test/pacman/meson.build b/test/pacman/meson.build index ecab75b2..af3d7774 100644 --- a/test/pacman/meson.build +++ b/test/pacman/meson.build @@ -362,7 +362,7 @@ foreach input : pacman_tests if not conf.get('HAVE_LIBCURL') args += '--without-curl' endif - if not conf.get('HAVE_LIBGPGME') + if not conf.has('HAVE_LIBGPGME') or conf.get('HAVE_LIBGPGME') == 0 args += '--without-gpg' endif -- 2.34.1
On Sat, Jan 1, 2022 at 2:49 PM Jeremy Huntwork <jeremy@merelinux.org> wrote:
libasignify provides a simple API for checking ed25519 signatures of blake2 file digests. See: https://github.com/vstakhov/asignify
These changes add support into libalpm, a new configuration option for the location of trusted public keys that libasignify uses, and modify the build to support only one signature method, gpgme or asignify.
A future patch will be needed to add appropriate asignify signing commands to makepkg.
Jeremy Huntwork (4): libalpm: Add support for asignify signatures Add a configuration option for asignify's key dir Add documentation for the AsignifyDir option Update meson for asignify
doc/pacman.conf.5.asciidoc | 8 +++++ etc/pacman.conf.in | 1 + lib/libalpm/alpm.c | 2 +- lib/libalpm/alpm.h | 19 +++++++++++ lib/libalpm/be_package.c | 22 ++++++++++--- lib/libalpm/be_sync.c | 2 +- lib/libalpm/error.c | 8 ++--- lib/libalpm/handle.c | 23 ++++++++++++-- lib/libalpm/handle.h | 1 + lib/libalpm/signing.c | 65 ++++++++++++++++++++++++++++++++++++++ lib/libalpm/signing.h | 1 + meson.build | 33 +++++++++++++------ meson_options.txt | 4 +-- src/pacman/conf.c | 16 ++++++++++ src/pacman/conf.h | 2 ++ src/pacman/pacman.c | 40 ++++++++++++++++++----- test/pacman/meson.build | 2 +- 17 files changed, 216 insertions(+), 33 deletions(-)
Hi, any feedback on this? I'm at the point in my own project where I need to decide how I'm moving forward, so it would be nice to have a feel for which way the wind is blowing. :) Thanks again, JH
On 13/1/22 23:24, Jeremy Huntwork wrote:
On Sat, Jan 1, 2022 at 2:49 PM Jeremy Huntwork <jeremy@merelinux.org> wrote:
libasignify provides a simple API for checking ed25519 signatures of blake2 file digests. See: https://github.com/vstakhov/asignify
These changes add support into libalpm, a new configuration option for the location of trusted public keys that libasignify uses, and modify the build to support only one signature method, gpgme or asignify.
A future patch will be needed to add appropriate asignify signing commands to makepkg.
Jeremy Huntwork (4): libalpm: Add support for asignify signatures Add a configuration option for asignify's key dir Add documentation for the AsignifyDir option Update meson for asignify
doc/pacman.conf.5.asciidoc | 8 +++++ etc/pacman.conf.in | 1 + lib/libalpm/alpm.c | 2 +- lib/libalpm/alpm.h | 19 +++++++++++ lib/libalpm/be_package.c | 22 ++++++++++--- lib/libalpm/be_sync.c | 2 +- lib/libalpm/error.c | 8 ++--- lib/libalpm/handle.c | 23 ++++++++++++-- lib/libalpm/handle.h | 1 + lib/libalpm/signing.c | 65 ++++++++++++++++++++++++++++++++++++++ lib/libalpm/signing.h | 1 + meson.build | 33 +++++++++++++------ meson_options.txt | 4 +-- src/pacman/conf.c | 16 ++++++++++ src/pacman/conf.h | 2 ++ src/pacman/pacman.c | 40 ++++++++++++++++++----- test/pacman/meson.build | 2 +- 17 files changed, 216 insertions(+), 33 deletions(-)
Hi, any feedback on this? I'm at the point in my own project where I need to decide how I'm moving forward, so it would be nice to have a feel for which way the wind is blowing. :)
The wind is not gusting too hard in any direction... I like the approach and the patches look relatively fine, but it seems the number of signify type approaches in the world is increasing. So decisions need to be made looking forward and trying to guess what the landscape will look like over the next few years. My crystal ball is a bit foggy, and I don't have time at the moment to spend clarifying it. If this was using a library *fully* implementing the OpenBSD signify, I would likely accept immediately. That is a format that will likely exist for a while. As far as I can tell, asignify is not used by any other project. It seems to have been dormant from 2015 until 2021, where some development restarted. The positive is that it will read signatures from signify. And that is where I am at considering these patches. I'm not sure what would convince me either way... Allan
On Thu, Jan 13, 2022 at 9:32 AM Allan McRae <allan@archlinux.org> wrote:
The wind is not gusting too hard in any direction... I like the approach and the patches look relatively fine, but it seems the number of signify type approaches in the world is increasing. So decisions need to be made looking forward and trying to guess what the landscape will look like over the next few years. My crystal ball is a bit foggy, and I don't have time at the moment to spend clarifying it.
If this was using a library *fully* implementing the OpenBSD signify, I would likely accept immediately. That is a format that will likely exist for a while.
As far as I can tell, asignify is not used by any other project. It seems to have been dormant from 2015 until 2021, where some development restarted. The positive is that it will read signatures from signify.
And that is where I am at considering these patches. I'm not sure what would convince me either way...
Awesome, thank you, that helps tremendously. I completely understand the reservation about asignify. It helps when there is already wider adoption. As stated elsewhere, I chose it mainly for simplicity - initially the thought of adding in patches to pacman was a bit daunting. I agree that signify or possibly minisign/libsodium would feel more comfortable on that score. Now that I have a better feel for the code base, perhaps I can look at one of those instead. Between those two, would you have a preference? asignify requires libbsd, so I'm inclined to start with minisign, especially as libsodium seems to be broadly used already: https://libsodium.gitbook.io/doc/libsodium_usershttps://libsodium.gitbook.io... JH
On Thu, Jan 13, 2022 at 10:39 AM Jeremy Huntwork <jeremy@merelinux.org> wrote:
used already: https://libsodium.gitbook.io/doc/libsodium_usershttps://libsodium.gitbook.io...
Meh, bad paste sorry. It's probably obvious but the correct link is https://libsodium.gitbook.io/doc/libsodium_users
participants (2)
-
Allan McRae
-
Jeremy Huntwork