diff options
author | Werner Koch <wk@gnupg.org> | 2004-02-02 18:09:35 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2004-02-02 18:09:35 +0100 |
commit | 5bda9a8e74753da5d7ee912c32a0137ebce2abd8 (patch) | |
tree | 17d077c8da8a9cba7a1d9919f8021424fcbd9ece /kbx | |
parent | Fix copyright line. (diff) | |
download | gnupg2-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/ChangeLog | 6 | ||||
-rw-r--r-- | kbx/keybox-blob.c | 11 | ||||
-rw-r--r-- | kbx/keybox-defs.h | 6 | ||||
-rw-r--r-- | kbx/keybox-search.c | 116 | ||||
-rw-r--r-- | kbx/keybox-update.c | 82 | ||||
-rw-r--r-- | kbx/keybox.h | 14 |
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); |