mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
card: Implement UID command and print capabilities.
* tools/card-call-scd.c (learn_status_cb): Return the full value for UIF. Add info about SM, MCL3, and PD. * tools/gpg-card.h (struct card_info_s): Add corresponding fields. * tools/gpg-card.c (list_openpgp): Print capabilities. Print the permanent flag for UIF. (cmd_uif): Implement. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
11f0700282
commit
c2a47475ba
@ -677,7 +677,10 @@ learn_status_cb (void *opaque, const char *line)
|
|||||||
|
|
||||||
log_assert (no >= 0 && no <= 2);
|
log_assert (no >= 0 && no <= 2);
|
||||||
data = unescape_status_string (line);
|
data = unescape_status_string (line);
|
||||||
parm->uif[no] = (data[0] != 0xff);
|
/* I am not sure why we test for 0xff but we better keep
|
||||||
|
* that in case of bogus card versions which did not
|
||||||
|
* initialize that DO correctly. */
|
||||||
|
parm->uif[no] = (data[0] == 0xff)? 0 : data[0];
|
||||||
xfree (data);
|
xfree (data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -692,6 +695,7 @@ learn_status_cb (void *opaque, const char *line)
|
|||||||
{
|
{
|
||||||
char *p, *p2, *buf;
|
char *p, *p2, *buf;
|
||||||
int abool;
|
int abool;
|
||||||
|
unsigned long number;
|
||||||
|
|
||||||
buf = p = unescape_status_string (line);
|
buf = p = unescape_status_string (line);
|
||||||
if (buf)
|
if (buf)
|
||||||
@ -713,6 +717,39 @@ learn_status_cb (void *opaque, const char *line)
|
|||||||
parm->extcap.kdf = abool;
|
parm->extcap.kdf = abool;
|
||||||
else if (!strcmp (p, "si"))
|
else if (!strcmp (p, "si"))
|
||||||
parm->status_indicator = strtoul (p2, NULL, 10);
|
parm->status_indicator = strtoul (p2, NULL, 10);
|
||||||
|
else if (!strcmp (p, "pd"))
|
||||||
|
parm->extcap.private_dos = abool;
|
||||||
|
else if (!strcmp (p, "mcl3"))
|
||||||
|
parm->extcap.mcl3 = strtoul (p2, NULL, 10);
|
||||||
|
else if (!strcmp (p, "sm"))
|
||||||
|
{
|
||||||
|
/* Unfortunately this uses OpenPGP algorithm
|
||||||
|
* ids so that we need to map them to Gcrypt
|
||||||
|
* ids. The mapping is limited to what
|
||||||
|
* OpenPGP cards support. Other cards
|
||||||
|
* should use a different tag than "sm". */
|
||||||
|
parm->extcap.sm = 1;
|
||||||
|
number = strtoul (p2, NULL, 10);
|
||||||
|
switch (number)
|
||||||
|
{
|
||||||
|
case CIPHER_ALGO_3DES:
|
||||||
|
parm->extcap.smalgo = GCRY_CIPHER_3DES;
|
||||||
|
break;
|
||||||
|
case CIPHER_ALGO_AES:
|
||||||
|
parm->extcap.smalgo = GCRY_CIPHER_AES;
|
||||||
|
break;
|
||||||
|
case CIPHER_ALGO_AES192:
|
||||||
|
parm->extcap.smalgo = GCRY_CIPHER_AES192;
|
||||||
|
break;
|
||||||
|
case CIPHER_ALGO_AES256:
|
||||||
|
parm->extcap.smalgo = GCRY_CIPHER_AES256;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown algorithm; dont claim SM support. */
|
||||||
|
parm->extcap.sm = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xfree (buf);
|
xfree (buf);
|
||||||
|
@ -839,6 +839,18 @@ list_openpgp (card_info_t info, estream_t fp, int no_key_lookup)
|
|||||||
tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
|
tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
|
||||||
info->chvinfo[0], info->chvinfo[1], info->chvinfo[2]);
|
info->chvinfo[0], info->chvinfo[1], info->chvinfo[2]);
|
||||||
tty_fprintf (fp, "Signature counter : %lu\n", info->sig_counter);
|
tty_fprintf (fp, "Signature counter : %lu\n", info->sig_counter);
|
||||||
|
tty_fprintf (fp, "Capabilities .....:");
|
||||||
|
if (info->extcap.ki)
|
||||||
|
tty_fprintf (fp, " key-import");
|
||||||
|
if (info->extcap.aac)
|
||||||
|
tty_fprintf (fp, " algo-change");
|
||||||
|
if (info->extcap.bt)
|
||||||
|
tty_fprintf (fp, " button");
|
||||||
|
if (info->extcap.sm)
|
||||||
|
tty_fprintf (fp, " sm(%s)", gcry_cipher_algo_name (info->extcap.smalgo));
|
||||||
|
if (info->extcap.private_dos)
|
||||||
|
tty_fprintf (fp, " priv-data");
|
||||||
|
tty_fprintf (fp, "\n");
|
||||||
if (info->extcap.kdf)
|
if (info->extcap.kdf)
|
||||||
{
|
{
|
||||||
tty_fprintf (fp, "KDF setting ......: %s\n",
|
tty_fprintf (fp, "KDF setting ......: %s\n",
|
||||||
@ -847,8 +859,9 @@ list_openpgp (card_info_t info, estream_t fp, int no_key_lookup)
|
|||||||
if (info->extcap.bt)
|
if (info->extcap.bt)
|
||||||
{
|
{
|
||||||
tty_fprintf (fp, "UIF setting ......: Sign=%s Decrypt=%s Auth=%s\n",
|
tty_fprintf (fp, "UIF setting ......: Sign=%s Decrypt=%s Auth=%s\n",
|
||||||
info->uif[0] ? "on" : "off", info->uif[1] ? "on" : "off",
|
info->uif[0] ? (info->uif[0]==2? "permanent": "on") : "off",
|
||||||
info->uif[2] ? "on" : "off");
|
info->uif[1] ? (info->uif[0]==2? "permanent": "on") : "off",
|
||||||
|
info->uif[2] ? (info->uif[0]==2? "permanent": "on") : "off");
|
||||||
}
|
}
|
||||||
|
|
||||||
list_all_kinfo (info, keyinfolabels, fp, no_key_lookup);
|
list_all_kinfo (info, keyinfolabels, fp, no_key_lookup);
|
||||||
@ -2956,6 +2969,10 @@ cmd_uif (card_info_t info, char *argstr)
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int keyno;
|
int keyno;
|
||||||
|
char name[50];
|
||||||
|
unsigned char data[2];
|
||||||
|
char *answer = NULL;
|
||||||
|
int opt_yes;
|
||||||
|
|
||||||
if (!info)
|
if (!info)
|
||||||
return print_help
|
return print_help
|
||||||
@ -2963,6 +2980,14 @@ cmd_uif (card_info_t info, char *argstr)
|
|||||||
"Change the User Interaction Flag. N must in the range 1 to 3.",
|
"Change the User Interaction Flag. N must in the range 1 to 3.",
|
||||||
APP_TYPE_OPENPGP, APP_TYPE_PIV, 0);
|
APP_TYPE_OPENPGP, APP_TYPE_PIV, 0);
|
||||||
|
|
||||||
|
if (!info->extcap.bt)
|
||||||
|
{
|
||||||
|
log_error (_("This command is not supported by this card\n"));
|
||||||
|
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_yes = has_leading_option (argstr, "--yes");
|
||||||
argstr = skip_options (argstr);
|
argstr = skip_options (argstr);
|
||||||
|
|
||||||
if (digitp (argstr))
|
if (digitp (argstr))
|
||||||
@ -2982,10 +3007,68 @@ cmd_uif (card_info_t info, char *argstr)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !strcmp (argstr, "off") )
|
||||||
|
data[0] = 0x00;
|
||||||
|
else if ( !strcmp (argstr, "on") )
|
||||||
|
data[0] = 0x01;
|
||||||
|
else if ( !strcmp (argstr, "permanent") )
|
||||||
|
data[0] = 0x02;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
data[1] = 0x20;
|
||||||
|
|
||||||
err = GPG_ERR_NOT_IMPLEMENTED;
|
|
||||||
|
log_assert (keyno - 1 < DIM(info->uif));
|
||||||
|
if (info->uif[keyno-1] == 2)
|
||||||
|
{
|
||||||
|
log_info (_("User Interaction Flag is set to \"%s\" - can't change\n"),
|
||||||
|
"permanent");
|
||||||
|
err = gpg_error (GPG_ERR_INV_STATE);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data[0] == 0x02)
|
||||||
|
{
|
||||||
|
if (opt.interactive)
|
||||||
|
{
|
||||||
|
tty_printf (_("Warning: Setting the User Interaction Flag to \"%s\"\n"
|
||||||
|
" can only be reverted using a factory reset!\n"
|
||||||
|
), "permanent");
|
||||||
|
answer = tty_get (_("Continue? (y/N) "));
|
||||||
|
tty_kill_prompt ();
|
||||||
|
if (*answer == CONTROL_D)
|
||||||
|
err = gpg_error (GPG_ERR_CANCELED);
|
||||||
|
else if (!answer_is_yes_no_default (answer, 0/*(default to No)*/))
|
||||||
|
err = gpg_error (GPG_ERR_CANCELED);
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
else if (!opt_yes)
|
||||||
|
{
|
||||||
|
log_info (_("Warning: Setting the User Interaction Flag to \"%s\"\n"
|
||||||
|
" can only be reverted using a factory reset!\n"
|
||||||
|
), "permanent");
|
||||||
|
log_info (_("Please use \"uif --yes %d %s\"\n"),
|
||||||
|
keyno, "permanent");
|
||||||
|
err = gpg_error (GPG_ERR_CANCELED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (name, sizeof name, "UIF-%d", keyno);
|
||||||
|
err = scd_setattr (name, data, 2);
|
||||||
|
if (!err) /* Read all UIF attributes again. */
|
||||||
|
err = scd_getattr ("UIF", info);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
xfree (answer);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,10 +175,15 @@ struct card_info_s
|
|||||||
unsigned int aac:1; /* Algorithm attributes are changeable. */
|
unsigned int aac:1; /* Algorithm attributes are changeable. */
|
||||||
unsigned int kdf:1; /* KDF object to support PIN hashing available. */
|
unsigned int kdf:1; /* KDF object to support PIN hashing available. */
|
||||||
unsigned int bt:1; /* Button for confirmation available. */
|
unsigned int bt:1; /* Button for confirmation available. */
|
||||||
|
unsigned int sm:1; /* Secure messaging available. */
|
||||||
|
unsigned int smalgo:15;/* Secure messaging cipher algorithm. */
|
||||||
|
unsigned int private_dos:1;/* Support fpr private use DOs. */
|
||||||
|
unsigned int mcl3:16; /* Max. length for a OpenPGP card cert.3 */
|
||||||
} extcap;
|
} extcap;
|
||||||
unsigned int status_indicator;
|
unsigned int status_indicator;
|
||||||
int kdf_do_enabled; /* True if card has a KDF object. */
|
int kdf_do_enabled; /* True if card has a KDF object. */
|
||||||
int uif[3]; /* True if User Interaction Flag is on. */
|
int uif[3]; /* True if User Interaction Flag is on. */
|
||||||
|
/* 1 = on, 2 = permanent on. */
|
||||||
};
|
};
|
||||||
typedef struct card_info_s *card_info_t;
|
typedef struct card_info_s *card_info_t;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user