Implement inline package signature verification.

This replaces calling out to an external gpg command for verification
with inline verification using the security/netpgpverify library.

Bump version to 20150901.
This commit is contained in:
jperkin 2015-09-01 12:14:05 +00:00
parent 17b2670f7b
commit 747bcb0822
12 changed files with 67 additions and 124 deletions

View file

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.208 2015/04/21 00:28:19 joerg Exp $
# $NetBSD: Makefile,v 1.209 2015/09/01 12:14:05 jperkin Exp $
# Notes to package maintainers:
#
@ -128,6 +128,7 @@ FILESDIR.bzip2?= ${.CURDIR}/../../archivers/bzip2/files
FILESDIR.libarchive?= ${.CURDIR}/../../archivers/libarchive/files
FILESDIR.zlib?= ${.CURDIR}/../../devel/zlib/files
FILESDIR.libfetch?= ${.CURDIR}/../../net/libfetch/files
FILESDIR.netpgpverify?= ${.CURDIR}/../../security/netpgpverify/files
.if empty(USE_BUILTIN.bzip2:M[yY][eE][sS])
CPPFLAGS+= -I${WRKDIR}/bzip2
@ -176,6 +177,10 @@ pre-configure: config-guess-override config-sub-override
.endif
CPPFLAGS+= -I${WRKDIR}/libfetch
LDFLAGS+= -L${WRKDIR}/libfetch
# Avoid duplicate and conflicting headers, pull in any we need
# directly with <netpgpgverify/*.h>
CPPFLAGS+= -I${WRKDIR}
LDFLAGS+= -L${WRKDIR}/netpgpverify
CONFIGURE_ENV+= LIBS=${LIBS:Q}
@ -191,6 +196,7 @@ do-extract:
@${CP} -R ${FILESDIR.libarchive} ${WRKDIR}/libarchive
.endif
@${CP} -R ${FILESDIR.libfetch} ${WRKDIR}/libfetch
@${CP} -R ${FILESDIR.netpgpverify} ${WRKDIR}/netpgpverify
pre-configure:
.if empty(USE_BUILTIN.bzip2:M[yY][eE][sS])
@ -213,7 +219,11 @@ pre-configure:
${SETENV} ${MAKE_ENV} ${BSD_MAKE_ENV} \
${MAKE_PROGRAM} ${MAKE_FLAGS} ${BUILD_MAKE_FLAGS} \
-f ${MAKE_FILE} depend all
cd ${WRKDIR}/netpgpverify && \
${SED} -e '/zlib/d' Makefile.lib.in >Makefile.in && \
./configure && ${SETENV} ${MAKE_ENV} ${BSD_MAKE_ENV} \
${MAKE_PROGRAM} ${MAKE_FLAGS} ${BUILD_MAKE_FLAGS} \
-f ${MAKE_FILE} all
# XXX Reverse the order that update does things since
# XXX we need pkg_delete built before we can deinstall.

View file

@ -1,4 +1,4 @@
# $NetBSD: Makefile.in,v 1.29 2015/01/22 09:19:47 jperkin Exp $
# $NetBSD: Makefile.in,v 1.30 2015/09/01 12:14:06 jperkin Exp $
srcdir= @srcdir@
@ -20,7 +20,7 @@ LDFLAGS= @LDFLAGS@ -L../lib
SSL_SUPPORT= @ssl_support@
LIBS= -linstall -larchive -lfetch
LIBS= -linstall -larchive -lfetch -lnetpgpverify
.if !empty(SSL_SUPPORT)
LIBS+= -lssl -lcrypto
.endif

View file

@ -1,4 +1,4 @@
# $NetBSD: Makefile.in,v 1.27 2015/01/22 09:19:47 jperkin Exp $
# $NetBSD: Makefile.in,v 1.28 2015/09/01 12:14:06 jperkin Exp $
srcdir= @srcdir@
@ -28,7 +28,7 @@ PROG= pkg_admin
SCRIPTS= audit-packages download-vulnerability-list
.if empty(BOOTSTRAP)
LIBS= -linstall -larchive -lfetch
LIBS= -linstall -larchive -lfetch -lnetpgpverify
.if !empty(SSL_SUPPORT)
LIBS+= -lssl -lcrypto
CFLAGS+= -DHAVE_SSL

View file

@ -1,4 +1,4 @@
# $NetBSD: Makefile.in,v 1.25 2015/01/22 09:19:47 jperkin Exp $
# $NetBSD: Makefile.in,v 1.26 2015/09/01 12:14:06 jperkin Exp $
srcdir= @srcdir@
@ -26,7 +26,7 @@ PROG= pkg_create
SSL_SUPPORT= @ssl_support@
.if empty(BOOTSTRAP)
LIBS= -linstall -larchive -lfetch @LIBS@
LIBS= -linstall -larchive -lfetch -lnetpgpverify @LIBS@
.if !empty(SSL_SUPPORT)
LIBS+= -lssl -lcrypto
.endif

View file

@ -1,4 +1,4 @@
# $NetBSD: Makefile.in,v 1.22 2015/01/22 09:19:47 jperkin Exp $
# $NetBSD: Makefile.in,v 1.23 2015/09/01 12:14:06 jperkin Exp $
srcdir= @srcdir@
@ -15,7 +15,7 @@ SSL_SUPPORT= @ssl_support@
CC= @CC@
CCLD= $(CC)
LIBS= -linstall -larchive -lfetch @LIBS@
LIBS= -linstall -larchive -lfetch -lnetpgpverify @LIBS@
.if !empty(SSL_SUPPORT)
LIBS+= -lssl -lcrypto

View file

@ -1,4 +1,4 @@
# $NetBSD: Makefile.in,v 1.28 2015/01/22 09:19:47 jperkin Exp $
# $NetBSD: Makefile.in,v 1.29 2015/09/01 12:14:06 jperkin Exp $
srcdir= @srcdir@
@ -17,7 +17,7 @@ SSL_SUPPORT= @ssl_support@
CC= @CC@
CCLD= $(CC)
.if empty(BOOTSTRAP)
LIBS= -linstall -larchive -lfetch @LIBS@
LIBS= -linstall -larchive -lfetch -lnetpgpverify @LIBS@
.if !empty(SSL_SUPPORT)
LIBS+= -lssl -lcrypto
.endif

View file

@ -1,4 +1,4 @@
# $NetBSD: Makefile.in,v 1.34 2013/09/12 11:03:10 jperkin Exp $
# $NetBSD: Makefile.in,v 1.35 2015/09/01 12:14:06 jperkin Exp $
srcdir= @srcdir@
@ -27,7 +27,7 @@ INSTALL= @INSTALL@
LIB= libinstall.a
OBJS= automatic.o conflicts.o dewey.o fexec.o file.o \
gpgsig.o global.o iterate.o license.o lpkg.o opattern.o \
global.o iterate.o license.o lpkg.o opattern.o \
parse-config.o pkgdb.o plist.o remove.o \
str.o var.o version.o vulnerabilities-file.o xwrapper.o
@ -36,7 +36,7 @@ CPPFLAGS+= -DSYSCONFDIR=\"$(sysconfdir)\"
.if !empty(BOOTSTRAP)
CPPFLAGS+= -DBOOTSTRAP
.else
OBJS+= pkg_io.o pkg_signature.o
OBJS+= gpgsig.o pkg_io.o pkg_signature.o
.endif
.if !empty(SSL_SUPPORT)

View file

@ -1,4 +1,4 @@
/* $NetBSD: gpgsig.c,v 1.3 2009/08/02 17:56:45 joerg Exp $ */
/* $NetBSD: gpgsig.c,v 1.4 2015/09/01 12:14:06 jperkin Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
#endif
@ -7,7 +7,7 @@
#include <sys/cdefs.h>
#endif
__RCSID("$NetBSD: gpgsig.c,v 1.3 2009/08/02 17:56:45 joerg Exp $");
__RCSID("$NetBSD: gpgsig.c,v 1.4 2015/09/01 12:14:06 jperkin Exp $");
/*-
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
@ -51,105 +51,45 @@ __RCSID("$NetBSD: gpgsig.c,v 1.3 2009/08/02 17:56:45 joerg Exp $");
#endif
#include "lib.h"
static void
verify_signature(const char *input, size_t input_len, const char *keyring,
const char *detached_signature)
{
const char *argv[8], **argvp;
pid_t child;
int fd[2], status;
if (pipe(fd) == -1)
err(EXIT_FAILURE, "cannot create input pipes");
child = vfork();
if (child == -1)
err(EXIT_FAILURE, "cannot fork GPG process");
if (child == 0) {
close(fd[1]);
close(STDIN_FILENO);
if (dup2(fd[0], STDIN_FILENO) == -1) {
static const char err_msg[] =
"cannot redirect stdin of GPG process\n";
write(STDERR_FILENO, err_msg, sizeof(err_msg) - 1);
_exit(255);
}
close(fd[0]);
argvp = argv;
*argvp++ = gpg_cmd;
*argvp++ = "--verify";
if (keyring != NULL) {
*argvp++ = "--no-default-keyring";
*argvp++ = "--keyring";
*argvp++ = keyring;
}
if (detached_signature != NULL)
*argvp++ = detached_signature;
*argvp++ = "-";
*argvp = NULL;
execvp(gpg_cmd, __UNCONST(argv));
_exit(255);
}
close(fd[0]);
if (write(fd[1], input, input_len) != (ssize_t)input_len)
errx(EXIT_FAILURE, "Short read from GPG");
close(fd[1]);
waitpid(child, &status, 0);
if (status)
errx(EXIT_FAILURE, "GPG could not verify the signature");
}
#include "netpgpverify/verify.h"
int
inline_gpg_verify(const char *content, size_t len, const char *keyring)
gpg_verify(const char *content, size_t len, const char *keyring,
const char *sig, size_t sig_len)
{
verify_signature(content, len, keyring, NULL);
pgpv_t pgp;
pgpv_cursor_t cursor;
static const char hdr1[] = "-----BEGIN PGP SIGNED MESSAGE-----\n";
static const char hdr2[] = "Hash: SHA512\n\n";
ssize_t buflen;
char *buf;
return 0;
}
int
detached_gpg_verify(const char *content, size_t len,
const char *signature, size_t signature_len, const char *keyring)
{
int fd;
const char *tmpdir;
char *tempsig;
ssize_t ret;
if (gpg_cmd == NULL) {
warnx("GPG variable not set, failing signature check");
return -1;
/*
* If there is a detached signature we need to construct a format that
* netpgp can parse, otherwise use as-is.
*/
if (sig_len) {
buf = xasprintf("%s%s%s%s", hdr1, hdr2, content, sig);
buflen = strlen(buf);
} else {
buf = content;
buflen = len;
}
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = "/tmp";
tempsig = xasprintf("%s/pkg_install.XXXXXX", tmpdir);
memset(&pgp, 0, sizeof(pgp));
memset(&cursor, 0, sizeof(cursor));
fd = mkstemp(tempsig);
if (fd == -1) {
warnx("Creating temporary file for GPG signature failed");
return -1;
}
if (!pgpv_read_pubring(&pgp, keyring, -1))
err(EXIT_FAILURE, "cannot read keyring");
while (signature_len) {
ret = write(fd, signature, signature_len);
if (ret == -1)
err(EXIT_FAILURE, "Write to GPG failed");
if (ret == 0)
errx(EXIT_FAILURE, "Short write to GPG");
signature_len -= ret;
signature += ret;
}
if (!pgpv_verify(&cursor, &pgp, buf, buflen))
errx(EXIT_FAILURE, "unable to verify signature: %s",
cursor.why);
verify_signature(content, len, keyring, tempsig);
pgpv_close(&pgp);
unlink(tempsig);
close(fd);
free(tempsig);
if (sig_len)
free(buf);
return 0;
}

View file

@ -1,4 +1,4 @@
/* $NetBSD: lib.h,v 1.65 2014/12/30 15:13:21 wiz Exp $ */
/* $NetBSD: lib.h,v 1.66 2015/09/01 12:14:06 jperkin Exp $ */
/* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */
@ -400,9 +400,7 @@ int easy_pkcs7_sign(const char *, size_t, char **, size_t *, const char *,
const char *);
#endif
int inline_gpg_verify(const char *, size_t, const char *);
int detached_gpg_verify(const char *, size_t, const char *, size_t,
const char *);
int gpg_verify(const char *, size_t, const char *, const char *, size_t);
int detached_gpg_sign(const char *, size_t, char **, size_t *, const char *,
const char *);

View file

@ -1,4 +1,4 @@
/* $NetBSD: pkg_signature.c,v 1.11 2013/09/11 14:10:05 khorben Exp $ */
/* $NetBSD: pkg_signature.c,v 1.12 2015/09/01 12:14:06 jperkin Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
@ -7,7 +7,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
__RCSID("$NetBSD: pkg_signature.c,v 1.11 2013/09/11 14:10:05 khorben Exp $");
__RCSID("$NetBSD: pkg_signature.c,v 1.12 2015/09/01 12:14:06 jperkin Exp $");
/*-
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
@ -366,8 +366,8 @@ pkg_verify_signature(const char *archive_name, struct archive **archive,
free(state);
goto no_valid_signature;
}
has_sig = !detached_gpg_verify(hash_file, hash_len,
signature_file, signature_len, gpg_keyring_verify);
has_sig = !gpg_verify(hash_file, hash_len, gpg_keyring_verify,
signature_file, signature_len);
free(signature_file);
} else {

View file

@ -1,4 +1,4 @@
/* $NetBSD: version.h,v 1.168 2015/05/08 16:29:37 agc Exp $ */
/* $NetBSD: version.h,v 1.169 2015/09/01 12:14:06 jperkin Exp $ */
/*
* Copyright (c) 2001 Thomas Klausner. All rights reserved.
@ -27,6 +27,6 @@
#ifndef _INST_LIB_VERSION_H_
#define _INST_LIB_VERSION_H_
#define PKGTOOLS_VERSION 20150508
#define PKGTOOLS_VERSION 20150901
#endif /* _INST_LIB_VERSION_H_ */

View file

@ -1,4 +1,4 @@
/* $NetBSD: vulnerabilities-file.c,v 1.7 2010/06/16 23:02:49 joerg Exp $ */
/* $NetBSD: vulnerabilities-file.c,v 1.8 2015/09/01 12:14:06 jperkin Exp $ */
/*-
* Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org>.
@ -38,7 +38,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
__RCSID("$NetBSD: vulnerabilities-file.c,v 1.7 2010/06/16 23:02:49 joerg Exp $");
__RCSID("$NetBSD: vulnerabilities-file.c,v 1.8 2015/09/01 12:14:06 jperkin Exp $");
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
@ -110,12 +110,7 @@ verify_signature_pkcs7(const char *input)
static void
verify_signature(const char *input, size_t input_len)
{
if (gpg_cmd == NULL && certs_pkg_vulnerabilities == NULL)
errx(EXIT_FAILURE,
"At least GPG or CERTIFICATE_ANCHOR_PKGVULN "
"must be configured");
if (gpg_cmd != NULL)
inline_gpg_verify(input, input_len, gpg_keyring_pkgvuln);
gpg_verify(input, input_len, gpg_keyring_pkgvuln, NULL, 0);
if (certs_pkg_vulnerabilities != NULL)
verify_signature_pkcs7(input);
}