diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 15 | ||||
-rw-r--r-- | g10/helptext.c | 10 | ||||
-rw-r--r-- | g10/import.c | 77 | ||||
-rw-r--r-- | g10/keydb.h | 1 | ||||
-rw-r--r-- | g10/keygen.c | 14 | ||||
-rw-r--r-- | g10/ringedit.c | 17 | ||||
-rw-r--r-- | g10/seckey-cert.c | 2 | ||||
-rw-r--r-- | g10/sig-check.c | 16 | ||||
-rw-r--r-- | g10/sign.c | 10 | ||||
-rw-r--r-- | g10/skclist.c | 26 |
10 files changed, 160 insertions, 28 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index d91abd1c9..9b9493a04 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,18 @@ +Tue Jan 12 11:17:18 CET 1999 Werner Koch <[email protected]> + + * ringedit.c (find_keyblock_bysk): New. + + * skc_list.c (is_insecure): New. + (build_sk_list): usage check for insecure keys. + + * import.c (chk_self_sigs): Add handling for subkeys. + (delete_inv_parts): Skip unsigned subkeys + + * sig-check.c (do_check): Print info if the signature is older + than the key. + * keygen.c (generate_subkeypair): Fail on time warp. + * sign.c (do_sign): Ditto. + Sun Jan 10 15:10:02 CET 1999 Werner Koch <[email protected]> * armor.c (fake_packet): Fixed not-dash-escaped bug. diff --git a/g10/helptext.c b/g10/helptext.c index 2e1bca94d..459f62ed7 100644 --- a/g10/helptext.c +++ b/g10/helptext.c @@ -36,7 +36,7 @@ * Translators should use the key as msgid, this is to keep the msgid short * and to allow for easy changing of the helptexts. * - * Mini gloassary: + * Mini glossary: * * "user ID", "trustdb", "NOTE" and "WARNING". */ @@ -60,14 +60,14 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = { }, { N_("pklist.user_id.enter"), -"Enter the user id of the addresse to whom you want to send the message." +"Enter the user id of the addressee to whom you want to send the message." }, { N_("keygen.algo"), "Select the algorithm to use.\n" "DSA (aka DSS) is the digital signature algorithm which can only be used\n" "for signatures. This is the suggested algorithm because verification of\n" -"DSA signatures are much faster than those of ElGamal\n" +"DSA signatures are much faster than those of ElGamal.\n" "ElGamal is a algorithm which can be used for signatures and encryption.\n" "OpenPGP distunguishs between two flavors of this algorithms: a encrypt only\n" "and a sign+encrypt; actually it is the same, but some parameters must be\n" @@ -75,7 +75,7 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = { "does this but other OpenPGP implemenations are not required to understand\n" "the signature+encryption flavor.\n" "The first (primary) key must always be a key which is capable of signing;\n" -"this is the reason why the ecrytion only ElGamal key is disabled in this." +"this is the reason why the encryption only ElGamal key is disabled in this." }, @@ -165,7 +165,7 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = { { N_("keyedit.remove.uid.okay"), "Answer \"yes\" if you really want to delete this user ID.\n" - "All ceritifcates are then also lost!" + "All certificates are then also lost!" }, { N_("keyedit.remove.subkey.okay"), diff --git a/g10/import.c b/g10/import.c index 734f9b06b..0b5fdf29b 100644 --- a/g10/import.c +++ b/g10/import.c @@ -661,12 +661,13 @@ import_revoke_cert( const char *fname, KBNODE node ) * loop over the keyblock and check all self signatures. * Mark all user-ids with a self-signature by setting flag bit 0. * Mark all user-ids with an invalid self-signature by setting bit 1. + * This works allso for subkeys, here the subkey is marked. */ static int chk_self_sigs( const char *fname, KBNODE keyblock, PKT_public_key *pk, u32 *keyid ) { - KBNODE n, unode; + KBNODE n; PKT_signature *sig; int rc; @@ -675,22 +676,50 @@ chk_self_sigs( const char *fname, KBNODE keyblock, continue; sig = n->pkt->pkt.signature; if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { - unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); - if( !unode ) { - log_error_f(fname, _("key %08lX: no user-id for signature\n"), - (ulong)keyid[1]); - return -1; /* the complete keyblock is invalid */ + if( (sig->sig_class&~3) == 0x10 ) { + KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); + if( !unode ) { + log_error_f(fname, + _("key %08lX: no user-id for signature\n"), + (ulong)keyid[1]); + return -1; /* the complete keyblock is invalid */ + } + rc = check_key_signature( keyblock, n, NULL); + if( rc ) { + log_error_f( fname, rc == G10ERR_PUBKEY_ALGO ? + _("key %08lX: unsupported public key algorithm\n"): + _("key %08lX: invalid self-signature\n"), + (ulong)keyid[1]); + + unode->flag |= 2; /* mark as invalid */ + } + unode->flag |= 1; /* mark that signature checked */ } - rc = check_key_signature( keyblock, n, NULL); - if( rc ) { - log_error_f( fname, rc == G10ERR_PUBKEY_ALGO ? - _("key %08lX: unsupported public key algorithm\n"): - _("key %08lX: invalid self-signature\n"), - (ulong)keyid[1]); - - unode->flag |= 2; /* mark as invalid */ + else if( sig->sig_class == 0x18 ) { + KBNODE knode = find_prev_kbnode( keyblock, + n, PKT_PUBLIC_SUBKEY ); + if( !knode ) + knode = find_prev_kbnode( keyblock, + n, PKT_SECRET_SUBKEY ); + + if( !knode ) { + log_error_f(fname, + _("key %08lX: no subkey for key binding\n"), + (ulong)keyid[1]); + } + else { + rc = check_key_signature( keyblock, n, NULL); + if( rc ) { + log_error_f( fname, rc == G10ERR_PUBKEY_ALGO ? + _("key %08lX: unsupported public key algorithm\n"): + _("key %08lX: invalid subkey binding\n"), + (ulong)keyid[1]); + + knode->flag |= 2; /* mark as invalid */ + } + } + knode->flag |= 1; /* mark that signature checked */ } - unode->flag |= 1; /* mark that signature checked */ } } return 0; @@ -730,6 +759,22 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) else nvalid++; } + else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { + if( (node->flag & 2) || !(node->flag & 1) ) { + if( opt.verbose ) { + log_info_f(fname, _("key %08lX: skipped subkey\n"), + (ulong)keyid[1]); + } + delete_kbnode( node ); /* the subkey */ + /* and all following signature packets */ + while( node->next + && node->next->pkt->pkttype == PKT_SIGNATURE ) { + delete_kbnode( node->next ); + node = node->next; + } + } + } else if( node->pkt->pkttype == PKT_SIGNATURE && check_pubkey_algo( node->pkt->pkt.signature->pubkey_algo) && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA ) @@ -845,7 +890,7 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock, } } - /* merge subkey certifcates */ + /* merge subkey certificates */ for(onode=keyblock_orig->next; onode; onode=onode->next ) { if( !(onode->flag & 1) && ( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY diff --git a/g10/keydb.h b/g10/keydb.h index 4a18b7ea0..73c2d5969 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -194,6 +194,7 @@ int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid, int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos ); int find_keyblock_byname( KBPOS *kbpos, const char *username ); int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk ); +int find_keyblock_bysk( KBPOS *kbpos, PKT_secret_key *sk ); int find_secret_keyblock_byname( KBPOS *kbpos, const char *username ); int lock_keyblock( KBPOS *kbpos ); void unlock_keyblock( KBPOS *kbpos ); diff --git a/g10/keygen.c b/g10/keygen.c index d66585295..2b5d34d3b 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -971,6 +971,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) char *passphrase = NULL; DEK *dek = NULL; STRING2KEY *s2k = NULL; + u32 cur_time; /* break out the primary secret key */ node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); @@ -981,6 +982,19 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) /* make a copy of the sk to keep the protected one in the keyblock */ sk = copy_secret_key( NULL, node->pkt->pkt.secret_key ); + + cur_time = make_timestamp(); + if( sk->timestamp > cur_time ) { + ulong d = sk->timestamp - cur_time; + log_info( d==1 ? _("key has been created %lu second " + "in future (time warp or clock problem)\n") + : _("key has been created %lu seconds " + "in future (time warp or clock problem)\n"), d ); + rc = G10ERR_TIME_CONFLICT; + goto leave; + } + + /* unprotect to get the passphrase */ switch( is_secret_key_protected( sk ) ) { case -1: diff --git a/g10/ringedit.c b/g10/ringedit.c index 10fea1eaf..4a97f78f8 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -480,6 +480,23 @@ find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk ) return rc; } +/**************** + * Combined function to search for a key and get the position + * of the keyblock. + */ +int +find_keyblock_bysk( KBPOS *kbpos, PKT_secret_key *sk ) +{ + PACKET pkt; + int rc; + + init_packet( &pkt ); + pkt.pkttype = PKT_SECRET_KEY; + pkt.pkt.secret_key = sk; + rc = search( &pkt, kbpos, 0 ); + return rc; +} + /**************** * Combined function to search for a username and get the position diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 5edebf782..7712036e4 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -1,4 +1,4 @@ -/* seckey-cert.c - secret key certifucate packet handling +/* seckey-cert.c - secret key certificate packet handling * Copyright (C) 1998 Free Software Foundation, Inc. * * This file is part of GnuPG. diff --git a/g10/sig-check.c b/g10/sig-check.c index 2460cd09a..0eb29eafb 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -157,15 +157,22 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest ) return G10ERR_PUBKEY_ALGO; } - if( pk->timestamp > sig->timestamp ) + if( pk->timestamp > sig->timestamp ) { + ulong d = pk->timestamp - sig->timestamp; + log_info( d==1 + ? _("public key is %lu second newer than the signature\n") + : _("public key is %lu seconds newer than the signature\n"), + d ); return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */ + } cur_time = make_timestamp(); if( pk->timestamp > cur_time ) { ulong d = pk->timestamp - cur_time; - log_info(_("public key created %lu %s " - "in future (time warp or clock problem)\n"), - d, d==1? _("second"):_("seconds") ); + log_info( d==1 ? _("key has been created %lu second " + "in future (time warp or clock problem)\n") + : _("key has been created %lu seconds " + "in future (time warp or clock problem)\n"), d ); return G10ERR_TIME_CONFLICT; } @@ -331,7 +338,6 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ) keyid_from_pk( pk, keyid ); md = md_open( algo, 0 ); - /*md_start_debug(md, "check");*/ hash_public_key( md, pk ); hash_uid_node( unode, md, sig ); if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { diff --git a/g10/sign.c b/g10/sign.c index abb6e9d44..b011043b2 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -47,6 +47,16 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, byte *dp; int rc; + if( sk->timestamp > sig->timestamp ) { + ulong d = sk->timestamp - sig->timestamp; + log_info( d==1 ? _("key has been created %lu second " + "in future (time warp or clock problem)\n") + : _("key has been created %lu seconds " + "in future (time warp or clock problem)\n"), d ); + return G10ERR_TIME_CONFLICT; + } + + print_pubkey_algo_note(sk->pubkey_algo); if( !digest_algo ) diff --git a/g10/skclist.c b/g10/skclist.c index 8ae3fc15b..2c46d6699 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -32,6 +32,7 @@ #include "memory.h" #include "util.h" #include "i18n.h" +#include "cipher.h" void @@ -46,6 +47,19 @@ release_sk_list( SK_LIST sk_list ) } } + +/* Check that we are only using keys which don't have + * the string "(insecure!)" or "not secure" or "do not use" + * in one of the user ids + */ +static int +is_insecure( PKT_secret_key *sk ) +{ + + BUG(); +} + + int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, unsigned usage ) @@ -66,10 +80,15 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, SK_LIST r; if( sk->version == 4 && (usage & PUBKEY_USAGE_SIG) && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_error("this is a PGP generated " + log_info("this is a PGP generated " "ElGamal key which is NOT secure for signatures!\n"); free_secret_key( sk ); sk = NULL; } + else if( random_is_faked() && !is_insecure( sk ) ) { + log_info(_("key is not flagged as insecure - " + "can't use it with the faked RNG!\n")); + free_secret_key( sk ); sk = NULL; + } else { r = m_alloc( sizeof *r ); r->sk = sk; sk = NULL; @@ -102,6 +121,11 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, locusr->d ); free_secret_key( sk ); sk = NULL; } + else if( random_is_faked() && !is_insecure( sk ) ) { + log_info(_("key is not flagged as insecure - " + "can't use it with the faked RNG!\n")); + free_secret_key( sk ); sk = NULL; + } else { r = m_alloc( sizeof *r ); r->sk = sk; sk = NULL; |