gnupg (10 files)
cvs user wk
cvs at cvs.gnupg.org
Thu Jan 20 18:13:43 CET 2005
Date: Thursday, January 20, 2005 @ 18:21:40
Author: wk
Path: /cvs/gnupg/gnupg
Modified: NEWS doc/README.W32 g10/ChangeLog g10/card-util.c g10/getkey.c
g10/gpgv.c g10/import.c g10/keydb.h g10/keylist.c g10/main.h
* gpgv.c (tty_fprintf): New stub.
* card-util.c (card_status): Create asecret key stub on the fly
and print more information about a card key.
* import.c (pub_to_sec_keyblock, auto_create_card_key_stub): New.
* getkey.c (get_seckeyblock_byfprint): New.
* keylist.c (print_card_key_info): New.
-----------------+
NEWS | 31 +++++--
doc/README.W32 | 14 ---
g10/ChangeLog | 8 +
g10/card-util.c | 35 +++++++-
g10/getkey.c | 32 ++++++-
g10/gpgv.c | 1
g10/import.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
g10/keydb.h | 9 +-
g10/keylist.c | 60 +++++++++++++
g10/main.h | 6 +
10 files changed, 396 insertions(+), 33 deletions(-)
Index: gnupg/NEWS
diff -u gnupg/NEWS:1.228 gnupg/NEWS:1.229
--- gnupg/NEWS:1.228 Thu Jan 20 12:42:03 2005
+++ gnupg/NEWS Thu Jan 20 18:21:40 2005
@@ -1,15 +1,6 @@
Noteworthy changes in version 1.4.1
-------------------------------------------------
- * [W32] The algorithm for the default home directory changed:
- First we look at the environment variable GNUPGHOME, if this one
- is not set, we check whether the registry entry
- HKCU\Software\GNU\GnuPG:HomeDir has been set and if this fails
- we use a GnuPG directory below the standard application data
- directory (APPDATA) of the current user. Only in the case that
- this directory cannot be determined, the old default of c:\gnupg
- will be used. The option --homedir still overrides all of them.
-
* New --rfc2440-text option which controls how text is handled in
signatures. This is in response to some problems seen with
certain PGP/MIME mail clients and GnuPG version 1.4.0. More
@@ -27,6 +18,28 @@
option --with-libcurl. Without this option, the existing HTTP
code is used for HTTP, and HTTPS and FTP are not supported.
+ * When running a --card-status or --card-edit and a public key is
+ available, missing secret key stubs will be created on the fly.
+ Details of the key are listed too.
+
+ * [W32] The algorithm for the default home directory changed:
+ First we look at the environment variable GNUPGHOME, if this one
+ is not set, we check whether the registry entry
+ {HKCU,HKLM}\Software\GNU\GnuPG:HomeDir has been set. If this
+ fails we use a GnuPG directory below the standard application
+ data directory (APPDATA) of the current user. Only in the case
+ that this directory cannot be determined, the old default of
+ c:\gnupg will be used. The option --homedir still overrides all
+ of them.
+
+ * [W32] The locale selection under Windows changed. You need to
+ enter the locale in the registry at HKCU\Software\GNU\GnuPG:Lang.
+ For German you would use "de". If it is not set, GnupG falls
+ back to HKLM. The languages files "*.mo" are expected in a
+ directory named "gnupg.nls" below the installation directory;
+ that directory must be stored in the registry at the same key as
+ above with the name "Install Directory".
+
Noteworthy changes in version 1.4.0 (2004-12-16)
-------------------------------------------------
Index: gnupg/doc/README.W32
diff -u gnupg/doc/README.W32:1.5 gnupg/doc/README.W32:1.6
--- gnupg/doc/README.W32:1.5 Thu Jan 20 12:42:03 2005
+++ gnupg/doc/README.W32 Thu Jan 20 18:21:40 2005
@@ -30,18 +30,10 @@
Internationalization support:
-----------------------------
- 1. Decide where to store the translation files for your language.
- Here we assume the directory "c:/gnu/locale/fr"
+ 1
- 2. Set the directory with the translations into the Registry under
- the key:
- HKEY_CURRENT_USER -> Control Panel -> Mingw32 -> NLS
- (you probably need to create the keys Mingw32 and NLS) using a string
- entry with the name "MoDir".
- 3. Select which language to use and copy the currect translation file
- under the name "gnupg.mo" into the directory set in step 2
- (Example: "copy fr.mo c:\gnu\locale\fr\gnupg.mo")
- 4. Done.
+Store the locale id (like "de") into the registry under the key
+HKEY_CURRENT_USER\Software\GNU\GnuPG with the name "Lang".
How to build it from the source:
Index: gnupg/g10/ChangeLog
diff -u gnupg/g10/ChangeLog:1.682 gnupg/g10/ChangeLog:1.683
--- gnupg/g10/ChangeLog:1.682 Thu Jan 20 12:42:03 2005
+++ gnupg/g10/ChangeLog Thu Jan 20 18:21:40 2005
@@ -1,5 +1,13 @@
2005-01-20 Werner Koch <wk at g10code.com>
+ * gpgv.c (tty_fprintf): New stub.
+
+ * card-util.c (card_status): Create asecret key stub on the fly
+ and print more information about a card key.
+ * import.c (pub_to_sec_keyblock, auto_create_card_key_stub): New.
+ * getkey.c (get_seckeyblock_byfprint): New.
+ * keylist.c (print_card_key_info): New.
+
* g10.c (i18n_init) [W32]: Pass registry key to gettext
initialization.
* gpgv.c (i18n_init) [W32]: Ditto.
Index: gnupg/g10/card-util.c
diff -u gnupg/g10/card-util.c:1.24 gnupg/g10/card-util.c:1.25
--- gnupg/g10/card-util.c:1.24 Tue Dec 14 08:49:26 2004
+++ gnupg/g10/card-util.c Thu Jan 20 18:21:40 2005
@@ -1,5 +1,5 @@
/* card-util.c - Utility functions for the OpenPGP card.
- * Copyright (C) 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -270,6 +270,7 @@
PKT_public_key *pk = xcalloc (1, sizeof *pk);
int rc;
unsigned int uval;
+ const unsigned char *thefpr;
if (serialno && serialnobuflen)
*serialno = 0;
@@ -425,8 +426,34 @@
tty_fprintf (fp, " created ....: %s\n",
asctimestamp (info.fpr3time));
tty_fprintf (fp, "General key info..: ");
- if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20))
- print_pubkey_info (fp, pk);
+
+ thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 :
+ info.fpr3valid? info.fpr3 : NULL);
+ if ( thefpr && !get_pubkey_byfprint (pk, thefpr, 20))
+ {
+ KBNODE keyblock = NULL;
+
+ print_pubkey_info (fp, pk);
+
+ if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
+ print_card_key_info (fp, keyblock);
+ else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
+ {
+ release_kbnode (keyblock);
+ keyblock = NULL;
+
+ if (!auto_create_card_key_stub (info.serialno,
+ info.fpr1valid? info.fpr1:NULL,
+ info.fpr2valid? info.fpr2:NULL,
+ info.fpr3valid? info.fpr3:NULL))
+ {
+ if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
+ print_card_key_info (fp, keyblock);
+ }
+ }
+
+ release_kbnode (keyblock);
+ }
else
tty_fprintf (fp, "[none]\n");
}
@@ -1037,7 +1064,7 @@
}
-/* This fucntion is used by the key edit menu to generate an arbitrary
+/* This function is used by the key edit menu to generate an arbitrary
subkey. */
int
card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
Index: gnupg/g10/getkey.c
diff -u gnupg/g10/getkey.c:1.123 gnupg/g10/getkey.c:1.124
--- gnupg/g10/getkey.c:1.123 Thu Dec 30 04:26:57 2004
+++ gnupg/g10/getkey.c Thu Jan 20 18:21:40 2005
@@ -1,6 +1,6 @@
/* getkey.c - Get a key from the database
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- * 2004 Free Software Foundation, Inc.
+ * 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -1139,13 +1139,41 @@
if (!rc && sk )
sk_from_block ( &ctx, sk, kb );
release_kbnode ( kb );
- get_pubkey_end( &ctx );
+ get_seckey_end( &ctx );
}
else
rc = G10ERR_GENERAL; /* Oops */
return rc;
}
+
+/* Search for a secret key with the given fingerprint and return the
+ complete keyblock which may have more than only this key. */
+int
+get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint,
+ size_t fprint_len )
+{
+ int rc;
+ struct getkey_ctx_s ctx;
+
+ if (fprint_len != 20 && fprint_len == 16)
+ return G10ERR_GENERAL; /* Oops */
+
+ memset (&ctx, 0, sizeof ctx);
+ ctx.not_allocated = 1;
+ ctx.kr_handle = keydb_new (1);
+ ctx.nitems = 1;
+ ctx.items[0].mode = (fprint_len==16
+ ? KEYDB_SEARCH_MODE_FPR16
+ : KEYDB_SEARCH_MODE_FPR20);
+ memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
+ rc = lookup (&ctx, ret_keyblock, 1);
+ get_seckey_end (&ctx);
+
+ return rc;
+}
+
+
/************************************************
************* Merging stuff ********************
Index: gnupg/g10/gpgv.c
diff -u gnupg/g10/gpgv.c:1.26 gnupg/g10/gpgv.c:1.27
--- gnupg/g10/gpgv.c:1.26 Thu Jan 20 12:42:03 2005
+++ gnupg/g10/gpgv.c Thu Jan 20 18:21:40 2005
@@ -380,6 +380,7 @@
/* Stubs to avoid linking to ../util/ttyio.c */
int tty_batchmode( int onoff ) { return 0; }
void tty_printf( const char *fmt, ... ) { }
+void tty_fprintf (FILE *fp, const char *fmt, ... ) { }
void tty_print_string( const byte *p, size_t n ) { }
void tty_print_utf8_string( const byte *p, size_t n ) {}
void tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) {}
Index: gnupg/g10/import.c
diff -u gnupg/g10/import.c:1.119 gnupg/g10/import.c:1.120
--- gnupg/g10/import.c:1.119 Mon Jan 3 16:15:34 2005
+++ gnupg/g10/import.c Thu Jan 20 18:21:40 2005
@@ -1,6 +1,6 @@
-/* import.c
+/* import.c - import a key into our key storage.
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- * 2004 Free Software Foundation, Inc.
+ * 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -2118,3 +2118,232 @@
return 0;
}
+
+
+
+/* Walk a public keyblock and produce a secret keyblock out of it.
+ Instead of inserting the secret key parameters (which we don't
+ have), we insert a stub. */
+static KBNODE
+pub_to_sec_keyblock (KBNODE pub_keyblock)
+{
+ KBNODE pubnode, secnode;
+ KBNODE sec_keyblock = NULL;
+ KBNODE walkctx = NULL;
+
+ while((pubnode = walk_kbnode (pub_keyblock,&walkctx,0)))
+ {
+ if (pubnode->pkt->pkttype == PKT_PUBLIC_KEY
+ || pubnode->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+ {
+ /* Make a secret key. We only need to convert enough to
+ write the keyblock out. */
+ PKT_public_key *pk = pubnode->pkt->pkt.public_key;
+ PACKET *pkt = m_alloc_clear (sizeof *pkt);
+ PKT_secret_key *sk = m_alloc_clear (sizeof *sk);
+ int i, n;
+
+ if (pubnode->pkt->pkttype == PKT_PUBLIC_KEY)
+ pkt->pkttype = PKT_SECRET_KEY;
+ else
+ pkt->pkttype = PKT_SECRET_SUBKEY;
+
+ pkt->pkt.secret_key = sk;
+
+ copy_public_parts_to_secret_key ( pk, sk );
+ sk->version = pk->version;
+ sk->timestamp = pk->timestamp;
+
+ n = pubkey_get_npkey (pk->pubkey_algo);
+ if (!n)
+ n = 1; /* Unknown number of parameters, however the data
+ is stored in the first mpi. */
+ for (i=0; i < n; i++ )
+ sk->skey[i] = mpi_copy (pk->pkey[i]);
+
+ sk->is_protected = 1;
+ sk->protect.s2k.mode = 1001;
+
+ secnode = new_kbnode (pkt);
+ }
+ else
+ {
+ secnode = clone_kbnode (pubnode);
+ }
+
+ if(!sec_keyblock)
+ sec_keyblock = secnode;
+ else
+ add_kbnode (sec_keyblock, secnode);
+ }
+
+ return sec_keyblock;
+}
+
+
+/* Walk over the secret keyring SEC_KEYBLOCK and update any simple
+ stub keys with the serial number SNNUM of the card if one of the
+ fingerprints FPR1, FPR2 or FPR3 match. Print a note if the key is
+ a duplicate (may happen in case of backed uped keys).
+
+ Returns: True if anything changed.
+*/
+static int
+update_sec_keyblock_with_cardinfo (KBNODE sec_keyblock,
+ const unsigned char *fpr1,
+ const unsigned char *fpr2,
+ const unsigned char *fpr3,
+ const char *serialnostr)
+{
+ KBNODE node;
+ KBNODE walkctx = NULL;
+ PKT_secret_key *sk;
+ byte array[MAX_FINGERPRINT_LEN];
+ size_t n;
+ int result = 0;
+ const char *s;
+
+ while((node = walk_kbnode (sec_keyblock, &walkctx, 0)))
+ {
+ if (node->pkt->pkttype != PKT_SECRET_KEY
+ && node->pkt->pkttype != PKT_SECRET_SUBKEY)
+ continue;
+ sk = node->pkt->pkt.secret_key;
+
+ fingerprint_from_sk (sk, array, &n);
+ if (n != 20)
+ continue; /* Can't be a card key. */
+ if ( !((fpr1 && !memcmp (array, fpr1, 20))
+ || (fpr2 && !memcmp (array, fpr2, 20))
+ || (fpr3 && !memcmp (array, fpr3, 20))) )
+ continue; /* No match. */
+
+ if (sk->is_protected == 1 && sk->protect.s2k.mode == 1001)
+ {
+ /* Standard case: migrate that stub to a key stub. */
+ sk->protect.s2k.mode = 1002;
+ s = serialnostr;
+ for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
+ sk->protect.ivlen++, s += 2)
+ sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
+ result = 1;
+ }
+ else if (sk->is_protected == 1 && sk->protect.s2k.mode == 1002)
+ {
+ s = serialnostr;
+ for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
+ sk->protect.ivlen++, s += 2)
+ if (sk->protect.iv[sk->protect.ivlen] != xtoi_2 (s))
+ {
+ log_info (_("NOTE: a key's S/N does not "
+ "match the card's one\n"));
+ break;
+ }
+ }
+ else
+ {
+ if (node->pkt->pkttype != PKT_SECRET_KEY)
+ log_info (_("NOTE: primary key is online and stored on card\n"));
+ else
+ log_info (_("NOTE: secondary key is online and stored on card\n"));
+ }
+ }
+
+ return result;
+}
+
+
+
+/* Check whether a secret key stub exists for the public key PK. If
+ not create such a stub key and store it into the secring. If it
+ exists, add appropriate subkey stubs and update the secring.
+ Return 0 if the key could be created. */
+int
+auto_create_card_key_stub ( const char *serialnostr,
+ const unsigned char *fpr1,
+ const unsigned char *fpr2,
+ const unsigned char *fpr3)
+{
+ KBNODE pub_keyblock;
+ KBNODE sec_keyblock;
+ KEYDB_HANDLE hd;
+ int rc;
+
+ /* We only want to do this for an OpenPGP card. */
+ if (!serialnostr || strncmp (serialnostr, "D27600012401", 12)
+ || strlen (serialnostr) != 32 )
+ return G10ERR_GENERAL;
+
+ /* First get the public keyring from any of the provided fingerprints. */
+ if ( (fpr1 && !get_keyblock_byfprint (&pub_keyblock, fpr1, 20))
+ || (fpr2 && !get_keyblock_byfprint (&pub_keyblock, fpr2, 20))
+ || (fpr3 && !get_keyblock_byfprint (&pub_keyblock, fpr3, 20)))
+ ;
+ else
+ return G10ERR_GENERAL;
+
+ hd = keydb_new (1);
+
+ /* Now check whether there is a secret keyring. */
+ {
+ PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
+ byte afp[MAX_FINGERPRINT_LEN];
+ size_t an;
+
+ fingerprint_from_pk (pk, afp, &an);
+ memset (afp, 0, MAX_FINGERPRINT_LEN);
+ rc = keydb_search_fpr (hd, afp);
+ }
+
+ if (!rc)
+ {
+ rc = keydb_get_keyblock (hd, &sec_keyblock);
+ if (rc)
+ {
+ log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
+ rc = G10ERR_GENERAL;
+ }
+ else
+ {
+ merge_keys_and_selfsig (sec_keyblock);
+
+ /* FIXME: We need to add new subkeys first. */
+ if (update_sec_keyblock_with_cardinfo (sec_keyblock,
+ fpr1, fpr2, fpr3,
+ serialnostr))
+ {
+ rc = keydb_update_keyblock (hd, sec_keyblock );
+ if (rc)
+ log_error (_("error writing keyring `%s': %s\n"),
+ keydb_get_resource_name (hd), g10_errstr(rc) );
+ }
+ }
+ }
+ else /* A secret key does not exists - create it. */
+ {
+ sec_keyblock = pub_to_sec_keyblock (pub_keyblock);
+ update_sec_keyblock_with_cardinfo (sec_keyblock,
+ fpr1, fpr2, fpr3,
+ serialnostr);
+
+ rc = keydb_locate_writable (hd, NULL);
+ if (rc)
+ {
+ log_error (_("no default secret keyring: %s\n"), g10_errstr (rc));
+ rc = G10ERR_GENERAL;
+ }
+ else
+ {
+ rc = keydb_insert_keyblock (hd, sec_keyblock );
+ if (rc)
+ log_error (_("error writing keyring `%s': %s\n"),
+ keydb_get_resource_name (hd), g10_errstr(rc) );
+ }
+ }
+
+ release_kbnode (sec_keyblock);
+ release_kbnode (pub_keyblock);
+ keydb_release (hd);
+ return rc;
+}
+
Index: gnupg/g10/keydb.h
diff -u gnupg/g10/keydb.h:1.87 gnupg/g10/keydb.h:1.88
--- gnupg/g10/keydb.h:1.87 Wed Nov 17 17:04:21 2004
+++ gnupg/g10/keydb.h Thu Jan 20 18:21:40 2005
@@ -224,10 +224,15 @@
int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
STRLIST names, KBNODE *ret_keyblock );
+int get_seckey_next (GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock);
+void get_seckey_end( GETKEY_CTX ctx );
+
int get_seckey_byfprint( PKT_secret_key *sk,
const byte *fprint, size_t fprint_len);
-int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
-void get_seckey_end( GETKEY_CTX ctx );
+int get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint,
+ size_t fprint_len );
+
+
int enum_secret_keys( void **context, PKT_secret_key *sk,
int with_subkeys, int with_spm );
void merge_keys_and_selfsig( KBNODE keyblock );
Index: gnupg/g10/keylist.c
diff -u gnupg/g10/keylist.c:1.94 gnupg/g10/keylist.c:1.95
--- gnupg/g10/keylist.c:1.94 Tue Jan 18 10:51:58 2005
+++ gnupg/g10/keylist.c Thu Jan 20 18:21:40 2005
@@ -1,6 +1,6 @@
/* keylist.c
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- * 2004 Free Software Foundation, Inc.
+ * 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -167,6 +167,60 @@
m_free (p);
}
+
+/* Print basic information of a secret key including the card serial
+ number information. */
+void
+print_card_key_info (FILE *fp, KBNODE keyblock)
+{
+ KBNODE node;
+ int i;
+
+ for (node = keyblock; node; node = node->next )
+ {
+ if (node->pkt->pkttype == PKT_SECRET_KEY
+ || (node->pkt->pkttype == PKT_SECRET_SUBKEY) )
+ {
+ PKT_secret_key *sk = node->pkt->pkt.secret_key;
+
+ tty_fprintf (fp, "%s%c %4u%c/%s ",
+ node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
+ (sk->protect.s2k.mode==1001)?'#':
+ (sk->protect.s2k.mode==1002)?'>':' ',
+ nbits_from_sk (sk),
+ pubkey_letter (sk->pubkey_algo),
+ keystr_from_sk(sk));
+ tty_fprintf (fp, _("created: %s"), datestr_from_sk (sk));
+ tty_fprintf (fp, " ");
+ tty_fprintf (fp, _("expires: %s"), expirestr_from_sk (sk));
+ if (sk->is_protected && sk->protect.s2k.mode == 1002)
+ {
+ tty_fprintf (fp, "\n ");
+ tty_fprintf (fp, _("card-no: "));
+ if (sk->protect.ivlen == 16
+ && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
+ {
+ /* This is an OpenPGP card. */
+ for (i=8; i < 14; i++)
+ {
+ if (i == 10)
+ tty_fprintf (fp, " ");
+ tty_fprintf (fp, "%02X", sk->protect.iv[i]);
+ }
+ }
+ else
+ { /* Something is wrong: Print all. */
+ for (i=0; i < sk->protect.ivlen; i++)
+ tty_fprintf (fp, "%02X", sk->protect.iv[i]);
+ }
+ }
+ tty_fprintf (fp, "\n");
+ }
+ }
+}
+
+
+
/* Flags = 0x01 hashed 0x02 critical */
static void
status_one_subpacket(sigsubpkttype_t type,size_t len,int flags,const byte *buf)
@@ -1437,9 +1491,9 @@
}
else if (mode == 2) {
fp = NULL; /* use tty */
- /* Translators: this should fit into 24 bytes to that the fingerprint
- * data is properly aligned with the user ID */
if(primary)
+ /* TRANSLATORS: this should fit into 24 bytes to that the
+ * fingerprint data is properly aligned with the user ID */
text = _(" Primary key fingerprint:");
else
text = _(" Subkey fingerprint:");
Index: gnupg/g10/main.h
diff -u gnupg/g10/main.h:1.124 gnupg/g10/main.h:1.125
--- gnupg/g10/main.h:1.124 Thu Jan 20 12:42:03 2005
+++ gnupg/g10/main.h Thu Jan 20 18:21:40 2005
@@ -211,6 +211,11 @@
int collapse_uids( KBNODE *keyblock );
+int auto_create_card_key_stub ( const char *serialnostr,
+ const unsigned char *fpr1,
+ const unsigned char *fpr2,
+ const unsigned char *fpr3);
+
/*-- export.c --*/
int parse_export_options(char *str,unsigned int *options,int noisy);
int export_pubkeys( STRLIST users, unsigned int options );
@@ -247,6 +252,7 @@
void set_attrib_fd(int fd);
void print_seckey_info (PKT_secret_key *sk);
void print_pubkey_info (FILE *fp, PKT_public_key *pk);
+void print_card_key_info (FILE *fp, KBNODE keyblock);
/*-- verify.c --*/
void print_file_status( int status, const char *name, int what );
More information about the Gnupg-commits
mailing list