summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/ChangeLog50
-rw-r--r--g10/build-packet.c257
-rw-r--r--g10/card-util.c294
-rw-r--r--g10/delkey.c38
-rw-r--r--g10/export.c837
-rw-r--r--g10/free-packet.c233
-rw-r--r--g10/getkey.c2
-rw-r--r--g10/import.c444
-rw-r--r--g10/keydb.h17
-rw-r--r--g10/keyedit.c94
-rw-r--r--g10/keyid.c452
-rw-r--r--g10/keylist.c154
-rw-r--r--g10/keyring.c35
-rw-r--r--g10/main.h4
-rw-r--r--g10/mainproc.c17
-rw-r--r--g10/packet.h87
-rw-r--r--g10/parse-packet.c300
-rw-r--r--g10/passphrase.c26
-rw-r--r--g10/pubkey-enc.c2
-rw-r--r--g10/sign.c2
20 files changed, 1353 insertions, 1992 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index eede33667..70e471e12 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,53 @@
+2010-09-06 Werner Koch <wk@g10code.com>
+
+
+ * card-util.c (card_status): Remove stub creation fro GnuPG >= 2.
+ (card_store_subkey): Temporary disable this code.
+
+ * keyedit.c (show_key_with_all_names): Merge secret and public key
+ parts.
+ (show_basic_key_info): Ditto.
+ * delkey.c (do_delete_key): Ditto.
+ * export.c (subkey_in_list_p, exact_subkey_match_p): Ditto.
+ (new_subkey_list_item): Ditto.
+
+ * keyid.c (keystr_from_sk, keystr_from_sk_with_sub)
+ (keyid_from_sk, nbits_from_sk, datestr_from_sk)
+ (expirestr_from_sk, colon_datestr_from_sk, fingerprint_from_sk)
+ (serialno_and_fpr_from_sk, do_fingerprint_md_sk): Remove.
+
+ * import.c (print_import_ok): Remove arg SK.
+ (import_secret_one): Adjust for seckey_info format.
+ (transfer_secret_keys): Ditto. Use gpg_format_keydesc.
+ (sec_to_pub_keyblock): Simplify.
+ (pub_to_sec_keyblock): Remove.
+ (auto_create_card_key_stub): Remove - not anymore needed.
+ (update_sec_keyblock_with_cardinfo): Remove.
+ (import_secret_one): Use arg option instead of the global option.
+
+ * free-packet.c (copy_public_key): Adjust for seckey_info format.
+ (copy_public_parts_to_secret_key, copy_secret_key)
+ (cmp_secret_keys, cmp_public_secret_key): Remove.
+
+ * passphrase.c (gpg_format_keydesc): Add arg MODE and change all
+ callers.
+ * keyring.c (keyring_search): Remove special case for secret keys.
+ * mainproc.c (struct mainproc_context): Remove unused field
+ LAST_SECKEY.
+ * parse-packet.c (parse_key): Rewrite to cope with new seckey_info
+ format.
+ * build-packet.c (do_public_key, do_secret_key): Merge code into ...
+ (do_key): .. new. Cope with seckey_info format.
+
+2010-09-03 Werner Koch <wk@g10code.com>
+
+ * packet.h (struct seckey_info): New.
+ (PKT_public_key): Increase size of PKEY to allow storing of secret
+ keys. Add field SECKEY_INFO.
+ (PKT_secret_key): Remove.
+ * free-packet.c (release_public_key_parts): Take care of change.
+ (release_secret_key_parts, free_secret_key): Remove.
+
2010-09-02 Werner Koch <wk@g10code.com>
* import.c (transfer_secret_keys, import_secret_one): Enable stats.
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 37922d90c..354afece7 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -1,6 +1,6 @@
/* build-packet.c - assemble packets and write them
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- * 2006 Free Software Foundation, Inc.
+ * 2006, 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -35,8 +35,7 @@
#include "options.h"
static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
-static int do_public_key( IOBUF out, int ctb, PKT_public_key *pk );
-static int do_secret_key( IOBUF out, int ctb, PKT_secret_key *pk );
+static int do_key (iobuf_t out, int ctb, PKT_public_key *pk);
static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
static u32 calc_plaintext( PKT_plaintext *pt );
@@ -107,11 +106,9 @@ build_packet( IOBUF out, PACKET *pkt )
break;
case PKT_PUBLIC_SUBKEY:
case PKT_PUBLIC_KEY:
- rc = do_public_key( out, ctb, pkt->pkt.public_key );
- break;
case PKT_SECRET_SUBKEY:
case PKT_SECRET_KEY:
- rc = do_secret_key( out, ctb, pkt->pkt.secret_key );
+ rc = do_key (out, ctb, pkt->pkt.public_key);
break;
case PKT_SYMKEY_ENC:
rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
@@ -242,198 +239,162 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
return 0;
}
-static int
-do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
-{
- int rc = 0;
- int n, i;
- IOBUF a = iobuf_temp();
-
- if ( !pk->version )
- iobuf_put( a, 3 );
- else
- iobuf_put( a, pk->version );
- write_32(a, pk->timestamp );
- if ( pk->version < 4 )
- {
- u16 ndays;
- if ( pk->expiredate )
- ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
- else
- ndays = 0;
- write_16(a, ndays );
- }
- iobuf_put (a, pk->pubkey_algo );
- n = pubkey_get_npkey ( pk->pubkey_algo );
- if ( !n )
- write_fake_data( a, pk->pkey[0] );
- for (i=0; i < n && !rc ; i++ )
- rc = mpi_write(a, pk->pkey[i] );
-
- if (!rc)
- {
- write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
- rc = iobuf_write_temp ( out, a );
- }
-
- iobuf_close(a);
- return rc;
-}
-
static int
-do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
+do_key (iobuf_t out, int ctb, PKT_public_key *pk)
{
- int rc = 0;
+ gpg_error_t err = 0;
int i, nskey, npkey;
- IOBUF a = iobuf_temp(); /* Build in a self-enlarging buffer. */
+ iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer. */
/* Write the version number - if none is specified, use 3 */
- if ( !sk->version )
+ if ( !pk->version )
iobuf_put ( a, 3 );
else
- iobuf_put ( a, sk->version );
- write_32 (a, sk->timestamp );
+ iobuf_put ( a, pk->version );
+ write_32 (a, pk->timestamp );
/* v3 needs the expiration time. */
- if ( sk->version < 4 )
+ if ( pk->version < 4 )
{
u16 ndays;
- if ( sk->expiredate )
- ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L);
+ if ( pk->expiredate )
+ ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
else
ndays = 0;
write_16(a, ndays);
}
- iobuf_put (a, sk->pubkey_algo );
+ iobuf_put (a, pk->pubkey_algo );
/* Get number of secret and public parameters. They are held in one
array first the public ones, then the secret ones. */
- nskey = pubkey_get_nskey ( sk->pubkey_algo );
- npkey = pubkey_get_npkey ( sk->pubkey_algo );
+ nskey = pubkey_get_nskey (pk->pubkey_algo);
+ npkey = pubkey_get_npkey (pk->pubkey_algo);
/* If we don't have any public parameters - which is the case if we
don't know the algorithm used - the parameters are stored as one
blob in a faked (opaque) MPI. */
- if ( !npkey )
+ if (!npkey)
{
- write_fake_data( a, sk->skey[0] );
+ write_fake_data (a, pk->pkey[0]);
goto leave;
}
- assert ( npkey < nskey );
+ assert (npkey < nskey);
/* Writing the public parameters is easy. */
for (i=0; i < npkey; i++ )
- if ((rc = mpi_write (a, sk->skey[i])))
+ if ((err = mpi_write (a, pk->pkey[i])))
goto leave;
- /* Build the header for protected (encrypted) secret parameters. */
- if ( sk->is_protected )
+ if (pk->seckey_info)
{
- if ( is_RSA(sk->pubkey_algo)
- && sk->version < 4
- && !sk->protect.s2k.mode )
- {
- /* The simple rfc1991 (v3) way. */
- iobuf_put (a, sk->protect.algo );
- iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
- }
- else
+ /* This is a secret key packet. */
+ struct seckey_info *ski = pk->seckey_info;
+
+ /* Build the header for protected (encrypted) secret parameters. */
+ if (ski->is_protected)
{
- /* OpenPGP protection according to rfc2440. */
- iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff );
- iobuf_put(a, sk->protect.algo );
- if ( sk->protect.s2k.mode >= 1000 )
+ if ( is_RSA (pk->pubkey_algo) && pk->version < 4 && !ski->s2k.mode )
{
- /* These modes are not possible in OpenPGP, we use them
- to implement our extensions, 101 can be seen as a
- private/experimental extension (this is not specified
- in rfc2440 but the same scheme is used for all other
- algorithm identifiers) */
- iobuf_put(a, 101 );
- iobuf_put(a, sk->protect.s2k.hash_algo );
- iobuf_write(a, "GNU", 3 );
- iobuf_put(a, sk->protect.s2k.mode - 1000 );
- }
- else
+ /* The simple rfc1991 (v3) way. */
+ iobuf_put (a, ski->algo );
+ iobuf_write (a, ski->iv, ski->ivlen);
+ }
+ else
{
- iobuf_put(a, sk->protect.s2k.mode );
- iobuf_put(a, sk->protect.s2k.hash_algo );
- }
- if ( sk->protect.s2k.mode == 1
- || sk->protect.s2k.mode == 3 )
- iobuf_write (a, sk->protect.s2k.salt, 8 );
-
- if ( sk->protect.s2k.mode == 3 )
- iobuf_put (a, sk->protect.s2k.count );
-
- /* For our special modes 1001, 1002 we do not need an IV. */
- if ( sk->protect.s2k.mode != 1001
- && sk->protect.s2k.mode != 1002 )
- iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
- }
- }
- else
- iobuf_put (a, 0 );
-
- if ( sk->protect.s2k.mode == 1001 )
- ; /* GnuPG extension - don't write a secret key at all. */
- else if ( sk->protect.s2k.mode == 1002 )
- {
- /* GnuPG extension - divert to OpenPGP smartcard. */
- iobuf_put(a, sk->protect.ivlen ); /* Length of the serial number
- or 0 for no serial
- number. */
- /* The serial number gets stored in the IV field. */
- iobuf_write(a, sk->protect.iv, sk->protect.ivlen);
- }
- else if ( sk->is_protected && sk->version >= 4 )
- {
- /* The secret key is protected - write it out as it is. */
- byte *p;
- unsigned int ndatabits;
-
- assert (gcry_mpi_get_flag (sk->skey[npkey], GCRYMPI_FLAG_OPAQUE));
- p = gcry_mpi_get_opaque (sk->skey[npkey], &ndatabits );
- iobuf_write (a, p, (ndatabits+7)/8 );
- }
- else if ( sk->is_protected )
- {
- /* The secret key is protected the old v4 way. */
- for ( ; i < nskey; i++ )
+ /* OpenPGP protection according to rfc2440. */
+ iobuf_put (a, ski->sha1chk? 0xfe : 0xff);
+ iobuf_put (a, ski->algo);
+ if (ski->s2k.mode >= 1000)
+ {
+ /* These modes are not possible in OpenPGP, we use
+ them to implement our extensions, 101 can be
+ viewed as a private/experimental extension (this
+ is not specified in rfc2440 but the same scheme
+ is used for all other algorithm identifiers). */
+ iobuf_put (a, 101);
+ iobuf_put (a, ski->s2k.hash_algo);
+ iobuf_write (a, "GNU", 3 );
+ iobuf_put (a, ski->s2k.mode - 1000);
+ }
+ else
+ {
+ iobuf_put (a, ski->s2k.mode);
+ iobuf_put (a, ski->s2k.hash_algo);
+ }
+
+ if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
+ iobuf_write (a, ski->s2k.salt, 8);
+
+ if (ski->s2k.mode == 3)
+ iobuf_put (a, ski->s2k.count);
+
+ /* For our special modes 1001, 1002 we do not need an IV. */
+ if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
+ iobuf_write (a, ski->iv, ski->ivlen);
+ }
+ }
+ else /* Not protected. */
+ iobuf_put (a, 0 );
+
+ if (ski->s2k.mode == 1001)
+ ; /* GnuPG extension - don't write a secret key at all. */
+ else if (ski->s2k.mode == 1002)
+ {
+ /* GnuPG extension - divert to OpenPGP smartcard. */
+ /* Length of the serial number or 0 for no serial number. */
+ iobuf_put (a, ski->ivlen );
+ /* The serial number gets stored in the IV field. */
+ iobuf_write (a, ski->iv, ski->ivlen);
+ }
+ else if (ski->is_protected && pk->version >= 4)
{
+ /* The secret key is protected - write it out as it is. */
byte *p;
unsigned int ndatabits;
+
+ assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE));
+ p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits);
+ iobuf_write (a, p, (ndatabits+7)/8 );
+ }
+ else if (ski->is_protected)
+ {
+ /* The secret key is protected the old v4 way. */
+ for ( ; i < nskey; i++ )
+ {
+ byte *p;
+ unsigned int ndatabits;
- assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
- p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
- iobuf_write (a, p, (ndatabits+7)/8);
+ assert (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE));
+ p = gcry_mpi_get_opaque (pk->pkey[i], &ndatabits);
+ iobuf_write (a, p, (ndatabits+7)/8);
+ }
+ write_16 (a, ski->csum );
+ }
+ else
+ {
+ /* Non-protected key. */
+ for ( ; i < nskey; i++ )
+ if ( (err = mpi_write (a, pk->pkey[i])))
+ goto leave;
+ write_16 (a, ski->csum );
}
- write_16(a, sk->csum );
- }
- else
- {
- /* Non-protected key. */
- for ( ; i < nskey; i++ )
- if ( (rc = mpi_write (a, sk->skey[i])))
- goto leave;
- write_16 (a, sk->csum );
}
leave:
- if (!rc)
+ if (!err)
{
/* Build the header of the packet - which we must do after
writing all the other stuff, so that we know the length of
the packet */
- write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes);
- /* And finally write it out the real stream */
- rc = iobuf_write_temp( out, a );
+ write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
+ /* And finally write it out to the real stream. */
+ err = iobuf_write_temp (out, a);
}
- iobuf_close(a); /* Close the remporary buffer */
- return rc;
+ iobuf_close (a); /* Close the temporary buffer */
+ return err;
}
static int
diff --git a/g10/card-util.c b/g10/card-util.c
index 4b537bcb3..1dd7a9219 100644
--- a/g10/card-util.c
+++ b/g10/card-util.c
@@ -207,6 +207,9 @@ get_manufacturer (unsigned int no)
case 0x0005: return "ZeitControl";
case 0x002A: return "Magrathea";
+
+ case 0xF517: return "FSIJ";
+
/* 0x00000 and 0xFFFF are defined as test cards per spec,
0xFFF00 to 0xFFFE are assigned for use with randomly created
serial numbers. */
@@ -581,6 +584,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
print_pubkey_info (fp, pk);
+#if GNUPG_MAJOR_VERSION == 1
if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
print_card_key_info (fp, keyblock);
else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
@@ -599,6 +603,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
}
release_kbnode (keyblock);
+#endif /* GNUPG_MAJOR_VERSION == 1 */
}
else
tty_fprintf (fp, "[none]\n");
@@ -1514,150 +1519,151 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
int
card_store_subkey (KBNODE node, int use)
{
- struct agent_card_info_s info;
- int okay = 0;
- int rc;
- int keyno, i;
- PKT_secret_key *copied_sk = NULL;
- PKT_secret_key *sk;
- size_t n;
- const char *s;
- int allow_keyno[3];
- unsigned int nbits;
-
-
- assert (node->pkt->pkttype == PKT_SECRET_KEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY);
- sk = node->pkt->pkt.secret_key;
-
- if (get_info_for_key_operation (&info))
- return 0;
-
- if (!info.extcap.ki)
- {
- tty_printf ("The card does not support the import of keys\n");
- tty_printf ("\n");
- goto leave;
- }
-
- show_card_key_info (&info);
-
- nbits = nbits_from_sk (sk);
-
- if (!is_RSA (sk->pubkey_algo) || (!info.is_v2 && nbits != 1024) )
- {
- tty_printf ("You may only store a 1024 bit RSA key on the card\n");
- tty_printf ("\n");
- goto leave;
- }
-
- allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG)));
- allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
- allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
-
- tty_printf (_("Please select where to store the key:\n"));
-
- if (allow_keyno[0])
- tty_printf (_(" (1) Signature key\n"));
- if (allow_keyno[1])
- tty_printf (_(" (2) Encryption key\n"));
- if (allow_keyno[2])
- tty_printf (_(" (3) Authentication key\n"));
-
- for (;;)
- {
- char *answer = cpr_get ("cardedit.genkeys.storekeytype",
- _("Your selection? "));
- cpr_kill_prompt();
- if (*answer == CONTROL_D || !*answer)
- {
- xfree (answer);
- goto leave;
- }
- keyno = *answer? atoi(answer): 0;
- xfree(answer);
- if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
- {
- if (info.is_v2 && !info.extcap.aac
- && info.key_attr[keyno-1].nbits != nbits)
- {
- tty_printf ("Key does not match the card's capability.\n");
- }
- else
- break; /* Okay. */
- }
- else
- tty_printf(_("Invalid selection.\n"));
- }
-
- if (replace_existing_key_p (&info, keyno))
- goto leave;
-
- /* Unprotect key. */
- switch (is_secret_key_protected (sk) )
- {
- case 0: /* Not protected. */
- break;
- case -1:
- log_error (_("unknown key protection algorithm\n"));
- goto leave;
- default:
- if (sk->protect.s2k.mode == 1001)
- {
- log_error (_("secret parts of key are not available\n"));
- goto leave;
- }
- if (sk->protect.s2k.mode == 1002)
- {
- log_error (_("secret key already stored on a card\n"));
- goto leave;
- }
- /* We better copy the key before we unprotect it. */
- copied_sk = sk = copy_secret_key (NULL, sk);
- rc = 0/*check_secret_key (sk, 0)*/;
- if (rc)
- goto leave;
- }
-
-#warning code save_unprotected_key_to_card
- /* rc = save_unprotected_key_to_card (sk, keyno); */
- /* if (rc) */
- /* { */
- /* log_error (_("error writing key to card: %s\n"), gpg_strerror (rc)); */
- /* goto leave; */
- /* } */
-
- /* Get back to the maybe protected original secret key. */
- if (copied_sk)
- {
- free_secret_key (copied_sk);
- copied_sk = NULL;
- }
- sk = node->pkt->pkt.secret_key;
-
- /* Get rid of the secret key parameters and store the serial numer. */
- n = pubkey_get_nskey (sk->pubkey_algo);
- for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
- {
- gcry_mpi_release (sk->skey[i]);
- sk->skey[i] = NULL;
- }
- i = pubkey_get_npkey (sk->pubkey_algo);
- sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
- sk->is_protected = 1;
- sk->protect.s2k.mode = 1002;
- s = info.serialno;
- 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);
-
- okay = 1;
-
- leave:
- if (copied_sk)
- free_secret_key (copied_sk);
- agent_release_card_info (&info);
- return okay;
+/* struct agent_card_info_s info; */
+/* int okay = 0; */
+/* int rc; */
+/* int keyno, i; */
+/* PKT_secret_key *copied_sk = NULL; */
+/* PKT_secret_key *sk; */
+/* size_t n; */
+/* const char *s; */
+/* int allow_keyno[3]; */
+/* unsigned int nbits; */
+
+
+/* assert (node->pkt->pkttype == PKT_SECRET_KEY */
+/* || node->pkt->pkttype == PKT_SECRET_SUBKEY); */
+/* sk = node->pkt->pkt.secret_key; */
+
+/* if (get_info_for_key_operation (&info)) */
+/* return 0; */
+
+/* if (!info.extcap.ki) */
+/* { */
+/* tty_printf ("The card does not support the import of keys\n"); */
+/* tty_printf ("\n"); */
+/* goto leave; */
+/* } */
+
+/* show_card_key_info (&info); */
+
+/* nbits = nbits_from_sk (sk); */
+
+/* if (!is_RSA (sk->pubkey_algo) || (!info.is_v2 && nbits != 1024) ) */
+/* { */
+/* tty_printf ("You may only store a 1024 bit RSA key on the card\n"); */
+/* tty_printf ("\n"); */
+/* goto leave; */
+/* } */
+
+/* allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG))); */
+/* allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC))); */
+/* allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH))); */
+
+/* tty_printf (_("Please select where to store the key:\n")); */
+
+/* if (allow_keyno[0]) */
+/* tty_printf (_(" (1) Signature key\n")); */
+/* if (allow_keyno[1]) */
+/* tty_printf (_(" (2) Encryption key\n")); */
+/* if (allow_keyno[2]) */
+/* tty_printf (_(" (3) Authentication key\n")); */
+
+/* for (;;) */
+/* { */
+/* char *answer = cpr_get ("cardedit.genkeys.storekeytype", */
+/* _("Your selection? ")); */
+/* cpr_kill_prompt(); */
+/* if (*answer == CONTROL_D || !*answer) */
+/* { */
+/* xfree (answer); */
+/* goto leave; */
+/* } */
+/* keyno = *answer? atoi(answer): 0; */
+/* xfree(answer); */
+/* if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1]) */
+/* { */
+/* if (info.is_v2 && !info.extcap.aac */
+/* && info.key_attr[keyno-1].nbits != nbits) */
+/* { */
+/* tty_printf ("Key does not match the card's capability.\n"); */
+/* } */
+/* else */
+/* break; /\* Okay. *\/ */
+/* } */
+/* else */
+/* tty_printf(_("Invalid selection.\n")); */
+/* } */
+
+/* if (replace_existing_key_p (&info, keyno)) */
+/* goto leave; */
+
+/* /\* Unprotect key. *\/ */
+/* switch (is_secret_key_protected (sk) ) */
+/* { */
+/* case 0: /\* Not protected. *\/ */
+/* break; */
+/* case -1: */
+/* log_error (_("unknown key protection algorithm\n")); */
+/* goto leave; */
+/* default: */
+/* if (sk->protect.s2k.mode == 1001) */
+/* { */
+/* log_error (_("secret parts of key are not available\n")); */
+/* goto leave; */
+/* } */
+/* if (sk->protect.s2k.mode == 1002) */
+/* { */
+/* log_error (_("secret key already stored on a card\n")); */
+/* goto leave; */
+/* } */
+/* /\* We better copy the key before we unprotect it. *\/ */
+/* copied_sk = sk = copy_secret_key (NULL, sk); */
+/* rc = 0/\*check_secret_key (sk, 0)*\/; */
+/* if (rc) */
+/* goto leave; */
+/* } */
+
+/* #warning code save_unprotected_key_to_card */
+/* /\* rc = save_unprotected_key_to_card (sk, keyno); *\/ */
+/* /\* if (rc) *\/ */
+/* /\* { *\/ */
+/* /\* log_error (_("error writing key to card: %s\n"), gpg_strerror (rc)); *\/ */
+/* /\* goto leave; *\/ */
+/* /\* } *\/ */
+
+/* /\* Get back to the maybe protected original secret key. *\/ */
+/* if (copied_sk) */
+/* { */
+/* free_secret_key (copied_sk); */
+/* copied_sk = NULL; */
+/* } */
+/* sk = node->pkt->pkt.secret_key; */
+
+/* /\* Get rid of the secret key parameters and store the serial numer. *\/ */
+/* n = pubkey_get_nskey (sk->pubkey_algo); */
+/* for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++) */
+/* { */
+/* gcry_mpi_release (sk->skey[i]); */
+/* sk->skey[i] = NULL; */
+/* } */
+/* i = pubkey_get_npkey (sk->pubkey_algo); */
+/* sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8); */
+/* sk->is_protected = 1; */
+/* sk->protect.s2k.mode = 1002; */
+/* s = info.serialno; */
+/* 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); */
+
+/* okay = 1; */
+
+/* leave: */
+/* if (copied_sk) */
+/* free_secret_key (copied_sk); */
+/* agent_release_card_info (&info); */
+/* return okay; */
+ return -1;
}
diff --git a/g10/delkey.c b/g10/delkey.c
index 2361d8323..62c75632b 100644
--- a/g10/delkey.c
+++ b/g10/delkey.c
@@ -54,7 +54,6 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
KBNODE node;
KEYDB_HANDLE hd = keydb_new ();
PKT_public_key *pk = NULL;
- PKT_secret_key *sk = NULL;
u32 keyid[2];
int okay=0;
int yes;
@@ -91,28 +90,19 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
goto leave;
}
- if( secret )
+ pk = node->pkt->pkt.public_key;
+ keyid_from_pk( pk, keyid );
+
+ if (!force)
{
- sk = node->pkt->pkt.secret_key;
- keyid_from_sk( sk, keyid );
- }
- else
- {
- /* public */
- pk = node->pkt->pkt.public_key;
- keyid_from_pk( pk, keyid );
-
- if(!force)
- {
- if (have_secret_key_with_kid (keyid))
- {
- *r_sec_avail = 1;
- rc = -1;
- goto leave;
- }
- else
- rc = 0;
- }
+ if (have_secret_key_with_kid (keyid))
+ {
+ *r_sec_avail = 1;
+ rc = -1;
+ goto leave;
+ }
+ else
+ rc = 0;
}
if( rc )
@@ -133,9 +123,9 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
}
else {
if( secret )
- print_seckey_info( sk );
+ print_seckey_info (pk);
else
- print_pubkey_info(NULL, pk );
+ print_pubkey_info (NULL, pk );
tty_printf( "\n" );
yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"
diff --git a/g10/export.c b/g10/export.c
index e5a0d9d95..bea798e47 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -190,10 +190,7 @@ subkey_in_list_p (subkey_list_t list, KBNODE node)
{
u32 kid[2];
- if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- keyid_from_pk (node->pkt->pkt.public_key, kid);
- else
- keyid_from_sk (node->pkt->pkt.secret_key, kid);
+ keyid_from_pk (node->pkt->pkt.public_key, kid);
for (; list; list = list->next)
if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
@@ -208,10 +205,9 @@ new_subkey_list_item (KBNODE node)
{
subkey_list_t list = xcalloc (1, sizeof *list);
- if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+ if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY)
keyid_from_pk (node->pkt->pkt.public_key, list->kid);
- else if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
- keyid_from_sk (node->pkt->pkt.secret_key, list->kid);
return list;
}
@@ -235,19 +231,13 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
{
case KEYDB_SEARCH_MODE_SHORT_KID:
case KEYDB_SEARCH_MODE_LONG_KID:
- if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- keyid_from_pk (node->pkt->pkt.public_key, kid);
- else
- keyid_from_sk (node->pkt->pkt.secret_key, kid);
+ keyid_from_pk (node->pkt->pkt.public_key, kid);
break;
case KEYDB_SEARCH_MODE_FPR16:
case KEYDB_SEARCH_MODE_FPR20:
case KEYDB_SEARCH_MODE_FPR:
- if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
- else
- fingerprint_from_sk (node->pkt->pkt.secret_key, fpr,&fprlen);
+ fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
break;
default:
@@ -287,451 +277,466 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
/* If keyblock_out is non-NULL, AND the exit code is zero, then it
contains a pointer to the first keyblock found and exported. No
- other keyblocks are exported. The caller must free it. */
+ other keyblocks are exported. The caller must free it. */
static int
-do_export_stream( IOBUF out, strlist_t users, int secret,
- KBNODE *keyblock_out, unsigned int options, int *any )
+do_export_stream (iobuf_t out, strlist_t users, int secret,
+ kbnode_t *keyblock_out, unsigned int options, int *any)
{
- int rc = 0;
- gpg_error_t err;
- PACKET pkt;
- KBNODE keyblock = NULL;
- KBNODE kbctx, node;
- size_t ndesc, descindex;
- KEYDB_SEARCH_DESC *desc = NULL;
- subkey_list_t subkey_list = NULL; /* Track alreay processed subkeys. */
- KEYDB_HANDLE kdbhd;
- strlist_t sl;
- int indent = 0;
-
- *any = 0;
- init_packet( &pkt );
- kdbhd = keydb_new ();
-
- if (!users) {
- ndesc = 1;
- desc = xcalloc ( ndesc, sizeof *desc );
- desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
+ gpg_error_t err = 0;
+ PACKET pkt;
+ KBNODE keyblock = NULL;
+ KBNODE kbctx, node;
+ size_t ndesc, descindex;
+ KEYDB_SEARCH_DESC *desc = NULL;
+ subkey_list_t subkey_list = NULL; /* Track already processed subkeys. */
+ KEYDB_HANDLE kdbhd;
+ strlist_t sl;
+ int indent = 0;
+
+ *any = 0;
+ init_packet (&pkt);
+ kdbhd = keydb_new ();
+
+ if (!users)
+ {
+ ndesc = 1;
+ desc = xcalloc (ndesc, sizeof *desc);
+ desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
}
- else {
- for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
- ;
- desc = xmalloc ( ndesc * sizeof *desc);
+ else
+ {
+ for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
+ ;
+ desc = xmalloc ( ndesc * sizeof *desc);
- for (ndesc=0, sl=users; sl; sl = sl->next) {
- if (!(err=classify_user_id (sl->d, desc+ndesc)))
- ndesc++;
- else
- log_error (_("key \"%s\" not found: %s\n"),
- sl->d, gpg_strerror (err));
+ for (ndesc=0, sl=users; sl; sl = sl->next)
+ {
+ if (!(err=classify_user_id (sl->d, desc+ndesc)))
+ ndesc++;
+ else
+ log_error (_("key \"%s\" not found: %s\n"),
+ sl->d, gpg_strerror (err));
}
- /* It would be nice to see which of the given users did
- actually match one in the keyring. To implement this we
- need to have a found flag for each entry in desc and to set
- this we must check all those entries after a match to mark
- all matched one - currently we stop at the first match. To
- do this we need an extra flag to enable this feature so */
+ /* It would be nice to see which of the given users did actually
+ match one in the keyring. To implement this we need to have
+ a found flag for each entry in desc. To set this flag we
+ must check all those entries after a match to mark all
+ matched one - currently we stop at the first match. To do
+ this we need an extra flag to enable this feature. */
}
#ifdef ENABLE_SELINUX_HACKS
- if (secret) {
- log_error (_("exporting secret keys not allowed\n"));
- rc = G10ERR_GENERAL;
- goto leave;
+ if (secret)
+ {
+ log_error (_("exporting secret keys not allowed\n"));
+ err = G10ERR_GENERAL;
+ goto leave;
}
#endif
- while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) {
- int sha1_warned=0,skip_until_subkey=0;
- u32 sk_keyid[2];
+ while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex)))
+ {
+ int sha1_warned = 0;
+ int skip_until_subkey = 0;
+ u32 keyid[2];
- if (!users)
- desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+ if (!users)
+ desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
- /* Read the keyblock. */
- rc = keydb_get_keyblock (kdbhd, &keyblock );
- if( rc ) {
- log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
- goto leave;
+ /* Read the keyblock. */
+ err = keydb_get_keyblock (kdbhd, &keyblock);
+ if (err)
+ {
+ log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
+ goto leave;
}
- if((node=find_kbnode(keyblock,PKT_SECRET_KEY)))
- {
- PKT_secret_key *sk=node->pkt->pkt.secret_key;
-
- keyid_from_sk(sk,sk_keyid);
-
- /* We can't apply GNU mode 1001 on an unprotected key. */
- if( secret == 2 && !sk->is_protected )
- {
- log_info(_("key %s: not protected - skipped\n"),
- keystr(sk_keyid));
- continue;
- }
-
- /* No v3 keys with GNU mode 1001. */
- if( secret == 2 && sk->version == 3 )
- {
- log_info(_("key %s: PGP 2.x style key - skipped\n"),
- keystr(sk_keyid));
- continue;
- }
-
- /* It does not make sense to export a key with a primary
- key on card using a non-key stub. We simply skip those
- keys when used with --export-secret-subkeys. */
- if (secret == 2 && sk->is_protected
- && sk->protect.s2k.mode == 1002 )
- {
- log_info(_("key %s: key material on-card - skipped\n"),
- keystr(sk_keyid));
- continue;
- }
- }
- else
- {
- /* It's a public key export, so do the cleaning if
- requested. Note that both export-clean and
- export-minimal only apply to UID sigs (0x10, 0x11,
- 0x12, and 0x13). A designated revocation is never
- stripped, even with export-minimal set. */
-
- if(options&EXPORT_CLEAN)
- clean_key(keyblock,opt.verbose,options&EXPORT_MINIMAL,NULL,NULL);
- }
-
- /* And write it. */
- for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
- if( skip_until_subkey )
- {
- if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype==PKT_SECRET_SUBKEY)
- skip_until_subkey=0;
- else
- continue;
- }
-
- /* We used to use comment packets, but not any longer. In
- case we still have comments on a key, strip them here
- before we call build_packet(). */
- if( node->pkt->pkttype == PKT_COMMENT )
- continue;
+ if ((node=find_kbnode(keyblock, PKT_SECRET_KEY)))
+ {
+ PKT_public_key *pk = node->pkt->pkt.public_key;
+
+ keyid_from_pk (pk, keyid);
+
+ /* We can't apply GNU mode 1001 on an unprotected key. */
+ if( secret == 2
+ && pk->seckey_info && !pk->seckey_info->is_protected )
+ {
+ log_info (_("key %s: not protected - skipped\n"),
+ keystr (keyid));
+ continue;
+ }
- /* Make sure that ring_trust packets never get exported. */
- if (node->pkt->pkttype == PKT_RING_TRUST)
+ /* No v3 keys with GNU mode 1001. */
+ if( secret == 2 && pk->version == 3 )
+ {
+ log_info(_("key %s: PGP 2.x style key - skipped\n"),
+ keystr (keyid));
+ continue;
+ }
+
+ /* It does not make sense to export a key with a primary
+ key on card using a non-key stub. We simply skip those
+ keys when used with --export-secret-subkeys. */
+ if (secret == 2
+ && pk->seckey_info && pk->seckey_info->is_protected
+ && pk->seckey_info->s2k.mode == 1002 )
+ {
+ log_info(_("key %s: key material on-card - skipped\n"),
+ keystr (keyid));
continue;
+ }
+ }
+ else
+ {
+ /* It's a public key export, so do the cleaning if
+ requested. Note that both export-clean and
+ export-minimal only apply to UID sigs (0x10, 0x11, 0x12,
+ and 0x13). A designated revocation is never stripped,
+ even with export-minimal set. */
+ if ( (options & EXPORT_CLEAN) )
+ clean_key (keyblock, opt.verbose, options&EXPORT_MINIMAL,
+ NULL, NULL);
+ }
- /* If exact is set, then we only export what was requested
- (plus the primary key, if the user didn't specifically
- request it). */
- if(desc[descindex].exact
- && (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype==PKT_SECRET_SUBKEY))
- {
- if (!exact_subkey_match_p (desc+descindex, node))
- {
- /* Before skipping this subkey, check whether any
- other description wants an exact match on a
- subkey and include that subkey into the output
- too. Need to add this subkey to a list so that
- it won't get processed a second time.
+ /* And write it. */
+ for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
+ {
+ if (skip_until_subkey)
+ {
+ if (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype==PKT_SECRET_SUBKEY)
+ skip_until_subkey = 0;
+ else
+ continue;
+ }
+
+ /* We used to use comment packets, but not any longer. In
+ case we still have comments on a key, strip them here
+ before we call build_packet(). */
+ if (node->pkt->pkttype == PKT_COMMENT)
+ continue;
+
+ /* Make sure that ring_trust packets never get exported. */
+ if (node->pkt->pkttype == PKT_RING_TRUST)
+ continue;
+
+ /* If exact is set, then we only export what was requested
+ (plus the primary key, if the user didn't specifically
+ request it). */
+ if (desc[descindex].exact
+ && (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY))
+ {
+ if (!exact_subkey_match_p (desc+descindex, node))
+ {
+ /* Before skipping this subkey, check whether any
+ other description wants an exact match on a
+ subkey and include that subkey into the output
+ too. Need to add this subkey to a list so that
+ it won't get processed a second time.
- So the first step here is to check that list and
- skip in any case if the key is in that list.
-
- We need this whole mess because the import
- function is not able to merge secret keys and
- thus it is useless to output them as two
- separate keys and have import merge them. */
- if (subkey_in_list_p (subkey_list, node))
- skip_until_subkey = 1; /* Already processed this one. */
- else
- {
- size_t j;
-
- for (j=0; j < ndesc; j++)
- if (j != descindex && desc[j].exact
- && exact_subkey_match_p (desc+j, node))
- break;
- if (!(j < ndesc))
- skip_until_subkey = 1; /* No other one matching. */
- }
- }
-
- if(skip_until_subkey)
- continue;
-
- /* Mark this one as processed. */
+ So the first step here is to check that list and
+ skip in any case if the key is in that list.
+
+ We need this whole mess because the import
+ function is not able to merge secret keys and
+ thus it is useless to output them as two separate
+ keys and have import merge them. */
+ if (subkey_in_list_p (subkey_list, node))
+ skip_until_subkey = 1; /* Already processed this one. */
+ else
+ {
+ size_t j;
+
+ for (j=0; j < ndesc; j++)
+ if (j != descindex && desc[j].exact
+ && exact_subkey_match_p (desc+j, node))
+ break;
+ if (!(j < ndesc))
+ skip_until_subkey = 1; /* No other one matching. */
+ }
+ }
+
+ if(skip_until_subkey)
+ continue;
+
+ /* Mark this one as processed. */
+ {
+ subkey_list_t tmp = new_subkey_list_item (node);
+ tmp->next = subkey_list;
+ subkey_list = tmp;
+ }
+ }
+
+ if (node->pkt->pkttype == PKT_SIGNATURE)
+ {
+ /* Do not export packets which are marked as not
+ exportable. */
+ if (!(options&EXPORT_LOCAL_SIGS)
+ && !node->pkt->pkt.signature->flags.exportable)
+ continue; /* not exportable */
+
+ /* Do not export packets with a "sensitive" revocation
+ key unless the user wants us to. Note that we do
+ export these when issuing the actual revocation
+ (see revoke.c). */
+ if (!(options&EXPORT_SENSITIVE_REVKEYS)
+ && node->pkt->pkt.signature->revkey)
{
- subkey_list_t tmp = new_subkey_list_item (node);
- tmp->next = subkey_list;
- subkey_list = tmp;
+ int i;
+
+ for (i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
+ if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40))
+ break;
+
+ if (i < node->pkt->pkt.signature->numrevkeys)
+ continue;
}
- }
-
- if(node->pkt->pkttype==PKT_SIGNATURE)
- {
- /* do not export packets which are marked as not
- exportable */
- if(!(options&EXPORT_LOCAL_SIGS)
- && !node->pkt->pkt.signature->flags.exportable)
- continue; /* not exportable */
-
- /* Do not export packets with a "sensitive" revocation
- key unless the user wants us to. Note that we do
- export these when issuing the actual revocation
- (see revoke.c). */
- if(!(options&EXPORT_SENSITIVE_REVKEYS)
- && node->pkt->pkt.signature->revkey)
- {
- int i;
-
- for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
- if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
- break;
-
- if(i<node->pkt->pkt.signature->numrevkeys)
- continue;
- }
- }
-
- /* Don't export attribs? */
- if( !(options&EXPORT_ATTRIBUTES) &&
- node->pkt->pkttype == PKT_USER_ID &&
- node->pkt->pkt.user_id->attrib_data ) {
+ }
+
+ /* Don't export attribs? */
+ if (!(options&EXPORT_ATTRIBUTES)
+ && node->pkt->pkttype == PKT_USER_ID
+ && node->pkt->pkt.user_id->attrib_data )
+ {
/* Skip until we get to something that is not an attrib
or a signature on an attrib */
- while(kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) {
- kbctx=kbctx->next;
- }
+ while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE)
+ kbctx = kbctx->next;
continue;
}
- if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY )
- {
- /* We don't want to export the secret parts of the
- * primary key, this is done by using GNU protection mode 1001
- */
- int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
- node->pkt->pkt.secret_key->protect.s2k.mode = 1001;
- if ((options&EXPORT_SEXP_FORMAT))
- rc = build_sexp (out, node->pkt, &indent);
- else
- rc = build_packet (out, node->pkt);
- node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
- }
- else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY
- && (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD))
- {
- /* If the subkey is protected reset the passphrase to
- export an unprotected subkey. This feature is
- useful in cases of a subkey copied to an unattended
- machine where a passphrase is not required. */
- PKT_secret_key *sk_save, *sk;
-
- sk_save = node->pkt->pkt.secret_key;
- sk = copy_secret_key (NULL, sk_save);
- node->pkt->pkt.secret_key = sk;
-
- log_info (_("about to export an unprotected subkey\n"));
- switch (is_secret_key_protected (sk))
- {
- case -1:
- rc = G10ERR_PUBKEY_ALGO;
- break;
- case 0:
- break;
- default:
- if (sk->protect.s2k.mode == 1001)
- ; /* No secret parts. */
- else if( sk->protect.s2k.mode == 1002 )
- ; /* Card key stub. */
- else
- {
- /* rc = check_secret_key( sk, 0 ); */
- }
- break;
- }
- if (rc)
- {
- node->pkt->pkt.secret_key = sk_save;
- free_secret_key (sk);
- log_error (_("failed to unprotect the subkey: %s\n"),
- g10_errstr (rc));
- goto leave;
- }
-
- if ((options&EXPORT_SEXP_FORMAT))
- rc = build_sexp (out, node->pkt, &indent);
- else
- rc = build_packet (out, node->pkt);
-
- node->pkt->pkt.secret_key = sk_save;
- free_secret_key (sk);
- }
- else
- {
- /* Warn the user if the secret key or any of the secret
- subkeys are protected with SHA1 and we have
- simple_sk_checksum set. */
- if(!sha1_warned && opt.simple_sk_checksum &&
- (node->pkt->pkttype==PKT_SECRET_KEY ||
- node->pkt->pkttype==PKT_SECRET_SUBKEY) &&
- node->pkt->pkt.secret_key->protect.sha1chk)
- {
- /* I hope this warning doesn't confuse people. */
- log_info(_("WARNING: secret key %s does not have a "
- "simple SK checksum\n"),keystr(sk_keyid));
-
- sha1_warned=1;
- }
-
- if ((options&EXPORT_SEXP_FORMAT))
- rc = build_sexp (out, node->pkt, &indent);
- else
- rc = build_packet (out, node->pkt);
- }
-
- if( rc ) {
- log_error("build_packet(%d) failed: %s\n",
- node->pkt->pkttype, g10_errstr(rc) );
- goto leave;
+ if (secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY)
+ {
+ /* We don't want to export the secret parts of the
+ * primary key, this is done by temporary switching to
+ * GNU protection mode 1001. */
+ int save_mode = node->pkt->pkt.public_key->seckey_info->s2k.mode;
+ node->pkt->pkt.public_key->seckey_info->s2k.mode = 1001;
+ if ((options&EXPORT_SEXP_FORMAT))
+ err = build_sexp (out, node->pkt, &indent);
+ else
+ err = build_packet (out, node->pkt);
+ node->pkt->pkt.public_key->seckey_info->s2k.mode = save_mode;
+ }
+ else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY
+ && (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD))
+ {
+ /* If the subkey is protected reset the passphrase to
+ export an unprotected subkey. This feature is useful
+ in cases of a subkey copied to an unattended machine
+ where a passphrase is not required. */
+ err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ goto leave;
+#warning We need to implement this
+ /* PKT_secret_key *sk_save, *sk; */
+
+ /* sk_save = node->pkt->pkt.secret_key; */
+ /* sk = copy_secret_key (NULL, sk_save); */
+ /* node->pkt->pkt.secret_key = sk; */
+
+ /* log_info (_("about to export an unprotected subkey\n")); */
+ /* switch (is_secret_key_protected (sk)) */
+ /* { */
+ /* case -1: */
+ /* err = gpg_error (GPG_ERR_PUBKEY_ALGO); */
+ /* break; */
+ /* case 0: */
+ /* break; */
+ /* default: */
+ /* if (sk->protect.s2k.mode == 1001) */
+ /* ; /\* No secret parts. *\/ */
+ /* else if( sk->protect.s2k.mode == 1002 ) */
+ /* ; /\* Card key stub. *\/ */
+ /* else */
+ /* { */
+ /* /\* err = check_secret_key( sk, 0 ); *\/ */
+ /* } */
+ /* break; */
+ /* } */
+ /* if (err) */
+ /* { */
+ /* node->pkt->pkt.secret_key = sk_save; */
+ /* free_secret_key (sk); */
+ /* log_error (_("failed to unprotect the subkey: %s\n"), */
+ /* g10_errstr (rc)); */
+ /* goto leave; */
+ /* } */
+
+ /* if ((options&EXPORT_SEXP_FORMAT)) */
+ /* err = build_sexp (out, node->pkt, &indent); */
+ /* else */
+ /* err = build_packet (out, node->pkt); */
+
+ /* node->pkt->pkt.secret_key = sk_save; */
+ /* free_secret_key (sk); */
+ }
+ else
+ {
+ /* Warn the user if the secret key or any of the secret
+ subkeys are protected with SHA1 and we have
+ simple_sk_checksum set. */
+ if (!sha1_warned && opt.simple_sk_checksum &&
+ (node->pkt->pkttype == PKT_SECRET_KEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+ && node->pkt->pkt.public_key->seckey_info->sha1chk)
+ {
+ /* I hope this warning doesn't confuse people. */
+ log_info(_("WARNING: secret key %s does not have a "
+ "simple SK checksum\n"), keystr (keyid));
+
+ sha1_warned = 1;
+ }
+
+ if ((options&EXPORT_SEXP_FORMAT))
+ err = build_sexp (out, node->pkt, &indent);
+ else
+ err = build_packet (out, node->pkt);
+ }
+
+ if (err)
+ {
+ log_error ("build_packet(%d) failed: %s\n",
+ node->pkt->pkttype, gpg_strerror (err));
+ goto leave;
}
}
- if ((options&EXPORT_SEXP_FORMAT) && indent)
- {
- for (; indent; indent--)
- iobuf_put (out, ')');
- iobuf_put (out, '\n');
- }
-
- ++*any;
- if(keyblock_out)
- {
- *keyblock_out=keyblock;
- break;
- }
+ if ((options&EXPORT_SEXP_FORMAT) && indent)
+ {
+ for (; indent; indent--)
+ iobuf_put (out, ')');
+ iobuf_put (out, '\n');
+ }
+
+ ++*any;
+ if(keyblock_out)
+ {
+ *keyblock_out=keyblock;
+ break;
+ }
}
- if ((options&EXPORT_SEXP_FORMAT) && indent)
- {
- for (; indent; indent--)
- iobuf_put (out, ')');
- iobuf_put (out, '\n');
- }
- if( rc == -1 )
- rc = 0;
-
- leave:
- release_subkey_list (subkey_list);
- xfree(desc);
- keydb_release (kdbhd);
- if(rc || keyblock_out==NULL)
- release_kbnode( keyblock );
- if( !*any )
- log_info(_("WARNING: nothing exported\n"));
- return rc;
+ if ((options&EXPORT_SEXP_FORMAT) && indent)
+ {
+ for (; indent; indent--)
+ iobuf_put (out, ')');
+ iobuf_put (out, '\n');
+ }
+ if( err == -1 )
+ err = 0;
+
+ leave:
+ release_subkey_list (subkey_list);
+ xfree(desc);
+ keydb_release (kdbhd);
+ if (err || !keyblock_out)
+ release_kbnode( keyblock );
+ if( !*any )
+ log_info(_("WARNING: nothing exported\n"));
+ return err;
}
-static int
-write_sexp_line (iobuf_t out, int *indent, const char *text)
-{
- int i;
+/* static int */
+/* write_sexp_line (iobuf_t out, int *indent, const char *text) */
+/* { */
+/* int i; */
- for (i=0; i < *indent; i++)
- iobuf_put (out, ' ');
- iobuf_writestr (out, text);
- return 0;
-}
+/* for (i=0; i < *indent; i++) */
+/* iobuf_put (out, ' '); */
+/* iobuf_writestr (out, text); */
+/* return 0; */
+/* } */
-static int
-write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a)
-{
- int rc;
- unsigned char *buffer;
+/* static int */
+/* write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a) */
+/* { */
+/* int rc; */
+/* unsigned char *buffer; */
- write_sexp_line (out, indent, "(");
- iobuf_writestr (out, name);
- iobuf_writestr (out, " #");
+/* write_sexp_line (out, indent, "("); */
+/* iobuf_writestr (out, name); */
+/* iobuf_writestr (out, " #"); */
- rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a);
- assert (!rc);
- iobuf_writestr (out, buffer);
- iobuf_writestr (out, "#)");
- gcry_free (buffer);
- return 0;
-}
+/* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a); */
+/* assert (!rc); */
+/* iobuf_writestr (out, buffer); */
+/* iobuf_writestr (out, "#)"); */
+/* gcry_free (buffer); */
+/* return 0; */
+/* } */
static int
build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
{
- PKT_secret_key *sk = pkt->pkt.secret_key;
- char tmpbuf[100];
-
- if (pkt->pkttype == PKT_SECRET_KEY)
- {
- iobuf_writestr (out, "(openpgp-key\n");
- (*indent)++;
- }
- else
- {
- iobuf_writestr (out, " (subkey\n");
- (*indent)++;
- }
- (*indent)++;
- write_sexp_line (out, indent, "(private-key\n");
- (*indent)++;
- if (is_RSA (sk->pubkey_algo) && !sk->is_protected)
- {
- write_sexp_line (out, indent, "(rsa\n");
- (*indent)++;
- write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "u", sk->skey[5]);
- iobuf_put (out,')'); iobuf_put (out,'\n');
- (*indent)--;
- }
- else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected)
- {
- write_sexp_line (out, indent, "(dsa\n");
- (*indent)++;
- write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "x", sk->skey[4]);
- iobuf_put (out,')'); iobuf_put (out,'\n');
- (*indent)--;
- }
- else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected)
- {
- write_sexp_line (out, indent, "(elg\n");
- (*indent)++;
- write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "x", sk->skey[4]);
- iobuf_put (out,')'); iobuf_put (out,'\n');
- (*indent)--;
- }
- write_sexp_line (out, indent, "(attrib\n"); (*indent)++;
- sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp);
- write_sexp_line (out, indent, tmpbuf);
- iobuf_put (out,')'); (*indent)--; /* close created */
- iobuf_put (out,')'); (*indent)--; /* close attrib */
- iobuf_put (out,')'); (*indent)--; /* close private-key */
- if (pkt->pkttype != PKT_SECRET_KEY)
- iobuf_put (out,')'), (*indent)--; /* close subkey */
- iobuf_put (out,'\n');
-
- return 0;
+ /* FIXME: Not yet implemented. */
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ /* PKT_secret_key *sk = pkt->pkt.secret_key; */
+ /* char tmpbuf[100]; */
+
+ /* if (pkt->pkttype == PKT_SECRET_KEY) */
+ /* { */
+ /* iobuf_writestr (out, "(openpgp-key\n"); */
+ /* (*indent)++; */
+ /* } */
+ /* else */
+ /* { */
+ /* iobuf_writestr (out, " (subkey\n"); */
+ /* (*indent)++; */
+ /* } */
+ /* (*indent)++; */
+ /* write_sexp_line (out, indent, "(private-key\n"); */
+ /* (*indent)++; */
+ /* if (is_RSA (sk->pubkey_algo) && !sk->is_protected) */
+ /* { */
+ /* write_sexp_line (out, indent, "(rsa\n"); */
+ /* (*indent)++; */
+ /* write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "u", sk->skey[5]); */
+ /* iobuf_put (out,')'); iobuf_put (out,'\n'); */
+ /* (*indent)--; */
+ /* } */
+ /* else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected) */
+ /* { */
+ /* write_sexp_line (out, indent, "(dsa\n"); */
+ /* (*indent)++; */
+ /* write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
+ /* iobuf_put (out,')'); iobuf_put (out,'\n'); */
+ /* (*indent)--; */
+ /* } */
+ /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */
+ /* { */
+ /* write_sexp_line (out, indent, "(elg\n"); */
+ /* (*indent)++; */
+ /* write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
+ /* write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
+ /* iobuf_put (out,')'); iobuf_put (out,'\n'); */
+ /* (*indent)--; */
+ /* } */
+ /* write_sexp_line (out, indent, "(attrib\n"); (*indent)++; */
+ /* sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp); */
+ /* write_sexp_line (out, indent, tmpbuf); */
+ /* iobuf_put (out,')'); (*indent)--; /\* close created *\/ */
+ /* iobuf_put (out,')'); (*indent)--; /\* close attrib *\/ */
+ /* iobuf_put (out,')'); (*indent)--; /\* close private-key *\/ */
+ /* if (pkt->pkttype != PKT_SECRET_KEY) */
+ /* iobuf_put (out,')'), (*indent)--; /\* close subkey *\/ */
+ /* iobuf_put (out,'\n'); */
+
+ /* return 0; */
}
diff --git a/g10/free-packet.c b/g10/free-packet.c
index 5da7fc0ac..47d89eed5 100644
--- a/g10/free-packet.c
+++ b/g10/free-packet.c
@@ -1,6 +1,6 @@
/* free-packet.c - cleanup stuff for packets
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- * 2005 Free Software Foundation, Inc.
+ * 2005, 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -76,37 +76,51 @@ free_seckey_enc( PKT_signature *sig )
void
-release_public_key_parts( PKT_public_key *pk )
+release_public_key_parts (PKT_public_key *pk)
{
- int n, i;
- n = pubkey_get_npkey( pk->pubkey_algo );
- if( !n )
- mpi_release(pk->pkey[0]);
- for(i=0; i < n; i++ ) {
- mpi_release( pk->pkey[i] );
- pk->pkey[i] = NULL;
+ int n, i;
+
+ if (pk->seckey_info)
+ n = pubkey_get_nskey (pk->pubkey_algo);
+ else
+ n = pubkey_get_npkey (pk->pubkey_algo);
+ if (!n)
+ mpi_release (pk->pkey[0]);
+ for (i=0; i < n; i++ )
+ {
+ mpi_release (pk->pkey[i]);
+ pk->pkey[i] = NULL;
}
- if (pk->prefs) {
- xfree (pk->prefs);
- pk->prefs = NULL;
+ if (pk->seckey_info)
+ {
+ xfree (pk->seckey_info);
+ pk->seckey_info = NULL;
}
- if (pk->user_id) {
- free_user_id (pk->user_id);
- pk->user_id = NULL;
+ if (pk->prefs)
+ {
+ xfree (pk->prefs);
+ pk->prefs = NULL;
+ }
+ if (pk->user_id)
+ {
+ free_user_id (pk->user_id);
+ pk->user_id = NULL;
}
- if (pk->revkey) {
- xfree(pk->revkey);
- pk->revkey=NULL;
- pk->numrevkeys=0;
+ if (pk->revkey)
+ {
+ xfree(pk->revkey);
+ pk->revkey=NULL;
+ pk->numrevkeys=0;
}
+
}
void
-free_public_key( PKT_public_key *pk )
+free_public_key (PKT_public_key *pk)
{
- release_public_key_parts( pk );
- xfree(pk);
+ release_public_key_parts (pk);
+ xfree(pk);
}
@@ -150,55 +164,45 @@ copy_prefs (const prefitem_t *prefs)
}
+/* Copy the public key S to D. If D is NULL allocate a new public key
+ structure. If S has seckret key infos, only the public stuff is
+ copied. */
PKT_public_key *
-copy_public_key ( PKT_public_key *d, PKT_public_key *s)
+copy_public_key (PKT_public_key *d, PKT_public_key *s)
{
- int n, i;
-
- if( !d )
- d = xmalloc(sizeof *d);
- memcpy( d, s, sizeof *d );
- d->user_id = scopy_user_id (s->user_id);
- d->prefs = copy_prefs (s->prefs);
- n = pubkey_get_npkey( s->pubkey_algo );
- if( !n )
- d->pkey[0] = mpi_copy(s->pkey[0]);
- else {
- for(i=0; i < n; i++ )
- d->pkey[i] = mpi_copy( s->pkey[i] );
+ int n, i;
+
+ if (!d)
+ d = xmalloc (sizeof *d);
+ memcpy (d, s, sizeof *d);
+ d->seckey_info = NULL;
+ d->user_id = scopy_user_id (s->user_id);
+ d->prefs = copy_prefs (s->prefs);
+
+ n = pubkey_get_npkey (s->pubkey_algo);
+ i = 0;
+ if (!n)
+ d->pkey[i++] = mpi_copy (s->pkey[0]);
+ else
+ {
+ for (; i < n; i++ )
+ d->pkey[i] = mpi_copy( s->pkey[i] );
}
- if( !s->revkey && s->numrevkeys )
- BUG();
- if( s->numrevkeys ) {
- d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
- memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
+ for (; i < PUBKEY_MAX_NSKEY; i++)
+ d->pkey[i] = NULL;
+
+ if (!s->revkey && s->numrevkeys)
+ BUG();
+ if (s->numrevkeys)
+ {
+ d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
+ memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
}
- else
- d->revkey = NULL;
- return d;
+ else
+ d->revkey = NULL;
+ return d;
}
-/****************
- * Replace all common parts of a sk by the one from the public key.
- * This is a hack and a better solution will be to just store the real secret
- * parts somewhere and don't duplicate all the other stuff.
- */
-void
-copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
- sk->expiredate = pk->expiredate;
- sk->pubkey_algo = pk->pubkey_algo;
- sk->pubkey_usage= pk->pubkey_usage;
- sk->req_usage = pk->req_usage;
- sk->req_algo = pk->req_algo;
- sk->has_expired = pk->has_expired;
- sk->is_revoked = pk->is_revoked;
- sk->is_valid = pk->is_valid;
- sk->main_keyid[0]= pk->main_keyid[0];
- sk->main_keyid[1]= pk->main_keyid[1];
- sk->keyid[0] = pk->keyid[0];
- sk->keyid[1] = pk->keyid[1];
-}
static pka_info_t *
@@ -257,48 +261,6 @@ scopy_user_id (PKT_user_id *s)
void
-release_secret_key_parts( PKT_secret_key *sk )
-{
- int n, i;
-
- n = pubkey_get_nskey( sk->pubkey_algo );
- if( !n )
- mpi_release(sk->skey[0]);
- for(i=0; i < n; i++ ) {
- mpi_release( sk->skey[i] );
- sk->skey[i] = NULL;
- }
-}
-
-void
-free_secret_key( PKT_secret_key *sk )
-{
- release_secret_key_parts( sk );
- xfree(sk);
-}
-
-PKT_secret_key *
-copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
-{
- int n, i;
-
- if( !d )
- d = xmalloc_secure(sizeof *d);
- else
- release_secret_key_parts (d);
- memcpy( d, s, sizeof *d );
- n = pubkey_get_nskey( s->pubkey_algo );
- if( !n )
- d->skey[0] = mpi_copy(s->skey[0]);
- else {
- for(i=0; i < n; i++ )
- d->skey[i] = mpi_copy( s->skey[i] );
- }
-
- return d;
-}
-
-void
free_comment( PKT_comment *rem )
{
xfree(rem);
@@ -407,11 +369,9 @@ free_packet( PACKET *pkt )
break;
case PKT_PUBLIC_KEY:
case PKT_PUBLIC_SUBKEY:
- free_public_key( pkt->pkt.public_key );
- break;
case PKT_SECRET_KEY:
case PKT_SECRET_SUBKEY:
- free_secret_key( pkt->pkt.secret_key );
+ free_public_key (pkt->pkt.public_key);
break;
case PKT_COMMENT:
free_comment( pkt->pkt.comment );
@@ -462,59 +422,6 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
return 0;
}
-/****************
- * Returns 0 if they match.
- * We only compare the public parts.
- */
-int
-cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
-{
- int n, i;
-
- log_debug ("FIXME: %s Should not be used\n", __func__);
- if( a->timestamp != b->timestamp )
- return -1;
- if( a->version < 4 && a->expiredate != b->expiredate )
- return -1;
- if( a->pubkey_algo != b->pubkey_algo )
- return -1;
-
- n = pubkey_get_npkey( b->pubkey_algo );
- if( !n )
- return -1; /* can't compare due to unknown algorithm */
- for(i=0; i < n; i++ ) {
- if( mpi_cmp( a->skey[i], b->skey[i] ) )
- return -1;
- }
-
- return 0;
-}
-
-/****************
- * Returns 0 if they match.
- */
-int
-cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
- int n, i;
-
- if( pk->timestamp != sk->timestamp )
- return -1;
- if( pk->version < 4 && pk->expiredate != sk->expiredate )
- return -1;
- if( pk->pubkey_algo != sk->pubkey_algo )
- return -1;
-
- n = pubkey_get_npkey( pk->pubkey_algo );
- if( !n )
- return -1; /* can't compare due to unknown algorithm */
- for(i=0; i < n; i++ ) {
- if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
- return -1;
- }
- return 0;
-}
-
int
diff --git a/g10/getkey.c b/g10/getkey.c
index 4929974a3..401e66879 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -2522,7 +2522,7 @@ found:
* so that can free it's context.
*/
int
-enum_secret_keys (void **context, PKT_secret_key * sk,
+enum_secret_keys (void **context, PKT_public_key * sk,
int with_subkeys, int with_spm)
{
log_debug ("FIXME: Anonymous recipient does not yet work\n");
diff --git a/g10/import.c b/g10/import.c
index b1834655b..e3e7824a2 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -567,19 +567,16 @@ fix_bad_direct_key_sigs (kbnode_t keyblock, u32 *keyid)
static void
-print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason)
+print_import_ok (PKT_public_key *pk, unsigned int reason)
{
byte array[MAX_FINGERPRINT_LEN], *s;
char buf[MAX_FINGERPRINT_LEN*2+30], *p;
size_t i, n;
- sprintf (buf, "%u ", reason);
+ snprintf (buf, sizeof buf, "%u ", reason);
p = buf + strlen (buf);
- if (pk)
- fingerprint_from_pk (pk, array, &n);
- else
- fingerprint_from_sk (sk, array, &n);
+ fingerprint_from_pk (pk, array, &n);
s = array;
for (i=0; i < n ; i++, s++, p += 2)
sprintf (p, "%02X", *s);
@@ -886,7 +883,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
char *us = get_long_user_id_string( keyid );
write_status_text( STATUS_IMPORTED, us );
xfree(us);
- print_import_ok (pk,NULL, 1);
+ print_import_ok (pk, 1);
}
stats->imported++;
if( is_RSA( pk->pubkey_algo ) )
@@ -1007,14 +1004,13 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
stats->n_uids_cleaned +=n_uids_cleaned;
if (is_status_enabled ())
- print_import_ok (pk, NULL,
- ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
+ print_import_ok (pk, ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
}
else
{
same_key = 1;
if (is_status_enabled ())
- print_import_ok (pk, NULL, 0);
+ print_import_ok (pk, 0);
if( !opt.quiet )
{
@@ -1092,7 +1088,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
size_t keklen;
kbnode_t ctx = NULL;
kbnode_t node;
- PKT_secret_key *main_sk, *sk;
+ PKT_public_key *main_pk, *pk;
+ struct seckey_info *ski;
int nskey;
membuf_t mbuf;
int i, j;
@@ -1126,21 +1123,25 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
xfree (kek);
kek = NULL;
- main_sk = NULL;
+ main_pk = NULL;
while ((node = walk_kbnode (sec_keyblock, &ctx, 0)))
{
if (node->pkt->pkttype != PKT_SECRET_KEY
&& node->pkt->pkttype != PKT_SECRET_SUBKEY)
continue;
- sk = node->pkt->pkt.secret_key;
- if (!main_sk)
- main_sk = sk;
+ pk = node->pkt->pkt.public_key;
+ if (!main_pk)
+ main_pk = pk;
+
+ ski = pk->seckey_info;
+ if (!ski)
+ BUG ();
stats->count++;
stats->secret_read++;
/* Convert our internal secret key object into an S-expression. */
- nskey = pubkey_get_nskey (sk->pubkey_algo);
+ nskey = pubkey_get_nskey (pk->pubkey_algo);
if (!nskey || nskey > PUBKEY_MAX_NSKEY)
{
err = gpg_error (GPG_ERR_BAD_SECKEY);
@@ -1152,10 +1153,10 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
put_membuf_str (&mbuf, "(skey");
for (i=j=0; i < nskey; i++)
{
- if (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE))
+ if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
{
put_membuf_str (&mbuf, " e %b");
- format_args_buf_ptr[i] = gcry_mpi_get_opaque (sk->skey[i], &n);
+ format_args_buf_ptr[i] = gcry_mpi_get_opaque (pk->pkey[i], &n);
format_args_buf_int[i] = (n+7)/8;
format_args[j++] = format_args_buf_int + i;
format_args[j++] = format_args_buf_ptr + i;
@@ -1163,7 +1164,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
else
{
put_membuf_str (&mbuf, " _ %m");
- format_args[j++] = sk->skey + i;
+ format_args[j++] = pk->pkey + i;
}
}
put_membuf_str (&mbuf, ")\n");
@@ -1182,21 +1183,21 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
goto leave;
}
- if (sk->is_protected)
+ if (ski->is_protected)
{
char countbuf[35];
snprintf (countbuf, sizeof countbuf, "%lu",
- (unsigned long)sk->protect.s2k.count);
+ (unsigned long)ski->s2k.count);
err = gcry_sexp_build
(&prot, NULL,
" (protection %s %s %b %d %s %b %s)\n",
- sk->protect.sha1chk? "sha1":"sum",
- openpgp_cipher_algo_name (sk->protect.algo),
- (int)sk->protect.ivlen, sk->protect.iv,
- sk->protect.s2k.mode,
- openpgp_md_algo_name (sk->protect.s2k.hash_algo),
- (int)sizeof (sk->protect.s2k.salt), sk->protect.s2k.salt,
+ ski->sha1chk? "sha1":"sum",
+ openpgp_cipher_algo_name (ski->algo),
+ (int)ski->ivlen, ski->iv,
+ ski->s2k.mode,
+ openpgp_md_algo_name (ski->s2k.hash_algo),
+ (int)sizeof (ski->s2k.salt), ski->s2k.salt,
countbuf);
}
else
@@ -1213,9 +1214,9 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
" %S\n"
" (csum %d)\n"
" %S)\n",
- sk->version,
- openpgp_pk_algo_name (sk->pubkey_algo),
- skey, (int)(unsigned long)sk->csum, prot);
+ pk->version,
+ openpgp_pk_algo_name (pk->pubkey_algo),
+ skey, (int)(unsigned long)ski->csum, prot);
gcry_sexp_release (skey);
gcry_sexp_release (prot);
if (!err)
@@ -1243,37 +1244,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
/* Send the wrapped key to the agent. */
{
- char *uid, *desc;
- size_t uidlen;
- u32 keyid[2];
- char *orig_codeset;
-
- /* FIXME: We should use gpg_format_keydesc, however that
- requires a public key structure. It might be useful to
- merge the secret and public key structures. */
- keyid_from_sk (sk, keyid);
- uid = get_user_id (keyid, &uidlen);
- orig_codeset = i18n_switchto_utf8 ();
- desc = xtryasprintf (_("Please enter the passphrase to import the"
- " secret key for the OpenPGP certificate:\n"
- "\"%.*s\"\n" \
- "%u-bit %s key, ID %s,\n"
- "created %s.\n"),
- (int)uidlen, uid,
- nbits_from_sk (sk),
- openpgp_pk_algo_name (sk->pubkey_algo),
- (main_sk == sk
- ? keystr_from_sk (sk)
- : keystr_from_sk_with_sub (main_sk, sk)),
- strtimestamp (sk->timestamp));
- i18n_switchback (orig_codeset);
- xfree (uid);
- if (desc)
- {
- uid = percent_plus_escape (desc);
- xfree (desc);
- desc = uid;
- }
+ char *desc = gpg_format_keydesc (pk, 1, 1);
err = agent_import_key (ctrl, desc, &cache_nonce,
wrappedkey, wrappedkeylen);
xfree (desc);
@@ -1282,23 +1253,23 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
{
if (opt.verbose)
log_info (_("key %s: secret key imported\n"),
- keystr_from_sk_with_sub (main_sk, sk));
+ keystr_from_pk_with_sub (main_pk, pk));
stats->secret_imported++;
}
else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
{
if (opt.verbose)
log_info (_("key %s: secret key already exists\n"),
- keystr_from_sk_with_sub (main_sk, sk));
+ keystr_from_pk_with_sub (main_pk, pk));
err = 0;
stats->secret_dups++;
}
else
{
log_error (_("key %s: error sending to agent: %s\n"),
- keystr_from_sk_with_sub (main_sk, sk),
+ keystr_from_pk_with_sub (main_pk, pk),
gpg_strerror (err));
- if (sk->protect.algo == GCRY_CIPHER_IDEA
+ if (ski->algo == GCRY_CIPHER_IDEA
&& gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
{
write_status (STATUS_RSA_OR_IDEA);
@@ -1333,40 +1304,24 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock)
if (secnode->pkt->pkttype == PKT_SECRET_KEY
|| secnode->pkt->pkttype == PKT_SECRET_SUBKEY)
{
- /* Make a public key. We only need to convert enough to
- write the keyblock out. */
+ /* Make a public key. */
PACKET *pkt;
- PKT_secret_key *sk;
- PKT_public_key *pk;
- int n, i;
-
- pkt = xcalloc (1, sizeof *pkt);
- sk = secnode->pkt->pkt.secret_key;
- pk = xcalloc (1, sizeof *pk);
+ PKT_public_key *pk;
+ pkt = xtrycalloc (1, sizeof *pkt);
+ pk = pkt? copy_public_key (NULL, secnode->pkt->pkt.public_key): NULL;
+ if (!pk)
+ {
+ xfree (pkt);
+ release_kbnode (pub_keyblock);
+ return NULL;
+ }
if (secnode->pkt->pkttype == PKT_SECRET_KEY)
pkt->pkttype = PKT_PUBLIC_KEY;
else
pkt->pkttype = PKT_PUBLIC_SUBKEY;
-
pkt->pkt.public_key = pk;
- pk->version = sk->version;
- pk->timestamp = sk->timestamp;
- pk->expiredate = sk->expiredate;
- pk->pubkey_algo = sk->pubkey_algo;
-
- n = pubkey_get_npkey (pk->pubkey_algo);
- if (!n)
- {
- /* We can't properly extract the pubkey without knowing
- the number of MPIs */
- release_kbnode (pub_keyblock);
- return NULL;
- }
-
- for (i=0; i < n; i++)
- pk->pkey[i] = mpi_copy (sk->skey[i]);
pubnode = new_kbnode (pkt);
}
else
@@ -1393,10 +1348,10 @@ static int
import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
struct stats_s *stats, unsigned int options)
{
- PKT_secret_key *sk;
+ PKT_public_key *pk;
+ struct seckey_info *ski;
KBNODE node, uidnode;
u32 keyid[2];
- int have_seckey;
int rc = 0;
/* Get the key and print some info about it */
@@ -1404,16 +1359,17 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
if (!node)
BUG ();
- sk = node->pkt->pkt.secret_key;
- keyid_from_sk (sk, keyid);
+ pk = node->pkt->pkt.public_key;
+
+ keyid_from_pk (pk, keyid);
uidnode = find_next_kbnode (keyblock, PKT_USER_ID);
if (opt.verbose)
{
log_info ("sec %4u%c/%s %s ",
- nbits_from_sk (sk),
- pubkey_letter (sk->pubkey_algo),
- keystr_from_sk (sk), datestr_from_sk (sk));
+ nbits_from_pk (pk),
+ pubkey_letter (pk->pubkey_algo),
+ keystr_from_pk (pk), datestr_from_pk (pk));
if (uidnode)
print_utf8_buffer (log_get_stream (), uidnode->pkt->pkt.user_id->name,
uidnode->pkt->pkt.user_id->len);
@@ -1423,16 +1379,24 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
if (!uidnode)
{
- log_error( _("key %s: no user ID\n"), keystr_from_sk(sk));
+ log_error( _("key %s: no user ID\n"), keystr_from_pk (pk));
return 0;
}
-
+
+ ski = pk->seckey_info;
+ if (!ski)
+ {
+ /* Actually an internal error. */
+ log_error ("key %s: secret key info missing\n", keystr_from_pk (pk));
+ return 0;
+ }
+
/* A quick check to not import keys with an invalid protection
cipher algorithm (only checks the primary key, though). */
- if (sk->protect.algo > 110)
+ if (ski->algo > 110)
{
log_error (_("key %s: secret key with invalid cipher %d"
- " - skipped\n"),keystr_from_sk(sk),sk->protect.algo);
+ " - skipped\n"), keystr_from_pk (pk), ski->algo);
return 0;
}
@@ -1447,9 +1411,9 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
}
#endif
- clear_kbnode_flags( keyblock );
+ clear_kbnode_flags (keyblock);
- if ( !(opt.import_options&IMPORT_MERGE_ONLY) )
+ if (!(options&IMPORT_MERGE_ONLY) || !have_secret_key_with_kid (keyid) )
{
/* We don't have this key, insert as a new key. */
kbnode_t pub_keyblock;
@@ -1458,7 +1422,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
pub_keyblock = sec_to_pub_keyblock (keyblock);
if (!pub_keyblock)
log_error ("key %s: failed to create public key from secret key\n",
- keystr_from_sk (sk));
+ keystr_from_pk (pk));
else
{
import_one (fname, pub_keyblock, stats,
@@ -1474,29 +1438,29 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
node = get_pubkeyblock (keyid);
if (!node)
log_error ("key %s: failed to re-lookup public key\n",
- keystr_from_sk (sk));
+ keystr_from_pk (pk));
else
{
if (!transfer_secret_keys (ctrl, stats, keyblock))
{
if (!opt.quiet)
log_info (_("key %s: secret key imported\n"),
- keystr_from_sk (sk));
+ keystr_from_pk (pk));
if (is_status_enabled ())
- print_import_ok (NULL, sk, 1|16);
+ print_import_ok (pk, 1|16);
check_prefs (node);
}
release_kbnode (node);
}
}
}
- else if (have_secret_key_with_kid (keyid))
+ else
{
/* We don't want to merge the secret keys. */
- log_error( _("key %s: secret key part already available\n"),
- keystr_from_sk(sk));
+ log_error (_("key %s: secret key part already available\n"),
+ keystr_from_pk (pk));
if (is_status_enabled ())
- print_import_ok (NULL, sk, 16);
+ print_import_ok (pk, 16);
}
return rc;
@@ -2072,12 +2036,12 @@ collapse_uids( KBNODE *keyblock )
{
const char *key="???";
- if( (uid1=find_kbnode( *keyblock, PKT_PUBLIC_KEY )) )
- key=keystr_from_pk(uid1->pkt->pkt.public_key);
- else if( (uid1 = find_kbnode( *keyblock, PKT_SECRET_KEY )) )
- key=keystr_from_sk(uid1->pkt->pkt.secret_key);
+ if ((uid1 = find_kbnode (*keyblock, PKT_PUBLIC_KEY)) )
+ key = keystr_from_pk (uid1->pkt->pkt.public_key);
+ else if ((uid1 = find_kbnode( *keyblock, PKT_SECRET_KEY)) )
+ key = keystr_from_pk (uid1->pkt->pkt.public_key);
- log_info(_("key %s: duplicated user ID detected - merged\n"),key);
+ log_info (_("key %s: duplicated user ID detected - merged\n"), key);
}
return any;
@@ -2308,8 +2272,8 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
/* do we have this in the original keyblock? */
for(onode=keyblock_orig->next; onode; onode=onode->next )
if( onode->pkt->pkttype == PKT_SECRET_SUBKEY
- && !cmp_secret_keys( onode->pkt->pkt.secret_key,
- node->pkt->pkt.secret_key ) )
+ && !cmp_public_keys (onode->pkt->pkt.public_key,
+ node->pkt->pkt.public_key) )
break;
if( !onode ) { /* this is a new subkey: append */
rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
@@ -2327,14 +2291,11 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
|| onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
/* find the subkey in the imported keyblock */
for(node=keyblock->next; node; node=node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY)
&& !cmp_public_keys( onode->pkt->pkt.public_key,
node->pkt->pkt.public_key ) )
break;
- else if( node->pkt->pkttype == PKT_SECRET_SUBKEY
- && !cmp_secret_keys( onode->pkt->pkt.secret_key,
- node->pkt->pkt.secret_key ) )
- break;
}
if( node ) { /* found: merge */
rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
@@ -2497,8 +2458,9 @@ merge_keysigs (KBNODE dst, KBNODE src, int *n_sigs,
return 0;
}
-/****************
- * append the subkey starting with NODE and all signatures to KEYBLOCK.
+
+/*
+ * Append the subkey starting with NODE and all signatures to KEYBLOCK.
* Mark all new and copied packets by setting flag bit 0.
*/
static int
@@ -2530,233 +2492,3 @@ append_key (KBNODE keyblock, KBNODE node, int *n_sigs,
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 = xmalloc_clear (sizeof *pkt);
- PKT_secret_key *sk = xmalloc_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;
-
- log_debug ("FIXME: Do we need the stub at all?\n");
- hd = keydb_new (); /* FIXME. */
-
- /* 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);
- if (an < MAX_FINGERPRINT_LEN)
- memset (afp+an, 0, MAX_FINGERPRINT_LEN-an);
- 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;
-}
diff --git a/g10/keydb.h b/g10/keydb.h
index ca6b901c2..63f42a572 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -195,7 +195,7 @@ void set_next_passphrase( const char *s );
char *get_last_passphrase(void);
void next_to_last_passphrase(void);
-char *gpg_format_keydesc (PKT_public_key *pk, int escaped);
+char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped);
/*-- getkey.c --*/
@@ -241,8 +241,8 @@ void getkey_end (getkey_ctx_t ctx);
int have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
-int enum_secret_keys( void **context, PKT_secret_key *sk,
- int with_subkeys, int with_spm );
+//int enum_secret_keys( void **context, PKT_secret_key *sk,
+// int with_subkeys, int with_spm );
void merge_keys_and_selfsig( KBNODE keyblock );
char*get_user_id_string( u32 *keyid );
char*get_user_id_string_native( u32 *keyid );
@@ -263,34 +263,23 @@ const char *keystr_with_sub (u32 *main_kid, u32 *sub_kid);
const char *keystr_from_pk(PKT_public_key *pk);
const char *keystr_from_pk_with_sub (PKT_public_key *main_pk,
PKT_public_key *sub_pk);
-const char *keystr_from_sk(PKT_secret_key *sk);
-const char *keystr_from_sk_with_sub (PKT_secret_key *main_sk,
- PKT_secret_key *sub_sk);
const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc);
-u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
u32 keyid_from_fingerprint(const byte *fprint, size_t fprint_len, u32 *keyid);
byte *namehash_from_uid(PKT_user_id *uid);
unsigned nbits_from_pk( PKT_public_key *pk );
-unsigned nbits_from_sk( PKT_secret_key *sk );
const char *datestr_from_pk( PKT_public_key *pk );
-const char *datestr_from_sk( PKT_secret_key *sk );
const char *datestr_from_sig( PKT_signature *sig );
const char *expirestr_from_pk( PKT_public_key *pk );
-const char *expirestr_from_sk( PKT_secret_key *sk );
const char *expirestr_from_sig( PKT_signature *sig );
const char *revokestr_from_pk( PKT_public_key *pk );
const char *usagestr_from_pk( PKT_public_key *pk );
const char *colon_strtime (u32 t);
const char *colon_datestr_from_pk (PKT_public_key *pk);
-const char *colon_datestr_from_sk (PKT_secret_key *sk);
const char *colon_datestr_from_sig (PKT_signature *sig);
const char *colon_expirestr_from_sig (PKT_signature *sig);
-byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
-char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
- PKT_secret_key *sk);
gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array);
gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip);
diff --git a/g10/keyedit.c b/g10/keyedit.c
index a0864577a..86dacfff5 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -2924,7 +2924,9 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
keyid_from_pk (pk, NULL);
tty_printf ("%s%c %4u%c/%s ",
- node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" : "sub",
+ node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+ node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+ node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
(node->flag & NODFLG_SELKEY) ? '*' : ' ',
nbits_from_pk (pk),
pubkey_letter (pk->pubkey_algo), keystr (pk->keyid));
@@ -2941,7 +2943,35 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
tty_printf (_("usage: %s"), usagestr_from_pk (pk));
tty_printf ("\n");
- if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+ if (pk->seckey_info
+ && pk->seckey_info->is_protected
+ && pk->seckey_info->s2k.mode == 1002)
+ {
+ tty_printf (" ");
+ tty_printf (_("card-no: "));
+ if (pk->seckey_info->ivlen == 16
+ && !memcmp (pk->seckey_info->iv,
+ "\xD2\x76\x00\x01\x24\x01", 6))
+ {
+ /* This is an OpenPGP card. */
+ for (i = 8; i < 14; i++)
+ {
+ if (i == 10)
+ tty_printf (" ");
+ tty_printf ("%02X", pk->seckey_info->iv[i]);
+ }
+ }
+ else
+ {
+ /* Unknown card: Print all. */
+ for (i = 0; i < pk->seckey_info->ivlen; i++)
+ tty_printf ("%02X", pk->seckey_info->iv[i]);
+ }
+ tty_printf ("\n");
+ }
+
+ if (node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_SECRET_KEY)
{
if (opt.trust_model != TM_ALWAYS)
{
@@ -2970,47 +3000,13 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
}
}
- if (node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr)
+ if ((node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_SECRET_KEY) && with_fpr)
{
print_fingerprint (pk, 2);
tty_printf ("\n");
}
}
- else if (node->pkt->pkttype == PKT_SECRET_KEY
- || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY))
- {
- PKT_secret_key *sk = node->pkt->pkt.secret_key;
- tty_printf ("%s%c %4u%c/%s ",
- node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
- (node->flag & NODFLG_SELKEY) ? '*' : ' ',
- nbits_from_sk (sk),
- pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk));
- tty_printf (_("created: %s"), datestr_from_sk (sk));
- tty_printf (" ");
- tty_printf (_("expires: %s"), expirestr_from_sk (sk));
- tty_printf ("\n");
- if (sk->is_protected && sk->protect.s2k.mode == 1002)
- {
- tty_printf (" ");
- tty_printf (_("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_printf (" ");
- tty_printf ("%02X", sk->protect.iv[i]);
- }
- }
- else
- { /* Something is wrong: Print all. */
- for (i = 0; i < sk->protect.ivlen; i++)
- tty_printf ("%02X", sk->protect.iv[i]);
- }
- tty_printf ("\n");
- }
- }
}
show_names (keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
@@ -3035,14 +3031,17 @@ show_basic_key_info (KBNODE keyblock)
/* The primary key */
for (node = keyblock; node; node = node->next)
{
- if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+ if (node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_SECRET_KEY)
{
PKT_public_key *pk = node->pkt->pkt.public_key;
/* Note, we use the same format string as in other show
functions to make the translation job easier. */
tty_printf ("%s %4u%c/%s ",
- node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" : "sub",
+ node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+ node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+ node->pkt->pkttype == PKT_SECRET_KEY ? "sec" :"ssb",
nbits_from_pk (pk),
pubkey_letter (pk->pubkey_algo), keystr_from_pk (pk));
tty_printf (_("created: %s"), datestr_from_pk (pk));
@@ -3052,21 +3051,6 @@ show_basic_key_info (KBNODE keyblock)
print_fingerprint (pk, 3);
tty_printf ("\n");
}
- else if (node->pkt->pkttype == PKT_SECRET_KEY)
- {
- PKT_secret_key *sk = node->pkt->pkt.secret_key;
- tty_printf ("%s %4u%c/%s",
- node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
- nbits_from_sk (sk),
- pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk));
- tty_printf (_("created: %s"), datestr_from_sk (sk));
- tty_printf (" ");
- tty_printf (_("expires: %s"), expirestr_from_sk (sk));
- tty_printf ("\n");
- log_debug ("FIXME\n");
- /* print_fingerprint (NULL, sk, 3); */
- tty_printf ("\n");
- }
}
/* The user IDs. */
diff --git a/g10/keyid.c b/g10/keyid.c
index a6e8b3728..1d0972649 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -38,24 +38,27 @@
#define KEYID_STR_SIZE 19
+/* Return a letter describing the public key algorithms. */
int
pubkey_letter( int algo )
{
- switch( algo ) {
- case PUBKEY_ALGO_RSA: return 'R' ;
- case PUBKEY_ALGO_RSA_E: return 'r' ;
- case PUBKEY_ALGO_RSA_S: return 's' ;
- case PUBKEY_ALGO_ELGAMAL_E: return 'g';
- case PUBKEY_ALGO_ELGAMAL: return 'G' ;
- case PUBKEY_ALGO_DSA: return 'D' ;
- default: return '?';
+ switch (algo)
+ {
+ case PUBKEY_ALGO_RSA: return 'R' ;
+ case PUBKEY_ALGO_RSA_E: return 'r' ;
+ case PUBKEY_ALGO_RSA_S: return 's' ;
+ case PUBKEY_ALGO_ELGAMAL_E: return 'g';
+ case PUBKEY_ALGO_ELGAMAL: return 'G' ;
+ case PUBKEY_ALGO_DSA: return 'D' ;
+ default: return '?';
}
}
-/* This function is useful for v4 fingerprints and v3 or v4 key
- signing. */
+
+/* Hash a public key. This function is useful for v4 fingerprints and
+ for v3 or v4 key signing. */
void
-hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
+hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
{
unsigned int n = 6;
unsigned int nn[PUBKEY_MAX_NPKEY];
@@ -77,17 +80,19 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
n+=nn[0];
}
else
- for(i=0; i < npkey; i++ )
- {
- if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i]))
- BUG ();
- pp[i] = xmalloc (nbytes);
- if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
- &nbytes, pk->pkey[i]))
- BUG ();
- nn[i] = nbytes;
- n += nn[i];
- }
+ {
+ for(i=0; i < npkey; i++ )
+ {
+ if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i]))
+ BUG ();
+ pp[i] = xmalloc (nbytes);
+ if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
+ &nbytes, pk->pkey[i]))
+ BUG ();
+ nn[i] = nbytes;
+ n += nn[i];
+ }
+ }
gcry_md_putc ( md, 0x99 ); /* ctb */
/* What does it mean if n is greater than than 0xFFFF ? */
@@ -125,6 +130,7 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
}
}
+
static gcry_md_hd_t
do_fingerprint_md( PKT_public_key *pk )
{
@@ -138,27 +144,9 @@ do_fingerprint_md( PKT_public_key *pk )
return md;
}
-static gcry_md_hd_t
-do_fingerprint_md_sk( PKT_secret_key *sk )
-{
- PKT_public_key pk;
- int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */
- int i;
-
- if(npkey==0)
- return NULL;
-
- pk.pubkey_algo = sk->pubkey_algo;
- pk.version = sk->version;
- pk.timestamp = sk->timestamp;
- pk.expiredate = sk->expiredate;
- pk.pubkey_algo = sk->pubkey_algo;
- for( i=0; i < npkey; i++ )
- pk.pkey[i] = sk->skey[i];
- return do_fingerprint_md( &pk );
-}
-
+/* fixme: Check whether we can replace this function or if not
+ describe why we need it. */
u32
v3_keyid (gcry_mpi_t a, u32 *ki)
{
@@ -280,24 +268,6 @@ keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
}
-const char *
-keystr_from_sk(PKT_secret_key *sk)
-{
- keyid_from_sk (sk,NULL);
-
- return keystr(sk->keyid);
-}
-
-
-const char *
-keystr_from_sk_with_sub (PKT_secret_key *main_sk, PKT_secret_key *sub_sk)
-{
- keyid_from_sk (main_sk, NULL);
- keyid_from_sk (sub_sk, NULL);
-
- return keystr_with_sub (main_sk->keyid, sub_sk->keyid);
-}
-
const char *
keystr_from_desc(KEYDB_SEARCH_DESC *desc)
@@ -332,72 +302,18 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc)
}
}
-/****************
- * Get the keyid from the secret key and put it into keyid
- * if this is not NULL. Return the 32 low bits of the keyid.
- */
-u32
-keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
-{
- u32 lowbits;
- u32 dummy_keyid[2];
- if( !keyid )
- keyid = dummy_keyid;
-
- if( sk->keyid[0] || sk->keyid[1] )
- {
- keyid[0] = sk->keyid[0];
- keyid[1] = sk->keyid[1];
- lowbits = keyid[1];
- }
- else if( sk->version < 4 )
- {
- if( is_RSA(sk->pubkey_algo) )
- {
- lowbits = (pubkey_get_npkey (sk->pubkey_algo) ?
- v3_keyid( sk->skey[0], keyid ) : 0); /* Take n. */
- sk->keyid[0]=keyid[0];
- sk->keyid[1]=keyid[1];
- }
- else
- sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
- }
- else
- {
- const byte *dp;
- gcry_md_hd_t md;
-
- md = do_fingerprint_md_sk(sk);
- if(md)
- {
- dp = gcry_md_read (md, 0);
- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
- lowbits = keyid[1];
- gcry_md_close (md);
- sk->keyid[0] = keyid[0];
- sk->keyid[1] = keyid[1];
- }
- else
- sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
- }
-
- return lowbits;
-}
-
-
-/****************
+/*
* Get the keyid from the public key and put it into keyid
* if this is not NULL. Return the 32 low bits of the keyid.
*/
u32
-keyid_from_pk( PKT_public_key *pk, u32 *keyid )
+keyid_from_pk (PKT_public_key *pk, u32 *keyid)
{
u32 lowbits;
u32 dummy_keyid[2];
- if( !keyid )
+ if (!keyid)
keyid = dummy_keyid;
if( pk->keyid[0] || pk->keyid[1] )
@@ -442,61 +358,66 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid )
}
-/****************
+/*
* Get the keyid from the fingerprint. This function is simple for most
* keys, but has to do a keylookup for old stayle keys.
*/
u32
keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
{
- u32 dummy_keyid[2];
-
- if( !keyid )
- keyid = dummy_keyid;
-
- if( fprint_len != 20 ) {
- /* This is special as we have to lookup the key first */
- PKT_public_key pk;
- int rc;
-
- memset( &pk, 0, sizeof pk );
- rc = get_pubkey_byfprint( &pk, fprint, fprint_len );
- if( rc ) {
- log_error("Oops: keyid_from_fingerprint: no pubkey\n");
- keyid[0] = 0;
- keyid[1] = 0;
- }
- else
- keyid_from_pk( &pk, keyid );
+ u32 dummy_keyid[2];
+
+ if( !keyid )
+ keyid = dummy_keyid;
+
+ if (fprint_len != 20)
+ {
+ /* This is special as we have to lookup the key first. */
+ PKT_public_key pk;
+ int rc;
+
+ memset (&pk, 0, sizeof pk);
+ rc = get_pubkey_byfprint (&pk, fprint, fprint_len);
+ if( rc )
+ {
+ log_error("Oops: keyid_from_fingerprint: no pubkey\n");
+ keyid[0] = 0;
+ keyid[1] = 0;
+ }
+ else
+ keyid_from_pk (&pk, keyid);
}
- else {
- const byte *dp = fprint;
- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
+ else
+ {
+ const byte *dp = fprint;
+ keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+ keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
}
- return keyid[1];
+ return keyid[1];
}
u32
-keyid_from_sig( PKT_signature *sig, u32 *keyid )
+keyid_from_sig (PKT_signature *sig, u32 *keyid)
{
- if( keyid ) {
- keyid[0] = sig->keyid[0];
- keyid[1] = sig->keyid[1];
+ if( keyid )
+ {
+ keyid[0] = sig->keyid[0];
+ keyid[1] = sig->keyid[1];
}
- return sig->keyid[1];
+ return sig->keyid[1];
}
+
byte *
-namehash_from_uid(PKT_user_id *uid)
+namehash_from_uid (PKT_user_id *uid)
{
if (!uid->namehash)
{
uid->namehash = xmalloc (20);
- if(uid->attrib_data)
+ if (uid->attrib_data)
rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
else
rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
@@ -505,117 +426,95 @@ namehash_from_uid(PKT_user_id *uid)
return uid->namehash;
}
-/****************
- * return the number of bits used in the pk
- */
-unsigned
-nbits_from_pk( PKT_public_key *pk )
-{
- return pubkey_nbits( pk->pubkey_algo, pk->pkey );
-}
-/****************
- * return the number of bits used in the sk
+/*
+ * Return the number of bits used in PK.
*/
-unsigned
-nbits_from_sk( PKT_secret_key *sk )
+unsigned int
+nbits_from_pk (PKT_public_key *pk)
{
- return pubkey_nbits( sk->pubkey_algo, sk->skey );
+ return pubkey_nbits (pk->pubkey_algo, pk->pkey);
}
+
static const char *
mk_datestr (char *buffer, time_t atime)
{
- struct tm *tp;
-
- if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
- strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
- else {
- tp = gmtime (&atime);
- sprintf (buffer,"%04d-%02d-%02d",
- 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
+ struct tm *tp;
+
+ if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
+ strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
+ else
+ {
+ tp = gmtime (&atime);
+ sprintf (buffer,"%04d-%02d-%02d",
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
}
- return buffer;
+ return buffer;
}
-/****************
+
+/*
* return a string with the creation date of the pk
* Note: this is alloced in a static buffer.
* Format is: yyyy-mm-dd
*/
const char *
-datestr_from_pk( PKT_public_key *pk )
+datestr_from_pk (PKT_public_key *pk)
{
- static char buffer[11+5];
- time_t atime = pk->timestamp;
-
- return mk_datestr (buffer, atime);
+ static char buffer[11+5];
+ time_t atime = pk->timestamp;
+
+ return mk_datestr (buffer, atime);
}
-const char *
-datestr_from_sk( PKT_secret_key *sk )
-{
- static char buffer[11+5];
- time_t atime = sk->timestamp;
-
- return mk_datestr (buffer, atime);
-}
const char *
-datestr_from_sig( PKT_signature *sig )
+datestr_from_sig (PKT_signature *sig )
{
- static char buffer[11+5];
- time_t atime = sig->timestamp;
+ static char buffer[11+5];
+ time_t atime = sig->timestamp;
- return mk_datestr (buffer, atime);
+ return mk_datestr (buffer, atime);
}
-const char *
-expirestr_from_pk( PKT_public_key *pk )
-{
- static char buffer[11+5];
- time_t atime;
-
- if( !pk->expiredate )
- return _("never ");
- atime = pk->expiredate;
- return mk_datestr (buffer, atime);
-}
const char *
-expirestr_from_sk( PKT_secret_key *sk )
+expirestr_from_pk (PKT_public_key *pk)
{
- static char buffer[11+5];
- time_t atime;
+ static char buffer[11+5];
+ time_t atime;
- if( !sk->expiredate )
- return _("never ");
- atime = sk->expiredate;
- return mk_datestr (buffer, atime);
+ if (!pk->expiredate)
+ return _("never ");
+ atime = pk->expiredate;
+ return mk_datestr (buffer, atime);
}
+
const char *
-expirestr_from_sig( PKT_signature *sig )
+expirestr_from_sig (PKT_signature *sig)
{
- static char buffer[11+5];
- time_t atime;
-
- if(!sig->expiredate)
- return _("never ");
- atime=sig->expiredate;
- return mk_datestr (buffer, atime);
+ static char buffer[11+5];
+ time_t atime;
+
+ if (!sig->expiredate)
+ return _("never ");
+ atime=sig->expiredate;
+ return mk_datestr (buffer, atime);
}
+
const char *
revokestr_from_pk( PKT_public_key *pk )
{
- static char buffer[11+5];
- time_t atime;
+ static char buffer[11+5];
+ time_t atime;
- if(!pk->revoked.date)
- return _("never ");
- atime=pk->revoked.date;
- return mk_datestr (buffer, atime);
+ if(!pk->revoked.date)
+ return _("never ");
+ atime=pk->revoked.date;
+ return mk_datestr (buffer, atime);
}
@@ -666,14 +565,6 @@ colon_datestr_from_pk (PKT_public_key *pk)
return buf;
}
-const char *
-colon_datestr_from_sk (PKT_secret_key *sk)
-{
- static char buf[20];
-
- snprintf (buf, sizeof buf, "%lu", (ulong)sk->timestamp);
- return buf;
-}
const char *
colon_datestr_from_sig (PKT_signature *sig)
@@ -697,14 +588,13 @@ colon_expirestr_from_sig (PKT_signature *sig)
}
-/**************** .
+/*
* Return a byte array with the fingerprint for the given PK/SK
* The length of the array is returned in ret_len. Caller must free
* the array or provide an array of length MAX_FINGERPRINT_LEN.
*/
-
byte *
-fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
+fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
{
byte *buf;
const byte *dp;
@@ -771,106 +661,8 @@ fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
return array;
}
-byte *
-fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
-{
- byte *buf;
- const char *dp;
- size_t len, nbytes;
- int i;
-
- if (sk->version < 4)
- {
- if ( is_RSA(sk->pubkey_algo) )
- {
- /* RSA in version 3 packets is special. */
- gcry_md_hd_t md;
-
- if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
- BUG ();
- if (pubkey_get_npkey( sk->pubkey_algo ) > 1)
- {
- for (i=0; i < 2; i++)
- {
- if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
- &nbytes, sk->skey[i]))
- BUG ();
- /* fixme: Better allocate BUF on the stack */
- buf = xmalloc (nbytes);
- if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes,
- NULL, sk->skey[i]))
- BUG ();
- gcry_md_write (md, buf, nbytes);
- xfree (buf);
- }
- }
- gcry_md_final(md);
- if (!array)
- array = xmalloc (16);
- len = 16;
- memcpy (array, gcry_md_read (md, DIGEST_ALGO_MD5), 16);
- gcry_md_close (md);
- }
- else
- {
- if (!array)
- array = xmalloc (16);
- len=16;
- memset (array,0,16);
- }
- }
- else
- {
- gcry_md_hd_t md;
-
- md = do_fingerprint_md_sk(sk);
- if (md)
- {
- dp = gcry_md_read ( md, 0 );
- len = gcry_md_get_algo_dlen ( gcry_md_get_algo (md) );
- assert ( len <= MAX_FINGERPRINT_LEN );
- if (!array)
- array = xmalloc( len );
- memcpy (array, dp, len);
- gcry_md_close (md);
- }
- else
- {
- len = MAX_FINGERPRINT_LEN;
- if (!array)
- array = xmalloc (len);
- memset (array, 0, len);
- }
- }
-
- *ret_len = len;
- return array;
-}
-/* Create a serialno/fpr string from the serial number and the secret
- key. Caller must free the returned string. There is no error
- return. */
-char *
-serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
- PKT_secret_key *sk)
-{
- unsigned char fpr[MAX_FINGERPRINT_LEN];
- size_t fprlen;
- char *buffer, *p;
- int i;
-
- fingerprint_from_sk (sk, fpr, &fprlen);
- buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1);
- for (i=0; i < snlen; i++, p+=2)
- sprintf (p, "%02X", sn[i]);
- *p++ = '/';
- for (i=0; i < fprlen; i++, p+=2)
- sprintf (p, "%02X", fpr[i]);
- *p = 0;
- return buffer;
-}
-
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
diff --git a/g10/keylist.c b/g10/keylist.c
index b99047b70..2d3574a6d 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -44,7 +44,7 @@
static void list_all (int);
static void list_one (strlist_t names, int secret);
static void locate_one (strlist_t names);
-static void print_card_serialno (PKT_secret_key * sk);
+static void print_card_serialno (PKT_public_key *sk);
struct sig_stats
{
@@ -174,52 +174,53 @@ print_pubkey_info (estream_t fp, PKT_public_key * pk)
/* Print basic information of a secret key including the card serial
number information. */
void
-print_card_key_info (estream_t fp, KBNODE keyblock)
+print_card_key_info (estream_t fp, kbnode_t 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");
- }
- }
+ /* KBNODE node; */
+ /* int i; */
+
+ log_debug ("Fixme: Needs to be adjusted to gpg-agent\n");
+ /* for (node = keyblock; node; node = node->next) */
+ /* { */
+ /* if (node->pkt->pkttype == PKT_SECRET_KEY */
+ /* || (node->pkt->pkttype == PKT_SECRET_SUBKEY)) */
+ /* { */
+ /* PKT_public_key *pk = node->pkt->pkt.public_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"); */
+ /* } */
+ /* } */
}
@@ -1524,37 +1525,38 @@ print_fingerprint (PKT_public_key *pk, int mode)
/* Print the serial number of an OpenPGP card if available. */
static void
-print_card_serialno (PKT_secret_key * sk)
+print_card_serialno (PKT_public_key *pk)
{
- int i;
-
- if (!sk)
- return;
- if (!sk->is_protected || sk->protect.s2k.mode != 1002)
- return; /* Not a card. */
- if (opt.with_colons)
- return; /* Handled elsewhere. */
-
- es_fputs (_(" Card serial no. ="), es_stdout);
- es_putc (' ', es_stdout);
- if (sk->protect.ivlen == 16
- && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
- {
- /* This is an OpenPGP card. Just print the relevant part. */
- for (i = 8; i < 14; i++)
- {
- if (i == 10)
- es_putc (' ', es_stdout);
- es_fprintf (es_stdout, "%02X", sk->protect.iv[i]);
- }
- }
- else
- {
- /* Something is wrong: Print all. */
- for (i = 0; i < sk->protect.ivlen; i++)
- es_fprintf (es_stdout, "%02X", sk->protect.iv[i]);
- }
- es_putc ('\n', es_stdout);
+ log_debug ("Fixme: Needs to be adjusted to gpg-agent\n");
+ /* int i; */
+
+ /* if (!sk) */
+ /* return; */
+ /* if (!sk->is_protected || sk->protect.s2k.mode != 1002) */
+ /* return; /\* Not a card. *\/ */
+ /* if (opt.with_colons) */
+ /* return; /\* Handled elsewhere. *\/ */
+
+ /* es_fputs (_(" Card serial no. ="), es_stdout); */
+ /* es_putc (' ', es_stdout); */
+ /* if (sk->protect.ivlen == 16 */
+ /* && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6)) */
+ /* { */
+ /* /\* This is an OpenPGP card. Just print the relevant part. *\/ */
+ /* for (i = 8; i < 14; i++) */
+ /* { */
+ /* if (i == 10) */
+ /* es_putc (' ', es_stdout); */
+ /* es_fprintf (es_stdout, "%02X", sk->protect.iv[i]); */
+ /* } */
+ /* } */
+ /* else */
+ /* { */
+ /* /\* Something is wrong: Print all. *\/ */
+ /* for (i = 0; i < sk->protect.ivlen; i++) */
+ /* es_fprintf (es_stdout, "%02X", sk->protect.iv[i]); */
+ /* } */
+ /* es_putc ('\n', es_stdout); */
}
diff --git a/g10/keyring.c b/g10/keyring.c
index 5277db989..d069b1397 100644
--- a/g10/keyring.c
+++ b/g10/keyring.c
@@ -899,7 +899,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
int use_offtbl;
PKT_user_id *uid = NULL;
PKT_public_key *pk = NULL;
- PKT_secret_key *sk = NULL;
u32 aki[2];
/* figure out what information we need */
@@ -1017,10 +1016,11 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
}
pk = NULL;
- sk = NULL;
uid = NULL;
if ( pkt.pkttype == PKT_PUBLIC_KEY
- || pkt.pkttype == PKT_PUBLIC_SUBKEY)
+ || pkt.pkttype == PKT_PUBLIC_SUBKEY
+ || pkt.pkttype == PKT_SECRET_KEY
+ || pkt.pkttype == PKT_SECRET_SUBKEY)
{
pk = pkt.pkt.public_key;
++pk_no;
@@ -1041,21 +1041,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
uid = pkt.pkt.user_id;
++uid_no;
}
- else if ( pkt.pkttype == PKT_SECRET_KEY
- || pkt.pkttype == PKT_SECRET_SUBKEY)
- {
- sk = pkt.pkt.secret_key;
- ++pk_no;
-
- if (need_fpr) {
- fingerprint_from_sk (sk, afp, &an);
- while (an < 20) /* fill up to 20 bytes */
- afp[an++] = 0;
- }
- if (need_keyid)
- keyid_from_sk (sk, aki);
-
- }
for (n=0; n < ndesc; n++)
{
@@ -1076,29 +1061,29 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
break;
case KEYDB_SEARCH_MODE_SHORT_KID:
- if ((pk||sk) && desc[n].u.kid[1] == aki[1])
+ if (pk && desc[n].u.kid[1] == aki[1])
goto found;
break;
case KEYDB_SEARCH_MODE_LONG_KID:
- if ((pk||sk) && desc[n].u.kid[0] == aki[0]
+ if (pk && desc[n].u.kid[0] == aki[0]
&& desc[n].u.kid[1] == aki[1])
goto found;
break;
case KEYDB_SEARCH_MODE_FPR16:
- if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16))
+ if (pk && !memcmp (desc[n].u.fpr, afp, 16))
goto found;
break;
case KEYDB_SEARCH_MODE_FPR20:
case KEYDB_SEARCH_MODE_FPR:
- if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20))
+ if (pk && !memcmp (desc[n].u.fpr, afp, 20))
goto found;
break;
case KEYDB_SEARCH_MODE_FIRST:
- if (pk||sk)
+ if (pk)
goto found;
break;
case KEYDB_SEARCH_MODE_NEXT:
- if (pk||sk)
+ if (pk)
goto found;
break;
default:
@@ -1128,7 +1113,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
{
hd->found.offset = main_offset;
hd->found.kr = hd->current.kr;
- hd->found.pk_no = (pk||sk)? pk_no : 0;
+ hd->found.pk_no = pk? pk_no : 0;
hd->found.uid_no = uid? uid_no : 0;
}
else if (rc == -1)
diff --git a/g10/main.h b/g10/main.h
index e84d5d05f..ba8afbafa 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -277,10 +277,6 @@ void import_print_stats (void *hd);
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);
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 87e99126a..02ffae92e 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -58,7 +58,6 @@ struct mainproc_context
{
struct mainproc_context *anchor; /* May be useful in the future. */
PKT_public_key *last_pubkey;
- PKT_secret_key *last_seckey;
PKT_user_id *last_user_id;
md_filter_context_t mfx;
int sigs_only; /* Process only signatures and reject all other stuff. */
@@ -1118,15 +1117,13 @@ list_node( CTX c, KBNODE node )
u32 keyid[2];
if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
- || c->list->pkt->pkttype == PKT_SECRET_KEY ) {
- if( c->list->pkt->pkttype == PKT_PUBLIC_KEY )
- keyid_from_pk( c->list->pkt->pkt.public_key, keyid );
- else
- keyid_from_sk( c->list->pkt->pkt.secret_key, keyid );
-
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
- is_selfsig = 1;
- }
+ || c->list->pkt->pkttype == PKT_SECRET_KEY )
+ {
+ keyid_from_pk (c->list->pkt->pkt.public_key, keyid);
+
+ if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
+ is_selfsig = 1;
+ }
}
if( opt.with_colons ) {
putchar(':');
diff --git a/g10/packet.h b/g10/packet.h
index d124f4c1d..02674a039 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -53,11 +53,12 @@ typedef struct {
byte value;
} prefitem_t;
-typedef struct {
- int mode;
- byte hash_algo;
- byte salt[8];
- u32 count;
+typedef struct
+{
+ int mode; /* Must be an integer due to the GNU modes 1001 et al. */
+ byte hash_algo;
+ byte salt[8];
+ u32 count;
} STRING2KEY;
typedef struct {
@@ -204,11 +205,35 @@ struct revoke_info
byte algo;
};
+
+/* Information pertaining to secret keys. */
+struct seckey_info
+{
+ int is_protected:1; /* The secret info is protected and must */
+ /* be decrypted before use, the protected */
+ /* MPIs are simply (void*) pointers to memory */
+ /* and should never be passed to a mpi_xxx() */
+ int sha1chk:1; /* SHA1 is used instead of a 16 bit checksum */
+ u16 csum; /* Checksum for old protection modes. */
+ byte algo; /* Cipher used to protect the secret information. */
+ STRING2KEY s2k; /* S2K parameter. */
+ byte ivlen; /* Used length of the IV. */
+ byte iv[16]; /* Initialization vector for CFB mode. */
+};
+
+
/****************
- * Note about the pkey/skey elements: We assume that the secret keys
- * has the same elements as the public key at the begin of the array, so
- * that npkey < nskey and it is possible to compare the secret and
- * public keys by comparing the first npkey elements of pkey againts skey.
+ * We assume that secret keys have the same number of parameters as
+ * the public key and that the public parameters are the first items
+ * in the PKEY array. Thus NPKEY is always less than NSKEY and it is
+ * possible to compare the secret and public keys by comparing the
+ * first NPKEY elements of the PKEY array. Note that since GnuPG 2.1
+ * we don't use secret keys anymore directly because they are managed
+ * by gpg-agent. However for parsing OpenPGP key files we need a way
+ * to temporary store those secret keys. We do this by putting them
+ * into the public key structure and extending the PKEY field to NSKEY
+ * elements; the extra secret key information are stored in the
+ * SECKEY_INFO field.
*/
typedef struct {
u32 timestamp; /* key made */
@@ -243,44 +268,16 @@ typedef struct {
byte trust_depth;
byte trust_value;
const byte *trust_regexp;
- gcry_mpi_t pkey[PUBKEY_MAX_NPKEY];
+ struct seckey_info *seckey_info; /* If not NULL this malloced
+ structure describes a secret
+ key. */
+ gcry_mpi_t pkey[PUBKEY_MAX_NSKEY]; /* Right, NSKEY elements. */
} PKT_public_key;
/* Evaluates as true if the pk is disabled, and false if it isn't. If
there is no disable value cached, fill one in. */
#define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a))))
-typedef struct {
- u32 timestamp; /* key made */
- u32 expiredate; /* expires at this date or 0 if not at all */
- u32 max_expiredate; /* must not expire past this date */
- byte hdrbytes; /* number of header bytes */
- byte version;
- byte pubkey_algo; /* algorithm used for public key scheme */
- byte pubkey_usage;
- byte req_usage;
- byte req_algo;
- u32 has_expired; /* set to the expiration date if expired */
- int is_revoked; /* key has been revoked */
- int is_valid; /* key (especially subkey) is valid */
- u32 main_keyid[2]; /* keyid of the primary key */
- u32 keyid[2];
- byte is_primary;
- byte is_protected; /* The secret info is protected and must */
- /* be decrypted before use, the protected */
- /* MPIs are simply (void*) pointers to memory */
- /* and should never be passed to a mpi_xxx() */
- struct {
- byte algo; /* cipher used to protect the secret information*/
- byte sha1chk; /* SHA1 is used instead of a 16 bit checksum */
- STRING2KEY s2k;
- byte ivlen; /* used length of the iv */
- byte iv[16]; /* initialization vector for CFB mode */
- } protect;
- gcry_mpi_t skey[PUBKEY_MAX_NSKEY];
- u16 csum; /* checksum */
-} PKT_secret_key;
-
typedef struct {
int len; /* length of data */
@@ -339,7 +336,7 @@ struct packet_struct {
PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */
PKT_signature *signature; /* PKT_SIGNATURE */
PKT_public_key *public_key; /* PKT_PUBLIC_[SUB)KEY */
- PKT_secret_key *secret_key; /* PKT_SECRET_[SUB]KEY */
+ PKT_public_key *secret_key; /* PKT_SECRET_[SUB]KEY */
PKT_comment *comment; /* PKT_COMMENT */
PKT_user_id *user_id; /* PKT_USER_ID */
PKT_compressed *compressed; /* PKT_COMPRESSED */
@@ -452,22 +449,16 @@ void free_seckey_enc( PKT_signature *enc );
int digest_algo_from_sig( PKT_signature *sig );
void release_public_key_parts( PKT_public_key *pk );
void free_public_key( PKT_public_key *key );
-void release_secret_key_parts( PKT_secret_key *sk );
-void free_secret_key( PKT_secret_key *sk );
void free_attributes(PKT_user_id *uid);
void free_user_id( PKT_user_id *uid );
void free_comment( PKT_comment *rem );
void free_packet( PACKET *pkt );
prefitem_t *copy_prefs (const prefitem_t *prefs);
PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
-void copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
-PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
PKT_user_id *scopy_user_id (PKT_user_id *sd );
int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
-int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
int cmp_signatures( PKT_signature *a, PKT_signature *b );
-int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 2065c22ef..c83524016 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -565,12 +565,9 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos,
{
case PKT_PUBLIC_KEY:
case PKT_PUBLIC_SUBKEY:
- pkt->pkt.public_key = xmalloc_clear (sizeof *pkt->pkt.public_key);
- rc = parse_key (inp, pkttype, pktlen, hdr, hdrlen, pkt);
- break;
case PKT_SECRET_KEY:
case PKT_SECRET_SUBKEY:
- pkt->pkt.secret_key = xmalloc_clear (sizeof *pkt->pkt.secret_key);
+ pkt->pkt.public_key = xmalloc_clear (sizeof *pkt->pkt.public_key);
rc = parse_key (inp, pkttype, pktlen, hdr, hdrlen, pkt);
break;
case PKT_SYMKEY_ENC:
@@ -627,6 +624,7 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos,
}
leave:
+ /* FIXME: Do we leak in case of an error? */
if (!rc && iobuf_error (inp))
rc = G10ERR_INV_KEYRING;
return rc;
@@ -1815,6 +1813,7 @@ static int
parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
byte * hdr, int hdrlen, PACKET * pkt)
{
+ gpg_error_t err = 0;
int i, version, algorithm;
unsigned n;
unsigned long timestamp, expiredate, max_expiredate;
@@ -1822,9 +1821,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
int is_v4 = 0;
int rc = 0;
u32 keyid[2];
+ PKT_public_key *pk;
(void) hdr;
+ pk = pkt->pkt.public_key; /* PK has been cleared. */
+
version = iobuf_get_noeof (inp);
pktlen--;
if (pkttype == PKT_PUBLIC_SUBKEY && version == '#')
@@ -1853,14 +1855,14 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
else if (version != 2 && version != 3)
{
log_error ("packet(%d) with unknown version %d\n", pkttype, version);
- rc = gpg_error (GPG_ERR_INV_PACKET);
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
if (pktlen < 11)
{
log_error ("packet(%d) too short\n", pkttype);
- rc = gpg_error (GPG_ERR_INV_PACKET);
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
@@ -1894,38 +1896,14 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
pkttype == PKT_SECRET_SUBKEY ? "secret sub" : "??",
version, algorithm, timestamp, expiredate);
- if (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY)
- {
- PKT_secret_key *sk = pkt->pkt.secret_key;
+ pk->timestamp = timestamp;
+ pk->expiredate = expiredate;
+ pk->max_expiredate = max_expiredate;
+ pk->hdrbytes = hdrlen;
+ pk->version = version;
+ pk->is_primary = (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY);
+ pk->pubkey_algo = algorithm;
- sk->timestamp = timestamp;
- sk->expiredate = expiredate;
- sk->max_expiredate = max_expiredate;
- sk->hdrbytes = hdrlen;
- sk->version = version;
- sk->is_primary = pkttype == PKT_SECRET_KEY;
- sk->pubkey_algo = algorithm;
- sk->req_usage = 0;
- sk->pubkey_usage = 0; /* not yet used */
- }
- else
- {
- PKT_public_key *pk = pkt->pkt.public_key;
-
- pk->timestamp = timestamp;
- pk->expiredate = expiredate;
- pk->max_expiredate = max_expiredate;
- pk->hdrbytes = hdrlen;
- pk->version = version;
- pk->is_primary = pkttype == PKT_PUBLIC_KEY;
- pk->pubkey_algo = algorithm;
- pk->req_usage = 0;
- pk->pubkey_usage = 0; /* not yet used */
- pk->is_revoked = 0;
- pk->is_disabled = 0;
- pk->keyid[0] = 0;
- pk->keyid[1] = 0;
- }
nskey = pubkey_get_nskey (algorithm);
npkey = pubkey_get_npkey (algorithm);
if (!npkey)
@@ -1936,62 +1914,77 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
}
- if (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY)
+ if (!npkey)
{
- PKT_secret_key *sk = pkt->pkt.secret_key;
- byte temp[16];
- size_t snlen = 0;
-
- if (!npkey)
- {
- sk->skey[0] = gcry_mpi_set_opaque (NULL, read_rest (inp, pktlen, 0),
- pktlen * 8);
- pktlen = 0;
- goto leave;
- }
-
+ /* Unknown algorithm - put data into an opaque MPI. */
+ pk->pkey[0] = gcry_mpi_set_opaque (NULL,
+ read_rest (inp, pktlen, 0),
+ pktlen * 8);
+ pktlen = 0;
+ goto leave;
+ }
+ else
+ {
+ /* Fill in public key parameters. */
for (i = 0; i < npkey; i++)
{
n = pktlen;
- sk->skey[i] = mpi_read (inp, &n, 0);
+ pk->pkey[i] = mpi_read (inp, &n, 0);
pktlen -= n;
if (list_mode)
{
- es_fprintf (listfp, "\tskey[%d]: ", i);
- mpi_print (listfp, sk->skey[i], mpi_print_mode);
+ es_fprintf (listfp, "\tpkey[%d]: ", i);
+ mpi_print (listfp, pk->pkey[i], mpi_print_mode);
es_putc ('\n', listfp);
}
- if (!sk->skey[i])
- rc = G10ERR_INVALID_PACKET;
+ if (!pk->pkey[i])
+ err = gpg_error (GPG_ERR_INV_PACKET);
}
- if (rc) /* One of the MPIs were bad. */
+ if (err)
goto leave;
- sk->protect.algo = iobuf_get_noeof (inp);
+ }
+
+ if (list_mode)
+ keyid_from_pk (pk, keyid);
+
+ if (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY)
+ {
+ struct seckey_info *ski;
+ byte temp[16];
+ size_t snlen = 0;
+
+ pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
+ if (!pk->seckey_info)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ ski->algo = iobuf_get_noeof (inp);
pktlen--;
- sk->protect.sha1chk = 0;
- if (sk->protect.algo)
+ if (ski->algo)
{
- sk->is_protected = 1;
- sk->protect.s2k.count = 0;
- if (sk->protect.algo == 254 || sk->protect.algo == 255)
+ ski->is_protected = 1;
+ ski->s2k.count = 0;
+ if (ski->algo == 254 || ski->algo == 255)
{
if (pktlen < 3)
{
- rc = G10ERR_INVALID_PACKET;
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
- sk->protect.sha1chk = (sk->protect.algo == 254);
- sk->protect.algo = iobuf_get_noeof (inp);
+ ski->sha1chk = (ski->algo == 254);
+ ski->algo = iobuf_get_noeof (inp);
pktlen--;
- /* Note that a sk->protect.algo > 110 is illegal, but
- I'm not erroring on it here as otherwise there would
- be no way to delete such a key. */
- sk->protect.s2k.mode = iobuf_get_noeof (inp);
+ /* Note that a ski->algo > 110 is illegal, but I'm not
+ erroring on it here as otherwise there would be no
+ way to delete such a key. */
+ ski->s2k.mode = iobuf_get_noeof (inp);
pktlen--;
- sk->protect.s2k.hash_algo = iobuf_get_noeof (inp);
+ ski->s2k.hash_algo = iobuf_get_noeof (inp);
pktlen--;
- /* check for the special GNU extension */
- if (is_v4 && sk->protect.s2k.mode == 101)
+ /* Check for the special GNU extension. */
+ if (is_v4 && ski->s2k.mode == 101)
{
for (i = 0; i < 4 && pktlen; i++, pktlen--)
temp[i] = iobuf_get_noeof (inp);
@@ -1999,26 +1992,30 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
{
if (list_mode)
es_fprintf (listfp, "\tunknown S2K %d\n",
- sk->protect.s2k.mode);
- rc = G10ERR_INVALID_PACKET;
+ ski->s2k.mode);
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
/* Here we know that it is a GNU extension. What
* follows is the GNU protection mode: All values
* have special meanings and they are mapped to MODE
* with a base of 1000. */
- sk->protect.s2k.mode = 1000 + temp[3];
+ ski->s2k.mode = 1000 + temp[3];
}
- switch (sk->protect.s2k.mode)
+
+ /* Read the salt. */
+ switch (ski->s2k.mode)
{
case 1:
case 3:
for (i = 0; i < 8 && pktlen; i++, pktlen--)
temp[i] = iobuf_get_noeof (inp);
- memcpy (sk->protect.s2k.salt, temp, 8);
+ memcpy (ski->s2k.salt, temp, 8);
break;
}
- switch (sk->protect.s2k.mode)
+
+ /* Check the mode. */
+ switch (ski->s2k.mode)
{
case 0:
if (list_mode)
@@ -2043,202 +2040,163 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
default:
if (list_mode)
es_fprintf (listfp, "\tunknown %sS2K %d\n",
- sk->protect.s2k.mode < 1000 ? "" : "GNU ",
- sk->protect.s2k.mode);
- rc = G10ERR_INVALID_PACKET;
+ ski->s2k.mode < 1000 ? "" : "GNU ",
+ ski->s2k.mode);
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
+ /* Print some info. */
if (list_mode)
{
es_fprintf (listfp, ", algo: %d,%s hash: %d",
- sk->protect.algo,
- sk->protect.sha1chk ? " SHA1 protection,"
- : " simple checksum,", sk->protect.s2k.hash_algo);
- if (sk->protect.s2k.mode == 1 || sk->protect.s2k.mode == 3)
+ ski->algo,
+ ski->sha1chk ? " SHA1 protection,"
+ : " simple checksum,", ski->s2k.hash_algo);
+ if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
{
es_fprintf (listfp, ", salt: ");
- es_write_hexstring (listfp, sk->protect.s2k.salt, 8,
- 0, NULL);
+ es_write_hexstring (listfp, ski->s2k.salt, 8, 0, NULL);
}
es_putc ('\n', listfp);
}
- if (sk->protect.s2k.mode == 3)
+ /* Read remaining protection parameters. */
+ if (ski->s2k.mode == 3)
{
if (pktlen < 1)
{
- rc = G10ERR_INVALID_PACKET;
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
- sk->protect.s2k.count = iobuf_get (inp);
+ ski->s2k.count = iobuf_get (inp);
pktlen--;
if (list_mode)
es_fprintf (listfp, "\tprotect count: %lu\n",
- (ulong) sk->protect.s2k.count);
+ (ulong) ski->s2k.count);
}
- else if (sk->protect.s2k.mode == 1002)
+ else if (ski->s2k.mode == 1002)
{
/* Read the serial number. */
if (pktlen < 1)
{
- rc = G10ERR_INVALID_PACKET;
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
snlen = iobuf_get (inp);
pktlen--;
if (pktlen < snlen || snlen == -1)
{
- rc = G10ERR_INVALID_PACKET;
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
}
}
else /* Old version; no S2K, so we set mode to 0, hash MD5. */
{
- /* Note that a sk->protect.algo > 110 is illegal, but
- I'm not erroring on it here as otherwise there would
- be no way to delete such a key. */
- sk->protect.s2k.mode = 0;
- sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
+ /* Note that a ski->algo > 110 is illegal, but I'm not
+ erroring on it here as otherwise there would be no
+ way to delete such a key. */
+ ski->s2k.mode = 0;
+ ski->s2k.hash_algo = DIGEST_ALGO_MD5;
if (list_mode)
es_fprintf (listfp, "\tprotect algo: %d (hash algo: %d)\n",
- sk->protect.algo, sk->protect.s2k.hash_algo);
+ ski->algo, ski->s2k.hash_algo);
}
/* It is really ugly that we don't know the size
* of the IV here in cases we are not aware of the algorithm.
* so a
- * sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
+ * ski->ivlen = cipher_get_blocksize (ski->algo);
* won't work. The only solution I see is to hardwire it.
* NOTE: if you change the ivlen above 16, don't forget to
* enlarge temp. */
- sk->protect.ivlen = openpgp_cipher_blocklen (sk->protect.algo);
- assert (sk->protect.ivlen <= sizeof (temp));
+ ski->ivlen = openpgp_cipher_blocklen (ski->algo);
+ assert (ski->ivlen <= sizeof (temp));
- if (sk->protect.s2k.mode == 1001)
- sk->protect.ivlen = 0;
- else if (sk->protect.s2k.mode == 1002)
- sk->protect.ivlen = snlen < 16 ? snlen : 16;
+ if (ski->s2k.mode == 1001)
+ ski->ivlen = 0;
+ else if (ski->s2k.mode == 1002)
+ ski->ivlen = snlen < 16 ? snlen : 16;
- if (pktlen < sk->protect.ivlen)
+ if (pktlen < ski->ivlen)
{
- rc = G10ERR_INVALID_PACKET;
+ err = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
- for (i = 0; i < sk->protect.ivlen && pktlen; i++, pktlen--)
+ for (i = 0; i < ski->ivlen && pktlen; i++, pktlen--)
temp[i] = iobuf_get_noeof (inp);
if (list_mode)
{
es_fprintf (listfp,
- sk->protect.s2k.mode == 1002 ? "\tserial-number: "
- : "\tprotect IV: ");
- for (i = 0; i < sk->protect.ivlen; i++)
+ ski->s2k.mode == 1002 ? "\tserial-number: "
+ : "\tprotect IV: ");
+ for (i = 0; i < ski->ivlen; i++)
es_fprintf (listfp, " %02x", temp[i]);
es_putc ('\n', listfp);
}
- memcpy (sk->protect.iv, temp, sk->protect.ivlen);
+ memcpy (ski->iv, temp, ski->ivlen);
}
- else
- sk->is_protected = 0;
/* It does not make sense to read it into secure memory.
* If the user is so careless, not to protect his secret key,
* we can assume, that he operates an open system :=(.
* So we put the key into secure memory when we unprotect it. */
- if (sk->protect.s2k.mode == 1001 || sk->protect.s2k.mode == 1002)
+ if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002)
{
/* Better set some dummy stuff here. */
- sk->skey[npkey] = gcry_mpi_set_opaque (NULL,
+ pk->pkey[npkey] = gcry_mpi_set_opaque (NULL,
xstrdup ("dummydata"),
10 * 8);
pktlen = 0;
}
- else if (is_v4 && sk->is_protected)
+ else if (is_v4 && ski->is_protected)
{
/* Ugly: The length is encrypted too, so we read all stuff
* up to the end of the packet into the first SKEY
* element. */
- sk->skey[npkey] = gcry_mpi_set_opaque (NULL,
+ pk->pkey[npkey] = gcry_mpi_set_opaque (NULL,
read_rest (inp, pktlen, 0),
pktlen * 8);
pktlen = 0;
if (list_mode)
- {
- es_fprintf (listfp, "\tencrypted stuff follows\n");
- }
+ es_fprintf (listfp, "\tskey[%d]: [v4 protected]\n", npkey);
}
- else /* The v3 method: The mpi length is not encrypted. */
+ else
{
+ /* The v3 method: The mpi length is not encrypted. */
for (i = npkey; i < nskey; i++)
{
- if (sk->is_protected)
+ if (ski->is_protected)
{
- sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
+ pk->pkey[i] = read_protected_v3_mpi (inp, &pktlen);
if (list_mode)
- es_fprintf (listfp, "\tskey[%d]: [encrypted]\n", i);
+ es_fprintf (listfp, "\tskey[%d]: [v3 protected]\n", i);
}
else
{
n = pktlen;
- sk->skey[i] = mpi_read (inp, &n, 0);
+ pk->pkey[i] = mpi_read (inp, &n, 0);
pktlen -= n;
if (list_mode)
{
es_fprintf (listfp, "\tskey[%d]: ", i);
- mpi_print (listfp, sk->skey[i], mpi_print_mode);
+ mpi_print (listfp, pk->pkey[i], mpi_print_mode);
es_putc ('\n', listfp);
}
}
- if (!sk->skey[i])
- rc = G10ERR_INVALID_PACKET;
+ if (!pk->pkey[i])
+ err = gpg_error (GPG_ERR_INV_PACKET);
}
- if (rc)
+ if (err)
goto leave;
- sk->csum = read_16 (inp);
+ ski->csum = read_16 (inp);
pktlen -= 2;
if (list_mode)
- {
- es_fprintf (listfp, "\tchecksum: %04hx\n", sk->csum);
- }
+ es_fprintf (listfp, "\tchecksum: %04hx\n", ski->csum);
}
-
- if (list_mode)
- keyid_from_sk (sk, keyid);
- }
- else
- {
- PKT_public_key *pk = pkt->pkt.public_key;
-
- if (!npkey)
- {
- pk->pkey[0] = gcry_mpi_set_opaque (NULL,
- read_rest (inp, pktlen, 0),
- pktlen * 8);
- pktlen = 0;
- goto leave;
- }
-
- for (i = 0; i < npkey; i++)
- {
- n = pktlen;
- pk->pkey[i] = mpi_read (inp, &n, 0);
- pktlen -= n;
- if (list_mode)
- {
- es_fprintf (listfp, "\tpkey[%d]: ", i);
- mpi_print (listfp, pk->pkey[i], mpi_print_mode);
- es_putc ('\n', listfp);
- }
- if (!pk->pkey[i])
- rc = G10ERR_INVALID_PACKET;
- }
- if (rc)
- goto leave;
- if (list_mode)
- keyid_from_pk (pk, keyid);
}
if (list_mode)
diff --git a/g10/passphrase.c b/g10/passphrase.c
index b934cb349..60560123f 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -686,10 +686,10 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
/* Return an allocated utf-8 string describing the key PK. IF ESCAPED
- is true spaces and control characters are percent or plus
- escaped. */
+ is true spaces and control characters are percent or plus escaped.
+ MODE 0 is for the common prompt, MODE 1 for the import prompt. */
char *
-gpg_format_keydesc (PKT_public_key *pk, int escaped)
+gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
{
char *uid;
size_t uidlen;
@@ -698,6 +698,7 @@ gpg_format_keydesc (PKT_public_key *pk, int escaped)
char *orig_codeset;
char *maink;
char *desc;
+ const char *prompt;
algo_name = gcry_pk_algo_name (pk->pubkey_algo);
timestr = strtimestamp (pk->timestamp);
@@ -712,11 +713,26 @@ gpg_format_keydesc (PKT_public_key *pk, int escaped)
else
maink = NULL;
- desc = xtryasprintf (_("Please enter the passphrase to unlock the"
- " secret key for the OpenPGP certificate:\n"
+ switch (mode)
+ {
+ case 0:
+ prompt = _("Please enter the passphrase to unlock the"
+ " secret key for the OpenPGP certificate:");
+ break;
+ case 1:
+ prompt = _("Please enter the passphrase to import the"
+ " secret key for the OpenPGP certificate:");
+ break;
+ default:
+ prompt = "?";
+ break;
+ }
+
+ desc = xtryasprintf (_("%s\n"
"\"%.*s\"\n"
"%u-bit %s key, ID %s,\n"
"created %s%s.\n"),
+ prompt,
(int)uidlen, uid,
nbits_from_pk (pk), algo_name,
keystr (pk->keyid), timestr,
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index d90559d32..74bdc7655 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -196,7 +196,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
goto leave;
/* Decrypt. */
- desc = gpg_format_keydesc (sk, 1);
+ desc = gpg_format_keydesc (sk, 0, 1);
err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe);
xfree (desc);
gcry_sexp_release (s_data);
diff --git a/g10/sign.c b/g10/sign.c
index d5b6a5118..eeb4549ca 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -314,7 +314,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
char *desc;
gcry_sexp_t s_sigval;
- desc = gpg_format_keydesc (pksk, 1);
+ desc = gpg_format_keydesc (pksk, 0, 1);
err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc,
dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
&s_sigval);