1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-05 12:31:50 +01:00

Revamped preference handling

This commit is contained in:
Werner Koch 2001-08-10 14:04:32 +00:00
parent 57c1dbc21d
commit dc718d704f
20 changed files with 355 additions and 312 deletions

4
NEWS
View File

@ -16,6 +16,10 @@
primary UID, "setpref" and "updpref" can be used to change the primary UID, "setpref" and "updpref" can be used to change the
preferences. 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) Noteworthy changes in version 1.0.6 (2001-05-29)
------------------------------------------------ ------------------------------------------------

1
THANKS
View File

@ -139,6 +139,7 @@ Philippe Laliberte arsphl@oeil.qc.ca
Peter Fales psfales@lucent.com Peter Fales psfales@lucent.com
Peter Gutmann pgut001@cs.auckland.ac.nz Peter Gutmann pgut001@cs.auckland.ac.nz
Peter Marschall Peter.Marschall@gedos.de Peter Marschall Peter.Marschall@gedos.de
Peter Valchev pvalchev@openbsd.org
Piotr Krukowiecki piotr@pingu.ii.uj.edu.pl Piotr Krukowiecki piotr@pingu.ii.uj.edu.pl
QingLong qinglong@bolizm.ihep.su QingLong qinglong@bolizm.ihep.su
Ralph Gillen gillen@theochem.uni-duesseldorf.de Ralph Gillen gillen@theochem.uni-duesseldorf.de

View File

@ -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) Record type 5: (pref record)
-------------- --------------
Informations about preferences This record type is not anymore used.
1 byte value 5 1 byte value 5
1 byte reserved 1 byte reserved

View File

@ -354,6 +354,7 @@ List preferences.</para></listitem></varlistentry>
<term>showpref</term> <term>showpref</term>
<listitem><para> <listitem><para>
More verbose preferences listing.</para></listitem></varlistentry> More verbose preferences listing.</para></listitem></varlistentry>
<varlistentry>
<term>setpref &ParmString;</term> <term>setpref &ParmString;</term>
<listitem><para> <listitem><para>
Set the list of user ID preferences to &ParmString;, this should be 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 command just initializes an internal list and does not change anything
unless another command which changes the self-signatures is used. unless another command which changes the self-signatures is used.
</para></listitem></varlistentry> </para></listitem></varlistentry>
<varlistentry>
<term>updpref</term> <term>updpref</term>
<listitem><para> <listitem><para>
Change the preferences of all user IDs (or just of the selected ones Change the preferences of all user IDs (or just of the selected ones

View File

@ -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> 2001-08-09 Werner Koch <wk@gnupg.org>
* build-packet.c (build_sig_subpkt): Fixed calculation of * build-packet.c (build_sig_subpkt): Fixed calculation of

View File

@ -351,7 +351,7 @@ encode_crypt( const char *filename, STRLIST remusr )
/* register the compress filter */ /* register the compress filter */
if( do_compress ) { 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 ) if( !compr_algo )
; /* don't use compression */ ; /* don't use compression */
else { else {

View File

@ -77,10 +77,18 @@ release_public_key_parts( PKT_public_key *pk )
mpi_free( pk->pkey[i] ); mpi_free( pk->pkey[i] );
pk->pkey[i] = NULL; pk->pkey[i] = NULL;
} }
if (pk->prefs) {
m_free (pk->prefs);
pk->prefs = NULL;
}
if( pk->namehash ) { if( pk->namehash ) {
m_free(pk->namehash); m_free(pk->namehash);
pk->namehash = NULL; 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 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 * PKT_public_key *
copy_public_key_new_namehash( PKT_public_key *d, PKT_public_key *s, copy_public_key ( PKT_public_key *d, PKT_public_key *s)
const byte *namehash )
{ {
int n, i; int n, i;
if( !d ) if( !d )
d = m_alloc(sizeof *d); d = m_alloc(sizeof *d);
memcpy( d, s, sizeof *d ); memcpy( d, s, sizeof *d );
if( namehash ) { d->user_id = scopy_user_id (s->user_id);
d->namehash = m_alloc( 20 ); d->prefs = copy_prefs (s->prefs);
memcpy(d->namehash, namehash, 20 );
}
else if( s->namehash ) {
d->namehash = m_alloc( 20 );
memcpy(d->namehash, s->namehash, 20 );
}
n = pubkey_get_npkey( s->pubkey_algo ); n = pubkey_get_npkey( s->pubkey_algo );
if( !n ) if( !n )
d->pkey[0] = mpi_copy(s->pkey[0]); 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; 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. * 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 * 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 * PKT_user_id *
copy_user_id( PKT_user_id *d, PKT_user_id *s ) scopy_user_id (PKT_user_id *s)
{ {
if( !d ) if (s)
d = m_alloc(sizeof *d + s->len - 1 ); s->ref++;
memcpy( d, s, sizeof *d + s->len - 1 ); return s;
return d;
} }
@ -240,11 +262,17 @@ free_comment( PKT_comment *rem )
} }
void void
free_user_id( PKT_user_id *uid ) free_user_id (PKT_user_id *uid)
{ {
if( uid->photo ) assert (uid->ref > 0);
m_free( uid->photo ); if (--uid->ref)
m_free(uid); return;
if (uid->photo)
m_free (uid->photo);
if (uid->prefs)
m_free (uid->prefs);
m_free (uid);
} }
void void
@ -466,6 +494,9 @@ cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
{ {
int res; int res;
if ( a == b )
return 0;
res = a->len - b->len; res = a->len - b->len;
if( !res ) if( !res )
res = memcmp( a->name, b->name, a->len ); res = memcmp( a->name, b->name, a->len );

View File

@ -358,15 +358,14 @@ getkey_disable_caches()
static void static void
pk_from_block ( GETKEY_CTX ctx, pk_from_block ( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE keyblock )
PKT_public_key *pk, KBNODE keyblock, const char *namehash )
{ {
KBNODE a = ctx->found_key ? ctx->found_key : keyblock; KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
assert ( a->pkt->pkttype == PKT_PUBLIC_KEY assert ( a->pkt->pkttype == PKT_PUBLIC_KEY
|| a->pkt->pkttype == PKT_PUBLIC_SUBKEY ); || 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 static void
@ -435,7 +434,7 @@ get_pubkey( PKT_public_key *pk, u32 *keyid )
ctx.req_usage = pk->req_usage; ctx.req_usage = pk->req_usage;
rc = lookup( &ctx, &kb, 0 ); rc = lookup( &ctx, &kb, 0 );
if ( !rc ) { if ( !rc ) {
pk_from_block ( &ctx, pk, kb, NULL ); pk_from_block ( &ctx, pk, kb );
} }
get_pubkey_end( &ctx ); get_pubkey_end( &ctx );
release_kbnode ( kb ); release_kbnode ( kb );
@ -925,7 +924,7 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
} }
rc = lookup( ctx, ret_kb, 0 ); rc = lookup( ctx, ret_kb, 0 );
if ( !rc && pk ) { 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 ); rc = lookup( ctx, ret_keyblock, 0 );
if ( !rc && pk && ret_keyblock ) if ( !rc && pk && ret_keyblock )
pk_from_block ( ctx, pk, *ret_keyblock, NULL ); pk_from_block ( ctx, pk, *ret_keyblock );
return rc; return rc;
} }
@ -1020,7 +1019,7 @@ get_pubkey_byfprint( PKT_public_key *pk,
memcpy( ctx.items[0].fprint, fprint, fprint_len ); memcpy( ctx.items[0].fprint, fprint, fprint_len );
rc = lookup( &ctx, &kb, 0 ); rc = lookup( &ctx, &kb, 0 );
if (!rc && pk ) if (!rc && pk )
pk_from_block ( &ctx, pk, kb, NULL ); pk_from_block ( &ctx, pk, kb );
release_kbnode ( kb ); release_kbnode ( kb );
get_pubkey_end( &ctx ); 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 static void
fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated ) fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
{ {
PKT_user_id *uid = uidnode->pkt->pkt.user_id; PKT_user_id *uid = uidnode->pkt->pkt.user_id;
PKT_signature *sig = signode->pkt->pkt.signature; PKT_signature *sig = signode->pkt->pkt.signature;
const byte *p; const byte *p, *sym, *hash, *zip;
size_t n; size_t n, nsym, nhash, nzip;
uid->created = 0; /* not created == invalid */ uid->created = 0; /* not created == invalid */
if ( IS_UID_REV ( sig ) ) { 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 /* 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; uid->is_primary = 0;
p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL ); p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL );
if ( p && *p ) if ( p && *p )
@ -1445,6 +1453,43 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
* there should be no security problem with this. * there should be no security problem with this.
* For now we only look at the hashed one. * 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 static void
@ -1800,6 +1845,7 @@ merge_selfsigs( KBNODE keyblock )
KBNODE k; KBNODE k;
int revoked; int revoked;
PKT_public_key *main_pk; PKT_public_key *main_pk;
prefitem_t *prefs;
if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) { if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) {
if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) { if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) {
@ -1836,6 +1882,33 @@ merge_selfsigs( KBNODE keyblock )
merge_selfsigs_subkey ( keyblock, k ); 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 *********************** ************* Find stuff ***********************
************************************************/ ************************************************/
static int static PKT_user_id *
find_by_name( KBNODE keyblock, const char *name, find_by_name( KBNODE keyblock, const char *name, int mode )
int mode, byte *namehash )
{ {
KBNODE k; KBNODE k;
@ -1965,23 +2037,11 @@ find_by_name( KBNODE keyblock, const char *name,
if( k->pkt->pkttype == PKT_USER_ID if( k->pkt->pkttype == PKT_USER_ID
&& !compare_name( k->pkt->pkt.user_id->name, && !compare_name( k->pkt->pkt.user_id->name,
k->pkt->pkt.user_id->len, name, mode)) { k->pkt->pkt.user_id->len, name, mode)) {
/* we found a matching name, look for the key */ return k->pkt->pkt.user_id;
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 0; return NULL;
} }
@ -2068,7 +2128,7 @@ find_by_fpr( KBNODE keyblock, const char *name, int mode )
*/ */
static int 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 keyblock = ctx->keyblock;
KBNODE k; KBNODE k;
@ -2098,6 +2158,10 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
} }
if (!req_usage) { 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; ctx->found_key = foundk;
cache_user_id( keyblock ); cache_user_id( keyblock );
return 1; /* found */ return 1; /* found */
@ -2200,6 +2264,13 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
log_debug( "\tusing key %08lX\n", log_debug( "\tusing key %08lX\n",
(ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) ); (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; ctx->found_key = latest_key;
if (latest_key != keyblock && opt.verbose) { if (latest_key != keyblock && opt.verbose) {
@ -2220,8 +2291,6 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
{ {
int rc; int rc;
int oldmode = set_packet_list_mode(0); int oldmode = set_packet_list_mode(0);
byte namehash[20];
int use_namehash=0;
KBNODE secblock = NULL; /* helper */ KBNODE secblock = NULL; /* helper */
int no_suitable_key = 0; 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++ ) { for(n=0; n < ctx->nitems; n++, item++ ) {
KBNODE k = NULL; KBNODE k = NULL;
int found = 0; int found = 0;
PKT_user_id *found_uid = NULL;
if( item->mode < 10 ) { if( item->mode < 10 ) {
found = find_by_name( ctx->keyblock, found_uid = find_by_name( ctx->keyblock,
item->name, item->mode, item->name, item->mode );
namehash ); found = !!found_uid;
use_namehash = found;
} }
else if( item->mode >= 10 && item->mode <= 12 ) { else if( item->mode >= 10 && item->mode <= 12 ) {
k = find_by_keyid( ctx->keyblock, k = find_by_keyid( ctx->keyblock,
@ -2287,7 +2356,7 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
if( found ) { if( found ) {
/* this keyblock looks fine - do further investigation */ /* this keyblock looks fine - do further investigation */
merge_selfsigs ( ctx->keyblock ); merge_selfsigs ( ctx->keyblock );
if ( finish_lookup( ctx, k ) ) { if ( finish_lookup( ctx, k, found_uid ) ) {
no_suitable_key = 0; no_suitable_key = 0;
if ( secmode ) { if ( secmode ) {
merge_public_with_secret ( ctx->keyblock, merge_public_with_secret ( ctx->keyblock,

View File

@ -40,7 +40,7 @@
#include "status.h" #include "status.h"
#include "i18n.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, static void show_key_with_all_names( KBNODE keyblock,
int only_marked, int with_fpr, int with_subkeys, int with_prefs ); int only_marked, int with_fpr, int with_subkeys, int with_prefs );
static void show_key_and_fingerprint( KBNODE keyblock ); 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? "))){ _("Really update the preferences? "))){
if ( menu_set_preferences (keyblock, sec_keyblock) ) { if ( menu_set_preferences (keyblock, sec_keyblock) ) {
update_trust_record (keyblock, 0, NULL);
merge_keys_and_selfsig (keyblock); merge_keys_and_selfsig (keyblock);
modified = 1; modified = 1;
redisplay = 1; redisplay = 1;
@ -1065,49 +1064,31 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
* show preferences of a public keyblock. * show preferences of a public keyblock.
*/ */
static void 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 ); const prefitem_t *prefs;
PKT_public_key *pk;
byte *p;
int i; int i;
size_t n;
byte namehash[20];
if( !node ) if( !uid || !uid->prefs )
return; /* is a secret keyblock */
pk = node->pkt->pkt.public_key;
if( !pk->local_id ) {
log_error("oops: no LID\n");
return; return;
} prefs = uid->prefs;
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 (verbose) { if (verbose) {
int any, des_seen=0; int any, des_seen=0;
tty_printf (" Cipher: "); tty_printf (" Cipher: ");
for(i=any=0; i < n; i+=2 ) { for(i=any=0; prefs[i].type; i++ ) {
if( p[i] == PREFTYPE_SYM ) { if( prefs[i].type == PREFTYPE_SYM ) {
const char *s = cipher_algo_to_string (p[i+1]); const char *s = cipher_algo_to_string (prefs[i].value);
if (any) if (any)
tty_printf (", "); tty_printf (", ");
any = 1; any = 1;
/* We don't want to display strings for experimental algos */ /* 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 ); tty_printf ("%s", s );
else else
tty_printf ("[%d]", p[i+1]); tty_printf ("[%d]", prefs[i].value);
if (p[i+1] == CIPHER_ALGO_3DES ) if (prefs[i].value == CIPHER_ALGO_3DES )
des_seen = 1; des_seen = 1;
} }
} }
@ -1117,34 +1098,32 @@ show_prefs( KBNODE keyblock, PKT_user_id *uid, int verbose )
tty_printf ("3DES"); tty_printf ("3DES");
} }
tty_printf ("\n Hash: "); tty_printf ("\n Hash: ");
for(i=any=0; i < n; i+=2 ) { for(i=any=0; prefs[i].type; i++ ) {
if( p[i] == PREFTYPE_HASH ) { if( prefs[i].type == PREFTYPE_HASH ) {
const char *s = digest_algo_to_string (p[i+1]); const char *s = digest_algo_to_string (prefs[i].value);
if (any) if (any)
tty_printf (", "); tty_printf (", ");
any = 1; any = 1;
/* We don't want to display strings for experimental algos */ /* 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 ); tty_printf ("%s", s );
else else
tty_printf ("[%d]", p[i+1]); tty_printf ("[%d]", prefs[i].value);
} }
} }
tty_printf("\n"); tty_printf("\n");
} }
else { else {
tty_printf(" "); tty_printf(" ");
for(i=0; i < n; i+=2 ) { for(i=0; prefs[i].type; i++ ) {
if( p[i] ) tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
tty_printf( " %c%d", p[i] == PREFTYPE_SYM ? 'S' : prefs[i].type == PREFTYPE_HASH ? 'H' :
p[i] == PREFTYPE_HASH ? 'H' : prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
p[i] == PREFTYPE_COMPR ? 'Z':'?', p[i+1]); prefs[i].value);
} }
tty_printf("\n"); 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_print_utf8_string( uid->name, uid->len );
tty_printf("\n"); tty_printf("\n");
if( with_prefs ) 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 */ /* insert/append to secret keyblock */
pkt = m_alloc_clear( sizeof *pkt ); pkt = m_alloc_clear( sizeof *pkt );
pkt->pkttype = PKT_USER_ID; 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); node = new_kbnode(pkt);
if( sec_where ) if( sec_where )
insert_kbnode( sec_where, node, 0 ); insert_kbnode( sec_where, node, 0 );

View File

@ -62,6 +62,17 @@ typedef enum {
CTRLPKT_PLAINTEXT_MARK =3 CTRLPKT_PLAINTEXT_MARK =3
} ctrlpkttype_t; } 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 { typedef struct {
int mode; int mode;
@ -102,6 +113,7 @@ typedef struct {
byte data[1]; byte data[1];
} subpktarea_t; } subpktarea_t;
typedef struct { typedef struct {
ulong local_id; /* internal use, valid if > 0 */ ulong local_id; /* internal use, valid if > 0 */
struct { struct {
@ -123,6 +135,21 @@ typedef struct {
} PKT_signature; } 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 * 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 * 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 */ ulong local_id; /* internal use, valid if > 0 */
u32 main_keyid[2]; /* keyid of the primary key */ u32 main_keyid[2]; /* keyid of the primary key */
u32 keyid[2]; /* calculated by keyid_from_pk() */ 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 */ byte *namehash; /* if != NULL: found by this name */
PKT_user_id *user_id; /* if != NULL: found by that uid */
MPI pkey[PUBKEY_MAX_NPKEY]; MPI pkey[PUBKEY_MAX_NPKEY];
} PKT_public_key; } PKT_public_key;
@ -183,18 +212,6 @@ typedef struct {
char data[1]; char data[1];
} PKT_comment; } 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 { typedef struct {
u32 len; /* reserved */ u32 len; /* reserved */
byte new_ctb; 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_user_id( PKT_user_id *uid );
void free_comment( PKT_comment *rem ); void free_comment( PKT_comment *rem );
void free_packet( PACKET *pkt ); 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( 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 ); 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_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
PKT_signature *copy_signature( PKT_signature *d, PKT_signature *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_public_keys( PKT_public_key *a, PKT_public_key *b );
int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b ); int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
int cmp_signatures( PKT_signature *a, PKT_signature *b ); int cmp_signatures( PKT_signature *a, PKT_signature *b );

View File

@ -1590,6 +1590,7 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
byte *p; byte *p;
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + pktlen); 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->len = pktlen;
packet->pkt.user_id->photo = NULL; packet->pkt.user_id->photo = NULL;
packet->pkt.user_id->photolen = 0; 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->created = 0;
packet->pkt.user_id->help_key_usage = 0; packet->pkt.user_id->help_key_usage = 0;
packet->pkt.user_id->help_key_expire = 0; packet->pkt.user_id->help_key_expire = 0;
packet->pkt.user_id->prefs = NULL;
p = packet->pkt.user_id->name; p = packet->pkt.user_id->name;
for( ; pktlen; pktlen--, p++ ) for( ; pktlen; pktlen--, p++ )
@ -1630,6 +1632,7 @@ parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
byte *p; byte *p;
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 30); 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 ); 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->len = strlen(packet->pkt.user_id->name);
packet->pkt.user_id->is_primary = 0; 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->created = 0;
packet->pkt.user_id->help_key_usage = 0; packet->pkt.user_id->help_key_usage = 0;
packet->pkt.user_id->help_key_expire = 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->photo = m_alloc(sizeof *packet->pkt.user_id + pktlen);
packet->pkt.user_id->photolen = pktlen; packet->pkt.user_id->photolen = pktlen;

View File

@ -1036,13 +1036,15 @@ algo_available( int preftype, int algo )
else if( preftype == PREFTYPE_HASH ) { else if( preftype == PREFTYPE_HASH ) {
return algo && !check_digest_algo( algo ); return algo && !check_digest_algo( algo );
} }
else if( preftype == PREFTYPE_COMPR ) { else if( preftype == PREFTYPE_ZIP ) {
return !algo || algo == 1 || algo == 2; return !algo || algo == 1 || algo == 2;
} }
else else
return 0; return 0;
} }
/**************** /****************
* Return -1 if we could not find an algorithm. * 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; PK_LIST pkr;
u32 bits[8]; u32 bits[8];
byte *pref = NULL; const prefitem_t *prefs;
size_t npref;
int i, j; int i, j;
int compr_hack=0; int compr_hack=0;
int any; int any;
@ -1065,43 +1066,38 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
u32 mask[8]; u32 mask[8];
memset( mask, 0, 8 * sizeof *mask ); 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 ) if( preftype == PREFTYPE_SYM )
mask[0] |= (1<<2); /* 3DES is implicitly there */ 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; any = 0;
if( pref ) { if( prefs ) {
#if 0 for (i=0; prefs[i].type; i++ ) {
log_hexdump("raw: ", pref, npref ); if( prefs[i].type == preftype ) {
#endif mask[prefs[i].value/32] |= 1 << (prefs[i].value%32);
for(i=0; i+1 < npref; i+=2 ) {
if( pref[i] == preftype ) {
mask[pref[i+1]/32] |= 1 << (pref[i+1]%32);
any = 1; any = 1;
} }
} }
} }
if( (!pref || !any) && preftype == PREFTYPE_COMPR ) {
if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) {
mask[0] |= 3; /* asume no_compression and old pgp */ mask[0] |= 3; /* asume no_compression and old pgp */
compr_hack = 1; compr_hack = 1;
} }
#if 0 #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[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
(ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]); (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);
#endif #endif
for(i=0; i < 8; i++ ) for(i=0; i < 8; i++ )
bits[i] &= mask[i]; bits[i] &= mask[i];
#if 0 #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[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
(ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]); (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);
#endif #endif
@ -1114,20 +1110,20 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
*/ */
i = -1; i = -1;
any = 0; any = 0;
if( pref ) { if( prefs ) {
for(j=0; j+1 < npref; j+=2 ) { for(j=0; prefs[j].type; j++ ) {
if( pref[j] == preftype ) { if( prefs[j].type == preftype ) {
if( (bits[pref[j+1]/32] & (1<<(pref[j+1]%32))) ) { if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) {
if( algo_available( preftype, pref[j+1] ) ) { if( algo_available( preftype, prefs[j].value ) ) {
any = 1; any = 1;
i = pref[j+1]; i = prefs[j].value;
break; break;
} }
} }
} }
} }
} }
if( !pref || !any ) { if( !prefs || !any ) {
for(j=0; j < 256; j++ ) for(j=0; j < 256; j++ )
if( (bits[j/32] & (1<<(j%32))) ) { if( (bits[j/32] & (1<<(j%32))) ) {
if( algo_available( preftype, j ) ) { 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 */ i = 1; /* yep; we can use compression algo 1 */
} }
m_free(pref);
return i; return i;
} }

View File

@ -37,6 +37,29 @@
static int get_it( PKT_pubkey_enc *k, static int get_it( PKT_pubkey_enc *k,
DEK *dek, PKT_secret_key *sk, u32 *keyid ); 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 * Get the session key from a pubkey enc paket and return
* it in DEK, which should have been allocated in secure memory. * 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 ); log_hexdump("DEK is:", dek->key, dek->keylen );
/* check that the algo is in the preferences and whether it has expired */ /* check that the algo is in the preferences and whether it has expired */
{ {
PKT_public_key *pk = m_alloc_clear( sizeof *pk ); PKT_public_key *pk = NULL;
if( (rc = get_pubkey( pk, keyid )) ) KBNODE pkb = get_pubkeyblock (keyid);
log_error("public key problem: %s\n", g10_errstr(rc) );
else if( !pk->local_id && query_trust_record(pk) ) if( !pkb ) {
log_error("can't check algorithm against preferences\n"); rc = -1;
log_error("oops: public key not found for preference check\n");
}
else if( dek->algo != CIPHER_ALGO_3DES 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, /* Don't print a note while we are not on verbose mode,
* the cipher is blowfish and the preferences have twofish * the cipher is blowfish and the preferences have twofish
* listed */ * listed */
if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
|| !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, || !is_algo_in_prefs( pkb, PREFTYPE_SYM, CIPHER_ALGO_TWOFISH))
CIPHER_ALGO_TWOFISH ) )
log_info(_( log_info(_(
"NOTE: cipher algorithm %d not found in preferences\n"), "NOTE: cipher algorithm %d not found in preferences\n"),
dek->algo ); dek->algo );
} }
if (!rc) {
KBNODE k;
if( !rc && pk->expiredate && pk->expiredate <= make_timestamp() ) { 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 (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"), log_info(_("NOTE: secret key %08lX expired at %s\n"),
(ulong)keyid[1], asctimestamp( pk->expiredate) ); (ulong)keyid[1], asctimestamp( pk->expiredate) );
} }
}
/* FIXME: check wheter the key has been revoked and display /* FIXME: check wheter the key has been revoked and display
* the revocation reason. Actually the user should know this himself, * 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 * the message. The user can than watch out for snakes send by
* one of those Eves outside his paradise :-) * one of those Eves outside his paradise :-)
*/ */
free_public_key( pk ); release_kbnode (pkb);
rc = 0; rc = 0;
} }

View File

@ -292,7 +292,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) ) if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) )
goto leave; goto leave;
if( !old_style ) 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 */ /* prepare iobufs */

View File

@ -1161,7 +1161,7 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
if( *p ) if( *p )
fprintf(fp, " %c%d", *p == PREFTYPE_SYM ? 'S' : fprintf(fp, " %c%d", *p == PREFTYPE_SYM ? 'S' :
*p == PREFTYPE_HASH ? 'H' : *p == PREFTYPE_HASH ? 'H' :
*p == PREFTYPE_COMPR ? 'Z' : '?', p[1]); *p == PREFTYPE_ZIP ? 'Z' : '?', p[1]);
} }
putc('\n', fp); putc('\n', fp);
break; break;

View File

@ -125,7 +125,7 @@ struct trust_record {
/* or 0 for a global pref record */ /* or 0 for a global pref record */
ulong next; /* points to next pref record */ ulong next; /* points to next pref record */
byte data[ITEMS_PER_PREF_RECORD]; byte data[ITEMS_PER_PREF_RECORD];
} pref; } pref; /* pref records are not anymore used! */
struct { /* signature record */ struct { /* signature record */
ulong lid; ulong lid;
ulong next; /* recnno of next record or NULL for last one */ ulong next; /* recnno of next record or NULL for last one */

View File

@ -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 static ulong
make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire, 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 ); lid, &bestsig );
if( (u->r.uid.uidflags & UIDF_CHECKED) if( (u->r.uid.uidflags & UIDF_CHECKED)
&& (u->r.uid.uidflags & UIDF_VALID) ) { && (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 /* 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 ) { for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
read_record( recno, &urec, RECTYPE_UID ); read_record( recno, &urec, RECTYPE_UID );
for(r2=urec.r.uid.prefrec ; r2; r2 = prec.r.pref.next ) { 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 ); read_record( r2, &prec, RECTYPE_PREF );
delete_record( r2 ); 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;
}

View File

@ -37,11 +37,6 @@
#define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */ #define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */
#define PREFTYPE_SYM 1
#define PREFTYPE_HASH 2
#define PREFTYPE_COMPR 3
/*-- trustdb.c --*/ /*-- trustdb.c --*/
void list_trust_path( const char *username ); void list_trust_path( const char *username );
void register_trusted_key( const char *string ); 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 ); int refresh, ulong selected_lid );
unsigned get_ownertrust( ulong lid ); unsigned get_ownertrust( ulong lid );
int get_ownertrust_info( 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 ); int keyid_from_lid( ulong lid, u32 *keyid );
ulong lid_from_keyblock( KBNODE keyblock ); ulong lid_from_keyblock( KBNODE keyblock );
int query_trust_record( PKT_public_key *pk ); int query_trust_record( PKT_public_key *pk );

View File

@ -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> 2001-07-09 Werner Koch <wk@gnupg.org>
* config.links: Changed the way the list of files to be * config.links: Changed the way the list of files to be

View File

@ -198,8 +198,8 @@ case "${target}" in
path="powerpc32" path="powerpc32"
;; ;;
powerpc*-*-netbsd*) powerpc*-*-netbsd* | powerpc*-*-openbsd*)
echo '/* configured NetBSD on powerpc */' >>./mpi/asm-syntax.h echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
mpi_sflags="-Wa,-mppc" mpi_sflags="-Wa,-mppc"