aboutsummaryrefslogtreecommitdiffstats
path: root/g10/keylist.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/keylist.c')
-rw-r--r--g10/keylist.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/g10/keylist.c b/g10/keylist.c
index 751a61c9b..4109968c0 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -105,6 +105,83 @@ list_all( int secret )
}
+/****************
+ * Check whether the user ID at NODE is valid; that is it has a
+ * valid self-signature but no later valid revocation.
+ * Caller has to pass the keyID of the primary in mainkey.
+ * Returns: NULL = valid
+ * string with the reason why it is invalid
+ */
+static const char *
+is_uid_valid ( KBNODE keyblock, KBNODE uidnode, u32 *mainkid )
+{
+ KBNODE node;
+ PKT_signature *selfsig = NULL; /* the latest valid self signature */
+
+ /* The key signature verify function can's handle secret keys yet and
+ * becuase we are not sure whether the duplication of user IDs and
+ * self-signatures should be kept on secret keys we are not going to fix
+ * it there. */
+ if ( keyblock->pkt->pkttype == PKT_SECRET_KEY )
+ return NULL;
+
+ assert ( uidnode->pkt->pkttype == PKT_USER_ID
+ || uidnode->pkt->pkttype == PKT_PHOTO_ID );
+
+ /* first find out about the latest valid self-signature */
+ for ( node = uidnode->next; node; node = node->next ) {
+ PKT_signature *sig;
+
+ if ( node->pkt->pkttype == PKT_USER_ID
+ || node->pkt->pkttype == PKT_PHOTO_ID
+ || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY )
+ break;
+ if ( node->pkt->pkttype != PKT_SIGNATURE )
+ continue;
+ sig = node->pkt->pkt.signature;
+ if ( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] )
+ continue; /* we only care about self-signatures for now */
+
+ if ( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */
+ if ( !check_key_signature( keyblock, node, NULL ) ) {
+ if ( !selfsig )
+ selfsig = sig; /* use the first valid sig */
+ else if ( sig->timestamp > selfsig->timestamp
+ && sig->sig_class >= selfsig->sig_class )
+ selfsig = sig; /* but this one is newer */
+ }
+ }
+ }
+
+ if ( !selfsig )
+ return _("invalid"); /* no valid self signature */
+
+ /* watch out for a newer revocation */
+ for ( node = uidnode->next; node; node = node->next ) {
+ PKT_signature *sig;
+
+ if ( node->pkt->pkttype == PKT_USER_ID
+ || node->pkt->pkttype == PKT_PHOTO_ID
+ || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY )
+ break;
+ if ( node->pkt->pkttype != PKT_SIGNATURE )
+ continue;
+ sig = node->pkt->pkt.signature;
+ if ( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] )
+ continue; /* we only care about self-signatures for now */
+
+ if ( sig->sig_class == 0x30
+ && sig->timestamp >= selfsig->timestamp ) {
+ if ( !check_key_signature( keyblock, node, NULL ) )
+ return _("revoked");
+ }
+ }
+
+ return NULL; /* UID is valid */
+}
+
static void
list_one( STRLIST names, int secret )
@@ -263,9 +340,13 @@ list_keyblock( KBNODE keyblock, int secret )
node->pkt->pkt.user_id->len, ':' );
putchar(':');
}
- else
+ else {
+ const char *s = is_uid_valid ( keyblock, node, keyid );
+ if ( s )
+ printf ("[%s] ", s );
print_utf8_string( stdout, node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len );
+ }
putchar('\n');
if( !any ) {