From 5cb3cfdb9d8caa6d7a4a1979c50c46896957b934 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 9 Nov 2013 12:29:15 -0800 Subject: [PATCH] Introduce and use a structure to hold OpenPGP fingerprints Fingerprint lengths can be 16 bytes (for v3 keys) or 20 bytes (for v4 keys). Rather than passing around a size and fingerprint buffer separately use a structure to hold both pieces of information and just pass that around. --- keyd.c | 7 ++++--- keydb.c | 8 ++++---- keydb.h | 3 +-- keydb_dynamic.c | 4 ++-- keydb_hkp.c | 10 +++++----- keydb_keyd.c | 8 ++++---- keyid.c | 26 +++++++++++--------------- keyid.h | 6 ++---- keyindex.c | 23 +++++++++++------------ keystructs.h | 10 ++++++++++ lookup.c | 34 ++++++++++++++++++---------------- onak.c | 33 ++++++++++++++++++--------------- 12 files changed, 90 insertions(+), 82 deletions(-) diff --git a/keyd.c b/keyd.c index 5cd7b57..b8b8ad3 100644 --- a/keyd.c +++ b/keyd.c @@ -155,13 +155,13 @@ int sock_do(struct onak_dbctx *dbctx, int fd) ssize_t count = 0; int ret = 0; uint64_t keyid = 0; - uint8_t fp[MAX_FINGERPRINT_LEN]; char *search = NULL; struct openpgp_publickey *key = NULL; struct openpgp_packet_list *packets = NULL; struct openpgp_packet_list *list_end = NULL; struct buffer_ctx storebuf; struct skshash hash; + struct openpgp_fingerprint fingerprint; /* * Get the command from the client. @@ -242,7 +242,8 @@ int sock_do(struct onak_dbctx *dbctx, int fd) if (bytes > MAX_FINGERPRINT_LEN) { ret = 1; } else { - read(fd, fp, bytes); + fingerprint.length = bytes; + read(fd, fingerprint.fp, bytes); } storebuf.offset = 0; if (ret == 0) { @@ -250,7 +251,7 @@ int sock_do(struct onak_dbctx *dbctx, int fd) "Fetching by fingerprint" ", result: %d", dbctx->fetch_key_fp(dbctx, - fp, bytes, + &fingerprint, &key, false)); if (key != NULL) { storebuf.size = 8192; diff --git a/keydb.c b/keydb.c index 57472f9..354255f 100644 --- a/keydb.c +++ b/keydb.c @@ -253,13 +253,13 @@ int generic_update_keys(struct onak_dbctx *dbctx, #ifdef NEED_GET_FP static int generic_fetch_key_fp(struct onak_dbctx *dbctx, - uint8_t *fp, size_t fpsize, + struct openpgp_fingerprint *fingerprint, struct openpgp_publickey **publickey, bool intrans) { uint64_t keyid; int i; - if (fpsize > MAX_FINGERPRINT_LEN) { + if (fingerprint->length > MAX_FINGERPRINT_LEN) { return 0; } @@ -271,8 +271,8 @@ static int generic_fetch_key_fp(struct onak_dbctx *dbctx, * if the backend can't do it we're going to fail anyway. */ keyid = 0; - for (i = (fpsize - 8); i < fpsize; i++) { - keyid = (keyid << 8) + fp[i]; + for (i = (fingerprint->length - 8); i < fingerprint->length; i++) { + keyid = (keyid << 8) + fingerprint->fp[i]; } return dbctx->fetch_key_id(dbctx, keyid, publickey, intrans); diff --git a/keydb.h b/keydb.h index 50f969a..6c1bcf5 100644 --- a/keydb.h +++ b/keydb.h @@ -81,8 +81,7 @@ struct onak_dbctx { * are using. */ int (*fetch_key_fp)(struct onak_dbctx *, - uint8_t *fp, - size_t fpsize, + struct openpgp_fingerprint *fingerprint, struct openpgp_publickey **publickey, bool intrans); diff --git a/keydb_dynamic.c b/keydb_dynamic.c index 32695c3..1e7d6b2 100644 --- a/keydb_dynamic.c +++ b/keydb_dynamic.c @@ -66,14 +66,14 @@ static int dynamic_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid, } static int dynamic_fetch_key_fp(struct onak_dbctx *dbctx, - uint8_t *fp, size_t fpsize, + struct openpgp_fingerprint *fingerprint, struct openpgp_publickey **publickey, bool intrans) { struct onak_dynamic_dbctx *privctx = (struct onak_dynamic_dbctx *) dbctx->priv; return privctx->loadeddbctx->fetch_key_fp(privctx->loadeddbctx, - fp, fpsize, publickey, intrans); + fingerprint, publickey, intrans); } static int dynamic_fetch_key_text(struct onak_dbctx *dbctx, diff --git a/keydb_hkp.c b/keydb_hkp.c index 8bb8c02..0c6fd5a 100644 --- a/keydb_hkp.c +++ b/keydb_hkp.c @@ -163,7 +163,7 @@ static int hkp_fetch_key_id(struct onak_dbctx *dbctx, * hkp_fetch_key_fp - Given a fingerprint fetch the key from HKP server. */ static int hkp_fetch_key_fp(struct onak_dbctx *dbctx, - uint8_t *fp, size_t fpsize, + struct openpgp_fingerprint *fingerprint, struct openpgp_publickey **publickey, bool intrans) { @@ -171,19 +171,19 @@ static int hkp_fetch_key_fp(struct onak_dbctx *dbctx, char keyurl[1024]; int i, ofs; - if (fpsize > MAX_FINGERPRINT_LEN) { + if (fingerprint->length > MAX_FINGERPRINT_LEN) { return 0; } ofs = snprintf(keyurl, sizeof(keyurl), "%s/lookup?op=get&search=0x", privctx->hkpbase); - if ((ofs + fpsize * 2 + 1)> sizeof(keyurl)) { + if ((ofs + fingerprint->length * 2 + 1)> sizeof(keyurl)) { return 0; } - for (i = 0; i < fpsize; i++) { - ofs += sprintf(&keyurl[ofs], "%02X", fp[i]); + for (i = 0; i < fingerprint->length; i++) { + ofs += sprintf(&keyurl[ofs], "%02X", fingerprint->fp[i]); } return (hkp_fetch_key_url(dbctx, keyurl, publickey, intrans)); diff --git a/keydb_keyd.c b/keydb_keyd.c index 1d10928..d05c7f8 100644 --- a/keydb_keyd.c +++ b/keydb_keyd.c @@ -116,7 +116,7 @@ static int keyd_fetch_key_id(struct onak_dbctx *dbctx, } static int keyd_fetch_key_fp(struct onak_dbctx *dbctx, - uint8_t *fp, size_t fpsize, + struct openpgp_fingerprint *fingerprint, struct openpgp_publickey **publickey, bool intrans) { @@ -128,16 +128,16 @@ static int keyd_fetch_key_fp(struct onak_dbctx *dbctx, ssize_t count = 0; uint8_t size; - if (fpsize > MAX_FINGERPRINT_LEN) { + if (fingerprint->length > MAX_FINGERPRINT_LEN) { return 0; } write(keyd_fd, &cmd, sizeof(cmd)); read(keyd_fd, &cmd, sizeof(cmd)); if (cmd == KEYD_REPLY_OK) { - size = fpsize; + size = fingerprint->length; write(keyd_fd, &size, sizeof(size)); - write(keyd_fd, fp, size); + write(keyd_fd, fingerprint->fp, size); keybuf.offset = 0; read(keyd_fd, &keybuf.size, sizeof(keybuf.size)); if (keybuf.size > 0) { diff --git a/keyid.c b/keyid.c index 6920ee4..6a9b558 100644 --- a/keyid.c +++ b/keyid.c @@ -59,8 +59,7 @@ onak_status_t get_keyid(struct openpgp_publickey *publickey, uint64_t *keyid) * which we've returned. */ onak_status_t get_fingerprint(struct openpgp_packet *packet, - unsigned char *fingerprint, - size_t *len) + struct openpgp_fingerprint *fingerprint) { struct sha1_ctx sha_ctx; struct md5_ctx md5_context; @@ -69,10 +68,8 @@ onak_status_t get_fingerprint(struct openpgp_packet *packet, if (fingerprint == NULL) return ONAK_E_INVALID_PARAM; - if (len == NULL) - return ONAK_E_INVALID_PARAM; - *len = 0; + fingerprint->length = 0; switch (packet->data[0]) { case 2: @@ -90,8 +87,8 @@ onak_status_t get_fingerprint(struct openpgp_packet *packet, packet->data[11+modlen] + 7) >> 3; md5_update(&md5_context, explen, &packet->data[12 + modlen]); - *len = 16; - md5_digest(&md5_context, *len, fingerprint); + fingerprint->length = 16; + md5_digest(&md5_context, fingerprint->length, fingerprint->fp); break; @@ -109,8 +106,8 @@ onak_status_t get_fingerprint(struct openpgp_packet *packet, sha1_update(&sha_ctx, sizeof(c), &c); sha1_update(&sha_ctx, packet->length, packet->data); - *len = 20; - sha1_digest(&sha_ctx, *len, fingerprint); + fingerprint->length = 20; + sha1_digest(&sha_ctx, fingerprint->length, fingerprint->fp); break; default: @@ -129,8 +126,7 @@ onak_status_t get_packetid(struct openpgp_packet *packet, uint64_t *keyid) { int offset = 0; int i = 0; - size_t length = 0; - unsigned char buff[20]; + struct openpgp_fingerprint fingerprint; #ifdef NETTLE_WITH_RIPEMD160 struct ripemd160_ctx ripemd160_context; uint8_t data; @@ -162,11 +158,11 @@ onak_status_t get_packetid(struct openpgp_packet *packet, uint64_t *keyid) ripemd160_digest(&ripemd160_context, RIPEMD160_DIGEST_SIZE, - buff); + fingerprint.fp); for (*keyid = 0, i = 12; i < 20; i++) { *keyid <<= 8; - *keyid += buff[i]; + *keyid += fingerprint.fp[i]; } return ONAK_E_OK; @@ -197,11 +193,11 @@ onak_status_t get_packetid(struct openpgp_packet *packet, uint64_t *keyid) } break; case 4: - get_fingerprint(packet, buff, &length); + get_fingerprint(packet, &fingerprint); for (*keyid = 0, i = 12; i < 20; i++) { *keyid <<= 8; - *keyid += buff[i]; + *keyid += fingerprint.fp[i]; } break; diff --git a/keyid.h b/keyid.h index a0ae4ff..47f7d16 100644 --- a/keyid.h +++ b/keyid.h @@ -37,16 +37,14 @@ onak_status_t get_keyid(struct openpgp_publickey *publickey, uint64_t *keyid); /** * get_fingerprint - Given a public key returns the fingerprint. * @publickey: The key to calculate the id for. - * @fingerprint: The fingerprint (must be at least 20 bytes of space). - * @len: The length of the returned fingerprint. + * @fingerprint: The fingerprint structure to store the result in * * This function returns the fingerprint for a given public key. As Type 3 * fingerprints are 16 bytes and Type 4 are 20 the len field indicates * which we've returned. */ onak_status_t get_fingerprint(struct openpgp_packet *packet, - unsigned char *fingerprint, - size_t *len); + struct openpgp_fingerprint *fingerprint); /** * get_packetid - Given a PGP packet returns the keyid. diff --git a/keyindex.c b/keyindex.c index 4ca6a41..4dbb074 100644 --- a/keyindex.c +++ b/keyindex.c @@ -284,21 +284,21 @@ int list_subkeys(struct onak_dbctx *dbctx, void display_fingerprint(struct openpgp_publickey *key) { int i = 0; - size_t length = 0; - unsigned char fp[20]; + struct openpgp_fingerprint fingerprint; - get_fingerprint(key->publickey, fp, &length); + get_fingerprint(key->publickey, &fingerprint); printf(" Key fingerprint ="); - for (i = 0; i < length; i++) { - if ((length == 16) || + for (i = 0; i < fingerprint.length; i++) { + if ((fingerprint.length == 16) || (i % 2 == 0)) { printf(" "); } - if (length == 20 && (i * 2) == length) { + if (fingerprint.length == 20 && + (i * 2) == fingerprint.length) { /* Extra space in the middle of a SHA1 fingerprint */ printf(" "); } - printf("%02X", fp[i]); + printf("%02X", fingerprint.fp[i]); } printf("\n"); @@ -464,10 +464,9 @@ int mrkey_index(struct openpgp_publickey *keys) int type = 0; int length = 0; int i = 0; - size_t fplength = 0; - unsigned char fp[20]; int c; uint64_t keyid; + struct openpgp_fingerprint fingerprint; while (keys != NULL) { created_time = (keys->publickey->data[1] << 24) + @@ -487,10 +486,10 @@ int mrkey_index(struct openpgp_publickey *keys) type = keys->publickey->data[7]; break; case 4: - (void) get_fingerprint(keys->publickey, fp, &fplength); + (void) get_fingerprint(keys->publickey, &fingerprint); - for (i = 0; i < fplength; i++) { - printf("%02X", fp[i]); + for (i = 0; i < fingerprint.length; i++) { + printf("%02X", fingerprint.fp[i]); } type = keys->publickey->data[5]; diff --git a/keystructs.h b/keystructs.h index 13f9160..108bf4b 100644 --- a/keystructs.h +++ b/keystructs.h @@ -30,6 +30,16 @@ /* v3 MD5 fingerprint is 16 characters, v4 SHA-1 fingerprint is 20 */ #define MAX_FINGERPRINT_LEN 20 +/** + * @brief Stores the fingerprint of an OpenPGP key + */ +struct openpgp_fingerprint { + /** Length of fingerprint. 16 bytes for v3, 20 for v4 */ + size_t length; + /** Fingerprint data. Only the first length bytes are valid */ + uint8_t fp[MAX_FINGERPRINT_LEN]; +}; + /** * @brief Stores an OpenPGP packet. * diff --git a/lookup.c b/lookup.c index 533433a..9815cbb 100644 --- a/lookup.c +++ b/lookup.c @@ -47,8 +47,9 @@ #define OP_HGET 5 void find_keys(struct onak_dbctx *dbctx, - char *search, uint64_t keyid, uint8_t *fp, size_t fpsize, - bool ishex, bool isfp, bool fingerprint, bool skshash, + char *search, uint64_t keyid, + struct openpgp_fingerprint *fingerprint, + bool ishex, bool isfp, bool dispfp, bool skshash, bool exact, bool verbose, bool mrhkp) { struct openpgp_publickey *publickey = NULL; @@ -58,7 +59,7 @@ void find_keys(struct onak_dbctx *dbctx, count = dbctx->fetch_key_id(dbctx, keyid, &publickey, false); } else if (isfp) { - count = dbctx->fetch_key_fp(dbctx, fp, fpsize, &publickey, + count = dbctx->fetch_key_fp(dbctx, fingerprint, &publickey, false); } else { count = dbctx->fetch_key_text(dbctx, search, &publickey); @@ -68,7 +69,7 @@ void find_keys(struct onak_dbctx *dbctx, printf("info:1:%d\n", count); mrkey_index(publickey); } else { - key_index(dbctx, publickey, verbose, fingerprint, + key_index(dbctx, publickey, verbose, dispfp, skshash, true); } free_publickey(publickey); @@ -110,14 +111,14 @@ int main(int argc, char *argv[]) int op = OP_UNKNOWN; int i; int indx = 0; - bool fingerprint = false; + bool dispfp = false; bool skshash = false; bool exact = false; bool ishex = false; bool isfp = false; bool mrhkp = false; uint64_t keyid = 0; - uint8_t fp[MAX_FINGERPRINT_LEN]; + struct openpgp_fingerprint fingerprint; char *search = NULL; char *end = NULL; struct openpgp_publickey *publickey = NULL; @@ -146,8 +147,10 @@ int main(int argc, char *argv[]) params[i+1] = NULL; if (search != NULL && strlen(search) == 42 && search[0] == '0' && search[1] == 'x') { + fingerprint.length = MAX_FINGERPRINT_LEN; for (i = 0; i < MAX_FINGERPRINT_LEN; i++) { - fp[i] = (hex2bin(search[2 + i * 2]) + fingerprint.fp[i] = (hex2bin( + search[2 + i * 2]) << 4) + hex2bin(search[3 + i * 2]); } @@ -164,7 +167,7 @@ int main(int argc, char *argv[]) indx = atoi(params[i+1]); } else if (!strcmp(params[i], "fingerprint")) { if (!strcmp(params[i+1], "on")) { - fingerprint = true; + dispfp = true; } } else if (!strcmp(params[i], "hash")) { if (!strcmp(params[i+1], "on")) { @@ -224,8 +227,8 @@ int main(int argc, char *argv[]) result = dbctx->fetch_key_id(dbctx, keyid, &publickey, false); } else if (isfp) { - result = dbctx->fetch_key_fp(dbctx, fp, - MAX_FINGERPRINT_LEN, &publickey, false); + result = dbctx->fetch_key_fp(dbctx, + &fingerprint, &publickey, false); } else { result = dbctx->fetch_key_text(dbctx, search, @@ -253,19 +256,18 @@ int main(int argc, char *argv[]) } break; case OP_INDEX: - find_keys(dbctx, search, keyid, fp, MAX_FINGERPRINT_LEN, - ishex, isfp, fingerprint, skshash, + find_keys(dbctx, search, keyid, &fingerprint, + ishex, isfp, dispfp, skshash, exact, false, mrhkp); break; case OP_VINDEX: - find_keys(dbctx, search, keyid, fp, MAX_FINGERPRINT_LEN, - ishex, isfp, fingerprint, skshash, + find_keys(dbctx, search, keyid, &fingerprint, + ishex, isfp, dispfp, skshash, exact, true, mrhkp); break; case OP_PHOTO: if (isfp) { - dbctx->fetch_key_fp(dbctx, fp, - MAX_FINGERPRINT_LEN, + dbctx->fetch_key_fp(dbctx, &fingerprint, &publickey, false); } else { dbctx->fetch_key_id(dbctx, keyid, diff --git a/onak.c b/onak.c index 7a5d693..575e7bc 100644 --- a/onak.c +++ b/onak.c @@ -45,9 +45,10 @@ #include "version.h" void find_keys(struct onak_dbctx *dbctx, - char *search, uint64_t keyid, uint8_t *fp, bool ishex, - bool isfp, bool fingerprint, bool skshash, bool exact, - bool verbose) + char *search, uint64_t keyid, + struct openpgp_fingerprint *fingerprint, + bool ishex, bool isfp, bool dispfp, bool skshash, + bool exact, bool verbose) { struct openpgp_publickey *publickey = NULL; int count = 0; @@ -56,13 +57,13 @@ void find_keys(struct onak_dbctx *dbctx, count = dbctx->fetch_key_id(dbctx, keyid, &publickey, false); } else if (isfp) { - count = dbctx->fetch_key_fp(dbctx, fp, MAX_FINGERPRINT_LEN, + count = dbctx->fetch_key_fp(dbctx, fingerprint, &publickey, false); } else { count = dbctx->fetch_key_text(dbctx, search, &publickey); } if (publickey != NULL) { - key_index(dbctx, publickey, verbose, fingerprint, skshash, + key_index(dbctx, publickey, verbose, dispfp, skshash, false); free_publickey(publickey); } else if (count == 0) { @@ -162,18 +163,18 @@ int main(int argc, char *argv[]) char *search = NULL; char *end = NULL; uint64_t keyid = 0; - uint8_t fp[MAX_FINGERPRINT_LEN]; int i; bool ishex = false; bool isfp = false; bool update = false; bool binary = false; - bool fingerprint = false; + bool dispfp = false; bool skshash = false; int optchar; struct dump_ctx dumpstate; struct skshash hash; struct onak_dbctx *dbctx; + struct openpgp_fingerprint fingerprint; while ((optchar = getopt(argc, argv, "bc:fsuv")) != -1 ) { switch (optchar) { @@ -184,7 +185,7 @@ int main(int argc, char *argv[]) configfile = strdup(optarg); break; case 'f': - fingerprint = true; + dispfp = true; break; case 's': skshash = true; @@ -320,8 +321,10 @@ int main(int argc, char *argv[]) search = argv[optind+1]; if (search != NULL && strlen(search) == 42 && search[0] == '0' && search[1] == 'x') { + fingerprint.length = MAX_FINGERPRINT_LEN; for (i = 0; i < MAX_FINGERPRINT_LEN; i++) { - fp[i] = (hex2bin(search[2 + i * 2]) << 4) + + fingerprint.fp[i] = + (hex2bin(search[2 + i * 2]) << 4) + hex2bin(search[3 + i * 2]); } isfp = true; @@ -335,12 +338,12 @@ int main(int argc, char *argv[]) } dbctx = config.dbinit(false); if (!strcmp("index", argv[optind])) { - find_keys(dbctx, search, keyid, fp, ishex, isfp, - fingerprint, skshash, + find_keys(dbctx, search, keyid, &fingerprint, ishex, + isfp, dispfp, skshash, false, false); } else if (!strcmp("vindex", argv[optind])) { - find_keys(dbctx, search, keyid, fp, ishex, isfp, - fingerprint, skshash, + find_keys(dbctx, search, keyid, &fingerprint, ishex, + isfp, dispfp, skshash, false, true); } else if (!strcmp("getphoto", argv[optind])) { if (!ishex) { @@ -373,8 +376,8 @@ int main(int argc, char *argv[]) " You must supply a keyid / " "fingerprint."); } else if ((isfp && - dbctx->fetch_key_fp(dbctx, fp, - MAX_FINGERPRINT_LEN, + dbctx->fetch_key_fp(dbctx, + &fingerprint, &keys, false)) || (ishex && dbctx->fetch_key_id(dbctx, keyid, -- 2.39.5