Fix some error handling, json support, keyring handling.
This commit is contained in:
parent
9f7f145236
commit
3118701f5e
@ -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 pgp_subpacket_t *src)
|
||||
}
|
||||
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, const pgp_subpacket_t *packet)
|
||||
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, uint8_t *userid)
|
||||
/* 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, pgp_cbdata_t *cbinfo)
|
||||
|
||||
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, pgp_cbdata_t *cbinfo)
|
||||
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, pgp_cbdata_t *cbinfo)
|
||||
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, pgp_cbdata_t *cbinfo)
|
||||
}
|
||||
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, pgp_cbdata_t *cbinfo)
|
||||
case PGP_PTAG_CT_SIGNATURE_FOOTER:
|
||||
case PGP_PARSER_ERRCODE:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -812,6 +807,77 @@ pgp_keyring_read_from_mem(pgp_io_t *io,
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
\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
|
||||
|
||||
@ -1030,7 +1096,8 @@ pgp_keyring_list(pgp_io_t *io, const pgp_keyring_t *keyring, const int psigs)
|
||||
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_keyring_t *keyring, mj_t *obj, const in
|
||||
"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;
|
||||
|
@ -96,6 +96,8 @@ pgp_seckey_t *pgp_decrypt_seckey(const pgp_key_t *, FILE *);
|
||||
|
||||
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_key_t *);
|
||||
|
||||
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 *);
|
||||
|
||||
|
27
crypto/external/bsd/netpgp/dist/src/lib/misc.c
vendored
27
crypto/external/bsd/netpgp/dist/src/lib/misc.c
vendored
@ -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, pgp_cbdata_t *cbinfo)
|
||||
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, pgp_cbdata_t *cbinfo)
|
||||
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;
|
||||
|
225
crypto/external/bsd/netpgp/dist/src/lib/netpgp.c
vendored
225
crypto/external/bsd/netpgp/dist/src/lib/netpgp.c
vendored
@ -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 *name)
|
||||
return (i == netpgp->c) ? -1 : (int)i;
|
||||
}
|
||||
|
||||
/* 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 filename of a keyring */
|
||||
static char *
|
||||
keyringfile(netpgp_t *netpgp, const char *name)
|
||||
{
|
||||
char f[MAXPATHLEN];
|
||||
char *homedir;
|
||||
char *filename;
|
||||
|
||||
homedir = netpgp_getvar(netpgp, "homedir");
|
||||
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 f[MAXPATHLEN];
|
||||
char *filename;
|
||||
char *homedir;
|
||||
|
||||
homedir = netpgp_getvar(netpgp, "homedir");
|
||||
if ((filename = netpgp_getvar(netpgp, name)) == NULL) {
|
||||
(void) snprintf(f, sizeof(f), "%s/%s.gpg", homedir, name);
|
||||
filename = f;
|
||||
}
|
||||
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 pgp_keyring_t *keyring, const char *useri
|
||||
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, char **json, char *name, const char *fm
|
||||
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 *f)
|
||||
pgp_io_t *io;
|
||||
unsigned realarmor;
|
||||
int done;
|
||||
pgp_keyring_t *keyring;
|
||||
pgp_key_t *key;
|
||||
const char *ringname;
|
||||
int rv;
|
||||
|
||||
io = netpgp->io;
|
||||
realarmor = isarmoured(io, f, NULL, IMPORT_ARMOR_HEAD);
|
||||
done = pgp_keyring_fileread(netpgp->pubring, realarmor, f);
|
||||
if (!done) {
|
||||
(void) fprintf(io->errs, "Cannot import key from file %s\n", f);
|
||||
|
||||
if (f == NULL) {
|
||||
(void) fprintf(io->errs, "No input file given\n");
|
||||
return 0;
|
||||
}
|
||||
return pgp_keyring_list(io, netpgp->pubring, 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(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;
|
||||
}
|
||||
|
||||
rv = appendtokeyring(netpgp, ringname, key);
|
||||
pgp_keyring_free(keyring);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define ID_OFFSET 38
|
||||
|
@ -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 *packet)
|
||||
{
|
||||
free(packet->raw);
|
||||
packet->raw = NULL;
|
||||
packet->tag = PGP_PTAG_CT_RESERVED;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3066,11 +3067,12 @@ parse_mdc(pgp_region_t *region, pgp_stream_t *stream)
|
||||
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, uint32_t *pktlen)
|
||||
(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, uint32_t *pktlen)
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -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 <agc@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
|
||||
|
153
crypto/external/bsd/netpgp/dist/src/libmj/mj.c
vendored
153
crypto/external/bsd/netpgp/dist/src/libmj/mj.c
vendored
@ -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 encoded)
|
||||
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 encoded)
|
||||
}
|
||||
}
|
||||
*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 char *trailer)
|
||||
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 *atom, int encoded)
|
||||
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 *atom, int encoded)
|
||||
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 *from, int *to, int *tok)
|
||||
|
||||
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 depth, const char *trailer)
|
||||
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, "}");
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user