mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
intermediate check in
This commit is contained in:
parent
6fbee8ab86
commit
9b609091ab
5
NEWS
5
NEWS
@ -35,11 +35,16 @@ Noteworthy changes in version 0.3.3
|
||||
|
||||
* gpg now disables core dumps.
|
||||
|
||||
* compress and symmetric cipher preferences are now used.
|
||||
Because there is no 3DES yet, this is replaced by Blowfish.
|
||||
|
||||
* We have added the Twofish as an experimental cipher algorithm.
|
||||
Many thanks to Matthew Skala for doing this work.
|
||||
Twofish is the AES submission from Schneier et al.; see
|
||||
"www.counterpane.com/twofish.html" for more information.
|
||||
|
||||
* [talk about --emulate-encr-mpi-bug]
|
||||
|
||||
|
||||
|
||||
Noteworthy changes in version 0.3.2
|
||||
|
5
README
5
README
@ -22,7 +22,7 @@
|
||||
"pub 1312G/FF3EAA0B 1998-02-09 Werner Koch <wk@isil.d.shuttle.de>"
|
||||
"Key fingerprint = 8489 6CD0 1851 0E33 45DA CD67 036F 11B8 FF3E AA0B"
|
||||
|
||||
My standard key is now:
|
||||
My usual key is now:
|
||||
"pub 1024D/621CC013 1998-07-07 Werner Koch <werner.koch@guug.de>"
|
||||
"Key fingerprint = ECAF 7590 EB34 43B5 C7CF 3ACB 6C7E E1B8 621C C013"
|
||||
|
||||
@ -42,7 +42,8 @@
|
||||
IDEA (which is patented worldwide) and RSA (which is patented in
|
||||
the United States until Sep 20, 2000).
|
||||
|
||||
GNUPG is in most aspects compatible with other OpenPGP implementations.
|
||||
GNUPG is in almost all aspects compatible with other OpenPGP
|
||||
implementations.
|
||||
|
||||
The default algorithms are now DSA and ELGamal. ELGamal for signing
|
||||
is still available, but due to the larger size of such signatures it
|
||||
|
1
THANKS
1
THANKS
@ -29,6 +29,7 @@ Nicolas Graner Nicolas.Graner@cri.u-psud.fr
|
||||
Oskari Jääskeläinen f33003a@cc.hut.fi
|
||||
Peter Gutmann pgut001@cs.auckland.ac.nz
|
||||
Ralph Gillen gillen@theochem.uni-duesseldorf.de
|
||||
Serge Munhoven munhoven@mema.ucl.ac.be
|
||||
Steffen Ullrich ccrlphr@xensei.com
|
||||
Thomas Roessler roessler@guug.de
|
||||
Tom Spindler dogcow@home.merit.edu
|
||||
|
17
TODO
17
TODO
@ -1,5 +1,7 @@
|
||||
* Fix Oscaris problems with the trustdb.
|
||||
|
||||
* Replace the SIGUSR1 stuff by semaphores to avoid loss of a signal.
|
||||
|
||||
* add test cases for invalid data (scrambled armor or other random data)
|
||||
|
||||
* fix the expire stuff for v4 packets.
|
||||
@ -8,14 +10,16 @@
|
||||
sig) into a compressed packet - or should we only compress the data?
|
||||
what does pgp 5 do, what does OpenPGP say=
|
||||
|
||||
* invalid packets (Marco)
|
||||
* invalid packets (Marco) und Markus Gruber
|
||||
|
||||
* add some sanity checks to read_keyblock, so that we are sure that
|
||||
the minimal requirements are met (?)
|
||||
the minimal requirements are met (?)
|
||||
|
||||
* what about the CR,LF in cleartext singatures?
|
||||
|
||||
* make preferences work
|
||||
* decryption of message with multiple recipients does not work.
|
||||
|
||||
* preferences of hash algorithms are not yet used.
|
||||
|
||||
* rewrite --list-packets or put it into another tool.
|
||||
|
||||
@ -25,8 +29,6 @@
|
||||
* Burn the buffers used by fopen(), or use read(2). Does this
|
||||
really make sense?
|
||||
|
||||
* enable a SIGSEGV handler while using zlib functions
|
||||
|
||||
* Change the buffering to a mbuf like scheme? Need it for PSST anyway.
|
||||
* add checking of armor trailers
|
||||
* remove all "Fixmes"
|
||||
@ -40,3 +42,8 @@
|
||||
|
||||
* replace getkey.c#enum_secret_keys
|
||||
|
||||
* OpenBSD has sometimes problems reading from /dev/random.
|
||||
|
||||
* change the fake_data stuff to mpi_set_opaque
|
||||
|
||||
|
||||
|
@ -128,6 +128,7 @@ Record type 5: (pref record)
|
||||
1 u32 LID; points to the directory record (and not to the uid record!).
|
||||
(or 0 for standard preference record)
|
||||
1 u32 next
|
||||
30 byte preference data
|
||||
|
||||
Record type 6 (sigrec)
|
||||
-------------
|
||||
|
@ -130,8 +130,6 @@ B<--edit-key> I<name>
|
||||
Remove a subkey.
|
||||
B<passwd>
|
||||
Change the passphrase of the secret key.
|
||||
B<check>
|
||||
Check signatures
|
||||
B<uid> I<n>
|
||||
Toggle selection of user id with index I<n>.
|
||||
Use 0 to deselect all.
|
||||
@ -140,6 +138,8 @@ B<--edit-key> I<name>
|
||||
Use 0 to deselect all.
|
||||
B<check>
|
||||
Check all selected user ids.
|
||||
B<pref>
|
||||
List preferences.
|
||||
B<toggle>
|
||||
Toggle between public and secret key listing.
|
||||
B<save>
|
||||
@ -316,7 +316,8 @@ B<--marginals-needed> I<n>
|
||||
B<--cipher-algo> I<name>
|
||||
Use I<name> as cipher algorithm. Running the program
|
||||
with the option B<--verbose> yields a list of supported
|
||||
algorithms.
|
||||
algorithms. If this is not used the cipher algorithm is
|
||||
selected from the preferences stored with the key.
|
||||
|
||||
B<--digest-algo> I<name>
|
||||
Use I<name> as message digest algorithm. Running the
|
||||
@ -329,6 +330,8 @@ B<--compress-algo> I<number>
|
||||
version which is used by PGP. This is only used for
|
||||
new messages. The default algorithm may give better
|
||||
results because the window size is not limited to 8K.
|
||||
If this is not used the OpenPGP behaviour is used; i.e.
|
||||
the compression algorith is selected from the preferences.
|
||||
|
||||
B<--passphrase-fd> I<n>
|
||||
Read the passphrase from file descriptor I<n>. If you use
|
||||
|
@ -1,3 +1,27 @@
|
||||
Wed Aug 5 11:54:37 1998 Werner Koch (wk@(none))
|
||||
|
||||
* g10.c (check_opts): Moved to main. Changed def_cipher_algo
|
||||
semantics and chnaged all users.
|
||||
|
||||
* pubkey-enc.c (get_sssion_key): New informational output
|
||||
about preferences.
|
||||
|
||||
* parse-packet.c (parse_symkeyenc): Fixed salted+iterated S2K
|
||||
(parse_key): Ditto.
|
||||
* build-packet.c (do_secret_key): Ditto.
|
||||
(do_symkey_enc): Ditto.
|
||||
|
||||
Tue Aug 4 08:59:10 1998 Werner Koch (wk@(none))
|
||||
|
||||
* getkey.c (enum_secret_keys): Now returns only primary keys.
|
||||
|
||||
* getkey (lookup): Now sets the new namehash field.
|
||||
|
||||
* parse-packet.c (parse_sig_subpkt2): New.
|
||||
|
||||
* sign.c (sign_file): one-pass sigs are now emiited reverse.
|
||||
Preference data is considered when selecting the compress algo.
|
||||
|
||||
Wed Jul 29 12:53:03 1998 Werner Koch (wk@(none))
|
||||
|
||||
* free-packet.c (copy_signature): New.
|
||||
|
@ -301,18 +301,24 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
|
||||
iobuf_put(a, sk->protect.s2k.mode );
|
||||
iobuf_put(a, sk->protect.s2k.hash_algo );
|
||||
if( sk->protect.s2k.mode == 1
|
||||
|| sk->protect.s2k.mode == 4 )
|
||||
|| sk->protect.s2k.mode == 3 )
|
||||
iobuf_write(a, sk->protect.s2k.salt, 8 );
|
||||
if( sk->protect.s2k.mode == 4 )
|
||||
write_32(a, sk->protect.s2k.count );
|
||||
if( sk->protect.s2k.mode == 3 )
|
||||
iobuf_put(a, sk->protect.s2k.count );
|
||||
iobuf_write(a, sk->protect.iv, 8 );
|
||||
}
|
||||
}
|
||||
else
|
||||
iobuf_put(a, 0 );
|
||||
for( ; i < nskey; i++ )
|
||||
mpi_write(a, sk->skey[i] );
|
||||
write_16(a, sk->csum );
|
||||
if( sk->is_protected && sk->version >= 4
|
||||
&& !(opt.emulate_bugs & EMUBUG_ENCR_MPI) ) {
|
||||
BUG();
|
||||
}
|
||||
else {
|
||||
for( ; i < nskey; i++ )
|
||||
mpi_write(a, sk->skey[i] );
|
||||
write_16(a, sk->csum );
|
||||
}
|
||||
|
||||
leave:
|
||||
write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 );
|
||||
@ -331,17 +337,17 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
|
||||
|
||||
assert( enc->version == 4 );
|
||||
switch( enc->s2k.mode ) {
|
||||
case 0: case 1: case 4: break;
|
||||
case 0: case 1: case 3: break;
|
||||
default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
|
||||
}
|
||||
iobuf_put( a, enc->version );
|
||||
iobuf_put( a, enc->cipher_algo );
|
||||
iobuf_put( a, enc->s2k.mode );
|
||||
iobuf_put( a, enc->s2k.hash_algo );
|
||||
if( enc->s2k.mode == 1 || enc->s2k.mode == 4 ) {
|
||||
if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) {
|
||||
iobuf_write(a, enc->s2k.salt, 8 );
|
||||
if( enc->s2k.mode == 4 )
|
||||
write_32(a, enc->s2k.count);
|
||||
if( enc->s2k.mode == 3 )
|
||||
iobuf_put(a, enc->s2k.count);
|
||||
}
|
||||
if( enc->seskeylen )
|
||||
iobuf_write(a, enc->seskey, enc->seskeylen );
|
||||
|
35
g10/encode.c
35
g10/encode.c
@ -34,6 +34,7 @@
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "filter.h"
|
||||
#include "trustdb.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
@ -93,7 +94,9 @@ encode_simple( const char *filename, int mode )
|
||||
s2k->mode = opt.rfc1991? 0:1;
|
||||
s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
|
||||
: DEFAULT_DIGEST_ALGO;
|
||||
cfx.dek = passphrase_to_dek( NULL, opt.def_cipher_algo, s2k, 2 );
|
||||
cfx.dek = passphrase_to_dek( NULL,
|
||||
opt.def_cipher_algo ? opt.def_cipher_algo
|
||||
: DEFAULT_CIPHER_ALGO , s2k, 2 );
|
||||
if( !cfx.dek || !cfx.dek->keylen ) {
|
||||
rc = G10ERR_PASSPHRASE;
|
||||
m_free(cfx.dek);
|
||||
@ -218,7 +221,13 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
|
||||
/* create a session key */
|
||||
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
|
||||
cfx.dek->algo = opt.def_cipher_algo;
|
||||
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
||||
cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM );
|
||||
if( cfx.dek->algo == -1 )
|
||||
cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
||||
}
|
||||
else
|
||||
cfx.dek->algo = opt.def_cipher_algo;
|
||||
make_session_key( cfx.dek );
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
||||
@ -253,8 +262,16 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
/* register the cipher filter */
|
||||
iobuf_push_filter( out, cipher_filter, &cfx );
|
||||
/* register the compress filter */
|
||||
if( opt.compress )
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
if( opt.compress ) {
|
||||
int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
|
||||
if( !compr_algo )
|
||||
; /* don't use compression */
|
||||
else {
|
||||
if( compr_algo == 1 )
|
||||
zfx.algo = 1; /* default is 2 */
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
}
|
||||
}
|
||||
|
||||
/* do the work */
|
||||
if( (rc = build_packet( out, &pkt )) )
|
||||
@ -293,7 +310,15 @@ encrypt_filter( void *opaque, int control,
|
||||
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
||||
if( !efx->header_okay ) {
|
||||
efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek );
|
||||
efx->cfx.dek->algo = opt.def_cipher_algo;
|
||||
|
||||
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
||||
efx->cfx.dek->algo =
|
||||
select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM );
|
||||
if( efx->cfx.dek->algo == -1 )
|
||||
efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
||||
}
|
||||
else
|
||||
efx->cfx.dek->algo = opt.def_cipher_algo;
|
||||
make_session_key( efx->cfx.dek );
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is: ",
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "memory.h"
|
||||
#include "options.h"
|
||||
|
||||
void
|
||||
free_symkey_enc( PKT_symkey_enc *enc )
|
||||
@ -82,6 +83,10 @@ release_public_key_parts( PKT_public_key *pk )
|
||||
mpi_free( pk->pkey[i] );
|
||||
pk->pkey[i] = NULL;
|
||||
}
|
||||
if( pk->namehash ) {
|
||||
m_free(pk->namehash);
|
||||
pk->namehash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -123,13 +128,22 @@ cp_data_block( byte *s )
|
||||
|
||||
|
||||
PKT_public_key *
|
||||
copy_public_key( PKT_public_key *d, PKT_public_key *s )
|
||||
copy_public_key_new_namehash( PKT_public_key *d, PKT_public_key *s,
|
||||
const byte *namehash )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
n = pubkey_get_npkey( s->pubkey_algo );
|
||||
if( !n )
|
||||
d->pkey[0] = cp_fake_data(s->pkey[0]);
|
||||
@ -140,6 +154,11 @@ copy_public_key( 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 );
|
||||
}
|
||||
|
||||
PKT_signature *
|
||||
copy_signature( PKT_signature *d, PKT_signature *s )
|
||||
|
34
g10/g10.c
34
g10/g10.c
@ -173,6 +173,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ 559, "always-trust", 0, "@"},
|
||||
{ 562, "emulate-checksum-bug", 0, "@"},
|
||||
{ 554, "run-as-shm-coprocess", 4, "@" },
|
||||
{ 568, "emulate-encr-mpi-bug", 0, "@"},
|
||||
{0} };
|
||||
|
||||
|
||||
@ -361,24 +362,6 @@ set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd )
|
||||
|
||||
|
||||
|
||||
static void
|
||||
check_opts(void)
|
||||
{
|
||||
if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) )
|
||||
log_error(_("selected cipher algorithm is invalid\n"));
|
||||
if( opt.def_digest_algo && check_digest_algo(opt.def_digest_algo) )
|
||||
log_error(_("selected digest algorithm is invalid\n"));
|
||||
if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
|
||||
log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
|
||||
if( opt.completes_needed < 1 )
|
||||
log_error(_("completes-needed must be greater than 0\n"));
|
||||
if( opt.marginals_needed < 2 )
|
||||
log_error(_("marginals-needed must be greater than 1\n"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
@ -426,7 +409,7 @@ main( int argc, char **argv )
|
||||
i18n_init();
|
||||
opt.compress = -1; /* defaults to standard compress level */
|
||||
/* fixme: set the next two to zero and decide where used */
|
||||
opt.def_cipher_algo = DEFAULT_CIPHER_ALGO;
|
||||
opt.def_cipher_algo = 0;
|
||||
opt.def_digest_algo = 0;
|
||||
opt.def_compress_algo = 2;
|
||||
opt.completes_needed = 1;
|
||||
@ -615,6 +598,7 @@ main( int argc, char **argv )
|
||||
log_error("shared memory coprocessing is not available\n");
|
||||
#endif
|
||||
break;
|
||||
case 568: opt.emulate_bugs |= EMUBUG_ENCR_MPI; break;
|
||||
default : errors++; pargs.err = configfp? 1:2; break;
|
||||
}
|
||||
}
|
||||
@ -657,12 +641,22 @@ main( int argc, char **argv )
|
||||
if( def_cipher_string ) {
|
||||
opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
|
||||
m_free(def_cipher_string); def_cipher_string = NULL;
|
||||
if( check_cipher_algo(opt.def_cipher_algo) )
|
||||
log_error(_("selected cipher algorithm is invalid\n"));
|
||||
}
|
||||
if( def_digest_string ) {
|
||||
opt.def_digest_algo = string_to_digest_algo(def_digest_string);
|
||||
m_free(def_digest_string); def_digest_string = NULL;
|
||||
if( check_digest_algo(opt.def_digest_algo) )
|
||||
log_error(_("selected digest algorithm is invalid\n"));
|
||||
}
|
||||
check_opts();
|
||||
if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
|
||||
log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
|
||||
if( opt.completes_needed < 1 )
|
||||
log_error(_("completes-needed must be greater than 0\n"));
|
||||
if( opt.marginals_needed < 2 )
|
||||
log_error(_("marginals-needed must be greater than 1\n"));
|
||||
|
||||
if( log_get_errorcount(0) )
|
||||
g10_exit(2);
|
||||
|
||||
|
14
g10/getkey.c
14
g10/getkey.c
@ -685,6 +685,8 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
|
||||
KBNODE keyblock = NULL;
|
||||
KBPOS kbpos;
|
||||
int oldmode = set_packet_list_mode(0);
|
||||
byte namehash[20];
|
||||
int use_namehash=0;
|
||||
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
@ -719,6 +721,10 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
|
||||
u32 aki[2];
|
||||
keyid_from_pk( kk->pkt->pkt.public_key, aki );
|
||||
cache_user_id( k->pkt->pkt.user_id, aki );
|
||||
rmd160_hash_buffer( namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
use_namehash = 1;
|
||||
k = kk;
|
||||
break;
|
||||
}
|
||||
@ -799,7 +805,8 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
|
||||
if( k ) { /* found */
|
||||
assert( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||
copy_public_key( pk, k->pkt->pkt.public_key );
|
||||
copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
add_stuff_from_selfsig( keyblock, k );
|
||||
if( ret_keyblock ) {
|
||||
*ret_keyblock = keyblock;
|
||||
@ -950,7 +957,7 @@ lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name )
|
||||
|
||||
|
||||
/****************
|
||||
* Enumerate all secret keys. Caller must use these procedure:
|
||||
* Enumerate all primary secret keys. Caller must use these procedure:
|
||||
* 1) create a void pointer and initialize it to NULL
|
||||
* 2) pass this void pointer by reference to this function
|
||||
* and provide space for the secret key (pass a buffer for sk)
|
||||
@ -997,8 +1004,7 @@ enum_secret_keys( void **context, PKT_secret_key *sk )
|
||||
while( (rc=parse_packet(c->iobuf, &pkt)) != -1 ) {
|
||||
if( rc )
|
||||
; /* e.g. unknown packet */
|
||||
else if( pkt.pkttype == PKT_SECRET_KEY
|
||||
|| pkt.pkttype == PKT_SECRET_SUBKEY ) {
|
||||
else if( pkt.pkttype == PKT_SECRET_KEY ) {
|
||||
copy_secret_key( sk, pkt.pkt.secret_key );
|
||||
set_packet_list_mode(save_mode);
|
||||
return 0; /* found */
|
||||
|
@ -91,6 +91,7 @@ struct pubkey_find_info {
|
||||
int check_signatures_trust( PKT_signature *sig );
|
||||
void release_pk_list( PK_LIST pk_list );
|
||||
int build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage );
|
||||
int select_algo_from_prefs( PK_LIST pk_list, int preftype );
|
||||
|
||||
/*-- skclist.c --*/
|
||||
void release_sk_list( SK_LIST sk_list );
|
||||
|
@ -40,8 +40,9 @@
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static void show_prefs( KBNODE keyblock, PKT_user_id *uid );
|
||||
static void show_key_with_all_names( KBNODE keyblock,
|
||||
int only_marked, int with_fpr, int with_subkeys );
|
||||
int only_marked, int with_fpr, int with_subkeys, int with_prefs );
|
||||
static void show_key_and_fingerprint( KBNODE keyblock );
|
||||
static void show_fingerprint( PKT_public_key *pk );
|
||||
static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock );
|
||||
@ -256,7 +257,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified )
|
||||
}
|
||||
/* Ask whether we realy should sign these user id(s) */
|
||||
tty_printf("\n");
|
||||
show_key_with_all_names( keyblock, 1, 1, 0 );
|
||||
show_key_with_all_names( keyblock, 1, 1, 0, 0 );
|
||||
tty_printf("\n");
|
||||
tty_printf(_(
|
||||
"Are you really sure that you want to sign this key\n"
|
||||
@ -544,7 +545,7 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
enum cmdids { cmdNONE = 0,
|
||||
cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
|
||||
cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY,
|
||||
cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST,
|
||||
cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
|
||||
cmdNOP };
|
||||
static struct { const char *name;
|
||||
enum cmdids id;
|
||||
@ -573,6 +574,7 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
{ N_("toggle") , cmdTOGGLE , 1, N_("toggle between secret "
|
||||
"and public key listing") },
|
||||
{ N_("t" ) , cmdTOGGLE , 1, NULL },
|
||||
{ N_("pref") , cmdPREF , 0, N_("list preferences") },
|
||||
{ N_("passwd") , cmdPASSWD , 1, N_("change the passphrase") },
|
||||
{ N_("trust") , cmdTRUST , 0, N_("change the ownertrust") },
|
||||
|
||||
@ -625,7 +627,7 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
|
||||
tty_printf("\n");
|
||||
if( redisplay ) {
|
||||
show_key_with_all_names( cur_keyblock, 0, 0, 1 );
|
||||
show_key_with_all_names( cur_keyblock, 0, 0, 1, 0 );
|
||||
tty_printf("\n");
|
||||
redisplay = 0;
|
||||
}
|
||||
@ -670,7 +672,7 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
break;
|
||||
|
||||
case cmdQUIT:
|
||||
if( !modified )
|
||||
if( !modified && !sec_modified )
|
||||
goto leave;
|
||||
if( !cpr_get_answer_is_yes("keyedit.save",_("Save changes? ")) ) {
|
||||
if( cpr_enabled()
|
||||
@ -680,11 +682,13 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
}
|
||||
/* fall thru */
|
||||
case cmdSAVE:
|
||||
if( modified ) {
|
||||
rc = update_keyblock( &keyblockpos, keyblock );
|
||||
if( rc ) {
|
||||
log_error(_("update failed: %s\n"), g10_errstr(rc) );
|
||||
break;
|
||||
if( modified || sec_modified ) {
|
||||
if( modified ) {
|
||||
rc = update_keyblock( &keyblockpos, keyblock );
|
||||
if( rc ) {
|
||||
log_error(_("update failed: %s\n"), g10_errstr(rc) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( sec_modified ) {
|
||||
rc = update_keyblock( &sec_keyblockpos, sec_keyblock );
|
||||
@ -807,7 +811,7 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
break;
|
||||
|
||||
case cmdTRUST:
|
||||
show_key_with_all_names( keyblock, 0, 0, 1 );
|
||||
show_key_with_all_names( keyblock, 0, 0, 1, 0 );
|
||||
tty_printf("\n");
|
||||
if( edit_ownertrust( find_kbnode( keyblock,
|
||||
PKT_PUBLIC_KEY )->pkt->pkt.public_key->local_id, 1 ) )
|
||||
@ -816,6 +820,10 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
* are updated immediately */
|
||||
break;
|
||||
|
||||
case cmdPREF:
|
||||
show_key_with_all_names( keyblock, 0, 0, 0, 1 );
|
||||
break;
|
||||
|
||||
case cmdNOP:
|
||||
break;
|
||||
|
||||
@ -833,6 +841,45 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* show preferences of a public keyblock.
|
||||
*/
|
||||
static void
|
||||
show_prefs( KBNODE keyblock, PKT_user_id *uid )
|
||||
{
|
||||
KBNODE node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
|
||||
PKT_public_key *pk;
|
||||
byte *p;
|
||||
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;
|
||||
}
|
||||
|
||||
rmd160_hash_buffer( namehash, uid->name, uid->len );
|
||||
|
||||
p = get_pref_data( pk->local_id, namehash, &n );
|
||||
if( !p )
|
||||
return;
|
||||
|
||||
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]);
|
||||
}
|
||||
tty_printf("\n");
|
||||
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Display the key a the user ids, if only_marked is true, do only
|
||||
@ -840,7 +887,7 @@ keyedit_menu( const char *username, STRLIST locusr )
|
||||
*/
|
||||
static void
|
||||
show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
int with_fpr, int with_subkeys )
|
||||
int with_fpr, int with_subkeys, int with_prefs )
|
||||
{
|
||||
KBNODE node;
|
||||
int i;
|
||||
@ -850,6 +897,15 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
|
||||
PKT_public_key *pk = node->pkt->pkt.public_key;
|
||||
int otrust=0, trust=0;
|
||||
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
||||
/* do it here, so that debug messages don't clutter the
|
||||
* output */
|
||||
trust = query_trust_info(pk);
|
||||
otrust = get_ownertrust_info( pk->local_id );
|
||||
}
|
||||
|
||||
tty_printf("%s%c %4u%c/%08lX created: %s expires: %s",
|
||||
node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
|
||||
(node->flag & NODFLG_SELKEY)? '*':' ',
|
||||
@ -859,9 +915,6 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
datestr_from_pk(pk),
|
||||
expirestr_from_pk(pk) );
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
||||
int otrust, trust;
|
||||
trust = query_trust_info(pk);
|
||||
otrust = get_ownertrust_info( pk->local_id );
|
||||
tty_printf(" trust: %c/%c", otrust, trust );
|
||||
if( with_fpr )
|
||||
show_fingerprint( pk );
|
||||
@ -896,6 +949,8 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|
||||
tty_printf("(%d) ", i);
|
||||
tty_print_string( uid->name, uid->len );
|
||||
tty_printf("\n");
|
||||
if( with_prefs )
|
||||
show_prefs( keyblock, uid );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
g10/keygen.c
35
g10/keygen.c
@ -32,6 +32,7 @@
|
||||
#include "ttyio.h"
|
||||
#include "options.h"
|
||||
#include "keydb.h"
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
@ -389,7 +390,7 @@ ask_algo( int *ret_v4, int addmode )
|
||||
|
||||
*ret_v4 = 1;
|
||||
for(;;) {
|
||||
answer = tty_get(_("Your selection? "));
|
||||
answer = cpr_get("keygen.algo",_("Your selection? "));
|
||||
tty_kill_prompt();
|
||||
algo = *answer? atoi(answer): 1;
|
||||
m_free(answer);
|
||||
@ -433,7 +434,7 @@ ask_keysize( int algo )
|
||||
" highest suggested keysize is 2048 bits\n"),
|
||||
pubkey_algo_to_string(algo) );
|
||||
for(;;) {
|
||||
answer = tty_get(_("What keysize do you want? (1024) "));
|
||||
answer = cpr_get("keygen.size",_("What keysize do you want? (1024) "));
|
||||
tty_kill_prompt();
|
||||
nbits = *answer? atoi(answer): 1024;
|
||||
m_free(answer);
|
||||
@ -441,7 +442,7 @@ ask_keysize( int algo )
|
||||
tty_printf(_("DSA only allows keysizes from 512 to 1024\n"));
|
||||
else if( nbits < 768 )
|
||||
tty_printf(_("keysize too small; 768 is smallest value allowed.\n"));
|
||||
else if( nbits > 2048 ) {
|
||||
else if( nbits > 2048 && !cpr_enabled() ) {
|
||||
tty_printf(_("Keysizes larger than 2048 are not suggested because "
|
||||
"computations take REALLY long!\n"));
|
||||
if( tty_get_answer_is_yes(_(
|
||||
@ -452,7 +453,7 @@ ask_keysize( int algo )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( nbits > 1536 ) {
|
||||
else if( nbits > 1536 && !cpr_enabled() ) {
|
||||
if( tty_get_answer_is_yes(_(
|
||||
"Do you really need such a large keysize? ")) )
|
||||
break;
|
||||
@ -494,7 +495,7 @@ ask_valid_days()
|
||||
int mult;
|
||||
|
||||
m_free(answer);
|
||||
answer = tty_get(_("Key is valid for? (0) "));
|
||||
answer = cpr_get("keygen.valid",_("Key is valid for? (0) "));
|
||||
tty_kill_prompt();
|
||||
trim_spaces(answer);
|
||||
if( !*answer )
|
||||
@ -517,7 +518,8 @@ ask_valid_days()
|
||||
add_days_to_timestamp( make_timestamp(), valid_days )));
|
||||
}
|
||||
|
||||
if( tty_get_answer_is_yes(_("Is this correct (y/n)? ")) )
|
||||
if( !cpr_enabled()
|
||||
&& tty_get_answer_is_yes(_("Is this correct (y/n)? ")) )
|
||||
break;
|
||||
}
|
||||
m_free(answer);
|
||||
@ -556,7 +558,7 @@ ask_user_id( int mode )
|
||||
if( !aname ) {
|
||||
for(;;) {
|
||||
m_free(aname);
|
||||
aname = tty_get(_("Real name: "));
|
||||
aname = cpr_get("keygen.name",_("Real name: "));
|
||||
trim_spaces(aname);
|
||||
tty_kill_prompt();
|
||||
if( strpbrk( aname, "<([])>" ) )
|
||||
@ -572,7 +574,7 @@ ask_user_id( int mode )
|
||||
if( !amail ) {
|
||||
for(;;) {
|
||||
m_free(amail);
|
||||
amail = tty_get(_("Email address: "));
|
||||
amail = cpr_get("keygen.email",_("Email address: "));
|
||||
trim_spaces(amail);
|
||||
strlwr(amail);
|
||||
tty_kill_prompt();
|
||||
@ -592,7 +594,7 @@ ask_user_id( int mode )
|
||||
if( !acomment ) {
|
||||
for(;;) {
|
||||
m_free(acomment);
|
||||
acomment = tty_get(_("Comment: "));
|
||||
acomment = cpr_get("keygen.comment",_("Comment: "));
|
||||
trim_spaces(acomment);
|
||||
tty_kill_prompt();
|
||||
if( !*acomment )
|
||||
@ -622,9 +624,16 @@ ask_user_id( int mode )
|
||||
/* fixme: add a warning if this user-id already exists */
|
||||
for(;;) {
|
||||
char *ansstr = N_("NnCcEeOoQq");
|
||||
answer = tty_get(_(
|
||||
"Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "));
|
||||
tty_kill_prompt();
|
||||
|
||||
if( cpr_enabled() ) {
|
||||
answer = m_strdup(ansstr+6);
|
||||
answer[1] = 0;
|
||||
}
|
||||
else {
|
||||
answer = tty_get(_(
|
||||
"Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "));
|
||||
tty_kill_prompt();
|
||||
}
|
||||
if( strlen(answer) > 1 )
|
||||
;
|
||||
else if( *answer == ansstr[0] || *answer == ansstr[1] ) {
|
||||
@ -950,7 +959,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
assert(algo);
|
||||
nbits = ask_keysize( algo );
|
||||
ndays = ask_valid_days();
|
||||
if( !tty_get_answer_is_yes( _("Really create? ") ) )
|
||||
if( !cpr_enabled() && !tty_get_answer_is_yes( _("Really create? ") ) )
|
||||
goto leave;
|
||||
|
||||
if( passphrase ) {
|
||||
|
@ -171,6 +171,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|
||||
PKT_pubkey_enc *enc;
|
||||
int result = 0;
|
||||
|
||||
/* check whether the secret key is available and store in this case */
|
||||
c->last_was_session_key = 1;
|
||||
enc = pkt->pkt.pubkey_enc;
|
||||
/*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
|
||||
@ -208,7 +209,9 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
/*printf("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
|
||||
if( !c->dek && !c->last_was_session_key ) {
|
||||
/* assume this is old conventional encrypted data */
|
||||
c->dek = passphrase_to_dek( NULL, opt.def_cipher_algo, NULL, 0 );
|
||||
c->dek = passphrase_to_dek( NULL,
|
||||
opt.def_cipher_algo ? opt.def_cipher_algo
|
||||
: DEFAULT_CIPHER_ALGO, NULL, 0 );
|
||||
}
|
||||
else if( !c->dek )
|
||||
result = G10ERR_NO_SECKEY;
|
||||
@ -223,6 +226,8 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
}
|
||||
else {
|
||||
log_error(_("decryption failed: %s\n"), g10_errstr(result));
|
||||
/* FIXME: if this is secret key not available, try with
|
||||
* other keys */
|
||||
}
|
||||
free_packet(pkt);
|
||||
c->last_was_session_key = 0;
|
||||
@ -707,7 +712,9 @@ do_proc_packets( CTX c, IOBUF a )
|
||||
while( (rc=parse_packet(a, pkt)) != -1 ) {
|
||||
/* cleanup if we have an illegal data structure */
|
||||
if( c->dek && pkt->pkttype != PKT_ENCRYPTED ) {
|
||||
log_error("oops: valid pubkey enc packet not followed by data\n");
|
||||
/* FIXME: do we need to ave it in case we have no secret
|
||||
* key for one of the next reciepents- we should check it
|
||||
* here. */
|
||||
m_free(c->dek); c->dek = NULL; /* burn it */
|
||||
}
|
||||
|
||||
@ -889,7 +896,7 @@ proc_tree( CTX c, KBNODE node )
|
||||
/* ask for file and hash it */
|
||||
if( c->sigs_only )
|
||||
rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
|
||||
n1->pkt->pkt.onepass_sig->sig_class == 0x01 );
|
||||
n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
|
||||
else
|
||||
rc = ask_for_detached_datafile( &c->mfx,
|
||||
iobuf_get_fname(c->iobuf));
|
||||
|
@ -56,6 +56,7 @@ struct {
|
||||
|
||||
|
||||
#define EMUBUG_GPGCHKSUM 1
|
||||
#define EMUBUG_ENCR_MPI 2
|
||||
|
||||
#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */
|
||||
#define DBG_MPI_VALUE 2 /* debug mpi details */
|
||||
|
@ -112,6 +112,7 @@ typedef struct {
|
||||
byte pubkey_usage; /* for now only used to pass it to getkey() */
|
||||
ulong local_id; /* internal use, valid if > 0 */
|
||||
u32 keyid[2]; /* calculated by keyid_from_pk() */
|
||||
byte *namehash; /* if != NULL: found by this name */
|
||||
MPI pkey[PUBKEY_MAX_NPKEY];
|
||||
} PKT_public_key;
|
||||
|
||||
@ -235,6 +236,8 @@ int copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff );
|
||||
int skip_some_packets( IOBUF inp, unsigned n );
|
||||
const byte *parse_sig_subpkt( const byte *buffer,
|
||||
sigsubpkttype_t reqtype, size_t *ret_n );
|
||||
const byte *parse_sig_subpkt2( PKT_signature *sig,
|
||||
sigsubpkttype_t reqtype, size_t *ret_n );
|
||||
|
||||
/*-- build-packet.c --*/
|
||||
int build_packet( IOBUF inp, PACKET *pkt );
|
||||
@ -257,6 +260,9 @@ void free_user_id( PKT_user_id *uid );
|
||||
void free_comment( PKT_comment *rem );
|
||||
void free_packet( PACKET *pkt );
|
||||
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 );
|
||||
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 );
|
||||
|
@ -461,6 +461,25 @@ read_rest( IOBUF inp, ulong *r_pktlen )
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *
|
||||
read_rest2( IOBUF inp, size_t pktlen )
|
||||
{
|
||||
byte *p;
|
||||
int i;
|
||||
|
||||
if( iobuf_in_block_mode(inp) ) {
|
||||
log_error("read_rest: can't store stream data\n");
|
||||
p = NULL;
|
||||
}
|
||||
else {
|
||||
p = m_alloc( pktlen );
|
||||
for(i=0; pktlen; pktlen--, i++ )
|
||||
p[i] = iobuf_get(inp);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
@ -491,8 +510,8 @@ parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
case 1: /* salted s2k */
|
||||
minlen = 8;
|
||||
break;
|
||||
case 4: /* iterated+salted s2k */
|
||||
minlen = 12;
|
||||
case 3: /* iterated+salted s2k */
|
||||
minlen = 9;
|
||||
break;
|
||||
default:
|
||||
log_error("unknown S2K %d\n", s2kmode );
|
||||
@ -509,12 +528,12 @@ parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
k->cipher_algo = cipher_algo;
|
||||
k->s2k.mode = s2kmode;
|
||||
k->s2k.hash_algo = hash_algo;
|
||||
if( s2kmode == 1 || s2kmode == 4 ) {
|
||||
if( s2kmode == 1 || s2kmode == 3 ) {
|
||||
for(i=0; i < 8 && pktlen; i++, pktlen-- )
|
||||
k->s2k.salt[i] = iobuf_get_noeof(inp);
|
||||
}
|
||||
if( s2kmode == 4 ) {
|
||||
k->s2k.count = read_32(inp); pktlen -= 4;
|
||||
if( s2kmode == 3 ) {
|
||||
k->s2k.count = iobuf_get(inp); pktlen--;
|
||||
}
|
||||
k->seskeylen = seskeylen;
|
||||
for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
|
||||
@ -524,11 +543,11 @@ parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
if( list_mode ) {
|
||||
printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n",
|
||||
version, cipher_algo, s2kmode, hash_algo);
|
||||
if( s2kmode == 1 || s2kmode == 4 ) {
|
||||
if( s2kmode == 1 || s2kmode == 3 ) {
|
||||
printf("\tsalt ");
|
||||
for(i=0; i < 8; i++ )
|
||||
printf("%02x", k->s2k.salt[i]);
|
||||
if( s2kmode == 4 )
|
||||
if( s2kmode == 3 )
|
||||
printf(", count %lu\n", (ulong)k->s2k.count );
|
||||
printf("\n");
|
||||
}
|
||||
@ -675,6 +694,10 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
|
||||
if( n < 8 )
|
||||
break;
|
||||
return buffer;
|
||||
case SIGSUBPKT_PREF_SYM:
|
||||
case SIGSUBPKT_PREF_HASH:
|
||||
case SIGSUBPKT_PREF_COMPR:
|
||||
return buffer;
|
||||
case SIGSUBPKT_PRIV_ADD_SIG:
|
||||
/* because we use private data, we check the GNUPG marker */
|
||||
if( n < 24 )
|
||||
@ -693,6 +716,19 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
|
||||
}
|
||||
|
||||
|
||||
const byte *
|
||||
parse_sig_subpkt2( PKT_signature *sig, sigsubpkttype_t reqtype, size_t *ret_n )
|
||||
{
|
||||
const byte *p;
|
||||
|
||||
p = parse_sig_subpkt( sig->hashed_data, reqtype, ret_n );
|
||||
if( !p )
|
||||
p = parse_sig_subpkt( sig->unhashed_data, reqtype, ret_n );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PKT_signature *sig )
|
||||
@ -779,7 +815,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
log_error("signature packet without timestamp\n");
|
||||
else
|
||||
sig->timestamp = buffer_to_u32(p);
|
||||
p = parse_sig_subpkt( sig->unhashed_data, SIGSUBPKT_ISSUER, NULL );
|
||||
p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
|
||||
if( !p )
|
||||
log_error("signature packet without keyid\n");
|
||||
else {
|
||||
@ -959,7 +995,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
}
|
||||
|
||||
|
||||
if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
|
||||
if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
|
||||
PKT_secret_key *sk = pkt->pkt.secret_key;
|
||||
byte temp[8];
|
||||
|
||||
@ -990,7 +1026,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
switch( sk->protect.s2k.mode ) {
|
||||
case 1:
|
||||
case 4:
|
||||
case 3:
|
||||
for(i=0; i < 8 && pktlen; i++, pktlen-- )
|
||||
temp[i] = iobuf_get_noeof(inp);
|
||||
memcpy(sk->protect.s2k.salt, temp, 8 );
|
||||
@ -1001,7 +1037,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
break;
|
||||
case 1: if( list_mode ) printf( "\tsalted S2K" );
|
||||
break;
|
||||
case 4: if( list_mode ) printf( "\titer+salt S2K" );
|
||||
case 3: if( list_mode ) printf( "\titer+salt S2K" );
|
||||
break;
|
||||
default:
|
||||
if( list_mode )
|
||||
@ -1016,7 +1052,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
sk->protect.algo,
|
||||
sk->protect.s2k.hash_algo );
|
||||
if( sk->protect.s2k.mode == 1
|
||||
|| sk->protect.s2k.mode == 4 ) {
|
||||
|| sk->protect.s2k.mode == 3 ) {
|
||||
printf(", salt: ");
|
||||
for(i=0; i < 8; i++ )
|
||||
printf("%02x", sk->protect.s2k.salt[i]);
|
||||
@ -1024,13 +1060,13 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
if( sk->protect.s2k.mode == 4 ) {
|
||||
if( pktlen < 4 ) {
|
||||
if( sk->protect.s2k.mode == 3 ) {
|
||||
if( pktlen < 1 ) {
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
sk->protect.s2k.count = read_32(inp);
|
||||
pktlen -= 4;
|
||||
sk->protect.s2k.count = iobuf_get(inp);
|
||||
pktlen--;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1066,25 +1102,37 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
* If the user is so careless, not to protect his secret key,
|
||||
* we can assume, that he operates an open system :=(.
|
||||
* So we put the key into secure memory when we unprotect it. */
|
||||
|
||||
for(i=npkey; i < nskey; i++ ) {
|
||||
n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
if( sk->is_protected )
|
||||
mpi_set_protect_flag(sk->skey[i]);
|
||||
if( is_v4 && sk->is_protected && !(opt.emulate_bugs & EMUBUG_ENCR_MPI)){
|
||||
/* ugly; the length is encrypted too, so wee read all
|
||||
* stuff up to the end of the packet into the first
|
||||
* skey element */
|
||||
sk->skey[npkey] = mpi_set_opaque(NULL,
|
||||
read_rest2(inp, pktlen), pktlen );
|
||||
pktlen = 0;
|
||||
if( list_mode ) {
|
||||
printf( "\tskey[%d]: ", i);
|
||||
if( sk->is_protected )
|
||||
printf( "[encrypted]\n");
|
||||
else {
|
||||
mpi_print(stdout, sk->skey[i], mpi_print_mode );
|
||||
putchar('\n');
|
||||
}
|
||||
printf("\tencrypted stuff follows\n");
|
||||
}
|
||||
}
|
||||
else { /* v3 method: the mpi length is not encrypted */
|
||||
for(i=npkey; i < nskey; i++ ) {
|
||||
n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
if( sk->is_protected )
|
||||
mpi_set_protect_flag(sk->skey[i]);
|
||||
if( list_mode ) {
|
||||
printf( "\tskey[%d]: ", i);
|
||||
if( sk->is_protected )
|
||||
printf( "[encrypted]\n");
|
||||
else {
|
||||
mpi_print(stdout, sk->skey[i], mpi_print_mode );
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sk->csum = read_16(inp); pktlen -= 2;
|
||||
if( list_mode ) {
|
||||
printf("\tchecksum: %04hx\n", sk->csum);
|
||||
sk->csum = read_16(inp); pktlen -= 2;
|
||||
if( list_mode ) {
|
||||
printf("\tchecksum: %04hx\n", sk->csum);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -195,7 +195,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
|
||||
assert( s2k->hash_algo );
|
||||
dek->keylen = 0;
|
||||
md = md_open( s2k->hash_algo, 1);
|
||||
if( s2k->mode == 1 || s2k->mode == 4 ) {
|
||||
if( s2k->mode == 1 || s2k->mode == 3 ) {
|
||||
if( create )
|
||||
randomize_buffer(s2k->salt, 8, 1);
|
||||
md_write( md, s2k->salt, 8 );
|
||||
|
@ -512,3 +512,102 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return -1 if we could not find an algorithm.
|
||||
*/
|
||||
int
|
||||
select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
||||
{
|
||||
PK_LIST pkr;
|
||||
u32 bits[8];
|
||||
byte *pref = NULL;
|
||||
size_t npref;
|
||||
int i, j;
|
||||
int compr_hack=0;
|
||||
int any;
|
||||
|
||||
if( !pk_list )
|
||||
return -1;
|
||||
|
||||
memset( bits, ~0, 8 * sizeof *bits );
|
||||
for( pkr = pk_list; pkr; pkr = pkr->next ) {
|
||||
u32 mask[8];
|
||||
|
||||
memset( mask, 0, 8 * sizeof *mask );
|
||||
if( !pkr->pk->local_id )
|
||||
BUG(); /* if this occurs, we can use get_ownertrust to set it */
|
||||
if( preftype == PREFTYPE_SYM )
|
||||
bits[0] = (1<<2); /* 3DES is implicitly there */
|
||||
m_free(pref);
|
||||
pref = get_pref_data( pkr->pk->local_id, pkr->pk->namehash, &npref);
|
||||
any = 0;
|
||||
if( pref ) {
|
||||
/*log_hexdump("raw: ", pref, npref );*/
|
||||
for(i=0; i+1 < npref; i+=2 ) {
|
||||
if( pref[i] == preftype ) {
|
||||
mask[pref[i+1]/32] |= 1 << (pref[i+1]%32);
|
||||
any = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (!pref || !any) && preftype == PREFTYPE_COMPR ) {
|
||||
mask[0] |= 3; /* asume no_compression and old pgp */
|
||||
compr_hack = 1;
|
||||
}
|
||||
|
||||
/*log_debug("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]);*/
|
||||
for(i=0; i < 8; i++ )
|
||||
bits[i] &= mask[i];
|
||||
/*log_debug("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]);*/
|
||||
}
|
||||
/* usable algorithms are now in bits
|
||||
* We now use the last key from pk_list to select
|
||||
* the algorithm we want to use. there are no
|
||||
* preferences for the last key, we select the one
|
||||
* corresponding to first set bit.
|
||||
*/
|
||||
i = -1;
|
||||
any = 0;
|
||||
if( pref ) {
|
||||
for(j=0; j+1 < npref; j+=2 ) {
|
||||
if( pref[j] == preftype ) {
|
||||
any = 1;
|
||||
if( (bits[pref[j+1]/32] & (1<<(pref[j+1]%32))) ) {
|
||||
i = pref[j+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !pref || !any ) {
|
||||
for(j=0; j < 256; j++ )
|
||||
if( (bits[j/32] & (1<<(j%32))) ) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*log_debug("prefs of type %d: selected %d\n", preftype, i );*/
|
||||
if( compr_hack && !i ) {
|
||||
/* selected no compression, but we should check whether
|
||||
* algorithm 1 is also available (the ordering is not relevant
|
||||
* in this case). */
|
||||
if( bits[0] & (1<<1) )
|
||||
i = 1; /* yep; we can use compression algo 1 */
|
||||
}
|
||||
|
||||
if( preftype == PREFTYPE_SYM && i == CIPHER_ALGO_3DES ) {
|
||||
i = CIPHER_ALGO_BLOWFISH;
|
||||
if( opt.verbose )
|
||||
log_info("replacing 3DES by Blowfish\n");
|
||||
}
|
||||
|
||||
|
||||
m_free(pref);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "packet.h"
|
||||
#include "mpi.h"
|
||||
#include "keydb.h"
|
||||
#include "trustdb.h"
|
||||
#include "cipher.h"
|
||||
#include "status.h"
|
||||
|
||||
@ -124,6 +125,20 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
|
||||
}
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is:", dek->key, dek->keylen );
|
||||
/* check that the algo is in the preferences */
|
||||
{
|
||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||
if( (rc = get_pubkey( pk, k->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");
|
||||
else if( dek->algo != CIPHER_ALGO_3DES
|
||||
&& !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) )
|
||||
log_info("note: cipher algorithm %d not found in preferences\n",
|
||||
dek->algo );
|
||||
free_public_key( pk );
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
leave:
|
||||
mpi_free(plain_dek);
|
||||
|
@ -67,19 +67,48 @@ do_check( PKT_secret_key *sk )
|
||||
memcpy(save_iv, sk->protect.iv, 8 );
|
||||
cipher_decrypt( cipher_hd, sk->protect.iv, sk->protect.iv, 8 );
|
||||
csum = 0;
|
||||
for(i=pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
|
||||
buffer = mpi_get_secure_buffer( sk->skey[i], &nbytes, NULL );
|
||||
cipher_sync( cipher_hd );
|
||||
assert( mpi_is_protected(sk->skey[i]) );
|
||||
cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
|
||||
mpi_set_buffer( sk->skey[i], buffer, nbytes, 0 );
|
||||
mpi_clear_protect_flag( sk->skey[i] );
|
||||
csum += checksum_mpi( sk->skey[i] );
|
||||
m_free( buffer );
|
||||
if( sk->version >= 4 && !(opt.emulate_bugs & EMUBUG_ENCR_MPI) ) {
|
||||
int ndata;
|
||||
byte *p, *data;
|
||||
|
||||
i = pubkey_get_npkey(sk->pubkey_algo);
|
||||
assert( mpi_is_opaque( sk->skey[i] ) );
|
||||
p = mpi_get_opaque( sk->skey[i], &ndata );
|
||||
data = m_alloc_secure( ndata );
|
||||
cipher_decrypt( cipher_hd, data, p, ndata );
|
||||
mpi_free( sk->skey[i] ); sk->skey[i] = NULL ;
|
||||
p = data;
|
||||
csum = checksum( data, ndata);
|
||||
if( ndata < 2 )
|
||||
log_bug("not enough bytes for checksum\n");
|
||||
sk->csum = data[ndata-2] << 8 | data[ndata-1];
|
||||
/* must check it here otherwise the mpi_read_xx would fail
|
||||
* because the length das an abritary value */
|
||||
if( sk->csum == csum ) {
|
||||
for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
|
||||
nbytes = ndata;
|
||||
sk->skey[i] = mpi_read_from_buffer(p, &nbytes, 1 );
|
||||
ndata -= nbytes;
|
||||
p += nbytes;
|
||||
}
|
||||
}
|
||||
m_free(data);
|
||||
}
|
||||
if( opt.emulate_bugs & EMUBUG_GPGCHKSUM ) {
|
||||
csum = sk->csum;
|
||||
else {
|
||||
for(i=pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
|
||||
buffer = mpi_get_secure_buffer( sk->skey[i], &nbytes, NULL );
|
||||
cipher_sync( cipher_hd );
|
||||
assert( mpi_is_protected(sk->skey[i]) );
|
||||
cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
|
||||
mpi_set_buffer( sk->skey[i], buffer, nbytes, 0 );
|
||||
mpi_clear_protect_flag( sk->skey[i] );
|
||||
csum += checksum_mpi( sk->skey[i] );
|
||||
m_free( buffer );
|
||||
}
|
||||
if( opt.emulate_bugs & EMUBUG_GPGCHKSUM ) {
|
||||
csum = sk->csum;
|
||||
}
|
||||
}
|
||||
cipher_close( cipher_hd );
|
||||
/* now let's see whether we have used the right passphrase */
|
||||
@ -190,21 +219,26 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
cipher_setkey( cipher_hd, dek->key, dek->keylen );
|
||||
cipher_setiv( cipher_hd, NULL );
|
||||
cipher_encrypt( cipher_hd, sk->protect.iv, sk->protect.iv, 8 );
|
||||
/* NOTE: we always recalculate the checksum because there are some
|
||||
* test releases which calculated it wrong */
|
||||
csum = 0;
|
||||
for(i=pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
|
||||
csum += checksum_mpi_counted_nbits( sk->skey[i] );
|
||||
buffer = mpi_get_buffer( sk->skey[i], &nbytes, NULL );
|
||||
cipher_sync( cipher_hd );
|
||||
assert( !mpi_is_protected(sk->skey[i]) );
|
||||
cipher_encrypt( cipher_hd, buffer, buffer, nbytes );
|
||||
mpi_set_buffer( sk->skey[i], buffer, nbytes, 0 );
|
||||
mpi_set_protect_flag( sk->skey[i] );
|
||||
m_free( buffer );
|
||||
if( sk->version >= 4 && !(opt.emulate_bugs & EMUBUG_ENCR_MPI) ) {
|
||||
BUG();
|
||||
}
|
||||
else {
|
||||
/* NOTE: we always recalculate the checksum because there
|
||||
* are some * test releases which calculated it wrong */
|
||||
csum = 0;
|
||||
for(i=pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
|
||||
csum += checksum_mpi_counted_nbits( sk->skey[i] );
|
||||
buffer = mpi_get_buffer( sk->skey[i], &nbytes, NULL );
|
||||
cipher_sync( cipher_hd );
|
||||
assert( !mpi_is_protected(sk->skey[i]) );
|
||||
cipher_encrypt( cipher_hd, buffer, buffer, nbytes );
|
||||
mpi_set_buffer( sk->skey[i], buffer, nbytes, 0 );
|
||||
mpi_set_protect_flag( sk->skey[i] );
|
||||
m_free( buffer );
|
||||
}
|
||||
sk->csum = csum;
|
||||
}
|
||||
sk->csum = csum;
|
||||
sk->is_protected = 1;
|
||||
cipher_close( cipher_hd );
|
||||
}
|
||||
|
34
g10/sign.c
34
g10/sign.c
@ -35,6 +35,7 @@
|
||||
#include "main.h"
|
||||
#include "filter.h"
|
||||
#include "ttyio.h"
|
||||
#include "trustdb.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
@ -118,6 +119,8 @@ only_old_style( SK_LIST sk_list )
|
||||
return old_style;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Sign the files whose names are in FILENAME.
|
||||
* If DETACHED has the value true,
|
||||
@ -150,6 +153,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
SK_LIST sk_rover = NULL;
|
||||
int multifile = 0;
|
||||
int old_style = opt.rfc1991;
|
||||
int compr_algo = -1; /* unknown */
|
||||
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
@ -176,6 +180,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
if( encrypt ) {
|
||||
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 );
|
||||
}
|
||||
|
||||
/* prepare iobufs */
|
||||
@ -227,16 +233,31 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
}
|
||||
|
||||
if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) {
|
||||
if( old_style )
|
||||
zfx.algo = 1;
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
if( !compr_algo )
|
||||
; /* don't use compression */
|
||||
else {
|
||||
if( old_style || compr_algo == 1 )
|
||||
zfx.algo = 1;
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
}
|
||||
}
|
||||
|
||||
if( !detached && !old_style ) {
|
||||
/* loop over the secret certificates and build headers */
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
int skcount=0;
|
||||
/* loop over the secret certificates and build headers
|
||||
* The specs now say that the data should be bracket by
|
||||
* the onepass-sig and signature-packet; so we muts build it
|
||||
* here in reverse order */
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
|
||||
skcount++;
|
||||
for( ; skcount; skcount-- ) {
|
||||
PKT_secret_key *sk;
|
||||
PKT_onepass_sig *ops;
|
||||
int i = 0;
|
||||
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
|
||||
if( ++i == skcount )
|
||||
break;
|
||||
|
||||
sk = sk_rover->sk;
|
||||
ops = m_alloc_clear( sizeof *ops );
|
||||
@ -244,7 +265,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
ops->digest_algo = hash_for(sk->pubkey_algo);
|
||||
ops->pubkey_algo = sk->pubkey_algo;
|
||||
keyid_from_sk( sk, ops->keyid );
|
||||
ops->last = !sk_rover->next;
|
||||
ops->last = skcount == 1;
|
||||
|
||||
init_packet(&pkt);
|
||||
pkt.pkttype = PKT_ONEPASS_SIG;
|
||||
@ -259,7 +280,6 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* setup the inner packet */
|
||||
if( detached ) {
|
||||
if( multifile ) {
|
||||
|
@ -60,7 +60,7 @@ got_fatal_signal( int sig )
|
||||
fprintf( stderr, "\n%s: %s caught ... exiting\n",
|
||||
log_get_name(), signal_name(sig) );
|
||||
secmem_term();
|
||||
exit( 2 );
|
||||
exit( 8 );
|
||||
}
|
||||
|
||||
|
||||
@ -94,6 +94,7 @@ init_signals()
|
||||
do_sigaction( SIGHUP, &nact );
|
||||
do_sigaction( SIGTERM, &nact );
|
||||
do_sigaction( SIGQUIT, &nact );
|
||||
do_sigaction( SIGSEGV, &nact );
|
||||
nact.sa_handler = got_usr_signal;
|
||||
sigaction( SIGUSR1, &nact, NULL );
|
||||
}
|
||||
|
@ -113,8 +113,7 @@ init_shm_coprocessing ( ulong requested_shm_size, int lock_mem )
|
||||
log_fatal("too much shared memory requested; only 8k are allowed\n");
|
||||
shm_size = 4096 /* one page for us */ + requested_shm_size;
|
||||
|
||||
/* FIXME: Need other permissions ... */
|
||||
shm_id = shmget( IPC_PRIVATE, shm_size, IPC_CREAT | 0777 );
|
||||
shm_id = shmget( IPC_PRIVATE, shm_size, IPC_CREAT | 0700 );
|
||||
if ( shm_id == -1 )
|
||||
log_fatal("can't get %uk of shared memory: %s\n",
|
||||
(unsigned)shm_size/1024, strerror(errno));
|
||||
|
15
g10/tdbio.c
15
g10/tdbio.c
@ -356,6 +356,7 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
{
|
||||
int i;
|
||||
ulong rnum = rec->recnum;
|
||||
byte *p;
|
||||
|
||||
fprintf(fp, "rec %5lu, ", rnum );
|
||||
|
||||
@ -405,9 +406,15 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
putc('\n', fp);
|
||||
break;
|
||||
case RECTYPE_PREF:
|
||||
fprintf(fp, "pref %lu, next=%lu\n",
|
||||
rec->r.uid.lid,
|
||||
rec->r.uid.next);
|
||||
fprintf(fp, "pref %lu, next=%lu,",
|
||||
rec->r.pref.lid, rec->r.pref.next);
|
||||
for(i=0,p=rec->r.pref.data; i < ITEMS_PER_PREF_RECORD; i+=2,p+=2 ) {
|
||||
if( *p )
|
||||
fprintf(fp, " %c%d", *p == PREFTYPE_SYM ? 'S' :
|
||||
*p == PREFTYPE_HASH ? 'H' :
|
||||
*p == PREFTYPE_COMPR ? 'Z' : '?', p[1]);
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
case RECTYPE_SIG:
|
||||
fprintf(fp, "sig %lu, next=%lu,",
|
||||
@ -537,6 +544,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
case RECTYPE_PREF: /* preference record */
|
||||
rec->r.pref.lid = buftoulong(p); p += 4;
|
||||
rec->r.pref.next = buftoulong(p); p += 4;
|
||||
memcpy( rec->r.pref.data, p, 30 );
|
||||
break;
|
||||
case RECTYPE_SIG:
|
||||
rec->r.sig.lid = buftoulong(p); p += 4;
|
||||
@ -638,6 +646,7 @@ tdbio_write_record( TRUSTREC *rec )
|
||||
case RECTYPE_PREF:
|
||||
ulongtobuf(p, rec->r.pref.lid); p += 4;
|
||||
ulongtobuf(p, rec->r.pref.next); p += 4;
|
||||
memcpy( p, rec->r.pref.data, 30 );
|
||||
break;
|
||||
|
||||
case RECTYPE_SIG:
|
||||
|
@ -26,6 +26,10 @@
|
||||
#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5)
|
||||
#define ITEMS_PER_HTBL_RECORD ((TRUST_RECORD_LEN-2)/4)
|
||||
#define ITEMS_PER_HLST_RECORD ((TRUST_RECORD_LEN-6)/5)
|
||||
#define ITEMS_PER_PREF_RECORD (TRUST_RECORD_LEN-10)
|
||||
#if ITEMS_PER_PREF_RECORD % 2
|
||||
#error ITEMS_PER_PREF_RECORD must be even
|
||||
#endif
|
||||
#define MAX_LIST_SIGS_DEPTH 20
|
||||
|
||||
|
||||
@ -40,7 +44,6 @@
|
||||
#define RECTYPE_HLST 11
|
||||
|
||||
|
||||
|
||||
#define DIRF_CHECKED 1 /* everything has been checked, the other bits are
|
||||
valid */
|
||||
#define DIRF_MISKEY 2 /* some keys are missing, so they could not be checked*/
|
||||
@ -91,10 +94,11 @@ struct trust_record {
|
||||
byte uidflags;
|
||||
byte namehash[20]; /* ripemd hash of the username */
|
||||
} uid;
|
||||
struct { /* preference reord */
|
||||
struct { /* preference record */
|
||||
ulong lid; /* point back to the directory record */
|
||||
/* or 0 for a glocal pref record */
|
||||
ulong next; /* points to next pref record */
|
||||
byte data[ITEMS_PER_PREF_RECORD];
|
||||
} pref;
|
||||
struct { /* signature record */
|
||||
ulong lid;
|
||||
|
132
g10/trustdb.c
132
g10/trustdb.c
@ -1593,8 +1593,6 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
|
||||
u32 keyid[2];
|
||||
|
||||
|
||||
if( DBG_TRUST )
|
||||
log_info("check_trust() called.\n");
|
||||
keyid_from_pk( pk, keyid );
|
||||
|
||||
/* get the pubkey record */
|
||||
@ -1762,6 +1760,90 @@ get_ownertrust_info( ulong lid )
|
||||
}
|
||||
|
||||
|
||||
byte *
|
||||
get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
|
||||
{
|
||||
TRUSTREC rec;
|
||||
ulong recno;
|
||||
int rc;
|
||||
|
||||
if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
|
||||
log_error("get_pref_data: read dir record failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
|
||||
rc = tdbio_read_record( recno, &rec, RECTYPE_UID );
|
||||
if( rc ) {
|
||||
log_error("get_pref_data: read uid record failed: %s\n",
|
||||
g10_errstr(rc));
|
||||
return NULL;
|
||||
}
|
||||
if( rec.r.uid.prefrec
|
||||
&& ( !namehash || !memcmp(namehash, rec.r.uid.namehash, 20) )) {
|
||||
byte *buf;
|
||||
/* found the correct one or the first one */
|
||||
rc = tdbio_read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
|
||||
if( rc ) {
|
||||
log_error("get_pref_data: read pref record failed: %s\n",
|
||||
g10_errstr(rc));
|
||||
return NULL;
|
||||
}
|
||||
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, rc;
|
||||
byte *pref;
|
||||
|
||||
if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
|
||||
log_error("is_algo_in_prefs: read dir record failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
|
||||
rc = tdbio_read_record( recno, &rec, RECTYPE_UID );
|
||||
if( rc ) {
|
||||
log_error("is_algo_in_prefs: read uid record failed: %s\n",
|
||||
g10_errstr(rc));
|
||||
return 0;
|
||||
}
|
||||
if( rec.r.uid.prefrec ) {
|
||||
rc = tdbio_read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
|
||||
if( rc ) {
|
||||
log_error("is_algo_in_prefs: read pref record failed: %s\n",
|
||||
g10_errstr(rc));
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* This function simply looks for the key in the trustdb
|
||||
@ -1909,8 +1991,40 @@ insert_trust_record( PKT_public_key *orig_pk )
|
||||
rc = 0;
|
||||
}
|
||||
else { /* build the prefrecord */
|
||||
static struct {
|
||||
sigsubpkttype_t subpkttype;
|
||||
int preftype;
|
||||
} prefs[] = {
|
||||
{ SIGSUBPKT_PREF_SYM, PREFTYPE_SYM },
|
||||
{ SIGSUBPKT_PREF_HASH, PREFTYPE_HASH },
|
||||
{ SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
|
||||
{ 0, 0 }
|
||||
};
|
||||
const byte *s;
|
||||
size_t n;
|
||||
int k, i;
|
||||
assert(uidlist);
|
||||
assert(!uidlist->help_pref);
|
||||
uidlist->mark |= 1; /* mark valid */
|
||||
|
||||
i = 0;
|
||||
for(k=0; prefs[k].subpkttype; k++ ) {
|
||||
s = parse_sig_subpkt2( sig, prefs[k].subpkttype, &n );
|
||||
if( s ) {
|
||||
while( n ) {
|
||||
if( !i || i >= ITEMS_PER_PREF_RECORD ) {
|
||||
rec = m_alloc_clear( sizeof *rec );
|
||||
rec->rectype = RECTYPE_PREF;
|
||||
rec->next = uidlist->help_pref;
|
||||
uidlist->help_pref = rec;
|
||||
i = 0;
|
||||
}
|
||||
rec->r.pref.data[i++] = prefs[k].preftype;
|
||||
rec->r.pref.data[i++] = *s++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( 0 /* is revocation sig etc */ ) {
|
||||
@ -1959,13 +2073,15 @@ insert_trust_record( PKT_public_key *orig_pk )
|
||||
rec->r.uid.lid = dirrec.recnum;
|
||||
rec->recnum = tdbio_new_recnum();
|
||||
/* (preference records) */
|
||||
for( rec2 = rec->help_pref; rec2; rec2 = rec2->next ) {
|
||||
rec2->r.pref.lid = dirrec.recnum;
|
||||
rec2->recnum = tdbio_new_recnum();
|
||||
if( rec->help_pref ) {
|
||||
for( rec2 = rec->help_pref; rec2; rec2 = rec2->next ) {
|
||||
rec2->r.pref.lid = dirrec.recnum;
|
||||
rec2->recnum = tdbio_new_recnum();
|
||||
}
|
||||
for( rec2 = rec->help_pref; rec2->next; rec2 = rec2->next )
|
||||
rec2->next->r.pref.next = rec2->recnum;
|
||||
rec->r.uid.prefrec = rec2->recnum;
|
||||
}
|
||||
for( rec2 = rec->help_pref; rec2; rec2 = rec2->next )
|
||||
rec2->r.pref.next = rec2->next? rec2->next->recnum : 0;
|
||||
rec->r.uid.prefrec = rec->help_pref? rec->help_pref->recnum : 0;
|
||||
}
|
||||
for(rec=uidlist_head; rec; rec = rec->next )
|
||||
rec->r.uid.next = rec->next? rec->next->recnum : 0;
|
||||
|
@ -35,6 +35,11 @@
|
||||
#define TRUST_FLAG_REVOKED 32 /* r: revoked */
|
||||
|
||||
|
||||
#define PREFTYPE_SYM 1
|
||||
#define PREFTYPE_HASH 2
|
||||
#define PREFTYPE_COMPR 3
|
||||
|
||||
|
||||
/*-- trustdb.c --*/
|
||||
void list_trustdb(const char *username);
|
||||
void list_trust_path( int max_depth, const char *username );
|
||||
@ -47,6 +52,8 @@ int query_trust_info( PKT_public_key *pk );
|
||||
int enum_trust_web( void **context, ulong *lid );
|
||||
int get_ownertrust( ulong lid, unsigned *r_otrust );
|
||||
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 query_trust_record( PKT_public_key *pk );
|
||||
int insert_trust_record( PKT_public_key *pk );
|
||||
|
@ -50,6 +50,7 @@ typedef struct mpi_struct {
|
||||
int sign; /* indicates a negative number */
|
||||
unsigned flags; /* bit 0: array must be allocated in secure memory space */
|
||||
/* bit 1: the mpi is encrypted */
|
||||
/* bit 2: the limb is a pointer to some m_alloced data */
|
||||
mpi_limb_t *d; /* array with the limbs */
|
||||
} *MPI;
|
||||
|
||||
@ -80,6 +81,9 @@ typedef struct mpi_struct {
|
||||
void mpi_resize( MPI a, unsigned nlimbs );
|
||||
MPI mpi_copy( MPI a );
|
||||
#endif
|
||||
#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
|
||||
MPI mpi_set_opaque( MPI a, void *p, int len );
|
||||
void *mpi_get_opaque( MPI a, int *len );
|
||||
#define mpi_is_protected(a) ((a) && ((a)->flags&2))
|
||||
#define mpi_set_protect_flag(a) ((a)->flags |= 2)
|
||||
#define mpi_clear_protect_flag(a) ((a)->flags &= ~2)
|
||||
@ -100,6 +104,7 @@ int mpi_write( IOBUF out, MPI a );
|
||||
#else
|
||||
MPI mpi_read(IOBUF inp, unsigned *nread, int secure);
|
||||
#endif
|
||||
MPI mpi_read_from_buffer(byte *buffer, unsigned *ret_nread, int secure);
|
||||
int mpi_fromstr(MPI val, const char *str);
|
||||
int mpi_print( FILE *fp, MPI a, int mode );
|
||||
u32 mpi_get_keyid( MPI a, u32 *keyid );
|
||||
|
@ -1,3 +1,12 @@
|
||||
Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none))
|
||||
|
||||
* mpicoder.c (mpi_read_from_buffer): New.
|
||||
|
||||
* mpiutil.c (mpi_set_opaque): New.
|
||||
(mpi_get_opaque): New.
|
||||
(mpi_copy): Changed to support opauqe flag
|
||||
(mpi_free): Ditto.
|
||||
|
||||
Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* mpiutil.c (mpi_clear): Reset flags.
|
||||
|
@ -123,6 +123,50 @@ mpi_read(IOBUF inp, unsigned *ret_nread, int secure)
|
||||
}
|
||||
|
||||
|
||||
MPI
|
||||
mpi_read_from_buffer(byte *buffer, unsigned *ret_nread, int secure)
|
||||
{
|
||||
int i, j;
|
||||
unsigned nbits, nbytes, nlimbs, nread=0;
|
||||
mpi_limb_t a;
|
||||
MPI val = MPI_NULL;
|
||||
|
||||
if( *ret_nread < 2 )
|
||||
goto leave;
|
||||
nbits = buffer[0] << 8 | buffer[1];
|
||||
if( nbits > MAX_EXTERN_MPI_BITS ) {
|
||||
log_error("mpi too large (%u bits)\n", nbits);
|
||||
goto leave;
|
||||
}
|
||||
buffer += 2;
|
||||
nread = 2;
|
||||
|
||||
nbytes = (nbits+7) / 8;
|
||||
nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
|
||||
val = secure? mpi_alloc_secure( nlimbs )
|
||||
: mpi_alloc( nlimbs );
|
||||
i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
|
||||
i %= BYTES_PER_MPI_LIMB;
|
||||
val->nbits = nbits;
|
||||
j= val->nlimbs = nlimbs;
|
||||
val->sign = 0;
|
||||
for( ; j > 0; j-- ) {
|
||||
a = 0;
|
||||
for(; i < BYTES_PER_MPI_LIMB; i++ ) {
|
||||
if( ++nread > *ret_nread )
|
||||
log_bug("mpi larger than buffer");
|
||||
a <<= 8;
|
||||
a |= *buffer++;
|
||||
}
|
||||
i = 0;
|
||||
val->d[j-1] = a;
|
||||
}
|
||||
|
||||
leave:
|
||||
*ret_nread = nread;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Make an mpi from a character string.
|
||||
|
@ -193,12 +193,16 @@ mpi_free( MPI a )
|
||||
return;
|
||||
if( DBG_MEMORY )
|
||||
log_debug("mpi_free\n" );
|
||||
#ifdef M_DEBUG
|
||||
mpi_debug_free_limb_space(a->d, info);
|
||||
#else
|
||||
mpi_free_limb_space(a->d);
|
||||
#endif
|
||||
if( a->flags & ~3 )
|
||||
if( a->flags & 4 )
|
||||
m_free( a->d );
|
||||
else {
|
||||
#ifdef M_DEBUG
|
||||
mpi_debug_free_limb_space(a->d, info);
|
||||
#else
|
||||
mpi_free_limb_space(a->d);
|
||||
#endif
|
||||
}
|
||||
if( a->flags & ~7 )
|
||||
log_bug("invalid flag value in mpi\n");
|
||||
m_free(a);
|
||||
}
|
||||
@ -232,6 +236,47 @@ mpi_set_secure( MPI a )
|
||||
}
|
||||
|
||||
|
||||
MPI
|
||||
mpi_set_opaque( MPI a, void *p, int len )
|
||||
{
|
||||
if( !a ) {
|
||||
#ifdef M_DEBUG
|
||||
a = mpi_debug_alloc(0,"alloc_opaque");
|
||||
#else
|
||||
a = mpi_alloc(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if( a->flags & 4 )
|
||||
m_free( a->d );
|
||||
else {
|
||||
#ifdef M_DEBUG
|
||||
mpi_debug_free_limb_space(a->d, "alloc_opaque");
|
||||
#else
|
||||
mpi_free_limb_space(a->d);
|
||||
#endif
|
||||
}
|
||||
|
||||
a->d = p;
|
||||
a->alloced = 0;
|
||||
a->nlimbs = 0;
|
||||
a->nbits = len;
|
||||
a->flags = 4;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
mpi_get_opaque( MPI a, int *len )
|
||||
{
|
||||
if( !(a->flags & 4) )
|
||||
log_bug("mpi_get_opaque on normal mpi\n");
|
||||
if( len )
|
||||
*len = a->nbits;
|
||||
return a->d;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Note: This copy function should not interpret the MPI
|
||||
* but copy it transparently.
|
||||
@ -246,7 +291,13 @@ mpi_copy( MPI a )
|
||||
int i;
|
||||
MPI b;
|
||||
|
||||
if( a ) {
|
||||
if( a && (a->flags & 4) ) {
|
||||
void *p = m_is_secure(a->d)? m_alloc_secure( a->nbits )
|
||||
: m_alloc( a->nbits );
|
||||
memcpy( p, a->d, a->nbits );
|
||||
b = mpi_set_opaque( NULL, p, a->nbits );
|
||||
}
|
||||
else if( a ) {
|
||||
#ifdef M_DEBUG
|
||||
b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
|
||||
: mpi_debug_alloc( a->nlimbs, info );
|
||||
|
@ -103,15 +103,6 @@ main(int argc, char **argv)
|
||||
if( argc < 1 )
|
||||
my_usage();
|
||||
|
||||
#if 0
|
||||
shm_ID = atoi( argv[1] );
|
||||
pool = shmat( shm_ID, 0, 0 );
|
||||
if( pool == (void*)-1 )
|
||||
log_fatal("shmat of %d failed: %s\n", shm_ID, strerror(errno));
|
||||
log_info("attached to %p id=%d\n", pool, shm_ID );
|
||||
getchar();
|
||||
#endif
|
||||
|
||||
for(n=0,i=1; i < argc; i++ )
|
||||
n += strlen(argv[i]) + 1;
|
||||
p = m_alloc( 100 + n );
|
||||
|
@ -1,3 +1,7 @@
|
||||
Mon Aug 3 17:06:00 1998 Werner Koch (wk@(none))
|
||||
|
||||
* secmem.c (MAP_ANON): Add a macro test
|
||||
|
||||
Wed Jul 29 14:53:34 1998 Werner Koch (wk@(none))
|
||||
|
||||
* ttyio.c (tty_get_answer_is_yes): New.
|
||||
|
@ -706,6 +706,8 @@ iobuf_pop_filter( IOBUF a, int (*f)(void *opaque, int control,
|
||||
m_free(a->d.buf);
|
||||
memcpy(a,b, sizeof *a);
|
||||
m_free(b);
|
||||
if( DBG_IOBUF )
|
||||
log_debug("iobuf-%d.%d: popped filter\n", a->no, a->subno );
|
||||
}
|
||||
else if( !b->chain ) { /* remove the last iobuf from the chain */
|
||||
log_bug("Ohh jeee, trying to remove a head filter\n");
|
||||
|
@ -35,6 +35,9 @@
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
#define DEFAULT_POOLSIZE 8196
|
||||
|
||||
@ -105,10 +108,10 @@ init_pool( size_t n)
|
||||
if( disable_secmem )
|
||||
log_bug("secure memory is disabled");
|
||||
|
||||
#if HAVE_MMAP && defined(MAP_ANONYMOUS)
|
||||
#if HAVE_MMAP && defined(MAP_ANON)
|
||||
poolsize = (poolsize + 4095) & ~4095;
|
||||
pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
MAP_PRIVATE|MAP_ANON, -1, 0);
|
||||
if( pool == (void*)-1 )
|
||||
log_error("can't mmap pool of %u bytes: %s - using malloc\n",
|
||||
(unsigned)poolsize, strerror(errno));
|
||||
|
Loading…
x
Reference in New Issue
Block a user