diff options
author | agc <agc@pkgsrc.org> | 2014-02-04 02:11:18 +0000 |
---|---|---|
committer | agc <agc@pkgsrc.org> | 2014-02-04 02:11:18 +0000 |
commit | a145a45761dc7d12bd7a4c8f68d50f2fcfcb7fd1 (patch) | |
tree | c57375724b589f375d29b5f60052936a55ece8dd /security | |
parent | 5466d91855ee1f75903d32b0ba24be1cb9b38f83 (diff) | |
download | pkgsrc-a145a45761dc7d12bd7a4c8f68d50f2fcfcb7fd1.tar.gz |
Update security/netpgpverify to version 20140202
Changes from previous version:
Add the ability for netpgpverify to verify ssh-pub-key-based signatures.
It is much more likely for ssh (rather than pgp) keys to be available,
and used, as a source of authentication data. These changes add the
ability for netpgpverify(1) -- the standalone, zero-prereq utility -
to verify signatures made by netpgp when using ssh keys.
Running the regression tests in WRKDIR gives the following output:
% mk -f *.bsd tst
./netpgpverify -k pubring.gpg NetBSD-6.0_RC1_hashes.asc
Good signature for NetBSD-6.0_RC1_hashes.asc made Thu Aug 23 11:47:50 2012
signature 4096/RSA (Encrypt or Sign) 064973ac4c4a706e 2009-06-23
fingerprint ddee 2bdb 9c98 a0d1 d4fb dbf7 0649 73ac 4c4a 706e
uid NetBSD Security Officer <security-officer@NetBSD.org>
./netpgpverify -k pubring.gpg NetBSD-6.0_RC1_hashes.gpg
Good signature for NetBSD-6.0_RC1_hashes.gpg made Thu Mar 14 13:32:59 2013
signature 4096/RSA (Encrypt or Sign) 064973ac4c4a706e 2009-06-23
fingerprint ddee 2bdb 9c98 a0d1 d4fb dbf7 0649 73ac 4c4a 706e
uid NetBSD Security Officer <security-officer@NetBSD.org>
./netpgpverify -v
netpgpverify portable 20140202
./netpgpverify -S sshtest-20140202.pub data.gpg
Good signature for data.gpg made Mon Feb 3 17:54:21 2014
signature 4096/RSA (Encrypt or Sign) 4d129225945bbb8f 1970-01-01
fingerprint 874b 75de d6a3 341f 2d5a 2219 4d12 9225 945b bb8f
uid netbsd-001.cupertino.alistaircrooks.com (sshtest-20140202.pub) <agc@netbsd-001.cupertino.alistaircrooks.com>
./netpgpverify -S sshtest-20140202.pub data.sig
Good signature for data.sig made Sun Feb 2 21:45:05 2014
signature 4096/RSA (Encrypt or Sign) 4d129225945bbb8f 1970-01-01
fingerprint 874b 75de d6a3 341f 2d5a 2219 4d12 9225 945b bb8f
uid netbsd-001.cupertino.alistaircrooks.com (sshtest-20140202.pub) <agc@netbsd-001.cupertino.alistaircrooks.com>
expected failure, to check bad signatures fail to verify
sed -e 's|A|B|' data.gpg | ./netpgpverify -S sshtest-20140202.pub
Signature did not match contents -- Signature on data did not match
*** Error code 1 (ignored)
%
A new HOWTO file is provided in the sources (files/HOWTO) to show how
to sign data using ssh keys and netpgp(1).
Diffstat (limited to 'security')
-rw-r--r-- | security/netpgpverify/Makefile | 6 | ||||
-rw-r--r-- | security/netpgpverify/files/Makefile.bsd | 23 | ||||
-rw-r--r-- | security/netpgpverify/files/Makefile.in | 9 | ||||
-rw-r--r-- | security/netpgpverify/files/bignum.c | 2 | ||||
-rw-r--r-- | security/netpgpverify/files/bufgap.c | 508 | ||||
-rw-r--r-- | security/netpgpverify/files/bufgap.h | 88 | ||||
-rwxr-xr-x | security/netpgpverify/files/chk.sh | 119 | ||||
-rw-r--r-- | security/netpgpverify/files/data | 28 | ||||
-rw-r--r-- | security/netpgpverify/files/data.gpg | bin | 0 -> 1056 bytes | |||
-rw-r--r-- | security/netpgpverify/files/data.sig | bin | 0 -> 549 bytes | |||
-rw-r--r-- | security/netpgpverify/files/defs.h | 92 | ||||
-rw-r--r-- | security/netpgpverify/files/libverify.c | 389 | ||||
-rw-r--r-- | security/netpgpverify/files/main.c | 34 | ||||
-rw-r--r-- | security/netpgpverify/files/netpgpverify.1 | 28 | ||||
-rw-r--r-- | security/netpgpverify/files/pubring.gpg | bin | 19264 -> 2009747 bytes | |||
-rw-r--r-- | security/netpgpverify/files/sshtest-20140202 | 51 | ||||
-rw-r--r-- | security/netpgpverify/files/sshtest-20140202.pub | 1 | ||||
-rw-r--r-- | security/netpgpverify/files/verify.h | 10 |
18 files changed, 1324 insertions, 64 deletions
diff --git a/security/netpgpverify/Makefile b/security/netpgpverify/Makefile index 0d7c4cd454b..c7682b3793f 100644 --- a/security/netpgpverify/Makefile +++ b/security/netpgpverify/Makefile @@ -1,13 +1,13 @@ -# $NetBSD: Makefile,v 1.4 2013/12/20 17:16:48 agc Exp $ +# $NetBSD: Makefile,v 1.5 2014/02/04 02:11:18 agc Exp $ -DISTNAME= netpgpverify-20131219 +DISTNAME= netpgpverify-20140202 CATEGORIES= security MASTER_SITES= # empty DISTFILES= # empty MAINTAINER= agc@NetBSD.org HOMEPAGE= http://www.NetBSD.org/ -COMMENT= Standalone PGP signature verification utility +COMMENT= Standalone PGP and ssh signature verification utility LICENSE= modified-bsd AUTO_MKDIRS= yes diff --git a/security/netpgpverify/files/Makefile.bsd b/security/netpgpverify/files/Makefile.bsd index 95a445a4181..327bc74e877 100644 --- a/security/netpgpverify/files/Makefile.bsd +++ b/security/netpgpverify/files/Makefile.bsd @@ -1,23 +1,32 @@ -# $NetBSD: Makefile.bsd,v 1.1 2013/03/16 07:32:34 agc Exp $ +# $NetBSD: Makefile.bsd,v 1.2 2014/02/04 02:11:18 agc Exp $ PROG=netpgpverify -SRCS= b64.c bignum.c digest.c +SRCS= b64.c bignum.c bufgap.c digest.c SRCS+= libverify.c main.c misc.c SRCS+= pgpsum.c rsa.c -SRCS+= tiger.c SRCS+= bzlib.c zlib.c -SRCS+= sha1.c sha2.c md5c.c rmd160.c +SRCS+= md5c.c rmd160.c sha1.c sha2.c tiger.c -MAN=netpgpverify.1 +CPPFLAGS+=-I. -WARNS=5 +.ifndef PRODUCTION +CPPFLAGS+=-g -O0 +LDFLAGS+=-g -O0 +.endif + +MAN= netpgpverify.1 +WARNS= 6 .include <bsd.prog.mk> -t: ${PROG} +tst: ./${PROG} -k pubring.gpg NetBSD-6.0_RC1_hashes.asc ./${PROG} -k pubring.gpg NetBSD-6.0_RC1_hashes.gpg ./${PROG} -v + ./${PROG} -S sshtest-20140202.pub data.gpg + ./${PROG} -S sshtest-20140202.pub data.sig + @echo "expected failure, to check bad signatures fail to verify" + -sed -e 's|A|B|' data.gpg | ./${PROG} -S sshtest-20140202.pub diff --git a/security/netpgpverify/files/Makefile.in b/security/netpgpverify/files/Makefile.in index e04f7f40d3e..b5556238865 100644 --- a/security/netpgpverify/files/Makefile.in +++ b/security/netpgpverify/files/Makefile.in @@ -1,15 +1,14 @@ -# $NetBSD: Makefile.in,v 1.1 2013/03/16 07:32:34 agc Exp $ +# $NetBSD: Makefile.in,v 1.2 2014/02/04 02:11:18 agc Exp $ PROG=netpgpverify -OBJS= b64.o bignum.o digest.o +OBJS= b64.o bignum.o bufgap.o digest.o OBJS+= libverify.o main.o misc.o OBJS+= pgpsum.o rsa.o -OBJS+= tiger.o OBJS+= bzlib.o zlib.o -OBJS+= sha1.o sha2.o md5c.o rmd160.o +OBJS+= sha1.o sha2.o md5c.o rmd160.o tiger.o PREFIX=@PREFIX@ MANDIR=@MANDIR@ @@ -27,6 +26,8 @@ tst: ./${PROG} -k pubring.gpg NetBSD-6.0_RC1_hashes.asc ./${PROG} -k pubring.gpg NetBSD-6.0_RC1_hashes.gpg ./${PROG} -v + ./${PROG} -S testkey.pub data.gpg + ./${PROG} -S testkey.pub data.sig clean: rm -rf *.core ${OBJS} ${PROG} diff --git a/security/netpgpverify/files/bignum.c b/security/netpgpverify/files/bignum.c index e983005328a..c825b30c501 100644 --- a/security/netpgpverify/files/bignum.c +++ b/security/netpgpverify/files/bignum.c @@ -5157,7 +5157,7 @@ getbn(BIGNUM **a, const char *str, int radix) if (mp_getradix_num(*a, radix, __UNCONST(str)) != MP_OKAY) { return 0; } - mp_radix_size(__UNCONST(*a), radix, &len); + mp_radix_size(__UNCONST(a), radix, &len); return len - 1; } diff --git a/security/netpgpverify/files/bufgap.c b/security/netpgpverify/files/bufgap.c new file mode 100644 index 00000000000..66a30ec5dcd --- /dev/null +++ b/security/netpgpverify/files/bufgap.c @@ -0,0 +1,508 @@ +/* $NetBSD: bufgap.c,v 1.1 2014/02/04 02:11:18 agc Exp $ */ + +/*- + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alistair Crooks (agc@NetBSD.org) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" + +#include <sys/types.h> +#include <sys/stat.h> + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "bufgap.h" +#include "defs.h" + +/* macros to get subscripts in buffer */ +#define AFTSUB(bp, n) ((bp)->buf[(int)n]) +#define BEFSUB(bp, n) ((bp)->buf[(int)((bp)->size - (n) - 1)]) + +/* initial allocation size */ +#ifndef CHUNKSIZE +#define CHUNKSIZE 256 +#endif + +#ifndef KiB +#define KiB(x) ((x) * 1024) +#endif + +#define BGCHUNKSIZE KiB(4) + +#ifndef __UNCONST +#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) +#endif + +#ifndef USE_UTF +#define USE_UTF 0 +#endif + +#if !USE_UTF +#define Rune char +#define utfbytes(x) strlen(x) +#define utfrune(a, b) strchr(a, b) +#define utfnlen(a, b) bounded_strlen(a, b) + +static size_t +bounded_strlen(const char *s, size_t maxlen) +{ + size_t n; + + for (n = 0 ; n < maxlen && s[n] != 0x0 ; n++) { + } + return n; +} + +static int +chartorune(Rune *rp, char *s) +{ + *rp = s[0]; + return 1; +} + +static int +priorrune(Rune *rp, char *s) +{ + *rp = s[0]; + return 1; +} +#else +#include "ure.h" +#endif + +/* save `n' chars of `s' in malloc'd memory */ +static char * +strnsave(char *s, int n) +{ + char *cp; + + if (n < 0) { + n = (int)strlen(s); + } + NEWARRAY(char, cp, n + 1, "strnsave", return NULL); + (void) memcpy(cp, s, (size_t)n); + cp[n] = 0x0; + return cp; +} + +/* open a file in a buffer gap structure */ +int +bufgap_open(bufgap_t *bp, const char *f) +{ + struct stat s; + int64_t cc; + FILE *filep; + char *cp; + + (void) memset(bp, 0x0, sizeof(*bp)); + filep = NULL; + if (f != NULL && (filep = fopen(f, "r")) == NULL) { + return 0; + } + if (f == NULL) { + bp->size = BGCHUNKSIZE; + NEWARRAY(char, bp->buf, bp->size, "f_open", return 0); + } else { + (void) fstat(fileno(filep), &s); + bp->size = (int) ((s.st_size / BGCHUNKSIZE) + 1) * BGCHUNKSIZE; + NEWARRAY(char, bp->buf, bp->size, "f_open", return 0); + cc = fread(&BEFSUB(bp, s.st_size), sizeof(char), + (size_t)s.st_size, filep); + (void) fclose(filep); + if (cc != s.st_size) { + FREE(bp->buf); + FREE(bp); + return 0; + } + bp->name = strnsave(__UNCONST(f), (int)utfbytes(__UNCONST(f))); + bp->bbc = s.st_size; + cp = &BEFSUB(bp, cc); + for (;;) { + if ((cp = utfrune(cp, '\n')) == NULL) { + break; + } + bp->blc++; + cp++; + } + bp->bcc = utfnlen(&BEFSUB(bp, cc), (size_t)cc); + } + return 1; +} + +/* close a buffer gapped file */ +void +bufgap_close(bufgap_t *bp) +{ + FREE(bp->buf); +} + +/* move forwards `n' chars/bytes in a buffer gap */ +int +bufgap_forwards(bufgap_t *bp, uint64_t n, int type) +{ + Rune r; + int rlen; + + switch(type) { + case BGChar: + if (bp->bcc >= n) { + while (n-- > 0) { + rlen = chartorune(&r, &BEFSUB(bp, bp->bbc)); + if (rlen == 1) { + AFTSUB(bp, bp->abc) = BEFSUB(bp, bp->bbc); + } else { + (void) memmove(&AFTSUB(bp, bp->abc), + &BEFSUB(bp, bp->bbc), + (size_t)rlen); + } + bp->acc++; + bp->bcc--; + bp->abc += rlen; + bp->bbc -= rlen; + if (r == '\n') { + bp->alc++; + bp->blc--; + } + } + return 1; + } + break; + case BGByte: + if (bp->bbc >= n) { + for ( ; n > 0 ; n -= rlen) { + rlen = chartorune(&r, &BEFSUB(bp, bp->bbc)); + if (rlen == 1) { + AFTSUB(bp, bp->abc) = BEFSUB(bp, bp->bbc); + } else { + (void) memmove(&AFTSUB(bp, bp->abc), + &BEFSUB(bp, bp->bbc), + (size_t)rlen); + } + bp->acc++; + bp->bcc--; + bp->abc += rlen; + bp->bbc -= rlen; + if (r == '\n') { + bp->alc++; + bp->blc--; + } + } + return 1; + } + } + return 0; +} + +/* move backwards `n' chars in a buffer gap */ +int +bufgap_backwards(bufgap_t *bp, uint64_t n, int type) +{ + Rune r; + int rlen; + + switch(type) { + case BGChar: + if (bp->acc >= n) { + while (n-- > 0) { + rlen = priorrune(&r, &AFTSUB(bp, bp->abc)); + bp->bcc++; + bp->acc--; + bp->bbc += rlen; + bp->abc -= rlen; + if (rlen == 1) { + BEFSUB(bp, bp->bbc) = AFTSUB(bp, bp->abc); + } else { + (void) memmove(&BEFSUB(bp, bp->bbc), + &AFTSUB(bp, bp->abc), + (size_t)rlen); + } + if (r == '\n') { + bp->blc++; + bp->alc--; + } + } + return 1; + } + break; + case BGByte: + if (bp->acc >= n) { + for ( ; n > 0 ; n -= rlen) { + rlen = priorrune(&r, &AFTSUB(bp, bp->abc)); + bp->bcc++; + bp->acc--; + bp->bbc += rlen; + bp->abc -= rlen; + if (rlen == 1) { + BEFSUB(bp, bp->bbc) = AFTSUB(bp, bp->abc); + } else { + (void) memmove(&BEFSUB(bp, bp->bbc), + &AFTSUB(bp, bp->abc), + (size_t)rlen); + } + if (r == '\n') { + bp->blc++; + bp->alc--; + } + } + return 1; + } + } + return 0; +} + +/* move within a buffer gap */ +int +bufgap_seek(bufgap_t *bp, int64_t off, int whence, int type) +{ + switch(type) { + case BGLine: + switch(whence) { + case BGFromBOF: + if (off < 0 || off > (int64_t)(bp->alc + bp->blc)) { + return 0; + } + if (off < (int64_t)bp->alc) { + while (off <= (int64_t)bp->alc && bufgap_backwards(bp, 1, BGChar)) { + } + if (off > 0) { + (void) bufgap_forwards(bp, 1, BGChar); + } + } else if (off > (int64_t)bp->alc) { + while (off > (int64_t)bp->alc && bufgap_forwards(bp, 1, BGChar)) { + } + } + return 1; + case BGFromHere: + return bufgap_seek(bp, (int64_t)(bp->alc + off), BGFromBOF, BGLine); + case BGFromEOF: + return bufgap_seek(bp, (int64_t)(bp->alc + bp->blc + off), BGFromBOF, BGLine); + } + break; + case BGChar: + switch(whence) { + case BGFromBOF: + if (off < 0 || off > (int64_t)(bp->acc + bp->bcc)) { + return 0; + } + if (off < (int64_t)bp->acc) { + return bufgap_backwards(bp, bp->acc - off, BGChar); + } else if (off > (int64_t)bp->acc) { + return bufgap_forwards(bp, off - bp->acc, BGChar); + } + return 1; + case BGFromHere: + return bufgap_seek(bp, (int64_t)(bp->acc + off), BGFromBOF, BGChar); + case BGFromEOF: + return bufgap_seek(bp, (int64_t)(bp->acc + bp->bcc + off), BGFromBOF, BGChar); + } + break; + case BGByte: + switch(whence) { + case BGFromBOF: + if (off < 0 || off > (int64_t)(bp->abc + bp->bbc)) { + return 0; + } + if (off < (int64_t)bp->abc) { + return bufgap_backwards(bp, bp->abc - off, BGByte); + } else if (off > (int64_t)bp->abc) { + return bufgap_forwards(bp, off - bp->abc, BGByte); + } + return 1; + case BGFromHere: + return bufgap_seek(bp, (int64_t)(bp->abc + off), BGFromBOF, BGByte); + case BGFromEOF: + return bufgap_seek(bp, (int64_t)(bp->abc + bp->bbc + off), BGFromBOF, BGByte); + } + break; + } + return 0; +} + +/* return a pointer to the text in the buffer gap */ +char * +bufgap_getstr(bufgap_t *bp) +{ + return &BEFSUB(bp, bp->bbc); +} + +/* return the binary text in the buffer gap */ +int +bufgap_getbin(bufgap_t *bp, void *dst, size_t len) +{ + int cc; + + cc = (bp->bcc < len) ? (int)bp->bcc : (int)len; + (void) memcpy(dst, &BEFSUB(bp, bp->bbc), len); + return cc; +} + +/* return offset (from beginning/end) in a buffer gap */ +int64_t +bufgap_tell(bufgap_t *bp, int whence, int type) +{ + switch(whence) { + case BGFromBOF: + return (type == BGLine) ? bp->alc : + (type == BGByte) ? bp->abc : bp->acc; + case BGFromEOF: + return (type == BGLine) ? bp->blc : + (type == BGByte) ? bp->bbc : bp->bcc; + default: + (void) fprintf(stderr, "weird whence in bufgap_tell\n"); + break; + } + return (int64_t)0; +} + +/* return size of buffer gap */ +int64_t +bufgap_size(bufgap_t *bp, int type) +{ + return (type == BGLine) ? bp->alc + bp->blc : + (type == BGChar) ? bp->acc + bp->bcc : + bp->abc + bp->bbc; +} + +/* insert `n' chars of `s' in a buffer gap */ +int +bufgap_insert(bufgap_t *bp, const char *s, int n) +{ + int64_t off; + Rune r; + int rlen; + int i; + + if (n < 0) { + n = (int)strlen(s); + } + for (i = 0 ; i < n ; i += rlen) { + if (bp->bbc + bp->abc == bp->size) { + off = bufgap_tell(bp, BGFromBOF, BGChar); + (void) bufgap_seek(bp, 0, BGFromEOF, BGChar); + bp->size *= 2; + RENEW(char, bp->buf, bp->size, "bufgap_insert", return 0); + (void) bufgap_seek(bp, off, BGFromBOF, BGChar); + } + if ((rlen = chartorune(&r, __UNCONST(s))) == 1) { + AFTSUB(bp, bp->abc) = *s; + } else { + (void) memmove(&AFTSUB(bp, bp->abc), s, (size_t)rlen); + } + if (r == '\n') { + bp->alc++; + } + bp->modified = 1; + bp->abc += rlen; + bp->acc++; + s += rlen; + } + return 1; +} + +/* delete `n' bytes from the buffer gap */ +int +bufgap_delete(bufgap_t *bp, uint64_t n) +{ + uint64_t i; + Rune r; + int rlen; + + if (n <= bp->bbc) { + for (i = 0 ; i < n ; i += rlen) { + rlen = chartorune(&r, &BEFSUB(bp, bp->bbc)); + if (r == '\n') { + bp->blc--; + } + bp->bbc -= rlen; + bp->bcc--; + bp->modified = 1; + } + return 1; + } + return 0; +} + +/* look at a character in a buffer gap `delta' UTF chars away */ +int +bufgap_peek(bufgap_t *bp, int64_t delta) +{ + int ch; + + if (delta != 0) { + if (!bufgap_seek(bp, delta, BGFromHere, BGChar)) { + return -1; + } + } + ch = BEFSUB(bp, bp->bbc); + if (delta != 0) { + (void) bufgap_seek(bp, -delta, BGFromHere, BGChar); + } + return ch; +} + +/* return, in malloc'd storage, text from the buffer gap */ +char * +bufgap_gettext(bufgap_t *bp, int64_t from, int64_t to) +{ + int64_t off; + int64_t n; + char *text; + + off = bufgap_tell(bp, BGFromBOF, BGChar); + NEWARRAY(char, text, (to - from + 1), "bufgap_gettext", return NULL); + (void) bufgap_seek(bp, from, BGFromBOF, BGChar); + for (n = 0 ; n < to - from ; n++) { + text[(int)n] = BEFSUB(bp, bp->bbc - n); + } + text[(int)n] = 0x0; + (void) bufgap_seek(bp, off, BGFromBOF, BGChar); + return text; +} + +/* return 1 if we wrote the file correctly */ +int +bufgap_write(bufgap_t *bp, FILE *filep) +{ + if (fwrite(bp->buf, sizeof(char), (size_t)bp->abc, filep) != (size_t)bp->abc) { + return 0; + } + if (fwrite(&BEFSUB(bp, bp->bbc), sizeof(char), (size_t)bp->bbc, filep) != (size_t)bp->bbc) { + return 0; + } + return 1; +} + +/* tell if the buffer gap is dirty - has been modified */ +int +bufgap_dirty(bufgap_t *bp) +{ + return (int)bp->modified; +} diff --git a/security/netpgpverify/files/bufgap.h b/security/netpgpverify/files/bufgap.h new file mode 100644 index 00000000000..1ad24679cc6 --- /dev/null +++ b/security/netpgpverify/files/bufgap.h @@ -0,0 +1,88 @@ +/* $NetBSD: bufgap.h,v 1.1 2014/02/04 02:11:18 agc Exp $ */ + +/*- + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alistair Crooks (agc@NetBSD.org) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef BUFGAP_H_ +#define BUFGAP_H_ 20091023 + +#include <sys/types.h> + +#include <inttypes.h> +#include <stdio.h> + +#ifndef BUFGAP_VERSION_STRING +#define BUFGAP_VERSION_STRING "20091022" +#endif + +#ifndef BUFGAP_AUTHOR_STRING +#define BUFGAP_AUTHOR_STRING "Alistair Crooks (agc@netbsd.org)" +#endif + +/* Constants for Buffer Gap routines */ +enum { + BGByte, + BGChar, + BGLine, + + BGFromBOF, + BGFromHere, + BGFromEOF +}; + +/* this struct describes a file in memory */ +typedef struct bufgap_t { + uint64_t size; /* size of file */ + uint64_t abc; /* # of bytes after the gap */ + uint64_t bbc; /* # of bytes before the gap */ + uint64_t acc; /* # of utf chars after the gap */ + uint64_t bcc; /* # of utf chars before the gap */ + uint64_t alc; /* # of records after the gap */ + uint64_t blc; /* # of records before the gap */ + char *name; /* file name - perhaps null */ + char *buf; /* buffer-gap buffer */ + char modified; /* file has been modified */ +} bufgap_t; + +int bufgap_open(bufgap_t *, const char *); +void bufgap_close(bufgap_t *); +int bufgap_forwards(bufgap_t *, uint64_t, int); +int bufgap_backwards(bufgap_t *, uint64_t, int); +int bufgap_seek(bufgap_t *, int64_t, int, int); +char *bufgap_getstr(bufgap_t *); +int bufgap_getbin(bufgap_t *, void *, size_t); +int64_t bufgap_tell(bufgap_t *, int, int); +int64_t bufgap_size(bufgap_t *, int); +int bufgap_insert(bufgap_t *, const char *, int); +int bufgap_delete(bufgap_t *, uint64_t); +int bufgap_peek(bufgap_t *, int64_t); +char *bufgap_gettext(bufgap_t *, int64_t, int64_t); +int bufgap_write(bufgap_t *, FILE *); +int bufgap_dirty(bufgap_t *); + +#endif /* !BUFGAP_H_ */ diff --git a/security/netpgpverify/files/chk.sh b/security/netpgpverify/files/chk.sh new file mode 100755 index 00000000000..8af99f1a360 --- /dev/null +++ b/security/netpgpverify/files/chk.sh @@ -0,0 +1,119 @@ +#! /bin/sh + +# $NetBSD: chk.sh,v 1.1 2014/02/04 02:11:18 agc Exp $ + +# Copyright (c) 2013,2014 Alistair Crooks <agc@NetBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +die() { + echo "$*" >&2 + exit 1 +} + +os=EdgeBSD +osrev=6 +arch=amd64 +pkgsrc=pkgsrc-2013Q2 +keyring="" +while [ $# -gt 0 ]; do + case "$1" in + --arch|-a) arch=$2; shift ;; + --keyring|-k) keyring=$2; shift ;; + --os|-o) os=$2; shift ;; + --pkgsrc) pkgsrc=$2; shift ;; + -v) set -x ;; + *) break ;; + esac + shift +done + +case "${keyring}" in +"") keyring=$HOME/.gnupg/pubring.gpg ;; +esac + +#fetch file +repo=ftp://ftp.edgebsd.org/pub/pkgsrc/packages/${os}/${arch}/${os}-${osrev}/${pkgsrc}/All/ + +if [ ! -f $1 ]; then + case "${repo}" in + */) remote=${repo}$1 ;; + *) remote=${repo}/$1 ;; + esac + ftp ${remote} +fi + +name=$(basename $1 .tgz) +dir=$(mktemp -d /tmp/chk.XXXXXX) +here=$(pwd) +case "$1" in +/*) archive=$1 ;; +*) archive=${here}/$1 ;; +esac +(cd ${dir} && ar x ${archive}) + +# grab values from already calculated hashes +digest=$(awk '$1 ~ /algorithm:/ { print $2 }' ${dir}/+PKG_HASH) +blocksize=$(awk '/^block size:/ { print $3 }' ${dir}/+PKG_HASH) + +# check the hashes in +PKG_HASH match the original archive +size=$(ls -l ${dir}/$1 | awk '{ print $5 }') +printf "pkgsrc signature\n\nversion: 1\n" > ${dir}/calc +printf "pkgname: %s\n" ${name} >> ${dir}/calc +printf "algorithm: ${digest}\n" >> ${dir}/calc +printf "block size: ${blocksize}\n" >> ${dir}/calc +printf "file size: %s\n\n" ${size} >> ${dir}/calc +off=0 +n=0 +while [ ${off} -lt ${size} ]; do + rm -f ${dir}/in + dd if=${dir}/$1 of=${dir}/in bs=${blocksize} count=1 skip=${n} 2>/dev/null + digest ${digest} < ${dir}/in >> ${dir}/calc + off=$(( off + ${blocksize} )) + n=$(( n + 1 )) +done +printf "end pkgsrc signature\n" >> ${dir}/calc + +# make sure what was signed is what we have +diff ${dir}/+PKG_HASH ${dir}/calc || die "Bad hashes generated" + +# use netpgpverify to verify the signature +if [ -x /usr/pkg/bin/netpgpverify ]; then + # check the signature in +PKG_GPG_SIGNATURE + cp ${keyring} ${dir}/pubring.gpg + # calculate the sig file we want to verify + echo "-----BEGIN PGP SIGNED MESSAGE-----" > ${dir}/${name}.sig + echo "Hash: ${digest}" >> ${dir}/${name}.sig + echo "" >> ${dir}/${name}.sig + cat ${dir}/+PKG_HASH ${dir}/+PKG_GPG_SIGNATURE >> ${dir}/${name}.sig + (cd ${dir} && netpgpverify -k pubring.gpg ${name}.sig) || die "Bad signature" +else + gpg --recv 0x6F3AF5E2 + (cd ${dir} && gpg --verify --homedir=${dir} ./+PKG_GPG_SIGNATURE ./+PKG_HASH) || die "Bad signature" +fi +echo "Signatures match on ${name} package" + +# clean up +rm -rf ${dir} + +exit 0 diff --git a/security/netpgpverify/files/data b/security/netpgpverify/files/data new file mode 100644 index 00000000000..5e8b66cf701 --- /dev/null +++ b/security/netpgpverify/files/data @@ -0,0 +1,28 @@ +# $NetBSD: data,v 1.1 2014/02/04 02:11:18 agc Exp $ + +PROG=netpgpverify + +SRCS= b64.c bignum.c digest.c +SRCS+= libverify.c main.c misc.c +SRCS+= pgpsum.c rsa.c + +SRCS+= bzlib.c zlib.c + +SRCS+= sha1.c sha2.c md5c.c rmd160.c tiger.c + +CPPFLAGS+=-I. + +.ifndef PRODUCTION +CPPFLAGS+=-g -O0 +LDFLAGS+=-g -O0 +.endif + +MAN= netpgpverify.1 +WARNS= 6 + +.include <bsd.prog.mk> + +tst: + ./${PROG} -k pubring.gpg NetBSD-6.0_RC1_hashes.asc + ./${PROG} -k pubring.gpg NetBSD-6.0_RC1_hashes.gpg + ./${PROG} -v diff --git a/security/netpgpverify/files/data.gpg b/security/netpgpverify/files/data.gpg Binary files differnew file mode 100644 index 00000000000..77b8460c0fe --- /dev/null +++ b/security/netpgpverify/files/data.gpg diff --git a/security/netpgpverify/files/data.sig b/security/netpgpverify/files/data.sig Binary files differnew file mode 100644 index 00000000000..a5c6443ac20 --- /dev/null +++ b/security/netpgpverify/files/data.sig diff --git a/security/netpgpverify/files/defs.h b/security/netpgpverify/files/defs.h new file mode 100644 index 00000000000..db51ecb7b41 --- /dev/null +++ b/security/netpgpverify/files/defs.h @@ -0,0 +1,92 @@ +/* $NetBSD: defs.h,v 1.1 2014/02/04 02:11:18 agc Exp $ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alistair Crooks (agc@NetBSD.org) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef DEFS_H_ +#define DEFS_H_ + +#include <sys/types.h> +#include <sys/param.h> + +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define NEWARRAY(type,ptr,size,where,action) do { \ + if ((ptr = calloc(sizeof(type), (unsigned)(size))) == NULL) { \ + (void) fprintf(stderr, "%s: can't allocate %lu bytes\n", \ + where, (unsigned long)(size * sizeof(type))); \ + action; \ + } \ +} while( /* CONSTCOND */ 0) + +#define RENEW(type,ptr,size,where,action) do { \ + type *_newptr; \ + _newptr = realloc(ptr, (size_t)(sizeof(type) * (size))); \ + if (_newptr == NULL) { \ + (void) fprintf(stderr, "%s: can't realloc %lu bytes\n", \ + where, (unsigned long)(size * sizeof(type))); \ + action; \ + } else { \ + ptr = _newptr; \ + } \ +} while( /* CONSTCOND */ 0) + +#define NEW(type, ptr, where, action) NEWARRAY(type, ptr, 1, where, action) + +#define FREE(ptr) (void) free(ptr) + +#define ALLOC(type, v, size, c, init, incr, where, action) do { \ + uint32_t _newsize = size; \ + if (size == 0) { \ + _newsize = init; \ + NEWARRAY(type, v, _newsize, where ": new", action); \ + } else if (c == size) { \ + _newsize = size + incr; \ + RENEW(type, v, _newsize, where ": renew", action); \ + } \ + size = _newsize; \ +} while( /* CONSTCOND */ 0) + +#define DEFINE_ARRAY(name, type) \ +typedef struct name { \ + uint32_t c; \ + uint32_t size; \ + type *v; \ +} name + +#endif /* !DEFS_H_ */ diff --git a/security/netpgpverify/files/libverify.c b/security/netpgpverify/files/libverify.c index 571085a39ff..9437855c3eb 100644 --- a/security/netpgpverify/files/libverify.c +++ b/security/netpgpverify/files/libverify.c @@ -43,8 +43,9 @@ #include "zlib.h" #include "array.h" -#include "bn.h" #include "b64.h" +#include "bn.h" +#include "bufgap.h" #include "digest.h" #include "pgpsum.h" #include "rsa.h" @@ -151,7 +152,6 @@ static int read_all_packets(pgpv_t */*pgp*/, pgpv_mem_t */*mem*/, const char */*op*/); static int read_binary_file(pgpv_t */*pgp*/, const char */*op*/, const char */*fmt*/, ...); static int read_binary_memory(pgpv_t */*pgp*/, const char */*op*/, const void */*memory*/, size_t /*size*/); -static int pgpv_find_keyid(pgpv_t */*pgp*/, const char */*strkeyid*/, uint8_t */*keyid*/); /* read a file into the pgpv_mem_t struct */ static int @@ -296,6 +296,68 @@ get_pkt_len(uint8_t newfmt, uint8_t *p, size_t filesize, int isprimary) } } +static const uint8_t base64s[] = +/* 000 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 016 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 032 */ "\0\0\0\0\0\0\0\0\0\0\0?\0\0\0@" +/* 048 */ "56789:;<=>\0\0\0\0\0\0" +/* 064 */ "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17" +/* 080 */ "\20\21\22\23\24\25\26\27\30\31\32\0\0\0\0\0" +/* 096 */ "\0\33\34\35\36\37 !\"#$%&'()" +/* 112 */ "*+,-./01234\0\0\0\0\0" +/* 128 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 144 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 160 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 176 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 192 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 208 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 224 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +/* 240 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + +/* short function to decode from base64 */ +/* inspired by an ancient copy of b64.c, then rewritten, the bugs are all mine */ +static int +frombase64(char *dst, const char *src, size_t size, int flag) +{ + uint8_t out[3]; + uint8_t in[4]; + uint8_t b; + size_t srcc; + int dstc; + int gotc; + int i; + + USE_ARG(flag); + for (dstc = 0, srcc = 0 ; srcc < size; ) { + for (gotc = 0, i = 0; i < 4 && srcc < size; i++) { + for (b = 0x0; srcc < size && b == 0x0 ; ) { + b = base64s[(unsigned)src[srcc++]]; + } + if (srcc < size) { + gotc += 1; + if (b) { + in[i] = (uint8_t)(b - 1); + } + } else { + in[i] = 0x0; + } + } + if (gotc) { + out[0] = (uint8_t)((unsigned)in[0] << 2 | + (unsigned)in[1] >> 4); + out[1] = (uint8_t)((unsigned)in[1] << 4 | + (unsigned)in[2] >> 2); + out[2] = (uint8_t)(((in[2] << 6) & 0xc0) | in[3]); + for (i = 0; i < gotc - 1; i++) { + *dst++ = out[i]; + } + dstc += gotc - 1; + } + } + return dstc; +} + /* get the length of the packet length field */ static unsigned get_pkt_len_len(uint8_t newfmt, uint8_t *p, int isprimary) @@ -403,8 +465,8 @@ fmt_key_mpis(pgpv_pubkey_t *pubkey, uint8_t *buf, size_t size) cc = 0; buf[cc++] = pubkey->version; - cc += fmt_32(&buf[cc], (uint32_t)pubkey->birth); - buf[cc++] = pubkey->keyalg; + cc += fmt_32(&buf[cc], (uint32_t)pubkey->birth); /* XXX - do this portably! */ + buf[cc++] = pubkey->keyalg; /* XXX - sign, or encrypt and sign? */ switch(pubkey->keyalg) { case PUBKEY_RSA_ENCRYPT_OR_SIGN: case PUBKEY_RSA_ENCRYPT: @@ -429,7 +491,7 @@ fmt_key_mpis(pgpv_pubkey_t *pubkey, uint8_t *buf, size_t size) /* calculate the fingerprint, RFC 4880, section 12.2 */ static int -pgpv_calc_fingerprint(pgpv_fingerprint_t *fingerprint, pgpv_pubkey_t *pubkey) +pgpv_calc_fingerprint(pgpv_fingerprint_t *fingerprint, pgpv_pubkey_t *pubkey, const char *hashtype) { digest_t fphash; uint16_t cc; @@ -440,7 +502,7 @@ pgpv_calc_fingerprint(pgpv_fingerprint_t *fingerprint, pgpv_pubkey_t *pubkey) memset(&fphash, 0x0, sizeof(fphash)); if (pubkey->version == 4) { /* v4 keys */ - fingerprint->hashalg = digest_get_alg("sha1"); + fingerprint->hashalg = digest_get_alg(hashtype); digest_init(&fphash, (unsigned)fingerprint->hashalg); cc = fmt_key_mpis(pubkey, buf, sizeof(buf)); digest_update(&fphash, &ch, 1); @@ -493,9 +555,9 @@ fmt_fingerprint(char *s, size_t size, pgpv_fingerprint_t *fingerprint, const cha /* calculate keyid from a pubkey */ static int -pgpv_calc_keyid(pgpv_pubkey_t *key) +calc_keyid(pgpv_pubkey_t *key, const char *hashtype) { - pgpv_calc_fingerprint(&key->fingerprint, key); + pgpv_calc_fingerprint(&key->fingerprint, key, hashtype); memcpy(key->keyid, &key->fingerprint.v[key->fingerprint.len - PGPV_KEYID_LEN], PGPV_KEYID_LEN); return 1; } @@ -1387,22 +1449,45 @@ fmt_userid(char *s, size_t size, pgpv_primarykey_t *primary, uint8_t u) (userid->revoked) ? " [REVOKED]" : ""); } +/* format a trust sig - used to order the userids when formatting */ +static size_t +fmt_trust(char *s, size_t size, pgpv_signed_userid_t *userid, uint32_t u) +{ + pgpv_signature_t *sig; + size_t cc; + + sig = &ARRAY_ELEMENT(userid->sigs, u); + cc = snprintf(s, size, "trust "); + cc += fmt_binary(&s[cc], size - cc, sig->signer, 8); + return cc + snprintf(&s[cc], size - cc, "\n"); +} + /* print a primary key, per RFC 4880 */ static size_t -fmt_primary(char *s, size_t size, pgpv_primarykey_t *primary, int dosubkeys) +fmt_primary(char *s, size_t size, pgpv_primarykey_t *primary, const char *modifiers) { - unsigned i; - size_t cc; + pgpv_signed_userid_t *userid; + unsigned i; + unsigned j; + size_t cc; cc = fmt_pubkey(s, size, &primary->primary, "signature "); cc += fmt_userid(&s[cc], size - cc, primary, primary->primary_userid); for (i = 0 ; i < ARRAY_COUNT(primary->signed_userids) ; i++) { if (i != primary->primary_userid) { cc += fmt_userid(&s[cc], size - cc, primary, i); + if (strcasecmp(modifiers, "trust") == 0) { + userid = &ARRAY_ELEMENT(primary->signed_userids, i); + for (j = 0 ; j < ARRAY_COUNT(userid->sigs) ; j++) { + cc += fmt_trust(&s[cc], size - cc, userid, j); + } + } } } - for (i = 0 ; dosubkeys && i < ARRAY_COUNT(primary->signed_subkeys) ; i++) { - cc += fmt_pubkey(&s[cc], size - cc, &ARRAY_ELEMENT(primary->signed_subkeys, i).subkey, "encryption"); + if (strcasecmp(modifiers, "subkeys") == 0) { + for (i = 0 ; i < ARRAY_COUNT(primary->signed_subkeys) ; i++) { + cc += fmt_pubkey(&s[cc], size - cc, &ARRAY_ELEMENT(primary->signed_subkeys, i).subkey, "encryption"); + } } cc += snprintf(&s[cc], size - cc, "\n"); return cc; @@ -2028,7 +2113,7 @@ recog_primary_key(pgpv_t *pgp, pgpv_primarykey_t *primary) printf("recog_primary_key: not signed public subkey\n"); return 0; } - pgpv_calc_keyid(&subkey.subkey); + calc_keyid(&subkey.subkey, "sha1"); ARRAY_APPEND(primary->signed_subkeys, subkey); } } while (pgp->pkt < ARRAY_COUNT(pgp->pkts) && pkt_is(pgp, USERID_PKT)); @@ -2061,7 +2146,7 @@ read_all_packets(pgpv_t *pgp, pgpv_mem_t *mem, const char *op) } if (strcmp(op, "pubring") == 0) { for (pgp->pkt = 0; pgp->pkt < ARRAY_COUNT(pgp->pkts) && recog_primary_key(pgp, &primary) ; ) { - pgpv_calc_keyid(&primary.primary); + calc_keyid(&primary.primary, "sha1"); ARRAY_APPEND(pgp->primaries, primary); } if (pgp->pkt < ARRAY_COUNT(pgp->pkts)) { @@ -2088,6 +2173,194 @@ read_binary_file(pgpv_t *pgp, const char *op, const char *fmt, ...) return read_all_packets(pgp, &ARRAY_LAST(pgp->areas), op); } +/* get a bignum from the buffer gap */ +static int +getbignum(pgpv_bignum_t *bignum, bufgap_t *bg, char *buf, const char *header) +{ + uint32_t len; + + (void) bufgap_getbin(bg, &len, sizeof(len)); + len = ntohl(len); + (void) bufgap_seek(bg, sizeof(len), BGFromHere, BGByte); + (void) bufgap_getbin(bg, buf, len); + bignum->bn = BN_bin2bn((const uint8_t *)buf, (int)len, NULL); + bignum->bits = BN_num_bits(bignum->bn); + (void) bufgap_seek(bg, len, BGFromHere, BGByte); + return 1; +} + +/* structure for searching for constant strings */ +typedef struct str_t { + const char *s; /* string */ + size_t len; /* its length */ + int type; /* return type */ +} str_t; + +static str_t pkatypes[] = { + { "ssh-rsa", 7, PUBKEY_RSA_SIGN }, + { "ssh-dss", 7, PUBKEY_DSA }, + { "ssh-dsa", 7, PUBKEY_DSA }, + { NULL, 0, 0 } +}; + +/* look for a string in the given array */ +static int +findstr(str_t *array, const char *name) +{ + str_t *sp; + + for (sp = array ; sp->s ; sp++) { + if (strncmp(name, sp->s, sp->len) == 0) { + return sp->type; + } + } + return -1; +} + +/* read public key from the ssh pubkey file */ +static int +read_ssh_file(pgpv_t *pgp, pgpv_primarykey_t *primary, const char *fmt, ...) +{ + pgpv_signed_userid_t userid; + pgpv_pubkey_t *pubkey; + struct stat st; + bufgap_t bg; + uint32_t len; + int64_t off; + va_list args; + char hostname[256]; + char owner[256]; + char *space; + char *buf; + char *bin; + char f[1024]; + int ok; + int cc; + + memset(primary, 0x0, sizeof(*primary)); + (void) memset(&bg, 0x0, sizeof(bg)); + va_start(args, fmt); + vsnprintf(f, sizeof(f), fmt, args); + va_end(args); + if (!bufgap_open(&bg, f)) { + (void) fprintf(stderr, "pgp_ssh2pubkey: can't open '%s'\n", f); + return 0; + } + (void)stat(f, &st); + if ((buf = calloc(1, (size_t)st.st_size)) == NULL) { + (void) fprintf(stderr, "can't calloc %zu bytes for '%s'\n", (size_t)st.st_size, f); + bufgap_close(&bg); + return 0; + } + if ((bin = calloc(1, (size_t)st.st_size)) == NULL) { + (void) fprintf(stderr, "can't calloc %zu bytes for '%s'\n", (size_t)st.st_size, f); + (void) free(buf); + bufgap_close(&bg); + return 0; + } + + /* move past ascii type of key */ + while (bufgap_peek(&bg, 0) != ' ') { + if (!bufgap_seek(&bg, 1, BGFromHere, BGByte)) { + (void) fprintf(stderr, "bad key file '%s'\n", f); + (void) free(buf); + bufgap_close(&bg); + return 0; + } + } + if (!bufgap_seek(&bg, 1, BGFromHere, BGByte)) { + (void) fprintf(stderr, "bad key file '%s'\n", f); + (void) free(buf); + bufgap_close(&bg); + return 0; + } + off = bufgap_tell(&bg, BGFromBOF, BGByte); + + if (bufgap_size(&bg, BGByte) - off < 10) { + (void) fprintf(stderr, "bad key file '%s'\n", f); + (void) free(buf); + bufgap_close(&bg); + return 0; + } + + /* convert from base64 to binary */ + cc = bufgap_getbin(&bg, buf, (size_t)bg.bcc); + if ((space = strchr(buf, ' ')) != NULL) { + cc = (int)(space - buf); + } + cc = frombase64(bin, buf, (size_t)cc, 0); + bufgap_delete(&bg, (uint64_t)bufgap_tell(&bg, BGFromEOF, BGByte)); + bufgap_insert(&bg, bin, cc); + bufgap_seek(&bg, off, BGFromBOF, BGByte); + + /* get the type of key */ + (void) bufgap_getbin(&bg, &len, sizeof(len)); + len = ntohl(len); + if (len >= st.st_size) { + (void) fprintf(stderr, "bad public key file '%s'\n", f); + return 0; + } + (void) bufgap_seek(&bg, sizeof(len), BGFromHere, BGByte); + (void) bufgap_getbin(&bg, buf, len); + (void) bufgap_seek(&bg, len, BGFromHere, BGByte); + + pubkey = &primary->primary; + pubkey->hashalg = digest_get_alg("sha256"); /* gets fixed up later */ + pubkey->version = 4; + pubkey->birth = 0; /* gets fixed up later */ + /* get key type */ + ok = 1; + switch (pubkey->keyalg = findstr(pkatypes, buf)) { + case PUBKEY_RSA_ENCRYPT_OR_SIGN: + case PUBKEY_RSA_SIGN: + getbignum(&pubkey->bn[RSA_E], &bg, buf, "RSA E"); + getbignum(&pubkey->bn[RSA_N], &bg, buf, "RSA N"); + break; + case PUBKEY_DSA: + getbignum(&pubkey->bn[DSA_P], &bg, buf, "DSA P"); + getbignum(&pubkey->bn[DSA_Q], &bg, buf, "DSA Q"); + getbignum(&pubkey->bn[DSA_G], &bg, buf, "DSA G"); + getbignum(&pubkey->bn[DSA_Y], &bg, buf, "DSA Y"); + break; + default: + (void) fprintf(stderr, "Unrecognised pubkey type %d for '%s'\n", + pubkey->keyalg, f); + ok = 0; + break; + } + + /* check for stragglers */ + if (ok && bufgap_tell(&bg, BGFromEOF, BGByte) > 0) { + printf("%"PRIi64" bytes left\n", bufgap_tell(&bg, BGFromEOF, BGByte)); + printf("[%s]\n", bufgap_getstr(&bg)); + ok = 0; + } + if (ok) { + memset(&userid, 0x0, sizeof(userid)); + (void) gethostname(hostname, sizeof(hostname)); + if (strlen(space + 1) - 1 == 0) { + (void) snprintf(owner, sizeof(owner), "<root@%s>", + hostname); + } else { + (void) snprintf(owner, sizeof(owner), "<%.*s>", + (int)strlen(space + 1) - 1, + space + 1); + } + calc_keyid(pubkey, "sha1"); + userid.userid.size = asprintf((char **)(void *)&userid.userid.data, + "%s (%s) %s", + hostname, + f, + owner); + ARRAY_APPEND(primary->signed_userids, userid); + primary->fmtsize = estimate_primarykey_size(primary) + 1024; + } + (void) free(bin); + (void) free(buf); + bufgap_close(&bg); + return ok; +} + /* parse memory according to "op" */ static int read_binary_memory(pgpv_t *pgp, const char *op, const void *memory, size_t size) @@ -2234,7 +2507,7 @@ pgpv_close(pgpv_t *pgp) /* return the formatted entry for the primary key desired */ size_t -pgpv_get_entry(pgpv_t *pgp, unsigned ent, char **ret) +pgpv_get_entry(pgpv_t *pgp, unsigned ent, char **ret, const char *modifiers) { size_t cc; @@ -2243,15 +2516,36 @@ pgpv_get_entry(pgpv_t *pgp, unsigned ent, char **ret) } *ret = NULL; cc = ARRAY_ELEMENT(pgp->primaries, ent).fmtsize; + if (modifiers == NULL || (strcasecmp(modifiers, "trust") != 0 && strcasecmp(modifiers, "subkeys") != 0)) { + modifiers = "no-subkeys"; + } + if (strcasecmp(modifiers, "trust") == 0) { + cc *= 2048; + } if ((*ret = calloc(1, cc)) == NULL) { return 0; } - return fmt_primary(*ret, cc, &ARRAY_ELEMENT(pgp->primaries, ent), NO_SUBKEYS); + return fmt_primary(*ret, cc, &ARRAY_ELEMENT(pgp->primaries, ent), modifiers); +} + +/* fixup key id, with birth, keyalg and hashalg value from signature */ +static int +fixup_ssh_keyid(pgpv_t *pgp, pgpv_signature_t *signature, const char *hashtype) +{ + pgpv_pubkey_t *pubkey; + unsigned i; + + for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) { + pubkey = &ARRAY_ELEMENT(pgp->primaries, i).primary; + pubkey->keyalg = signature->keyalg; + calc_keyid(pubkey, hashtype); + } + return 1; } /* find key id */ -int -pgpv_find_keyid(pgpv_t *pgp, const char *strkeyid, uint8_t *keyid) +static int +find_keyid(pgpv_t *pgp, const char *strkeyid, uint8_t *keyid) { unsigned i; uint8_t binkeyid[PGPV_KEYID_LEN]; @@ -2277,6 +2571,21 @@ pgpv_find_keyid(pgpv_t *pgp, const char *strkeyid, uint8_t *keyid) return -1; } +/* match the signature with the id indexed by 'primary' */ +static int +match_sig_id(pgpv_cursor_t *cursor, pgpv_signature_t *signature, pgpv_litdata_t *litdata, unsigned primary) +{ + pgpv_pubkey_t *pubkey; + uint8_t *data; + size_t insize; + + pubkey = &ARRAY_ELEMENT(cursor->pgp->primaries, primary).primary; + cursor->sigtime = signature->birth; + /* calc hash on data packet */ + data = get_literal_data(cursor, litdata, &insize); + return match_sig(cursor, signature, pubkey, data, insize); +} + /* verify the signed packets we have */ size_t pgpv_verify(pgpv_cursor_t *cursor, pgpv_t *pgp, const void *p, ssize_t size) @@ -2284,12 +2593,9 @@ pgpv_verify(pgpv_cursor_t *cursor, pgpv_t *pgp, const void *p, ssize_t size) pgpv_signature_t *signature; pgpv_onepass_t *onepass; pgpv_litdata_t *litdata; - pgpv_pubkey_t *pubkey; - unsigned primary; - uint8_t *data; size_t pkt; - size_t insize; char strkeyid[PGPV_STR_KEYID_LEN]; + int found; int j; if (cursor == NULL || pgp == NULL || p == NULL) { @@ -2336,21 +2642,21 @@ pgpv_verify(pgpv_cursor_t *cursor, pgpv_t *pgp, const void *p, ssize_t size) signature->keyalg, onepass->keyalg); return 0; } - if ((j = pgpv_find_keyid(cursor->pgp, NULL, onepass->keyid)) < 0) { + if (cursor->pgp->ssh) { + fixup_ssh_keyid(cursor->pgp, signature, "sha1"); + } + if (ARRAY_COUNT(cursor->pgp->primaries) == 1) { + j = 0; + } else if ((j = find_keyid(cursor->pgp, NULL, onepass->keyid)) < 0) { fmt_binary(strkeyid, sizeof(strkeyid), onepass->keyid, (unsigned)sizeof(onepass->keyid)); snprintf(cursor->why, sizeof(cursor->why), "Signature key id %s not found ", strkeyid); return 0; } - primary = (unsigned)j; - pubkey = &ARRAY_ELEMENT(cursor->pgp->primaries, primary).primary; - cursor->sigtime = signature->birth; - /* calc hash on data packet */ - data = get_literal_data(cursor, litdata, &insize); - if (!match_sig(cursor, signature, pubkey, data, insize)) { + if (!match_sig_id(cursor, signature, litdata, (unsigned)j)) { return 0; } ARRAY_APPEND(cursor->datacookies, pkt); - ARRAY_APPEND(cursor->found, primary); + ARRAY_APPEND(cursor->found, j); return pkt + 1; } @@ -2369,6 +2675,27 @@ pgpv_read_pubring(pgpv_t *pgp, const void *keyring, ssize_t size) return read_binary_file(pgp, "pubring", "%s/%s", nonnull_getenv("HOME"), ".gnupg/pubring.gpg"); } +/* set up the pubkey keyring from ssh pub key */ +int +pgpv_read_ssh_pubkeys(pgpv_t *pgp, const void *keyring, ssize_t size) +{ + pgpv_primarykey_t primary; + + if (pgp == NULL) { + return 0; + } + if (keyring) { + if (!read_ssh_file(pgp, &primary, "%s", keyring)) { + return 0; + } + } else if (!read_ssh_file(pgp, &primary, "pubring", "%s/%s", nonnull_getenv("HOME"), ".ssh/id_rsa.pub")) { + return 0; + } + ARRAY_APPEND(pgp->primaries, primary); + pgp->ssh = 1; + return 1; +} + /* get verified data as a string, return its size */ size_t pgpv_get_verified(pgpv_cursor_t *cursor, size_t cookie, char **ret) diff --git a/security/netpgpverify/files/main.c b/security/netpgpverify/files/main.c index 793f5355cdb..40cc1755c49 100644 --- a/security/netpgpverify/files/main.c +++ b/security/netpgpverify/files/main.c @@ -49,11 +49,11 @@ ptime(int64_t secs) /* print entry n */ static void -pentry(pgpv_t *pgp, int n) +pentry(pgpv_t *pgp, int n, const char *modifiers) { char *s; - pgpv_get_entry(pgp, (unsigned)n, &s); + pgpv_get_entry(pgp, (unsigned)n, &s, modifiers); printf("%s", s); free(s); } @@ -91,6 +91,7 @@ static int verify_data(pgpv_t *pgp, const char *cmd, const char *inname, char *in, ssize_t cc) { pgpv_cursor_t cursor; + const char *modifiers; size_t size; size_t cookie; char *data; @@ -103,16 +104,17 @@ verify_data(pgpv_t *pgp, const char *cmd, const char *inname, char *in, ssize_t } return 1; } - } else if (strcasecmp(cmd, "verify") == 0) { + } else if (strcasecmp(cmd, "verify") == 0 || strcasecmp(cmd, "trust") == 0) { + modifiers = (strcasecmp(cmd, "trust") == 0) ? "trust" : NULL; if (pgpv_verify(&cursor, pgp, in, cc)) { printf("Good signature for %s made ", inname); ptime(cursor.sigtime); - pentry(pgp, ARRAY_ELEMENT(cursor.found, 0)); + pentry(pgp, ARRAY_ELEMENT(cursor.found, 0), modifiers); return 1; } - fprintf(stderr, "Signature did not match contents -- %s", cursor.why); + fprintf(stderr, "Signature did not match contents -- %s\n", cursor.why); } else { - fprintf(stderr, "unrecognised command \"%s\"", cmd); + fprintf(stderr, "unrecognised command \"%s\"\n", cmd); } return 0; } @@ -120,21 +122,29 @@ verify_data(pgpv_t *pgp, const char *cmd, const char *inname, char *in, ssize_t int main(int argc, char **argv) { + const char *modifiers; const char *keyring; const char *cmd; ssize_t cc; size_t size; pgpv_t pgp; char *in; + int ssh; int ok; int i; memset(&pgp, 0x0, sizeof(pgp)); keyring = NULL; + ssh = 0; ok = 1; cmd = "verify"; - while ((i = getopt(argc, argv, "c:k:v")) != -1) { + modifiers = NULL; + while ((i = getopt(argc, argv, "S:c:k:v")) != -1) { switch(i) { + case 'S': + ssh = 1; + keyring = optarg; + break; case 'c': cmd = optarg; break; @@ -148,8 +158,14 @@ main(int argc, char **argv) break; } } - if (!pgpv_read_pubring(&pgp, keyring, -1)) { - errx(EXIT_FAILURE, "can't read keyring"); + if (ssh) { + if (!pgpv_read_ssh_pubkeys(&pgp, keyring, -1)) { + fprintf(stderr, "can't read ssh keyring\n"); + exit(EXIT_FAILURE); + } + } else if (!pgpv_read_pubring(&pgp, keyring, -1)) { + fprintf(stderr, "can't read keyring\n"); + exit(EXIT_FAILURE); } if (optind == argc) { in = getstdin(&cc, &size); diff --git a/security/netpgpverify/files/netpgpverify.1 b/security/netpgpverify/files/netpgpverify.1 index cb33c4412e8..a23c9104687 100644 --- a/security/netpgpverify/files/netpgpverify.1 +++ b/security/netpgpverify/files/netpgpverify.1 @@ -1,6 +1,6 @@ -.\" $NetBSD: netpgpverify.1,v 1.2 2013/07/20 21:50:54 wiz Exp $ +.\" $NetBSD: netpgpverify.1,v 1.3 2014/02/04 02:11:18 agc Exp $ .\" -.\" Copyright (c) 2013 Alistair Crooks <agc@NetBSD.org> +.\" Copyright (c) 2013,2014 Alistair Crooks <agc@NetBSD.org> .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -23,7 +23,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 15, 2013 +.Dd February 2, 2014 .Dt NETPGPVERIFY 1 .Os .Sh NAME @@ -32,6 +32,7 @@ .Sh SYNOPSIS .Nm .Op Fl v +.Op Fl S Ar ssh-pub-key-file .Op Fl c Ar command .Op Fl k Ar keyring .Ar file ... @@ -87,6 +88,24 @@ will also verify the signature on the data, and, if successfully verified, will display the verified data on .Dv stdout . +The +.Fl S +argument allows an ssh public key file to be used as the source of +truth for the key. +This ssh-key-based signature can be created using the +.Xr netpgp 1 +utility. +.Pp +If a detached signature +.Dq .sig +is given on the command line, the signing information will be retrieved +from that file, and the original data is expected to be found in a file in the same +directory with the same name with the +.Dq .sig +suffix removed. +.Pp +Both text mode signatures, and binary signatures, can be verified by +.Nm .Sh SIGNING AND VERIFICATION Verification of a file's signature is best viewed using the following example: .Bd -literal @@ -106,7 +125,6 @@ or 2 if any other error occurs. .Sh SEE ALSO .Xr netpgp 1 , .\" .Xr libbz2 3 , -.Xr libnetpgp 3 , .Xr zlib 3 .Sh STANDARDS The @@ -118,4 +136,4 @@ The command first appeared in .Nx 7.0 . .Sh AUTHORS -.An Alistair Crooks Aq Mt agc@NetBSD.org . +.An Alistair Crooks Aq agc@NetBSD.org . diff --git a/security/netpgpverify/files/pubring.gpg b/security/netpgpverify/files/pubring.gpg Binary files differindex 796a40a1398..113e332c1e5 100644 --- a/security/netpgpverify/files/pubring.gpg +++ b/security/netpgpverify/files/pubring.gpg diff --git a/security/netpgpverify/files/sshtest-20140202 b/security/netpgpverify/files/sshtest-20140202 new file mode 100644 index 00000000000..68ac811d2e8 --- /dev/null +++ b/security/netpgpverify/files/sshtest-20140202 @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/security/netpgpverify/files/sshtest-20140202.pub b/security/netpgpverify/files/sshtest-20140202.pub new file mode 100644 index 00000000000..865d17203ad --- /dev/null +++ b/security/netpgpverify/files/sshtest-20140202.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC9GQFh9ZovYFZ+alATAZX9un7IlwstYzvFRjsuu0vhOrdh5WyU9fIyWQL9ZTIv8JTIDx9DfPnqb5LuFmpe2l5ZtgZDo7un8EV4xx5knph2GZJMMokLs64XhWc2pgbkterCV6cUR7gtO3v281JkSQFyyG5Gz3EWnq+tCub4ulMcqhcqX9Q+x/Ury4Bahz+Y9MyrIh0nHppRdDR/DAWj+3wTjtTAthCTcEViVj1HRx61UBcIKi1OZzleeYolHpgpQDrQWBTi+T7HkiBKm42gy+6EM9ptoClAsfDXf0R+a6XOzMGlXi4SWdcHDkJ1D9E/2be91p+NueUrcPGDFtTd5G9QUhuSN27mqLptuXGpJ5/Uxv8HDY6p7AU0ybdlDXtXceoCZgYEHAHZ6H9ypGUJFxh68DZvIzrV1MzRe3m8HNvE1ZbpZ4mYP6hg/6CVhFGYri4l54o4VJaoOFtKPoR9gf5QW7SJXjITEoZ5UoFPCF+l5y66xXvdrBheLC1Ko/XZSNGhOlh9dseW+l4yHIHDSgpaN5neSjgouFXOOgtPxulJshJojwaJUFYJywxmaZn8+QYMD47w16S1nlP3OW1aWxe58dVDnHYGJ8rAasiCHUlLfxR2DAhBUVP/r2nlxyv9o+5MgBDHvtfNHNN0R5aW7LZyjBkXl+70dDk7338yLrVzuQ== agc@netbsd-001.cupertino.alistaircrooks.com diff --git a/security/netpgpverify/files/verify.h b/security/netpgpverify/files/verify.h index 11f0345ebc3..2cdc732261d 100644 --- a/security/netpgpverify/files/verify.h +++ b/security/netpgpverify/files/verify.h @@ -23,9 +23,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef NETPGP_VERIFY_H_ -#define NETPGP_VERIFY_H_ 20131219 +#define NETPGP_VERIFY_H_ 20140202 -#define NETPGPVERIFY_VERSION "netpgpverify portable 20131219" +#define NETPGPVERIFY_VERSION "netpgpverify portable 20140202" #include <sys/types.h> @@ -49,7 +49,7 @@ typedef struct pgpv_bignum_t { } pgpv_bignum_t; /* right now, our max binary digest length is 20 bytes */ -#define PGPV_MAX_HASH_LEN 20 +#define PGPV_MAX_HASH_LEN 64 /* fingerprint */ typedef struct pgpv_fingerprint_t { @@ -251,6 +251,7 @@ typedef struct pgpv_t { PGPV_ARRAY(size_t, datastarts); /* starts of data packets */ size_t pkt; /* when parsing, current pkt number */ const char *op; /* the operation we're doing */ + unsigned ssh; /* using ssh keys */ } pgpv_t; #define PGPV_REASON_LEN 128 @@ -281,11 +282,12 @@ typedef struct pgpv_cursor_t { __BEGIN_DECLS int pgpv_read_pubring(pgpv_t */*pgp*/, const void */*keyringfile/mem*/, ssize_t /*size*/); +int pgpv_read_ssh_pubkeys(pgpv_t */*pgp*/, const void */*keyring*/, ssize_t /*size*/); size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/); size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/); -size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/); +size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/, const char */*modifiers*/); int pgpv_close(pgpv_t */*pgp*/); |