Snapshot release 0.4.2

This commit is contained in:
Werner Koch 1998-10-18 15:21:22 +00:00
parent 1f460046d5
commit 6e16296864
32 changed files with 2438 additions and 1521 deletions

12
NEWS
View File

@ -1,5 +1,8 @@
Noteworthy changes in version 0.4.2 Noteworthy changes in version 0.4.2
----------------------------------- -----------------------------------
* This is only a snapshot: There are still a few bugs.
* Fixed this huge memory leak. * Fixed this huge memory leak.
* Redesigned the trust database: You should run "gpgm --check-trustdb". * Redesigned the trust database: You should run "gpgm --check-trustdb".
@ -26,6 +29,15 @@ Noteworthy changes in version 0.4.2
of packets, so that the keyservers don't accept these keys. of packets, so that the keyservers don't accept these keys.
Simply using "--edit-key" fixes the problem. Simply using "--edit-key" fixes the problem.
* New option --force-v3-sigs to generate signed messages which are
compatible to PGP 5.
* Add some code to support DLD (for non ELF systems) - but this is
not tested because my BSD box is currently broken.
* New command "expire" in the edit-key menu.
Noteworthy changes in version 0.4.1 Noteworthy changes in version 0.4.1
----------------------------------- -----------------------------------

8
README
View File

@ -331,11 +331,3 @@
please subscribe before posting, see above (~line 33)). please subscribe before posting, see above (~line 33)).
Supported targets:
------------------
powerpc-unknown-linux-gnu (linuxppc)
hppa1.1-hp-hpux10.20

33
TODO
View File

@ -1,33 +1,15 @@
* change ringedit:
- avoid all copy operations
- delete for update by changing the packet type to a
special unused packet. (export most know about this)
- do an append instead of an update or insert
- export may be used to compress a keyring.
- keep track of all offset in the trustbd and index them
by keyid.
- If the lookup does not find a public key block at the
stored offset disable this keyid.
- If the keyid was not found or is disabled, walk thru
the pubring.
- use ftruncate to recover from keyring errors.
maybe a new option to do this or simply mark the
wrong part as unused.
This makes signature checks and imports much faster; only keys
given by a userid or a fingerprint (RSA only) have to walk tru
the ring.
* There is a new memory leak in update-trustdb * There is a new memory leak in update-trustdb :-(
* Fix ;) revocation and expire stuff.
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but: * OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
OpenBSD binaries are a.out, so every symbol begins with "_" OpenBSD binaries are a.out, so every symbol begins with "_"
* use dld if we don't have dlopen.
* should we flush the getkey.c caches while doing an import? * should we flush the getkey.c caches while doing an import?
* prefer a type 16 subkey for encryption because pgp cannot handle * prefer a type 16 subkey for encryption because pgp cannot handle
type 20. type 20?
* calculation of marginals never yields a completely trusted key. * calculation of marginals never yields a completely trusted key.
@ -36,6 +18,11 @@
* Exportable Certification Flag is ignored * Exportable Certification Flag is ignored
* We need a maintainence pass over the trustdb which flags
signatures as expired if the key used to make the signature has
expired. Maybe it is a good idea to store the exiration time
in the key record of the trustdb.
* write a tool to extract selected keys from a file. * write a tool to extract selected keys from a file.
* new menu to delete signatures and list signature in menu * new menu to delete signatures and list signature in menu
@ -71,8 +58,6 @@
* add an option to re-create a public key from a secret key; we * add an option to re-create a public key from a secret key; we
can do this in trustdb.c:verify_own_keys. can do this in trustdb.c:verify_own_keys.
* OpenBSD has sometimes problems reading from /dev/random.
* change the fake_data stuff to mpi_set_opaque * change the fake_data stuff to mpi_set_opaque
* Is it okay to use gettext for the help system? * Is it okay to use gettext for the help system?

View File

@ -1 +1 @@
0.4.1a 0.4.2

View File

@ -364,6 +364,14 @@ Other Notes
to keep them small. to keep them small.
Supported targets:
------------------
powerpc-unknown-linux-gnu (linuxppc)
hppa1.1-hp-hpux10.20

View File

@ -103,6 +103,12 @@
is choosen. You may add an type 16 ElGamal key to your public is choosen. You may add an type 16 ElGamal key to your public
key which is easy as your key signatures are still valid. key which is easy as your key signatures are still valid.
Q: Why is PGP 5.x not able to verify my messages.
A: PGP 5.x does not accept V4 signatures for data material but
OpenPGP requires generation of V3 signatures for all kind of
data. Use the option "--force-v3-sigs" to generate V3 signatures
for data.
Q: I can't delete a user id because it is already deleted on my Q: I can't delete a user id because it is already deleted on my
public keyring. public keyring.
A: Because you can only select from the public key ring, there is A: Because you can only select from the public key ring, there is

View File

@ -1,4 +1,4 @@
GNUPG and OpenPGP GnuPG and OpenPGP
================= =================
The current OpenPGP draft expires 1999-02. The current OpenPGP draft expires 1999-02.
@ -22,17 +22,21 @@
Compatibility Notes Compatibility Notes
=================== ===================
GNUPG (>=0.4.1) is in compliance with OpenPGP despite these exeptions: GnuPG (>=0.4.1) is in compliance with OpenPGP despite these exeptions:
* (5.1) The critical bit in signature subpackets is currently * (5.1) The critical bit in signature subpackets is currently
ignored. This will be fixed soon. ignored. This will be fixed soon.
* (5.3) GNUPG has an option to use simple S2K for "Symmetric-Key
* (5.2) GnuPG generates V4 signatures for all V4 keys. The option
--force-v3-sigs allows to override.
* (5.3) GnuPG has an option to use simple S2K for "Symmetric-Key
Encrypted Session-Key Packets"; however a warning message is Encrypted Session-Key Packets"; however a warning message is
issued if this option is active. issued if this option is active.
* (5.5.2) states that an implementaion MUST NOT create a v3 key * (5.5.2) states that an implementaion MUST NOT create a v3 key
with an algorithm other than RSA. GNUPG has an option to with an algorithm other than RSA. GnuPG has an option to
create an ElGamal key in a v3 packet; the properties of such create an ElGamal key in a v3 packet; the properties of such
a key are as good as a v4 key. RFC1991 does not specifiy how a key are as good as a v4 key. RFC1991 does not specifiy how
to create fingerprints for algorithms other than RSA and so it to create fingerprints for algorithms other than RSA and so it
@ -46,7 +50,7 @@
due to patent problems. due to patent problems.
* (12.1) states that an implementaion MUST NOT use a symmetric * (12.1) states that an implementaion MUST NOT use a symmetric
algorithm which is not in the preference list. GNUPG has an algorithm which is not in the preference list. GnuPG has an
option to override this. option to override this.
* A special format of partial packet length exists for v3 packets * A special format of partial packet length exists for v3 packets

View File

@ -128,6 +128,11 @@ B<--edit-key> I<name>
Add a subkey to this key. Add a subkey to this key.
B<delkey> B<delkey>
Remove a subkey. Remove a subkey.
B<expire>
Change the key expiration time. If a key is
select, the time of this key will be changed.
With no selection the key expiration of the
primary key is changed.
B<passwd> B<passwd>
Change the passphrase of the secret key. Change the passphrase of the secret key.
B<uid> I<n> B<uid> I<n>
@ -303,7 +308,16 @@ B<--status-fd> I<n>
Write special status strings to the file descriptor I<n>. Write special status strings to the file descriptor I<n>.
B<--no-comment> B<--no-comment>
Do not write comment packets. Do not write comment packets. This option affects only
the generation of secret keys. Output of option packets
is disabled since version 0.4.2.
B<--comment> I<string>
Use I<string> as comment string in clear text signatures.
B<--set-filename> I<string>
Use I<string> as the name of file which is stored in
messages.
B<--completes-needed> I<n> B<--completes-needed> I<n>
Number of completely trusted users to introduce a new Number of completely trusted users to introduce a new
@ -373,6 +387,15 @@ B<--passphrase-fd> I<n>
can only be used if only one passphrase is supplied. can only be used if only one passphrase is supplied.
B<Don't use this option if you can avoid it> B<Don't use this option if you can avoid it>
B<--rfc1991>
Try to be more RFC1991 (PGP 2.x) compliant.
B<--force-v3-sigs>
OpenPGP states that a implemenation should generate
v4 signatures but PGP 5.x does only recognize such
signatures on key material. This options forces
v3 signatures for signatures on data.
B<--no-verbose> B<--no-verbose>
Reset verbose level to 0. Reset verbose level to 0.

View File

@ -1,3 +1,15 @@
Sun Oct 18 11:49:03 1998 Werner Koch (wk@isil.d.shuttle.de)
* sign.c (only_old_style): Add option force_v3_sigs
(sign_file): Fixed a bug in sig->version
(clearsign_file): Ditto.
* parse-packet.c (dump_sig_subpkt): New
* keyedit.c (menu_expire): New.
* free-packet.c (cmp_signatures): New
Sat Oct 17 10:22:39 1998 Werner Koch (wk@isil.d.shuttle.de) Sat Oct 17 10:22:39 1998 Werner Koch (wk@isil.d.shuttle.de)
* armor.c: changed output line length from 72 to 64. * armor.c: changed output line length from 72 to 64.

View File

@ -51,10 +51,4 @@ run-as-shm-coprocess [request-locked-shm-size]
# You will have to use "--status-fd" too # You will have to use "--status-fd" too
# Note: This option dioes only work if given on the command line. # Note: This option dioes only work if given on the command line.
set-filename <name>
# Set <name> as the filename into the plaintext packet
comment <string>
# Add <string> as comment to the output

View File

@ -215,7 +215,7 @@ do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L); ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
else else
ndays = 0; ndays = 0;
write_16(a, 0 ); write_16(a, ndays );
} }
iobuf_put(a, pk->pubkey_algo ); iobuf_put(a, pk->pubkey_algo );
n = pubkey_get_npkey( pk->pubkey_algo ); n = pubkey_get_npkey( pk->pubkey_algo );

View File

@ -395,6 +395,30 @@ cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
return 0; return 0;
} }
int
cmp_signatures( PKT_signature *a, PKT_signature *b )
{
int n, i;
if( a->keyid[0] != b->keyid[0] )
return -1;
if( a->keyid[1] != b->keyid[1] )
return -1;
if( a->pubkey_algo != b->pubkey_algo )
return -1;
n = pubkey_get_nsig( a->pubkey_algo );
if( !n )
return -1; /* can't compare due to unknown algorithm */
for(i=0; i < n; i++ ) {
if( mpi_cmp( a->data[i] , b->data[i] ) )
return -1;
}
return 0;
}
int int
cmp_user_ids( PKT_user_id *a, PKT_user_id *b ) cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
{ {

View File

@ -137,6 +137,7 @@ enum cmd_and_opt_values { aNull = 0,
oSetFilename, oSetFilename,
oComment, oComment,
oThrowKeyid, oThrowKeyid,
oForceV3Sigs,
oS2KMode, oS2KMode,
oS2KDigest, oS2KDigest,
oS2KCipher, oS2KCipher,
@ -205,6 +206,7 @@ static ARGPARSE_OPTS opts[] = {
#endif #endif
{ oOutput, "output", 2, N_("use as output file")}, { oOutput, "output", 2, N_("use as output file")},
{ oVerbose, "verbose", 0, N_("verbose") }, { oVerbose, "verbose", 0, N_("verbose") },
{ oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
/* { oDryRun, "dry-run", 0, N_("do not make any changes") }, */ /* { oDryRun, "dry-run", 0, N_("do not make any changes") }, */
{ oBatch, "batch", 0, N_("batch mode: never ask")}, { oBatch, "batch", 0, N_("batch mode: never ask")},
{ oAnswerYes, "yes", 0, N_("assume yes on most questions")}, { oAnswerYes, "yes", 0, N_("assume yes on most questions")},
@ -714,6 +716,7 @@ main( int argc, char **argv )
case oSetFilename: opt.set_filename = pargs.r.ret_str; break; case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
case oComment: opt.comment_string = pargs.r.ret_str; break; case oComment: opt.comment_string = pargs.r.ret_str; break;
case oThrowKeyid: opt.throw_keyid = 1; break; case oThrowKeyid: opt.throw_keyid = 1; break;
case oForceV3Sigs: opt.force_v3_sigs = 1; break;
case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break;
case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break; case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break; case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;

View File

@ -610,7 +610,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
for(k=keyblock; k; k = k->next ) { for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_SIGNATURE if( k->pkt->pkttype == PKT_SIGNATURE
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10 && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
&& sig->sig_class <= 0x13 && sig->sig_class <= 0x30
&& sig->keyid[0] == kid[0] && sig->keyid[0] == kid[0]
&& sig->keyid[1] == kid[1] && sig->keyid[1] == kid[1]
&& sig->version > 3 ) { && sig->version > 3 ) {
@ -660,7 +660,7 @@ merge_keys_and_selfsig( KBNODE keyblock )
} }
else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10 && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
&& sig->sig_class <= 0x13 && sig->version > 3 && sig->sig_class <= 0x30 && sig->version > 3
&& sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) { && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
/* okay this is (the first) self-signature which can be used /* okay this is (the first) self-signature which can be used
* FIXME: We should only use this if the signature is valid * FIXME: We should only use this if the signature is valid

View File

@ -48,6 +48,7 @@ static void show_fingerprint( PKT_public_key *pk );
static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock ); static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock );
static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock ); static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_select_uid( KBNODE keyblock, int index ); static int menu_select_uid( KBNODE keyblock, int index );
static int menu_select_key( KBNODE keyblock, int index ); static int menu_select_key( KBNODE keyblock, int index );
static int count_uids( KBNODE keyblock ); static int count_uids( KBNODE keyblock );
@ -478,7 +479,7 @@ keyedit_menu( const char *username, STRLIST locusr )
enum cmdids { cmdNONE = 0, enum cmdids { cmdNONE = 0,
cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY,
cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
cmdNOP }; cmdNOP };
static struct { const char *name; static struct { const char *name;
enum cmdids id; enum cmdids id;
@ -504,6 +505,7 @@ keyedit_menu( const char *username, STRLIST locusr )
{ N_("deluid") , cmdDELUID , 0, N_("delete user id") }, { N_("deluid") , cmdDELUID , 0, N_("delete user id") },
{ N_("addkey") , cmdADDKEY , 1, N_("add a secondary key") }, { N_("addkey") , cmdADDKEY , 1, N_("add a secondary key") },
{ N_("delkey") , cmdDELKEY , 0, N_("delete a secondary key") }, { N_("delkey") , cmdDELKEY , 0, N_("delete a secondary key") },
{ N_("expire") , cmdEXPIRE , 1, N_("change the expire date") },
{ N_("toggle") , cmdTOGGLE , 1, N_("toggle between secret " { N_("toggle") , cmdTOGGLE , 1, N_("toggle between secret "
"and public key listing") }, "and public key listing") },
{ N_("t" ) , cmdTOGGLE , 1, NULL }, { N_("t" ) , cmdTOGGLE , 1, NULL },
@ -761,6 +763,16 @@ keyedit_menu( const char *username, STRLIST locusr )
} }
break; break;
case cmdEXPIRE:
if( menu_expire( keyblock, sec_keyblock ) ) {
merge_keys_and_selfsig( sec_keyblock );
merge_keys_and_selfsig( keyblock );
sec_modified = 1;
modified = 1;
redisplay = 1;
}
break;
case cmdPASSWD: case cmdPASSWD:
if( change_passphrase( sec_keyblock ) ) if( change_passphrase( sec_keyblock ) )
sec_modified = 1; sec_modified = 1;
@ -1149,6 +1161,117 @@ menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
} }
static int
menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
{
int n1, rc;
u32 expiredate;
int mainkey=0;
PKT_secret_key *sk; /* copy of the main sk */
PKT_public_key *main_pk, *sub_pk;
PKT_user_id *uid;
KBNODE node;
u32 keyid[2];
if( count_selected_keys( sec_keyblock ) ) {
tty_printf(_("Please remove selections from the secret keys.\n"));
return 0;
}
n1 = count_selected_keys( pub_keyblock );
if( n1 > 1 ) {
tty_printf(_("Please select at most one secondary key.\n"));
return 0;
}
else if( n1 )
tty_printf(_("Changing exiration time for a secondary key.\n"));
else {
tty_printf(_("Changing exiration time for the primary key.\n"));
mainkey=1;
}
expiredate = ask_expiredate();
/* fixme: check that expiredate is > key creation date */
/* get the secret key , make a copy and set the expiration time into
* that key (because keygen_add-key-expire expects it there)
*/
node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
sk->expiredate = expiredate;
/* Now we can actually change the self signature(s) */
main_pk = sub_pk = NULL;
uid = NULL;
for( node=pub_keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
main_pk = node->pkt->pkt.public_key;
keyid_from_pk( main_pk, keyid );
}
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& (node->flag & NODFLG_SELKEY ) )
sub_pk = node->pkt->pkt.public_key;
else if( node->pkt->pkttype == PKT_USER_ID )
uid = node->pkt->pkt.user_id;
else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE ) {
PKT_signature *sig = node->pkt->pkt.signature;
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
&& ( (mainkey && uid && (sig->sig_class&~3) == 0x10)
|| (!mainkey && sig->sig_class == 0x18) ) ) {
/* this is a selfsignature which should be replaced */
PKT_signature *newsig;
PACKET *newpkt;
KBNODE sn;
/* find the corresponding secret self-signature */
for( sn=sec_keyblock; sn; sn = sn->next ) {
if( sn->pkt->pkttype == PKT_SIGNATURE
&& !cmp_signatures( sn->pkt->pkt.signature, sig ) )
break;
}
if( !sn )
log_info(_("No corresponding signature in secret ring\n"));
/* create new self signature */
if( mainkey )
rc = make_keysig_packet( &newsig, main_pk, uid, NULL,
sk, 0x13, 0,
keygen_add_std_prefs, sk );
else
rc = make_keysig_packet( &newsig, main_pk, NULL, sub_pk,
sk, 0x18, 0,
keygen_add_key_expire, sk );
if( rc ) {
log_error("make_keysig_packet failed: %s\n",
g10_errstr(rc));
free_secret_key( sk );
return 0;
}
/* replace the packet */
newpkt = m_alloc_clear( sizeof *newpkt );
newpkt->pkttype = PKT_SIGNATURE;
newpkt->pkt.signature = newsig;
free_packet( node->pkt );
m_free( node->pkt );
node->pkt = newpkt;
if( sn ) {
newpkt = m_alloc_clear( sizeof *newpkt );
newpkt->pkttype = PKT_SIGNATURE;
newpkt->pkt.signature = copy_signature( NULL, newsig );
free_packet( sn->pkt );
m_free( sn->pkt );
sn->pkt = newpkt;
}
}
}
}
free_secret_key( sk );
return 1;
}
/**************** /****************
* Select one user id or remove all selection if index is 0. * Select one user id or remove all selection if index is 0.
* Returns: True if the selection changed; * Returns: True if the selection changed;

View File

@ -51,8 +51,8 @@ write_uid( KBNODE root, const char *s )
static int int
add_key_expire( PKT_signature *sig, void *opaque ) keygen_add_key_expire( PKT_signature *sig, void *opaque )
{ {
PKT_secret_key *sk = opaque; PKT_secret_key *sk = opaque;
byte buf[8]; byte buf[8];
@ -80,7 +80,7 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
{ {
byte buf[8]; byte buf[8];
add_key_expire( sig, opaque ); keygen_add_key_expire( sig, opaque );
buf[0] = CIPHER_ALGO_BLOWFISH; buf[0] = CIPHER_ALGO_BLOWFISH;
buf[1] = CIPHER_ALGO_CAST5; buf[1] = CIPHER_ALGO_CAST5;
@ -176,7 +176,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk )
/* and make the signature */ /* and make the signature */
rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0,
add_key_expire, sk ); keygen_add_key_expire, sk );
if( rc ) { if( rc ) {
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) ); log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
return rc; return rc;
@ -481,7 +481,7 @@ ask_keysize( int algo )
} }
static u32 u32
ask_expiredate() ask_expiredate()
{ {
char *answer; char *answer;
@ -495,7 +495,7 @@ ask_expiredate()
" <n>m = key expires in n months\n" " <n>m = key expires in n months\n"
" <n>y = key expires in n years\n")); " <n>y = key expires in n years\n"));
/* Note: The elgamal subkey for DSA has no exiration date because /* Note: The elgamal subkey for DSA has no exiration date because
* is must be signed with the DSA key and this one has the expiration * it must be signed with the DSA key and this one has the expiration
* date */ * date */
answer = NULL; answer = NULL;

View File

@ -78,7 +78,9 @@ int delete_key( const char *username, int secure );
void keyedit_menu( const char *username, STRLIST locusr ); void keyedit_menu( const char *username, STRLIST locusr );
/*-- keygen.c --*/ /*-- keygen.c --*/
u32 ask_expiredate(void);
void generate_keypair(void); void generate_keypair(void);
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
int keygen_add_std_prefs( PKT_signature *sig, void *opaque ); int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ); int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );

View File

@ -41,7 +41,7 @@ struct {
int no_armor; int no_armor;
int list_packets; /* list-packets mode */ int list_packets; /* list-packets mode */
int def_cipher_algo; int def_cipher_algo;
int reserved1; int force_v3_sigs;
int def_digest_algo; int def_digest_algo;
int def_compress_algo; int def_compress_algo;
const char *def_secret_key; const char *def_secret_key;

View File

@ -273,6 +273,7 @@ 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 *copy_user_id( PKT_user_id *d, PKT_user_id *s );
int cmp_public_keys( PKT_public_key *d, PKT_public_key *s ); int cmp_public_keys( PKT_public_key *d, PKT_public_key *s );
int cmp_signatures( PKT_signature *a, PKT_signature *b );
int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk ); int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
int cmp_user_ids( PKT_user_id *a, PKT_user_id *b ); int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );

View File

@ -608,6 +608,97 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
} }
static void
dump_sig_subpkt( int hashed, int type, int critical,
const char * buffer, size_t buflen, size_t length )
{
const char *p=NULL;
printf("\t%s%ssubpkt %d len %u (", /*)*/
critical ? "critical ":"",
hashed ? "hashed ":"", type, (unsigned)length );
buffer++;
length--;
if( length > buflen ) {
printf("too short: buffer is only %u)\n", (unsigned)buflen );
return;
}
switch( type ) {
case SIGSUBPKT_SIG_CREATED:
if( length >= 4 )
printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) );
break;
case SIGSUBPKT_SIG_EXPIRE:
if( length >= 4 )
printf("sig expires %s", strtimestamp( buffer_to_u32(buffer) ) );
break;
case SIGSUBPKT_EXPORTABLE:
p = "exportable";
break;
case SIGSUBPKT_TRUST:
p = "trust signature";
break;
case SIGSUBPKT_REGEXP:
p = "regular expression";
break;
case SIGSUBPKT_REVOCABLE:
p = "revocable";
break;
case SIGSUBPKT_KEY_EXPIRE:
if( length >= 4 )
printf("key expires %s", strtimestamp( buffer_to_u32(buffer) ) );
break;
case SIGSUBPKT_ARR:
p = "additional recipient request";
break;
case SIGSUBPKT_PREF_SYM:
p = "preferred symmetric algorithms";
break;
case SIGSUBPKT_REV_KEY:
p = "revocation key";
break;
case SIGSUBPKT_ISSUER:
if( length >= 8 )
printf("issuer key ID %08lX%08lX",
(ulong)buffer_to_u32(buffer),
(ulong)buffer_to_u32(buffer+4) );
break;
case SIGSUBPKT_NOTATION:
p = "notation data";
break;
case SIGSUBPKT_PREF_HASH:
p = "preferred hash algorithms";
break;
case SIGSUBPKT_PREF_COMPR:
p = "preferred compression algorithms";
break;
case SIGSUBPKT_KS_FLAGS:
p = "key server preferences";
break;
case SIGSUBPKT_PREF_KS:
p = "preferred key server";
break;
case SIGSUBPKT_PRIMARY_UID:
p = "primary user id";
break;
case SIGSUBPKT_POLICY:
p = "policy URL";
break;
case SIGSUBPKT_KEY_FLAGS:
p = "key flags";
break;
case SIGSUBPKT_SIGNERS_UID:
p = "signer's user id";
break;
case SIGSUBPKT_PRIV_ADD_SIG:
p = "signs additional user id";
break;
default: p = "?"; break;
}
printf("%s)\n", p? p: "");
}
const byte * const byte *
parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n ) parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
{ {
@ -648,32 +739,9 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
} }
else else
critical = 0; critical = 0;
if( reqtype < 0 ) { /* list packets */ if( reqtype < 0 ) /* list packets */
printf("\t%ssubpacket %d of length %u (%s)\n", dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
reqtype == SIGSUBPKT_LIST_HASHED ? "hashed ":"", type, (unsigned)n, type, critical, buffer, buflen, n );
type == SIGSUBPKT_SIG_CREATED ? "signature creation time"
: type == SIGSUBPKT_SIG_EXPIRE ? "signature expiration time"
: type == SIGSUBPKT_EXPORTABLE ? "exportable"
: type == SIGSUBPKT_TRUST ? "trust signature"
: type == SIGSUBPKT_REGEXP ? "regular expression"
: type == SIGSUBPKT_REVOCABLE ? "revocable"
: type == SIGSUBPKT_KEY_EXPIRE ? "key expiration time"
: type == SIGSUBPKT_ARR ? "additional recipient request"
: type == SIGSUBPKT_PREF_SYM ? "preferred symmetric algorithms"
: type == SIGSUBPKT_REV_KEY ? "revocation key"
: type == SIGSUBPKT_ISSUER ? "issuer key ID"
: type == SIGSUBPKT_NOTATION ? "notation data"
: type == SIGSUBPKT_PREF_HASH ? "preferred hash algorithms"
: type == SIGSUBPKT_PREF_COMPR ? "preferred compression algorithms"
: type == SIGSUBPKT_KS_FLAGS ? "key server preferences"
: type == SIGSUBPKT_PREF_KS ? "preferred key server"
: type == SIGSUBPKT_PRIMARY_UID ? "primary user id"
: type == SIGSUBPKT_POLICY ? "policy URL"
: type == SIGSUBPKT_KEY_FLAGS ? "key flags"
: type == SIGSUBPKT_SIGNERS_UID ? "signer's user id"
: type == SIGSUBPKT_PRIV_ADD_SIG? "signs additional user id"
: "?");
}
else if( type == reqtype ) else if( type == reqtype )
break; /* found */ break; /* found */
buffer += n; buflen -=n; buffer += n; buflen -=n;

View File

@ -62,6 +62,8 @@
#include "options.h" #include "options.h"
#include "i18n.h" #include "i18n.h"
#undef HAVE_LIBGDBM /* <--- not ready */
struct resource_table_struct { struct resource_table_struct {
int used; int used;
int secret; /* this is a secret keyring */ int secret; /* this is a secret keyring */
@ -275,6 +277,7 @@ get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
if( !filename || !strcmp( resource_table[i].fname, filename ) ) { if( !filename || !strcmp( resource_table[i].fname, filename ) ) {
memset( kbpos, 0, sizeof *kbpos ); memset( kbpos, 0, sizeof *kbpos );
kbpos->resno = i; kbpos->resno = i;
kbpos->rt = resource_table[i].rt;
return 0; return 0;
} }
} }

View File

@ -108,6 +108,9 @@ only_old_style( SK_LIST sk_list )
SK_LIST sk_rover = NULL; SK_LIST sk_rover = NULL;
int old_style = 0; int old_style = 0;
if( opt.force_v3_sigs )
return 1;
/* if there are only old style capable key we use the old sytle */ /* if there are only old style capable key we use the old sytle */
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk; PKT_secret_key *sk = sk_rover->sk;
@ -369,7 +372,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
/* build the signature packet */ /* build the signature packet */
/* fixme: this code is partly duplicated in make_keysig_packet */ /* fixme: this code is partly duplicated in make_keysig_packet */
sig = m_alloc_clear( sizeof *sig ); sig = m_alloc_clear( sizeof *sig );
sig->version = sk->version; sig->version = old_style? 3 : sk->version;
keyid_from_sk( sk, sig->keyid ); keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo); sig->digest_algo = hash_for(sk->pubkey_algo);
sig->pubkey_algo = sk->pubkey_algo; sig->pubkey_algo = sk->pubkey_algo;
@ -605,7 +608,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
/* build the signature packet */ /* build the signature packet */
/* fixme: this code is duplicated above */ /* fixme: this code is duplicated above */
sig = m_alloc_clear( sizeof *sig ); sig = m_alloc_clear( sizeof *sig );
sig->version = sk->version; sig->version = old_style? 3 : sk->version;
keyid_from_sk( sk, sig->keyid ); keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo); sig->digest_algo = hash_for(sk->pubkey_algo);
sig->pubkey_algo = sk->pubkey_algo; sig->pubkey_algo = sk->pubkey_algo;

View File

@ -962,7 +962,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
} }
break; break;
case RECTYPE_CACH: /* cache record (FIXME)*/ case RECTYPE_CACH: /* cache record */
rec->r.cache.lid = buftoulong(p); p += 4; rec->r.cache.lid = buftoulong(p); p += 4;
memcpy(rec->r.cache.blockhash, p, 20); p += 20; memcpy(rec->r.cache.blockhash, p, 20); p += 20;
rec->r.cache.trustlevel = *p++; rec->r.cache.trustlevel = *p++;
@ -990,7 +990,6 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
/**************** /****************
* Write the record at RECNUM * Write the record at RECNUM
* FIXME: create/update keyhash record.
*/ */
int int
tdbio_write_record( TRUSTREC *rec ) tdbio_write_record( TRUSTREC *rec )
@ -1081,7 +1080,7 @@ tdbio_write_record( TRUSTREC *rec )
ulongtobuf( p, rec->r.sdir.hintlist ); ulongtobuf( p, rec->r.sdir.hintlist );
break; break;
case RECTYPE_CACH: /* FIXME*/ case RECTYPE_CACH:
ulongtobuf(p, rec->r.cache.lid); p += 4; ulongtobuf(p, rec->r.cache.lid); p += 4;
memcpy(p, rec->r.cache.blockhash, 20); p += 20; memcpy(p, rec->r.cache.blockhash, 20); p += 20;
*p++ = rec->r.cache.trustlevel; *p++ = rec->r.cache.trustlevel;

View File

@ -55,7 +55,8 @@
but we mark it to avoid duplicate checks */ but we mark it to avoid duplicate checks */
#define DIRF_REVOKED 8 /* the complete key has been revoked */ #define DIRF_REVOKED 8 /* the complete key has been revoked */
#define KEYF_REVOKED 8 /* this key has been revoked (only useful on subkeys)*/ #define KEYF_EXPIRED 4 /* this key is expired */
#define KEYF_REVOKED 8 /* this key has been revoked */
#define UIDF_CHECKED 1 /* user id has been checked - other bits are valid */ #define UIDF_CHECKED 1 /* user id has been checked - other bits are valid */
#define UIDF_VALID 2 /* this is a valid user id */ #define UIDF_VALID 2 /* this is a valid user id */

View File

@ -2054,7 +2054,7 @@ upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
/**************** /****************
* Note: A signature made with a secondayr key is not considered a * Note: A signature made with a secondary key is not considered a
* self-signature. * self-signature.
*/ */
static void static void
@ -2067,11 +2067,21 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
ulong lid = drec->recnum; ulong lid = drec->recnum;
if( !*uidrecno ) { if( !*uidrecno ) {
/* fixme: handle direct key signatures */ switch( sig->sig_class ) {
log_error("key %08lX: signature without user id\n", (ulong)keyid[1] ); case 0x20:
return; case 0x28: /* We do not need uids for [sub]key revications */
case 0x18: /* or subkey binding */
memset( &urec, 0, sizeof urec ); /* to catch errors */
break;
default:
log_error("key %08lX: signature (class %02x) without user id\n",
(ulong)keyid[1], sig->sig_class );
return;
}
} }
read_record( *uidrecno, &urec, RECTYPE_UID ); else
read_record( *uidrecno, &urec, RECTYPE_UID );
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
if( (sig->sig_class&~3) == 0x10 ) { if( (sig->sig_class&~3) == 0x10 ) {
@ -2099,12 +2109,19 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
urec.dirty = 1; urec.dirty = 1;
} }
} }
else {/* is revocation sig etc */ else if( sig->sig_class == 0x18 ) { /* key binding */
/* FIXME */
}
else if( sig->sig_class == 0x20 ) { /* key revocation */
/* FIXME */
}
else if( sig->sig_class == 0x28 ) { /* subkey revocation */
/* FIXME */
}
else if( sig->sig_class == 0x30 ) { /* cert revocation */
/* FIXME */ /* FIXME */
} }
} }
else if( !*uidrecno )
; /* skip record with direct key signatures here */
else if( (sig->sig_class&~3) == 0x10 ) { else if( (sig->sig_class&~3) == 0x10 ) {
/* We simply insert the signature into the sig records but /* We simply insert the signature into the sig records but
* avoid duplicate ones. We do not check them here because * avoid duplicate ones. We do not check them here because
@ -2365,8 +2382,20 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
} }
} }
else { else if( sig->sig_class == 0x18 ) { /* key binding */
/* handle other sig classes */ log_info(_("key %08lX: bogus key binding by %08lX\n"),
(ulong)keyid[1], (ulong)sig->keyid[1] );
}
else if( sig->sig_class == 0x20 ) { /* key revocation */
log_info(_("key %08lX: bogus key revocation by %08lX\n"),
(ulong)keyid[1], (ulong)sig->keyid[1] );
}
else if( sig->sig_class == 0x28 ) { /* subkey revocation */
log_info(_("key %08lX: bogus subkey revocation by %08lX\n"),
(ulong)keyid[1], (ulong)sig->keyid[1] );
}
else if( sig->sig_class == 0x30 ) { /* cert revocation */
/* FIXME: a signator wants to revoke his certification signature */
} }
leave: leave:

857
po/de.po

File diff suppressed because it is too large Load Diff

846
po/en.po

File diff suppressed because it is too large Load Diff

857
po/fr.po

File diff suppressed because it is too large Load Diff

847
po/it.po

File diff suppressed because it is too large Load Diff

View File

@ -2,34 +2,32 @@
# Run this to generate all the initial makefiles, etc. # Run this to generate all the initial makefiles, etc.
PGM=GnuPG PGM=GnuPG
DIE=no DIE=no
NO_AUTOMAKE=no
(autoconf --version) < /dev/null > /dev/null 2>&1 || { if (autoconf --version) < /dev/null > /dev/null 2>&1 ; then
:
else
echo echo
echo "**Error**: You must have "\`autoconf\'" installed to compile $PGM." echo "**Error**: You must have "\`autoconf\'" installed to compile $PGM."
echo ' (version 2.10 or newer is required' echo ' (version 2.10 or newer is required'
DIE=yes DIE="yes"
} fi
(automake --version) < /dev/null > /dev/null 2>&1 || { if (automake --version) < /dev/null > /dev/null 2>&1 ; then
echo if (aclocal --version) < /dev/null > /dev/null 2>&1; then
echo "**Error**: You must have "\`automake\'" installed to compile $PGM." :
echo ' (version 1.3 or newer is required)' else
DIE=yes
NO_AUTOMAKE=yes
}
# if no automake, don't bother testing for aclocal
test "$NO_AUTOMAKE" = "no" \
|| (aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo echo
echo "**Error**: Missing "\`aclocal\'". The version of "\`automake\' echo "**Error**: Missing "\`aclocal\'". The version of "\`automake\'
echo " installed doesn't appear recent enough." echo " installed doesn't appear recent enough."
DIE=yes DIE="yes"
} fi
else
echo
echo "**Error**: You must have "\`automake\'" installed to compile $PGM."
echo ' (version 1.3 or newer is required)'
DIE="yes"
fi
if test "$DIE" = "yes"; then if test "$DIE" = "yes"; then
exit 1 exit 1

View File

@ -35,7 +35,7 @@
* Create a lockfile with the given name. A TIMEOUT of 0 * Create a lockfile with the given name. A TIMEOUT of 0
* returns immediately, -1 waits forever (hopefully not), other * returns immediately, -1 waits forever (hopefully not), other
* values are timeouts in milliseconds. * values are timeouts in milliseconds.
* Returns: a char pointer used as handle for reelase lock * Returns: a char pointer used as handle for release lock
* or NULL in case of an error. * or NULL in case of an error.
* *
* Notes: This function creates a lock file in the same directory * Notes: This function creates a lock file in the same directory
@ -43,7 +43,7 @@
* A temporary file ".#lk.<pid>.<hostname> is used. * A temporary file ".#lk.<pid>.<hostname> is used.
* This function does nothing for Windoze. * This function does nothing for Windoze.
*/ */
int const char *
make_dotlock( const char *file_to_lock, long timeout ) make_dotlock( const char *file_to_lock, long timeout )
{ {
int rc=-1, fd=-1, pid; int rc=-1, fd=-1, pid;
@ -61,7 +61,7 @@ make_dotlock( const char *file_to_lock, long timeout )
if( !tname ) if( !tname )
log_fatal( "could not create temporary lock file '%s'\n"); log_fatal( "could not create temporary lock file '%s'\n");
log_debug( "dotlock_make: tmpname='%s'\n", tname ); log_debug( "dotlock_make: tmpname='%s'\n", tname );
chmod( tname, 0644 ); /* just in case an "umask" is set */ chmod( tname, 0644 ); /* just in case an umask is set */
if( !(fd = open( tname, O_WRONLY )) ) if( !(fd = open( tname, O_WRONLY )) )
log_fatal( "could not open temporary lock file '%s'\n", tname); log_fatal( "could not open temporary lock file '%s'\n", tname);
if( write(fd, pidstr, 11 ) != 11 ) if( write(fd, pidstr, 11 ) != 11 )
@ -126,21 +126,21 @@ make_dotlock( const char *file_to_lock, long timeout )
int int
release_dotlock( const char *lockfile ) release_dotlock( const char *lockfile )
{ {
int pid = ReadLockfile( lockfile ); int pid = rad_lockfile( lockfile );
if( pid == -1 ) { if( pid == -1 ) {
Log_printf( LERROR, "ReleaseLock: lockfile error"); log_error( "release_dotlock: lockfile error");
return -1; return -1;
} }
if( pid != getpid() ) { if( pid != getpid() ) {
Log_printf( LERROR, "ReleaseLock: not our lock (pid=%d)", pid); log_error( "release_dotlock: not our lock (pid=%d)", pid);
return -1; return -1;
} }
if( remove(lockfile) ) { if( remove( lockfile ) ) {
Log_printf( LERROR, "ReleaseLock: error removing lockfile '%s'", log_error( "release_dotlock: error removing lockfile '%s'",
lockfile); lockfile);
return -1; return -1;
} }
Log_printf( LMESG, "ReleaseLock: released lockfile '%s'", lockfile); log_debug( "release_dotlock: released lockfile '%s'", lockfile);
return 0; return 0;
} }
@ -156,12 +156,12 @@ read_lockfile( const char *name )
if( (fd = open(name, O_RDONLY)) == -1 ) { if( (fd = open(name, O_RDONLY)) == -1 ) {
int e = errno; int e = errno;
Log_printf(LJUNK, "error opening lockfile '%s'", name ); log_debug("error opening lockfile '%s'", name );
errno = e; /* restore errno */ errno = e;
return -1; return -1;
} }
if( read(fd, pidstr, 10 ) != 10 ) { if( read(fd, pidstr, 10 ) != 10 ) {
Log_printf(LNOISE, "error reading lockfile '%s'", name ); log_debug("error reading lockfile '%s'", name );
close(fd); close(fd);
errno = 0; errno = 0;
return -1; return -1;
@ -169,7 +169,7 @@ read_lockfile( const char *name )
close(fd); close(fd);
pid = atoi(pidstr); pid = atoi(pidstr);
if( !pid || pid == -1 ) { if( !pid || pid == -1 ) {
Log_printf(LERROR, "invalid pid %d in lockfile '%s'", pid, name ); log_error("invalid pid %d in lockfile '%s'", pid, name );
errno = 0; errno = 0;
return -1; return -1;
} }

View File

@ -431,7 +431,7 @@ iobuf_close( IOBUF a )
size_t dummy_len; size_t dummy_len;
int rc=0; int rc=0;
if( a->directfp ) { if( a && a->directfp ) {
fclose( a->directfp ); fclose( a->directfp );
if( DBG_IOBUF ) if( DBG_IOBUF )
log_debug("iobuf-close -> %p\n", a->directfp ); log_debug("iobuf-close -> %p\n", a->directfp );