mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
kbx: Implement update operation for OpenPGP keyblocks.
* kbx/keybox-update.c (keybox_update_keyblock): Implement. * kbx/keybox-search.c (get_blob_flags): Move to ... * kbx/keybox-defs.h (blob_get_type): here. * kbx/keybox-file.c (_keybox_read_blob2): Fix calling without R_BLOB. * g10/keydb.c (build_keyblock_image): Allow calling without R_SIGSTATUS. (keydb_update_keyblock): Implement for keybox. * kbx/keybox-dump.c (_keybox_dump_blob): Fix printing of the unhashed size. Print "does not expire" also on 64 bit platforms. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
a0102a548d
commit
5499942571
68
g10/keydb.c
68
g10/keydb.c
@ -1,6 +1,7 @@
|
||||
/* keydb.c - key database dispatcher
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
|
||||
* 2008, 2009, 2011, 2013 Free Software Foundation, Inc.
|
||||
* Coyrright (C) 2013 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -896,18 +897,24 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
|
||||
u32 *sigstatus;
|
||||
|
||||
*r_iobuf = NULL;
|
||||
*r_sigstatus = NULL;
|
||||
if (r_sigstatus)
|
||||
*r_sigstatus = NULL;
|
||||
|
||||
/* Allocate a vector for the signature cache. This is an array of
|
||||
u32 values with the first value giving the number of elements to
|
||||
follow and each element descriping the cache status of the
|
||||
signature. */
|
||||
for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));)
|
||||
if (node->pkt->pkttype == PKT_SIGNATURE)
|
||||
n_sigs++;
|
||||
sigstatus = xtrycalloc (1+n_sigs, sizeof *sigstatus);
|
||||
if (!sigstatus)
|
||||
return gpg_error_from_syserror ();
|
||||
if (r_sigstatus)
|
||||
{
|
||||
for (kbctx=NULL, n_sigs=0; (node = walk_kbnode (keyblock, &kbctx, 0));)
|
||||
if (node->pkt->pkttype == PKT_SIGNATURE)
|
||||
n_sigs++;
|
||||
sigstatus = xtrycalloc (1+n_sigs, sizeof *sigstatus);
|
||||
if (!sigstatus)
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
else
|
||||
sigstatus = NULL;
|
||||
|
||||
iobuf = iobuf_temp ();
|
||||
for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));)
|
||||
@ -940,8 +947,8 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
|
||||
n_sigs++;
|
||||
/* Fixme: Detect tye "missing key" status. */
|
||||
if (sig->flags.checked)
|
||||
/* Fixme: Detect the "missing key" status. */
|
||||
if (sig->flags.checked && sigstatus)
|
||||
{
|
||||
if (sig->flags.valid)
|
||||
{
|
||||
@ -957,10 +964,12 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
sigstatus[0] = n_sigs;
|
||||
if (sigstatus)
|
||||
sigstatus[0] = n_sigs;
|
||||
|
||||
*r_iobuf = iobuf;
|
||||
*r_sigstatus = sigstatus;
|
||||
if (r_sigstatus)
|
||||
*r_sigstatus = sigstatus;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -971,7 +980,7 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
|
||||
gpg_error_t
|
||||
keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
|
||||
{
|
||||
gpg_error_t rc;
|
||||
gpg_error_t err;
|
||||
|
||||
if (!hd)
|
||||
return gpg_error (GPG_ERR_INV_ARG);
|
||||
@ -984,28 +993,36 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
|
||||
if (opt.dry_run)
|
||||
return 0;
|
||||
|
||||
rc = lock_all (hd);
|
||||
if (rc)
|
||||
return rc;
|
||||
err = lock_all (hd);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
switch (hd->active[hd->found].type)
|
||||
{
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
rc = gpg_error (GPG_ERR_GENERAL); /* oops */
|
||||
err = gpg_error (GPG_ERR_GENERAL); /* oops */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
|
||||
err = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
{
|
||||
iobuf_t iobuf;
|
||||
|
||||
err = build_keyblock_image (kb, &iobuf, NULL);
|
||||
if (!err)
|
||||
{
|
||||
err = keybox_update_keyblock (hd->active[hd->found].u.kb,
|
||||
iobuf_get_temp_buffer (iobuf),
|
||||
iobuf_get_temp_length (iobuf));
|
||||
iobuf_close (iobuf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
/* case KEYDB_RESOURCE_TYPE_KEYRING: */
|
||||
/* rc = build_keyblock (kb, &image, &imagelen); */
|
||||
/* if (!rc) */
|
||||
/* rc = keybox_update_keyblock (hd->active[hd->found].u.kb, */
|
||||
/* image, imagelen); */
|
||||
/* break; */
|
||||
}
|
||||
|
||||
unlock_all (hd);
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -1197,6 +1214,9 @@ keydb_rebuild_caches (int noisy)
|
||||
log_error (_("failed to rebuild keyring cache: %s\n"),
|
||||
g10_errstr (rc));
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
/* N/A. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,8 +120,9 @@
|
||||
- bN Arbitrary space for example used to store data which is not
|
||||
part of the keyblock or certificate. For example the v3 key
|
||||
IDs go here.
|
||||
- bN Space for the keyblock or certifciate.
|
||||
- bN RFU
|
||||
- bN Space for the keyblock or certificate.
|
||||
- bN RFU. This is the remaining space after keyblock and before
|
||||
the checksum. Is is not covered by the checksum.
|
||||
- b20 SHA-1 checksum (useful for KS syncronisation?)
|
||||
Note, that KBX versions before GnuPG 2.1 used an MD5
|
||||
checksum. However it was only created but never checked.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* keybox-defs.h - interal Keybox defintions
|
||||
/* keybox-defs.h - internal Keybox definitions
|
||||
* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
@ -193,6 +193,20 @@ gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer,
|
||||
int what,
|
||||
size_t *flag_off, size_t *flag_size);
|
||||
|
||||
static inline int
|
||||
blob_get_type (KEYBOXBLOB blob)
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
size_t length;
|
||||
|
||||
buffer = _keybox_get_blob_image (blob, &length);
|
||||
if (length < 32)
|
||||
return -1; /* blob too short */
|
||||
|
||||
return buffer[4];
|
||||
}
|
||||
|
||||
|
||||
/*-- keybox-dump.c --*/
|
||||
int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp);
|
||||
int _keybox_dump_file (const char *filename, int stats_only, FILE *outfp);
|
||||
|
@ -245,7 +245,7 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
|
||||
|| rawdata_len + 4 > length
|
||||
|| rawdata_off+rawdata_len + 4 > length)
|
||||
fprintf (fp, "[Error: raw data larger than blob]\n");
|
||||
unhashed = get32 (buffer + rawdata_off + rawdata_len);
|
||||
unhashed = length - rawdata_off - rawdata_len;
|
||||
fprintf (fp, "Unhashed: %lu\n", unhashed);
|
||||
|
||||
nkeys = get16 (buffer + 16);
|
||||
@ -378,7 +378,7 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
|
||||
fputs ("[bad signature]", fp);
|
||||
else if (sflags < 0x10000000)
|
||||
fprintf (fp, "[bad flag %0lx]", sflags);
|
||||
else if (sflags == 0xffffffff)
|
||||
else if (sflags == (ulong)(-1))
|
||||
fputs ("[good - does not expire]", fp );
|
||||
else
|
||||
fprintf (fp, "[good - expires at %lu]", sflags);
|
||||
|
@ -43,7 +43,7 @@ ftello (FILE *stream)
|
||||
|
||||
|
||||
/* Read a block at the current postion and return it in r_blob.
|
||||
r_blob may be NULL to simply skip the current block */
|
||||
r_blob may be NULL to simply skip the current block. */
|
||||
int
|
||||
_keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
|
||||
{
|
||||
@ -55,7 +55,8 @@ _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
|
||||
|
||||
*skipped_deleted = 0;
|
||||
again:
|
||||
*r_blob = NULL;
|
||||
if (r_blob)
|
||||
*r_blob = NULL;
|
||||
off = ftello (fp);
|
||||
if (off == (off_t)-1)
|
||||
return gpg_error_from_syserror ();
|
||||
|
@ -65,19 +65,6 @@ get16 (const byte *buffer)
|
||||
|
||||
|
||||
|
||||
static inline int
|
||||
blob_get_type (KEYBOXBLOB blob)
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
size_t length;
|
||||
|
||||
buffer = _keybox_get_blob_image (blob, &length);
|
||||
if (length < 32)
|
||||
return -1; /* blob too short */
|
||||
|
||||
return buffer[4];
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
blob_get_blob_flags (KEYBOXBLOB blob)
|
||||
{
|
||||
|
@ -425,10 +425,47 @@ keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen,
|
||||
gpg_error_t
|
||||
keybox_update_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen)
|
||||
{
|
||||
(void)hd;
|
||||
(void)image;
|
||||
(void)imagelen;
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
gpg_error_t err;
|
||||
const char *fname;
|
||||
off_t off;
|
||||
KEYBOXBLOB blob;
|
||||
size_t nparsed;
|
||||
struct _keybox_openpgp_info info;
|
||||
|
||||
if (!hd || !image || !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)
|
||||
return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
|
||||
fname = hd->kb->fname;
|
||||
if (!fname)
|
||||
return gpg_error (GPG_ERR_INV_HANDLE);
|
||||
|
||||
off = _keybox_get_blob_fileoffset (hd->found.blob);
|
||||
if (off == (off_t)-1)
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
|
||||
/* Close this the file so that we do no mess up the position for a
|
||||
next search. */
|
||||
_keybox_close_file (hd);
|
||||
|
||||
/* Build a new blob. */
|
||||
err = _keybox_parse_openpgp (image, imagelen, &nparsed, &info);
|
||||
if (err)
|
||||
return err;
|
||||
assert (nparsed <= imagelen);
|
||||
err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen,
|
||||
NULL, hd->ephemeral);
|
||||
_keybox_destroy_openpgp_info (&info);
|
||||
|
||||
/* Update the keyblock. */
|
||||
if (!err)
|
||||
{
|
||||
err = blob_filecopy (FILECOPY_UPDATE, fname, blob, hd->secret, off);
|
||||
_keybox_release_blob (blob);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user