aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog22
-rw-r--r--g10/import.c38
-rw-r--r--g10/mainproc.c22
-rw-r--r--g10/packet.h2
-rw-r--r--g10/parse-packet.c18
-rw-r--r--g10/sig-check.c44
-rw-r--r--g10/status.c1
-rw-r--r--g10/status.h1
8 files changed, 88 insertions, 60 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 642494413..f9958dd6a 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,25 @@
+2003-08-12 David Shaw <[email protected]>
+
+ * packet.h, sig-check.c (signature_check2, do_check,
+ do_check_messages): Provide a signing-key-is-revoked flag. Change
+ all callers.
+
+ * status.h, status.c (get_status_string): New REVKEYSIG status tag
+ for a good signature from a revoked key.
+
+ * mainproc.c (do_check_sig, check_sig_and_print): Use it here.
+
+ * import.c (import_revoke_cert, merge_blocks, merge_sigs): Compare
+ actual signatures on import rather than using keyid or class
+ matching. This does not change actual behavior with a key, but
+ does mean that all sigs are imported whether they will be used or
+ not.
+
+ * parse-packet.c (parse_signature): Don't give "signature packet
+ without xxxx" warnings for experimental pk algorithms. An
+ experimental algorithm may not have a notion of (for example) a
+ keyid (i.e. PGP's x.509 stuff).
+
2003-08-02 David Shaw <[email protected]>
* options.h, g10.c (main), keylist.c (list_keyblock_print),
diff --git a/g10/import.c b/g10/import.c
index 48ef86834..ac4ab7291 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1,5 +1,6 @@
/* import.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -1030,12 +1031,12 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
if( onode->pkt->pkttype == PKT_USER_ID )
break;
else if( onode->pkt->pkttype == PKT_SIGNATURE
- && onode->pkt->pkt.signature->sig_class == 0x20
- && keyid[0] == onode->pkt->pkt.signature->keyid[0]
- && keyid[1] == onode->pkt->pkt.signature->keyid[1] ) {
+ && !cmp_signatures(node->pkt->pkt.signature,
+ onode->pkt->pkt.signature))
+ {
rc = 0;
goto leave; /* yes, we already know about it */
- }
+ }
}
@@ -1554,13 +1555,12 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
break;
else if( onode->pkt->pkttype == PKT_SIGNATURE
&& onode->pkt->pkt.signature->sig_class == 0x20
- && node->pkt->pkt.signature->keyid[0]
- == onode->pkt->pkt.signature->keyid[0]
- && node->pkt->pkt.signature->keyid[1]
- == onode->pkt->pkt.signature->keyid[1] ) {
+ && !cmp_signatures(onode->pkt->pkt.signature,
+ node->pkt->pkt.signature))
+ {
found = 1;
break;
- }
+ }
}
if( !found ) {
char *p=get_user_id_printable (keyid);
@@ -1768,20 +1768,12 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
|| n->pkt->pkt.signature->sig_class == 0x28 )
continue; /* skip signatures which are only valid on subkeys */
found = 0;
- for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next){
- if( n2->pkt->pkttype == PKT_SIGNATURE
- && n->pkt->pkt.signature->keyid[0]
- == n2->pkt->pkt.signature->keyid[0]
- && n->pkt->pkt.signature->keyid[1]
- == n2->pkt->pkt.signature->keyid[1]
- && n->pkt->pkt.signature->timestamp
- <= n2->pkt->pkt.signature->timestamp
- && n->pkt->pkt.signature->sig_class
- == n2->pkt->pkt.signature->sig_class ) {
- found++;
- break;
+ for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next)
+ if(!cmp_signatures(n->pkt->pkt.signature,n2->pkt->pkt.signature))
+ {
+ found++;
+ break;
}
- }
if( !found ) {
/* This signature is new or newer, append N to DST.
* We add a clone to the original keyblock, because this
diff --git a/g10/mainproc.c b/g10/mainproc.c
index e9a658ead..8cb7b9825 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -660,14 +660,12 @@ proc_compressed( CTX c, PACKET *pkt )
* Returns: 0 = valid signature or an error code
*/
static int
-do_check_sig( CTX c, KBNODE node, int *is_selfsig, int *is_expkey )
+do_check_sig( CTX c, KBNODE node, int *is_selfsig,
+ int *is_expkey, int *is_revkey )
{
PKT_signature *sig;
MD_HANDLE md = NULL, md2 = NULL;
- int algo, rc, dum2;
-
- if(!is_expkey)
- is_expkey=&dum2;
+ int algo, rc;
assert( node->pkt->pkttype == PKT_SIGNATURE );
if( is_selfsig )
@@ -721,9 +719,9 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig, int *is_expkey )
}
else
return G10ERR_SIG_CLASS;
- rc = signature_check2( sig, md, NULL, is_expkey, NULL );
+ rc = signature_check2( sig, md, NULL, is_expkey, is_revkey, NULL );
if( rc == G10ERR_BAD_SIGN && md2 )
- rc = signature_check2( sig, md2, NULL, is_expkey, NULL );
+ rc = signature_check2( sig, md2, NULL, is_expkey, is_revkey, NULL );
md_close(md);
md_close(md2);
@@ -946,7 +944,7 @@ list_node( CTX c, KBNODE node )
fputs("sig", stdout);
if( opt.check_sigs ) {
fflush(stdout);
- switch( (rc2=do_check_sig( c, node, &is_selfsig, NULL )) ) {
+ switch( (rc2=do_check_sig( c, node, &is_selfsig, NULL, NULL )) ) {
case 0: sigrc = '!'; break;
case G10ERR_BAD_SIGN: sigrc = '-'; break;
case G10ERR_NO_PUBKEY:
@@ -1205,7 +1203,7 @@ check_sig_and_print( CTX c, KBNODE node )
{
PKT_signature *sig = node->pkt->pkt.signature;
const char *astr, *tstr;
- int rc, is_expkey=0;
+ int rc, is_expkey=0, is_revkey=0;
if( opt.skip_verify ) {
log_info(_("signature verification suppressed\n"));
@@ -1280,10 +1278,10 @@ check_sig_and_print( CTX c, KBNODE node )
(int)strlen(tstr), tstr, astr? astr: "?",
(ulong)sig->keyid[1] );
- rc = do_check_sig(c, node, NULL, &is_expkey );
+ rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
if( rc == G10ERR_NO_PUBKEY && opt.keyserver_scheme && opt.keyserver_options.auto_key_retrieve) {
if( keyserver_import_keyid ( sig->keyid )==0 )
- rc = do_check_sig(c, node, NULL, &is_expkey );
+ rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
}
/* If the key still isn't found, try to inform the user where it
@@ -1319,6 +1317,8 @@ check_sig_and_print( CTX c, KBNODE node )
statno=STATUS_EXPSIG;
else if(is_expkey)
statno=STATUS_EXPKEYSIG;
+ else if(is_revkey)
+ statno=STATUS_REVKEYSIG;
else
statno=STATUS_GOODSIG;
diff --git a/g10/packet.h b/g10/packet.h
index 516c93a44..9d0e36154 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -461,7 +461,7 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
/*-- sig-check.c --*/
int signature_check( PKT_signature *sig, MD_HANDLE digest );
int signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
- int *r_expired, PKT_public_key *ret_pk );
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
/*-- seckey-cert.c --*/
int is_secret_key_protected( PKT_secret_key *sk );
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index b1d1e17df..1ba8f3239 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -1281,17 +1281,19 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
}
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
- if( !p )
- log_error("signature packet without timestamp\n");
- else
- sig->timestamp = buffer_to_u32(p);
+ if(p)
+ sig->timestamp = buffer_to_u32(p);
+ else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+ log_error("signature packet without timestamp\n");
+
p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
- if( !p )
- log_error("signature packet without keyid\n");
- else {
+ if(p)
+ {
sig->keyid[0] = buffer_to_u32(p);
sig->keyid[1] = buffer_to_u32(p+4);
- }
+ }
+ else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+ log_error("signature packet without keyid\n");
p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
if(p)
diff --git a/g10/sig-check.c b/g10/sig-check.c
index c2add6174..c3b6f041a 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -1,5 +1,6 @@
/* sig-check.c - Check a signature
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -40,7 +41,7 @@ struct cmp_help_context_s {
};
static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
- int *r_expired, PKT_public_key *ret_pk);
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
/****************
* Check the signature which is contained in SIG.
@@ -50,12 +51,12 @@ static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
int
signature_check( PKT_signature *sig, MD_HANDLE digest )
{
- return signature_check2( sig, digest, NULL, NULL, NULL );
+ return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
}
int
signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
- int *r_expired, PKT_public_key *ret_pk )
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
{
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
int rc=0;
@@ -77,7 +78,7 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
else {
if(r_expiredate)
*r_expiredate = pk->expiredate;
- rc = do_check( pk, sig, digest, r_expired, ret_pk );
+ rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
}
free_public_key( pk );
@@ -201,12 +202,15 @@ cmp_help( void *opaque, MPI result )
}
static int
-do_check_messages( PKT_public_key *pk, PKT_signature *sig, int *r_expired )
+do_check_messages( PKT_public_key *pk, PKT_signature *sig,
+ int *r_expired, int *r_revoked )
{
u32 cur_time;
if(r_expired)
*r_expired = 0;
+ if(r_revoked)
+ *r_revoked = 0;
if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
log_info(_("key %08lX: this is a PGP generated "
"ElGamal key which is NOT secure for signatures!\n"),
@@ -253,19 +257,22 @@ do_check_messages( PKT_public_key *pk, PKT_signature *sig, int *r_expired )
*r_expired = 1;
}
+ if(pk->is_revoked && r_revoked)
+ *r_revoked=1;
+
return 0;
}
static int
do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
- int *r_expired, PKT_public_key *ret_pk )
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
{
MPI result = NULL;
int rc=0;
struct cmp_help_context_s ctx;
- if( (rc=do_check_messages(pk,sig,r_expired)) )
+ if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
return rc;
if( (rc=check_digest_algo(sig->digest_algo)) )
return rc;
@@ -482,6 +489,8 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
rather than getting it from root or the keydb. If ret_pk is set,
fill in the public key that was used to verify the signature.
ret_pk is only meaningful when the verification was successful. */
+/* TODO: add r_revoked here as well. It has the same problems as
+ r_expiredate and r_expired and the cache. */
int
check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
PKT_public_key *ret_pk, int *is_selfsig,
@@ -516,8 +525,9 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
*is_selfsig = 1;
}
- /* TODO: should set r_expiredate here as well */
- if((rc=do_check_messages(pk,sig,r_expired)))
+ /* BUG: This is wrong for non-self-sigs.. needs to be the
+ actual pk */
+ if((rc=do_check_messages(pk,sig,r_expired,NULL)))
return rc;
return sig->flags.valid? 0 : G10ERR_BAD_SIGN;
}
@@ -537,7 +547,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
{
md = md_open( algo, 0 );
hash_public_key( md, pk );
- rc = do_check( pk, sig, md, r_expired, ret_pk );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
md_close(md);
}
@@ -549,7 +559,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
md = md_open( algo, 0 );
hash_public_key( md, pk );
hash_public_key( md, snode->pkt->pkt.public_key );
- rc = do_check( pk, sig, md, r_expired, ret_pk );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
md_close(md);
}
@@ -575,7 +585,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
md = md_open( algo, 0 );
hash_public_key( md, pk );
hash_public_key( md, snode->pkt->pkt.public_key );
- rc = do_check( pk, sig, md, r_expired, ret_pk );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
md_close(md);
}
@@ -590,7 +600,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
else if( sig->sig_class == 0x1f ) { /* direct key signature */
md = md_open( algo, 0 );
hash_public_key( md, pk );
- rc = do_check( pk, sig, md, r_expired, ret_pk );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
md_close(md);
}
@@ -608,12 +618,12 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
{
if( is_selfsig )
*is_selfsig = 1;
- rc = do_check( pk, sig, md, r_expired, ret_pk );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
}
else if (check_pk)
- rc=do_check(check_pk,sig,md,r_expired, ret_pk);
+ rc=do_check(check_pk,sig,md,r_expired,NULL,ret_pk);
else
- rc = signature_check2( sig, md, r_expiredate, r_expired, ret_pk);
+ rc=signature_check2(sig,md,r_expiredate,r_expired,NULL,ret_pk);
cache_sig_result ( sig, rc );
md_close(md);
diff --git a/g10/status.c b/g10/status.c
index cc30db79b..cde0c8d77 100644
--- a/g10/status.c
+++ b/g10/status.c
@@ -148,6 +148,7 @@ get_status_string ( int no )
case STATUS_SIGEXPIRED : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break;
case STATUS_EXPSIG : s = "EXPSIG"; break;
case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break;
+ case STATUS_REVKEYSIG : s = "REVKEYSIG"; break;
case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break;
default: s = "?"; break;
}
diff --git a/g10/status.h b/g10/status.h
index 44a7d6d32..68da60d28 100644
--- a/g10/status.h
+++ b/g10/status.h
@@ -99,6 +99,7 @@
#define STATUS_ATTRIBUTE 67
#define STATUS_IMPORT_OK 68
#define STATUS_IMPORT_CHECK 69
+#define STATUS_REVKEYSIG 70
/*-- status.c --*/
void set_status_fd ( int fd );