mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
* 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.
This commit is contained in:
parent
bdae155c7b
commit
5bda9a8e74
@ -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>
|
2003-11-12 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
Adjusted for API changes in Libksba.
|
Adjusted for API changes in Libksba.
|
||||||
|
@ -39,7 +39,7 @@ The first record of a plain KBX file has a special format:
|
|||||||
byte pgp_completes ditto.
|
byte pgp_completes ditto.
|
||||||
byte pgp_cert_depth 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]
|
X.509 specific are noted like [X.509: xxx]
|
||||||
|
|
||||||
u32 length of this blob (including these 4 bytes)
|
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
|
b20 The keys fingerprint
|
||||||
(fingerprints are always 20 bytes, MD5 left padded with zeroes)
|
(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)
|
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
|
u16 special key flags
|
||||||
bit 0 =
|
bit 0 =
|
||||||
u16 reserved
|
u16 reserved
|
||||||
@ -82,8 +82,11 @@ X.509 specific are noted like [X.509: xxx]
|
|||||||
0x00000002 = bad signature
|
0x00000002 = bad signature
|
||||||
0x10000000 = valid and expires at some date in 1978.
|
0x10000000 = valid and expires at some date in 1978.
|
||||||
0xffffffff = valid and does not expire
|
0xffffffff = valid and does not expire
|
||||||
u8 assigned ownertrust [X509: no used]
|
u8 assigned ownertrust [X509: not used]
|
||||||
u8 all_validity [X509: no 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
|
u16 reserved
|
||||||
u32 recheck_after
|
u32 recheck_after
|
||||||
u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
|
u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
|
||||||
|
@ -116,6 +116,12 @@ off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob);
|
|||||||
int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp);
|
int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp);
|
||||||
int _keybox_write_blob (KEYBOXBLOB 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 --*/
|
/*-- keybox-dump.c --*/
|
||||||
int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp);
|
int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp);
|
||||||
int _keybox_dump_file (const char *filename, FILE *outfp);
|
int _keybox_dump_file (const char *filename, FILE *outfp);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* keybox-search.c - Search operations
|
/* 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.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -26,12 +26,15 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "../jnlib/stringhelp.h" /* ascii_xxxx() */
|
#include "../jnlib/stringhelp.h" /* ascii_xxxx() */
|
||||||
|
|
||||||
#include "keybox-defs.h"
|
#include "keybox-defs.h"
|
||||||
|
|
||||||
|
|
||||||
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
|
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
|
||||||
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
|
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
|
||||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
||||||
|
|
||||||
|
|
||||||
struct sn_array_s {
|
struct sn_array_s {
|
||||||
int snlen;
|
int snlen;
|
||||||
unsigned char *sn;
|
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
|
static int
|
||||||
blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
|
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*/
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -384,6 +384,88 @@ keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
|
|||||||
|
|
||||||
#endif /*KEYBOX_WITH_X509*/
|
#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
|
int
|
||||||
keybox_delete (KEYBOX_HANDLE hd)
|
keybox_delete (KEYBOX_HANDLE hd)
|
||||||
|
16
kbx/keybox.h
16
kbx/keybox.h
@ -42,11 +42,21 @@ extern "C" {
|
|||||||
# include <ksba.h>
|
# include <ksba.h>
|
||||||
#endif
|
#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 --*/
|
/*-- keybox-init.c --*/
|
||||||
void *keybox_register_file (const char *fname, int secret);
|
void *keybox_register_file (const char *fname, int secret);
|
||||||
int keybox_is_writable (void *token);
|
int keybox_is_writable (void *token);
|
||||||
@ -61,6 +71,7 @@ int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
|
|||||||
#ifdef KEYBOX_WITH_X509
|
#ifdef KEYBOX_WITH_X509
|
||||||
int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert);
|
int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert);
|
||||||
#endif /*KEYBOX_WITH_X509*/
|
#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_reset (KEYBOX_HANDLE hd);
|
||||||
int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc);
|
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,
|
int keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert,
|
||||||
unsigned char *sha1_digest);
|
unsigned char *sha1_digest);
|
||||||
#endif /*KEYBOX_WITH_X509*/
|
#endif /*KEYBOX_WITH_X509*/
|
||||||
|
int keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value);
|
||||||
|
|
||||||
int keybox_delete (KEYBOX_HANDLE hd);
|
int keybox_delete (KEYBOX_HANDLE hd);
|
||||||
|
|
||||||
|
17
sm/ChangeLog
17
sm/ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
2004-02-02 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2004-01-30 Werner Koch <wk@gnupg.org>
|
2004-01-30 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* certchain.c (check_cert_policy): Fixed read error checking.
|
* certchain.c (check_cert_policy): Fixed read error checking.
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <ksba.h>
|
#include <ksba.h>
|
||||||
|
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -535,6 +536,11 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
case GPG_ERR_CERT_REVOKED:
|
case GPG_ERR_CERT_REVOKED:
|
||||||
log_error (_("the certificate has been revoked\n"));
|
log_error (_("the certificate has been revoked\n"));
|
||||||
any_revoked = 1;
|
any_revoked = 1;
|
||||||
|
/* Store that in the keybox so that key listings are
|
||||||
|
able to return the revoked flag. We don't care
|
||||||
|
about error, though. */
|
||||||
|
keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0,
|
||||||
|
VALIDITY_REVOKED);
|
||||||
break;
|
break;
|
||||||
case GPG_ERR_NO_CRL_KNOWN:
|
case GPG_ERR_NO_CRL_KNOWN:
|
||||||
log_error (_("no CRL found for certificate\n"));
|
log_error (_("no CRL found for certificate\n"));
|
||||||
|
@ -105,7 +105,14 @@ delete_one (CTRL ctrl, const char *username)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need to search again to get back to the right position. */
|
/* We need to search again to get back to the right position. */
|
||||||
|
rc = keydb_lock (kh);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error (_("error locking keybox: %s\n"), gpg_strerror (rc));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
keydb_search_reset (kh);
|
keydb_search_reset (kh);
|
||||||
|
160
sm/keydb.c
160
sm/keydb.c
@ -1,5 +1,5 @@
|
|||||||
/* keydb.c - key database dispatcher
|
/* keydb.c - key database dispatcher
|
||||||
* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -373,6 +373,21 @@ keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If the keyring has not yet been locked, lock it now. This
|
||||||
|
operation is required before any update opeations; it is optionaly
|
||||||
|
for an insert operation. The lock is released with
|
||||||
|
keydb_released. */
|
||||||
|
gpg_error_t
|
||||||
|
keydb_lock (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
if (!hd)
|
||||||
|
return gpg_error (GPG_ERR_INV_HANDLE);
|
||||||
|
if (hd->locked)
|
||||||
|
return 0; /* Already locked. */
|
||||||
|
return lock_all (hd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lock_all (KEYDB_HANDLE hd)
|
lock_all (KEYDB_HANDLE hd)
|
||||||
@ -380,8 +395,8 @@ lock_all (KEYDB_HANDLE hd)
|
|||||||
int i, rc = 0;
|
int i, rc = 0;
|
||||||
|
|
||||||
/* Fixme: This locking scheme may lead to deadlock if the resources
|
/* Fixme: This locking scheme may lead to deadlock if the resources
|
||||||
are not added in the same sequence by all processes. We are
|
are not added in the same order all processes. We are
|
||||||
cuurently only allowing one resource so it is not a problem. */
|
currently only allowing one resource so it is not a problem. */
|
||||||
for (i=0; i < hd->used; i++)
|
for (i=0; i < hd->used; i++)
|
||||||
{
|
{
|
||||||
switch (hd->active[i].type)
|
switch (hd->active[i].type)
|
||||||
@ -416,7 +431,10 @@ lock_all (KEYDB_HANDLE hd)
|
|||||||
else
|
else
|
||||||
hd->locked = 1;
|
hd->locked = 1;
|
||||||
|
|
||||||
return rc;
|
/* make_dotlock () does not yet guarantee that errno is set, thus
|
||||||
|
we can't rely on the error reason and will simply use
|
||||||
|
EACCES. */
|
||||||
|
return rc? gpg_error (GPG_ERR_EACCES) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -490,9 +508,8 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
|||||||
if( opt.dry_run )
|
if( opt.dry_run )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = lock_all (hd);
|
if (!hd->locked)
|
||||||
if (rc)
|
return gpg_error (GPG_ERR_CONFLICT);
|
||||||
return rc;
|
|
||||||
|
|
||||||
switch (hd->active[hd->found].type) {
|
switch (hd->active[hd->found].type) {
|
||||||
case KEYDB_RESOURCE_TYPE_NONE:
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
@ -552,7 +569,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return the last found keybox. Caller must free it. The returned
|
Return the last found object. Caller must free it. The returned
|
||||||
keyblock has the kbode flag bit 0 set for the node with the public
|
keyblock has the kbode flag bit 0 set for the node with the public
|
||||||
key used to locate the keyblock or flag bit 1 set for the user ID
|
key used to locate the keyblock or flag bit 1 set for the user ID
|
||||||
node. */
|
node. */
|
||||||
@ -580,6 +597,67 @@ keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return a flag of the last found object. WHICH is the flag requested;
|
||||||
|
it should be one of the KEYBOX_FLAG_ values. If the operation is
|
||||||
|
successful, the flag value will be stored at the address given by
|
||||||
|
VALUE. Return 0 on success or an error code. */
|
||||||
|
gpg_error_t
|
||||||
|
keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
if ( hd->found < 0 || hd->found >= hd->used)
|
||||||
|
return gpg_error (GPG_ERR_NOTHING_FOUND);
|
||||||
|
|
||||||
|
switch (hd->active[hd->found].type)
|
||||||
|
{
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
err = gpg_error (GPG_ERR_GENERAL); /* oops */
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||||
|
err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a flag of the last found object. WHICH is the flag to be set; it
|
||||||
|
should be one of the KEYBOX_FLAG_ values. If the operation is
|
||||||
|
successful, the flag value will be stored in the keybox. Note,
|
||||||
|
that some flag values can't be updated and thus may retrun an
|
||||||
|
error, some other flag values may be masked out before an update.
|
||||||
|
Returns 0 on success or an error code. */
|
||||||
|
gpg_error_t
|
||||||
|
keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
if ( hd->found < 0 || hd->found >= hd->used)
|
||||||
|
return gpg_error (GPG_ERR_NOTHING_FOUND);
|
||||||
|
|
||||||
|
if (!hd->locked)
|
||||||
|
return gpg_error (GPG_ERR_CONFLICT);
|
||||||
|
|
||||||
|
switch (hd->active[hd->found].type)
|
||||||
|
{
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
err = gpg_error (GPG_ERR_GENERAL); /* oops */
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||||
|
err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a new Certificate into one of the resources.
|
* Insert a new Certificate into one of the resources.
|
||||||
*/
|
*/
|
||||||
@ -679,9 +757,8 @@ keydb_delete (KEYDB_HANDLE hd)
|
|||||||
if( opt.dry_run )
|
if( opt.dry_run )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = lock_all (hd);
|
if (!hd->locked)
|
||||||
if (rc)
|
return gpg_error (GPG_ERR_CONFLICT); /* ...NOT_LOCKED would be better. */
|
||||||
return rc;
|
|
||||||
|
|
||||||
switch (hd->active[hd->found].type)
|
switch (hd->active[hd->found].type)
|
||||||
{
|
{
|
||||||
@ -1279,4 +1356,65 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is basically keydb_set_flags but it implements a complete
|
||||||
|
transaction by locating teh certificate in the DB and updating the
|
||||||
|
flags. */
|
||||||
|
gpg_error_t
|
||||||
|
keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
|
||||||
|
{
|
||||||
|
KEYDB_HANDLE kh;
|
||||||
|
gpg_error_t err;
|
||||||
|
unsigned char fpr[20];
|
||||||
|
unsigned int old_value;
|
||||||
|
|
||||||
|
if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
|
||||||
|
{
|
||||||
|
log_error (_("failed to get the fingerprint\n"));
|
||||||
|
return gpg_error (GPG_ERR_GENERAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
kh = keydb_new (0);
|
||||||
|
if (!kh)
|
||||||
|
{
|
||||||
|
log_error (_("failed to allocate keyDB handle\n"));
|
||||||
|
return gpg_error (GPG_ERR_ENOMEM);;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = keydb_lock (kh);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
|
||||||
|
keydb_release (kh);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = keydb_search_fpr (kh, fpr);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error (_("problem re-searching certificate: %s\n"),
|
||||||
|
gpg_strerror (err));
|
||||||
|
keydb_release (kh);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = keydb_get_flags (kh, which, idx, &old_value);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
|
||||||
|
keydb_release (kh);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (value != old_value)
|
||||||
|
{
|
||||||
|
err = keydb_set_flags (kh, which, idx, value);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error (_("error storing flags: %s\n"), gpg_strerror (err));
|
||||||
|
keydb_release (kh);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keydb_release (kh);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
10
sm/keydb.h
10
sm/keydb.h
@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
typedef struct keydb_handle *KEYDB_HANDLE;
|
typedef struct keydb_handle *KEYDB_HANDLE;
|
||||||
|
|
||||||
|
/* Flag value used with KEYBOX_FLAG_VALIDITY. */
|
||||||
|
#define VALIDITY_REVOKED (1<<5)
|
||||||
|
|
||||||
|
|
||||||
/*-- keydb.c --*/
|
/*-- keydb.c --*/
|
||||||
int keydb_add_resource (const char *url, int force, int secret);
|
int keydb_add_resource (const char *url, int force, int secret);
|
||||||
@ -34,6 +37,7 @@ KEYDB_HANDLE keydb_new (int secret);
|
|||||||
void keydb_release (KEYDB_HANDLE hd);
|
void keydb_release (KEYDB_HANDLE hd);
|
||||||
int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes);
|
int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes);
|
||||||
const char *keydb_get_resource_name (KEYDB_HANDLE hd);
|
const char *keydb_get_resource_name (KEYDB_HANDLE hd);
|
||||||
|
gpg_error_t keydb_lock (KEYDB_HANDLE hd);
|
||||||
|
|
||||||
#if 0 /* pgp stuff */
|
#if 0 /* pgp stuff */
|
||||||
int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
|
int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
|
||||||
@ -41,6 +45,10 @@ int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb);
|
|||||||
int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
|
int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
gpg_error_t keydb_get_flags (KEYDB_HANDLE hd, int which, int idx,
|
||||||
|
unsigned int *value);
|
||||||
|
gpg_error_t keydb_set_flags (KEYDB_HANDLE hd, int which, int idx,
|
||||||
|
unsigned int value);
|
||||||
int keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert);
|
int keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert);
|
||||||
int keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert);
|
int keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert);
|
||||||
int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert);
|
int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert);
|
||||||
@ -64,6 +72,8 @@ int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer);
|
|||||||
int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc);
|
int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc);
|
||||||
|
|
||||||
int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed);
|
int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed);
|
||||||
|
gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int which, int idx,
|
||||||
|
unsigned int value);
|
||||||
|
|
||||||
|
|
||||||
#endif /*GNUPG_KEYDB_H*/
|
#endif /*GNUPG_KEYDB_H*/
|
||||||
|
30
sm/keylist.c
30
sm/keylist.c
@ -33,6 +33,7 @@
|
|||||||
#include <ksba.h>
|
#include <ksba.h>
|
||||||
|
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
struct list_external_parm_s {
|
struct list_external_parm_s {
|
||||||
@ -145,7 +146,8 @@ email_kludge (const char *name)
|
|||||||
|
|
||||||
/* List one certificate in colon mode */
|
/* List one certificate in colon mode */
|
||||||
static void
|
static void
|
||||||
list_cert_colon (ksba_cert_t cert, FILE *fp, int have_secret)
|
list_cert_colon (ksba_cert_t cert, unsigned int validity,
|
||||||
|
FILE *fp, int have_secret)
|
||||||
{
|
{
|
||||||
int idx, trustletter = 0;
|
int idx, trustletter = 0;
|
||||||
char *p;
|
char *p;
|
||||||
@ -155,19 +157,17 @@ list_cert_colon (ksba_cert_t cert, FILE *fp, int have_secret)
|
|||||||
|
|
||||||
fputs (have_secret? "crs:":"crt:", fp);
|
fputs (have_secret? "crs:":"crt:", fp);
|
||||||
trustletter = 0;
|
trustletter = 0;
|
||||||
|
if ((validity & VALIDITY_REVOKED))
|
||||||
|
trustletter = 'r';
|
||||||
#if 0
|
#if 0
|
||||||
if (is_not_valid (cert))
|
else if (is_not_valid (cert))
|
||||||
putc ('i', fp);
|
putc ('i', fp);
|
||||||
else if ( is_revoked (cert) )
|
|
||||||
putc ('r', fp);
|
|
||||||
else if ( has_expired (cert))
|
else if ( has_expired (cert))
|
||||||
putcr ('e', fp);
|
putcr ('e', fp);
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
else
|
||||||
trustletter = '?'; /*get_validity_info ( pk, NULL );*/
|
trustletter = '?';
|
||||||
putc (trustletter, fp);
|
putc (trustletter, fp);
|
||||||
}
|
|
||||||
|
|
||||||
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
||||||
fprintf (fp, ":%u:%d:%s:",
|
fprintf (fp, ":%u:%d:%s:",
|
||||||
@ -481,9 +481,17 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
|
|||||||
lastresname = NULL;
|
lastresname = NULL;
|
||||||
while (!(rc = keydb_search (hd, desc, ndesc)))
|
while (!(rc = keydb_search (hd, desc, ndesc)))
|
||||||
{
|
{
|
||||||
|
unsigned int validity;
|
||||||
|
|
||||||
if (!names)
|
if (!names)
|
||||||
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
||||||
|
|
||||||
|
rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
rc = keydb_get_cert (hd, &cert);
|
rc = keydb_get_cert (hd, &cert);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -524,7 +532,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
|
|||||||
|| ((mode & 2) && have_secret) )
|
|| ((mode & 2) && have_secret) )
|
||||||
{
|
{
|
||||||
if (ctrl->with_colons)
|
if (ctrl->with_colons)
|
||||||
list_cert_colon (cert, fp, have_secret);
|
list_cert_colon (cert, validity, fp, have_secret);
|
||||||
else if (ctrl->with_chain)
|
else if (ctrl->with_chain)
|
||||||
list_cert_chain (cert, fp);
|
list_cert_chain (cert, fp);
|
||||||
else
|
else
|
||||||
@ -568,7 +576,7 @@ list_external_cb (void *cb_value, ksba_cert_t cert)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parm->with_colons)
|
if (parm->with_colons)
|
||||||
list_cert_colon (cert, parm->fp, 0);
|
list_cert_colon (cert, 0, parm->fp, 0);
|
||||||
else if (parm->with_chain)
|
else if (parm->with_chain)
|
||||||
list_cert_chain (cert, parm->fp);
|
list_cert_chain (cert, parm->fp);
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user