Module Name:    src
Committed By:   mlelstv
Date:           Tue Nov 13 14:52:31 UTC 2018

Modified Files:
        src/crypto/external/bsd/netpgp/dist/src/lib: keyring.c keyring.h misc.c
            netpgp.c packet-parse.c packet.h
        src/crypto/external/bsd/netpgp/dist/src/libmj: libmj.3 mj.c
        src/crypto/external/bsd/netpgp/dist/src/netpgpkeys: netpgpkeys.c

Log Message:
Fix some error handling, json support, keyring handling.


To generate a diff of this commit:
cvs rdiff -u -r1.55 -r1.56 \
    src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c
cvs rdiff -u -r1.34 -r1.35 \
    src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h
cvs rdiff -u -r1.41 -r1.42 src/crypto/external/bsd/netpgp/dist/src/lib/misc.c
cvs rdiff -u -r1.101 -r1.102 \
    src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c
cvs rdiff -u -r1.51 -r1.52 \
    src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c
cvs rdiff -u -r1.30 -r1.31 \
    src/crypto/external/bsd/netpgp/dist/src/lib/packet.h
cvs rdiff -u -r1.9 -r1.10 \
    src/crypto/external/bsd/netpgp/dist/src/libmj/libmj.3
cvs rdiff -u -r1.5 -r1.6 src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c
cvs rdiff -u -r1.26 -r1.27 \
    src/crypto/external/bsd/netpgp/dist/src/netpgpkeys/netpgpkeys.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c:1.55 src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c:1.56
--- src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c:1.55	Mon Mar 27 21:19:12 2017
+++ src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c	Tue Nov 13 14:52:30 2018
@@ -57,7 +57,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: keyring.c,v 1.55 2017/03/27 21:19:12 khorben Exp $");
+__RCSID("$NetBSD: keyring.c,v 1.56 2018/11/13 14:52:30 mlelstv Exp $");
 #endif
 
 #ifdef HAVE_FCNTL_H
@@ -456,10 +456,12 @@ copy_packet(pgp_subpacket_t *dst, const 
 	}
 	if ((dst->raw = calloc(1, src->length)) == NULL) {
 		(void) fprintf(stderr, "copy_packet: bad alloc\n");
+		dst->length = 0;
 	} else {
 		dst->length = src->length;
 		(void) memcpy(dst->raw, src->raw, src->length);
 	}
+	dst->tag = src->tag;
 	return dst;
 }
 
@@ -500,7 +502,6 @@ pgp_add_subpacket(pgp_key_t *keydata, co
 	EXPAND_ARRAY(keydata, packet);
 	/* initialise new entry in array */
 	subpktp = &keydata->packets[keydata->packetc++];
-	subpktp->length = 0;
 	subpktp->raw = NULL;
 	/* now copy it */
 	return copy_packet(subpktp, packet);
@@ -545,6 +546,7 @@ pgp_add_selfsigned_userid(pgp_key_t *key
 	/* add this packet to key */
 	sigpacket.length = pgp_mem_len(mem_sig);
 	sigpacket.raw = pgp_mem_data(mem_sig);
+	sigpacket.tag = PGP_PTAG_CT_SIGNATURE;
 
 	/* add userid to key */
 	(void) pgp_add_userid(key, userid);
@@ -596,13 +598,14 @@ cb_keyring_read(const pgp_packet_t *pkt,
 
 	cb = pgp_callback_arg(cbinfo);
 	keyring = cb->keyring;
+	key = keyring->keyc > 0 ? &keyring->keys[keyring->keyc - 1] : NULL;
+
 	switch (pkt->tag) {
 	case PGP_PARSER_PTAG:
 	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
 		/* we get these because we didn't prompt */
 		break;
 	case PGP_PTAG_CT_SIGNATURE_HEADER:
-		key = &keyring->keys[keyring->keyc - 1];
 		EXPAND_ARRAY(key, subsig);
 		key->subsigs[key->subsigc].uid = key->uidc - 1;
 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
@@ -610,7 +613,6 @@ cb_keyring_read(const pgp_packet_t *pkt,
 		key->subsigc += 1;
 		break;
 	case PGP_PTAG_CT_SIGNATURE:
-		key = &keyring->keys[keyring->keyc - 1];
 		EXPAND_ARRAY(key, subsig);
 		key->subsigs[key->subsigc].uid = key->uidc - 1;
 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
@@ -618,7 +620,6 @@ cb_keyring_read(const pgp_packet_t *pkt,
 		key->subsigc += 1;
 		break;
 	case PGP_PTAG_CT_TRUST:
-		key = &keyring->keys[keyring->keyc - 1];
 		key->subsigs[key->subsigc - 1].trustlevel = pkt->u.ss_trust.level;
 		key->subsigs[key->subsigc - 1].trustamount = pkt->u.ss_trust.amount;
 		break;
@@ -629,28 +630,23 @@ cb_keyring_read(const pgp_packet_t *pkt,
 		}
 		break;
 	case PGP_PTAG_SS_ISSUER_KEY_ID:
-		key = &keyring->keys[keyring->keyc - 1];
 		(void) memcpy(&key->subsigs[key->subsigc - 1].sig.info.signer_id,
 			      pkt->u.ss_issuer,
 			      sizeof(pkt->u.ss_issuer));
 		key->subsigs[key->subsigc - 1].sig.info.signer_id_set = 1;
 		break;
 	case PGP_PTAG_SS_CREATION_TIME:
-		key = &keyring->keys[keyring->keyc - 1];
 		key->subsigs[key->subsigc - 1].sig.info.birthtime = pkt->u.ss_time;
 		key->subsigs[key->subsigc - 1].sig.info.birthtime_set = 1;
 		break;
 	case PGP_PTAG_SS_EXPIRATION_TIME:
-		key = &keyring->keys[keyring->keyc - 1];
 		key->subsigs[key->subsigc - 1].sig.info.duration = pkt->u.ss_time;
 		key->subsigs[key->subsigc - 1].sig.info.duration_set = 1;
 		break;
 	case PGP_PTAG_SS_PRIMARY_USER_ID:
-		key = &keyring->keys[keyring->keyc - 1];
 		key->uid0 = key->uidc - 1;
 		break;
 	case PGP_PTAG_SS_REVOCATION_REASON:
-		key = &keyring->keys[keyring->keyc - 1];
 		if (key->uidc == 0) {
 			/* revoke whole key */
 			key->revoked = 1;
@@ -668,7 +664,6 @@ cb_keyring_read(const pgp_packet_t *pkt,
 	case PGP_PTAG_CT_SIGNATURE_FOOTER:
 	case PGP_PARSER_ERRCODE:
 		break;
-
 	default:
 		break;
 	}
@@ -813,6 +808,77 @@ pgp_keyring_read_from_mem(pgp_io_t *io,
 }
 
 /**
+   \ingroup HighLevel_KeyringWrite
+
+   \brief Writes a keyring to a file
+
+   \param keyring Pointer to an existing pgp_keyring_t struct
+   \param armour 1 if file is armoured; else 0
+   \param filename Filename of keyring to be written
+
+   \return pgp 1 if OK; 0 on error
+
+   \note Keyring struct must already exist.
+
+   \note Can be used with either a public or secret keyring.
+*/
+
+unsigned 
+pgp_keyring_filewrite(pgp_keyring_t *keyring,
+			unsigned armour,
+			const char *filename,
+			uint8_t *passphrase)
+{
+	pgp_output_t		*output;
+	int			fd;
+	unsigned	 	res = 1;
+	pgp_key_t		*key;
+	unsigned	 	n;
+	unsigned	 	keyc = (keyring != NULL) ? keyring->keyc : 0;
+	char 			*cp;
+	pgp_content_enum	type;
+	pgp_armor_type_t	atype;
+	char			keyid[PGP_KEY_ID_SIZE * 3];
+
+	fd = pgp_setup_file_write(&output, filename, 1);
+	if (fd < 0) {
+		perror(filename);
+		return 0;
+	}
+
+	type = keyring->keyc > 0 ? keyring->keys->type : PGP_PTAG_CT_PUBLIC_KEY;
+
+	if (armour) {
+		if (type == PGP_PTAG_CT_PUBLIC_KEY)
+			atype = PGP_PGP_PUBLIC_KEY_BLOCK;
+		else
+			atype = PGP_PGP_PRIVATE_KEY_BLOCK;
+		pgp_writer_push_armoured(output, atype);
+	}
+	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
+		/* write only keys of a single type */
+		if (key->type != type) {
+			(void) fprintf(stderr, "ERROR: skip key %d\n", n);
+			continue;
+		}
+		if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
+			pgp_write_xfer_pubkey(output, key, 0);
+		} else {
+			pgp_write_xfer_seckey(output, key, passphrase,
+					strlen((char *)passphrase), 0);
+		}
+	}
+	if (armour) {
+		pgp_writer_info_finalise(&output->errors, &output->writer);
+		pgp_writer_pop(output);
+	}
+
+	pgp_teardown_file_write(output, fd);
+
+	return res;
+}
+
+/**
    \ingroup HighLevel_KeyringRead
 
    \brief Frees keyring's contents (but not keyring itself)
@@ -1030,7 +1096,8 @@ pgp_keyring_list(pgp_io_t *io, const pgp
 			pgp_print_keydata(io, keyring, key, "sec",
 				&key->key.seckey.pubkey, 0);
 		} else {
-			pgp_print_keydata(io, keyring, key, "signature ", &key->key.pubkey, psigs);
+			pgp_print_keydata(io, keyring, key, "pub",
+				&key->key.pubkey, psigs);
 		}
 		(void) fputc('\n', io->res);
 	}
@@ -1059,7 +1126,7 @@ pgp_keyring_json(pgp_io_t *io, const pgp
 				"sec", &key->key.seckey.pubkey, psigs);
 		} else {
 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
-				"signature ", &key->key.pubkey, psigs);
+				"pub", &key->key.pubkey, psigs);
 		}
 		if (obj->value.v[obj->c].type != 0) {
 			obj->c += 1;

Index: src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.34 src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.35
--- src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.34	Mon Mar 27 21:06:50 2017
+++ src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h	Tue Nov 13 14:52:30 2018
@@ -96,6 +96,8 @@ pgp_seckey_t *pgp_decrypt_seckey(const p
 
 unsigned   pgp_keyring_fileread(pgp_keyring_t *, const unsigned,
 					const char *);
+unsigned   pgp_keyring_filewrite(pgp_keyring_t *, const unsigned,
+					const char *, uint8_t *);
 
 int pgp_keyring_list(pgp_io_t *, const pgp_keyring_t *, const int);
 int pgp_keyring_json(pgp_io_t *, const pgp_keyring_t *, mj_t *, const int);
@@ -110,7 +112,7 @@ unsigned pgp_is_key_supported(const pgp_
 
 uint8_t *pgp_add_userid(pgp_key_t *, const uint8_t *);
 pgp_subpacket_t *pgp_add_subpacket(pgp_key_t *,
-						const pgp_subpacket_t *);
+					const pgp_subpacket_t *);
 
 unsigned pgp_add_selfsigned_userid(pgp_key_t *, uint8_t *);
 

Index: src/crypto/external/bsd/netpgp/dist/src/lib/misc.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/misc.c:1.41 src/crypto/external/bsd/netpgp/dist/src/lib/misc.c:1.42
--- src/crypto/external/bsd/netpgp/dist/src/lib/misc.c:1.41	Mon Mar  5 02:20:18 2012
+++ src/crypto/external/bsd/netpgp/dist/src/lib/misc.c	Tue Nov 13 14:52:30 2018
@@ -57,7 +57,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: misc.c,v 1.41 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD: misc.c,v 1.42 2018/11/13 14:52:30 mlelstv Exp $");
 #endif
 
 #include <sys/types.h>
@@ -110,12 +110,14 @@ accumulate_cb(const pgp_packet_t *pkt, p
 	const pgp_contents_t	*content = &pkt->u;
 	pgp_keyring_t		*keyring;
 	accumulate_t		*accumulate;
+	pgp_key_t		*key;
 
 	if (pgp_get_debug_level(__FILE__)) {
 		(void) fprintf(stderr, "accumulate callback: packet tag %u\n", pkt->tag);
 	}
 	accumulate = pgp_callback_arg(cbinfo);
 	keyring = accumulate->keyring;
+	key = keyring->keyc > 0 ? &keyring->keys[keyring->keyc - 1] : NULL;
 	switch (pkt->tag) {
 	case PGP_PTAG_CT_PUBLIC_KEY:
 	case PGP_PTAG_CT_PUBLIC_SUBKEY:
@@ -131,17 +133,26 @@ accumulate_cb(const pgp_packet_t *pkt, p
 					content->userid,
 					keyring->keyc - 1);
 		}
-		if (keyring->keyc == 0) {
-			PGP_ERROR_1(cbinfo->errors, PGP_E_P_NO_USERID, "%s",
-			    "No userid found");
+		if (key != NULL) {
+			pgp_add_userid(key, content->userid);
 		} else {
-			pgp_add_userid(&keyring->keys[keyring->keyc - 1], content->userid);
+			PGP_ERROR_1(cbinfo->errors, PGP_E_P_NO_USERID, "%s",
+			    "No key for userid found");
 		}
 		return PGP_KEEP_MEMORY;
 	case PGP_PARSER_PACKET_END:
-		if (keyring->keyc > 0) {
-			pgp_add_subpacket(&keyring->keys[keyring->keyc - 1],
-						&content->packet);
+		if (key != NULL) {
+			switch (content->packet.tag) {
+			case PGP_PTAG_CT_RESERVED:
+				(void) fprintf(stderr, "Invalid packet tag\n");
+				break;
+			case PGP_PTAG_CT_PUBLIC_KEY:
+			case PGP_PTAG_CT_USER_ID:
+				break;
+			default:
+				pgp_add_subpacket(key, &content->packet);
+				break;
+			}
 			return PGP_KEEP_MEMORY;
 		}
 		return PGP_RELEASE_MEMORY;

Index: src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c:1.101 src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c:1.102
--- src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c:1.101	Mon Mar 27 20:55:13 2017
+++ src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c	Tue Nov 13 14:52:30 2018
@@ -34,7 +34,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: netpgp.c,v 1.101 2017/03/27 20:55:13 khorben Exp $");
+__RCSID("$NetBSD: netpgp.c,v 1.102 2018/11/13 14:52:30 mlelstv Exp $");
 #endif
 
 #include <sys/types.h>
@@ -222,34 +222,125 @@ findvar(netpgp_t *netpgp, const char *na
 	return (i == netpgp->c) ? -1 : (int)i;
 }
 
-/* read a keyring and return it */
-static void *
-readkeyring(netpgp_t *netpgp, const char *name)
+/* append a key to a keyring */
+static int
+appendkey(pgp_io_t *io, pgp_key_t *key, char *ringfile)
 {
-	pgp_keyring_t	*keyring;
+	pgp_output_t	*create;
 	const unsigned	 noarmor = 0;
+	int		 fd;
+
+	if ((fd = pgp_setup_file_append(&create, ringfile)) < 0) {
+		fd = pgp_setup_file_write(&create, ringfile, 0);
+	}
+	if (fd < 0) {
+		(void) fprintf(io->errs, "can't open pubring '%s'\n", ringfile);
+		return 0;
+	}
+	if (!pgp_write_xfer_pubkey(create, key, noarmor)) {
+		(void) fprintf(io->errs, "Cannot write pubkey\n");
+		return 0;
+	}
+	pgp_teardown_file_write(create, fd);
+	return 1;
+}
+
+/* return filename of a keyring */
+static char *
+keyringfile(netpgp_t *netpgp, const char *name)
+{
 	char		 f[MAXPATHLEN];
-	char		*filename;
 	char		*homedir;
+	char		*filename;
 
 	homedir = netpgp_getvar(netpgp, "homedir");
-	if ((filename = netpgp_getvar(netpgp, name)) == NULL) {
+	filename = netpgp_getvar(netpgp, name);
+	if (filename == NULL || filename[0] == '\0') {
 		(void) snprintf(f, sizeof(f), "%s/%s.gpg", homedir, name);
 		filename = f;
 	}
+
+	return netpgp_strdup(filename);
+}
+
+/* return an empty keyring */
+static void *
+newkeyring(netpgp_t *netpgp, const char *name)
+{
+	pgp_keyring_t	*keyring;
+	char		*filename;
+
+	if ((keyring = calloc(1, sizeof(*keyring))) == NULL) {
+		(void) fprintf(stderr, "newkeyring: bad alloc\n");
+		return NULL;
+	}
+
+	filename = keyringfile(netpgp, name);
+	netpgp_setvar(netpgp, name, filename);
+	free(filename);
+
+	return keyring;
+}
+
+/* read a keyring and return it */
+static void *
+readkeyring(netpgp_t *netpgp, const char *name)
+{
+	pgp_keyring_t	*keyring;
+	const unsigned	 noarmor = 0;
+	char		*filename;
+
 	if ((keyring = calloc(1, sizeof(*keyring))) == NULL) {
 		(void) fprintf(stderr, "readkeyring: bad alloc\n");
 		return NULL;
 	}
+
+	filename = keyringfile(netpgp, name);
 	if (!pgp_keyring_fileread(keyring, noarmor, filename)) {
+		free(filename);
 		free(keyring);
 		(void) fprintf(stderr, "Can't read %s %s\n", name, filename);
 		return NULL;
 	}
 	netpgp_setvar(netpgp, name, filename);
+	free(filename);
+
 	return keyring;
 }
 
+/* write a keyring */
+static int
+writekeyring(netpgp_t *netpgp, const char *name, pgp_keyring_t *keyring, uint8_t *passphrase)
+{
+	const unsigned	 noarmor = 0;
+	char		*filename;
+
+	filename = keyringfile(netpgp, name);
+	if (!pgp_keyring_filewrite(keyring, noarmor, filename, passphrase)) {
+		free(filename);
+		(void) fprintf(stderr, "Can't write %s %s\n", name, filename);
+		return 0;
+	}
+	netpgp_setvar(netpgp, name, filename);
+	free(filename);
+
+	return 1;
+}
+
+/* append key to a keyring */
+static int
+appendtokeyring(netpgp_t *netpgp, const char *name, pgp_key_t *key)
+{
+	char	*filename;
+	int	ret;
+
+	filename = keyringfile(netpgp, name);
+	ret = appendkey(netpgp->io, key, filename);
+	free(filename);
+
+	return ret;
+}
+
 /* read keys from ssh key files */
 static int
 readsshkeys(netpgp_t *netpgp, char *homedir, const char *needseckey)
@@ -442,29 +533,6 @@ resolve_userid(netpgp_t *netpgp, const p
 	return key;
 }
 
-/* append a key to a keyring */
-static int
-appendkey(pgp_io_t *io, pgp_key_t *key, char *ringfile)
-{
-	pgp_output_t	*create;
-	const unsigned	 noarmor = 0;
-	int		 fd;
-
-	if ((fd = pgp_setup_file_append(&create, ringfile)) < 0) {
-		fd = pgp_setup_file_write(&create, ringfile, 0);
-	}
-	if (fd < 0) {
-		(void) fprintf(io->errs, "can't open pubring '%s'\n", ringfile);
-		return 0;
-	}
-	if (!pgp_write_xfer_pubkey(create, key, noarmor)) {
-		(void) fprintf(io->errs, "Cannot write pubkey\n");
-		return 0;
-	}
-	pgp_teardown_file_write(create, fd);
-	return 1;
-}
-
 /* return 1 if the file contains ascii-armoured text */
 static unsigned
 isarmoured(pgp_io_t *io, const char *f, const void *memory, const char *text)
@@ -523,47 +591,8 @@ pobj(FILE *fp, mj_t *obj, int depth)
 		(void) fprintf(stderr, "No object found\n");
 		return;
 	}
-	for (i = 0 ; i < (unsigned)depth ; i++) {
-		p(fp, " ", NULL);
-	}
-	switch(obj->type) {
-	case MJ_NULL:
-	case MJ_FALSE:
-	case MJ_TRUE:
-		p(fp, (obj->type == MJ_NULL) ? "null" : (obj->type == MJ_FALSE) ? "false" : "true", NULL);
-		break;
-	case MJ_NUMBER:
-		p(fp, obj->value.s, NULL);
-		break;
-	case MJ_STRING:
-		if ((i = mj_asprint(&s, obj, MJ_HUMAN)) > 2) {
-			(void) fprintf(fp, "%.*s", (int)i - 2, &s[1]);
-			free(s);
-		}
-		break;
-	case MJ_ARRAY:
-		for (i = 0 ; i < obj->c ; i++) {
-			pobj(fp, &obj->value.v[i], depth + 1);
-			if (i < obj->c - 1) {
-				(void) fprintf(fp, ", "); 
-			}
-		}
-		(void) fprintf(fp, "\n"); 
-		break;
-	case MJ_OBJECT:
-		for (i = 0 ; i < obj->c ; i += 2) {
-			pobj(fp, &obj->value.v[i], depth + 1);
-			p(fp, ": ", NULL); 
-			pobj(fp, &obj->value.v[i + 1], 0);
-			if (i < obj->c - 1) {
-				p(fp, ", ", NULL); 
-			}
-		}
-		p(fp, "\n", NULL); 
-		break;
-	default:
-		break;
-	}
+
+	mj_pretty(obj, fp, depth, "");
 }
 
 /* return the time as a string */
@@ -843,7 +872,6 @@ netpgp_init(netpgp_t *netpgp)
 		/* read from ordinary pgp keyrings */
 		netpgp->pubring = readkeyring(netpgp, "pubring");
 		if (netpgp->pubring == NULL) {
-			(void) fprintf(io->errs, "Can't read pub keyring\n");
 			return 0;
 		}
 		/* if a userid has been given, we'll use it */
@@ -860,7 +888,6 @@ netpgp_init(netpgp_t *netpgp)
 			/* read the secret ring */
 			netpgp->secring = readkeyring(netpgp, "secring");
 			if (netpgp->secring == NULL) {
-				(void) fprintf(io->errs, "Can't read sec keyring\n");
 				return 0;
 			}
 			/* now, if we don't have a valid user, use the first in secring */
@@ -886,7 +913,6 @@ netpgp_init(netpgp_t *netpgp)
 		/* read from ssh keys */
 		last = (netpgp->pubring != NULL);
 		if (!readsshkeys(netpgp, homedir, netpgp_getvar(netpgp, "need seckey"))) {
-			(void) fprintf(io->errs, "Can't read ssh keys\n");
 			return 0;
 		}
 		if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) {
@@ -1060,7 +1086,7 @@ netpgp_match_keys_json(netpgp_t *netpgp,
 					id_array.c, 10, 10, "netpgp_match_keys_json", return 0);
 				pgp_sprint_mj(netpgp->io, netpgp->pubring,
 						key, &id_array.value.v[id_array.c++],
-						"signature ",
+						"signature",
 						&key->key.pubkey, psigs);
 			}
 			k += 1;
@@ -1153,15 +1179,52 @@ netpgp_import_key(netpgp_t *netpgp, char
 	pgp_io_t	*io;
 	unsigned	 realarmor;
 	int		 done;
+	pgp_keyring_t	*keyring;
+	pgp_key_t	*key;
+	const char	*ringname;
+	int		 rv;
 
 	io = netpgp->io;
+
+	if (f == NULL) {
+		(void) fprintf(io->errs, "No input file given\n");
+		return 0;
+	}
+
+	if ((keyring = calloc(1, sizeof(*keyring))) == NULL) {
+		(void) fprintf(io->errs, "netpgp_import_key: bad alloc\n");
+		return 0;
+	}
+
 	realarmor = isarmoured(io, f, NULL, IMPORT_ARMOR_HEAD);
-	done = pgp_keyring_fileread(netpgp->pubring, realarmor, f);
-	if (!done) {
+	done = pgp_keyring_fileread(keyring, realarmor, f);
+	if (!done || keyring->keyc == 0) {
 		(void) fprintf(io->errs, "Cannot import key from file %s\n", f);
+		pgp_keyring_free(keyring);
+		return 0;
+	}
+	done = pgp_keyring_list(io, keyring, 0);
+	if (!done)
+		return 0;
+
+	key = keyring->keys;
+
+	if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
+		ringname = "pubring";
+	} else {
+		ringname = "secring";
+	}
+
+	if (!done) {
+		pgp_keyring_free(keyring);
+		(void) fprintf(io->errs, "Bad append\n");
 		return 0;
 	}
-	return pgp_keyring_list(io, netpgp->pubring, 0);
+
+	rv = appendtokeyring(netpgp, ringname, key);
+	pgp_keyring_free(keyring);
+
+	return rv;
 }
 
 #define ID_OFFSET	38

Index: src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c:1.51 src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c:1.52
--- src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c:1.51	Mon Mar  5 02:20:18 2012
+++ src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c	Tue Nov 13 14:52:30 2018
@@ -58,7 +58,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: packet-parse.c,v 1.51 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD: packet-parse.c,v 1.52 2018/11/13 14:52:30 mlelstv Exp $");
 #endif
 
 #include <sys/types.h>
@@ -866,6 +866,7 @@ pgp_subpacket_free(pgp_subpacket_t *pack
 {
 	free(packet->raw);
 	packet->raw = NULL;
+	packet->tag = PGP_PTAG_CT_RESERVED;
 }
 
 /**
@@ -3066,11 +3067,12 @@ parse_mdc(pgp_region_t *region, pgp_stre
 static int 
 parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
 {
-	pgp_packet_t	pkt;
-	pgp_region_t	region;
-	uint8_t		ptag;
-	unsigned	indeterminate = 0;
-	int		ret;
+	pgp_packet_t		pkt;
+	pgp_region_t		region;
+	pgp_content_enum	tag;
+	uint8_t			ptag;
+	unsigned		indeterminate = 0;
+	int			ret;
 
 	pkt.u.ptag.position = stream->readinfo.position;
 
@@ -3142,6 +3144,9 @@ parse_packet(pgp_stream_t *stream, uint3
 		(void) fprintf(stderr, "parse_packet: type %u\n",
 			       pkt.u.ptag.type);
 	}
+
+	/* save tag for accumulator */
+	tag = pkt.u.ptag.type;
 	switch (pkt.u.ptag.type) {
 	case PGP_PTAG_CT_SIGNATURE:
 		ret = parse_sig(&region, stream);
@@ -3232,6 +3237,7 @@ parse_packet(pgp_stream_t *stream, uint3
 	if (ret > 0 && stream->readinfo.accumulate) {
 		pkt.u.packet.length = stream->readinfo.alength;
 		pkt.u.packet.raw = stream->readinfo.accumulated;
+		pkt.u.packet.tag = tag;
 		stream->readinfo.accumulated = NULL;
 		stream->readinfo.asize = 0;
 		CALLBACK(PGP_PARSER_PACKET_END, &stream->cbinfo, &pkt);

Index: src/crypto/external/bsd/netpgp/dist/src/lib/packet.h
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/packet.h:1.30 src/crypto/external/bsd/netpgp/dist/src/lib/packet.h:1.31
--- src/crypto/external/bsd/netpgp/dist/src/lib/packet.h:1.30	Mon Nov 15 08:56:30 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/packet.h	Tue Nov 13 14:52:30 2018
@@ -675,6 +675,7 @@ typedef struct pgp_ss_sig_target_t {
 
 /** pgp_subpacket_t */
 typedef struct pgp_subpacket_t {
+	pgp_content_enum	 tag;
 	size_t          	 length;
 	uint8_t			*raw;
 } pgp_subpacket_t;

Index: src/crypto/external/bsd/netpgp/dist/src/libmj/libmj.3
diff -u src/crypto/external/bsd/netpgp/dist/src/libmj/libmj.3:1.9 src/crypto/external/bsd/netpgp/dist/src/libmj/libmj.3:1.10
--- src/crypto/external/bsd/netpgp/dist/src/libmj/libmj.3:1.9	Wed Apr  4 21:39:35 2018
+++ src/crypto/external/bsd/netpgp/dist/src/libmj/libmj.3	Tue Nov 13 14:52:30 2018
@@ -1,4 +1,4 @@
-.\" $NetBSD: libmj.3,v 1.9 2018/04/04 21:39:35 sevan Exp $
+.\" $NetBSD: libmj.3,v 1.10 2018/11/13 14:52:30 mlelstv Exp $
 .\"
 .\" Copyright (c) 2010 Alistair Crooks <a...@netbsd.org>
 .\" All rights reserved.
@@ -161,7 +161,7 @@ function is used.
 The calling interface gives the ability to indent the
 output to a given
 .Fa depth
-and for the formatted output to be followed by a
+in characters and for the formatted output to be followed by a
 .Fa trailer
 string, which is usually
 .Dv NULL

Index: src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c
diff -u src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c:1.5 src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c:1.6
--- src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c:1.5	Sat Jun 25 00:37:44 2011
+++ src/crypto/external/bsd/netpgp/dist/src/libmj/mj.c	Tue Nov 13 14:52:30 2018
@@ -35,9 +35,16 @@
 #include "mj.h"
 #include "defs.h"
 
-/* save 'n' chars of 's' in malloc'd memory */
+#define JSON_ESCAPE '\xac'
+#define JSON_INDENT 4
+
+/*
+ * save 'n' chars of 's' in malloc'd memory
+ *
+ * optionally encode embedded quotes and null bytes
+ */
 static char *
-strnsave(const char *s, int n, unsigned encoded)
+strnsave(const char *s, int n, int encoded)
 {
 	char	*newc;
 	char	*cp;
@@ -47,19 +54,20 @@ strnsave(const char *s, int n, unsigned 
 		n = (int)strlen(s);
 	}
 	NEWARRAY(char, cp, n + n + 1, "strnsave", return NULL);
-	if (encoded) {
+	switch (encoded) {
+	case MJ_JSON_ENCODE:
 		newc = cp;
 		for (i = 0 ; i < n ; i++) {
-			if ((uint8_t)*s == 0xac) {
-				*newc++ = (char)0xac;
+			if (*s == JSON_ESCAPE) {
+				*newc++ = JSON_ESCAPE;
 				*newc++ = '1';
 				s += 1;
 			} else if (*s == '"') {
-				*newc++ = (char)0xac;
+				*newc++ = JSON_ESCAPE;
 				*newc++ = '2';
 				s += 1;
 			} else if (*s == 0x0) {
-				*newc++ = (char)0xac;
+				*newc++ = JSON_ESCAPE;
 				*newc++ = '0';
 				s += 1;
 			} else {
@@ -67,9 +75,11 @@ strnsave(const char *s, int n, unsigned 
 			}
 		}
 		*newc = 0x0;
-	} else {
+		break;
+	default:
 		(void) memcpy(cp, s, (unsigned)n);
 		cp[n] = 0x0;
+		break;
 	}
 	return cp;
 }
@@ -168,7 +178,7 @@ indent(FILE *fp, unsigned depth, const c
 	unsigned	i;
 
 	for (i = 0 ; i < depth ; i++) {
-		(void) fprintf(fp, "    ");
+		(void) fprintf(fp, " ");
 	}
 	if (trailer) {
 		(void) fprintf(fp, "%s", trailer);
@@ -225,7 +235,11 @@ mj_create(mj_t *atom, const char *type, 
 	return 1;
 }
 
-/* put a JSON tree into a text string */
+/*
+ * put a JSON tree into a text string
+ *
+ * optionally keep encoded quotes and null bytes
+ */
 int
 mj_snprint(char *buf, size_t size, mj_t *atom, int encoded)
 {
@@ -244,55 +258,66 @@ mj_snprint(char *buf, size_t size, mj_t 
 	case MJ_NUMBER:
 		return snprintf(buf, size, "%s", atom->value.s);
 	case MJ_STRING:
-		if (encoded) {
+		if (size < 3)
+			return 0;
+		switch (encoded) {
+		case MJ_JSON_ENCODE:
 			return snprintf(buf, size, "\"%s\"", atom->value.s);
-		}
-		for (bp = buf, *bp++ = '"', s = atom->value.s ;
-		     (size_t)(bp - buf) < size && (unsigned)(s - atom->value.s) < atom->c ; ) {
-			if ((uint8_t)*s == 0xac) {
-				switch(s[1]) {
-				case '0':
-					*bp++ = 0x0;
-					s += 2;
-					break;
-				case '1':
-					*bp++ = (char)0xac;
-					s += 2;
-					break;
-				case '2':
-					*bp++ = '"';
-					s += 2;
-					break;
-				default:
-					(void) fprintf(stderr, "unrecognised character '%02x'\n", (uint8_t)s[1]);
-					s += 1;
-					break;
+		default:
+			for (bp = buf, *bp++ = '"', s = atom->value.s ;
+			     (size_t)(bp - buf) < size - 2 && (unsigned)(s - atom->value.s) < atom->c ; ) {
+				if (*s == JSON_ESCAPE) {
+					switch(s[1]) {
+					case '0':
+						if ((size_t)(bp - buf) < size - 3)
+							break;
+						*bp++ = '\\';
+						*bp++ = '0';
+						s += 2;
+						break;
+					case '1':
+						*bp++ = JSON_ESCAPE;
+						s += 2;
+						break;
+					case '2':
+						if ((size_t)(bp - buf) < size - 3)
+							break;
+						*bp++ = '\\';
+						*bp++ = '"';
+						s += 2;
+						break;
+					default:
+						(void) fprintf(stderr, "unrecognised character '%02x'\n", (uint8_t)s[1]);
+						s += 1;
+						break;
+					}
+				} else {
+					*bp++ = *s++;
 				}
-			} else {
-				*bp++ = *s++;
 			}
+			*bp++ = '"';
+			*bp = 0x0;
+			return bp - buf;
 		}
-		*bp++ = '"';
-		*bp = 0x0;
-		return (int)(bp - buf) - 1;
+		break;
 	case MJ_ARRAY:
 		cc = snprintf(buf, size, "[ ");
 		for (i = 0 ; i < atom->c ; i++) {
+			const char *sep = i+1 < atom->c ? ", " : " ";
+
 			cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i], encoded);
-			if (i < atom->c - 1) {
-				cc += snprintf(&buf[cc], size - cc, ", ");
-			}
+			cc += snprintf(&buf[cc], size - cc, "%s", sep);
 		}
 		return cc + snprintf(&buf[cc], size - cc, "]\n");
 	case MJ_OBJECT:
 		cc = snprintf(buf, size, "{ ");
-		for (i = 0 ; i < atom->c ; i += 2) {
+		for (i = 0 ; i < atom->c - 1; i += 2) {
+			const char *sep = i+2 < atom->c ? ", " : " ";
+
 			cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i], encoded);
 			cc += snprintf(&buf[cc], size - cc, ":");
 			cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i + 1], encoded);
-			if (i + 1 < atom->c - 1) {
-				cc += snprintf(&buf[cc], size - cc, ", ");
-			}
+			cc += snprintf(&buf[cc], size - cc, "%s", sep);
 		}
 		return cc + snprintf(&buf[cc], size - cc, "}\n");
 	default:
@@ -305,13 +330,13 @@ mj_snprint(char *buf, size_t size, mj_t 
 int
 mj_asprint(char **buf, mj_t *atom, int encoded)
 {
-	int	 size;
+	size_t	size;
 
-	size = mj_string_size(atom);
-	if ((*buf = calloc(1, (unsigned)(size + 1))) == NULL) {
+	size = mj_string_size(atom) + 1;
+	if ((*buf = calloc(1, size)) == NULL) {
 		return -1;
 	}
-	return mj_snprint(*buf, (unsigned)(size + 1), atom, encoded) + 1;
+	return mj_snprint(*buf, size, atom, encoded);
 }
 
 /* read into a JSON tree from a string */
@@ -322,11 +347,11 @@ mj_parse(mj_t *atom, const char *s, int 
 
 	switch(atom->type = *tok = gettok(s, from, to, tok)) {
 	case MJ_NUMBER:
-		atom->value.s = strnsave(&s[*from], *to - *from, MJ_JSON_ENCODE);
+		atom->value.s = strnsave(&s[*from], *to - *from, MJ_HUMAN);
 		atom->c = atom->size = (unsigned)strlen(atom->value.s);
 		return gettok(s, from, to, tok);
 	case MJ_STRING:
-		atom->value.s = strnsave(&s[*from + 1], *to - *from - 2, MJ_HUMAN);
+		atom->value.s = strnsave(&s[*from + 1], *to - *from - 2, MJ_JSON_ENCODE);
 		atom->c = atom->size = (unsigned)strlen(atom->value.s);
 		return gettok(s, from, to, tok);
 	case MJ_NULL:
@@ -460,29 +485,35 @@ mj_string_size(mj_t *atom)
 	switch(atom->type) {
 	case MJ_NULL:
 	case MJ_TRUE:
+		/* true */
 		return 4;
 	case MJ_FALSE:
+		/* false */
 		return 5;
 	case MJ_NUMBER:
 		return atom->c;
 	case MJ_STRING:
+		/* "string" */
 		return atom->c + 2;
 	case MJ_ARRAY:
+		/* start '[ ' */
 		for (cc = 2, i = 0 ; i < atom->c ; i++) {
 			cc += mj_string_size(&atom->value.v[i]);
-			if (i < atom->c - 1) {
-				cc += 2;
-			}
+			/* separator ', ' or ' ' */
+			cc += (i < atom->c - 1) ? 2 : 1;
 		}
-		return cc + 1 + 1;
+		/* end ']' */
+		return cc + 1;
 	case MJ_OBJECT:
+		/* start '{ ' */
 		for (cc = 2, i = 0 ; i < atom->c ; i += 2) {
+			/* key:value */
 			cc += mj_string_size(&atom->value.v[i]) + 1 + mj_string_size(&atom->value.v[i + 1]);
-			if (i + 1 < atom->c - 1) {
-				cc += 2;
-			}
+			/* separator ', ' or ' ' */
+			cc += (i < atom->c - 1) ? 2 : 1;
 		}
-		return cc + 1 + 1;
+		/* end '}' */
+		return cc + 1;
 	default:
 		(void) fprintf(stderr, "mj_string_size: weird type %d\n", atom->type);
 		return 0;
@@ -607,20 +638,20 @@ mj_pretty(mj_t *mj, void *vp, unsigned d
 	case MJ_STRING:
 		indent(fp, depth, NULL);
 		mj_asprint(&s, mj, MJ_HUMAN);
-		(void) fprintf(fp, "\"%s\"", s);
+		(void) fprintf(fp, "%s", s);
 		free(s);
 		break;
 	case MJ_ARRAY:
 		indent(fp, depth, "[\n");
 		for (i = 0 ; i < mj->c ; i++) {
-			mj_pretty(&mj->value.v[i], fp, depth + 1, (i < mj->c - 1) ? ",\n" : "\n");
+			mj_pretty(&mj->value.v[i], fp, depth + JSON_INDENT, (i < mj->c - 1) ? ",\n" : "\n");
 		}
 		indent(fp, depth, "]");
 		break;
 	case MJ_OBJECT:
 		indent(fp, depth, "{\n");
 		for (i = 0 ; i < mj->c ; i += 2) {
-			mj_pretty(&mj->value.v[i], fp, depth + 1, " : ");
+			mj_pretty(&mj->value.v[i], fp, depth + JSON_INDENT, " : ");
 			mj_pretty(&mj->value.v[i + 1], fp, 0, (i < mj->c - 2) ? ",\n" : "\n");
 		}
 		indent(fp, depth, "}");

Index: src/crypto/external/bsd/netpgp/dist/src/netpgpkeys/netpgpkeys.c
diff -u src/crypto/external/bsd/netpgp/dist/src/netpgpkeys/netpgpkeys.c:1.26 src/crypto/external/bsd/netpgp/dist/src/netpgpkeys/netpgpkeys.c:1.27
--- src/crypto/external/bsd/netpgp/dist/src/netpgpkeys/netpgpkeys.c:1.26	Wed Dec 17 16:50:52 2014
+++ src/crypto/external/bsd/netpgp/dist/src/netpgpkeys/netpgpkeys.c	Tue Nov 13 14:52:30 2018
@@ -454,6 +454,9 @@ main(int argc, char **argv)
 		netpgp_set_homedir(&netpgp, getenv("HOME"),
 			netpgp_getvar(&netpgp, "ssh keys") ? "/.ssh" : "/.gnupg", 1);
 	}
+	if (p.keyring[0] != '\0') {
+		netpgp_setvar(&netpgp, "pubring", p.keyring);
+	}
 	/* initialise, and read keys from file */
 	if (!netpgp_init(&netpgp)) {
 		if (stat(netpgp_getvar(&netpgp, "homedir"), &st) < 0) {

Reply via email to