From 935edf88ab29b2f63afc2a0e3af1b33c92033ab7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 31 Oct 2014 12:15:34 +0100 Subject: [PATCH] kbx: Let keydb_search skip unwanted blobs. * kbx/keybox.h (keybox_blobtype_t): New. * kbx/keybox-defs.h (BLOBTYPE_*): Replace by KEYBOX_BLOBTYPE_*. * kbx/keybox-search.c (keybox_search): Add arg want_blobtype and skip non-matching blobs. * sm/keydb.c (keydb_search): Pass KEYBOX_BLOBTYPE_X509 to keybox_search. * g10/keydb.c (keydb_search): Pass KEYBOX_BLOBTYPE_PGP to keybox_search. -- Without this fix a listing of all keys would fail because the wrong blob type would be returned for the gpg or gpgsm. Signed-off-by: Werner Koch --- g10/keydb.c | 3 ++- kbx/keybox-blob.c | 10 +++++----- kbx/keybox-defs.h | 8 -------- kbx/keybox-dump.c | 34 +++++++++++++++++----------------- kbx/keybox-file.c | 2 +- kbx/keybox-search.c | 34 ++++++++++++++++++++-------------- kbx/keybox-update.c | 11 ++++++----- kbx/keybox.h | 9 +++++++++ sm/keydb.c | 1 + 9 files changed, 61 insertions(+), 51 deletions(-) diff --git a/g10/keydb.c b/g10/keydb.c index c192e06b4..a2cab18e2 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1448,7 +1448,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, break; case KEYDB_RESOURCE_TYPE_KEYBOX: rc = keybox_search (hd->active[hd->current].u.kb, desc, - ndesc, descindex, &hd->skipped_long_blobs); + ndesc, KEYBOX_BLOBTYPE_PGP, + descindex, &hd->skipped_long_blobs); break; } if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 35ce3e360..ef72148da 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -591,7 +591,7 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral) /* space where we write keyIDs and and other stuff so that the pointers can actually point to somewhere */ - if (blobtype == BLOBTYPE_PGP) + if (blobtype == KEYBOX_BLOBTYPE_PGP) { /* We need to store the keyids for all pgp v3 keys because those key IDs are not part of the fingerprint. While we are doing that, we @@ -611,7 +611,7 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral) } } - if (blobtype == BLOBTYPE_X509) + if (blobtype == KEYBOX_BLOBTYPE_X509) { /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to the utf-8 string represenation of them */ @@ -750,7 +750,7 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, init_membuf (&blob->bufbuf, 1024); blob->buf = &blob->bufbuf; - err = create_blob_header (blob, BLOBTYPE_PGP, as_ephemeral); + err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral); if (err) goto leave; err = pgp_create_blob_keyblock (blob, image, imagelen); @@ -937,7 +937,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, init_membuf (&blob->bufbuf, 1024); blob->buf = &blob->bufbuf; /* write out what we already have */ - rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral); + rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral); if (rc) goto leave; rc = x509_create_blob_cert (blob, cert); @@ -1031,7 +1031,7 @@ _keybox_get_blob_fileoffset (KEYBOXBLOB blob) void _keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp) { - if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER) + if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER) { u32 val = make_timestamp (); diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 415a3efff..8d795ab06 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -44,14 +44,6 @@ #include "keybox.h" -enum { - BLOBTYPE_EMPTY = 0, - BLOBTYPE_HEADER = 1, - BLOBTYPE_PGP = 2, - BLOBTYPE_X509 = 3 -}; - - typedef struct keyboxblob *KEYBOXBLOB; diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index dfa82007f..5315e8444 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -205,17 +205,17 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) type = buffer[4]; switch (type) { - case BLOBTYPE_EMPTY: + case KEYBOX_BLOBTYPE_EMPTY: fprintf (fp, "Type: Empty\n"); return 0; - case BLOBTYPE_HEADER: + case KEYBOX_BLOBTYPE_HEADER: fprintf (fp, "Type: Header\n"); return dump_header_blob (buffer, length, fp); - case BLOBTYPE_PGP: + case KEYBOX_BLOBTYPE_PGP: fprintf (fp, "Type: OpenPGP\n"); break; - case BLOBTYPE_X509: + case KEYBOX_BLOBTYPE_X509: fprintf (fp, "Type: X.509\n"); break; default: @@ -271,7 +271,7 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) fprintf (fp, "Key-Count: %lu\n", nkeys ); if (!nkeys) fprintf (fp, "[Error: no keys]\n"); - if (nkeys > 1 && type == BLOBTYPE_X509) + if (nkeys > 1 && type == KEYBOX_BLOBTYPE_X509) fprintf (fp, "[Error: only one key allowed for X509]\n"); keyinfolen = get16 (buffer + 18 ); @@ -321,13 +321,13 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) uidoff = get32( p ); uidlen = get32( p+4 ); - if (type == BLOBTYPE_X509 && !n) + if (type == KEYBOX_BLOBTYPE_X509 && !n) { fprintf (fp, "Issuer-Off: %lu\n", uidoff ); fprintf (fp, "Issuer-Len: %lu\n", uidlen ); fprintf (fp, "Issuer: \""); } - else if (type == BLOBTYPE_X509 && n == 1) + else if (type == KEYBOX_BLOBTYPE_X509 && n == 1) { fprintf (fp, "Subject-Off: %lu\n", uidoff ); fprintf (fp, "Subject-Len: %lu\n", uidlen ); @@ -342,12 +342,12 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) print_string (fp, buffer+uidoff, uidlen, '\"'); fputs ("\"\n", fp); uflags = get16 (p + 8); - if (type == BLOBTYPE_X509 && !n) + if (type == KEYBOX_BLOBTYPE_X509 && !n) { fprintf (fp, "Issuer-Flags: %04lX\n", uflags ); fprintf (fp, "Issuer-Validity: %d\n", p[10] ); } - else if (type == BLOBTYPE_X509 && n == 1) + else if (type == KEYBOX_BLOBTYPE_X509 && n == 1) { fprintf (fp, "Subject-Flags: %04lX\n", uflags ); fprintf (fp, "Subject-Validity: %d\n", p[10] ); @@ -452,12 +452,12 @@ hash_blob_rawdata (KEYBOXBLOB blob, unsigned char *digest) type = buffer[4]; switch (type) { - case BLOBTYPE_PGP: - case BLOBTYPE_X509: + case KEYBOX_BLOBTYPE_PGP: + case KEYBOX_BLOBTYPE_X509: break; - case BLOBTYPE_EMPTY: - case BLOBTYPE_HEADER: + case KEYBOX_BLOBTYPE_EMPTY: + case KEYBOX_BLOBTYPE_HEADER: default: memset (digest, 0, 20); return 0; @@ -519,16 +519,16 @@ update_stats (KEYBOXBLOB blob, struct file_stats_s *s) type = buffer[4]; switch (type) { - case BLOBTYPE_EMPTY: + case KEYBOX_BLOBTYPE_EMPTY: s->empty_blob_count++; return 0; - case BLOBTYPE_HEADER: + case KEYBOX_BLOBTYPE_HEADER: s->header_blob_count++; return 0; - case BLOBTYPE_PGP: + case KEYBOX_BLOBTYPE_PGP: s->pgp_blob_count++; break; - case BLOBTYPE_X509: + case KEYBOX_BLOBTYPE_X509: s->x509_blob_count++; break; default: diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c index 1ed51696e..98808ed4f 100644 --- a/kbx/keybox-file.c +++ b/kbx/keybox-file.c @@ -154,7 +154,7 @@ _keybox_write_header_blob (FILE *fp, int for_openpgp) /* Length of this blob. */ image[3] = 32; - image[4] = BLOBTYPE_HEADER; + image[4] = KEYBOX_BLOBTYPE_HEADER; image[5] = 1; /* Version */ if (for_openpgp) image[7] = 0x02; /* OpenPGP data may be available. */ diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index bf47042a3..10a71c4bd 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -573,7 +573,7 @@ static inline int has_keygrip (KEYBOXBLOB blob, const unsigned char *grip) { #ifdef KEYBOX_WITH_X509 - if (blob_get_type (blob) == BLOBTYPE_X509) + if (blob_get_type (blob) == KEYBOX_BLOBTYPE_X509) return blob_x509_has_grip (blob, grip); #endif return 0; @@ -587,7 +587,7 @@ has_issuer (KEYBOXBLOB blob, const char *name) return_val_if_fail (name, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) return 0; namelen = strlen (name); @@ -603,7 +603,7 @@ has_issuer_sn (KEYBOXBLOB blob, const char *name, return_val_if_fail (name, 0); return_val_if_fail (sn, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) return 0; namelen = strlen (name); @@ -617,7 +617,7 @@ has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) { return_val_if_fail (sn, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) return 0; return blob_cmp_sn (blob, sn, snlen); } @@ -629,7 +629,7 @@ has_subject (KEYBOXBLOB blob, const char *name) return_val_if_fail (name, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) return 0; namelen = strlen (name); @@ -646,12 +646,12 @@ has_username (KEYBOXBLOB blob, const char *name, int substr) return_val_if_fail (name, 0); btype = blob_get_type (blob); - if (btype != BLOBTYPE_PGP && btype != BLOBTYPE_X509) + if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509) return 0; namelen = strlen (name); return blob_cmp_name (blob, -1 /* all subject/user names */, name, - namelen, substr, (btype == BLOBTYPE_X509)); + namelen, substr, (btype == KEYBOX_BLOBTYPE_X509)); } @@ -664,16 +664,17 @@ has_mail (KEYBOXBLOB blob, const char *name, int substr) return_val_if_fail (name, 0); btype = blob_get_type (blob); - if (btype != BLOBTYPE_PGP && btype != BLOBTYPE_X509) + if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509) return 0; - if (btype == BLOBTYPE_PGP && *name == '<') + if (btype == KEYBOX_BLOBTYPE_PGP && *name == '<') name++; /* Hack to remove the leading '<' for gpg. */ namelen = strlen (name); if (namelen && name[namelen-1] == '>') namelen--; - return blob_cmp_mail (blob, name, namelen, substr, (btype == BLOBTYPE_X509)); + return blob_cmp_mail (blob, name, namelen, substr, + (btype == KEYBOX_BLOBTYPE_X509)); } @@ -719,10 +720,12 @@ keybox_search_reset (KEYBOX_HANDLE hd) /* Note: When in ephemeral mode the search function does visit all blobs but in standard mode, blobs flagged as ephemeral are ignored. + If WANT_BLOBTYPE is not 0 only blobs of this type are considered. The value at R_SKIPPED is updated by the number of skipped long records (counts PGP and X.509). */ int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, + keybox_blobtype_t want_blobtype, size_t *r_descindex, unsigned long *r_skipped) { int rc; @@ -851,6 +854,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, for (;;) { unsigned int blobflags; + int blobtype; _keybox_release_blob (blob); blob = NULL; rc = _keybox_read_blob (&blob, hd->fp); @@ -864,9 +868,11 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, if (rc) break; - if (blob_get_type (blob) == BLOBTYPE_HEADER) + blobtype = blob_get_type (blob); + if (blobtype == KEYBOX_BLOBTYPE_HEADER) + continue; + if (want_blobtype && blobtype != want_blobtype) continue; - blobflags = blob_get_blob_flags (blob); if (!hd->ephemeral && (blobflags & 2)) @@ -1025,7 +1031,7 @@ keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, if (!hd->found.blob) return gpg_error (GPG_ERR_NOTHING_FOUND); - if (blob_get_type (hd->found.blob) != BLOBTYPE_PGP) + if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP) return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); buffer = _keybox_get_blob_image (hd->found.blob, &length); @@ -1077,7 +1083,7 @@ keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert) if (!hd->found.blob) return gpg_error (GPG_ERR_NOTHING_FOUND); - if (blob_get_type (hd->found.blob) != BLOBTYPE_X509) + if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_X509) return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); buffer = _keybox_get_blob_image (hd->found.blob, &length); diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index 693b7324a..11861ac14 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -282,7 +282,8 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, failsafe the blob type.) */ while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 ) { - if (first_record && for_openpgp && buffer[4] == BLOBTYPE_HEADER) + if (first_record && for_openpgp + && buffer[4] == KEYBOX_BLOBTYPE_HEADER) { first_record = 0; buffer[7] |= 0x02; /* OpenPGP data may be available. */ @@ -446,7 +447,7 @@ keybox_update_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) return gpg_error (GPG_ERR_INV_VALUE); if (!hd->found.blob) return gpg_error (GPG_ERR_NOTHING_FOUND); - if (blob_get_type (hd->found.blob) != BLOBTYPE_PGP) + if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP) return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); fname = hd->kb->fname; if (!fname) @@ -704,7 +705,7 @@ keybox_compress (KEYBOX_HANDLE hd) size_t length; buffer = _keybox_get_blob_image (blob, &length); - if (length > 4 && buffer[4] == BLOBTYPE_HEADER) + if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER) { u32 last_maint = ((buffer[20] << 24) | (buffer[20+1] << 16) | (buffer[20+2] << 8) | (buffer[20+3])); @@ -751,7 +752,7 @@ keybox_compress (KEYBOX_HANDLE hd) if (first_blob) { first_blob = 0; - if (length > 4 && buffer[4] == BLOBTYPE_HEADER) + if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER) { /* Write out the blob with an updated maintenance time stamp and if needed (ie. used by gpg) set the openpgp @@ -769,7 +770,7 @@ keybox_compress (KEYBOX_HANDLE hd) break; any_changes = 1; } - else if (length > 4 && buffer[4] == BLOBTYPE_HEADER) + else if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER) { /* Oops: There is another header record - remove it. */ any_changes = 1; diff --git a/kbx/keybox.h b/kbx/keybox.h index b44f1b2ba..386fff1e6 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -56,6 +56,14 @@ typedef enum #define KEYBOX_FLAG_BLOB_SECRET 1 #define KEYBOX_FLAG_BLOB_EPHEMERAL 2 +/* The keybox blob types. */ +typedef enum + { + KEYBOX_BLOBTYPE_EMPTY = 0, + KEYBOX_BLOBTYPE_HEADER = 1, + KEYBOX_BLOBTYPE_PGP = 2, + KEYBOX_BLOBTYPE_X509 = 3 + } keybox_blobtype_t; /*-- keybox-init.c --*/ @@ -87,6 +95,7 @@ int keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value); int keybox_search_reset (KEYBOX_HANDLE hd); int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, + keybox_blobtype_t want_blobtype, size_t *r_descindex, unsigned long *r_skipped); diff --git a/sm/keydb.c b/sm/keydb.c index 83e573f28..974625dbc 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -972,6 +972,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) break; case KEYDB_RESOURCE_TYPE_KEYBOX: rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc, + KEYBOX_BLOBTYPE_X509, NULL, &skipped); break; }