diff --git a/g10/ChangeLog b/g10/ChangeLog index ee9d7a3af..1f49dc691 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,25 @@ 2002-11-13 David Shaw + * encode.c (encode_simple): Make sure that files larger than about + 4G use partial length encoding. This is required because OpenPGP + allows only for 32 bit length fields. From Werner on stable + branch. + + * getkey.c (get_pubkey_direct): Renamed to... + (get_pubkey_fast): this and made extern. + (get_pubkey_byfprint_fast): New. From Werner on stable branch. + + * keydb.h, import.c (import_one): Use get_pubkey_fast instead of + get_pubkey. We don't need a merged key and actually this might + lead to recursions. + (revocation_present): Likewise for search by fingerprint. From + Werner on stable branch. + + * g10.c (main): Try to create the trustdb even for non-colon-mode + list-key operations. This is required because getkey needs to + know whether a a key is ultimately trusted. From Werner on stable + branch. + * exec.c [__CYGWIN32__]: Keep cygwin separate from Mingw32; we don't need it here as it behaves more like a Posix system. From Werner on stable branch. diff --git a/g10/encode.c b/g10/encode.c index b635ce0b4..a814544e9 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -292,13 +292,18 @@ encode_simple( const char *filename, int mode, int compat ) messages. */ if( filename && !opt.textmode ) { - if( !(filesize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: empty file\n"), filename ); - /* we can't yet encode the length of very large files, - * so we switch to partial lengthn encoding in this case */ - if ( filesize >= IOBUF_FILELENGTH_LIMIT ) - filesize = 0; + off_t tmpsize; + if ( !(tmpsize = iobuf_get_filelength(inp)) ) + log_info(_("%s: WARNING: empty file\n"), filename ); + /* We can't encode the length of very large files because + OpenPGP uses only 32 bit for file sizes. So if the the + size of a file is larger than 2^32 minus some bytes for + packet headers, we switch to partial length encoding. */ + if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) + filesize = tmpsize; + else + filesize = 0; } else filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ @@ -519,12 +524,18 @@ encode_crypt( const char *filename, STRLIST remusr ) } if( filename && !opt.textmode ) { - if( !(filesize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: empty file\n"), filename ); - /* we can't yet encode the length of very large files, - * so we switch to partial length encoding in this case */ - if ( filesize >= IOBUF_FILELENGTH_LIMIT ) - filesize = 0; + off_t tmpsize; + + if ( !(tmpsize = iobuf_get_filelength(inp)) ) + log_info(_("%s: WARNING: empty file\n"), filename ); + /* We can't encode the length of very large files because + OpenPGP uses only 32 bit for file sizes. So if the the + size of a file is larger than 2^32 minus some bytes for + packet headers, we switch to partial length encoding. */ + if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) + filesize = tmpsize; + else + filesize = 0; } else filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ diff --git a/g10/g10.c b/g10/g10.c index ba5ae58a2..62a1a9ad0 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -2078,13 +2078,6 @@ main( int argc, char **argv ) case aEnArmor: case aFixTrustDB: break; - case aKMode: - case aListKeys: - case aListSecretKeys: - case aCheckKeys: - if( opt.with_colons ) /* need this to list the trust */ - rc = setup_trustdb(1, trustdb_name ); - break; case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break; case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break; default: rc = setup_trustdb(1, trustdb_name ); break; diff --git a/g10/getkey.c b/g10/getkey.c index ab296f641..5bb2d2263 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -374,8 +374,8 @@ get_pubkey( PKT_public_key *pk, u32 *keyid ) /* Get a public key and store it into the allocated pk. This function differs from get_pubkey() in that it does not do a check of the key to avoid recursion. It should be used only in very certain cases. */ -static int -get_pubkey_direct (PKT_public_key *pk, u32 *keyid) +int +get_pubkey_fast (PKT_public_key *pk, u32 *keyid) { int rc = 0; KEYDB_HANDLE hd; @@ -906,6 +906,54 @@ get_pubkey_byfprint( PKT_public_key *pk, return rc; } + +/* Get a public key and store it into the allocated pk. This function + differs from get_pubkey_byfprint() in that it does not do a check + of the key to avoid recursion. It should be used only in very + certain cases. PK may be NULL to check just for the existance of + the key. */ +int +get_pubkey_byfprint_fast (PKT_public_key *pk, + const byte *fprint, size_t fprint_len) +{ + int rc = 0; + KEYDB_HANDLE hd; + KBNODE keyblock; + unsigned char fprbuf[MAX_FINGERPRINT_LEN]; + int i; + + for (i=0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++) + fprbuf[i] = fprint[i]; + while (i < MAX_FINGERPRINT_LEN) + fprbuf[i++] = 0; + + hd = keydb_new (0); + rc = keydb_search_fpr (hd, fprbuf); + if (rc == -1) + { + keydb_release (hd); + return G10ERR_NO_PUBKEY; + } + rc = keydb_get_keyblock (hd, &keyblock); + keydb_release (hd); + if (rc) + { + log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc)); + return G10ERR_NO_PUBKEY; + } + + assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY ); + if (pk) + copy_public_key (pk, keyblock->pkt->pkt.public_key ); + release_kbnode (keyblock); + + /* Not caching key here since it won't have all of the fields + properly set. */ + + return 0; +} + /**************** * Search for a key with the given fingerprint and return the * complete keyblock which may have more than only this key. @@ -1524,7 +1572,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) trusted key is still valid - if it has been revoked or the user should also renmove the ultimate trust flag. */ - if(get_pubkey_direct(ultimate_pk,sig->keyid)==0 && + if(get_pubkey_fast(ultimate_pk,sig->keyid)==0 && check_key_signature(keyblock,k,NULL)==0 && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE) { diff --git a/g10/import.c b/g10/import.c index 2ff06b51d..d06d957c2 100644 --- a/g10/import.c +++ b/g10/import.c @@ -638,7 +638,7 @@ import_one( const char *fname, KBNODE keyblock, /* do we have this key already in one of our pubrings ? */ pk_orig = m_alloc_clear( sizeof *pk_orig ); - rc = get_pubkey( pk_orig, keyid ); + rc = get_pubkey_fast ( pk_orig, keyid ); if( rc && rc != G10ERR_NO_PUBKEY && rc != G10ERR_UNU_PUBKEY ) { log_error( _("key %08lX: public key not found: %s\n"), (ulong)keyid[1], g10_errstr(rc)); @@ -1476,8 +1476,8 @@ revocation_present(KBNODE keyblock) itself? */ int rc; - rc=get_pubkey_byfprint(NULL,sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN); + rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx]->fpr, + MAX_FINGERPRINT_LEN); if(rc==G10ERR_NO_PUBKEY || rc==G10ERR_UNU_PUBKEY) { /* No, so try and get it */ @@ -1492,7 +1492,7 @@ revocation_present(KBNODE keyblock) MAX_FINGERPRINT_LEN); /* Do we have it now? */ - rc=get_pubkey_byfprint(NULL, + rc=get_pubkey_byfprint_fast (NULL, sig->revkey[idx]->fpr, MAX_FINGERPRINT_LEN); } diff --git a/g10/keydb.h b/g10/keydb.h index c4b12dde5..a3d48508c 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -195,6 +195,7 @@ int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc); void cache_public_key( PKT_public_key *pk ); void getkey_disable_caches(void); int get_pubkey( PKT_public_key *pk, u32 *keyid ); +int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid ); KBNODE get_pubkeyblock( u32 *keyid ); int get_pubkey_byname( PKT_public_key *pk, const char *name, KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd); @@ -206,6 +207,8 @@ int get_seckey( PKT_secret_key *sk, u32 *keyid ); int get_primary_seckey( PKT_secret_key *sk, u32 *keyid ); int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, size_t fprint_len ); +int get_pubkey_byfprint_fast (PKT_public_key *pk, + const byte *fprint, size_t fprint_len); int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, size_t fprint_len ); int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid );