1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-03 12:11:33 +01:00

Removed more secret key related code.

It builds fine and passes some of the tests but there are quite some
features which don't work yet.
This commit is contained in:
Werner Koch 2010-09-06 19:57:42 +00:00
parent daab9aff3a
commit 299ed4c9e2
20 changed files with 1307 additions and 1946 deletions

View File

@ -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.

View File

@ -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,18 +239,22 @@ 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();
static int
do_key (iobuf_t out, int ctb, PKT_public_key *pk)
{
gpg_error_t err = 0;
int i, nskey, npkey;
iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer. */
/* Write the version number - if none is specified, use 3 */
if ( !pk->version )
iobuf_put( a, 3 );
iobuf_put ( a, 3 );
else
iobuf_put( a, pk->version );
write_32(a, pk->timestamp );
iobuf_put ( a, pk->version );
write_32 (a, pk->timestamp );
/* v3 needs the expiration time. */
if ( pk->version < 4 )
{
u16 ndays;
@ -261,179 +262,139 @@ do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
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 )
{
int rc = 0;
int i, nskey, npkey;
IOBUF a = iobuf_temp(); /* Build in a self-enlarging buffer. */
/* Write the version number - if none is specified, use 3 */
if ( !sk->version )
iobuf_put ( a, 3 );
else
iobuf_put ( a, sk->version );
write_32 (a, sk->timestamp );
/* v3 needs the expiration time. */
if ( sk->version < 4 )
{
u16 ndays;
if ( sk->expiredate )
ndays = (u16)((sk->expiredate - sk->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 )
/* 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)
{
/* The simple rfc1991 (v3) way. */
iobuf_put (a, sk->protect.algo );
iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
}
else
{
/* 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 );
}
/* 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 );
/* 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 ( sk->protect.s2k.mode == 3 )
iobuf_put (a, sk->protect.s2k.count );
if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
iobuf_write (a, ski->s2k.salt, 8);
/* 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 (ski->s2k.mode == 3)
iobuf_put (a, ski->s2k.count);
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;
/* 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 );
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++ )
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 (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[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 (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

View File

@ -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;
/* 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;
/* 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 (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;
}
/* 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);
/* show_card_key_info (&info); */
nbits = nbits_from_sk (sk);
/* 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;
}
/* 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)));
/* 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"));
/* 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"));
/* 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"));
}
/* 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;
/* 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;
}
/* /\* 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; */
/* } */
/* #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 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);
/* /\* 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;
/* okay = 1; */
leave:
if (copied_sk)
free_secret_key (copied_sk);
agent_release_card_info (&info);
return okay;
/* leave: */
/* if (copied_sk) */
/* free_secret_key (copied_sk); */
/* agent_release_card_info (&info); */
/* return okay; */
return -1;
}

View File

@ -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 )
{
sk = node->pkt->pkt.secret_key;
keyid_from_sk( sk, keyid );
}
else
{
/* public */
pk = node->pkt->pkt.public_key;
keyid_from_pk( pk, keyid );
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 (!force)
{
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"

View File

@ -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;
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 ();
*any = 0;
init_packet (&pkt);
kdbhd = keydb_new ();
if (!users) {
ndesc = 1;
desc = xcalloc ( ndesc, sizeof *desc );
desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
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;
if ((node=find_kbnode(keyblock, PKT_SECRET_KEY)))
{
PKT_public_key *pk = node->pkt->pkt.public_key;
keyid_from_sk(sk,sk_keyid);
keyid_from_pk (pk, 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;
/* Make sure that ring_trust packets never get exported. */
if (node->pkt->pkttype == PKT_RING_TRUST)
/* 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;
}
/* 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.
/* 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;
}
So the first step here is to check that list and
skip in any case if the key is in that list.
/* 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);
}
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;
/* 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;
}
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. */
}
}
/* 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(skip_until_subkey)
continue;
/* Make sure that ring_trust packets never get exported. */
if (node->pkt->pkttype == PKT_RING_TRUST)
continue;
/* Mark this one as processed. */
/* 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))
{
subkey_list_t tmp = new_subkey_list_item (node);
tmp->next = subkey_list;
subkey_list = tmp;
/* 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(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 */
if(skip_until_subkey)
continue;
/* 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;
/* Mark this one as processed. */
{
subkey_list_t tmp = new_subkey_list_item (node);
tmp->next = subkey_list;
subkey_list = tmp;
}
}
for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
break;
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 */
if(i<node->pkt->pkt.signature->numrevkeys)
continue;
}
}
/* 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;
/* Don't export attribs? */
if( !(options&EXPORT_ATTRIBUTES) &&
node->pkt->pkttype == PKT_USER_ID &&
node->pkt->pkt.user_id->attrib_data ) {
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 )
{
/* 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;
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;
/* 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;
}
/* 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))
rc = build_sexp (out, node->pkt, &indent);
else
rc = build_packet (out, node->pkt);
/* 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.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));
/* 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;
}
sha1_warned = 1;
}
if ((options&EXPORT_SEXP_FORMAT))
rc = build_sexp (out, node->pkt, &indent);
else
rc = build_packet (out, node->pkt);
}
if ((options&EXPORT_SEXP_FORMAT))
err = build_sexp (out, node->pkt, &indent);
else
err = build_packet (out, node->pkt);
}
if( rc ) {
log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) );
goto leave;
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');
}
if ((options&EXPORT_SEXP_FORMAT) && indent)
{
for (; indent; indent--)
iobuf_put (out, ')');
iobuf_put (out, '\n');
}
++*any;
if(keyblock_out)
{
*keyblock_out=keyblock;
break;
}
++*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;
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(rc || keyblock_out==NULL)
release_kbnode( keyblock );
if( !*any )
log_info(_("WARNING: nothing exported\n"));
return rc;
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];
/* 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');
/* 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;
/* return 0; */
}

View File

@ -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->revkey) {
xfree(pk->revkey);
pk->revkey=NULL;
pk->numrevkeys=0;
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;
}
}
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;
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] );
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 *
@ -256,48 +260,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 )
{
@ -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

View File

@ -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");

View File

@ -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;
}

View File

@ -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);

View File

@ -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. */

View File

@ -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];
u32 dummy_keyid[2];
if( !keyid )
keyid = dummy_keyid;
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;
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 );
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
/*
* Return the number of bits used in PK.
*/
unsigned
nbits_from_pk( PKT_public_key *pk )
unsigned int
nbits_from_pk (PKT_public_key *pk)
{
return pubkey_nbits( pk->pubkey_algo, pk->pkey );
return pubkey_nbits (pk->pubkey_algo, pk->pkey);
}
/****************
* return the number of bits used in the sk
*/
unsigned
nbits_from_sk( PKT_secret_key *sk )
{
return pubkey_nbits( sk->pubkey_algo, sk->skey );
}
static const char *
mk_datestr (char *buffer, time_t atime)
{
struct tm *tp;
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 );
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;
static char buffer[11+5];
time_t atime = pk->timestamp;
return mk_datestr (buffer, atime);
return mk_datestr (buffer, atime);
}
const char *
datestr_from_sk( PKT_secret_key *sk )
datestr_from_sig (PKT_signature *sig )
{
static char buffer[11+5];
time_t atime = sk->timestamp;
static char buffer[11+5];
time_t atime = sig->timestamp;
return mk_datestr (buffer, atime);
return mk_datestr (buffer, atime);
}
const char *
datestr_from_sig( PKT_signature *sig )
expirestr_from_pk (PKT_public_key *pk)
{
static char buffer[11+5];
time_t atime = sig->timestamp;
static char buffer[11+5];
time_t atime;
return mk_datestr (buffer, atime);
if (!pk->expiredate)
return _("never ");
atime = pk->expiredate;
return mk_datestr (buffer, atime);
}
const char *
expirestr_from_pk( PKT_public_key *pk )
expirestr_from_sig (PKT_signature *sig)
{
static char buffer[11+5];
time_t atime;
static char buffer[11+5];
time_t atime;
if( !pk->expiredate )
return _("never ");
atime = pk->expiredate;
return mk_datestr (buffer, atime);
if (!sig->expiredate)
return _("never ");
atime=sig->expiredate;
return mk_datestr (buffer, atime);
}
const char *
expirestr_from_sk( PKT_secret_key *sk )
{
static char buffer[11+5];
time_t atime;
if( !sk->expiredate )
return _("never ");
atime = sk->expiredate;
return mk_datestr (buffer, atime);
}
const char *
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);
}
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,105 +661,7 @@ 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;
}

View File

@ -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;
/* 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;
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");
}
}
/* 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;
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. */
/* 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);
/* 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); */
}

View File

@ -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)

View File

@ -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);

View File

@ -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 );
|| 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( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
is_selfsig = 1;
}
}
if( opt.with_colons ) {
putchar(':');

View File

@ -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 );

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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);