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(®ion, 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) {