1998-01-02 21:40:10 +01:00
|
|
|
|
/* trustdb.c
|
2003-11-15 01:19:49 +01:00
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002
|
|
|
|
|
* 2003 Free Software Foundation, Inc.
|
1998-01-02 21:40:10 +01:00
|
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
|
* This file is part of GnuPG.
|
1998-01-02 21:40:10 +01:00
|
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
1998-01-02 21:40:10 +01:00
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
|
* GnuPG is distributed in the hope that it will be useful,
|
1998-01-02 21:40:10 +01:00
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
2002-10-30 04:11:57 +01:00
|
|
|
|
#ifndef DISABLE_REGEX
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#ifdef USE_GNU_REGEX
|
|
|
|
|
#include "_regex.h"
|
|
|
|
|
#else
|
|
|
|
|
#include <regex.h>
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* !DISABLE_REGEX */
|
|
|
|
|
|
1998-01-02 21:40:10 +01:00
|
|
|
|
#include "errors.h"
|
|
|
|
|
#include "iobuf.h"
|
|
|
|
|
#include "keydb.h"
|
2002-06-29 15:46:34 +02:00
|
|
|
|
#include "memory.h"
|
1998-01-02 21:40:10 +01:00
|
|
|
|
#include "util.h"
|
1998-01-12 11:18:17 +01:00
|
|
|
|
#include "options.h"
|
1998-01-16 22:15:24 +01:00
|
|
|
|
#include "packet.h"
|
|
|
|
|
#include "main.h"
|
1998-04-02 12:30:03 +02:00
|
|
|
|
#include "i18n.h"
|
1998-07-09 15:37:17 +02:00
|
|
|
|
#include "tdbio.h"
|
2002-06-29 15:46:34 +02:00
|
|
|
|
#include "trustdb.h"
|
1998-12-08 13:20:53 +01:00
|
|
|
|
|
1998-01-16 22:15:24 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* A structure to store key identification as well as some stuff needed
|
|
|
|
|
* for validation
|
|
|
|
|
*/
|
|
|
|
|
struct key_item {
|
|
|
|
|
struct key_item *next;
|
2002-10-30 04:11:57 +01:00
|
|
|
|
unsigned int ownertrust,min_ownertrust;
|
|
|
|
|
byte trust_depth;
|
|
|
|
|
byte trust_value;
|
|
|
|
|
char *trust_regexp;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
u32 kid[2];
|
1998-11-03 20:38:58 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
|
1998-11-03 20:38:58 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Structure to keep track of keys, this is used as an array wherre
|
|
|
|
|
* the item right after the last one has a keyblock set to NULL.
|
|
|
|
|
* Maybe we can drop this thing and replace it by key_item
|
|
|
|
|
*/
|
|
|
|
|
struct key_array {
|
|
|
|
|
KBNODE keyblock;
|
1999-03-08 20:50:18 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* control information for the trust DB */
|
1999-02-24 11:12:32 +01:00
|
|
|
|
static struct {
|
|
|
|
|
int init;
|
|
|
|
|
int level;
|
|
|
|
|
char *dbname;
|
|
|
|
|
} trustdb_args;
|
1998-10-07 15:30:43 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* some globals */
|
|
|
|
|
static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */
|
|
|
|
|
static struct key_item *utk_list; /* all ultimately trusted keys */
|
1998-10-07 15:30:43 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static int pending_check_trustdb;
|
1998-10-16 18:00:17 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static int validate_keys (int interactive);
|
1998-10-07 15:30:43 +02:00
|
|
|
|
|
1998-09-28 21:25:31 +02:00
|
|
|
|
|
1998-01-30 21:25:31 +01:00
|
|
|
|
/**********************************************
|
2002-06-29 15:46:34 +02:00
|
|
|
|
************* some helpers *******************
|
1998-01-30 21:25:31 +01:00
|
|
|
|
**********************************************/
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static struct key_item *
|
|
|
|
|
new_key_item (void)
|
1998-01-30 21:25:31 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item *k;
|
|
|
|
|
|
|
|
|
|
k = m_alloc_clear (sizeof *k);
|
|
|
|
|
return k;
|
1998-01-30 21:25:31 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2002-06-29 15:46:34 +02:00
|
|
|
|
release_key_items (struct key_item *k)
|
1998-01-30 21:25:31 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item *k2;
|
2000-07-14 19:34:53 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (; k; k = k2)
|
|
|
|
|
{
|
|
|
|
|
k2 = k->next;
|
2002-10-30 04:11:57 +01:00
|
|
|
|
m_free (k->trust_regexp);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
m_free (k);
|
2000-07-14 19:34:53 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* For fast keylook up we need a hash table. Each byte of a KeyIDs
|
|
|
|
|
* should be distributed equally over the 256 possible values (except
|
|
|
|
|
* for v3 keyIDs but we consider them as not important here). So we
|
|
|
|
|
* can just use 10 bits to index a table of 1024 key items.
|
|
|
|
|
* Possible optimization: Don not use key_items but other hash_table when the
|
|
|
|
|
* duplicates lists gets too large.
|
1998-01-30 21:25:31 +01:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static KeyHashTable
|
|
|
|
|
new_key_hash_table (void)
|
1998-01-30 21:25:31 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item **tbl;
|
|
|
|
|
|
|
|
|
|
tbl = m_alloc_clear (1024 * sizeof *tbl);
|
|
|
|
|
return tbl;
|
1998-01-30 21:25:31 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static void
|
|
|
|
|
release_key_hash_table (KeyHashTable tbl)
|
1998-01-30 21:25:31 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
int i;
|
1998-01-30 21:25:31 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (!tbl)
|
|
|
|
|
return;
|
|
|
|
|
for (i=0; i < 1024; i++)
|
|
|
|
|
release_key_items (tbl[i]);
|
|
|
|
|
m_free (tbl);
|
1998-01-30 21:25:31 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Returns: True if the keyID is in the given hash table
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
test_key_hash_table (KeyHashTable tbl, u32 *kid)
|
1999-03-11 16:42:06 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item *k;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next)
|
|
|
|
|
if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
|
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Add a new key to the hash table. The key is identified by its key ID.
|
|
|
|
|
*/
|
1999-03-11 16:42:06 +01:00
|
|
|
|
static void
|
2002-06-29 15:46:34 +02:00
|
|
|
|
add_key_hash_table (KeyHashTable tbl, u32 *kid)
|
1999-03-11 16:42:06 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item *k, *kk;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next)
|
|
|
|
|
if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
|
|
|
|
|
return; /* already in table */
|
|
|
|
|
|
|
|
|
|
kk = new_key_item ();
|
|
|
|
|
kk->kid[0] = kid[0];
|
|
|
|
|
kk->kid[1] = kid[1];
|
|
|
|
|
kk->next = tbl[(kid[1] & 0x03ff)];
|
|
|
|
|
tbl[(kid[1] & 0x03ff)] = kk;
|
|
|
|
|
}
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Release a key_array
|
|
|
|
|
*/
|
1999-03-11 16:42:06 +01:00
|
|
|
|
static void
|
2002-06-29 15:46:34 +02:00
|
|
|
|
release_key_array ( struct key_array *keys )
|
1999-03-11 16:42:06 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_array *k;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (keys) {
|
|
|
|
|
for (k=keys; k->keyblock; k++)
|
|
|
|
|
release_kbnode (k->keyblock);
|
|
|
|
|
m_free (keys);
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
|
|
/*********************************************
|
|
|
|
|
********** Initialization *****************
|
|
|
|
|
*********************************************/
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
|
|
|
|
|
1998-01-30 21:25:31 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Used to register extra ultimately trusted keys - this has to be done
|
|
|
|
|
* before initializing the validation module.
|
|
|
|
|
* FIXME: Should be replaced by a function to add those keys to the trustdb.
|
1998-07-21 14:53:38 +02:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
void
|
2003-11-01 02:13:16 +01:00
|
|
|
|
register_trusted_keyid(u32 *keyid)
|
1998-01-30 21:25:31 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item *k;
|
1998-01-16 22:15:24 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
k = new_key_item ();
|
2003-11-01 02:13:16 +01:00
|
|
|
|
k->kid[0] = keyid[0];
|
|
|
|
|
k->kid[1] = keyid[1];
|
2002-06-29 15:46:34 +02:00
|
|
|
|
k->next = user_utk_list;
|
|
|
|
|
user_utk_list = k;
|
1998-10-12 22:16:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
2003-11-01 02:13:16 +01:00
|
|
|
|
void
|
|
|
|
|
register_trusted_key( const char *string )
|
|
|
|
|
{
|
|
|
|
|
KEYDB_SEARCH_DESC desc;
|
|
|
|
|
|
|
|
|
|
if (classify_user_id (string, &desc) != KEYDB_SEARCH_MODE_LONG_KID )
|
|
|
|
|
{
|
|
|
|
|
log_error(_("`%s' is not a valid long keyID\n"), string );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
register_trusted_keyid(desc.u.kid);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Helper to add a key to the global list of ultimately trusted keys.
|
|
|
|
|
* Retruns: true = inserted, false = already in in list.
|
|
|
|
|
*/
|
1999-03-11 16:42:06 +01:00
|
|
|
|
static int
|
2002-06-29 15:46:34 +02:00
|
|
|
|
add_utk (u32 *kid)
|
1999-03-11 16:42:06 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item *k;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (k = utk_list; k; k = k->next)
|
|
|
|
|
{
|
|
|
|
|
if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
k = new_key_item ();
|
|
|
|
|
k->kid[0] = kid[0];
|
|
|
|
|
k->kid[1] = kid[1];
|
|
|
|
|
k->ownertrust = TRUST_ULTIMATE;
|
|
|
|
|
k->next = utk_list;
|
|
|
|
|
utk_list = k;
|
|
|
|
|
if( opt.verbose > 1 )
|
|
|
|
|
log_info(_("key %08lX: accepted as trusted key\n"), (ulong)kid[1]);
|
|
|
|
|
return 1;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
1998-01-12 11:18:17 +01:00
|
|
|
|
|
1998-01-16 22:15:24 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/****************
|
|
|
|
|
* Verify that all our secret keys are usable and put them into the utk_list.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
verify_own_keys(void)
|
2000-09-18 16:35:34 +02:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
TRUSTREC rec;
|
|
|
|
|
ulong recnum;
|
|
|
|
|
int rc;
|
|
|
|
|
struct key_item *k;
|
|
|
|
|
|
|
|
|
|
if (utk_list)
|
|
|
|
|
return;
|
2000-09-18 16:35:34 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* scan the trustdb to find all ultimately trusted keys */
|
|
|
|
|
for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ )
|
|
|
|
|
{
|
|
|
|
|
if ( rec.rectype == RECTYPE_TRUST
|
|
|
|
|
&& (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE)
|
|
|
|
|
{
|
|
|
|
|
byte *fpr = rec.r.trust.fingerprint;
|
|
|
|
|
int fprlen;
|
|
|
|
|
u32 kid[2];
|
|
|
|
|
|
|
|
|
|
/* Problem: We do only use fingerprints in the trustdb but
|
|
|
|
|
* we need the keyID here to indetify the key; we can only
|
|
|
|
|
* use that ugly hack to distinguish between 16 and 20
|
|
|
|
|
* butes fpr - it does not work always so we better change
|
|
|
|
|
* the whole validation code to only work with
|
|
|
|
|
* fingerprints */
|
|
|
|
|
fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20;
|
|
|
|
|
keyid_from_fingerprint (fpr, fprlen, kid);
|
|
|
|
|
if (!add_utk (kid))
|
|
|
|
|
log_info(_("key %08lX occurs more than once in the trustdb\n"),
|
|
|
|
|
(ulong)kid[1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-01-06 23:56:08 +01:00
|
|
|
|
|
|
|
|
|
/* Put any --trusted-key keys into the trustdb */
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (k = user_utk_list; k; k = k->next)
|
|
|
|
|
{
|
|
|
|
|
if ( add_utk (k->kid) )
|
|
|
|
|
{ /* not yet in trustDB as ultimately trusted */
|
|
|
|
|
PKT_public_key pk;
|
|
|
|
|
|
|
|
|
|
memset (&pk, 0, sizeof pk);
|
|
|
|
|
rc = get_pubkey (&pk, k->kid);
|
|
|
|
|
if (rc) {
|
|
|
|
|
log_info(_("key %08lX: no public key for trusted key - skipped\n"),
|
|
|
|
|
(ulong)k->kid[1] );
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
update_ownertrust (&pk,
|
|
|
|
|
((get_ownertrust (&pk) & ~TRUST_MASK)
|
|
|
|
|
| TRUST_ULTIMATE ));
|
|
|
|
|
release_public_key_parts (&pk);
|
|
|
|
|
}
|
2002-10-03 00:01:29 +02:00
|
|
|
|
log_info (_("key %08lX marked as ultimately trusted\n"),
|
2002-06-29 15:46:34 +02:00
|
|
|
|
(ulong)k->kid[1]);
|
|
|
|
|
}
|
2000-09-18 16:35:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* release the helper table table */
|
|
|
|
|
release_key_items (user_utk_list);
|
|
|
|
|
user_utk_list = NULL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2000-09-18 16:35:34 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
|
|
/*********************************************
|
|
|
|
|
*********** TrustDB stuff *******************
|
|
|
|
|
*********************************************/
|
2000-09-18 16:35:34 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Read a record but die if it does not exist
|
|
|
|
|
*/
|
2000-09-18 16:35:34 +02:00
|
|
|
|
static void
|
2002-06-29 15:46:34 +02:00
|
|
|
|
read_record (ulong recno, TRUSTREC *rec, int rectype )
|
2000-09-18 16:35:34 +02:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
int rc = tdbio_read_record (recno, rec, rectype);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error(_("trust record %lu, req type %d: read failed: %s\n"),
|
|
|
|
|
recno, rec->rectype, g10_errstr(rc) );
|
|
|
|
|
tdbio_invalid();
|
2000-09-18 16:35:34 +02:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (rectype != rec->rectype)
|
|
|
|
|
{
|
|
|
|
|
log_error(_("trust record %lu is not of requested type %d\n"),
|
|
|
|
|
rec->recnum, rectype);
|
|
|
|
|
tdbio_invalid();
|
2000-09-18 16:35:34 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Write a record and die on error
|
1998-01-13 20:04:23 +01:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static void
|
|
|
|
|
write_record (TRUSTREC *rec)
|
1998-01-13 20:04:23 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
int rc = tdbio_write_record (rec);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error(_("trust record %lu, type %d: write failed: %s\n"),
|
|
|
|
|
rec->recnum, rec->rectype, g10_errstr(rc) );
|
|
|
|
|
tdbio_invalid();
|
1998-01-13 20:04:23 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* sync the TrustDb and die on error
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
do_sync(void)
|
|
|
|
|
{
|
|
|
|
|
int rc = tdbio_sync ();
|
|
|
|
|
if(rc)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("trustdb: sync failed: %s\n"), g10_errstr(rc) );
|
|
|
|
|
g10_exit(2);
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 16:35:34 +02:00
|
|
|
|
|
2003-04-26 22:38:16 +02:00
|
|
|
|
static const char *
|
|
|
|
|
trust_model_string(void)
|
|
|
|
|
{
|
|
|
|
|
switch(opt.trust_model)
|
|
|
|
|
{
|
2003-11-15 01:19:49 +01:00
|
|
|
|
case TM_CLASSIC: return "classic";
|
|
|
|
|
case TM_PGP: return "PGP";
|
|
|
|
|
case TM_EXTERNAL: return "external";
|
|
|
|
|
case TM_ALWAYS: return "always";
|
|
|
|
|
default: return "unknown";
|
2003-04-26 22:38:16 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 16:35:34 +02:00
|
|
|
|
|
1999-03-11 16:42:06 +01:00
|
|
|
|
/****************
|
|
|
|
|
* Perform some checks over the trustdb
|
|
|
|
|
* level 0: only open the db
|
|
|
|
|
* 1: used for initial program startup
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
setup_trustdb( int level, const char *dbname )
|
|
|
|
|
{
|
|
|
|
|
/* just store the args */
|
|
|
|
|
if( trustdb_args.init )
|
|
|
|
|
return 0;
|
|
|
|
|
trustdb_args.level = level;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
trustdb_args.dbname = dbname? m_strdup(dbname): NULL;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_trustdb()
|
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
int level = trustdb_args.level;
|
|
|
|
|
const char* dbname = trustdb_args.dbname;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if( trustdb_args.init )
|
|
|
|
|
return;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
trustdb_args.init = 1;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2003-09-30 17:30:39 +02:00
|
|
|
|
if(level==0 || level==1)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
2003-09-30 17:30:39 +02:00
|
|
|
|
int rc = tdbio_set_dbname( dbname, !!level );
|
|
|
|
|
if( rc )
|
|
|
|
|
log_fatal("can't init trustdb: %s\n", g10_errstr(rc) );
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else
|
|
|
|
|
BUG();
|
2002-12-04 07:06:56 +01:00
|
|
|
|
|
2003-04-26 22:38:16 +02:00
|
|
|
|
if(opt.trust_model==TM_AUTO)
|
|
|
|
|
{
|
|
|
|
|
/* Try and set the trust model off of whatever the trustdb says
|
|
|
|
|
it is. */
|
|
|
|
|
opt.trust_model=tdbio_read_model();
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 22:22:09 +02:00
|
|
|
|
|
|
|
|
|
/* Sanity check this ;) */
|
2003-11-15 01:19:49 +01:00
|
|
|
|
if(opt.trust_model!=TM_CLASSIC
|
|
|
|
|
&& opt.trust_model!=TM_PGP
|
|
|
|
|
&& opt.trust_model!=TM_EXTERNAL)
|
2003-04-26 22:38:16 +02:00
|
|
|
|
{
|
|
|
|
|
log_info(_("unable to use unknown trust model (%d) - "
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
"assuming %s trust model\n"),opt.trust_model,"PGP");
|
|
|
|
|
opt.trust_model=TM_PGP;
|
2003-04-26 22:38:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(opt.verbose)
|
|
|
|
|
log_info(_("using %s trust model\n"),trust_model_string());
|
|
|
|
|
}
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 22:22:09 +02:00
|
|
|
|
|
2003-09-30 17:30:39 +02:00
|
|
|
|
if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
|
|
|
|
|
{
|
|
|
|
|
/* Verify the list of ultimately trusted keys and move the
|
|
|
|
|
--trusted-keys list there as well. */
|
|
|
|
|
if(level==1)
|
|
|
|
|
verify_own_keys();
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2003-09-30 17:30:39 +02:00
|
|
|
|
if(!tdbio_db_matches_options())
|
|
|
|
|
pending_check_trustdb=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************
|
|
|
|
|
************* Print helpers ****************
|
|
|
|
|
***********************************************/
|
1998-07-09 15:37:17 +02:00
|
|
|
|
|
1999-07-01 12:53:35 +02:00
|
|
|
|
/****************
|
|
|
|
|
* This function returns a letter for a trustvalue Trust flags
|
|
|
|
|
* are ignore.
|
|
|
|
|
*/
|
* armor.c (armor_filter): Comment about PGP's end of line tab problem.
* trustdb.h, trustdb.c (trust_letter): Make static. (get_ownertrust_info,
get_validity_info): Don't mask the trust level twice.
* trustdb.h, gpgv.c, trustdb.c (get_validity, get_validity_info),
keylist.c (list_keyblock_colon), keyedit.c (show_key_with_all_names_colon,
menu_revuid): Pass a user ID in rather than a namehash, so we only have to
do the hashing in one place.
* packet.h, pkclist.c (build_pk_list), free-packet.c
(release_public_key_parts): Remove unused namehash element for public
keys.
2003-01-11 04:57:00 +01:00
|
|
|
|
static int
|
2002-06-29 15:46:34 +02:00
|
|
|
|
trust_letter (unsigned int value)
|
1998-01-16 22:15:24 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
switch( (value & TRUST_MASK) )
|
|
|
|
|
{
|
|
|
|
|
case TRUST_UNKNOWN: return '-';
|
|
|
|
|
case TRUST_EXPIRED: return 'e';
|
|
|
|
|
case TRUST_UNDEFINED: return 'q';
|
|
|
|
|
case TRUST_NEVER: return 'n';
|
|
|
|
|
case TRUST_MARGINAL: return 'm';
|
|
|
|
|
case TRUST_FULLY: return 'f';
|
|
|
|
|
case TRUST_ULTIMATE: return 'u';
|
2003-01-11 22:13:41 +01:00
|
|
|
|
default: return '?';
|
1998-01-16 22:15:24 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-10-30 04:11:57 +01:00
|
|
|
|
/* The strings here are similar to those in
|
|
|
|
|
pkclist.c:do_edit_ownertrust() */
|
|
|
|
|
const char *
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
trust_value_to_string (unsigned int value)
|
2002-10-30 04:11:57 +01:00
|
|
|
|
{
|
|
|
|
|
switch( (value & TRUST_MASK) )
|
|
|
|
|
{
|
2003-01-11 22:13:41 +01:00
|
|
|
|
case TRUST_UNKNOWN: return _("unknown");
|
2002-10-30 04:11:57 +01:00
|
|
|
|
case TRUST_EXPIRED: return _("expired");
|
2003-01-11 22:13:41 +01:00
|
|
|
|
case TRUST_UNDEFINED: return _("undefined");
|
|
|
|
|
case TRUST_NEVER: return _("never");
|
|
|
|
|
case TRUST_MARGINAL: return _("marginal");
|
|
|
|
|
case TRUST_FULLY: return _("full");
|
|
|
|
|
case TRUST_ULTIMATE: return _("ultimate");
|
2002-10-30 04:11:57 +01:00
|
|
|
|
default: return "err";
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
int
|
|
|
|
|
string_to_trust_value (const char *str)
|
|
|
|
|
{
|
|
|
|
|
if(ascii_strcasecmp(str,"undefined")==0)
|
|
|
|
|
return TRUST_UNDEFINED;
|
|
|
|
|
else if(ascii_strcasecmp(str,"never")==0)
|
|
|
|
|
return TRUST_NEVER;
|
|
|
|
|
else if(ascii_strcasecmp(str,"marginal")==0)
|
|
|
|
|
return TRUST_MARGINAL;
|
|
|
|
|
else if(ascii_strcasecmp(str,"full")==0)
|
|
|
|
|
return TRUST_FULLY;
|
|
|
|
|
else if(ascii_strcasecmp(str,"ultimate")==0)
|
|
|
|
|
return TRUST_ULTIMATE;
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/****************
|
|
|
|
|
* Recreate the WoT but do not ask for new ownertrusts. Special
|
|
|
|
|
* feature: In batch mode and without a forced yes, this is only done
|
|
|
|
|
* when a check is due. This can be used to run the check from a crontab
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
check_trustdb ()
|
|
|
|
|
{
|
2003-04-26 22:38:16 +02:00
|
|
|
|
init_trustdb();
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
2002-11-04 18:30:38 +01:00
|
|
|
|
if (opt.batch && !opt.answer_yes)
|
|
|
|
|
{
|
|
|
|
|
ulong scheduled;
|
|
|
|
|
|
|
|
|
|
scheduled = tdbio_read_nextcheck ();
|
|
|
|
|
if (!scheduled)
|
|
|
|
|
{
|
|
|
|
|
log_info (_("no need for a trustdb check\n"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scheduled > make_timestamp ())
|
|
|
|
|
{
|
|
|
|
|
log_info (_("next trustdb check due at %s\n"),
|
|
|
|
|
strtimestamp (scheduled));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-07-21 14:53:38 +02:00
|
|
|
|
|
2002-11-04 18:30:38 +01:00
|
|
|
|
validate_keys (0);
|
1999-03-17 13:13:04 +01:00
|
|
|
|
}
|
2002-11-04 18:30:38 +01:00
|
|
|
|
else
|
|
|
|
|
log_info (_("no need for a trustdb check with \"%s\" trust model\n"),
|
|
|
|
|
trust_model_string());
|
1999-03-17 13:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Recreate the WoT.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
update_trustdb()
|
1999-03-11 16:42:06 +01:00
|
|
|
|
{
|
2003-04-26 22:38:16 +02:00
|
|
|
|
init_trustdb();
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
|
2003-04-26 22:38:16 +02:00
|
|
|
|
validate_keys (1);
|
2002-11-04 18:30:38 +01:00
|
|
|
|
else
|
|
|
|
|
log_info (_("no need for a trustdb update with \"%s\" trust model\n"),
|
|
|
|
|
trust_model_string());
|
1999-03-17 13:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
void
|
|
|
|
|
revalidation_mark (void)
|
1999-03-17 13:13:04 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
init_trustdb();
|
|
|
|
|
/* we simply set the time for the next check to 1 (far back in 1970)
|
|
|
|
|
* so that a --update-trustdb will be scheduled */
|
|
|
|
|
if (tdbio_write_nextcheck (1))
|
|
|
|
|
do_sync ();
|
|
|
|
|
pending_check_trustdb = 1;
|
1998-07-21 14:53:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 22:10:53 +01:00
|
|
|
|
int
|
|
|
|
|
trustdb_pending_check(void)
|
|
|
|
|
{
|
|
|
|
|
return pending_check_trustdb;
|
|
|
|
|
}
|
|
|
|
|
|
2003-07-22 01:19:15 +02:00
|
|
|
|
void
|
|
|
|
|
read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
|
|
|
|
|
byte *marginals,byte *completes,byte *cert_depth)
|
|
|
|
|
{
|
|
|
|
|
TRUSTREC opts;
|
|
|
|
|
|
|
|
|
|
init_trustdb();
|
|
|
|
|
|
|
|
|
|
read_record(0,&opts,RECTYPE_VER);
|
|
|
|
|
|
|
|
|
|
if(trust_model)
|
|
|
|
|
*trust_model=opts.r.ver.trust_model;
|
|
|
|
|
if(created)
|
|
|
|
|
*created=opts.r.ver.created;
|
|
|
|
|
if(nextcheck)
|
|
|
|
|
*nextcheck=opts.r.ver.nextcheck;
|
|
|
|
|
if(marginals)
|
|
|
|
|
*marginals=opts.r.ver.marginals;
|
|
|
|
|
if(completes)
|
|
|
|
|
*completes=opts.r.ver.completes;
|
|
|
|
|
if(cert_depth)
|
|
|
|
|
*cert_depth=opts.r.ver.cert_depth;
|
|
|
|
|
}
|
|
|
|
|
|
1999-03-11 16:42:06 +01:00
|
|
|
|
/***********************************************
|
2002-06-29 15:46:34 +02:00
|
|
|
|
*********** Ownertrust et al. ****************
|
1999-03-11 16:42:06 +01:00
|
|
|
|
***********************************************/
|
1998-01-16 22:15:24 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static int
|
|
|
|
|
read_trust_record (PKT_public_key *pk, TRUSTREC *rec)
|
|
|
|
|
{
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
init_trustdb();
|
|
|
|
|
rc = tdbio_search_trust_bypk (pk, rec);
|
|
|
|
|
if (rc == -1)
|
|
|
|
|
return -1; /* no record yet */
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error ("trustdb: searching trust record failed: %s\n",
|
|
|
|
|
g10_errstr (rc));
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rec->rectype != RECTYPE_TRUST)
|
|
|
|
|
{
|
|
|
|
|
log_error ("trustdb: record %lu is not a trust record\n",
|
|
|
|
|
rec->recnum);
|
|
|
|
|
return G10ERR_TRUSTDB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-03 20:38:58 +01:00
|
|
|
|
/****************
|
2002-06-29 15:46:34 +02:00
|
|
|
|
* Return the assigned ownertrust value for the given public key.
|
|
|
|
|
* The key should be the primary key.
|
1998-11-03 20:38:58 +01:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
unsigned int
|
|
|
|
|
get_ownertrust ( PKT_public_key *pk)
|
1998-01-24 17:32:27 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
TRUSTREC rec;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = read_trust_record (pk, &rec);
|
|
|
|
|
if (rc == -1)
|
|
|
|
|
return TRUST_UNKNOWN; /* no record yet */
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
|
|
|
|
return rc; /* actually never reached */
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
2002-10-30 04:11:57 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return rec.r.trust.ownertrust;
|
1998-11-03 20:38:58 +01:00
|
|
|
|
}
|
1998-10-25 20:00:01 +01:00
|
|
|
|
|
2002-10-30 04:11:57 +01:00
|
|
|
|
unsigned int
|
|
|
|
|
get_min_ownertrust (PKT_public_key *pk)
|
|
|
|
|
{
|
|
|
|
|
TRUSTREC rec;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = read_trust_record (pk, &rec);
|
|
|
|
|
if (rc == -1)
|
|
|
|
|
return TRUST_UNKNOWN; /* no record yet */
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
|
|
|
|
return rc; /* actually never reached */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rec.r.trust.min_ownertrust;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
2003-01-11 22:13:41 +01:00
|
|
|
|
* Same as get_ownertrust but this takes the minimum ownertrust value
|
|
|
|
|
* into into account, and will bump up the value as needed.
|
2002-06-29 15:46:34 +02:00
|
|
|
|
*/
|
2003-01-11 22:13:41 +01:00
|
|
|
|
static int
|
|
|
|
|
get_ownertrust_with_min (PKT_public_key *pk)
|
1998-01-13 20:04:23 +01:00
|
|
|
|
{
|
2003-01-11 22:13:41 +01:00
|
|
|
|
unsigned int otrust,otrust_min;
|
1998-01-30 21:25:31 +01:00
|
|
|
|
|
2003-03-04 16:24:12 +01:00
|
|
|
|
otrust = (get_ownertrust (pk) & TRUST_MASK);
|
2003-01-11 22:13:41 +01:00
|
|
|
|
otrust_min = get_min_ownertrust (pk);
|
|
|
|
|
if(otrust<otrust_min)
|
|
|
|
|
{
|
|
|
|
|
/* If the trust that the user has set is less than the trust
|
|
|
|
|
that was calculated from a trust signature chain, use the
|
|
|
|
|
higher of the two. We do this here and not in
|
|
|
|
|
get_ownertrust since the underlying ownertrust should not
|
|
|
|
|
really be set - just the appearance of the ownertrust. */
|
2002-10-30 04:11:57 +01:00
|
|
|
|
|
2003-01-11 22:13:41 +01:00
|
|
|
|
otrust=otrust_min;
|
|
|
|
|
}
|
2002-10-30 04:11:57 +01:00
|
|
|
|
|
2003-01-11 22:13:41 +01:00
|
|
|
|
return otrust;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Same as get_ownertrust but return a trust letter instead of an
|
|
|
|
|
* value. This takes the minimum ownertrust value into account.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
get_ownertrust_info (PKT_public_key *pk)
|
|
|
|
|
{
|
|
|
|
|
return trust_letter(get_ownertrust_with_min(pk));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Same as get_ownertrust but return a trust string instead of an
|
|
|
|
|
* value. This takes the minimum ownertrust value into account.
|
|
|
|
|
*/
|
|
|
|
|
const char *
|
|
|
|
|
get_ownertrust_string (PKT_public_key *pk)
|
|
|
|
|
{
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
return trust_value_to_string(get_ownertrust_with_min(pk));
|
1998-01-30 21:25:31 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Set the trust value of the given public key to the new value.
|
|
|
|
|
* The key should be a primary one.
|
1999-06-29 21:50:54 +02:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
void
|
|
|
|
|
update_ownertrust (PKT_public_key *pk, unsigned int new_trust )
|
|
|
|
|
{
|
|
|
|
|
TRUSTREC rec;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = read_trust_record (pk, &rec);
|
|
|
|
|
if (!rc)
|
|
|
|
|
{
|
|
|
|
|
if (DBG_TRUST)
|
|
|
|
|
log_debug ("update ownertrust from %u to %u\n",
|
|
|
|
|
(unsigned int)rec.r.trust.ownertrust, new_trust );
|
|
|
|
|
if (rec.r.trust.ownertrust != new_trust)
|
|
|
|
|
{
|
|
|
|
|
rec.r.trust.ownertrust = new_trust;
|
|
|
|
|
write_record( &rec );
|
|
|
|
|
revalidation_mark ();
|
|
|
|
|
do_sync ();
|
|
|
|
|
}
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else if (rc == -1)
|
|
|
|
|
{ /* no record yet - create a new one */
|
|
|
|
|
size_t dummy;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (DBG_TRUST)
|
|
|
|
|
log_debug ("insert ownertrust %u\n", new_trust );
|
1999-06-29 21:50:54 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
memset (&rec, 0, sizeof rec);
|
|
|
|
|
rec.recnum = tdbio_new_recnum ();
|
|
|
|
|
rec.rectype = RECTYPE_TRUST;
|
|
|
|
|
fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
|
|
|
|
|
rec.r.trust.ownertrust = new_trust;
|
|
|
|
|
write_record (&rec);
|
|
|
|
|
revalidation_mark ();
|
|
|
|
|
do_sync ();
|
|
|
|
|
rc = 0;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-10-30 04:11:57 +01:00
|
|
|
|
static void
|
|
|
|
|
update_min_ownertrust (u32 *kid, unsigned int new_trust )
|
|
|
|
|
{
|
|
|
|
|
PKT_public_key *pk;
|
|
|
|
|
TRUSTREC rec;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
pk = m_alloc_clear (sizeof *pk);
|
|
|
|
|
rc = get_pubkey (pk, kid);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("public key %08lX not found: %s\n"),
|
|
|
|
|
(ulong)kid[1], g10_errstr(rc) );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = read_trust_record (pk, &rec);
|
|
|
|
|
if (!rc)
|
|
|
|
|
{
|
|
|
|
|
if (DBG_TRUST)
|
|
|
|
|
log_debug ("key %08lX: update min_ownertrust from %u to %u\n",
|
|
|
|
|
(ulong)kid[1],(unsigned int)rec.r.trust.min_ownertrust,
|
|
|
|
|
new_trust );
|
|
|
|
|
if (rec.r.trust.min_ownertrust != new_trust)
|
|
|
|
|
{
|
|
|
|
|
rec.r.trust.min_ownertrust = new_trust;
|
|
|
|
|
write_record( &rec );
|
|
|
|
|
revalidation_mark ();
|
|
|
|
|
do_sync ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (rc == -1)
|
|
|
|
|
{ /* no record yet - create a new one */
|
|
|
|
|
size_t dummy;
|
|
|
|
|
|
|
|
|
|
if (DBG_TRUST)
|
|
|
|
|
log_debug ("insert min_ownertrust %u\n", new_trust );
|
|
|
|
|
|
|
|
|
|
memset (&rec, 0, sizeof rec);
|
|
|
|
|
rec.recnum = tdbio_new_recnum ();
|
|
|
|
|
rec.rectype = RECTYPE_TRUST;
|
|
|
|
|
fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
|
|
|
|
|
rec.r.trust.min_ownertrust = new_trust;
|
|
|
|
|
write_record (&rec);
|
|
|
|
|
revalidation_mark ();
|
|
|
|
|
do_sync ();
|
|
|
|
|
rc = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clear the ownertrust and min_ownertrust values. Return true if a
|
|
|
|
|
change actually happened. */
|
2002-06-29 15:46:34 +02:00
|
|
|
|
int
|
2002-10-30 04:11:57 +01:00
|
|
|
|
clear_ownertrusts (PKT_public_key *pk)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
TRUSTREC rec;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = read_trust_record (pk, &rec);
|
|
|
|
|
if (!rc)
|
|
|
|
|
{
|
|
|
|
|
if (DBG_TRUST)
|
2002-10-30 04:11:57 +01:00
|
|
|
|
{
|
|
|
|
|
log_debug ("clearing ownertrust (old value %u)\n",
|
|
|
|
|
(unsigned int)rec.r.trust.ownertrust);
|
|
|
|
|
log_debug ("clearing min_ownertrust (old value %u)\n",
|
|
|
|
|
(unsigned int)rec.r.trust.min_ownertrust);
|
|
|
|
|
}
|
|
|
|
|
if (rec.r.trust.ownertrust || rec.r.trust.min_ownertrust)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
rec.r.trust.ownertrust = 0;
|
2002-10-30 04:11:57 +01:00
|
|
|
|
rec.r.trust.min_ownertrust = 0;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
write_record( &rec );
|
|
|
|
|
revalidation_mark ();
|
|
|
|
|
do_sync ();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else if (rc != -1)
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
1998-11-13 20:41:41 +01:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return 0;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Note: Caller has to do a sync
|
1999-06-29 21:50:54 +02:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static void
|
2003-01-06 23:56:08 +01:00
|
|
|
|
update_validity (PKT_public_key *pk, PKT_user_id *uid,
|
2002-06-29 15:46:34 +02:00
|
|
|
|
int depth, int validity)
|
|
|
|
|
{
|
|
|
|
|
TRUSTREC trec, vrec;
|
|
|
|
|
int rc;
|
|
|
|
|
ulong recno;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
|
2003-01-14 19:13:22 +01:00
|
|
|
|
namehash_from_uid(uid);
|
2003-01-06 23:56:08 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
rc = read_trust_record (pk, &trec);
|
|
|
|
|
if (rc && rc != -1)
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (rc == -1) /* no record yet - create a new one */
|
|
|
|
|
{
|
|
|
|
|
size_t dummy;
|
|
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
|
memset (&trec, 0, sizeof trec);
|
|
|
|
|
trec.recnum = tdbio_new_recnum ();
|
|
|
|
|
trec.rectype = RECTYPE_TRUST;
|
|
|
|
|
fingerprint_from_pk (pk, trec.r.trust.fingerprint, &dummy);
|
|
|
|
|
trec.r.trust.ownertrust = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* locate an existing one */
|
|
|
|
|
recno = trec.r.trust.validlist;
|
|
|
|
|
while (recno)
|
|
|
|
|
{
|
|
|
|
|
read_record (recno, &vrec, RECTYPE_VALID);
|
2003-01-14 19:13:22 +01:00
|
|
|
|
if ( !memcmp (vrec.r.valid.namehash, uid->namehash, 20) )
|
2002-06-29 15:46:34 +02:00
|
|
|
|
break;
|
|
|
|
|
recno = vrec.r.valid.next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!recno) /* insert a new validity record */
|
|
|
|
|
{
|
|
|
|
|
memset (&vrec, 0, sizeof vrec);
|
|
|
|
|
vrec.recnum = tdbio_new_recnum ();
|
|
|
|
|
vrec.rectype = RECTYPE_VALID;
|
2003-01-14 19:13:22 +01:00
|
|
|
|
memcpy (vrec.r.valid.namehash, uid->namehash, 20);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
vrec.r.valid.next = trec.r.trust.validlist;
|
2003-04-30 07:33:52 +02:00
|
|
|
|
trec.r.trust.validlist = vrec.recnum;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
}
|
|
|
|
|
vrec.r.valid.validity = validity;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
vrec.r.valid.full_count = uid->help_full_count;
|
|
|
|
|
vrec.r.valid.marginal_count = uid->help_marginal_count;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
write_record (&vrec);
|
|
|
|
|
trec.r.trust.depth = depth;
|
|
|
|
|
write_record (&trec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reset validity for all user IDs. Caller must sync. */
|
|
|
|
|
static int
|
|
|
|
|
clear_validity (PKT_public_key *pk)
|
|
|
|
|
{
|
|
|
|
|
TRUSTREC trec, vrec;
|
|
|
|
|
int rc;
|
|
|
|
|
ulong recno;
|
|
|
|
|
int any = 0;
|
|
|
|
|
|
|
|
|
|
rc = read_trust_record (pk, &trec);
|
|
|
|
|
if (rc && rc != -1)
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2002-10-30 04:11:57 +01:00
|
|
|
|
if (rc == -1) /* no record yet - no need to clear it then ;-) */
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return 0;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
|
2002-10-30 04:11:57 +01:00
|
|
|
|
/* Clear minimum ownertrust, if any */
|
|
|
|
|
if(trec.r.trust.min_ownertrust)
|
|
|
|
|
{
|
|
|
|
|
trec.r.trust.min_ownertrust=0;
|
|
|
|
|
write_record(&trec);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
recno = trec.r.trust.validlist;
|
|
|
|
|
while (recno)
|
|
|
|
|
{
|
|
|
|
|
read_record (recno, &vrec, RECTYPE_VALID);
|
2003-01-06 23:56:08 +01:00
|
|
|
|
if ((vrec.r.valid.validity & TRUST_MASK)
|
|
|
|
|
|| vrec.r.valid.marginal_count || vrec.r.valid.full_count)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
vrec.r.valid.validity &= ~TRUST_MASK;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
vrec.r.valid.marginal_count = vrec.r.valid.full_count = 0;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
write_record (&vrec);
|
|
|
|
|
any = 1;
|
|
|
|
|
}
|
|
|
|
|
recno = vrec.r.valid.next;
|
1998-12-23 13:41:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return any;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/***********************************************
|
|
|
|
|
********* Query trustdb values **************
|
|
|
|
|
***********************************************/
|
1999-07-07 13:28:26 +02:00
|
|
|
|
|
2002-12-26 23:22:50 +01:00
|
|
|
|
/* Return true if key is disabled */
|
|
|
|
|
int
|
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not just the
keyid. This is for speed since there is no need to re-fetch a key when we
already have that key handy. Cache the result of the check so we don't
need to hit the trustdb more than once.
* getkey.c (skip_disabled): New function to get a pk and call is_disabled
on it. (key_byname): Use it here.
* packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New
"pk_is_disabled" macro to retrieve the cached disabled value if available,
and fill it in via cache_disabled_value if not available.
* trustdb.c (get_validity): Cache the disabled value since we have it
handy and it might be useful later.
* parse-packet.c (parse_key): Clear disabled flag when parsing a new key.
Just in case someone forgets to clear the whole key.
* getkey.c (merge_selfsigs_main): Add an "if all else fails" path for
setting a single user ID primary when there are multiple set primaries all
at the same second, or no primaries set and the most recent user IDs are
at the same second, or no signed user IDs at all. This is arbitrary, but
deterministic.
* exec.h, photoid.h: Add copyright message.
* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings. This is for
consistency with --show-photos.
* main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump
attribs if --attrib-fd is set when verifying signatures.
* g10.c (main): New --gnupg option to disable the various --openpgp,
--pgpX, etc. options. This is the same as --no-XXXX for those options.
* revoke.c (ask_revocation_reason): Clear old reason if user elects to
repeat question. This is bug 153.
* keyedit.c (sign_uids): Show keyid of the key making the signature.
2003-05-21 18:42:22 +02:00
|
|
|
|
cache_disabled_value(PKT_public_key *pk)
|
2002-12-26 23:22:50 +01:00
|
|
|
|
{
|
|
|
|
|
int rc;
|
|
|
|
|
TRUSTREC trec;
|
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not just the
keyid. This is for speed since there is no need to re-fetch a key when we
already have that key handy. Cache the result of the check so we don't
need to hit the trustdb more than once.
* getkey.c (skip_disabled): New function to get a pk and call is_disabled
on it. (key_byname): Use it here.
* packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New
"pk_is_disabled" macro to retrieve the cached disabled value if available,
and fill it in via cache_disabled_value if not available.
* trustdb.c (get_validity): Cache the disabled value since we have it
handy and it might be useful later.
* parse-packet.c (parse_key): Clear disabled flag when parsing a new key.
Just in case someone forgets to clear the whole key.
* getkey.c (merge_selfsigs_main): Add an "if all else fails" path for
setting a single user ID primary when there are multiple set primaries all
at the same second, or no primaries set and the most recent user IDs are
at the same second, or no signed user IDs at all. This is arbitrary, but
deterministic.
* exec.h, photoid.h: Add copyright message.
* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings. This is for
consistency with --show-photos.
* main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump
attribs if --attrib-fd is set when verifying signatures.
* g10.c (main): New --gnupg option to disable the various --openpgp,
--pgpX, etc. options. This is the same as --no-XXXX for those options.
* revoke.c (ask_revocation_reason): Clear old reason if user elects to
repeat question. This is bug 153.
* keyedit.c (sign_uids): Show keyid of the key making the signature.
2003-05-21 18:42:22 +02:00
|
|
|
|
int disabled=0;
|
2002-12-26 23:22:50 +01:00
|
|
|
|
|
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not just the
keyid. This is for speed since there is no need to re-fetch a key when we
already have that key handy. Cache the result of the check so we don't
need to hit the trustdb more than once.
* getkey.c (skip_disabled): New function to get a pk and call is_disabled
on it. (key_byname): Use it here.
* packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New
"pk_is_disabled" macro to retrieve the cached disabled value if available,
and fill it in via cache_disabled_value if not available.
* trustdb.c (get_validity): Cache the disabled value since we have it
handy and it might be useful later.
* parse-packet.c (parse_key): Clear disabled flag when parsing a new key.
Just in case someone forgets to clear the whole key.
* getkey.c (merge_selfsigs_main): Add an "if all else fails" path for
setting a single user ID primary when there are multiple set primaries all
at the same second, or no primaries set and the most recent user IDs are
at the same second, or no signed user IDs at all. This is arbitrary, but
deterministic.
* exec.h, photoid.h: Add copyright message.
* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings. This is for
consistency with --show-photos.
* main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump
attribs if --attrib-fd is set when verifying signatures.
* g10.c (main): New --gnupg option to disable the various --openpgp,
--pgpX, etc. options. This is the same as --no-XXXX for those options.
* revoke.c (ask_revocation_reason): Clear old reason if user elects to
repeat question. This is bug 153.
* keyedit.c (sign_uids): Show keyid of the key making the signature.
2003-05-21 18:42:22 +02:00
|
|
|
|
if(pk->is_disabled)
|
|
|
|
|
return (pk->is_disabled==2);
|
|
|
|
|
|
|
|
|
|
init_trustdb();
|
2002-12-26 23:22:50 +01:00
|
|
|
|
|
|
|
|
|
rc = read_trust_record (pk, &trec);
|
|
|
|
|
if (rc && rc != -1)
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
if (rc == -1) /* no record found, so assume not disabled */
|
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
|
|
if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
|
|
|
|
|
disabled=1;
|
|
|
|
|
|
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not just the
keyid. This is for speed since there is no need to re-fetch a key when we
already have that key handy. Cache the result of the check so we don't
need to hit the trustdb more than once.
* getkey.c (skip_disabled): New function to get a pk and call is_disabled
on it. (key_byname): Use it here.
* packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New
"pk_is_disabled" macro to retrieve the cached disabled value if available,
and fill it in via cache_disabled_value if not available.
* trustdb.c (get_validity): Cache the disabled value since we have it
handy and it might be useful later.
* parse-packet.c (parse_key): Clear disabled flag when parsing a new key.
Just in case someone forgets to clear the whole key.
* getkey.c (merge_selfsigs_main): Add an "if all else fails" path for
setting a single user ID primary when there are multiple set primaries all
at the same second, or no primaries set and the most recent user IDs are
at the same second, or no signed user IDs at all. This is arbitrary, but
deterministic.
* exec.h, photoid.h: Add copyright message.
* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings. This is for
consistency with --show-photos.
* main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump
attribs if --attrib-fd is set when verifying signatures.
* g10.c (main): New --gnupg option to disable the various --openpgp,
--pgpX, etc. options. This is the same as --no-XXXX for those options.
* revoke.c (ask_revocation_reason): Clear old reason if user elects to
repeat question. This is bug 153.
* keyedit.c (sign_uids): Show keyid of the key making the signature.
2003-05-21 18:42:22 +02:00
|
|
|
|
/* Cache it for later so we don't need to look at the trustdb every
|
|
|
|
|
time */
|
|
|
|
|
if(disabled)
|
|
|
|
|
pk->is_disabled=2;
|
|
|
|
|
else
|
|
|
|
|
pk->is_disabled=1;
|
|
|
|
|
|
2002-12-26 23:22:50 +01:00
|
|
|
|
leave:
|
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not just the
keyid. This is for speed since there is no need to re-fetch a key when we
already have that key handy. Cache the result of the check so we don't
need to hit the trustdb more than once.
* getkey.c (skip_disabled): New function to get a pk and call is_disabled
on it. (key_byname): Use it here.
* packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New
"pk_is_disabled" macro to retrieve the cached disabled value if available,
and fill it in via cache_disabled_value if not available.
* trustdb.c (get_validity): Cache the disabled value since we have it
handy and it might be useful later.
* parse-packet.c (parse_key): Clear disabled flag when parsing a new key.
Just in case someone forgets to clear the whole key.
* getkey.c (merge_selfsigs_main): Add an "if all else fails" path for
setting a single user ID primary when there are multiple set primaries all
at the same second, or no primaries set and the most recent user IDs are
at the same second, or no signed user IDs at all. This is arbitrary, but
deterministic.
* exec.h, photoid.h: Add copyright message.
* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings. This is for
consistency with --show-photos.
* main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump
attribs if --attrib-fd is set when verifying signatures.
* g10.c (main): New --gnupg option to disable the various --openpgp,
--pgpX, etc. options. This is the same as --no-XXXX for those options.
* revoke.c (ask_revocation_reason): Clear old reason if user elects to
repeat question. This is bug 153.
* keyedit.c (sign_uids): Show keyid of the key making the signature.
2003-05-21 18:42:22 +02:00
|
|
|
|
return disabled;
|
2002-12-26 23:22:50 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-09-30 17:30:39 +02:00
|
|
|
|
void
|
|
|
|
|
check_trustdb_stale(void)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
2003-09-30 17:30:39 +02:00
|
|
|
|
static int did_nextcheck=0;
|
2003-04-30 07:33:52 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
init_trustdb ();
|
2003-01-15 18:07:54 +01:00
|
|
|
|
if (!did_nextcheck
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
&& (opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC))
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
ulong scheduled;
|
|
|
|
|
|
|
|
|
|
did_nextcheck = 1;
|
|
|
|
|
scheduled = tdbio_read_nextcheck ();
|
|
|
|
|
if (scheduled && scheduled <= make_timestamp ())
|
|
|
|
|
{
|
|
|
|
|
if (opt.no_auto_check_trustdb)
|
|
|
|
|
{
|
|
|
|
|
pending_check_trustdb = 1;
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 22:22:09 +02:00
|
|
|
|
log_info (_("please do a --check-trustdb\n"));
|
2002-06-29 15:46:34 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_info (_("checking the trustdb\n"));
|
|
|
|
|
validate_keys (0);
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-07-07 13:28:26 +02:00
|
|
|
|
}
|
2003-09-30 17:30:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Return the validity information for PK. If the namehash is not
|
|
|
|
|
* NULL, the validity of the corresponsing user ID is returned,
|
|
|
|
|
* otherwise, a reasonable value for the entire key is returned.
|
|
|
|
|
*/
|
|
|
|
|
unsigned int
|
|
|
|
|
get_validity (PKT_public_key *pk, PKT_user_id *uid)
|
|
|
|
|
{
|
|
|
|
|
TRUSTREC trec, vrec;
|
|
|
|
|
int rc;
|
|
|
|
|
ulong recno;
|
|
|
|
|
unsigned int validity;
|
|
|
|
|
u32 kid[2];
|
|
|
|
|
PKT_public_key *main_pk;
|
|
|
|
|
|
|
|
|
|
if(uid)
|
|
|
|
|
namehash_from_uid(uid);
|
|
|
|
|
|
|
|
|
|
init_trustdb ();
|
|
|
|
|
check_trustdb_stale();
|
1999-06-29 21:50:54 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
keyid_from_pk (pk, kid);
|
|
|
|
|
if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1])
|
|
|
|
|
{ /* this is a subkey - get the mainkey */
|
|
|
|
|
main_pk = m_alloc_clear (sizeof *main_pk);
|
|
|
|
|
rc = get_pubkey (main_pk, pk->main_keyid);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error ("error getting main key %08lX of subkey %08lX: %s\n",
|
|
|
|
|
(ulong)pk->main_keyid[1], (ulong)kid[1], g10_errstr(rc));
|
|
|
|
|
validity = TRUST_UNKNOWN;
|
|
|
|
|
goto leave;
|
1999-07-07 13:28:26 +02:00
|
|
|
|
}
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else
|
|
|
|
|
main_pk = pk;
|
|
|
|
|
|
|
|
|
|
rc = read_trust_record (main_pk, &trec);
|
|
|
|
|
if (rc && rc != -1)
|
|
|
|
|
{
|
|
|
|
|
tdbio_invalid ();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (rc == -1) /* no record found */
|
|
|
|
|
{
|
|
|
|
|
validity = TRUST_UNKNOWN;
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* loop over all user IDs */
|
|
|
|
|
recno = trec.r.trust.validlist;
|
|
|
|
|
validity = 0;
|
|
|
|
|
while (recno)
|
|
|
|
|
{
|
|
|
|
|
read_record (recno, &vrec, RECTYPE_VALID);
|
2003-04-30 07:33:52 +02:00
|
|
|
|
|
|
|
|
|
if(uid)
|
|
|
|
|
{
|
|
|
|
|
/* If a user ID is given we return the validity for that
|
|
|
|
|
user ID ONLY. If the namehash is not found, then there
|
|
|
|
|
is no validity at all (i.e. the user ID wasn't
|
|
|
|
|
signed). */
|
|
|
|
|
if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0)
|
|
|
|
|
{
|
|
|
|
|
validity=(vrec.r.valid.validity & TRUST_MASK);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* If no namehash is given, we take the maximum validity
|
|
|
|
|
over all user IDs */
|
|
|
|
|
if ( validity < (vrec.r.valid.validity & TRUST_MASK) )
|
|
|
|
|
validity = (vrec.r.valid.validity & TRUST_MASK);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
recno = vrec.r.valid.next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) )
|
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not just the
keyid. This is for speed since there is no need to re-fetch a key when we
already have that key handy. Cache the result of the check so we don't
need to hit the trustdb more than once.
* getkey.c (skip_disabled): New function to get a pk and call is_disabled
on it. (key_byname): Use it here.
* packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New
"pk_is_disabled" macro to retrieve the cached disabled value if available,
and fill it in via cache_disabled_value if not available.
* trustdb.c (get_validity): Cache the disabled value since we have it
handy and it might be useful later.
* parse-packet.c (parse_key): Clear disabled flag when parsing a new key.
Just in case someone forgets to clear the whole key.
* getkey.c (merge_selfsigs_main): Add an "if all else fails" path for
setting a single user ID primary when there are multiple set primaries all
at the same second, or no primaries set and the most recent user IDs are
at the same second, or no signed user IDs at all. This is arbitrary, but
deterministic.
* exec.h, photoid.h: Add copyright message.
* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings. This is for
consistency with --show-photos.
* main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump
attribs if --attrib-fd is set when verifying signatures.
* g10.c (main): New --gnupg option to disable the various --openpgp,
--pgpX, etc. options. This is the same as --no-XXXX for those options.
* revoke.c (ask_revocation_reason): Clear old reason if user elects to
repeat question. This is bug 153.
* keyedit.c (sign_uids): Show keyid of the key making the signature.
2003-05-21 18:42:22 +02:00
|
|
|
|
{
|
|
|
|
|
validity |= TRUST_FLAG_DISABLED;
|
|
|
|
|
pk->is_disabled=2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pk->is_disabled=1;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
|
|
leave:
|
|
|
|
|
/* set some flags direct from the key */
|
|
|
|
|
if (main_pk->is_revoked)
|
|
|
|
|
validity |= TRUST_FLAG_REVOKED;
|
|
|
|
|
if (main_pk != pk && pk->is_revoked)
|
|
|
|
|
validity |= TRUST_FLAG_SUB_REVOKED;
|
|
|
|
|
/* Note: expiration is a trust value and not a flag - don't know why
|
|
|
|
|
* I initially designed it that way */
|
|
|
|
|
if (main_pk->has_expired || pk->has_expired)
|
|
|
|
|
validity = (validity & ~TRUST_MASK) | TRUST_EXPIRED;
|
|
|
|
|
|
|
|
|
|
if (pending_check_trustdb)
|
|
|
|
|
validity |= TRUST_FLAG_PENDING_CHECK;
|
|
|
|
|
|
|
|
|
|
if (main_pk != pk)
|
|
|
|
|
free_public_key (main_pk);
|
|
|
|
|
return validity;
|
1998-12-17 18:36:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
1999-03-11 16:42:06 +01:00
|
|
|
|
int
|
* armor.c (armor_filter): Comment about PGP's end of line tab problem.
* trustdb.h, trustdb.c (trust_letter): Make static. (get_ownertrust_info,
get_validity_info): Don't mask the trust level twice.
* trustdb.h, gpgv.c, trustdb.c (get_validity, get_validity_info),
keylist.c (list_keyblock_colon), keyedit.c (show_key_with_all_names_colon,
menu_revuid): Pass a user ID in rather than a namehash, so we only have to
do the hashing in one place.
* packet.h, pkclist.c (build_pk_list), free-packet.c
(release_public_key_parts): Remove unused namehash element for public
keys.
2003-01-11 04:57:00 +01:00
|
|
|
|
get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
|
1998-01-24 17:32:27 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
int trustlevel;
|
1998-01-24 17:32:27 +01:00
|
|
|
|
|
* armor.c (armor_filter): Comment about PGP's end of line tab problem.
* trustdb.h, trustdb.c (trust_letter): Make static. (get_ownertrust_info,
get_validity_info): Don't mask the trust level twice.
* trustdb.h, gpgv.c, trustdb.c (get_validity, get_validity_info),
keylist.c (list_keyblock_colon), keyedit.c (show_key_with_all_names_colon,
menu_revuid): Pass a user ID in rather than a namehash, so we only have to
do the hashing in one place.
* packet.h, pkclist.c (build_pk_list), free-packet.c
(release_public_key_parts): Remove unused namehash element for public
keys.
2003-01-11 04:57:00 +01:00
|
|
|
|
trustlevel = get_validity (pk, uid);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if( trustlevel & TRUST_FLAG_REVOKED )
|
|
|
|
|
return 'r';
|
2003-01-11 22:13:41 +01:00
|
|
|
|
return trust_letter ( trustlevel );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
get_validity_string (PKT_public_key *pk, PKT_user_id *uid)
|
|
|
|
|
{
|
|
|
|
|
int trustlevel;
|
|
|
|
|
|
|
|
|
|
trustlevel = get_validity (pk, uid);
|
|
|
|
|
if( trustlevel & TRUST_FLAG_REVOKED )
|
|
|
|
|
return _("revoked");
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
return trust_value_to_string(trustlevel);
|
1999-07-07 13:28:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
2003-01-06 23:56:08 +01:00
|
|
|
|
static void
|
|
|
|
|
get_validity_counts (PKT_public_key *pk, PKT_user_id *uid)
|
|
|
|
|
{
|
|
|
|
|
TRUSTREC trec, vrec;
|
|
|
|
|
ulong recno;
|
|
|
|
|
|
|
|
|
|
if(pk==NULL || uid==NULL)
|
|
|
|
|
BUG();
|
|
|
|
|
|
2003-01-14 19:13:22 +01:00
|
|
|
|
namehash_from_uid(uid);
|
1998-10-01 09:23:00 +02:00
|
|
|
|
|
2003-01-06 23:56:08 +01:00
|
|
|
|
uid->help_marginal_count=uid->help_full_count=0;
|
1998-10-01 09:23:00 +02:00
|
|
|
|
|
2003-01-06 23:56:08 +01:00
|
|
|
|
init_trustdb ();
|
|
|
|
|
|
|
|
|
|
if(read_trust_record (pk, &trec)!=0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* loop over all user IDs */
|
|
|
|
|
recno = trec.r.trust.validlist;
|
|
|
|
|
while (recno)
|
|
|
|
|
{
|
|
|
|
|
read_record (recno, &vrec, RECTYPE_VALID);
|
|
|
|
|
|
2003-01-14 19:13:22 +01:00
|
|
|
|
if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0)
|
2003-01-06 23:56:08 +01:00
|
|
|
|
{
|
|
|
|
|
uid->help_marginal_count=vrec.r.valid.marginal_count;
|
|
|
|
|
uid->help_full_count=vrec.r.valid.full_count;
|
|
|
|
|
/* printf("Fetched marginal %d, full %d\n",uid->help_marginal_count,uid->help_full_count); */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recno = vrec.r.valid.next;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-06-29 21:50:54 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
void
|
|
|
|
|
list_trust_path( const char *username )
|
1998-10-12 22:16:38 +02:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
1999-07-01 12:53:35 +02:00
|
|
|
|
/****************
|
2002-06-29 15:46:34 +02:00
|
|
|
|
* Enumerate all keys, which are needed to build all trust paths for
|
|
|
|
|
* the given key. This function does not return the key itself or
|
|
|
|
|
* the ultimate key (the last point in cerificate chain). Only
|
|
|
|
|
* certificate chains which ends up at an ultimately trusted key
|
|
|
|
|
* are listed. If ownertrust or validity is not NULL, the corresponding
|
|
|
|
|
* value for the returned LID is also returned in these variable(s).
|
|
|
|
|
*
|
|
|
|
|
* 1) create a void pointer and initialize it to NULL
|
|
|
|
|
* 2) pass this void pointer by reference to this function.
|
|
|
|
|
* Set lid to the key you want to enumerate and pass it by reference.
|
|
|
|
|
* 3) call this function as long as it does not return -1
|
|
|
|
|
* to indicate EOF. LID does contain the next key used to build the web
|
|
|
|
|
* 4) Always call this function a last time with LID set to NULL,
|
|
|
|
|
* so that it can free its context.
|
|
|
|
|
*
|
|
|
|
|
* Returns: -1 on EOF or the level of the returned LID
|
1999-07-01 12:53:35 +02:00
|
|
|
|
*/
|
|
|
|
|
int
|
2002-06-29 15:46:34 +02:00
|
|
|
|
enum_cert_paths( void **context, ulong *lid,
|
|
|
|
|
unsigned *ownertrust, unsigned *validity )
|
1999-07-07 13:28:26 +02:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return -1;
|
1999-07-07 13:28:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
1998-10-12 22:16:38 +02:00
|
|
|
|
|
1999-06-29 21:50:54 +02:00
|
|
|
|
/****************
|
2002-06-29 15:46:34 +02:00
|
|
|
|
* Print the current path
|
1999-06-29 21:50:54 +02:00
|
|
|
|
*/
|
|
|
|
|
void
|
2002-06-29 15:46:34 +02:00
|
|
|
|
enum_cert_paths_print( void **context, FILE *fp,
|
|
|
|
|
int refresh, ulong selected_lid )
|
1999-06-29 21:50:54 +02:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
|
|
/****************************************
|
|
|
|
|
*********** NEW NEW NEW ****************
|
|
|
|
|
****************************************/
|
1999-06-29 21:50:54 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static int
|
2002-10-30 04:11:57 +01:00
|
|
|
|
ask_ownertrust (u32 *kid,int minimum)
|
1999-06-29 21:50:54 +02:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
PKT_public_key *pk;
|
|
|
|
|
int rc;
|
|
|
|
|
int ot;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
pk = m_alloc_clear (sizeof *pk);
|
|
|
|
|
rc = get_pubkey (pk, kid);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("public key %08lX not found: %s\n"),
|
|
|
|
|
(ulong)kid[1], g10_errstr(rc) );
|
|
|
|
|
return TRUST_UNKNOWN;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
2002-11-07 05:37:27 +01:00
|
|
|
|
if(opt.force_ownertrust)
|
|
|
|
|
{
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
log_info("force trust for key %08lX%08lX to %s\n",
|
|
|
|
|
(ulong)kid[0],(ulong)kid[1],
|
|
|
|
|
trust_value_to_string(opt.force_ownertrust));
|
2002-11-07 05:37:27 +01:00
|
|
|
|
update_ownertrust(pk,opt.force_ownertrust);
|
|
|
|
|
ot=opt.force_ownertrust;
|
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else
|
2002-11-07 05:37:27 +01:00
|
|
|
|
{
|
|
|
|
|
ot=edit_ownertrust(pk,0);
|
|
|
|
|
if(ot>0)
|
|
|
|
|
ot = get_ownertrust (pk);
|
|
|
|
|
else if(ot==0)
|
|
|
|
|
ot = minimum?minimum:TRUST_UNDEFINED;
|
|
|
|
|
else
|
|
|
|
|
ot = -1; /* quit */
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
free_public_key( pk );
|
2002-10-30 04:11:57 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return ot;
|
1999-06-29 21:50:54 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static void
|
|
|
|
|
mark_keyblock_seen (KeyHashTable tbl, KBNODE node)
|
1998-10-12 22:16:38 +02:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for ( ;node; node = node->next )
|
|
|
|
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY
|
2003-01-06 23:56:08 +01:00
|
|
|
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
u32 aki[2];
|
1999-07-07 13:28:26 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
keyid_from_pk (node->pkt->pkt.public_key, aki);
|
|
|
|
|
add_key_hash_table (tbl, aki);
|
|
|
|
|
}
|
1998-10-25 20:00:01 +01:00
|
|
|
|
}
|
|
|
|
|
|
1998-10-12 22:16:38 +02:00
|
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
|
static void
|
2002-06-29 15:46:34 +02:00
|
|
|
|
dump_key_array (int depth, struct key_array *keys)
|
|
|
|
|
{
|
|
|
|
|
struct key_array *kar;
|
|
|
|
|
|
|
|
|
|
for (kar=keys; kar->keyblock; kar++)
|
|
|
|
|
{
|
|
|
|
|
KBNODE node = kar->keyblock;
|
|
|
|
|
u32 kid[2];
|
|
|
|
|
|
|
|
|
|
keyid_from_pk(node->pkt->pkt.public_key, kid);
|
|
|
|
|
printf ("%d:%08lX%08lX:K::%c::::\n",
|
|
|
|
|
depth, (ulong)kid[0], (ulong)kid[1], '?');
|
|
|
|
|
|
|
|
|
|
for (; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID)
|
|
|
|
|
{
|
|
|
|
|
int len = node->pkt->pkt.user_id->len;
|
|
|
|
|
|
|
|
|
|
if (len > 30)
|
|
|
|
|
len = 30;
|
|
|
|
|
printf ("%d:%08lX%08lX:U:::%c:::",
|
|
|
|
|
depth, (ulong)kid[0], (ulong)kid[1],
|
|
|
|
|
(node->flag & 4)? 'f':
|
|
|
|
|
(node->flag & 2)? 'm':
|
|
|
|
|
(node->flag & 1)? 'q':'-');
|
|
|
|
|
print_string (stdout, node->pkt->pkt.user_id->name, len, ':');
|
|
|
|
|
putchar (':');
|
|
|
|
|
putchar ('\n');
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-03-17 13:13:04 +01:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
}
|
1999-07-01 12:53:35 +02:00
|
|
|
|
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
1998-10-12 22:16:38 +02:00
|
|
|
|
static void
|
2003-01-06 23:56:08 +01:00
|
|
|
|
store_validation_status (int depth, KBNODE keyblock, KeyHashTable stored)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int status;
|
|
|
|
|
int any = 0;
|
|
|
|
|
|
|
|
|
|
for (node=keyblock; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID)
|
|
|
|
|
{
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
if (node->flag & 4)
|
|
|
|
|
status = TRUST_FULLY;
|
|
|
|
|
else if (node->flag & 2)
|
|
|
|
|
status = TRUST_MARGINAL;
|
|
|
|
|
else if (node->flag & 1)
|
|
|
|
|
status = TRUST_UNDEFINED;
|
|
|
|
|
else
|
|
|
|
|
status = 0;
|
|
|
|
|
|
|
|
|
|
if (status)
|
|
|
|
|
{
|
|
|
|
|
update_validity (keyblock->pkt->pkt.public_key,
|
2003-01-06 23:56:08 +01:00
|
|
|
|
uid, depth, status);
|
|
|
|
|
|
|
|
|
|
mark_keyblock_seen(stored,keyblock);
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
any = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-03-17 13:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (any)
|
|
|
|
|
do_sync ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* check whether the signature sig is in the klist k
|
1999-03-17 13:13:04 +01:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static struct key_item *
|
|
|
|
|
is_in_klist (struct key_item *k, PKT_signature *sig)
|
1998-10-12 22:16:38 +02:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (; k; k = k->next)
|
|
|
|
|
{
|
|
|
|
|
if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1])
|
|
|
|
|
return k;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return NULL;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
1998-11-05 19:00:08 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Mark the signature of the given UID which are used to certify it.
|
|
|
|
|
* To do this, we first revmove all signatures which are not valid and
|
|
|
|
|
* from the remain ones we look for the latest one. If this is not a
|
|
|
|
|
* certification revocation signature we mark the signature by setting
|
|
|
|
|
* node flag bit 8. Note that flag bits 9 and 10 are used for internal
|
|
|
|
|
* purposes.
|
1999-03-11 16:42:06 +01:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static void
|
|
|
|
|
mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
|
|
|
|
|
u32 *main_kid, struct key_item *klist,
|
|
|
|
|
u32 curtime, u32 *next_expire)
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
PKT_signature *sig;
|
|
|
|
|
|
|
|
|
|
/* first check all signatures */
|
|
|
|
|
for (node=uidnode->next; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
node->flag &= ~(1<<8 | 1<<9 | 1<<10);
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID
|
|
|
|
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
|
|
|
|
break; /* ready */
|
|
|
|
|
if (node->pkt->pkttype != PKT_SIGNATURE)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
sig = node->pkt->pkt.signature;
|
|
|
|
|
if (sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
|
|
|
|
|
continue; /* ignore self-signatures */
|
|
|
|
|
if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
|
|
|
|
|
continue; /* we only look at these signature classes */
|
|
|
|
|
if (!is_in_klist (klist, sig))
|
|
|
|
|
continue; /* no need to check it then */
|
|
|
|
|
if (check_key_signature (keyblock, node, NULL))
|
|
|
|
|
continue; /* ignore invalid signatures */
|
|
|
|
|
node->flag |= 1<<9;
|
|
|
|
|
}
|
|
|
|
|
/* reset the remaining flags */
|
|
|
|
|
for (; node; node = node->next)
|
|
|
|
|
node->flag &= ~(1<<8 | 1<<9 | 1 << 10);
|
|
|
|
|
|
|
|
|
|
/* kbnode flag usage: bit 9 is here set for signatures to consider,
|
|
|
|
|
* bit 10 will be set by the loop to keep track of keyIDs already
|
|
|
|
|
* processed, bit 8 will be set for the usable signatures */
|
|
|
|
|
|
|
|
|
|
/* for each cert figure out the latest valid one */
|
|
|
|
|
for (node=uidnode->next; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
KBNODE n, signode;
|
|
|
|
|
u32 kid[2];
|
|
|
|
|
u32 sigdate;
|
|
|
|
|
|
|
|
|
|
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
|
|
|
|
break;
|
|
|
|
|
if ( !(node->flag & (1<<9)) )
|
|
|
|
|
continue; /* not a node to look at */
|
|
|
|
|
if ( (node->flag & (1<<10)) )
|
|
|
|
|
continue; /* signature with a keyID already processed */
|
|
|
|
|
node->flag |= (1<<10); /* mark this node as processed */
|
|
|
|
|
sig = node->pkt->pkt.signature;
|
|
|
|
|
signode = node;
|
|
|
|
|
sigdate = sig->timestamp;
|
|
|
|
|
kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
|
|
|
|
|
for (n=uidnode->next; n; n = n->next)
|
|
|
|
|
{
|
|
|
|
|
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
|
|
|
|
break;
|
|
|
|
|
if ( !(n->flag & (1<<9)) )
|
|
|
|
|
continue;
|
|
|
|
|
if ( (n->flag & (1<<10)) )
|
|
|
|
|
continue; /* shortcut already processed signatures */
|
|
|
|
|
sig = n->pkt->pkt.signature;
|
|
|
|
|
if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1])
|
|
|
|
|
continue;
|
|
|
|
|
n->flag |= (1<<10); /* mark this node as processed */
|
|
|
|
|
|
|
|
|
|
/* If signode is nonrevocable and unexpired and n isn't,
|
|
|
|
|
then take signode (skip). It doesn't matter which is
|
|
|
|
|
older: if signode was older then we don't want to take n
|
|
|
|
|
as signode is nonrevocable. If n was older then we're
|
|
|
|
|
automatically fine. */
|
|
|
|
|
|
|
|
|
|
if(((IS_UID_SIG(signode->pkt->pkt.signature) &&
|
|
|
|
|
!signode->pkt->pkt.signature->flags.revocable &&
|
|
|
|
|
(signode->pkt->pkt.signature->expiredate==0 ||
|
|
|
|
|
signode->pkt->pkt.signature->expiredate>curtime))) &&
|
|
|
|
|
(!(IS_UID_SIG(n->pkt->pkt.signature) &&
|
|
|
|
|
!n->pkt->pkt.signature->flags.revocable &&
|
|
|
|
|
(n->pkt->pkt.signature->expiredate==0 ||
|
|
|
|
|
n->pkt->pkt.signature->expiredate>curtime))))
|
|
|
|
|
continue;
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* If n is nonrevocable and unexpired and signode isn't,
|
|
|
|
|
then take n. Again, it doesn't matter which is older: if
|
|
|
|
|
n was older then we don't want to take signode as n is
|
|
|
|
|
nonrevocable. If signode was older then we're
|
|
|
|
|
automatically fine. */
|
|
|
|
|
|
|
|
|
|
if((!(IS_UID_SIG(signode->pkt->pkt.signature) &&
|
|
|
|
|
!signode->pkt->pkt.signature->flags.revocable &&
|
|
|
|
|
(signode->pkt->pkt.signature->expiredate==0 ||
|
|
|
|
|
signode->pkt->pkt.signature->expiredate>curtime))) &&
|
|
|
|
|
((IS_UID_SIG(n->pkt->pkt.signature) &&
|
|
|
|
|
!n->pkt->pkt.signature->flags.revocable &&
|
|
|
|
|
(n->pkt->pkt.signature->expiredate==0 ||
|
|
|
|
|
n->pkt->pkt.signature->expiredate>curtime))))
|
|
|
|
|
{
|
|
|
|
|
signode = n;
|
|
|
|
|
sigdate = sig->timestamp;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* At this point, if it's newer, it goes in as the only
|
|
|
|
|
remaining possibilities are signode and n are both either
|
|
|
|
|
revocable or expired or both nonrevocable and unexpired.
|
|
|
|
|
If the timestamps are equal take the later ordered
|
|
|
|
|
packet, presuming that the key packets are hopefully in
|
|
|
|
|
their original order. */
|
|
|
|
|
|
|
|
|
|
if (sig->timestamp >= sigdate)
|
|
|
|
|
{
|
|
|
|
|
signode = n;
|
|
|
|
|
sigdate = sig->timestamp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sig = signode->pkt->pkt.signature;
|
|
|
|
|
if (IS_UID_SIG (sig))
|
|
|
|
|
{ /* this seems to be a usable one which is not revoked.
|
|
|
|
|
* Just need to check whether there is an expiration time,
|
|
|
|
|
* We do the expired certification after finding a suitable
|
|
|
|
|
* certification, the assumption is that a signator does not
|
|
|
|
|
* want that after the expiration of his certificate the
|
|
|
|
|
* system falls back to an older certification which has a
|
|
|
|
|
* different expiration time */
|
|
|
|
|
const byte *p;
|
|
|
|
|
u32 expire;
|
|
|
|
|
|
|
|
|
|
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL );
|
|
|
|
|
expire = p? sig->timestamp + buffer_to_u32(p) : 0;
|
|
|
|
|
|
|
|
|
|
if (expire==0 || expire > curtime )
|
|
|
|
|
{
|
|
|
|
|
signode->flag |= (1<<8); /* yeah, found a good cert */
|
|
|
|
|
if (expire && expire < *next_expire)
|
|
|
|
|
*next_expire = expire;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-11-03 20:38:58 +01:00
|
|
|
|
}
|
1998-10-12 22:16:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
2002-10-30 04:11:57 +01:00
|
|
|
|
/* Used by validate_one_keyblock to confirm a regexp within a trust
|
|
|
|
|
signature. Returns 1 for match, and 0 for no match or regex
|
|
|
|
|
error. */
|
|
|
|
|
static int
|
|
|
|
|
check_regexp(const char *exp,const char *string)
|
|
|
|
|
{
|
2003-03-24 21:05:53 +01:00
|
|
|
|
#ifdef DISABLE_REGEX
|
|
|
|
|
/* When DISABLE_REGEX is defined, assume all regexps do not
|
2002-10-30 04:11:57 +01:00
|
|
|
|
match. */
|
|
|
|
|
return 0;
|
2002-10-31 17:58:47 +01:00
|
|
|
|
#elif defined(__riscos__)
|
|
|
|
|
return riscos_check_regexp(exp, string, DBG_TRUST);
|
2002-10-30 04:11:57 +01:00
|
|
|
|
#else
|
|
|
|
|
int ret;
|
|
|
|
|
regex_t pat;
|
|
|
|
|
|
2002-10-31 00:40:05 +01:00
|
|
|
|
if(regcomp(&pat,exp,REG_ICASE|REG_NOSUB|REG_EXTENDED)!=0)
|
2002-10-30 04:11:57 +01:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ret=regexec(&pat,string,0,NULL,0);
|
|
|
|
|
|
|
|
|
|
regfree(&pat);
|
|
|
|
|
|
|
|
|
|
if(DBG_TRUST)
|
|
|
|
|
log_debug("regexp \"%s\" on \"%s\": %s\n",exp,string,ret==0?"YES":"NO");
|
|
|
|
|
|
|
|
|
|
return (ret==0);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
1998-10-12 22:16:38 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Return true if the key is signed by one of the keys in the given
|
|
|
|
|
* key ID list. User IDs with a valid signature are marked by node
|
|
|
|
|
* flags as follows:
|
|
|
|
|
* flag bit 0: There is at least one signature
|
|
|
|
|
* 1: There is marginal confidence that this is a legitimate uid
|
|
|
|
|
* 2: There is full confidence that this is a legitimate uid.
|
|
|
|
|
* 8: Used for internal purposes.
|
|
|
|
|
* 9: Ditto (in mark_usable_uid_certs())
|
|
|
|
|
* 10: Ditto (ditto)
|
|
|
|
|
* This function assumes that all kbnode flags are cleared on entry.
|
1998-11-03 20:38:58 +01:00
|
|
|
|
*/
|
1999-03-11 16:42:06 +01:00
|
|
|
|
static int
|
2002-06-29 15:46:34 +02:00
|
|
|
|
validate_one_keyblock (KBNODE kb, struct key_item *klist,
|
|
|
|
|
u32 curtime, u32 *next_expire)
|
|
|
|
|
{
|
|
|
|
|
struct key_item *kr;
|
|
|
|
|
KBNODE node, uidnode=NULL;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
PKT_user_id *uid=NULL;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
PKT_public_key *pk = kb->pkt->pkt.public_key;
|
|
|
|
|
u32 main_kid[2];
|
2003-01-06 23:56:08 +01:00
|
|
|
|
int issigned=0, any_signed = 0;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
|
|
keyid_from_pk(pk, main_kid);
|
|
|
|
|
for (node=kb; node; node = node->next)
|
|
|
|
|
{
|
2003-04-30 07:33:52 +02:00
|
|
|
|
/* A bit of discussion here: is it better for the web of trust
|
|
|
|
|
to be built among only self-signed uids? On the one hand, a
|
|
|
|
|
self-signed uid is a statement that the key owner definitely
|
|
|
|
|
intended that uid to be there, but on the other hand, a
|
|
|
|
|
signed (but not self-signed) uid does carry trust, of a sort,
|
|
|
|
|
even if it is a statement being made by people other than the
|
|
|
|
|
key owner "through" the uids on the key owner's key. I'm
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 16:30:07 +02:00
|
|
|
|
going with the latter. However, if the user ID was
|
|
|
|
|
explicitly revoked, or passively allowed to expire, that
|
|
|
|
|
should stop validity through the user ID until it is
|
|
|
|
|
resigned. -dshaw */
|
2003-04-30 07:33:52 +02:00
|
|
|
|
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 16:30:07 +02:00
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID
|
|
|
|
|
&& !node->pkt->pkt.user_id->is_revoked
|
|
|
|
|
&& !node->pkt->pkt.user_id->is_expired)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
if (uidnode && issigned)
|
|
|
|
|
{
|
2003-01-06 23:56:08 +01:00
|
|
|
|
if (uid->help_full_count >= opt.completes_needed
|
|
|
|
|
|| uid->help_marginal_count >= opt.marginals_needed )
|
2002-06-29 15:46:34 +02:00
|
|
|
|
uidnode->flag |= 4;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
else if (uid->help_full_count || uid->help_marginal_count)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
uidnode->flag |= 2;
|
|
|
|
|
uidnode->flag |= 1;
|
|
|
|
|
any_signed = 1;
|
|
|
|
|
}
|
|
|
|
|
uidnode = node;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
uid=uidnode->pkt->pkt.user_id;
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 16:30:07 +02:00
|
|
|
|
|
|
|
|
|
/* If the selfsig is going to expire... */
|
2003-04-30 07:33:52 +02:00
|
|
|
|
if(uid->expiredate && uid->expiredate<*next_expire)
|
|
|
|
|
*next_expire = uid->expiredate;
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 16:30:07 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
issigned = 0;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
get_validity_counts(pk,uid);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
mark_usable_uid_certs (kb, uidnode, main_kid, klist,
|
|
|
|
|
curtime, next_expire);
|
|
|
|
|
}
|
2003-04-30 07:33:52 +02:00
|
|
|
|
else if (node->pkt->pkttype == PKT_SIGNATURE
|
|
|
|
|
&& (node->flag & (1<<8)) && uid)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
2002-10-30 04:11:57 +01:00
|
|
|
|
/* Note that we are only seeing unrevoked sigs here */
|
2002-06-29 15:46:34 +02:00
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
|
|
|
|
|
kr = is_in_klist (klist, sig);
|
2002-10-30 04:11:57 +01:00
|
|
|
|
/* If the trust_regexp does not match, it's as if the sig
|
|
|
|
|
did not exist. This is safe for non-trust sigs as well
|
|
|
|
|
since we don't accept a regexp on the sig unless it's a
|
|
|
|
|
trust sig. */
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
if (kr && (kr->trust_regexp==NULL || opt.trust_model!=TM_PGP ||
|
2002-10-30 04:11:57 +01:00
|
|
|
|
(uidnode && check_regexp(kr->trust_regexp,
|
|
|
|
|
uidnode->pkt->pkt.user_id->name))))
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
if(DBG_TRUST && opt.trust_model==TM_PGP && sig->trust_depth)
|
2002-10-30 04:11:57 +01:00
|
|
|
|
log_debug("trust sig on %s, sig depth is %d, kr depth is %d\n",
|
|
|
|
|
uidnode->pkt->pkt.user_id->name,sig->trust_depth,
|
|
|
|
|
kr->trust_depth);
|
|
|
|
|
|
|
|
|
|
/* Are we part of a trust sig chain? We always favor
|
|
|
|
|
the latest trust sig, rather than the greater or
|
|
|
|
|
lesser trust sig or value. I could make a decent
|
|
|
|
|
argument for any of these cases, but this seems to be
|
|
|
|
|
what PGP does, and I'd like to be compatible. -dms */
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
if(opt.trust_model==TM_PGP && sig->trust_depth
|
2002-11-03 21:18:56 +01:00
|
|
|
|
&& pk->trust_timestamp<=sig->timestamp
|
|
|
|
|
&& (sig->trust_depth<=kr->trust_depth
|
|
|
|
|
|| kr->ownertrust==TRUST_ULTIMATE))
|
2002-10-30 04:11:57 +01:00
|
|
|
|
{
|
|
|
|
|
/* If we got here, we know that:
|
|
|
|
|
|
|
|
|
|
this is a trust sig.
|
|
|
|
|
|
|
|
|
|
it's a newer trust sig than any previous trust
|
|
|
|
|
sig on this key (not uid).
|
|
|
|
|
|
|
|
|
|
it is legal in that it was either generated by an
|
|
|
|
|
ultimate key, or a key that was part of a trust
|
|
|
|
|
chain, and the depth does not violate the
|
|
|
|
|
original trust sig.
|
|
|
|
|
|
|
|
|
|
if there is a regexp attached, it matched
|
|
|
|
|
successfully.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if(DBG_TRUST)
|
|
|
|
|
log_debug("replacing trust value %d with %d and "
|
|
|
|
|
"depth %d with %d\n",
|
|
|
|
|
pk->trust_value,sig->trust_value,
|
|
|
|
|
pk->trust_depth,sig->trust_depth);
|
|
|
|
|
|
|
|
|
|
pk->trust_value=sig->trust_value;
|
|
|
|
|
pk->trust_depth=sig->trust_depth-1;
|
|
|
|
|
|
|
|
|
|
/* If the trust sig contains a regexp, record it
|
|
|
|
|
on the pk for the next round. */
|
|
|
|
|
if(sig->trust_regexp)
|
|
|
|
|
pk->trust_regexp=sig->trust_regexp;
|
|
|
|
|
}
|
|
|
|
|
|
2003-01-06 23:56:08 +01:00
|
|
|
|
if (kr->ownertrust == TRUST_ULTIMATE)
|
|
|
|
|
uid->help_full_count = opt.completes_needed;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else if (kr->ownertrust == TRUST_FULLY)
|
2003-01-06 23:56:08 +01:00
|
|
|
|
uid->help_full_count++;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
else if (kr->ownertrust == TRUST_MARGINAL)
|
2003-01-06 23:56:08 +01:00
|
|
|
|
uid->help_marginal_count++;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
issigned = 1;
|
2002-10-30 04:11:57 +01:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
}
|
1998-10-12 22:16:38 +02:00
|
|
|
|
}
|
1998-11-05 19:00:08 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (uidnode && issigned)
|
|
|
|
|
{
|
2003-01-06 23:56:08 +01:00
|
|
|
|
if (uid->help_full_count >= opt.completes_needed
|
|
|
|
|
|| uid->help_marginal_count >= opt.marginals_needed )
|
2002-06-29 15:46:34 +02:00
|
|
|
|
uidnode->flag |= 4;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
else if (uid->help_full_count || uid->help_marginal_count)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
uidnode->flag |= 2;
|
|
|
|
|
uidnode->flag |= 1;
|
|
|
|
|
any_signed = 1;
|
1999-03-17 13:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return any_signed;
|
1998-10-12 22:16:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static int
|
2003-09-24 01:14:03 +02:00
|
|
|
|
search_skipfnc (void *opaque, u32 *kid, PKT_user_id *dummy)
|
1998-10-25 20:00:01 +01:00
|
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return test_key_hash_table ((KeyHashTable)opaque, kid);
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
1998-10-25 20:00:01 +01:00
|
|
|
|
|
1999-03-08 20:50:18 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Scan all keys and return a key_array of all suitable keys from
|
|
|
|
|
* kllist. The caller has to pass keydb handle so that we don't use
|
|
|
|
|
* to create our own. Returns either a key_array or NULL in case of
|
|
|
|
|
* an error. No results found are indicated by an empty array.
|
|
|
|
|
* Caller hast to release the returned array.
|
1999-03-11 16:42:06 +01:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static struct key_array *
|
2003-01-06 23:56:08 +01:00
|
|
|
|
validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
|
2002-06-29 15:46:34 +02:00
|
|
|
|
struct key_item *klist, u32 curtime, u32 *next_expire)
|
|
|
|
|
{
|
|
|
|
|
KBNODE keyblock = NULL;
|
|
|
|
|
struct key_array *keys = NULL;
|
|
|
|
|
size_t nkeys, maxkeys;
|
|
|
|
|
int rc;
|
|
|
|
|
KEYDB_SEARCH_DESC desc;
|
|
|
|
|
|
|
|
|
|
maxkeys = 1000;
|
|
|
|
|
keys = m_alloc ((maxkeys+1) * sizeof *keys);
|
|
|
|
|
nkeys = 0;
|
|
|
|
|
|
|
|
|
|
rc = keydb_search_reset (hd);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error ("keydb_search_reset failed: %s\n", g10_errstr(rc));
|
|
|
|
|
m_free (keys);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset (&desc, 0, sizeof desc);
|
|
|
|
|
desc.mode = KEYDB_SEARCH_MODE_FIRST;
|
|
|
|
|
desc.skipfnc = search_skipfnc;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
desc.skipfncvalue = full_trust;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
rc = keydb_search (hd, &desc, 1);
|
|
|
|
|
if (rc == -1)
|
|
|
|
|
{
|
|
|
|
|
keys[nkeys].keyblock = NULL;
|
|
|
|
|
return keys;
|
|
|
|
|
}
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error ("keydb_search_first failed: %s\n", g10_errstr(rc));
|
|
|
|
|
m_free (keys);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
PKT_public_key *pk;
|
|
|
|
|
|
|
|
|
|
rc = keydb_get_keyblock (hd, &keyblock);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
|
|
|
|
|
m_free (keys);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
|
|
|
|
|
{
|
|
|
|
|
log_debug ("ooops: invalid pkttype %d encountered\n",
|
|
|
|
|
keyblock->pkt->pkttype);
|
|
|
|
|
dump_kbnode (keyblock);
|
|
|
|
|
release_kbnode(keyblock);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2000-07-14 19:34:53 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* prepare the keyblock for further processing */
|
|
|
|
|
merge_keys_and_selfsig (keyblock);
|
|
|
|
|
clear_kbnode_flags (keyblock);
|
|
|
|
|
pk = keyblock->pkt->pkt.public_key;
|
|
|
|
|
if (pk->has_expired || pk->is_revoked)
|
|
|
|
|
{
|
|
|
|
|
/* it does not make sense to look further at those keys */
|
2003-01-06 23:56:08 +01:00
|
|
|
|
mark_keyblock_seen (full_trust, keyblock);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
}
|
|
|
|
|
else if (validate_one_keyblock (keyblock, klist, curtime, next_expire))
|
|
|
|
|
{
|
2003-01-06 23:56:08 +01:00
|
|
|
|
KBNODE node;
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (pk->expiredate && pk->expiredate >= curtime
|
|
|
|
|
&& pk->expiredate < *next_expire)
|
|
|
|
|
*next_expire = pk->expiredate;
|
|
|
|
|
|
|
|
|
|
if (nkeys == maxkeys) {
|
|
|
|
|
maxkeys += 1000;
|
|
|
|
|
keys = m_realloc (keys, (maxkeys+1) * sizeof *keys);
|
|
|
|
|
}
|
|
|
|
|
keys[nkeys++].keyblock = keyblock;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
|
|
|
|
|
/* Optimization - if all uids are fully trusted, then we
|
|
|
|
|
never need to consider this key as a candidate again. */
|
|
|
|
|
|
|
|
|
|
for (node=keyblock; node; node = node->next)
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & 4))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if(node==NULL)
|
|
|
|
|
mark_keyblock_seen (full_trust, keyblock);
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
keyblock = NULL;
|
|
|
|
|
}
|
1998-10-25 20:00:01 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
release_kbnode (keyblock);
|
|
|
|
|
keyblock = NULL;
|
|
|
|
|
}
|
|
|
|
|
while ( !(rc = keydb_search (hd, &desc, 1)) );
|
|
|
|
|
if (rc && rc != -1)
|
|
|
|
|
{
|
|
|
|
|
log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
|
|
|
|
|
m_free (keys);
|
|
|
|
|
return NULL;
|
1999-05-06 14:26:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
keys[nkeys].keyblock = NULL;
|
|
|
|
|
return keys;
|
|
|
|
|
}
|
1998-10-25 20:00:01 +01:00
|
|
|
|
|
2003-01-06 23:56:08 +01:00
|
|
|
|
/* Caller must sync */
|
2000-07-14 19:34:53 +02:00
|
|
|
|
static void
|
2003-01-06 23:56:08 +01:00
|
|
|
|
reset_trust_records (KEYDB_HANDLE hd, KeyHashTable exclude)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
{
|
|
|
|
|
int rc;
|
|
|
|
|
KBNODE keyblock = NULL;
|
|
|
|
|
KEYDB_SEARCH_DESC desc;
|
|
|
|
|
int count = 0, nreset = 0;
|
|
|
|
|
|
|
|
|
|
rc = keydb_search_reset (hd);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error ("keydb_search_reset failed: %s\n", g10_errstr(rc));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset (&desc, 0, sizeof desc);
|
|
|
|
|
desc.mode = KEYDB_SEARCH_MODE_FIRST;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
if(exclude)
|
|
|
|
|
{
|
|
|
|
|
desc.skipfnc = search_skipfnc;
|
|
|
|
|
desc.skipfncvalue = exclude;
|
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
rc = keydb_search (hd, &desc, 1);
|
|
|
|
|
if (rc && rc != -1 )
|
|
|
|
|
log_error ("keydb_search_first failed: %s\n", g10_errstr(rc));
|
|
|
|
|
else if (!rc)
|
|
|
|
|
{
|
|
|
|
|
desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
rc = keydb_get_keyblock (hd, &keyblock);
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
|
|
if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) /* paranoid assertion*/
|
|
|
|
|
{
|
|
|
|
|
nreset += clear_validity (keyblock->pkt->pkt.public_key);
|
|
|
|
|
release_kbnode (keyblock);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while ( !(rc = keydb_search (hd, &desc, 1)) );
|
|
|
|
|
if (rc && rc != -1)
|
|
|
|
|
log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
|
1998-11-03 20:38:58 +01:00
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (opt.verbose)
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 22:22:09 +02:00
|
|
|
|
log_info (_("%d keys processed (%d validity counts cleared)\n"),
|
2002-06-29 15:46:34 +02:00
|
|
|
|
count, nreset);
|
2003-01-06 23:56:08 +01:00
|
|
|
|
}
|
1999-03-11 16:42:06 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/*
|
|
|
|
|
* Run the key validation procedure.
|
1999-03-11 16:42:06 +01:00
|
|
|
|
*
|
2002-06-29 15:46:34 +02:00
|
|
|
|
* This works this way:
|
|
|
|
|
* Step 1: Find all ultimately trusted keys (UTK).
|
|
|
|
|
* mark them all as seen and put them into klist.
|
|
|
|
|
* Step 2: loop max_cert_times
|
|
|
|
|
* Step 3: if OWNERTRUST of any key in klist is undefined
|
|
|
|
|
* ask user to assign ownertrust
|
|
|
|
|
* Step 4: Loop over all keys in the keyDB which are not marked seen
|
|
|
|
|
* Step 5: if key is revoked or expired
|
|
|
|
|
* mark key as seen
|
|
|
|
|
* continue loop at Step 4
|
|
|
|
|
* Step 6: For each user ID of that key signed by a key in klist
|
|
|
|
|
* Calculate validity by counting trusted signatures.
|
|
|
|
|
* Set validity of user ID
|
|
|
|
|
* Step 7: If any signed user ID was found
|
|
|
|
|
* mark key as seen
|
|
|
|
|
* End Loop
|
|
|
|
|
* Step 8: Build a new klist from all fully trusted keys from step 6
|
|
|
|
|
* End Loop
|
|
|
|
|
* Ready
|
1999-03-11 16:42:06 +01:00
|
|
|
|
*
|
1998-01-13 20:04:23 +01:00
|
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
|
static int
|
|
|
|
|
validate_keys (int interactive)
|
|
|
|
|
{
|
|
|
|
|
int rc = 0;
|
|
|
|
|
int quit=0;
|
|
|
|
|
struct key_item *klist = NULL;
|
|
|
|
|
struct key_item *k;
|
|
|
|
|
struct key_array *keys = NULL;
|
|
|
|
|
struct key_array *kar;
|
|
|
|
|
KEYDB_HANDLE kdb = NULL;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int depth;
|
|
|
|
|
int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate;
|
2003-01-06 23:56:08 +01:00
|
|
|
|
KeyHashTable stored,used,full_trust;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
u32 start_time, next_expire;
|
|
|
|
|
|
|
|
|
|
start_time = make_timestamp ();
|
|
|
|
|
next_expire = 0xffffffff; /* set next expire to the year 2106 */
|
2003-01-06 23:56:08 +01:00
|
|
|
|
stored = new_key_hash_table ();
|
|
|
|
|
used = new_key_hash_table ();
|
|
|
|
|
full_trust = new_key_hash_table ();
|
2003-11-30 01:33:27 +01:00
|
|
|
|
|
|
|
|
|
kdb = keydb_new (0);
|
|
|
|
|
reset_trust_records (kdb,NULL);
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* Fixme: Instead of always building a UTK list, we could just build it
|
|
|
|
|
* here when needed */
|
|
|
|
|
if (!utk_list)
|
|
|
|
|
{
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 22:22:09 +02:00
|
|
|
|
log_info (_("no ultimately trusted keys found\n"));
|
2002-06-29 15:46:34 +02:00
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
|
2003-01-06 23:56:08 +01:00
|
|
|
|
/* mark all UTKs as used and fully_trusted and set validity to
|
|
|
|
|
ultimate */
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (k=utk_list; k; k = k->next)
|
|
|
|
|
{
|
|
|
|
|
KBNODE keyblock;
|
|
|
|
|
PKT_public_key *pk;
|
|
|
|
|
|
|
|
|
|
keyblock = get_pubkeyblock (k->kid);
|
|
|
|
|
if (!keyblock)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("public key of ultimately"
|
|
|
|
|
" trusted key %08lX not found\n"), (ulong)k->kid[1]);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2003-01-06 23:56:08 +01:00
|
|
|
|
mark_keyblock_seen (used, keyblock);
|
|
|
|
|
mark_keyblock_seen (stored, keyblock);
|
|
|
|
|
mark_keyblock_seen (full_trust, keyblock);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
pk = keyblock->pkt->pkt.public_key;
|
|
|
|
|
for (node=keyblock; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID)
|
2003-01-06 23:56:08 +01:00
|
|
|
|
update_validity (pk, node->pkt->pkt.user_id, 0, TRUST_ULTIMATE);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
}
|
|
|
|
|
if ( pk->expiredate && pk->expiredate >= start_time
|
|
|
|
|
&& pk->expiredate < next_expire)
|
|
|
|
|
next_expire = pk->expiredate;
|
|
|
|
|
|
|
|
|
|
release_kbnode (keyblock);
|
|
|
|
|
do_sync ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
klist = utk_list;
|
|
|
|
|
|
2002-12-04 07:06:56 +01:00
|
|
|
|
log_info(_("%d marginal(s) needed, %d complete(s) needed, %s trust model\n"),
|
2003-04-26 22:38:16 +02:00
|
|
|
|
opt.marginals_needed,opt.completes_needed,trust_model_string());
|
2002-12-04 07:06:56 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (depth=0; depth < opt.max_cert_depth; depth++)
|
|
|
|
|
{
|
2003-09-24 05:48:55 +02:00
|
|
|
|
int valids=0,key_count;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* See whether we should assign ownertrust values to the keys in
|
2003-09-24 05:48:55 +02:00
|
|
|
|
klist. */
|
2002-06-29 15:46:34 +02:00
|
|
|
|
ot_unknown = ot_undefined = ot_never = 0;
|
|
|
|
|
ot_marginal = ot_full = ot_ultimate = 0;
|
|
|
|
|
for (k=klist; k; k = k->next)
|
|
|
|
|
{
|
2002-10-30 04:11:57 +01:00
|
|
|
|
int min=0;
|
|
|
|
|
|
|
|
|
|
/* 120 and 60 are as per RFC2440 */
|
|
|
|
|
if(k->trust_value>=120)
|
|
|
|
|
min=TRUST_FULLY;
|
|
|
|
|
else if(k->trust_value>=60)
|
|
|
|
|
min=TRUST_MARGINAL;
|
|
|
|
|
|
|
|
|
|
if(min!=k->min_ownertrust)
|
|
|
|
|
update_min_ownertrust(k->kid,min);
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (interactive && k->ownertrust == TRUST_UNKNOWN)
|
|
|
|
|
{
|
2002-10-30 04:11:57 +01:00
|
|
|
|
k->ownertrust = ask_ownertrust (k->kid,min);
|
|
|
|
|
|
|
|
|
|
if (k->ownertrust == -1)
|
|
|
|
|
{
|
|
|
|
|
quit=1;
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
1999-03-11 16:42:06 +01:00
|
|
|
|
}
|
2002-10-30 04:11:57 +01:00
|
|
|
|
|
|
|
|
|
/* This can happen during transition from an old trustdb
|
|
|
|
|
before trust sigs. It can also happen if a user uses two
|
2002-11-03 21:18:56 +01:00
|
|
|
|
different versions of GnuPG or changes the --trust-model
|
|
|
|
|
setting. */
|
2002-10-30 04:11:57 +01:00
|
|
|
|
if(k->ownertrust<min)
|
|
|
|
|
{
|
|
|
|
|
if(DBG_TRUST)
|
|
|
|
|
log_debug("key %08lX: "
|
|
|
|
|
"overriding ownertrust \"%s\" with \"%s\"\n",
|
|
|
|
|
(ulong)k->kid[1],
|
* tdbio.c (create_version_record): Only create new trustdbs with
TM_CLASSIC or TM_PGP.
* trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
get_validity_string, ask_ownertrust, validate_keys), pkclist.c
(do_edit_ownertrust): Rename trust_string to trust_value_to_string for
naming consistency.
* trustdb.h, trustdb.c (string_to_trust_value): New function to translate
a string to a trust value.
* g10.c (main): Use string_to_trust_value here for --force-ownertrust.
* options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb,
check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An
"OpenPGP" trust model is misleading since there is no official OpenPGP
trust model. Use "PGP" instead.
2003-05-01 23:37:08 +02:00
|
|
|
|
trust_value_to_string(k->ownertrust),
|
|
|
|
|
trust_value_to_string(min));
|
2002-10-30 04:11:57 +01:00
|
|
|
|
|
|
|
|
|
k->ownertrust=min;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (k->ownertrust == TRUST_UNKNOWN)
|
2002-06-29 15:46:34 +02:00
|
|
|
|
ot_unknown++;
|
|
|
|
|
else if (k->ownertrust == TRUST_UNDEFINED)
|
|
|
|
|
ot_undefined++;
|
|
|
|
|
else if (k->ownertrust == TRUST_NEVER)
|
|
|
|
|
ot_never++;
|
|
|
|
|
else if (k->ownertrust == TRUST_MARGINAL)
|
|
|
|
|
ot_marginal++;
|
|
|
|
|
else if (k->ownertrust == TRUST_FULLY)
|
|
|
|
|
ot_full++;
|
|
|
|
|
else if (k->ownertrust == TRUST_ULTIMATE)
|
|
|
|
|
ot_ultimate++;
|
2003-09-24 05:48:55 +02:00
|
|
|
|
|
|
|
|
|
valids++;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
}
|
1999-03-08 20:50:18 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
/* Find all keys which are signed by a key in kdlist */
|
2003-01-06 23:56:08 +01:00
|
|
|
|
keys = validate_key_list (kdb, full_trust, klist,
|
|
|
|
|
start_time, &next_expire);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (!keys)
|
|
|
|
|
{
|
|
|
|
|
log_error ("validate_key_list failed\n");
|
|
|
|
|
rc = G10ERR_GENERAL;
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
1998-10-16 18:00:17 +02:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
for (key_count=0, kar=keys; kar->keyblock; kar++, key_count++)
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
/* Store the calculated valididation status somewhere */
|
|
|
|
|
if (opt.verbose > 1)
|
|
|
|
|
dump_key_array (depth, keys);
|
|
|
|
|
|
2003-01-06 23:56:08 +01:00
|
|
|
|
for (kar=keys; kar->keyblock; kar++)
|
|
|
|
|
store_validation_status (depth, kar->keyblock, stored);
|
|
|
|
|
|
2003-09-24 05:48:55 +02:00
|
|
|
|
log_info (_("depth: %d valid: %3d signed: %3d"
|
|
|
|
|
" trust: %d-, %dq, %dn, %dm, %df, %du\n"),
|
|
|
|
|
depth, valids, key_count, ot_unknown, ot_undefined,
|
2002-06-29 15:46:34 +02:00
|
|
|
|
ot_never, ot_marginal, ot_full, ot_ultimate );
|
|
|
|
|
|
|
|
|
|
/* Build a new kdlist from all fully valid keys in KEYS */
|
|
|
|
|
if (klist != utk_list)
|
|
|
|
|
release_key_items (klist);
|
|
|
|
|
klist = NULL;
|
|
|
|
|
for (kar=keys; kar->keyblock; kar++)
|
|
|
|
|
{
|
|
|
|
|
for (node=kar->keyblock; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID && (node->flag & 4))
|
|
|
|
|
{
|
2003-01-06 23:56:08 +01:00
|
|
|
|
u32 kid[2];
|
|
|
|
|
|
|
|
|
|
/* have we used this key already? */
|
|
|
|
|
keyid_from_pk (kar->keyblock->pkt->pkt.public_key, kid);
|
|
|
|
|
if(test_key_hash_table(used,kid)==0)
|
|
|
|
|
{
|
|
|
|
|
/* Normally we add both the primary and subkey
|
|
|
|
|
ids to the hash via mark_keyblock_seen, but
|
|
|
|
|
since we aren't using this hash as a skipfnc,
|
|
|
|
|
that doesn't matter here. */
|
|
|
|
|
add_key_hash_table (used,kid);
|
|
|
|
|
k = new_key_item ();
|
|
|
|
|
k->kid[0]=kid[0];
|
|
|
|
|
k->kid[1]=kid[1];
|
|
|
|
|
k->ownertrust =
|
2003-03-04 16:24:12 +01:00
|
|
|
|
(get_ownertrust (kar->keyblock->pkt->pkt.public_key)
|
|
|
|
|
& TRUST_MASK);
|
2003-01-06 23:56:08 +01:00
|
|
|
|
k->min_ownertrust =
|
|
|
|
|
get_min_ownertrust(kar->keyblock->pkt->pkt.public_key);
|
|
|
|
|
k->trust_depth=
|
|
|
|
|
kar->keyblock->pkt->pkt.public_key->trust_depth;
|
|
|
|
|
k->trust_value=
|
|
|
|
|
kar->keyblock->pkt->pkt.public_key->trust_value;
|
|
|
|
|
if(kar->keyblock->pkt->pkt.public_key->trust_regexp)
|
|
|
|
|
k->trust_regexp=
|
|
|
|
|
m_strdup(kar->keyblock->pkt->
|
|
|
|
|
pkt.public_key->trust_regexp);
|
|
|
|
|
k->next = klist;
|
|
|
|
|
klist = k;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
release_key_array (keys);
|
|
|
|
|
keys = NULL;
|
|
|
|
|
if (!klist)
|
|
|
|
|
break; /* no need to dive in deeper */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
leave:
|
|
|
|
|
keydb_release (kdb);
|
|
|
|
|
release_key_array (keys);
|
|
|
|
|
release_key_items (klist);
|
2003-01-06 23:56:08 +01:00
|
|
|
|
release_key_hash_table (full_trust);
|
|
|
|
|
release_key_hash_table (used);
|
|
|
|
|
release_key_hash_table (stored);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
if (!rc && !quit) /* mark trustDB as checked */
|
|
|
|
|
{
|
|
|
|
|
if (next_expire == 0xffffffff || next_expire < start_time )
|
|
|
|
|
tdbio_write_nextcheck (0);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tdbio_write_nextcheck (next_expire);
|
|
|
|
|
log_info (_("next trustdb check due at %s\n"),
|
|
|
|
|
strtimestamp (next_expire));
|
|
|
|
|
}
|
2002-12-04 07:06:56 +01:00
|
|
|
|
|
|
|
|
|
if(tdbio_update_version_record()!=0)
|
|
|
|
|
{
|
|
|
|
|
log_error(_("unable to update trustdb version record: "
|
|
|
|
|
"write failed: %s\n"), g10_errstr(rc));
|
|
|
|
|
tdbio_invalid();
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
do_sync ();
|
|
|
|
|
pending_check_trustdb = 0;
|
1998-07-21 14:53:38 +02:00
|
|
|
|
}
|
2003-03-04 16:24:12 +01:00
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
return rc;
|
1998-01-13 20:04:23 +01:00
|
|
|
|
}
|