mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
* call-agent.c (agent_scd_getattr): Don't clear the passed info
structure, so that it can indeed be updated. * card-util.c (fpr_is_zero): New. (generate_card_keys): New. (card_edit): New command "generate". * keygen.c (generate_keypair): New arg CARD_SERIALNO, removed call to check_smartcard. (check_smartcard,show_smartcard): Removed. (show_sha1_fpr,fpr_is_zero): Removed. * app-openpgp.c (do_getattr): Support SERIALNO and AID.
This commit is contained in:
parent
f194ebc782
commit
30342b06ef
5
NEWS
5
NEWS
@ -1,6 +1,11 @@
|
||||
Noteworthy changes in version 1.9.2 (unreleased)
|
||||
------------------------------------------------
|
||||
|
||||
* On card key generation is no longer done using the --gen-key
|
||||
command but from the menu provided by the new --card-edit command.
|
||||
|
||||
* PINs are now properly cached and there are only 2 PINs visible.
|
||||
The 3rd PIN (CHV2) is internally syncronized with the regular PIN.
|
||||
|
||||
|
||||
Noteworthy changes in version 1.9.1 (2003-09-06)
|
||||
|
4
README
4
README
@ -47,6 +47,10 @@ gpg2:
|
||||
Offers a menu to change the PIN of OpenPGP smartcards and to reset
|
||||
the retry counters.
|
||||
|
||||
--card-edit
|
||||
|
||||
Offers a menu to change any data object on the card and to generate
|
||||
the keys.
|
||||
|
||||
|
||||
OPTIONS
|
||||
|
1
TODO
1
TODO
@ -33,6 +33,7 @@ might want to have an agent context for each service request
|
||||
* sm/gpgsm.c
|
||||
** Support --output
|
||||
** mark all unimplemented commands and options.
|
||||
** Print a hint when of MD2 is the cause for a problem.
|
||||
|
||||
* sm/keydb.c
|
||||
** Check file permissions
|
||||
|
@ -1,3 +1,16 @@
|
||||
2003-10-08 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* call-agent.c (agent_scd_getattr): Don't clear the passed info
|
||||
structure, so that it can indeed be updated.
|
||||
|
||||
* card-util.c (fpr_is_zero): New.
|
||||
(generate_card_keys): New.
|
||||
(card_edit): New command "generate".
|
||||
* keygen.c (generate_keypair): New arg CARD_SERIALNO, removed call
|
||||
to check_smartcard.
|
||||
(check_smartcard,show_smartcard): Removed.
|
||||
(show_sha1_fpr,fpr_is_zero): Removed.
|
||||
|
||||
2003-10-01 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* card-util.c: Tweaked to use this source also under 1.3.
|
||||
|
@ -600,7 +600,6 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memset (info, 0, sizeof *info);
|
||||
rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
|
||||
learn_status_cb, info);
|
||||
|
||||
|
@ -241,6 +241,17 @@ print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
|
||||
tty_fprintf (fp, "\n");
|
||||
}
|
||||
|
||||
/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
|
||||
static int
|
||||
fpr_is_zero (const char *fpr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < 20 && !fpr[i]; i++)
|
||||
;
|
||||
return (i == 20);
|
||||
}
|
||||
|
||||
|
||||
/* Print all available information about the current card. */
|
||||
void
|
||||
@ -569,6 +580,76 @@ toggle_forcesig (void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_card_keys (void)
|
||||
{
|
||||
struct agent_card_info_s info;
|
||||
int rc;
|
||||
int forced_chv1;
|
||||
|
||||
memset (&info, 0, sizeof info);
|
||||
rc = agent_scd_getattr ("KEY-FPR", &info);
|
||||
if (!rc)
|
||||
rc = agent_scd_getattr ("SERIALNO", &info);
|
||||
if (!rc)
|
||||
rc = agent_scd_getattr ("CHV-STATUS", &info);
|
||||
if (!rc)
|
||||
rc = agent_scd_getattr ("DISP-NAME", &info);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error getting current key info: %s\n", gpg_strerror (rc));
|
||||
return;
|
||||
}
|
||||
if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
|
||||
|| (info.fpr2valid && !fpr_is_zero (info.fpr2))
|
||||
|| (info.fpr3valid && !fpr_is_zero (info.fpr3)))
|
||||
{
|
||||
tty_printf ("\n");
|
||||
log_info ("NOTE: keys are already stored on the card!\n");
|
||||
tty_printf ("\n");
|
||||
if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys",
|
||||
_("Replace existing keys? ")))
|
||||
{
|
||||
agent_release_card_info (&info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!info.disp_name || !*info.disp_name)
|
||||
{
|
||||
tty_printf ("\n");
|
||||
tty_printf (_("Please note that the factory settings of the PINs are\n"
|
||||
" PIN = \"%s\" Admin PIN = \"%s\"\n"
|
||||
"You should change them using the command --change-pin\n"),
|
||||
"123456", "12345678");
|
||||
tty_printf ("\n");
|
||||
}
|
||||
|
||||
forced_chv1 = !info.chv1_cached;
|
||||
if (forced_chv1)
|
||||
{ /* Switch of the forced mode so that during key generation we
|
||||
don't get bothered with PIN queries for each
|
||||
self-signature. */
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error clearing forced signature PIN flag: %s\n",
|
||||
gpg_strerror (rc));
|
||||
return;
|
||||
}
|
||||
}
|
||||
generate_keypair (NULL, info.serialno);
|
||||
agent_release_card_info (&info);
|
||||
if (forced_chv1)
|
||||
{ /* Switch back to forced state. */
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error setting forced signature PIN flag: %s\n",
|
||||
gpg_strerror (rc));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Menu to edit all user changeable values on an OpenPGP card. Only
|
||||
Key creation is not handled here. */
|
||||
@ -579,7 +660,7 @@ card_edit (STRLIST commands)
|
||||
cmdNOP = 0,
|
||||
cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
|
||||
cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
|
||||
cmdFORCESIG,
|
||||
cmdFORCESIG, cmdGENERATE,
|
||||
cmdINVCMD
|
||||
};
|
||||
|
||||
@ -601,6 +682,7 @@ card_edit (STRLIST commands)
|
||||
{ N_("lang") , cmdLANG , N_("change the language preferences") },
|
||||
{ N_("sex") , cmdSEX , N_("change card holder's sex") },
|
||||
{ N_("forcesig"), cmdFORCESIG, N_("toggle the signature force PIN flag") },
|
||||
{ N_("generate"), cmdGENERATE, N_("generate new keys") },
|
||||
{ NULL, cmdINVCMD }
|
||||
};
|
||||
|
||||
@ -725,6 +807,10 @@ card_edit (STRLIST commands)
|
||||
toggle_forcesig ();
|
||||
break;
|
||||
|
||||
case cmdGENERATE:
|
||||
generate_card_keys ();
|
||||
break;
|
||||
|
||||
case cmdQUIT:
|
||||
goto leave;
|
||||
|
||||
|
@ -2555,12 +2555,12 @@ main( int argc, char **argv )
|
||||
if( opt.batch ) {
|
||||
if( argc > 1 )
|
||||
wrong_args("--gen-key [parameterfile]");
|
||||
generate_keypair( argc? *argv : NULL );
|
||||
generate_keypair( argc? *argv : NULL, NULL );
|
||||
}
|
||||
else {
|
||||
if( argc )
|
||||
wrong_args("--gen-key");
|
||||
generate_keypair(NULL);
|
||||
generate_keypair(NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
|
194
g10/keygen.c
194
g10/keygen.c
@ -117,7 +117,6 @@ static int mdc_available,ks_modify;
|
||||
static void do_generate_keypair( struct para_data_s *para,
|
||||
struct output_control_s *outctrl, int card);
|
||||
static int write_keyblock( iobuf_t out, KBNODE node );
|
||||
static int check_smartcard (char **);
|
||||
static int gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root,
|
||||
u32 expireval, struct para_data_s *para);
|
||||
|
||||
@ -2219,11 +2218,12 @@ read_parameter_file( const char *fname )
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a keypair
|
||||
* (fname is only used in batch mode)
|
||||
* Generate a keypair (fname is only used in batch mode) If
|
||||
* CARD_SERIALNO is not NULL the fucntion will create the keys on an
|
||||
* OpenPGP Card.
|
||||
*/
|
||||
void
|
||||
generate_keypair( const char *fname )
|
||||
generate_keypair( const char *fname, const char *card_serialno )
|
||||
{
|
||||
unsigned int nbits;
|
||||
char *uid = NULL;
|
||||
@ -2232,42 +2232,34 @@ generate_keypair( const char *fname )
|
||||
int algo;
|
||||
unsigned int use;
|
||||
int both = 0;
|
||||
int card = 0;
|
||||
u32 expire;
|
||||
struct para_data_s *para = NULL;
|
||||
struct para_data_s *r;
|
||||
struct output_control_s outctrl;
|
||||
char *serialno = NULL;
|
||||
|
||||
memset (&outctrl, 0, sizeof (outctrl));
|
||||
|
||||
if (opt.batch && card_serialno)
|
||||
{
|
||||
/* We don't yet support unattended key generation. */
|
||||
log_error (_("sorry, can't do this in batch mode\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt.batch)
|
||||
{
|
||||
read_parameter_file( fname );
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
if (card_serialno)
|
||||
{
|
||||
xfree (serialno); serialno = NULL;
|
||||
card = check_smartcard (&serialno);
|
||||
if (card < 0)
|
||||
return;
|
||||
}
|
||||
while (card > 1);
|
||||
|
||||
if (serialno)
|
||||
{
|
||||
r = xcalloc (1, sizeof *r + strlen (serialno) );
|
||||
r = xcalloc (1, sizeof *r + strlen (card_serialno) );
|
||||
r->key = pSERIALNO;
|
||||
strcpy( r->u.value, serialno);
|
||||
strcpy( r->u.value, card_serialno);
|
||||
r->next = para;
|
||||
para = r;
|
||||
xfree (serialno); serialno = NULL;
|
||||
}
|
||||
|
||||
if (card)
|
||||
{
|
||||
algo = PUBKEY_ALGO_RSA;
|
||||
|
||||
r = xcalloc (1, sizeof *r + 20 );
|
||||
@ -2388,7 +2380,7 @@ generate_keypair( const char *fname )
|
||||
r->next = para;
|
||||
para = r;
|
||||
|
||||
dek = card? NULL : ask_passphrase( &s2k );
|
||||
dek = card_serialno? NULL : ask_passphrase( &s2k );
|
||||
if (dek)
|
||||
{
|
||||
r = xcalloc (1, sizeof *r );
|
||||
@ -2403,7 +2395,7 @@ generate_keypair( const char *fname )
|
||||
para = r;
|
||||
}
|
||||
|
||||
proc_parameter_file (para, "[internal]", &outctrl, card);
|
||||
proc_parameter_file (para, "[internal]", &outctrl, !!card_serialno);
|
||||
release_parameter_list (para);
|
||||
}
|
||||
|
||||
@ -2719,7 +2711,7 @@ do_generate_keypair (struct para_data_s *para,
|
||||
release_kbnode (pub_root);
|
||||
release_kbnode (sec_root);
|
||||
if (sk && !card) /* The unprotected secret key unless we have */
|
||||
free_secret_key (sk); /* shallow copy in card mode. */
|
||||
free_secret_key (sk); /* a shallow copy in card mode. */
|
||||
}
|
||||
|
||||
|
||||
@ -2848,158 +2840,6 @@ write_keyblock( iobuf_t out, KBNODE node )
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
show_sha1_fpr (const unsigned char *fpr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (fpr)
|
||||
{
|
||||
for (i=0; i < 20 ; i+=2, fpr += 2 )
|
||||
{
|
||||
if (i == 10 )
|
||||
tty_printf (" ");
|
||||
tty_printf (" %02X%02X", *fpr, fpr[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
tty_printf (" [none]");
|
||||
tty_printf ("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
show_smartcard (struct agent_card_info_s *info)
|
||||
{
|
||||
PKT_public_key *pk = xcalloc (1, sizeof *pk);
|
||||
|
||||
/* FIXME: Sanitize what we show. */
|
||||
tty_printf ("Name of cardholder: %s\n",
|
||||
info->disp_name && *info->disp_name? info->disp_name
|
||||
: "[not set]");
|
||||
tty_printf ("URL of public key : %s\n",
|
||||
info->pubkey_url && *info->pubkey_url? info->pubkey_url
|
||||
: "[not set]");
|
||||
tty_printf ("Signature key ....:");
|
||||
show_sha1_fpr (info->fpr1valid? info->fpr1:NULL);
|
||||
tty_printf ("Encryption key....:");
|
||||
show_sha1_fpr (info->fpr2valid? info->fpr2:NULL);
|
||||
tty_printf ("Authentication key:");
|
||||
show_sha1_fpr (info->fpr3valid? info->fpr3:NULL);
|
||||
|
||||
if (info->fpr1valid && !get_pubkey_byfprint (pk, info->fpr1, 20))
|
||||
print_pubkey_info (NULL, pk);
|
||||
|
||||
free_public_key( pk );
|
||||
}
|
||||
|
||||
/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
|
||||
static int
|
||||
fpr_is_zero (const char *fpr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < 20 && !fpr[i]; i++)
|
||||
;
|
||||
return (i == 20);
|
||||
}
|
||||
|
||||
/* Check whether a smartcatrd is available and alow to select it as
|
||||
the target for key generation.
|
||||
|
||||
Return values: -1 = Quit generation
|
||||
0 = No smartcard
|
||||
1 = Generate keypair
|
||||
*/
|
||||
static int
|
||||
check_smartcard (char **r_serialno)
|
||||
{
|
||||
struct agent_card_info_s info;
|
||||
int rc;
|
||||
|
||||
rc = agent_learn (&info);
|
||||
if (rc)
|
||||
{
|
||||
tty_printf (_("OpenPGP card not available: %s\n"),
|
||||
gpg_strerror (rc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
tty_printf (_("OpenPGP card no. %s detected\n"),
|
||||
info.serialno? info.serialno : "[none]");
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char *answer;
|
||||
int reread = 0;
|
||||
|
||||
tty_printf ("\n");
|
||||
show_smartcard (&info);
|
||||
|
||||
tty_printf ("\n"
|
||||
"K - generate all keys\n"
|
||||
"Q - quit\n"
|
||||
"\n");
|
||||
|
||||
answer = cpr_get("keygen.smartcard.menu",_("Your selection? "));
|
||||
cpr_kill_prompt();
|
||||
if (strlen (answer) != 1)
|
||||
continue;
|
||||
|
||||
rc = 0;
|
||||
if ( *answer == 'K' || *answer == 'k')
|
||||
{
|
||||
if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
|
||||
|| (info.fpr2valid && !fpr_is_zero (info.fpr2))
|
||||
|| (info.fpr3valid && !fpr_is_zero (info.fpr3)))
|
||||
{
|
||||
tty_printf ("\n");
|
||||
log_error ("WARNING: key does already exists!\n");
|
||||
tty_printf ("\n");
|
||||
if ( cpr_get_answer_is_yes( "keygen.card.replace_key",
|
||||
_("Replace existing key? ")))
|
||||
{
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( *answer == 'q' || *answer == 'Q')
|
||||
{
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (reread)
|
||||
{
|
||||
agent_release_card_info (&info);
|
||||
rc = agent_learn (&info);
|
||||
if (rc)
|
||||
{
|
||||
tty_printf (_("OpenPGP card not anymore available: %s\n"),
|
||||
gpg_strerror (rc));
|
||||
g10_exit (1);
|
||||
}
|
||||
reread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (r_serialno && rc > 0)
|
||||
{
|
||||
*r_serialno = info.serialno;
|
||||
info.serialno = NULL;
|
||||
}
|
||||
agent_release_card_info (&info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root,
|
||||
|
@ -165,7 +165,7 @@ void show_basic_key_info (KBNODE keyblock);
|
||||
/*-- keygen.c --*/
|
||||
u32 ask_expire_interval(int object);
|
||||
u32 ask_expiredate(void);
|
||||
void generate_keypair( const char *fname );
|
||||
void generate_keypair( const char *fname, const char *card_serialno );
|
||||
int keygen_set_std_prefs (const char *string,int personal);
|
||||
PKT_user_id *keygen_get_std_prefs (void);
|
||||
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
|
||||
|
@ -1,3 +1,7 @@
|
||||
2003-10-08 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* app-openpgp.c (do_getattr): Support SERIALNO and AID.
|
||||
|
||||
2003-10-01 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* ccid-driver.c: Detect GnuPG 1.3 and include appropriate files.
|
||||
|
@ -425,6 +425,8 @@ do_getattr (APP app, CTRL ctrl, const char *name)
|
||||
{ "CA-FPR", 0x00C6, 3 },
|
||||
{ "CHV-STATUS", 0x00C4, 1 },
|
||||
{ "SIG-COUNTER", 0x0093, 2 },
|
||||
{ "SERIALNO", 0x004F, -1 },
|
||||
{ "AID", 0x004F },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int idx, i;
|
||||
@ -437,6 +439,29 @@ do_getattr (APP app, CTRL ctrl, const char *name)
|
||||
if (!table[idx].name)
|
||||
return gpg_error (GPG_ERR_INV_NAME);
|
||||
|
||||
if (table[idx].special == -1)
|
||||
{
|
||||
/* The serial number is very special. We could have used the
|
||||
AID DO to retrieve it, but we have it already in the app
|
||||
context and the stanmp argument is required anyway which we
|
||||
can't by other means. The AID DO is available anyway but not
|
||||
hex formatted. */
|
||||
char *serial;
|
||||
time_t stamp;
|
||||
char tmp[50];
|
||||
|
||||
if (!app_get_serial_and_stamp (app, &serial, &stamp))
|
||||
{
|
||||
sprintf (tmp, "%lu", (unsigned long)stamp);
|
||||
send_status_info (ctrl, "SERIALNO",
|
||||
serial, strlen (serial),
|
||||
tmp, strlen (tmp),
|
||||
NULL, 0);
|
||||
xfree (serial);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
relptr = get_one_do (app->slot, table[idx].tag, &value, &valuelen);
|
||||
if (relptr)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user