mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
* passphrase.c (ask_passphrase): Add optional promptid arg.
Changed all callers. * cardglue.c (pin_cb): Use it here, so the machine interface can tell whether the Admin PIN is requested. * cardglue.c (agent_scd_checkpin): New. * misc.c (openpgp_pk_algo_usage): Added AUTH usage. * app-openpgp.c (check_against_given_fingerprint): New. Factored out that code elsewhere. (do_check_pin): New. * card-util.c (card_edit): New command "passwd". Add logic to check the PIN in advance. (card_status): Add new args to return the serial number. Changed all callers.
This commit is contained in:
parent
b194ed0e0a
commit
441aeb85f2
@ -1,3 +1,9 @@
|
|||||||
|
2003-10-21 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* configure.ac (PRINTABLE_OS_NAME): Remove special case for The
|
||||||
|
Hurd; Robert Millan reported that the uname test is now
|
||||||
|
sufficient.
|
||||||
|
|
||||||
2003-10-16 David Shaw <dshaw@jabberwocky.com>
|
2003-10-16 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* configure.ac: Include -ldl when card support is used.
|
* configure.ac: Include -ldl when card support is used.
|
||||||
|
@ -584,10 +584,6 @@ case "${target}" in
|
|||||||
*-linux*)
|
*-linux*)
|
||||||
PRINTABLE_OS_NAME="GNU/Linux"
|
PRINTABLE_OS_NAME="GNU/Linux"
|
||||||
;;
|
;;
|
||||||
dnl let that after linux to avoid gnu-linux problems
|
|
||||||
*-gnu*)
|
|
||||||
PRINTABLE_OS_NAME="GNU/Hurd"
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
PRINTABLE_OS_NAME=`uname -s || echo "Unknown"`
|
PRINTABLE_OS_NAME=`uname -s || echo "Unknown"`
|
||||||
;;
|
;;
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
|
2003-10-21 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* passphrase.c (ask_passphrase): Add optional promptid arg.
|
||||||
|
Changed all callers.
|
||||||
|
* cardglue.c (pin_cb): Use it here, so the machine interface can
|
||||||
|
tell whether the Admin PIN is requested.
|
||||||
|
|
||||||
|
* cardglue.c (agent_scd_checkpin): New.
|
||||||
|
|
||||||
|
* misc.c (openpgp_pk_algo_usage): Added AUTH usage.
|
||||||
|
|
||||||
|
* app-openpgp.c (check_against_given_fingerprint): New. Factored
|
||||||
|
out that code elsewhere.
|
||||||
|
(do_check_pin): New.
|
||||||
|
* card-util.c (card_edit): New command "passwd". Add logic to
|
||||||
|
check the PIN in advance.
|
||||||
|
(card_status): Add new args to return the serial number. Changed
|
||||||
|
all callers.
|
||||||
|
|
||||||
2003-10-14 David Shaw <dshaw@jabberwocky.com>
|
2003-10-14 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* import.c (import_one): Show the keyid when giving the Elgamal
|
* import.c (import_one): Show the keyid when giving the Elgamal
|
||||||
|
79
g10/apdu.c
79
g10/apdu.c
@ -51,6 +51,13 @@
|
|||||||
insertion of the card (1 = don't wait). */
|
insertion of the card (1 = don't wait). */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define DLSTDCALL __stdcall
|
||||||
|
#else
|
||||||
|
#define DLSTDCALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* A structure to collect information pertaining to one reader
|
/* A structure to collect information pertaining to one reader
|
||||||
slot. */
|
slot. */
|
||||||
struct reader_table_s {
|
struct reader_table_s {
|
||||||
@ -84,12 +91,12 @@ static struct reader_table_s reader_table[MAX_READER];
|
|||||||
|
|
||||||
|
|
||||||
/* ct API function pointer. */
|
/* ct API function pointer. */
|
||||||
static char (*CT_init) (unsigned short ctn, unsigned short Pn);
|
static char (* DLSTDCALL CT_init) (unsigned short ctn, unsigned short Pn);
|
||||||
static char (*CT_data) (unsigned short ctn, unsigned char *dad,
|
static char (* DLSTDCALL CT_data) (unsigned short ctn, unsigned char *dad,
|
||||||
unsigned char *sad, unsigned short lc,
|
unsigned char *sad, unsigned short lc,
|
||||||
unsigned char *cmd, unsigned short *lr,
|
unsigned char *cmd, unsigned short *lr,
|
||||||
unsigned char *rsp);
|
unsigned char *rsp);
|
||||||
static char (*CT_close) (unsigned short ctn);
|
static char (* DLSTDCALL CT_close) (unsigned short ctn);
|
||||||
|
|
||||||
/* PC/SC constants and function pointer. */
|
/* PC/SC constants and function pointer. */
|
||||||
#define PCSC_SCOPE_USER 0
|
#define PCSC_SCOPE_USER 0
|
||||||
@ -117,34 +124,38 @@ struct pcsc_io_request_s {
|
|||||||
|
|
||||||
typedef struct pcsc_io_request_s *pcsc_io_request_t;
|
typedef struct pcsc_io_request_s *pcsc_io_request_t;
|
||||||
|
|
||||||
long (*pcsc_establish_context) (unsigned long scope,
|
long (* DLSTDCALL pcsc_establish_context) (unsigned long scope,
|
||||||
const void *reserved1,
|
const void *reserved1,
|
||||||
const void *reserved2,
|
const void *reserved2,
|
||||||
unsigned long *r_context);
|
unsigned long *r_context);
|
||||||
long (*pcsc_release_context) (unsigned long context);
|
long (* DLSTDCALL pcsc_release_context) (unsigned long context);
|
||||||
long (*pcsc_list_readers) (unsigned long context, const char *groups,
|
long (* DLSTDCALL pcsc_list_readers) (unsigned long context,
|
||||||
char *readers, unsigned long *readerslen);
|
const char *groups,
|
||||||
long (*pcsc_connect) (unsigned long context,
|
char *readers, unsigned long*readerslen);
|
||||||
const char *reader,
|
long (* DLSTDCALL pcsc_connect) (unsigned long context,
|
||||||
unsigned long share_mode,
|
const char *reader,
|
||||||
unsigned long preferred_protocols,
|
unsigned long share_mode,
|
||||||
unsigned long *r_card,
|
unsigned long preferred_protocols,
|
||||||
unsigned long *r_active_protocol);
|
unsigned long *r_card,
|
||||||
long (*pcsc_disconnect) (unsigned long card, unsigned long disposition);
|
unsigned long *r_active_protocol);
|
||||||
long (*pcsc_status) (unsigned long card,
|
long (* DLSTDCALL pcsc_disconnect) (unsigned long card,
|
||||||
char *reader, unsigned long *readerlen,
|
unsigned long disposition);
|
||||||
unsigned long *r_state, unsigned long *r_protocol,
|
long (* DLSTDCALL pcsc_status) (unsigned long card,
|
||||||
unsigned char *atr, unsigned long *atrlen);
|
char *reader, unsigned long *readerlen,
|
||||||
long (*pcsc_begin_transaction) (unsigned long card);
|
unsigned long *r_state,
|
||||||
long (*pcsc_end_transaction) (unsigned long card);
|
unsigned long *r_protocol,
|
||||||
long (*pcsc_transmit) (unsigned long card,
|
unsigned char *atr, unsigned long *atrlen);
|
||||||
const pcsc_io_request_t send_pci,
|
long (* DLSTDCALL pcsc_begin_transaction) (unsigned long card);
|
||||||
const unsigned char *send_buffer,
|
long (* DLSTDCALL pcsc_end_transaction) (unsigned long card);
|
||||||
unsigned long send_len,
|
long (* DLSTDCALL pcsc_transmit) (unsigned long card,
|
||||||
pcsc_io_request_t recv_pci,
|
const pcsc_io_request_t send_pci,
|
||||||
unsigned char *recv_buffer,
|
const unsigned char *send_buffer,
|
||||||
unsigned long *recv_len);
|
unsigned long send_len,
|
||||||
long (*pcsc_set_timeout) (unsigned long context, unsigned long timeout);
|
pcsc_io_request_t recv_pci,
|
||||||
|
unsigned char *recv_buffer,
|
||||||
|
unsigned long *recv_len);
|
||||||
|
long (* DLSTDCALL pcsc_set_timeout) (unsigned long context,
|
||||||
|
unsigned long timeout);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ struct app_ctx_s {
|
|||||||
const char *chvnostr, int reset_mode,
|
const char *chvnostr, int reset_mode,
|
||||||
int (*pincb)(void*, const char *, char **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg);
|
void *pincb_arg);
|
||||||
|
int (*check_pin) (APP app, const char *keyidstr,
|
||||||
|
int (pincb)(void*, const char *, char **),
|
||||||
|
void *pincb_arg);
|
||||||
} fnc;
|
} fnc;
|
||||||
|
|
||||||
|
|
||||||
@ -106,6 +109,9 @@ int app_get_challenge (APP app, size_t nbytes, unsigned char *buffer);
|
|||||||
int app_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
|
int app_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
|
||||||
int (*pincb)(void*, const char *, char **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg);
|
void *pincb_arg);
|
||||||
|
int app_check_pin (APP app, const char *keyidstr,
|
||||||
|
int (*pincb)(void*, const char *, char **),
|
||||||
|
void *pincb_arg);
|
||||||
|
|
||||||
|
|
||||||
/*-- app-openpgp.c --*/
|
/*-- app-openpgp.c --*/
|
||||||
|
@ -912,6 +912,33 @@ compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If a fingerprint has been specified check it against the one on
|
||||||
|
the card. This is allows for a meaningful error message in case
|
||||||
|
the key on the card has been replaced but the shadow information
|
||||||
|
known to gpg was not updated. If there is no fingerprint we
|
||||||
|
assume that this is okay. */
|
||||||
|
static int
|
||||||
|
check_against_given_fingerprint (APP app, const char *fpr, int keyno)
|
||||||
|
{
|
||||||
|
unsigned char tmp[20];
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (s=fpr, n=0; hexdigitp (s); s++, n++)
|
||||||
|
;
|
||||||
|
if (n != 40)
|
||||||
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
|
else if (!*s)
|
||||||
|
; /* okay */
|
||||||
|
else
|
||||||
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
|
|
||||||
|
for (s=fpr, n=0; n < 20; s += 2, n++)
|
||||||
|
tmp[n] = xtoi_2 (s);
|
||||||
|
return compare_fingerprint (app, keyno, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Compute a digital signature on INDATA which is expected to be the
|
/* Compute a digital signature on INDATA which is expected to be the
|
||||||
raw message digest. For this application the KEYIDSTR consists of
|
raw message digest. For this application the KEYIDSTR consists of
|
||||||
@ -976,23 +1003,9 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
|||||||
known to gpg was not updated. If there is no fingerprint, gpg
|
known to gpg was not updated. If there is no fingerprint, gpg
|
||||||
will detect a bogus signature anyway due to the
|
will detect a bogus signature anyway due to the
|
||||||
verify-after-signing feature. */
|
verify-after-signing feature. */
|
||||||
if (fpr)
|
rc = fpr? check_against_given_fingerprint (app, fpr, 1) : 0;
|
||||||
{
|
if (rc)
|
||||||
for (s=fpr, n=0; hexdigitp (s); s++, n++)
|
return rc;
|
||||||
;
|
|
||||||
if (n != 40)
|
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
|
||||||
else if (!*s)
|
|
||||||
; /* okay */
|
|
||||||
else
|
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
|
||||||
|
|
||||||
for (s=fpr, n=0; n < 20; s += 2, n++)
|
|
||||||
tmp_sn[n] = xtoi_2 (s);
|
|
||||||
rc = compare_fingerprint (app, 1, tmp_sn);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hashalgo == GCRY_MD_SHA1)
|
if (hashalgo == GCRY_MD_SHA1)
|
||||||
memcpy (data, sha1_prefix, 15);
|
memcpy (data, sha1_prefix, 15);
|
||||||
@ -1107,23 +1120,9 @@ do_auth (APP app, const char *keyidstr,
|
|||||||
known to gpg was not updated. If there is no fingerprint, gpg
|
known to gpg was not updated. If there is no fingerprint, gpg
|
||||||
will detect a bogus signature anyway due to the
|
will detect a bogus signature anyway due to the
|
||||||
verify-after-signing feature. */
|
verify-after-signing feature. */
|
||||||
if (fpr)
|
rc = fpr? check_against_given_fingerprint (app, fpr, 3) : 0;
|
||||||
{
|
if (rc)
|
||||||
for (s=fpr, n=0; hexdigitp (s); s++, n++)
|
return rc;
|
||||||
;
|
|
||||||
if (n != 40)
|
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
|
||||||
else if (!*s)
|
|
||||||
; /* okay */
|
|
||||||
else
|
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
|
||||||
|
|
||||||
for (s=fpr, n=0; n < 20; s += 2, n++)
|
|
||||||
tmp_sn[n] = xtoi_2 (s);
|
|
||||||
rc = compare_fingerprint (app, 3, tmp_sn);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = verify_chv2 (app, pincb, pincb_arg);
|
rc = verify_chv2 (app, pincb, pincb_arg);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
@ -1177,23 +1176,9 @@ do_decipher (APP app, const char *keyidstr,
|
|||||||
the key on the card has been replaced but the shadow information
|
the key on the card has been replaced but the shadow information
|
||||||
known to gpg was not updated. If there is no fingerprint, the
|
known to gpg was not updated. If there is no fingerprint, the
|
||||||
decryption will won't produce the right plaintext anyway. */
|
decryption will won't produce the right plaintext anyway. */
|
||||||
if (fpr)
|
rc = fpr? check_against_given_fingerprint (app, fpr, 2) : 0;
|
||||||
{
|
if (rc)
|
||||||
for (s=fpr, n=0; hexdigitp (s); s++, n++)
|
return rc;
|
||||||
;
|
|
||||||
if (n != 40)
|
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
|
||||||
else if (!*s)
|
|
||||||
; /* okay */
|
|
||||||
else
|
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
|
||||||
|
|
||||||
for (s=fpr, n=0; n < 20; s += 2, n++)
|
|
||||||
tmp_sn[n] = xtoi_2 (s);
|
|
||||||
rc = compare_fingerprint (app, 2, tmp_sn);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = verify_chv2 (app, pincb, pincb_arg);
|
rc = verify_chv2 (app, pincb, pincb_arg);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
@ -1202,6 +1187,55 @@ do_decipher (APP app, const char *keyidstr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Perform a simple verify operation for CHV1 and CHV2, so that
|
||||||
|
further operations won't ask for CHV2 and it is possible to do a
|
||||||
|
cheap check on the PIN: If there is something wrong with the PIN
|
||||||
|
entry system, only the regular CHV will get blocked and not the
|
||||||
|
dangerous CHV3. KEYIDSTR is the usual card's serial number; an
|
||||||
|
optional fingerprint part will be ignored. */
|
||||||
|
static int
|
||||||
|
do_check_pin (APP app, const char *keyidstr,
|
||||||
|
int (pincb)(void*, const char *, char **),
|
||||||
|
void *pincb_arg)
|
||||||
|
{
|
||||||
|
unsigned char tmp_sn[20];
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (!keyidstr || !*keyidstr)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
/* Check whether an OpenPGP card of any version has been requested. */
|
||||||
|
if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
|
||||||
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
|
|
||||||
|
for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
|
||||||
|
;
|
||||||
|
if (n != 32)
|
||||||
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
|
else if (!*s)
|
||||||
|
; /* No fingerprint given: we allow this for now. */
|
||||||
|
else if (*s == '/')
|
||||||
|
; /* We ignore a fingerprint. */
|
||||||
|
else
|
||||||
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
|
|
||||||
|
for (s=keyidstr, n=0; n < 16; s += 2, n++)
|
||||||
|
tmp_sn[n] = xtoi_2 (s);
|
||||||
|
|
||||||
|
if (app->serialnolen != 16)
|
||||||
|
return gpg_error (GPG_ERR_INV_CARD);
|
||||||
|
if (memcmp (app->serialno, tmp_sn, 16))
|
||||||
|
return gpg_error (GPG_ERR_WRONG_CARD);
|
||||||
|
/* Yes, there is a race conditions: The user might pull the card
|
||||||
|
right here and we won't notice that. However this is not a
|
||||||
|
problem and the check above is merely for a graceful failure
|
||||||
|
between operations. */
|
||||||
|
|
||||||
|
return verify_chv2 (app, pincb, pincb_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Select the OpenPGP application on the card in SLOT. This function
|
/* Select the OpenPGP application on the card in SLOT. This function
|
||||||
@ -1262,6 +1296,7 @@ app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
|
|||||||
app->fnc.auth = do_auth;
|
app->fnc.auth = do_auth;
|
||||||
app->fnc.decipher = do_decipher;
|
app->fnc.decipher = do_decipher;
|
||||||
app->fnc.change_pin = do_change_pin;
|
app->fnc.change_pin = do_change_pin;
|
||||||
|
app->fnc.check_pin = do_check_pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
@ -255,13 +255,16 @@ fpr_is_zero (const char *fpr)
|
|||||||
|
|
||||||
/* Print all available information about the current card. */
|
/* Print all available information about the current card. */
|
||||||
void
|
void
|
||||||
card_status (FILE *fp)
|
card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||||
{
|
{
|
||||||
struct agent_card_info_s info;
|
struct agent_card_info_s info;
|
||||||
PKT_public_key *pk = xcalloc (1, sizeof *pk);
|
PKT_public_key *pk = xcalloc (1, sizeof *pk);
|
||||||
int rc;
|
int rc;
|
||||||
unsigned int uval;
|
unsigned int uval;
|
||||||
|
|
||||||
|
if (serialno && serialnobuflen)
|
||||||
|
*serialno = 0;
|
||||||
|
|
||||||
rc = agent_learn (&info);
|
rc = agent_learn (&info);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -289,6 +292,13 @@ card_status (FILE *fp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!serialno)
|
||||||
|
;
|
||||||
|
else if (strlen (serialno)+1 > serialnobuflen)
|
||||||
|
log_error ("serial number longer than expected\n");
|
||||||
|
else
|
||||||
|
strcpy (serialno, info.serialno);
|
||||||
|
|
||||||
if (opt.with_colons)
|
if (opt.with_colons)
|
||||||
fputs ("openpgp-card:\n", fp);
|
fputs ("openpgp-card:\n", fp);
|
||||||
|
|
||||||
@ -660,29 +670,33 @@ card_edit (STRLIST commands)
|
|||||||
cmdNOP = 0,
|
cmdNOP = 0,
|
||||||
cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
|
cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
|
||||||
cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
|
cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
|
||||||
cmdFORCESIG, cmdGENERATE,
|
cmdFORCESIG, cmdGENERATE, cmdPASSWD,
|
||||||
cmdINVCMD
|
cmdINVCMD
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
enum cmdids id;
|
enum cmdids id;
|
||||||
|
int requires_pin;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
} cmds[] = {
|
} cmds[] = {
|
||||||
{ N_("quit") , cmdQUIT , N_("quit this menu") },
|
{ N_("quit") , cmdQUIT , 0, N_("quit this menu") },
|
||||||
{ N_("q") , cmdQUIT , NULL },
|
{ N_("q") , cmdQUIT , 0, NULL },
|
||||||
{ N_("help") , cmdHELP , N_("show this help") },
|
{ N_("help") , cmdHELP , 0, N_("show this help") },
|
||||||
{ "?" , cmdHELP , NULL },
|
{ "?" , cmdHELP , 0, NULL },
|
||||||
{ N_("list") , cmdLIST , N_("list all available data") },
|
{ N_("list") , cmdLIST , 0, N_("list all available data") },
|
||||||
{ N_("l") , cmdLIST , NULL },
|
{ N_("l") , cmdLIST , 0, NULL },
|
||||||
{ N_("debug") , cmdDEBUG , NULL },
|
{ N_("debug") , cmdDEBUG , 0, NULL },
|
||||||
{ N_("name") , cmdNAME , N_("change card holder's name") },
|
{ N_("name") , cmdNAME , 1, N_("change card holder's name") },
|
||||||
{ N_("url") , cmdURL , N_("change URL to retrieve key") },
|
{ N_("url") , cmdURL , 1, N_("change URL to retrieve key") },
|
||||||
{ N_("login") , cmdLOGIN , N_("change the login name") },
|
{ N_("login") , cmdLOGIN , 1, N_("change the login name") },
|
||||||
{ N_("lang") , cmdLANG , N_("change the language preferences") },
|
{ N_("lang") , cmdLANG , 1, N_("change the language preferences") },
|
||||||
{ N_("sex") , cmdSEX , N_("change card holder's sex") },
|
{ N_("sex") , cmdSEX , 1, N_("change card holder's sex") },
|
||||||
{ N_("forcesig"), cmdFORCESIG, N_("toggle the signature force PIN flag") },
|
{ N_("forcesig"),
|
||||||
{ N_("generate"), cmdGENERATE, N_("generate new keys") },
|
cmdFORCESIG, 1, N_("toggle the signature force PIN flag") },
|
||||||
|
{ N_("generate"),
|
||||||
|
cmdGENERATE, 1, N_("generate new keys") },
|
||||||
|
{ N_("passwd"), cmdPASSWD, 0, N_("menu to change or unblock the PIN") },
|
||||||
{ NULL, cmdINVCMD }
|
{ NULL, cmdINVCMD }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -690,6 +704,9 @@ card_edit (STRLIST commands)
|
|||||||
int have_commands = !!commands;
|
int have_commands = !!commands;
|
||||||
int redisplay = 1;
|
int redisplay = 1;
|
||||||
char *answer = NULL;
|
char *answer = NULL;
|
||||||
|
int did_checkpin = 0;
|
||||||
|
char serialnobuf[50];
|
||||||
|
|
||||||
|
|
||||||
if (opt.command_fd != -1)
|
if (opt.command_fd != -1)
|
||||||
;
|
;
|
||||||
@ -705,18 +722,19 @@ card_edit (STRLIST commands)
|
|||||||
const char *arg_string = "";
|
const char *arg_string = "";
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
int requires_pin;
|
||||||
|
|
||||||
tty_printf("\n");
|
tty_printf("\n");
|
||||||
if (redisplay )
|
if (redisplay )
|
||||||
{
|
{
|
||||||
if (opt.with_colons)
|
if (opt.with_colons)
|
||||||
{
|
{
|
||||||
card_status (stdout);
|
card_status (stdout, serialnobuf, DIM (serialnobuf));
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
card_status (NULL);
|
card_status (NULL, serialnobuf, DIM (serialnobuf));
|
||||||
tty_printf("\n");
|
tty_printf("\n");
|
||||||
}
|
}
|
||||||
redisplay = 0;
|
redisplay = 0;
|
||||||
@ -750,6 +768,7 @@ card_edit (STRLIST commands)
|
|||||||
while( *answer == '#' );
|
while( *answer == '#' );
|
||||||
|
|
||||||
arg_number = 0; /* Yes, here is the init which egcc complains about */
|
arg_number = 0; /* Yes, here is the init which egcc complains about */
|
||||||
|
requires_pin = 0;
|
||||||
if (!*answer)
|
if (!*answer)
|
||||||
cmd = cmdLIST; /* Default to the list command */
|
cmd = cmdLIST; /* Default to the list command */
|
||||||
else if (*answer == CONTROL_D)
|
else if (*answer == CONTROL_D)
|
||||||
@ -769,7 +788,19 @@ card_edit (STRLIST commands)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
cmd = cmds[i].id;
|
cmd = cmds[i].id;
|
||||||
|
requires_pin = cmds[i].requires_pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requires_pin && !did_checkpin)
|
||||||
|
{
|
||||||
|
int rc = agent_scd_checkpin (serialnobuf);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
did_checkpin = 1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
@ -811,6 +842,11 @@ card_edit (STRLIST commands)
|
|||||||
generate_card_keys ();
|
generate_card_keys ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmdPASSWD:
|
||||||
|
change_pin (0);
|
||||||
|
did_checkpin = 0; /* Need to reset it of course. */
|
||||||
|
break;
|
||||||
|
|
||||||
case cmdQUIT:
|
case cmdQUIT:
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
@ -508,13 +508,16 @@ pin_cb (void *opaque, const char *info, char **retstr)
|
|||||||
{
|
{
|
||||||
char *value;
|
char *value;
|
||||||
int canceled;
|
int canceled;
|
||||||
|
int isadmin = (info && strstr (info, "dmin"));
|
||||||
|
|
||||||
|
|
||||||
*retstr = NULL;
|
*retstr = NULL;
|
||||||
log_debug ("asking for PIN '%s'\n", info);
|
log_debug ("asking for PIN '%s'\n", info);
|
||||||
|
|
||||||
value = ask_passphrase (info,
|
value = ask_passphrase (info,
|
||||||
info && strstr (info, "dmin")?
|
isadmin? "passphrase.adminpin.ask"
|
||||||
_("Enter Admin PIN: ") : _("Enter PIN: "),
|
: "passphrase.pin.ask",
|
||||||
|
isadmin? _("Enter Admin PIN: ") : _("Enter PIN: "),
|
||||||
&canceled);
|
&canceled);
|
||||||
if (!value && canceled)
|
if (!value && canceled)
|
||||||
return -1;
|
return -1;
|
||||||
@ -645,7 +648,6 @@ agent_scd_pkdecrypt (const char *serialno,
|
|||||||
const unsigned char *indata, size_t indatalen,
|
const unsigned char *indata, size_t indatalen,
|
||||||
unsigned char **r_buf, size_t *r_buflen)
|
unsigned char **r_buf, size_t *r_buflen)
|
||||||
{
|
{
|
||||||
|
|
||||||
APP app;
|
APP app;
|
||||||
|
|
||||||
*r_buf = NULL;
|
*r_buf = NULL;
|
||||||
@ -680,3 +682,18 @@ agent_scd_change_pin (int chvno)
|
|||||||
pin_cb, NULL);
|
pin_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perform a CHECKPIN operation. SERIALNO should be the seriial
|
||||||
|
number of the card - optioanlly followed by the fingerprint;
|
||||||
|
however the fingerprint is ignored here. */
|
||||||
|
int
|
||||||
|
agent_scd_checkpin (const char *serialnobuf)
|
||||||
|
{
|
||||||
|
APP app;
|
||||||
|
|
||||||
|
app = current_app? current_app : open_card ();
|
||||||
|
if (!app)
|
||||||
|
return gpg_error (GPG_ERR_CARD);
|
||||||
|
|
||||||
|
return app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -158,6 +158,10 @@ int agent_scd_pkdecrypt (const char *serialno,
|
|||||||
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
||||||
int agent_scd_change_pin (int chvno);
|
int agent_scd_change_pin (int chvno);
|
||||||
|
|
||||||
|
/* Send a CHECKPIN command. */
|
||||||
|
int agent_scd_checkpin (const char *serialnobuf);
|
||||||
|
|
||||||
|
|
||||||
#endif /*ENABLE_CARD_SUPPORT*/
|
#endif /*ENABLE_CARD_SUPPORT*/
|
||||||
#endif /*GNUPG_G10_CARDGLUE_H*/
|
#endif /*GNUPG_G10_CARDGLUE_H*/
|
||||||
|
|
||||||
|
@ -2914,7 +2914,7 @@ main( int argc, char **argv )
|
|||||||
case aCardStatus:
|
case aCardStatus:
|
||||||
if (argc)
|
if (argc)
|
||||||
wrong_args ("--card-status");
|
wrong_args ("--card-status");
|
||||||
card_status (stdout);
|
card_status (stdout, NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aCardEdit:
|
case aCardEdit:
|
||||||
|
@ -186,8 +186,8 @@ int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
|
|||||||
int have_static_passphrase(void);
|
int have_static_passphrase(void);
|
||||||
void read_passphrase_from_fd( int fd );
|
void read_passphrase_from_fd( int fd );
|
||||||
void passphrase_clear_cache ( u32 *keyid, int algo );
|
void passphrase_clear_cache ( u32 *keyid, int algo );
|
||||||
char *ask_passphrase (const char *description, const char *prompt,
|
char *ask_passphrase (const char *description, const char *promptid,
|
||||||
int *canceled);
|
const char *prompt, int *canceled);
|
||||||
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
|
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
|
||||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||||
const char *tryagain_text, int *canceled);
|
const char *tryagain_text, int *canceled);
|
||||||
|
@ -244,7 +244,7 @@ void unblock_all_signals(void);
|
|||||||
#ifdef ENABLE_CARD_SUPPORT
|
#ifdef ENABLE_CARD_SUPPORT
|
||||||
/*-- card-util.c --*/
|
/*-- card-util.c --*/
|
||||||
void change_pin (int no);
|
void change_pin (int no);
|
||||||
void card_status (FILE *fp);
|
void card_status (FILE *fp, char *serialno, size_t serialnobuflen);
|
||||||
void card_edit (STRLIST commands);
|
void card_edit (STRLIST commands);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ openpgp_pk_algo_usage ( int algo )
|
|||||||
/* they are hardwired in gpg 1.0 */
|
/* they are hardwired in gpg 1.0 */
|
||||||
switch ( algo ) {
|
switch ( algo ) {
|
||||||
case PUBKEY_ALGO_RSA:
|
case PUBKEY_ALGO_RSA:
|
||||||
use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
|
use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
|
||||||
break;
|
break;
|
||||||
case PUBKEY_ALGO_RSA_E:
|
case PUBKEY_ALGO_RSA_E:
|
||||||
use = PUBKEY_USAGE_ENC;
|
use = PUBKEY_USAGE_ENC;
|
||||||
@ -270,10 +270,10 @@ openpgp_pk_algo_usage ( int algo )
|
|||||||
use = PUBKEY_USAGE_ENC;
|
use = PUBKEY_USAGE_ENC;
|
||||||
break;
|
break;
|
||||||
case PUBKEY_ALGO_DSA:
|
case PUBKEY_ALGO_DSA:
|
||||||
use = PUBKEY_USAGE_SIG;
|
use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
|
||||||
break;
|
break;
|
||||||
case PUBKEY_ALGO_ELGAMAL:
|
case PUBKEY_ALGO_ELGAMAL:
|
||||||
use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
|
use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1007,7 +1007,9 @@ passphrase_clear_cache ( u32 *keyid, int algo )
|
|||||||
* Ask for a passphrase and return that string.
|
* Ask for a passphrase and return that string.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
ask_passphrase (const char *description, const char *prompt, int *canceled)
|
ask_passphrase (const char *description,
|
||||||
|
const char *promptid,
|
||||||
|
const char *prompt, int *canceled)
|
||||||
{
|
{
|
||||||
char *pw = NULL;
|
char *pw = NULL;
|
||||||
|
|
||||||
@ -1042,7 +1044,7 @@ ask_passphrase (const char *description, const char *prompt, int *canceled)
|
|||||||
pw = NULL;
|
pw = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pw = cpr_get_hidden("passphrase.ask",
|
pw = cpr_get_hidden(promptid? promptid : "passphrase.ask",
|
||||||
prompt?prompt : _("Enter passphrase: ") );
|
prompt?prompt : _("Enter passphrase: ") );
|
||||||
tty_kill_prompt();
|
tty_kill_prompt();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user