1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

* gpg.sgml: Document -K.

* g10.c: Make -K an alias for --list-secret-keys.

* keylist.c (print_card_serialno): New. Taken from gnupg 1.9.11.
(list_keyblock_print): Make use of it.
* keyedit.c (show_key_with_all_names): Print the card S/N.

* keyedit.c (keyedit_menu): New command ADDCARDKEY.
* card-util.c (card_generate_subkey): New.
* keygen.c (generate_card_subkeypair): New.
(gen_card_key): New arg IS_PRIMARY; changed all callers.

* cardglue.c (open_card): Use shutdown code if possible.
(check_card_serialno): Ditto.
This commit is contained in:
Werner Koch 2004-09-20 18:38:39 +00:00
parent 5576f6ef6c
commit 9d17a635c9
12 changed files with 356 additions and 14 deletions

View file

@ -1,5 +1,16 @@
2004-09-20 Werner Koch <wk@g10code.com>
* g10.c: Make -K an alias for --list-secret-keys.
* keylist.c (print_card_serialno): New. Taken from gnupg 1.9.11.
(list_keyblock_print): Make use of it.
* keyedit.c (show_key_with_all_names): Print the card S/N.
* keyedit.c (keyedit_menu): New command ADDCARDKEY.
* card-util.c (card_generate_subkey): New.
* keygen.c (generate_card_subkeypair): New.
(gen_card_key): New arg IS_PRIMARY; changed all callers.
* cardglue.c (open_card): Use shutdown code if possible.
(check_card_serialno): Ditto.

View file

@ -828,6 +828,120 @@ generate_card_keys (const char *serialno)
}
}
/* This fucntion is used by the key edit menu to generate an arbitrary
subkey. */
int
card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
{
struct agent_card_info_s info;
int okay = 0;
int forced_chv1 = 0;
int rc;
int keyno;
memset (&info, 0, sizeof info);
rc = agent_scd_getattr ("SERIALNO", &info);
if (rc || !info.serialno || strncmp (info.serialno, "D27600012401", 12)
|| strlen (info.serialno) != 32 )
{
log_error (_("cannot generate key: %s\n"),
rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
goto leave;
}
rc = agent_scd_getattr ("KEY-FPR", &info);
if (!rc)
rc = agent_scd_getattr ("CHV-STATUS", &info);
if (rc)
{
log_error ("error getting current key info: %s\n", gpg_strerror (rc));
goto leave;
}
tty_fprintf (NULL, "Signature key ....:");
print_sha1_fpr (NULL, info.fpr1valid? info.fpr1:NULL);
tty_fprintf (NULL, "Encryption key....:");
print_sha1_fpr (NULL, info.fpr2valid? info.fpr2:NULL);
tty_fprintf (NULL, "Authentication key:");
print_sha1_fpr (NULL, info.fpr3valid? info.fpr3:NULL);
tty_printf ("\n");
tty_printf (_("Please select the type of key to generate:\n"));
tty_printf (_(" (1) Signature key\n"));
tty_printf (_(" (2) Encryption key\n"));
tty_printf (_(" (3) Authentication key\n"));
for (;;)
{
char *answer = cpr_get ("cardedit.genkeys.subkeytype",
_("Your selection? "));
cpr_kill_prompt();
if (*answer == CONTROL_D)
{
xfree (answer);
goto leave;
}
keyno = *answer? atoi(answer): 0;
xfree(answer);
if (keyno >= 1 && keyno <= 3)
break; /* Okay. */
tty_printf(_("Invalid selection.\n"));
}
if ((keyno == 1 && info.fpr1valid)
|| (keyno == 2 && info.fpr2valid)
|| (keyno == 3 && info.fpr3valid))
{
tty_printf ("\n");
log_info ("WARNING: such a key has already been stored on the card!\n");
tty_printf ("\n");
if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
_("Replace existing key? ")))
goto leave;
}
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));
forced_chv1 = 0;
goto leave;
}
}
/* Check the PIN now, so that we won't get asked later for each
binding signature. */
rc = agent_scd_checkpin (info.serialno);
if (rc)
log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
else
okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
keyno, info.serialno);
leave:
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 okay;
}
}
return okay;
}
/* Menu to edit all user changeable values on an OpenPGP card. Only
Key creation is not handled here. */
void

View file

@ -812,8 +812,8 @@ agent_scd_change_pin (int chvno)
pin_cb, NULL);
}
/* Perform a CHECKPIN operation. SERIALNO should be the seriial
number of the card - optioanlly followed by the fingerprint;
/* Perform a CHECKPIN operation. SERIALNO should be the serial
number of the card - optionally followed by the fingerprint;
however the fingerprint is ignored here. */
int
agent_scd_checkpin (const char *serialnobuf)

View file

@ -80,6 +80,7 @@ enum cmd_and_opt_values
oVerbose = 'v',
oCompress = 'z',
oSetNotation = 'N',
aListSecretKeys = 'K',
oBatch = 500,
oMaxOutput,
oSigNotation,
@ -114,7 +115,6 @@ enum cmd_and_opt_values
aVerifyFiles,
aListKeys,
aListSigs,
aListSecretKeys,
aSendKeys,
aRecvKeys,
aSearchKeys,

View file

@ -1191,6 +1191,7 @@ keyedit_menu( const char *username, STRLIST locusr,
cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
cmdADDCARDKEY,
cmdNOP };
static struct { const char *name;
enum cmdids id;
@ -1223,6 +1224,7 @@ keyedit_menu( const char *username, STRLIST locusr,
/* delphoto is really deluid in disguise */
{ N_("delphoto"), cmdDELUID , 0,1, NULL },
{ N_("addkey") , cmdADDKEY , 1,1, N_("add a secondary key") },
{ N_("addcardkey"), cmdADDCARDKEY , 1,1, N_("add a key to a smartcard") },
{ N_("delkey") , cmdDELKEY , 0,1, N_("delete a secondary key") },
{ N_("addrevoker"),cmdADDREVOKER,1,1, N_("add a revocation key") },
{ N_("delsig") , cmdDELSIG , 0,1, N_("delete signatures") },
@ -1530,6 +1532,16 @@ keyedit_menu( const char *username, STRLIST locusr,
}
break;
#ifdef ENABLE_CARD_SUPPORT
case cmdADDCARDKEY:
if (card_generate_subkey (keyblock, sec_keyblock)) {
redisplay = 1;
sec_modified = modified = 1;
merge_keys_and_selfsig( sec_keyblock );
merge_keys_and_selfsig( keyblock );
}
break;
#endif /* ENABLE_CARD_SUPPORT */
case cmdDELKEY: {
int n1;
@ -2210,6 +2222,27 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
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");
}
}
else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
&& node->pkt->pkt.signature->sig_class == 0x28 ) {
@ -2555,7 +2588,7 @@ menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
/****************
* Remove all selceted userids from the keyrings
* Remove all selected userids from the keyrings
*/
static void
menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )

View file

@ -117,7 +117,8 @@ 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 out, KBNODE node );
static int gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root,
static int gen_card_key (int algo, int keyno, int is_primary,
KBNODE pub_root, KBNODE sec_root,
u32 expireval, struct para_data_s *para);
static void
@ -2481,7 +2482,7 @@ do_generate_keypair( struct para_data_s *para,
}
else
{
rc = gen_card_key (PUBKEY_ALGO_RSA, 1, pub_root, sec_root,
rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root,
get_parameter_u32 (para, pKEYEXPIRE), para);
if (!rc)
{
@ -2523,7 +2524,7 @@ do_generate_keypair( struct para_data_s *para,
}
else
{
rc = gen_card_key (PUBKEY_ALGO_RSA, 2, pub_root, sec_root,
rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root,
get_parameter_u32 (para, pKEYEXPIRE), para);
}
@ -2538,7 +2539,7 @@ do_generate_keypair( struct para_data_s *para,
if (card && get_parameter (para, pAUTHKEYTYPE))
{
rc = gen_card_key (PUBKEY_ALGO_RSA, 3, pub_root, sec_root,
rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root,
get_parameter_u32 (para, pKEYEXPIRE), para);
if (!rc)
@ -2768,6 +2769,120 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
return okay;
}
#ifdef ENABLE_CARD_SUPPORT
/* Generate a subkey on a card. */
int
generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
int keyno, const char *serialno)
{
int okay=0, rc=0;
KBNODE node;
PKT_secret_key *pri_sk = NULL;
int algo;
unsigned int use;
u32 expire;
char *passphrase = NULL;
u32 cur_time;
struct para_data_s *para = NULL;
assert (keyno >= 1 && keyno <= 3);
para = xcalloc (1, sizeof *para + strlen (serialno) );
para->key = pSERIALNO;
strcpy (para->u.value, serialno);
/* Break out the primary secret key */
node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
if(!node)
{
log_error("Oops; secret key not found anymore!\n");
goto leave;
}
/* Make a copy of the sk to keep the protected one in the keyblock */
pri_sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
cur_time = make_timestamp();
if (pri_sk->timestamp > cur_time)
{
ulong d = pri_sk->timestamp - cur_time;
log_info (d==1 ? _("key has been created %lu second "
"in future (time warp or clock problem)\n")
: _("key has been created %lu seconds "
"in future (time warp or clock problem)\n"), d );
if (!opt.ignore_time_conflict)
{
rc = G10ERR_TIME_CONFLICT;
goto leave;
}
}
if (pri_sk->version < 4)
{
log_info (_("NOTE: creating subkeys for v3 keys "
"is not OpenPGP compliant\n"));
goto leave;
}
/* Unprotect to get the passphrase. */
switch( is_secret_key_protected (pri_sk) )
{
case -1:
rc = G10ERR_PUBKEY_ALGO;
break;
case 0:
tty_printf("This key is not protected.\n");
break;
default:
tty_printf("Key is protected.\n");
rc = check_secret_key( pri_sk, 0 );
if (!rc)
passphrase = get_last_passphrase();
break;
}
if (rc)
goto leave;
algo = PUBKEY_ALGO_RSA;
expire = ask_expire_interval (0);
if (keyno == 1)
use = PUBKEY_USAGE_SIG;
else if (keyno == 2)
use = PUBKEY_USAGE_ENC;
else
use = PUBKEY_USAGE_AUTH;
if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.cardsub.okay",
_("Really create? ") ) )
goto leave;
if (passphrase)
set_next_passphrase (passphrase);
rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock, expire, para);
if (!rc)
rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, NULL, use);
if (!rc)
rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, NULL, use);
if (!rc)
{
okay = 1;
write_status_text (STATUS_KEY_CREATED, "S");
}
leave:
if (rc)
log_error (_("Key generation failed: %s\n"), g10_errstr(rc) );
m_free (passphrase);
/* Release the copy of the (now unprotected) secret keys. */
if (pri_sk)
free_secret_key (pri_sk);
set_next_passphrase( NULL );
release_parameter_list (para);
return okay;
}
#endif /* !ENABLE_CARD_SUPPORT */
/****************
* Write a keyblock to an output stream
*/
@ -2787,7 +2902,8 @@ write_keyblock( IOBUF out, KBNODE node )
static int
gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root,
gen_card_key (int algo, int keyno, int is_primary,
KBNODE pub_root, KBNODE sec_root,
u32 expireval, struct para_data_s *para)
{
#ifdef ENABLE_CARD_SUPPORT
@ -2848,12 +2964,12 @@ gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root,
}
pkt = xcalloc (1,sizeof *pkt);
pkt->pkttype = keyno == 1 ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
pkt->pkt.public_key = pk;
add_kbnode(pub_root, new_kbnode( pkt ));
pkt = xcalloc (1,sizeof *pkt);
pkt->pkttype = keyno == 1 ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
pkt->pkttype = is_primary ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
pkt->pkt.secret_key = sk;
add_kbnode(sec_root, new_kbnode( pkt ));

View file

@ -41,6 +41,7 @@
static void list_all(int);
static void list_one( STRLIST names, int secret);
static void print_card_serialno (PKT_secret_key *sk);
struct sig_stats
{
@ -752,6 +753,7 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
if( !any ) {
if( fpr )
print_fingerprint( pk, sk, 0 );
print_card_serialno (sk);
if( opt.with_key_data )
print_key_data( pk );
any = 1;
@ -805,6 +807,7 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
putchar('\n');
if( fpr )
print_fingerprint( pk, sk, 0 ); /* of the main key */
print_card_serialno (sk);
any = 1;
}
@ -817,7 +820,10 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
printf(_(" [expires: %s]"), expirestr_from_sk( sk2 ) );
putchar('\n');
if( fpr > 1 )
print_fingerprint( NULL, sk2, 0 );
{
print_fingerprint( NULL, sk2, 0 );
print_card_serialno (sk2);
}
}
else if( opt.list_sigs
&& node->pkt->pkttype == PKT_SIGNATURE
@ -861,6 +867,7 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
putchar('\n');
if( fpr )
print_fingerprint( pk, sk, 0 );
print_card_serialno (sk);
any=1;
}
@ -1475,6 +1482,41 @@ print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode )
tty_printf ("\n");
}
/* Print the serial number of an OpenPGP card if available. */
static void
print_card_serialno (PKT_secret_key *sk)
{
int i;
if (!sk)
return;
if (!sk->is_protected || sk->protect.s2k.mode != 1002)
return; /* Not a card. */
if (opt.with_colons)
return; /* Handled elesewhere. */
fputs (_(" Card serial no. ="), stdout);
putchar (' ');
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)
putchar (' ');
printf ("%02X", sk->protect.iv[i]);
}
}
else
{ /* Something is wrong: Print all. */
for (i=0; i < sk->protect.ivlen; i++)
printf ("%02X", sk->protect.iv[i]);
}
putchar ('\n');
}
void set_attrib_fd(int fd)
{
static int last_fd=-1;

View file

@ -162,6 +162,10 @@ int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
int keygen_add_revkey(PKT_signature *sig, void *opaque);
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
#ifdef ENABLE_CARD_SUPPORT
int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
int keyno, const char *serialno);
#endif
/*-- openfile.c --*/
int overwrite_filep( const char *fname );
@ -257,6 +261,7 @@ void unblock_all_signals(void);
void change_pin (int no);
void card_status (FILE *fp, char *serialno, size_t serialnobuflen);
void card_edit (STRLIST commands);
int card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
#endif
#endif /*G10_MAIN_H*/