summaryrefslogtreecommitdiffstats
path: root/kbx
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2004-02-02 18:09:35 +0100
committerWerner Koch <wk@gnupg.org>2004-02-02 18:09:35 +0100
commit5bda9a8e74753da5d7ee912c32a0137ebce2abd8 (patch)
tree17d077c8da8a9cba7a1d9919f8021424fcbd9ece /kbx
parentFix copyright line. (diff)
downloadgnupg2-5bda9a8e74753da5d7ee912c32a0137ebce2abd8.tar.xz
gnupg2-5bda9a8e74753da5d7ee912c32a0137ebce2abd8.zip
* keybox.h (keybox_flag_t): New.
* keybox-search.c (get_flag_from_image, keybox_get_flags): New. (_keybox_get_flag_location): New. * certchain.c (gpgsm_validate_chain): Mark revoked certs in the keybox. * keylist.c (list_cert_colon): New arg VALIDITY; use it to print a revoked flag. (list_internal_keys): Retrieve validity flag. (list_external_cb): Pass 0 as validity flag. * keydb.c (keydb_get_flags, keydb_set_flags): New. (keydb_set_cert_flags): New. (lock_all): Return a proper error code. (keydb_lock): New. (keydb_delete): Don't lock but check that it has been locked. (keydb_update_keyblock): Ditto. * delete.c (delete_one): Take a lock.
Diffstat (limited to 'kbx')
-rw-r--r--kbx/ChangeLog6
-rw-r--r--kbx/keybox-blob.c11
-rw-r--r--kbx/keybox-defs.h6
-rw-r--r--kbx/keybox-search.c116
-rw-r--r--kbx/keybox-update.c82
-rw-r--r--kbx/keybox.h14
6 files changed, 229 insertions, 6 deletions
diff --git a/kbx/ChangeLog b/kbx/ChangeLog
index 07a198200..a866e04f0 100644
--- a/kbx/ChangeLog
+++ b/kbx/ChangeLog
@@ -1,3 +1,9 @@
+2004-02-02 Werner Koch <wk@gnupg.org>
+
+ * keybox.h (keybox_flag_t): New.
+ * keybox-search.c (get_flag_from_image, keybox_get_flags): New.
+ (_keybox_get_flag_location): New.
+
2003-11-12 Werner Koch <wk@gnupg.org>
Adjusted for API changes in Libksba.
diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c
index 3d815321f..96595436c 100644
--- a/kbx/keybox-blob.c
+++ b/kbx/keybox-blob.c
@@ -39,7 +39,7 @@ The first record of a plain KBX file has a special format:
byte pgp_completes ditto.
byte pgp_cert_depth ditto.
-The OpenPGP and X.509 blob are verry similiar, things which are
+The OpenPGP and X.509 blob are very similiar, things which are
X.509 specific are noted like [X.509: xxx]
u32 length of this blob (including these 4 bytes)
@@ -57,7 +57,7 @@ X.509 specific are noted like [X.509: xxx]
b20 The keys fingerprint
(fingerprints are always 20 bytes, MD5 left padded with zeroes)
u32 offset to the n-th key's keyID (a keyID is always 8 byte)
- or 0 if not known which is the case opnly for X509.
+ or 0 if not known which is the case only for X509.
u16 special key flags
bit 0 =
u16 reserved
@@ -82,8 +82,11 @@ X.509 specific are noted like [X.509: xxx]
0x00000002 = bad signature
0x10000000 = valid and expires at some date in 1978.
0xffffffff = valid and does not expire
- u8 assigned ownertrust [X509: no used]
- u8 all_validity [X509: no used]
+ u8 assigned ownertrust [X509: not used]
+ u8 all_validity
+ OpenPGP: see ../g10/trustdb/TRUST_* [not yet used]
+ X509: Bit 4 set := key has been revoked. nOte that this value
+ matches TRUST_FLAG_REVOKED
u16 reserved
u32 recheck_after
u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h
index fa145f7e5..17431502f 100644
--- a/kbx/keybox-defs.h
+++ b/kbx/keybox-defs.h
@@ -116,6 +116,12 @@ off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob);
int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp);
int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp);
+/*-- keybox-search.c --*/
+gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer,
+ size_t length,
+ int what,
+ size_t *flag_off, size_t *flag_size);
+
/*-- keybox-dump.c --*/
int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp);
int _keybox_dump_file (const char *filename, FILE *outfp);
diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c
index b8add5abe..f23bfdada 100644
--- a/kbx/keybox-search.c
+++ b/kbx/keybox-search.c
@@ -1,5 +1,5 @@
/* keybox-search.c - Search operations
- * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -26,12 +26,15 @@
#include <errno.h>
#include "../jnlib/stringhelp.h" /* ascii_xxxx() */
+
#include "keybox-defs.h"
+
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
struct sn_array_s {
int snlen;
unsigned char *sn;
@@ -88,6 +91,97 @@ blob_get_blob_flags (KEYBOXBLOB blob)
}
+/* Return information on the flag WHAT within the blob BUFFER,LENGTH.
+ Return the offset and the length (in bytes) of the flag in
+ FLAGOFF,FLAG_SIZE. */
+gpg_err_code_t
+_keybox_get_flag_location (const unsigned char *buffer, size_t length,
+ int what, size_t *flag_off, size_t *flag_size)
+{
+ size_t pos;
+ size_t nkeys, keyinfolen;
+ size_t nuids, uidinfolen;
+ size_t nserial;
+ size_t nsigs, siginfolen;
+
+ switch (what)
+ {
+ case KEYBOX_FLAG_BLOB:
+ if (length < 8)
+ return GPG_ERR_INV_OBJ;
+ *flag_off = 6;
+ *flag_size = 2;
+ break;
+
+ case KEYBOX_FLAG_VALIDITY:
+ case KEYBOX_FLAG_OWNERTRUST:
+ if (length < 20)
+ return GPG_ERR_INV_OBJ;
+ /* Key info. */
+ nkeys = get16 (buffer + 16);
+ keyinfolen = get16 (buffer + 18 );
+ if (keyinfolen < 28)
+ return GPG_ERR_INV_OBJ;
+ pos = 20 + keyinfolen*nkeys;
+ if (pos+2 > length)
+ return GPG_ERR_INV_OBJ; /* Out of bounds. */
+ /* Serial number. */
+ nserial = get16 (buffer+pos);
+ pos += 2 + nserial;
+ if (pos+4 > length)
+ return GPG_ERR_INV_OBJ; /* Out of bounds. */
+ /* User IDs. */
+ nuids = get16 (buffer + pos); pos += 2;
+ uidinfolen = get16 (buffer + pos); pos += 2;
+ if (uidinfolen < 12 )
+ return GPG_ERR_INV_OBJ;
+ pos += uidinfolen*nuids;
+ if (pos+4 > length)
+ return GPG_ERR_INV_OBJ ; /* Out of bounds. */
+ /* Signature info. */
+ nsigs = get16 (buffer + pos); pos += 2;
+ siginfolen = get16 (buffer + pos); pos += 2;
+ if (siginfolen < 4 )
+ return GPG_ERR_INV_OBJ;
+ pos += siginfolen*nsigs;
+ if (pos+1+1+2+4+4+4+4 > length)
+ return GPG_ERR_INV_OBJ ; /* Out of bounds. */
+ *flag_size = 1;
+ *flag_off = pos;
+ if (what == KEYBOX_FLAG_VALIDITY)
+ ++*flag_off;
+ break;
+
+ default:
+ return GPG_ERR_INV_FLAG;
+ }
+ return 0;
+}
+
+/* Return one of the flags WHAT in VALUE from teh blob BUFFER of
+ LENGTH bytes. Return 0 on success or an raw error code. */
+static gpg_err_code_t
+get_flag_from_image (const unsigned char *buffer, size_t length,
+ int what, unsigned int *value)
+{
+ gpg_err_code_t ec;
+ size_t pos, size;
+
+ *value = 0;
+ ec = _keybox_get_flag_location (buffer, length, what, &pos, &size);
+ if (!ec)
+ switch (size)
+ {
+ case 1: *value = buffer[pos]; break;
+ case 2: *value = get16 (buffer + pos); break;
+ case 4: *value = get32 (buffer + pos); break;
+ default: ec = GPG_ERR_BUG; break;
+ }
+
+ return ec;
+}
+
+
static int
blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
{
@@ -811,3 +905,23 @@ keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert)
}
#endif /*KEYBOX_WITH_X509*/
+
+/* Return the flags named WHAT iat the address of VALUE. IDX is used
+ only for certain flags and should be 0 if not required. */
+int
+keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value)
+{
+ const unsigned char *buffer;
+ size_t length;
+ gpg_err_code_t ec;
+
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_VALUE);
+ if (!hd->found.blob)
+ return gpg_error (GPG_ERR_NOTHING_FOUND);
+
+ buffer = _keybox_get_blob_image (hd->found.blob, &length);
+ ec = get_flag_from_image (buffer, length, what, value);
+ return ec? gpg_error (ec):0;
+}
+
diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c
index ed9ca2bf7..47e53966a 100644
--- a/kbx/keybox-update.c
+++ b/kbx/keybox-update.c
@@ -384,6 +384,88 @@ keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
#endif /*KEYBOX_WITH_X509*/
+/* Note: We assume that the keybox has been locked before the current
+ search was executed. This is needed so that we can depend on the
+ offset information of the flags. */
+int
+keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
+{
+ off_t off;
+ const char *fname;
+ FILE *fp;
+ gpg_err_code_t ec;
+ size_t flag_pos, flag_size;
+ const unsigned char *buffer;
+ size_t length;
+
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_VALUE);
+ if (!hd->found.blob)
+ return gpg_error (GPG_ERR_NOTHING_FOUND);
+ if (!hd->kb)
+ return gpg_error (GPG_ERR_INV_HANDLE);
+ if (!hd->found.blob)
+ return gpg_error (GPG_ERR_NOTHING_FOUND);
+ 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);
+
+ buffer = _keybox_get_blob_image (hd->found.blob, &length);
+ ec = _keybox_get_flag_location (buffer, length, what, &flag_pos, &flag_size);
+ if (ec)
+ return gpg_error (ec);
+
+ off += flag_pos;
+
+ if (hd->fp)
+ {
+ fclose (hd->fp);
+ hd->fp = NULL;
+ }
+ fp = fopen (hd->kb->fname, "r+b");
+ if (!fp)
+ return gpg_error (gpg_err_code_from_errno (errno));
+
+ ec = 0;
+ if (fseeko (fp, off, SEEK_SET))
+ ec = gpg_error (gpg_err_code_from_errno (errno));
+ else
+ {
+ unsigned char tmp[4];
+
+ tmp[0] = value >> 24;
+ tmp[1] = value >> 16;
+ tmp[2] = value >> 8;
+ tmp[3] = value;
+
+ switch (flag_size)
+ {
+ case 1:
+ case 2:
+ case 4:
+ if (fwrite (tmp+4-flag_size, flag_size, 1, fp) != 1)
+ ec = gpg_err_code_from_errno (errno);
+ break;
+ default:
+ ec = GPG_ERR_BUG;
+ break;
+ }
+ }
+
+ if (fclose (fp))
+ {
+ if (!ec)
+ ec = gpg_err_code_from_errno (errno);
+ }
+
+ return gpg_error (ec);
+}
+
+
int
keybox_delete (KEYBOX_HANDLE hd)
diff --git a/kbx/keybox.h b/kbx/keybox.h
index 5a5ad2933..e4dc9d642 100644
--- a/kbx/keybox.h
+++ b/kbx/keybox.h
@@ -42,9 +42,19 @@ extern "C" {
# include <ksba.h>
#endif
+typedef struct keybox_handle *KEYBOX_HANDLE;
-typedef struct keybox_handle *KEYBOX_HANDLE;
+typedef enum
+ {
+ KEYBOX_FLAG_BLOB, /* The blob flags. */
+ KEYBOX_FLAG_VALIDITY, /* The validity of the entire key. */
+ KEYBOX_FLAG_OWNERTRUST, /* The assigned ownertrust. */
+ KEYBOX_FLAG_KEY, /* The key flags; requires a key index. */
+ KEYBOX_FLAG_UID, /* The user ID flags; requires an uid index. */
+ KEYBOX_FLAG_UID_VALIDITY/* The validity of a specific uid, requires
+ an uid index. */
+ } keyxox_flag_t;
/*-- keybox-init.c --*/
@@ -61,6 +71,7 @@ int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
#ifdef KEYBOX_WITH_X509
int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert);
#endif /*KEYBOX_WITH_X509*/
+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);
@@ -73,6 +84,7 @@ int keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
int keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
unsigned char *sha1_digest);
#endif /*KEYBOX_WITH_X509*/
+int keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value);
int keybox_delete (KEYBOX_HANDLE hd);