See ChangeLog: Wed Sep 15 16:22:17 CEST 1999 Werner Koch
[gnupg.git] / g10 / keylist.c
index f06b498..91a13af 100644 (file)
@@ -1,14 +1,14 @@
 /* keylist.c
  *     Copyright (C) 1998 Free Software Foundation, Inc.
  *
- * This file is part of GNUPG.
+ * This file is part of GnuPG.
  *
- * GNUPG is free software; you can redistribute it and/or modify
+ * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * GNUPG is distributed in the hope that it will be useful,
+ * GnuPG is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -36,7 +36,8 @@
 #include "i18n.h"
 
 static void list_all(int);
-static void list_one(const char *name, int secret);
+static void list_one( STRLIST names, int secret);
+static void list_keyblock( KBNODE keyblock, int secret );
 static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
 
 
@@ -50,8 +51,11 @@ public_key_list( int nnames, char **names )
     if( !nnames )
        list_all(0);
     else { /* List by user id */
+       STRLIST list = NULL;
        for( ; nnames ; nnames--, names++ )
-           list_one( *names, 0 );
+           add_to_strlist( &list, *names );
+       list_one( list, 0 );
+       free_strlist( list );
     }
 }
 
@@ -61,8 +65,11 @@ secret_key_list( int nnames, char **names )
     if( !nnames )
        list_all(1);
     else { /* List by user id */
+       STRLIST list = NULL;
        for( ; nnames ; nnames--, names++ )
-           list_one( *names, 1 );
+           add_to_strlist( &list, *names );
+       list_one( list, 1 );
+       free_strlist( list );
     }
 }
 
@@ -70,62 +77,115 @@ secret_key_list( int nnames, char **names )
 static void
 list_all( int secret )
 {
-    int i, seq=0;
-    const char *s;
-    IOBUF a;
-
-    while( (s=secret? get_secret_keyring(seq++):get_keyring(seq++)) ) {
-       if( !(a = iobuf_open(s)) ) {
-           log_error(_("can't open %s: %s\n"), s, strerror(errno));
-           continue;
-       }
-       if( seq > 1 )
-           putchar('\n');
-       printf("%s\n", s );
-       for(i=strlen(s); i; i-- )
-           putchar('-');
-       putchar('\n');
+    KBPOS kbpos;
+    KBNODE keyblock = NULL;
+    int rc=0;
+    int lastresno;
 
-       proc_packets( a );
-       iobuf_close(a);
+    rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock );
+    if( rc ) {
+       if( rc != -1 )
+           log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
+       goto leave;
     }
+
+    lastresno = -1;
+    while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
+       if( lastresno != kbpos.resno ) {
+           const char *s = keyblock_resource_name( &kbpos );
+           int i;
+
+           lastresno = kbpos.resno;
+           printf("%s\n", s );
+           for(i=strlen(s); i; i-- )
+               putchar('-');
+           putchar('\n');
+       }
+       merge_keys_and_selfsig( keyblock );
+       list_keyblock( keyblock, secret );
+       release_kbnode( keyblock ); keyblock = NULL;
+    }
+
+    if( rc && rc != -1 )
+       log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
+
+  leave:
+    enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
+    release_kbnode( keyblock );
 }
 
+
+
 static void
-list_one( const char *name, int secret )
+list_one( STRLIST names, int secret )
 {
     int rc = 0;
     KBNODE keyblock = NULL;
+    GETKEY_CTX ctx;
+
+    if( secret ) {
+       rc = get_seckey_bynames( &ctx, NULL, names, &keyblock );
+       if( rc ) {
+           log_error("error reading key: %s\n",  g10_errstr(rc) );
+           get_seckey_end( ctx );
+           return;
+       }
+       do {
+           merge_keys_and_selfsig( keyblock );
+           list_keyblock( keyblock, 1 );
+           release_kbnode( keyblock );
+       } while( !get_seckey_next( ctx, NULL, &keyblock ) );
+       get_seckey_end( ctx );
+    }
+    else {
+       rc = get_pubkey_bynames( &ctx, NULL, names, &keyblock );
+       if( rc ) {
+           log_error("error reading key: %s\n", g10_errstr(rc) );
+           get_pubkey_end( ctx );
+           return;
+       }
+       do {
+           list_keyblock( keyblock, 0 );
+           release_kbnode( keyblock );
+       } while( !get_pubkey_next( ctx, NULL, &keyblock ) );
+       get_pubkey_end( ctx );
+    }
+}
+
+static void
+print_key_data( PKT_public_key *pk, u32 *keyid )
+{
+    int n = pubkey_get_npkey( pk->pubkey_algo );
+    int i;
+
+    for(i=0; i < n; i++ ) {
+       printf("pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
+       mpi_print(stdout, pk->pkey[i], 1 );
+       putchar(':');
+       putchar('\n');
+    }
+}
+
+
+static void
+list_keyblock( KBNODE keyblock, int secret )
+{
+    int rc = 0;
     KBNODE kbctx;
     KBNODE node;
-    KBPOS kbpos;
     PKT_public_key *pk;
     PKT_secret_key *sk;
     u32 keyid[2];
     int any=0;
     int trustletter = 0;
-
-    /* search the userid */
-    rc = secret? find_secret_keyblock_byname( &kbpos, name )
-              : find_keyblock_byname( &kbpos, name );
-    if( rc ) {
-       log_error("%s: user not found\n", name );
-       goto leave;
-    }
-
-    /* read the keyblock */
-    rc = read_keyblock( &kbpos, &keyblock );
-    if( rc ) {
-       log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
-       goto leave;
-    }
-
+    int ulti_hack = 0;
 
     /* get the keyid from the keyblock */
     node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
     if( !node ) {
        log_error("Oops; key lost!\n");
-       goto leave;
+       dump_kbnode( keyblock );
+       return;
     }
 
     if( secret ) {
@@ -133,12 +193,12 @@ list_one( const char *name, int secret )
        sk = node->pkt->pkt.secret_key;
        keyid_from_sk( sk, keyid );
        if( opt.with_colons )
-           printf("sec::%u:%d:%08lX%08lX:%s:%u:::",
+           printf("sec:u:%u:%d:%08lX%08lX:%s:%s:::",
                    nbits_from_sk( sk ),
                    sk->pubkey_algo,
                    (ulong)keyid[0],(ulong)keyid[1],
                    datestr_from_sk( sk ),
-                   (unsigned)sk->valid_days
+                   sk->expiredate? strtimestamp(sk->expiredate):""
                    /* fixme: add LID here */ );
        else
            printf("sec  %4u%c/%08lX %s ", nbits_from_sk( sk ),
@@ -151,18 +211,22 @@ list_one( const char *name, int secret )
        sk = NULL;
        keyid_from_pk( pk, keyid );
        if( opt.with_colons ) {
-           trustletter = query_trust_info( pk );
-           printf("pub:%c:%u:%d:%08lX%08lX:%s:%u:",
+           trustletter = query_trust_info( pk, NULL );
+           if( trustletter == 'u' )
+               ulti_hack = 1;
+           printf("pub:%c:%u:%d:%08lX%08lX:%s:%s:",
                    trustletter,
                    nbits_from_pk( pk ),
                    pk->pubkey_algo,
                    (ulong)keyid[0],(ulong)keyid[1],
                    datestr_from_pk( pk ),
-                   (unsigned)pk->valid_days );
+                   pk->expiredate? strtimestamp(pk->expiredate):""
+                                            );
            if( pk->local_id )
                printf("%lu", pk->local_id );
            putchar(':');
-           /* fixme: add ownertrust here */
+           if( pk->local_id )
+               putchar( get_ownertrust_info( pk->local_id ) );
            putchar(':');
        }
        else
@@ -175,19 +239,37 @@ list_one( const char *name, int secret )
     for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
        if( node->pkt->pkttype == PKT_USER_ID ) {
            if( any ) {
-               if( opt.with_colons )
-                   printf("uid:::::::::");
+               if( opt.with_colons ) {
+                   byte namehash[20];
+
+                   if( pk && !ulti_hack ) {
+                       rmd160_hash_buffer( namehash,
+                                       node->pkt->pkt.user_id->name,
+                                       node->pkt->pkt.user_id->len  );
+                       trustletter = query_trust_info( pk, namehash );
+                   }
+                   else
+                       trustletter = 'u';
+                   printf("uid:%c::::::::", trustletter);
+               }
                else
                    printf("uid%*s", 28, "");
            }
-           print_string( stdout,  node->pkt->pkt.user_id->name,
-                         node->pkt->pkt.user_id->len, opt.with_colons );
-           if( opt.with_colons )
+           if( opt.with_colons ) {
+               print_string( stdout,  node->pkt->pkt.user_id->name,
+                             node->pkt->pkt.user_id->len, ':' );
                putchar(':');
+           }
+           else
+               print_utf8_string( stdout,  node->pkt->pkt.user_id->name,
+                                  node->pkt->pkt.user_id->len );
+
            putchar('\n');
            if( !any ) {
                if( opt.fingerprint )
                    fingerprint( pk, sk );
+               if( opt.with_key_data )
+                   print_key_data( pk, keyid );
                any = 1;
            }
        }
@@ -202,15 +284,17 @@ list_one( const char *name, int secret )
                any = 1;
            }
 
+
+
            keyid_from_pk( pk2, keyid2 );
            if( opt.with_colons ) {
-               printf("sub:%c:%u:%d:%08lX%08lX:%s:%u:",
+               printf("sub:%c:%u:%d:%08lX%08lX:%s:%s:",
                        trustletter,
                        nbits_from_pk( pk2 ),
                        pk2->pubkey_algo,
                        (ulong)keyid2[0],(ulong)keyid2[1],
                        datestr_from_pk( pk2 ),
-                       (unsigned)pk2->valid_days
+                       pk2->expiredate? strtimestamp(pk2->expiredate):""
                        /* fixme: add LID and ownertrust here */
                                                );
                if( pk->local_id ) /* use the local_id of the main key??? */
@@ -224,6 +308,10 @@ list_one( const char *name, int secret )
                                           pubkey_letter( pk2->pubkey_algo ),
                                           (ulong)keyid2[1],
                                           datestr_from_pk( pk2 ) );
+           if( opt.fingerprint > 1 )
+               fingerprint( pk2, NULL );
+           if( opt.with_key_data )
+               print_key_data( pk2, keyid2 );
        }
        else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
            u32 keyid2[2];
@@ -238,12 +326,12 @@ list_one( const char *name, int secret )
 
            keyid_from_sk( sk2, keyid2 );
            if( opt.with_colons )
-               printf("ssb::%u:%d:%08lX%08lX:%s:%u:::\n",
+               printf("ssb::%u:%d:%08lX%08lX:%s:%s:::\n",
                        nbits_from_sk( sk2 ),
                        sk2->pubkey_algo,
                        (ulong)keyid2[0],(ulong)keyid2[1],
                        datestr_from_sk( sk2 ),
-                       (unsigned)sk2->valid_days
+                       sk2->expiredate? strtimestamp(sk2->expiredate):""
                        /* fixme: add LID */
                                                );
            else
@@ -251,6 +339,9 @@ list_one( const char *name, int secret )
                                           pubkey_letter( sk2->pubkey_algo ),
                                           (ulong)keyid2[1],
                                           datestr_from_sk( sk2 ) );
+           if( opt.fingerprint > 1 )
+               fingerprint( NULL, sk2 );
+
        }
        else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
            PKT_signature *sig = node->pkt->pkt.signature;
@@ -261,6 +352,8 @@ list_one( const char *name, int secret )
                    puts("[revoked]");
                else if( sig->sig_class == 0x18 )
                    puts("[key binding]");
+               else if( sig->sig_class == 0x28 )
+                   puts("[subkey revoked]");
                else
                    putchar('\n');
                if( opt.fingerprint )
@@ -268,7 +361,8 @@ list_one( const char *name, int secret )
                any=1;
            }
 
-           if( sig->sig_class == 0x20 || sig->sig_class == 0x30 )
+           if( sig->sig_class == 0x20 || sig->sig_class == 0x28
+                                      || sig->sig_class == 0x30 )
                fputs("rev", stdout);
            else if( (sig->sig_class&~3) == 0x10 )
                fputs("sig", stdout);
@@ -313,7 +407,10 @@ list_one( const char *name, int secret )
            else {
                size_t n;
                char *p = get_user_id( sig->keyid, &n );
-               print_string( stdout, p, n, opt.with_colons );
+               if( opt.with_colons )
+                   print_string( stdout, p, n, ':' );
+               else
+                   print_utf8_string( stdout, p, n );
                m_free(p);
            }
            if( opt.with_colons )
@@ -327,11 +424,11 @@ list_one( const char *name, int secret )
            putchar(':');
        putchar('\n');
     }
+    else if( !opt.with_colons )
+       putchar('\n');  /* separator line */
+}
 
 
-  leave:
-    release_kbnode( keyblock );
-}
 
 static void
 fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
@@ -339,8 +436,8 @@ fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
     byte *array, *p;
     size_t i, n;
 
-    p = array = pk? fingerprint_from_pk( pk, &n )
-                  : fingerprint_from_sk( sk, &n );
+    p = array = pk? fingerprint_from_pk( pk, NULL, &n )
+                  : fingerprint_from_sk( sk, NULL, &n );
     if( opt.with_colons ) {
        printf("fpr:::::::::");
        for(i=0; i < n ; i++, p++ )