mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-17 14:07:03 +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>
|
2004-10-06 Werner Koch <wk@g10code.de>
|
||||||
|
|
||||||
* ccid-driver.c (ccid_open_reader): Store the vendor ID.
|
* 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 change_force_chv:1;
|
||||||
unsigned int private_dos:1;
|
unsigned int private_dos:1;
|
||||||
} extcap;
|
} 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;
|
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. */
|
/* Note, that FPR must be at least 20 bytes. */
|
||||||
static int
|
static int
|
||||||
store_fpr (int slot, int keynumber, u32 timestamp,
|
store_fpr (int slot, int keynumber, u32 timestamp,
|
||||||
@ -479,7 +553,7 @@ store_fpr (int slot, int keynumber, u32 timestamp,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
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 number, const unsigned char *fpr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -502,7 +576,7 @@ send_fpr_if_not_null (CTRL ctrl, const char *keyword,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
const unsigned char *a, size_t alen)
|
||||||
{
|
{
|
||||||
char *p, *buf = xmalloc (alen*2+1);
|
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
|
/* Implement the GETATTR command. This is similar to the LEARN
|
||||||
command but returns just one value via the status interface. */
|
command but returns just one value via the status interface. */
|
||||||
static int
|
static int
|
||||||
do_getattr (APP app, CTRL ctrl, const char *name)
|
do_getattr (app_t app, ctrl_t ctrl, const char *name)
|
||||||
{
|
{
|
||||||
static struct {
|
static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -622,7 +696,7 @@ do_getattr (APP app, CTRL ctrl, const char *name)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
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, "EXTCAP");
|
||||||
do_getattr (app, ctrl, "DISP-NAME");
|
do_getattr (app, ctrl, "DISP-NAME");
|
||||||
@ -661,7 +735,7 @@ verify_chv2 (app_t app,
|
|||||||
|
|
||||||
if (strlen (pinvalue) < 6)
|
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);
|
" minimum length is %d\n"), 2, 6);
|
||||||
xfree (pinvalue);
|
xfree (pinvalue);
|
||||||
return gpg_error (GPG_ERR_BAD_PIN);
|
return gpg_error (GPG_ERR_BAD_PIN);
|
||||||
@ -698,7 +772,7 @@ verify_chv2 (app_t app,
|
|||||||
|
|
||||||
/* Verify CHV3 if required. */
|
/* Verify CHV3 if required. */
|
||||||
static int
|
static int
|
||||||
verify_chv3 (APP app,
|
verify_chv3 (app_t app,
|
||||||
int (*pincb)(void*, const char *, char **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg)
|
void *pincb_arg)
|
||||||
{
|
{
|
||||||
@ -780,7 +854,7 @@ verify_chv3 (APP app,
|
|||||||
/* Handle the SETATTR operation. All arguments are already basically
|
/* Handle the SETATTR operation. All arguments are already basically
|
||||||
checked. */
|
checked. */
|
||||||
static int
|
static int
|
||||||
do_setattr (APP app, const char *name,
|
do_setattr (app_t app, const char *name,
|
||||||
int (*pincb)(void*, const char *, char **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const unsigned char *value, size_t valuelen)
|
const unsigned char *value, size_t valuelen)
|
||||||
@ -793,7 +867,7 @@ do_setattr (APP app, const char *name,
|
|||||||
int special;
|
int special;
|
||||||
} table[] = {
|
} table[] = {
|
||||||
{ "DISP-NAME", 0x005B },
|
{ "DISP-NAME", 0x005B },
|
||||||
{ "LOGIN-DATA", 0x005E },
|
{ "LOGIN-DATA", 0x005E, 2 },
|
||||||
{ "DISP-LANG", 0x5F2D },
|
{ "DISP-LANG", 0x5F2D },
|
||||||
{ "DISP-SEX", 0x5F35 },
|
{ "DISP-SEX", 0x5F35 },
|
||||||
{ "PUBKEY-URL", 0x5F50 },
|
{ "PUBKEY-URL", 0x5F50 },
|
||||||
@ -824,6 +898,8 @@ do_setattr (APP app, const char *name,
|
|||||||
|
|
||||||
if (table[idx].special == 1)
|
if (table[idx].special == 1)
|
||||||
app->force_chv1 = (valuelen && *value == 0);
|
app->force_chv1 = (valuelen && *value == 0);
|
||||||
|
else if (table[idx].special == 2)
|
||||||
|
parse_login_data (app);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -831,7 +907,7 @@ do_setattr (APP app, const char *name,
|
|||||||
|
|
||||||
/* Handle the PASSWD command. */
|
/* Handle the PASSWD command. */
|
||||||
static int
|
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 **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg)
|
void *pincb_arg)
|
||||||
{
|
{
|
||||||
@ -918,7 +994,7 @@ do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
|
|||||||
|
|
||||||
/* Handle the GENKEY command. */
|
/* Handle the GENKEY command. */
|
||||||
static int
|
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 **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg)
|
void *pincb_arg)
|
||||||
{
|
{
|
||||||
@ -1060,7 +1136,7 @@ convert_sig_counter_value (const unsigned char *value, size_t valuelen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long
|
static unsigned long
|
||||||
get_sig_counter (APP app)
|
get_sig_counter (app_t app)
|
||||||
{
|
{
|
||||||
void *relptr;
|
void *relptr;
|
||||||
unsigned char *value;
|
unsigned char *value;
|
||||||
@ -1076,7 +1152,7 @@ get_sig_counter (APP app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
const unsigned char *fpr;
|
||||||
unsigned char *buffer;
|
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
|
known to gpg was not updated. If there is no fingerprint we
|
||||||
assume that this is okay. */
|
assume that this is okay. */
|
||||||
static int
|
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];
|
unsigned char tmp[20];
|
||||||
const char *s;
|
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
|
not match the one required for the requested action (e.g. the
|
||||||
serial number does not match). */
|
serial number does not match). */
|
||||||
static int
|
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 **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
@ -1222,20 +1298,20 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
|||||||
|
|
||||||
{
|
{
|
||||||
char *prompt;
|
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);
|
return gpg_error_from_errno (errno);
|
||||||
rc = pincb (pincb_arg, prompt, &pinvalue);
|
rc = pincb (pincb_arg, prompt, &pinvalue);
|
||||||
free (prompt);
|
free (prompt);
|
||||||
}
|
}
|
||||||
if (rc)
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen (pinvalue) < 6)
|
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);
|
" minimum length is %d\n"), 1, 6);
|
||||||
xfree (pinvalue);
|
xfree (pinvalue);
|
||||||
return gpg_error (GPG_ERR_BAD_PIN);
|
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
|
not match the one required for the requested action (e.g. the
|
||||||
serial number does not match). */
|
serial number does not match). */
|
||||||
static int
|
static int
|
||||||
do_auth (APP app, const char *keyidstr,
|
do_auth (app_t app, const char *keyidstr,
|
||||||
int (*pincb)(void*, const char *, char **),
|
int (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
@ -1341,7 +1417,7 @@ do_auth (APP app, const char *keyidstr,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_decipher (APP app, const char *keyidstr,
|
do_decipher (app_t app, const char *keyidstr,
|
||||||
int (pincb)(void*, const char *, char **),
|
int (pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
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
|
dangerous CHV3. KEYIDSTR is the usual card's serial number; an
|
||||||
optional fingerprint part will be ignored. */
|
optional fingerprint part will be ignored. */
|
||||||
static int
|
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 **),
|
int (pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg)
|
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
|
/* Select the OpenPGP application on the card in SLOT. This function
|
||||||
must be used before any other OpenPGP application functions. */
|
must be used before any other OpenPGP application functions. */
|
||||||
int
|
int
|
||||||
app_select_openpgp (APP app)
|
app_select_openpgp (app_t app)
|
||||||
{
|
{
|
||||||
static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
|
static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
|
||||||
int slot = app->slot;
|
int slot = app->slot;
|
||||||
@ -1503,8 +1579,8 @@ app_select_openpgp (APP app)
|
|||||||
relptr = get_one_do (app, 0x00C4, &buffer, &buflen);
|
relptr = get_one_do (app, 0x00C4, &buffer, &buflen);
|
||||||
if (!relptr)
|
if (!relptr)
|
||||||
{
|
{
|
||||||
log_error (_("can't access CHV Status Bytes "
|
log_error (_("can't access %s - invalid OpenPGP card?\n"),
|
||||||
"- invalid OpenPGP card?\n"));
|
"CHV Status Bytes");
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
app->force_chv1 = (buflen && *buffer == 0);
|
app->force_chv1 = (buflen && *buffer == 0);
|
||||||
@ -1513,8 +1589,8 @@ app_select_openpgp (APP app)
|
|||||||
relptr = get_one_do (app, 0x00C0, &buffer, &buflen);
|
relptr = get_one_do (app, 0x00C0, &buffer, &buflen);
|
||||||
if (!relptr)
|
if (!relptr)
|
||||||
{
|
{
|
||||||
log_error (_("can't access Extended Capability Flags - "
|
log_error (_("can't access %s - invalid OpenPGP card?\n"),
|
||||||
"invalid OpenPGP card?\n"));
|
"Extended Capability Flags" );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if (buflen)
|
if (buflen)
|
||||||
@ -1531,6 +1607,7 @@ app_select_openpgp (APP app)
|
|||||||
if (app->card_version <= 0x0100 && manufacturer == 1)
|
if (app->card_version <= 0x0100 && manufacturer == 1)
|
||||||
app->app_local->extcap.change_force_chv = 1;
|
app->app_local->extcap.change_force_chv = 1;
|
||||||
|
|
||||||
|
parse_login_data (app);
|
||||||
|
|
||||||
if (opt.verbose > 1)
|
if (opt.verbose > 1)
|
||||||
dump_all_do (slot);
|
dump_all_do (slot);
|
||||||
@ -1562,7 +1639,7 @@ leave:
|
|||||||
buffers or NULL if the data object is not available. All returned
|
buffers or NULL if the data object is not available. All returned
|
||||||
values are sanitized. */
|
values are sanitized. */
|
||||||
int
|
int
|
||||||
app_openpgp_cardinfo (APP app,
|
app_openpgp_cardinfo (app_t app,
|
||||||
char **serialno,
|
char **serialno,
|
||||||
char **disp_name,
|
char **disp_name,
|
||||||
char **pubkey_url,
|
char **pubkey_url,
|
||||||
@ -1644,7 +1721,7 @@ app_openpgp_cardinfo (APP app,
|
|||||||
|
|
||||||
|
|
||||||
/* This function is currently only used by the sc-copykeys program to
|
/* 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
|
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
|
for the SO PIN. TEMPLATE and TEMPLATE_LEN describe a buffer with
|
||||||
the key template to store. CREATED_AT is the timestamp used to
|
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
|
RSA public exponent. This function silently overwrites an existing
|
||||||
key.*/
|
key.*/
|
||||||
int
|
int
|
||||||
app_openpgp_storekey (APP app, int keyno,
|
app_openpgp_storekey (app_t app, int keyno,
|
||||||
unsigned char *template, size_t template_len,
|
unsigned char *template, size_t template_len,
|
||||||
time_t created_at,
|
time_t created_at,
|
||||||
const unsigned char *m, size_t mlen,
|
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
|
/* Utility function for external tools: Read the public RSA key at
|
||||||
KEYNO and return modulus and exponent in (M,MLEN) and (E,ELEN). */
|
KEYNO and return modulus and exponent in (M,MLEN) and (E,ELEN). */
|
||||||
int
|
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)
|
unsigned char **e, size_t *elen)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user