aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog15
-rw-r--r--g10/helptext.c10
-rw-r--r--g10/import.c77
-rw-r--r--g10/keydb.h1
-rw-r--r--g10/keygen.c14
-rw-r--r--g10/ringedit.c17
-rw-r--r--g10/seckey-cert.c2
-rw-r--r--g10/sig-check.c16
-rw-r--r--g10/sign.c10
-rw-r--r--g10/skclist.c26
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;