mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-31 11:41:32 +01:00
Revamped preference handling
This commit is contained in:
parent
57c1dbc21d
commit
dc718d704f
4
NEWS
4
NEWS
@ -16,6 +16,10 @@
|
||||
primary UID, "setpref" and "updpref" can be used to change the
|
||||
preferences.
|
||||
|
||||
* Fixed the preference handling; since 1.0.5 they were erroneously
|
||||
matched against against the latest user ID and not the given one.
|
||||
|
||||
|
||||
Noteworthy changes in version 1.0.6 (2001-05-29)
|
||||
------------------------------------------------
|
||||
|
||||
|
1
THANKS
1
THANKS
@ -139,6 +139,7 @@ Philippe Laliberte arsphl@oeil.qc.ca
|
||||
Peter Fales psfales@lucent.com
|
||||
Peter Gutmann pgut001@cs.auckland.ac.nz
|
||||
Peter Marschall Peter.Marschall@gedos.de
|
||||
Peter Valchev pvalchev@openbsd.org
|
||||
Piotr Krukowiecki piotr@pingu.ii.uj.edu.pl
|
||||
QingLong qinglong@bolizm.ihep.su
|
||||
Ralph Gillen gillen@theochem.uni-duesseldorf.de
|
||||
|
@ -507,7 +507,7 @@ the DB is always of type 1 and this is the only record of this type.
|
||||
|
||||
Record type 5: (pref record)
|
||||
--------------
|
||||
Informations about preferences
|
||||
This record type is not anymore used.
|
||||
|
||||
1 byte value 5
|
||||
1 byte reserved
|
||||
|
@ -354,6 +354,7 @@ List preferences.</para></listitem></varlistentry>
|
||||
<term>showpref</term>
|
||||
<listitem><para>
|
||||
More verbose preferences listing.</para></listitem></varlistentry>
|
||||
<varlistentry>
|
||||
<term>setpref &ParmString;</term>
|
||||
<listitem><para>
|
||||
Set the list of user ID preferences to &ParmString;, this should be
|
||||
@ -363,6 +364,7 @@ preferences to nil. Only available algorithms are allowed. This
|
||||
command just initializes an internal list and does not change anything
|
||||
unless another command which changes the self-signatures is used.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry>
|
||||
<term>updpref</term>
|
||||
<listitem><para>
|
||||
Change the preferences of all user IDs (or just of the selected ones
|
||||
|
@ -1,3 +1,37 @@
|
||||
2001-08-10 Werner Koch <wk@gnupg.org>
|
||||
|
||||
Revamped the preference handling.
|
||||
|
||||
* packet.h (prefitem_t, preftype_t): New.
|
||||
(PKT_public_key): Added a uid field.
|
||||
(PKT_user_id): Added field to store preferences and a reference
|
||||
counter.
|
||||
* parse-packet.c (parse_user_id,parse_photo_id): Initialize them
|
||||
* free-packet.c (free_user_id): Free them.
|
||||
(copy_user_id): Removed.
|
||||
(scopy_user_id): New.
|
||||
(cmp_user_ids): Optimized for identical pointers.
|
||||
(release_public_key_parts): Release the uid.
|
||||
(copy_public_key_with_new_namehash): Removed.
|
||||
(copy_prefs): New.
|
||||
* keyedit.c (menu_adduid): Use the new shallow copy user id.
|
||||
(show_prefs): Adjusted implementation.
|
||||
(keyedit_menu): No more need to update the trustdb after changing
|
||||
preferences.
|
||||
* getkey.c (fixup_uidnode): Store preferences.
|
||||
(find_by_name): Return a user id packet and remove namehash stuff.
|
||||
(lookup): Removed the unused namehash stuff.
|
||||
(finish_lookup): Added foundu arg.
|
||||
(pk_from_block): Removed the namehash arg and changed all callers.
|
||||
(merge_selfsigs): Copy prefs to all keys.
|
||||
* trustdb.c (get_pref_data): Removed.
|
||||
(is_algo_in_prefs): Removed.
|
||||
(make_pref_record): Deleted and removed all class.
|
||||
* pkclist.c (select_algo_from_prefs): Adjusted for the new
|
||||
preference implementation.
|
||||
* pubkey-enc.c (is_algo_in_prefs): New.
|
||||
(get_it): Use that new function.
|
||||
|
||||
2001-08-09 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* build-packet.c (build_sig_subpkt): Fixed calculation of
|
||||
|
@ -351,7 +351,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
|
||||
/* register the compress filter */
|
||||
if( do_compress ) {
|
||||
int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
|
||||
int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_ZIP );
|
||||
if( !compr_algo )
|
||||
; /* don't use compression */
|
||||
else {
|
||||
|
@ -77,10 +77,18 @@ release_public_key_parts( PKT_public_key *pk )
|
||||
mpi_free( pk->pkey[i] );
|
||||
pk->pkey[i] = NULL;
|
||||
}
|
||||
if (pk->prefs) {
|
||||
m_free (pk->prefs);
|
||||
pk->prefs = NULL;
|
||||
}
|
||||
if( pk->namehash ) {
|
||||
m_free(pk->namehash);
|
||||
pk->namehash = NULL;
|
||||
}
|
||||
if (pk->user_id) {
|
||||
free_user_id (pk->user_id);
|
||||
pk->user_id = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -106,24 +114,42 @@ cp_subpktarea (subpktarea_t *s )
|
||||
return d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a copy of the preferences
|
||||
*/
|
||||
prefitem_t *
|
||||
copy_prefs (const prefitem_t *prefs)
|
||||
{
|
||||
size_t n;
|
||||
prefitem_t *new;
|
||||
|
||||
if (!prefs)
|
||||
return NULL;
|
||||
|
||||
for (n=0; prefs[n].type; n++)
|
||||
;
|
||||
new = m_alloc ( sizeof (*new) * (n+1));
|
||||
for (n=0; prefs[n].type; n++) {
|
||||
new[n].type = prefs[n].type;
|
||||
new[n].value = prefs[n].value;
|
||||
}
|
||||
new[n].type = PREFTYPE_NONE;
|
||||
new[n].value = 0;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
PKT_public_key *
|
||||
copy_public_key_new_namehash( PKT_public_key *d, PKT_public_key *s,
|
||||
const byte *namehash )
|
||||
copy_public_key ( PKT_public_key *d, PKT_public_key *s)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
if( !d )
|
||||
d = m_alloc(sizeof *d);
|
||||
memcpy( d, s, sizeof *d );
|
||||
if( namehash ) {
|
||||
d->namehash = m_alloc( 20 );
|
||||
memcpy(d->namehash, namehash, 20 );
|
||||
}
|
||||
else if( s->namehash ) {
|
||||
d->namehash = m_alloc( 20 );
|
||||
memcpy(d->namehash, s->namehash, 20 );
|
||||
}
|
||||
d->user_id = scopy_user_id (s->user_id);
|
||||
d->prefs = copy_prefs (s->prefs);
|
||||
n = pubkey_get_npkey( s->pubkey_algo );
|
||||
if( !n )
|
||||
d->pkey[0] = mpi_copy(s->pkey[0]);
|
||||
@ -134,12 +160,6 @@ copy_public_key_new_namehash( PKT_public_key *d, PKT_public_key *s,
|
||||
return d;
|
||||
}
|
||||
|
||||
PKT_public_key *
|
||||
copy_public_key( PKT_public_key *d, PKT_public_key *s )
|
||||
{
|
||||
return copy_public_key_new_namehash( d, s, NULL );
|
||||
}
|
||||
|
||||
/****************
|
||||
* Replace all common parts of a sk by the one from the public key.
|
||||
* This is a hack and a better solution will be to just store the real secret
|
||||
@ -183,13 +203,15 @@ copy_signature( PKT_signature *d, PKT_signature *s )
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shallow copy of the user ID
|
||||
*/
|
||||
PKT_user_id *
|
||||
copy_user_id( PKT_user_id *d, PKT_user_id *s )
|
||||
scopy_user_id (PKT_user_id *s)
|
||||
{
|
||||
if( !d )
|
||||
d = m_alloc(sizeof *d + s->len - 1 );
|
||||
memcpy( d, s, sizeof *d + s->len - 1 );
|
||||
return d;
|
||||
if (s)
|
||||
s->ref++;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@ -240,11 +262,17 @@ free_comment( PKT_comment *rem )
|
||||
}
|
||||
|
||||
void
|
||||
free_user_id( PKT_user_id *uid )
|
||||
free_user_id (PKT_user_id *uid)
|
||||
{
|
||||
if( uid->photo )
|
||||
m_free( uid->photo );
|
||||
m_free(uid);
|
||||
assert (uid->ref > 0);
|
||||
if (--uid->ref)
|
||||
return;
|
||||
|
||||
if (uid->photo)
|
||||
m_free (uid->photo);
|
||||
if (uid->prefs)
|
||||
m_free (uid->prefs);
|
||||
m_free (uid);
|
||||
}
|
||||
|
||||
void
|
||||
@ -466,6 +494,9 @@ cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
|
||||
{
|
||||
int res;
|
||||
|
||||
if ( a == b )
|
||||
return 0;
|
||||
|
||||
res = a->len - b->len;
|
||||
if( !res )
|
||||
res = memcmp( a->name, b->name, a->len );
|
||||
|
141
g10/getkey.c
141
g10/getkey.c
@ -358,15 +358,14 @@ getkey_disable_caches()
|
||||
|
||||
|
||||
static void
|
||||
pk_from_block ( GETKEY_CTX ctx,
|
||||
PKT_public_key *pk, KBNODE keyblock, const char *namehash )
|
||||
pk_from_block ( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE keyblock )
|
||||
{
|
||||
KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
|
||||
|
||||
assert ( a->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| a->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||
|
||||
copy_public_key_new_namehash( pk, a->pkt->pkt.public_key, namehash);
|
||||
copy_public_key ( pk, a->pkt->pkt.public_key );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -435,7 +434,7 @@ get_pubkey( PKT_public_key *pk, u32 *keyid )
|
||||
ctx.req_usage = pk->req_usage;
|
||||
rc = lookup( &ctx, &kb, 0 );
|
||||
if ( !rc ) {
|
||||
pk_from_block ( &ctx, pk, kb, NULL );
|
||||
pk_from_block ( &ctx, pk, kb );
|
||||
}
|
||||
get_pubkey_end( &ctx );
|
||||
release_kbnode ( kb );
|
||||
@ -925,7 +924,7 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
||||
}
|
||||
rc = lookup( ctx, ret_kb, 0 );
|
||||
if ( !rc && pk ) {
|
||||
pk_from_block ( ctx, pk, *ret_kb, NULL /* FIXME need to get the namehash*/ );
|
||||
pk_from_block ( ctx, pk, *ret_kb );
|
||||
}
|
||||
}
|
||||
|
||||
@ -972,7 +971,7 @@ get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
|
||||
|
||||
rc = lookup( ctx, ret_keyblock, 0 );
|
||||
if ( !rc && pk && ret_keyblock )
|
||||
pk_from_block ( ctx, pk, *ret_keyblock, NULL );
|
||||
pk_from_block ( ctx, pk, *ret_keyblock );
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -1020,7 +1019,7 @@ get_pubkey_byfprint( PKT_public_key *pk,
|
||||
memcpy( ctx.items[0].fprint, fprint, fprint_len );
|
||||
rc = lookup( &ctx, &kb, 0 );
|
||||
if (!rc && pk )
|
||||
pk_from_block ( &ctx, pk, kb, NULL );
|
||||
pk_from_block ( &ctx, pk, kb );
|
||||
release_kbnode ( kb );
|
||||
get_pubkey_end( &ctx );
|
||||
}
|
||||
@ -1399,14 +1398,23 @@ merge_keys_and_selfsig( KBNODE keyblock )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Apply information from SIGNODE (which is the valid self-signature
|
||||
* associated with that UID) to the UIDNODE:
|
||||
* - wether the UID has been revoked
|
||||
* - assumed creation date of the UID
|
||||
* - temporary store the keyflags here
|
||||
* - temporary store the key expiration time here
|
||||
* - mark whether the primary user ID flag hat been set.
|
||||
* - store the preferences
|
||||
*/
|
||||
static void
|
||||
fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
|
||||
{
|
||||
PKT_user_id *uid = uidnode->pkt->pkt.user_id;
|
||||
PKT_signature *sig = signode->pkt->pkt.signature;
|
||||
const byte *p;
|
||||
size_t n;
|
||||
const byte *p, *sym, *hash, *zip;
|
||||
size_t n, nsym, nhash, nzip;
|
||||
|
||||
uid->created = 0; /* not created == invalid */
|
||||
if ( IS_UID_REV ( sig ) ) {
|
||||
@ -1435,7 +1443,7 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
|
||||
}
|
||||
|
||||
/* Set the primary user ID flag - we will later wipe out some
|
||||
* of them to only have one in out keyblock */
|
||||
* of them to only have one in our keyblock */
|
||||
uid->is_primary = 0;
|
||||
p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL );
|
||||
if ( p && *p )
|
||||
@ -1445,6 +1453,43 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
|
||||
* there should be no security problem with this.
|
||||
* For now we only look at the hashed one.
|
||||
*/
|
||||
|
||||
/* now build the preferences list. We try to get the preferences
|
||||
* from the hashed list but if there are no such preferences, we
|
||||
* try to get them from the unhashed list. There is no risk with
|
||||
* that, because our implementation comes only with strong
|
||||
* algorithms and it woulkd be fruitless for an attacker to insert
|
||||
* an weak algorithm. */
|
||||
p = parse_sig_subpkt2 ( sig, SIGSUBPKT_PREF_SYM, &n );
|
||||
sym = p; nsym = p?n:0;
|
||||
p = parse_sig_subpkt2 ( sig, SIGSUBPKT_PREF_HASH, &n );
|
||||
hash = p; nhash = p?n:0;
|
||||
p = parse_sig_subpkt2 ( sig, SIGSUBPKT_PREF_COMPR, &n );
|
||||
zip = p; nzip = p?n:0;
|
||||
if (uid->prefs)
|
||||
m_free (uid->prefs);
|
||||
n = nsym + nhash + nzip;
|
||||
if (!n)
|
||||
uid->prefs = NULL;
|
||||
else {
|
||||
uid->prefs = m_alloc (sizeof (*uid->prefs) * (n+1));
|
||||
n = 0;
|
||||
for (; nsym; nsym--, n++) {
|
||||
uid->prefs[n].type = PREFTYPE_SYM;
|
||||
uid->prefs[n].value = *sym++;
|
||||
}
|
||||
for (; nhash; nhash--, n++) {
|
||||
uid->prefs[n].type = PREFTYPE_HASH;
|
||||
uid->prefs[n].value = *hash++;
|
||||
}
|
||||
for (; nzip; nzip--, n++) {
|
||||
uid->prefs[n].type = PREFTYPE_ZIP;
|
||||
uid->prefs[n].value = *sym++;
|
||||
}
|
||||
uid->prefs[n].type = PREFTYPE_NONE; /* end of list marker */
|
||||
uid->prefs[n].value = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1800,6 +1845,7 @@ merge_selfsigs( KBNODE keyblock )
|
||||
KBNODE k;
|
||||
int revoked;
|
||||
PKT_public_key *main_pk;
|
||||
prefitem_t *prefs;
|
||||
|
||||
if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) {
|
||||
if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) {
|
||||
@ -1836,6 +1882,33 @@ merge_selfsigs( KBNODE keyblock )
|
||||
merge_selfsigs_subkey ( keyblock, k );
|
||||
}
|
||||
}
|
||||
|
||||
/* set the preference list of all keys to those of the primary
|
||||
* user ID. Note: we use these preferences when we don't know by
|
||||
* which user ID the key has been selected.
|
||||
* fixme: we should keep atoms of commonly used preferences or
|
||||
* use reference counting to optimize the preference lists storage.
|
||||
* FIXME: it might be better to use the intersection of
|
||||
* all preferences.
|
||||
*/
|
||||
prefs = NULL;
|
||||
for (k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) {
|
||||
if (k->pkt->pkttype == PKT_USER_ID
|
||||
&& k->pkt->pkt.user_id->is_primary) {
|
||||
prefs = k->pkt->pkt.user_id->prefs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if ( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
PKT_public_key *pk = k->pkt->pkt.public_key;
|
||||
if (pk->prefs)
|
||||
m_free (pk->prefs);
|
||||
pk->prefs = copy_prefs (prefs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1955,9 +2028,8 @@ premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
|
||||
************* Find stuff ***********************
|
||||
************************************************/
|
||||
|
||||
static int
|
||||
find_by_name( KBNODE keyblock, const char *name,
|
||||
int mode, byte *namehash )
|
||||
static PKT_user_id *
|
||||
find_by_name( KBNODE keyblock, const char *name, int mode )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
@ -1965,23 +2037,11 @@ find_by_name( KBNODE keyblock, const char *name,
|
||||
if( k->pkt->pkttype == PKT_USER_ID
|
||||
&& !compare_name( k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len, name, mode)) {
|
||||
/* we found a matching name, look for the key */
|
||||
if( k->pkt->pkt.user_id->photo ) {
|
||||
/* oops: this can never happen */
|
||||
rmd160_hash_buffer( namehash,
|
||||
k->pkt->pkt.user_id->photo,
|
||||
k->pkt->pkt.user_id->photolen );
|
||||
}
|
||||
else {
|
||||
rmd160_hash_buffer( namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
}
|
||||
return 1;
|
||||
return k->pkt->pkt.user_id;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -2068,7 +2128,7 @@ find_by_fpr( KBNODE keyblock, const char *name, int mode )
|
||||
*/
|
||||
|
||||
static int
|
||||
finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
|
||||
finish_lookup( GETKEY_CTX ctx, KBNODE foundk, PKT_user_id *foundu )
|
||||
{
|
||||
KBNODE keyblock = ctx->keyblock;
|
||||
KBNODE k;
|
||||
@ -2098,6 +2158,10 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
|
||||
}
|
||||
|
||||
if (!req_usage) {
|
||||
PKT_public_key *pk = foundk->pkt->pkt.public_key;
|
||||
if (pk->user_id)
|
||||
free_user_id (pk->user_id);
|
||||
pk->user_id = scopy_user_id (foundu);
|
||||
ctx->found_key = foundk;
|
||||
cache_user_id( keyblock );
|
||||
return 1; /* found */
|
||||
@ -2200,6 +2264,13 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
|
||||
log_debug( "\tusing key %08lX\n",
|
||||
(ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) );
|
||||
|
||||
if (latest_key) {
|
||||
PKT_public_key *pk = latest_key->pkt->pkt.public_key;
|
||||
if (pk->user_id)
|
||||
free_user_id (pk->user_id);
|
||||
pk->user_id = scopy_user_id (foundu);
|
||||
}
|
||||
|
||||
ctx->found_key = latest_key;
|
||||
|
||||
if (latest_key != keyblock && opt.verbose) {
|
||||
@ -2220,8 +2291,6 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
||||
{
|
||||
int rc;
|
||||
int oldmode = set_packet_list_mode(0);
|
||||
byte namehash[20];
|
||||
int use_namehash=0;
|
||||
KBNODE secblock = NULL; /* helper */
|
||||
int no_suitable_key = 0;
|
||||
|
||||
@ -2261,12 +2330,12 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
||||
for(n=0; n < ctx->nitems; n++, item++ ) {
|
||||
KBNODE k = NULL;
|
||||
int found = 0;
|
||||
PKT_user_id *found_uid = NULL;
|
||||
|
||||
if( item->mode < 10 ) {
|
||||
found = find_by_name( ctx->keyblock,
|
||||
item->name, item->mode,
|
||||
namehash );
|
||||
use_namehash = found;
|
||||
found_uid = find_by_name( ctx->keyblock,
|
||||
item->name, item->mode );
|
||||
found = !!found_uid;
|
||||
}
|
||||
else if( item->mode >= 10 && item->mode <= 12 ) {
|
||||
k = find_by_keyid( ctx->keyblock,
|
||||
@ -2287,7 +2356,7 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
||||
if( found ) {
|
||||
/* this keyblock looks fine - do further investigation */
|
||||
merge_selfsigs ( ctx->keyblock );
|
||||
if ( finish_lookup( ctx, k ) ) {
|
||||
if ( finish_lookup( ctx, k, found_uid ) ) {
|
||||
no_suitable_key = 0;
|
||||
if ( secmode ) {
|
||||
merge_public_with_secret ( ctx->keyblock,
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static void show_prefs( KBNODE keyblock, PKT_user_id *uid, int verbose );
|
||||
static void show_prefs( PKT_user_id *uid, int verbose );
|
||||
static void show_key_with_all_names( KBNODE keyblock,
|
||||
int only_marked, int with_fpr, int with_subkeys, int with_prefs );
|
||||
static void show_key_and_fingerprint( KBNODE keyblock );
|
||||
@ -974,7 +974,6 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
_("Really update the preferences? "))){
|
||||
|
||||
if ( menu_set_preferences (keyblock, sec_keyblock) ) {
|
||||
update_trust_record (keyblock, 0, NULL);
|
||||
merge_keys_and_selfsig (keyblock);
|
||||
modified = 1;
|
||||
redisplay = 1;
|
||||
@ -1065,49 +1064,31 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
* show preferences of a public keyblock.
|
||||
*/
|
||||
static void
|
||||
show_prefs( KBNODE keyblock, PKT_user_id *uid, int verbose )
|
||||
show_prefs (PKT_user_id *uid, int verbose)
|
||||
{
|
||||
KBNODE node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
|
||||
PKT_public_key *pk;
|
||||
byte *p;
|
||||
const prefitem_t *prefs;
|
||||
int i;
|
||||
size_t n;
|
||||
byte namehash[20];
|
||||
|
||||
if( !node )
|
||||
return; /* is a secret keyblock */
|
||||
pk = node->pkt->pkt.public_key;
|
||||
if( !pk->local_id ) {
|
||||
log_error("oops: no LID\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if( uid->photo )
|
||||
rmd160_hash_buffer( namehash, uid->photo, uid->photolen );
|
||||
else
|
||||
rmd160_hash_buffer( namehash, uid->name, uid->len );
|
||||
|
||||
p = get_pref_data( pk->local_id, namehash, &n );
|
||||
if( !p )
|
||||
return;
|
||||
|
||||
if( !uid || !uid->prefs )
|
||||
return;
|
||||
prefs = uid->prefs;
|
||||
if (verbose) {
|
||||
int any, des_seen=0;
|
||||
|
||||
tty_printf (" Cipher: ");
|
||||
for(i=any=0; i < n; i+=2 ) {
|
||||
if( p[i] == PREFTYPE_SYM ) {
|
||||
const char *s = cipher_algo_to_string (p[i+1]);
|
||||
for(i=any=0; prefs[i].type; i++ ) {
|
||||
if( prefs[i].type == PREFTYPE_SYM ) {
|
||||
const char *s = cipher_algo_to_string (prefs[i].value);
|
||||
|
||||
if (any)
|
||||
tty_printf (", ");
|
||||
any = 1;
|
||||
/* We don't want to display strings for experimental algos */
|
||||
if (s && p[i+1] < 100 )
|
||||
if (s && prefs[i].value < 100 )
|
||||
tty_printf ("%s", s );
|
||||
else
|
||||
tty_printf ("[%d]", p[i+1]);
|
||||
if (p[i+1] == CIPHER_ALGO_3DES )
|
||||
tty_printf ("[%d]", prefs[i].value);
|
||||
if (prefs[i].value == CIPHER_ALGO_3DES )
|
||||
des_seen = 1;
|
||||
}
|
||||
}
|
||||
@ -1117,34 +1098,32 @@ show_prefs( KBNODE keyblock, PKT_user_id *uid, int verbose )
|
||||
tty_printf ("3DES");
|
||||
}
|
||||
tty_printf ("\n Hash: ");
|
||||
for(i=any=0; i < n; i+=2 ) {
|
||||
if( p[i] == PREFTYPE_HASH ) {
|
||||
const char *s = digest_algo_to_string (p[i+1]);
|
||||
for(i=any=0; prefs[i].type; i++ ) {
|
||||
if( prefs[i].type == PREFTYPE_HASH ) {
|
||||
const char *s = digest_algo_to_string (prefs[i].value);
|
||||
|
||||
if (any)
|
||||
tty_printf (", ");
|
||||
any = 1;
|
||||
/* We don't want to display strings for experimental algos */
|
||||
if (s && p[i+1] < 100 )
|
||||
if (s && prefs[i].value < 100 )
|
||||
tty_printf ("%s", s );
|
||||
else
|
||||
tty_printf ("[%d]", p[i+1]);
|
||||
tty_printf ("[%d]", prefs[i].value);
|
||||
}
|
||||
}
|
||||
tty_printf("\n");
|
||||
}
|
||||
else {
|
||||
tty_printf(" ");
|
||||
for(i=0; i < n; i+=2 ) {
|
||||
if( p[i] )
|
||||
tty_printf( " %c%d", p[i] == PREFTYPE_SYM ? 'S' :
|
||||
p[i] == PREFTYPE_HASH ? 'H' :
|
||||
p[i] == PREFTYPE_COMPR ? 'Z':'?', p[i+1]);
|
||||
for(i=0; prefs[i].type; i++ ) {
|
||||
tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
|
||||
prefs[i].type == PREFTYPE_HASH ? 'H' :
|
||||
prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
|
||||
prefs[i].value);
|
||||
}
|
||||
tty_printf("\n");
|
||||
}
|
||||
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
|
||||
@ -1244,7 +1223,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
tty_print_utf8_string( uid->name, uid->len );
|
||||
tty_printf("\n");
|
||||
if( with_prefs )
|
||||
show_prefs( keyblock, uid, with_prefs == 2 );
|
||||
show_prefs (uid, with_prefs == 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1355,7 +1334,7 @@ menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
/* insert/append to secret keyblock */
|
||||
pkt = m_alloc_clear( sizeof *pkt );
|
||||
pkt->pkttype = PKT_USER_ID;
|
||||
pkt->pkt.user_id = copy_user_id(NULL, uid);
|
||||
pkt->pkt.user_id = scopy_user_id(uid);
|
||||
node = new_kbnode(pkt);
|
||||
if( sec_where )
|
||||
insert_kbnode( sec_where, node, 0 );
|
||||
|
47
g10/packet.h
47
g10/packet.h
@ -62,6 +62,17 @@ typedef enum {
|
||||
CTRLPKT_PLAINTEXT_MARK =3
|
||||
} ctrlpkttype_t;
|
||||
|
||||
typedef enum {
|
||||
PREFTYPE_NONE = 0,
|
||||
PREFTYPE_SYM = 1,
|
||||
PREFTYPE_HASH = 2,
|
||||
PREFTYPE_ZIP = 3
|
||||
} preftype_t;
|
||||
|
||||
typedef struct {
|
||||
byte type;
|
||||
byte value;
|
||||
} prefitem_t;
|
||||
|
||||
typedef struct {
|
||||
int mode;
|
||||
@ -102,6 +113,7 @@ typedef struct {
|
||||
byte data[1];
|
||||
} subpktarea_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ulong local_id; /* internal use, valid if > 0 */
|
||||
struct {
|
||||
@ -123,6 +135,21 @@ typedef struct {
|
||||
} PKT_signature;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int ref; /* reference counter */
|
||||
int len; /* length of the name */
|
||||
char *photo; /* if this is not NULL, the packet is a photo ID */
|
||||
int photolen; /* and the length of the photo */
|
||||
int help_key_usage;
|
||||
u32 help_key_expire;
|
||||
int is_primary;
|
||||
int is_revoked;
|
||||
prefitem_t *prefs; /* list of preferences (may be NULL)*/
|
||||
u32 created; /* according to the self-signature */
|
||||
char name[1];
|
||||
} PKT_user_id;
|
||||
|
||||
|
||||
/****************
|
||||
* Note about the pkey/skey elements: We assume that the secret keys
|
||||
* has the same elemts as the public key at the begin of the array, so
|
||||
@ -144,7 +171,9 @@ typedef struct {
|
||||
ulong local_id; /* internal use, valid if > 0 */
|
||||
u32 main_keyid[2]; /* keyid of the primary key */
|
||||
u32 keyid[2]; /* calculated by keyid_from_pk() */
|
||||
prefitem_t *prefs; /* list of preferences (may be NULL) */
|
||||
byte *namehash; /* if != NULL: found by this name */
|
||||
PKT_user_id *user_id; /* if != NULL: found by that uid */
|
||||
MPI pkey[PUBKEY_MAX_NPKEY];
|
||||
} PKT_public_key;
|
||||
|
||||
@ -183,18 +212,6 @@ typedef struct {
|
||||
char data[1];
|
||||
} PKT_comment;
|
||||
|
||||
typedef struct {
|
||||
int len; /* length of the name */
|
||||
char *photo; /* if this is not NULL, the packet is a photo ID */
|
||||
int photolen; /* and the length of the photo */
|
||||
int help_key_usage;
|
||||
u32 help_key_expire;
|
||||
int is_primary;
|
||||
int is_revoked;
|
||||
u32 created; /* according to the self-signature */
|
||||
char name[1];
|
||||
} PKT_user_id;
|
||||
|
||||
typedef struct {
|
||||
u32 len; /* reserved */
|
||||
byte new_ctb;
|
||||
@ -365,14 +382,12 @@ void free_secret_key( PKT_secret_key *sk );
|
||||
void free_user_id( PKT_user_id *uid );
|
||||
void free_comment( PKT_comment *rem );
|
||||
void free_packet( PACKET *pkt );
|
||||
prefitem_t *copy_prefs (const prefitem_t *prefs);
|
||||
PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
|
||||
PKT_public_key *copy_public_key_new_namehash( PKT_public_key *d,
|
||||
PKT_public_key *s,
|
||||
const byte *namehash );
|
||||
void copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
|
||||
PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
|
||||
PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
|
||||
PKT_user_id *copy_user_id( PKT_user_id *d, PKT_user_id *s );
|
||||
PKT_user_id *scopy_user_id (PKT_user_id *sd );
|
||||
int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
|
||||
int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
|
||||
int cmp_signatures( PKT_signature *a, PKT_signature *b );
|
||||
|
@ -1590,6 +1590,7 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
byte *p;
|
||||
|
||||
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + pktlen);
|
||||
packet->pkt.user_id->ref = 1;
|
||||
packet->pkt.user_id->len = pktlen;
|
||||
packet->pkt.user_id->photo = NULL;
|
||||
packet->pkt.user_id->photolen = 0;
|
||||
@ -1598,6 +1599,7 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
packet->pkt.user_id->created = 0;
|
||||
packet->pkt.user_id->help_key_usage = 0;
|
||||
packet->pkt.user_id->help_key_expire = 0;
|
||||
packet->pkt.user_id->prefs = NULL;
|
||||
|
||||
p = packet->pkt.user_id->name;
|
||||
for( ; pktlen; pktlen--, p++ )
|
||||
@ -1630,6 +1632,7 @@ parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
byte *p;
|
||||
|
||||
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 30);
|
||||
packet->pkt.user_id->ref = 1;
|
||||
sprintf( packet->pkt.user_id->name, "[image of size %lu]", pktlen );
|
||||
packet->pkt.user_id->len = strlen(packet->pkt.user_id->name);
|
||||
packet->pkt.user_id->is_primary = 0;
|
||||
@ -1637,6 +1640,7 @@ parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
packet->pkt.user_id->created = 0;
|
||||
packet->pkt.user_id->help_key_usage = 0;
|
||||
packet->pkt.user_id->help_key_expire = 0;
|
||||
packet->pkt.user_id->prefs = NULL;
|
||||
|
||||
packet->pkt.user_id->photo = m_alloc(sizeof *packet->pkt.user_id + pktlen);
|
||||
packet->pkt.user_id->photolen = pktlen;
|
||||
|
@ -1036,13 +1036,15 @@ algo_available( int preftype, int algo )
|
||||
else if( preftype == PREFTYPE_HASH ) {
|
||||
return algo && !check_digest_algo( algo );
|
||||
}
|
||||
else if( preftype == PREFTYPE_COMPR ) {
|
||||
else if( preftype == PREFTYPE_ZIP ) {
|
||||
return !algo || algo == 1 || algo == 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Return -1 if we could not find an algorithm.
|
||||
*/
|
||||
@ -1051,8 +1053,7 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
||||
{
|
||||
PK_LIST pkr;
|
||||
u32 bits[8];
|
||||
byte *pref = NULL;
|
||||
size_t npref;
|
||||
const prefitem_t *prefs;
|
||||
int i, j;
|
||||
int compr_hack=0;
|
||||
int any;
|
||||
@ -1065,43 +1066,38 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
||||
u32 mask[8];
|
||||
|
||||
memset( mask, 0, 8 * sizeof *mask );
|
||||
if( !pkr->pk->local_id ) { /* try to set the local id */
|
||||
query_trust_info( pkr->pk, NULL );
|
||||
if( !pkr->pk->local_id ) {
|
||||
log_debug("select_algo_from_prefs: can't get LID\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( preftype == PREFTYPE_SYM )
|
||||
mask[0] |= (1<<2); /* 3DES is implicitly there */
|
||||
m_free(pref);
|
||||
pref = get_pref_data( pkr->pk->local_id, pkr->pk->namehash, &npref);
|
||||
|
||||
if (pkr->pk->user_id) /* selected by user ID */
|
||||
prefs = pkr->pk->user_id->prefs;
|
||||
else
|
||||
prefs = pkr->pk->prefs;
|
||||
|
||||
any = 0;
|
||||
if( pref ) {
|
||||
#if 0
|
||||
log_hexdump("raw: ", pref, npref );
|
||||
#endif
|
||||
for(i=0; i+1 < npref; i+=2 ) {
|
||||
if( pref[i] == preftype ) {
|
||||
mask[pref[i+1]/32] |= 1 << (pref[i+1]%32);
|
||||
if( prefs ) {
|
||||
for (i=0; prefs[i].type; i++ ) {
|
||||
if( prefs[i].type == preftype ) {
|
||||
mask[prefs[i].value/32] |= 1 << (prefs[i].value%32);
|
||||
any = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (!pref || !any) && preftype == PREFTYPE_COMPR ) {
|
||||
|
||||
if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) {
|
||||
mask[0] |= 3; /* asume no_compression and old pgp */
|
||||
compr_hack = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
log_debug("mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
|
||||
log_debug("pref mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
|
||||
(ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
|
||||
(ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);
|
||||
#endif
|
||||
for(i=0; i < 8; i++ )
|
||||
bits[i] &= mask[i];
|
||||
#if 0
|
||||
log_debug("bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
|
||||
log_debug("pref bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
|
||||
(ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
|
||||
(ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);
|
||||
#endif
|
||||
@ -1114,20 +1110,20 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
||||
*/
|
||||
i = -1;
|
||||
any = 0;
|
||||
if( pref ) {
|
||||
for(j=0; j+1 < npref; j+=2 ) {
|
||||
if( pref[j] == preftype ) {
|
||||
if( (bits[pref[j+1]/32] & (1<<(pref[j+1]%32))) ) {
|
||||
if( algo_available( preftype, pref[j+1] ) ) {
|
||||
if( prefs ) {
|
||||
for(j=0; prefs[j].type; j++ ) {
|
||||
if( prefs[j].type == preftype ) {
|
||||
if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) {
|
||||
if( algo_available( preftype, prefs[j].value ) ) {
|
||||
any = 1;
|
||||
i = pref[j+1];
|
||||
i = prefs[j].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !pref || !any ) {
|
||||
if( !prefs || !any ) {
|
||||
for(j=0; j < 256; j++ )
|
||||
if( (bits[j/32] & (1<<(j%32))) ) {
|
||||
if( algo_available( preftype, j ) ) {
|
||||
@ -1147,7 +1143,6 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
||||
i = 1; /* yep; we can use compression algo 1 */
|
||||
}
|
||||
|
||||
m_free(pref);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,29 @@
|
||||
static int get_it( PKT_pubkey_enc *k,
|
||||
DEK *dek, PKT_secret_key *sk, u32 *keyid );
|
||||
|
||||
|
||||
/* check that the given algo is mentioned in one of the valid user IDs */
|
||||
static int
|
||||
is_algo_in_prefs ( KBNODE keyblock, preftype_t type, int algo )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
for (k=keyblock; k; k=k->next) {
|
||||
if (k->pkt->pkttype == PKT_USER_ID) {
|
||||
PKT_user_id *uid = k->pkt->pkt.user_id;
|
||||
prefitem_t *prefs = uid->prefs;
|
||||
|
||||
if (uid->created && !uid->is_revoked && prefs ) {
|
||||
for (; prefs->type; prefs++ )
|
||||
if (prefs->type == type && prefs->value == algo)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Get the session key from a pubkey enc paket and return
|
||||
* it in DEK, which should have been allocated in secure memory.
|
||||
@ -175,29 +198,47 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
log_hexdump("DEK is:", dek->key, dek->keylen );
|
||||
/* check that the algo is in the preferences and whether it has expired */
|
||||
{
|
||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||
if( (rc = get_pubkey( pk, keyid )) )
|
||||
log_error("public key problem: %s\n", g10_errstr(rc) );
|
||||
else if( !pk->local_id && query_trust_record(pk) )
|
||||
log_error("can't check algorithm against preferences\n");
|
||||
PKT_public_key *pk = NULL;
|
||||
KBNODE pkb = get_pubkeyblock (keyid);
|
||||
|
||||
if( !pkb ) {
|
||||
rc = -1;
|
||||
log_error("oops: public key not found for preference check\n");
|
||||
}
|
||||
else if( dek->algo != CIPHER_ALGO_3DES
|
||||
&& !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) ) {
|
||||
&& !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ) ) {
|
||||
/* Don't print a note while we are not on verbose mode,
|
||||
* the cipher is blowfish and the preferences have twofish
|
||||
* listed */
|
||||
if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
|
||||
|| !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM,
|
||||
CIPHER_ALGO_TWOFISH ) )
|
||||
|| !is_algo_in_prefs( pkb, PREFTYPE_SYM, CIPHER_ALGO_TWOFISH))
|
||||
log_info(_(
|
||||
"NOTE: cipher algorithm %d not found in preferences\n"),
|
||||
dek->algo );
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
KBNODE k;
|
||||
|
||||
for (k=pkb; k; k = k->next) {
|
||||
if (k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
|
||||
u32 aki[2];
|
||||
keyid_from_pk(k->pkt->pkt.public_key, aki);
|
||||
|
||||
if( !rc && pk->expiredate && pk->expiredate <= make_timestamp() ) {
|
||||
log_info(_("NOTE: secret key %08lX expired at %s\n"),
|
||||
(ulong)keyid[1], asctimestamp( pk->expiredate) );
|
||||
}
|
||||
if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
|
||||
pk = k->pkt->pkt.public_key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pk)
|
||||
BUG ();
|
||||
if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
|
||||
log_info(_("NOTE: secret key %08lX expired at %s\n"),
|
||||
(ulong)keyid[1], asctimestamp( pk->expiredate) );
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: check wheter the key has been revoked and display
|
||||
* the revocation reason. Actually the user should know this himself,
|
||||
@ -206,7 +247,7 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
* the message. The user can than watch out for snakes send by
|
||||
* one of those Eves outside his paradise :-)
|
||||
*/
|
||||
free_public_key( pk );
|
||||
release_kbnode (pkb);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) )
|
||||
goto leave;
|
||||
if( !old_style )
|
||||
compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
|
||||
compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_ZIP );
|
||||
}
|
||||
|
||||
/* prepare iobufs */
|
||||
|
@ -1161,7 +1161,7 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
if( *p )
|
||||
fprintf(fp, " %c%d", *p == PREFTYPE_SYM ? 'S' :
|
||||
*p == PREFTYPE_HASH ? 'H' :
|
||||
*p == PREFTYPE_COMPR ? 'Z' : '?', p[1]);
|
||||
*p == PREFTYPE_ZIP ? 'Z' : '?', p[1]);
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
|
@ -125,7 +125,7 @@ struct trust_record {
|
||||
/* or 0 for a global pref record */
|
||||
ulong next; /* points to next pref record */
|
||||
byte data[ITEMS_PER_PREF_RECORD];
|
||||
} pref;
|
||||
} pref; /* pref records are not anymore used! */
|
||||
struct { /* signature record */
|
||||
ulong lid;
|
||||
ulong next; /* recnno of next record or NULL for last one */
|
||||
|
136
g10/trustdb.c
136
g10/trustdb.c
@ -1378,72 +1378,6 @@ make_sig_records( KBNODE keyblock, KBNODE uidnode,
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Make a preference record (or a list of them) according to the supplied
|
||||
* signature.
|
||||
* Returns: The record number of the first pref record.
|
||||
*/
|
||||
static ulong
|
||||
make_pref_record( PKT_signature *sig, ulong lid )
|
||||
{
|
||||
static struct {
|
||||
sigsubpkttype_t subpkttype;
|
||||
int preftype;
|
||||
} ptable[] = {
|
||||
{ SIGSUBPKT_PREF_SYM, PREFTYPE_SYM },
|
||||
{ SIGSUBPKT_PREF_HASH, PREFTYPE_HASH },
|
||||
{ SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
|
||||
{ 0, 0 }
|
||||
};
|
||||
TRUSTREC *precs, **p_end, *p=NULL, *p2;
|
||||
ulong precno;
|
||||
int k, idx=0;
|
||||
const byte *s;
|
||||
size_t n;
|
||||
|
||||
#if (ITEMS_PER_PREF_RECORD % 2) != 0
|
||||
#error ITEMS_PER_PREF_RECORD must have an even value
|
||||
#endif
|
||||
|
||||
precs = NULL; p_end = &precs;
|
||||
for(k=0; ptable[k].subpkttype; k++ ) {
|
||||
s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
|
||||
if( !s )
|
||||
continue;
|
||||
for( ; n; n--, s++ ) {
|
||||
if( !idx ) {
|
||||
p = m_alloc_clear( sizeof *p );
|
||||
p->rectype = RECTYPE_PREF;
|
||||
p->r.pref.lid = lid;
|
||||
}
|
||||
p->r.pref.data[idx++] = ptable[k].preftype;
|
||||
p->r.pref.data[idx++] = *s;
|
||||
if( idx >= ITEMS_PER_PREF_RECORD ) {
|
||||
p->recnum = tdbio_new_recnum();
|
||||
*p_end = p;
|
||||
p_end = &p->next;
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( idx ) {
|
||||
p->recnum = tdbio_new_recnum();
|
||||
*p_end = p;
|
||||
p_end = &p->next;
|
||||
}
|
||||
|
||||
precno = precs? precs->recnum : 0;
|
||||
/* write the precs and release the memory */
|
||||
for( p = precs; p ; p = p2 ) {
|
||||
if( p->next )
|
||||
p->r.pref.next = p->next->recnum;
|
||||
write_record( p );
|
||||
p2 = p->next;
|
||||
m_free( p );
|
||||
}
|
||||
return precno;
|
||||
}
|
||||
|
||||
|
||||
static ulong
|
||||
make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire,
|
||||
@ -1480,7 +1414,7 @@ make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire,
|
||||
lid, &bestsig );
|
||||
if( (u->r.uid.uidflags & UIDF_CHECKED)
|
||||
&& (u->r.uid.uidflags & UIDF_VALID) ) {
|
||||
u->r.uid.prefrec = bestsig? make_pref_record( bestsig, lid ) : 0;
|
||||
u->r.uid.prefrec = 0;
|
||||
}
|
||||
|
||||
/* the next test is really bad because we should modify
|
||||
@ -1579,6 +1513,8 @@ do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
|
||||
for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
|
||||
read_record( recno, &urec, RECTYPE_UID );
|
||||
for(r2=urec.r.uid.prefrec ; r2; r2 = prec.r.pref.next ) {
|
||||
/* we don't use preference records any more, but all ones might
|
||||
* still be there */
|
||||
read_record( r2, &prec, RECTYPE_PREF );
|
||||
delete_record( r2 );
|
||||
}
|
||||
@ -2748,69 +2684,3 @@ enum_cert_paths_print( void **context, FILE *fp,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return an allocated buffer with the preference values for
|
||||
* the key with LID and the userid which is identified by the
|
||||
* HAMEHASH or the first one if namehash is NULL. ret_n receives
|
||||
* the length of the allocated buffer. Structure of the buffer is
|
||||
* a repeated sequences of 2 bytes; where the first byte describes the
|
||||
* type of the preference and the second one the value. The constants
|
||||
* PREFTYPE_xxxx should be used to reference a type.
|
||||
*/
|
||||
byte *
|
||||
get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
|
||||
{
|
||||
TRUSTREC rec;
|
||||
ulong recno;
|
||||
|
||||
init_trustdb();
|
||||
read_record( lid, &rec, RECTYPE_DIR );
|
||||
for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
|
||||
read_record( recno, &rec, RECTYPE_UID );
|
||||
if( rec.r.uid.prefrec
|
||||
&& ( !namehash || !memcmp(namehash, rec.r.uid.namehash, 20) )) {
|
||||
byte *buf;
|
||||
/* found the correct one or the first one */
|
||||
read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
|
||||
if( rec.r.pref.next )
|
||||
log_info(_("WARNING: can't yet handle long pref records\n"));
|
||||
buf = m_alloc( ITEMS_PER_PREF_RECORD );
|
||||
memcpy( buf, rec.r.pref.data, ITEMS_PER_PREF_RECORD );
|
||||
*ret_n = ITEMS_PER_PREF_RECORD;
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Check whether the algorithm is in one of the pref records
|
||||
*/
|
||||
int
|
||||
is_algo_in_prefs( ulong lid, int preftype, int algo )
|
||||
{
|
||||
TRUSTREC rec;
|
||||
ulong recno;
|
||||
int i;
|
||||
byte *pref;
|
||||
|
||||
init_trustdb();
|
||||
read_record( lid, &rec, RECTYPE_DIR );
|
||||
for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
|
||||
read_record( recno, &rec, RECTYPE_UID );
|
||||
if( rec.r.uid.prefrec ) {
|
||||
read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
|
||||
if( rec.r.pref.next )
|
||||
log_info(_("WARNING: can't yet handle long pref records\n"));
|
||||
pref = rec.r.pref.data;
|
||||
for(i=0; i+1 < ITEMS_PER_PREF_RECORD; i+=2 ) {
|
||||
if( pref[i] == preftype && pref[i+1] == algo )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -37,11 +37,6 @@
|
||||
#define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */
|
||||
|
||||
|
||||
#define PREFTYPE_SYM 1
|
||||
#define PREFTYPE_HASH 2
|
||||
#define PREFTYPE_COMPR 3
|
||||
|
||||
|
||||
/*-- trustdb.c --*/
|
||||
void list_trust_path( const char *username );
|
||||
void register_trusted_key( const char *string );
|
||||
@ -59,8 +54,6 @@ void enum_cert_paths_print( void **context, FILE *fp,
|
||||
int refresh, ulong selected_lid );
|
||||
unsigned get_ownertrust( ulong lid );
|
||||
int get_ownertrust_info( ulong lid );
|
||||
byte *get_pref_data( ulong lid, const byte *namehash, size_t *ret_n );
|
||||
int is_algo_in_prefs( ulong lid, int preftype, int algo );
|
||||
int keyid_from_lid( ulong lid, u32 *keyid );
|
||||
ulong lid_from_keyblock( KBNODE keyblock );
|
||||
int query_trust_record( PKT_public_key *pk );
|
||||
|
@ -1,3 +1,8 @@
|
||||
2001-08-09 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* config.links: Added configuraton for powerpc-openbsd. By Peter
|
||||
Valchev
|
||||
|
||||
2001-07-09 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* config.links: Changed the way the list of files to be
|
||||
|
@ -198,8 +198,8 @@ case "${target}" in
|
||||
path="powerpc32"
|
||||
;;
|
||||
|
||||
powerpc*-*-netbsd*)
|
||||
echo '/* configured NetBSD on powerpc */' >>./mpi/asm-syntax.h
|
||||
powerpc*-*-netbsd* | powerpc*-*-openbsd*)
|
||||
echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h
|
||||
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
|
||||
cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
|
||||
mpi_sflags="-Wa,-mppc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user