mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
(parse_login_data): New.
(app_select_openpgp): Call it. (do_setattr): Reparse it after change.
This commit is contained in:
parent
e1f3dc1c77
commit
2c31e2f853
@ -1,3 +1,9 @@
|
||||
2004-10-14 Werner Koch <wk@g10code.com>
|
||||
|
||||
* app-openpgp.c (parse_login_data): New.
|
||||
(app_select_openpgp): Call it.
|
||||
(do_setattr): Reparse it after change.
|
||||
|
||||
2004-10-06 Werner Koch <wk@g10code.de>
|
||||
|
||||
* ccid-driver.c (ccid_open_reader): Store the vendor ID.
|
||||
|
@ -101,6 +101,11 @@ struct app_local_s {
|
||||
unsigned int change_force_chv:1;
|
||||
unsigned int private_dos:1;
|
||||
} extcap;
|
||||
struct
|
||||
{
|
||||
unsigned int no_sync:1; /* Do not sync CHV1 and CHV2 */
|
||||
unsigned int def_chv2:1; /* Use 123456 for CHV2. */
|
||||
} flags;
|
||||
};
|
||||
|
||||
|
||||
@ -411,6 +416,75 @@ count_bits (const unsigned char *a, size_t len)
|
||||
return n;
|
||||
}
|
||||
|
||||
/* GnuPG makes special use of the login-data DO, this fucntion parses
|
||||
the login data to store the flags for later use. It may be called
|
||||
at any time and should be called after changing the login-data DO.
|
||||
|
||||
Everything up to a LF is considered a mailbox or account name. If
|
||||
the first LF is follewed by DC4 (0x14) control sequence are
|
||||
expected up to the next LF. Control sequences are separated by FS
|
||||
(0x28) and consist of key=value pairs. There is one key defined:
|
||||
|
||||
F=<flags>
|
||||
|
||||
Were FLAGS is a plain hexadecimal number representing flag values.
|
||||
The lsb is here the rightmost bit. Defined flags bits are:
|
||||
|
||||
Bit 0 = CHV1 and CHV2 are not syncronized
|
||||
Bit 1 = CHV2 has been been set to the default PIN of "123456"
|
||||
(this implies that bit 0 is also set).
|
||||
|
||||
*/
|
||||
static void
|
||||
parse_login_data (app_t app)
|
||||
{
|
||||
unsigned char *buffer, *p;
|
||||
size_t buflen, len;
|
||||
void *relptr;
|
||||
|
||||
/* Set defaults. */
|
||||
app->app_local->flags.no_sync = 0;
|
||||
app->app_local->flags.def_chv2 = 0;
|
||||
|
||||
/* Read the DO. */
|
||||
relptr = get_one_do (app, 0x005E, &buffer, &buflen);
|
||||
if (!relptr)
|
||||
return; /* Ooops. */
|
||||
for (; buflen; buflen--, buffer++)
|
||||
if (*buffer == '\n')
|
||||
break;
|
||||
if (buflen < 2 || buffer[1] != '\x14')
|
||||
return; /* No control sequences. */
|
||||
buflen--;
|
||||
buffer++;
|
||||
do
|
||||
{
|
||||
buflen--;
|
||||
buffer++;
|
||||
if (buflen > 1 && *buffer == 'F' && buffer[1] == '=')
|
||||
{
|
||||
/* Flags control sequence found. */
|
||||
int lastdig = 0;
|
||||
|
||||
/* For now we are only interested in the last digit, so skip
|
||||
any leading digits but bail out on invalid characters. */
|
||||
for (p=buffer+2, len = buflen-2; len && hexdigitp (p); p++, len--)
|
||||
lastdig = xtoi_1 (p);
|
||||
if (len && !(*p == '\n' || *p == '\x18'))
|
||||
goto next; /* Invalid characters in field. */
|
||||
app->app_local->flags.no_sync = !!(lastdig & 1);
|
||||
app->app_local->flags.def_chv2 = (lastdig & 3) == 3;
|
||||
}
|
||||
next:
|
||||
for (; buflen && *buffer != '\x18'; buflen--, buffer++)
|
||||
if (*buffer == '\n')
|
||||
buflen = 1;
|
||||
}
|
||||
while (buflen);
|
||||
|
||||
xfree (relptr);
|
||||
}
|
||||
|
||||
/* Note, that FPR must be at least 20 bytes. */
|
||||
static int
|
||||
store_fpr (int slot, int keynumber, u32 timestamp,
|
||||
@ -479,7 +553,7 @@ store_fpr (int slot, int keynumber, u32 timestamp,
|
||||
|
||||
|
||||
static void
|
||||
send_fpr_if_not_null (CTRL ctrl, const char *keyword,
|
||||
send_fpr_if_not_null (ctrl_t ctrl, const char *keyword,
|
||||
int number, const unsigned char *fpr)
|
||||
{
|
||||
int i;
|
||||
@ -502,7 +576,7 @@ send_fpr_if_not_null (CTRL ctrl, const char *keyword,
|
||||
}
|
||||
|
||||
static void
|
||||
send_key_data (CTRL ctrl, const char *name,
|
||||
send_key_data (ctrl_t ctrl, const char *name,
|
||||
const unsigned char *a, size_t alen)
|
||||
{
|
||||
char *p, *buf = xmalloc (alen*2+1);
|
||||
@ -520,7 +594,7 @@ send_key_data (CTRL ctrl, const char *name,
|
||||
/* Implement the GETATTR command. This is similar to the LEARN
|
||||
command but returns just one value via the status interface. */
|
||||
static int
|
||||
do_getattr (APP app, CTRL ctrl, const char *name)
|
||||
do_getattr (app_t app, ctrl_t ctrl, const char *name)
|
||||
{
|
||||
static struct {
|
||||
const char *name;
|
||||
@ -622,7 +696,7 @@ do_getattr (APP app, CTRL ctrl, const char *name)
|
||||
|
||||
|
||||
static int
|
||||
do_learn_status (APP app, CTRL ctrl)
|
||||
do_learn_status (app_t app, ctrl_t ctrl)
|
||||
{
|
||||
do_getattr (app, ctrl, "EXTCAP");
|
||||
do_getattr (app, ctrl, "DISP-NAME");
|
||||
@ -661,7 +735,7 @@ verify_chv2 (app_t app,
|
||||
|
||||
if (strlen (pinvalue) < 6)
|
||||
{
|
||||
log_error (_("prassphrase (CHV%d) is too short;"
|
||||
log_error (_("PIN for CHV%d is too short;"
|
||||
" minimum length is %d\n"), 2, 6);
|
||||
xfree (pinvalue);
|
||||
return gpg_error (GPG_ERR_BAD_PIN);
|
||||
@ -698,7 +772,7 @@ verify_chv2 (app_t app,
|
||||
|
||||
/* Verify CHV3 if required. */
|
||||
static int
|
||||
verify_chv3 (APP app,
|
||||
verify_chv3 (app_t app,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg)
|
||||
{
|
||||
@ -780,7 +854,7 @@ verify_chv3 (APP app,
|
||||
/* Handle the SETATTR operation. All arguments are already basically
|
||||
checked. */
|
||||
static int
|
||||
do_setattr (APP app, const char *name,
|
||||
do_setattr (app_t app, const char *name,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const unsigned char *value, size_t valuelen)
|
||||
@ -793,7 +867,7 @@ do_setattr (APP app, const char *name,
|
||||
int special;
|
||||
} table[] = {
|
||||
{ "DISP-NAME", 0x005B },
|
||||
{ "LOGIN-DATA", 0x005E },
|
||||
{ "LOGIN-DATA", 0x005E, 2 },
|
||||
{ "DISP-LANG", 0x5F2D },
|
||||
{ "DISP-SEX", 0x5F35 },
|
||||
{ "PUBKEY-URL", 0x5F50 },
|
||||
@ -824,6 +898,8 @@ do_setattr (APP app, const char *name,
|
||||
|
||||
if (table[idx].special == 1)
|
||||
app->force_chv1 = (valuelen && *value == 0);
|
||||
else if (table[idx].special == 2)
|
||||
parse_login_data (app);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -831,7 +907,7 @@ do_setattr (APP app, const char *name,
|
||||
|
||||
/* Handle the PASSWD command. */
|
||||
static int
|
||||
do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
|
||||
do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg)
|
||||
{
|
||||
@ -918,7 +994,7 @@ do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
|
||||
|
||||
/* Handle the GENKEY command. */
|
||||
static int
|
||||
do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg)
|
||||
{
|
||||
@ -1060,7 +1136,7 @@ convert_sig_counter_value (const unsigned char *value, size_t valuelen)
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
get_sig_counter (APP app)
|
||||
get_sig_counter (app_t app)
|
||||
{
|
||||
void *relptr;
|
||||
unsigned char *value;
|
||||
@ -1076,7 +1152,7 @@ get_sig_counter (APP app)
|
||||
}
|
||||
|
||||
static int
|
||||
compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr)
|
||||
compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
|
||||
{
|
||||
const unsigned char *fpr;
|
||||
unsigned char *buffer;
|
||||
@ -1116,7 +1192,7 @@ compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr)
|
||||
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)
|
||||
check_against_given_fingerprint (app_t app, const char *fpr, int keyno)
|
||||
{
|
||||
unsigned char tmp[20];
|
||||
const char *s;
|
||||
@ -1147,7 +1223,7 @@ check_against_given_fingerprint (APP app, const char *fpr, int keyno)
|
||||
not match the one required for the requested action (e.g. the
|
||||
serial number does not match). */
|
||||
static int
|
||||
do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
do_sign (app_t app, const char *keyidstr, int hashalgo,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
@ -1222,20 +1298,20 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
|
||||
{
|
||||
char *prompt;
|
||||
if (asprintf (&prompt, "PIN [sigs done: %lu]", sigcount) < 0)
|
||||
if (asprintf (&prompt, _("PIN [sigs done: %lu]"), sigcount) < 0)
|
||||
return gpg_error_from_errno (errno);
|
||||
rc = pincb (pincb_arg, prompt, &pinvalue);
|
||||
free (prompt);
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
|
||||
log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (strlen (pinvalue) < 6)
|
||||
{
|
||||
log_error (_("prassphrase (CHV%d) is too short;"
|
||||
log_error (_("PIN for CHV%d is too short;"
|
||||
" minimum length is %d\n"), 1, 6);
|
||||
xfree (pinvalue);
|
||||
return gpg_error (GPG_ERR_BAD_PIN);
|
||||
@ -1282,7 +1358,7 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
not match the one required for the requested action (e.g. the
|
||||
serial number does not match). */
|
||||
static int
|
||||
do_auth (APP app, const char *keyidstr,
|
||||
do_auth (app_t app, const char *keyidstr,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
@ -1341,7 +1417,7 @@ do_auth (APP app, const char *keyidstr,
|
||||
|
||||
|
||||
static int
|
||||
do_decipher (APP app, const char *keyidstr,
|
||||
do_decipher (app_t app, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
@ -1403,7 +1479,7 @@ do_decipher (APP app, const char *keyidstr,
|
||||
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,
|
||||
do_check_pin (app_t app, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg)
|
||||
{
|
||||
@ -1450,7 +1526,7 @@ do_check_pin (APP app, const char *keyidstr,
|
||||
/* Select the OpenPGP application on the card in SLOT. This function
|
||||
must be used before any other OpenPGP application functions. */
|
||||
int
|
||||
app_select_openpgp (APP app)
|
||||
app_select_openpgp (app_t app)
|
||||
{
|
||||
static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
|
||||
int slot = app->slot;
|
||||
@ -1503,8 +1579,8 @@ app_select_openpgp (APP app)
|
||||
relptr = get_one_do (app, 0x00C4, &buffer, &buflen);
|
||||
if (!relptr)
|
||||
{
|
||||
log_error (_("can't access CHV Status Bytes "
|
||||
"- invalid OpenPGP card?\n"));
|
||||
log_error (_("can't access %s - invalid OpenPGP card?\n"),
|
||||
"CHV Status Bytes");
|
||||
goto leave;
|
||||
}
|
||||
app->force_chv1 = (buflen && *buffer == 0);
|
||||
@ -1513,8 +1589,8 @@ app_select_openpgp (APP app)
|
||||
relptr = get_one_do (app, 0x00C0, &buffer, &buflen);
|
||||
if (!relptr)
|
||||
{
|
||||
log_error (_("can't access Extended Capability Flags - "
|
||||
"invalid OpenPGP card?\n"));
|
||||
log_error (_("can't access %s - invalid OpenPGP card?\n"),
|
||||
"Extended Capability Flags" );
|
||||
goto leave;
|
||||
}
|
||||
if (buflen)
|
||||
@ -1531,6 +1607,7 @@ app_select_openpgp (APP app)
|
||||
if (app->card_version <= 0x0100 && manufacturer == 1)
|
||||
app->app_local->extcap.change_force_chv = 1;
|
||||
|
||||
parse_login_data (app);
|
||||
|
||||
if (opt.verbose > 1)
|
||||
dump_all_do (slot);
|
||||
@ -1562,7 +1639,7 @@ leave:
|
||||
buffers or NULL if the data object is not available. All returned
|
||||
values are sanitized. */
|
||||
int
|
||||
app_openpgp_cardinfo (APP app,
|
||||
app_openpgp_cardinfo (app_t app,
|
||||
char **serialno,
|
||||
char **disp_name,
|
||||
char **pubkey_url,
|
||||
@ -1644,7 +1721,7 @@ app_openpgp_cardinfo (APP app,
|
||||
|
||||
|
||||
/* This function is currently only used by the sc-copykeys program to
|
||||
store a key on the smartcard. APP ist the application handle,
|
||||
store a key on the smartcard. app_t ist the application handle,
|
||||
KEYNO is the number of the key and PINCB, PINCB_ARG are used to ask
|
||||
for the SO PIN. TEMPLATE and TEMPLATE_LEN describe a buffer with
|
||||
the key template to store. CREATED_AT is the timestamp used to
|
||||
@ -1652,7 +1729,7 @@ app_openpgp_cardinfo (APP app,
|
||||
RSA public exponent. This function silently overwrites an existing
|
||||
key.*/
|
||||
int
|
||||
app_openpgp_storekey (APP app, int keyno,
|
||||
app_openpgp_storekey (app_t app, int keyno,
|
||||
unsigned char *template, size_t template_len,
|
||||
time_t created_at,
|
||||
const unsigned char *m, size_t mlen,
|
||||
@ -1697,7 +1774,7 @@ app_openpgp_storekey (APP app, int keyno,
|
||||
/* Utility function for external tools: Read the public RSA key at
|
||||
KEYNO and return modulus and exponent in (M,MLEN) and (E,ELEN). */
|
||||
int
|
||||
app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen,
|
||||
app_openpgp_readkey (app_t app, int keyno, unsigned char **m, size_t *mlen,
|
||||
unsigned char **e, size_t *elen)
|
||||
{
|
||||
int rc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user