mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
scd: Allow KEYGRIP as KEYIDSTR.
* scd/app-openpgp.c (struct app_local_s): Add keygrip_str. (store_keygrip): New. (read_public_key): Call store_keygrip to hold keygrip. (get_public_key): Likewise. (send_keypair_info): Use stored keygrip_str. (check_keyidstr): Allow use of KEYGRIP. (do_check_pin): Allow use of KEYGRIP of signing slot. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
b0f0791e4a
commit
e769609cd3
@ -176,6 +176,7 @@ struct app_local_s {
|
|||||||
is usually only required for cross checks
|
is usually only required for cross checks
|
||||||
because the length of an S-expression is
|
because the length of an S-expression is
|
||||||
implicitly available. */
|
implicitly available. */
|
||||||
|
unsigned char keygrip_str[41]; /* The keygrip, null terminated */
|
||||||
} pk[3];
|
} pk[3];
|
||||||
|
|
||||||
unsigned char status_indicator; /* The card status indicator. */
|
unsigned char status_indicator; /* The card status indicator. */
|
||||||
@ -1575,6 +1576,23 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gpg_error_t
|
||||||
|
store_keygrip (app_t app, int keyno)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
unsigned char grip[20];
|
||||||
|
|
||||||
|
err = keygrip_from_canon_sexp (app->app_local->pk[keyno].key,
|
||||||
|
app->app_local->pk[keyno].keylen,
|
||||||
|
grip);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
bin2hex (grip, 20, app->app_local->pk[keyno].keygrip_str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse tag-length-value data for public key in BUFFER of BUFLEN
|
/* Parse tag-length-value data for public key in BUFFER of BUFLEN
|
||||||
length. Key of KEYNO in APP is updated with an S-expression of
|
length. Key of KEYNO in APP is updated with an S-expression of
|
||||||
public key. When CTRL is not NULL, fingerprint is computed with
|
public key. When CTRL is not NULL, fingerprint is computed with
|
||||||
@ -1626,6 +1644,8 @@ read_public_key (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
app->app_local->pk[keyno].key = keybuf;
|
app->app_local->pk[keyno].key = keybuf;
|
||||||
/* Decrement for trailing '\0' */
|
/* Decrement for trailing '\0' */
|
||||||
app->app_local->pk[keyno].keylen = len - 1;
|
app->app_local->pk[keyno].keylen = len - 1;
|
||||||
|
|
||||||
|
err = store_keygrip (app, keyno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -1773,11 +1793,13 @@ get_public_key (app_t app, int keyno)
|
|||||||
app->app_local->pk[keyno].key = (unsigned char*)keybuf;
|
app->app_local->pk[keyno].key = (unsigned char*)keybuf;
|
||||||
/* Decrement for trailing '\0' */
|
/* Decrement for trailing '\0' */
|
||||||
app->app_local->pk[keyno].keylen = len - 1;
|
app->app_local->pk[keyno].keylen = len - 1;
|
||||||
|
err = store_keygrip (app, keyno);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
/* Set a flag to indicate that we tried to read the key. */
|
/* Set a flag to indicate that we tried to read the key. */
|
||||||
app->app_local->pk[keyno].read_done = 1;
|
if (!err)
|
||||||
|
app->app_local->pk[keyno].read_done = 1;
|
||||||
|
|
||||||
xfree (buffer);
|
xfree (buffer);
|
||||||
return err;
|
return err;
|
||||||
@ -1796,8 +1818,6 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key)
|
|||||||
/* Note that GnuPG 1.x does not need this and it would be too time
|
/* Note that GnuPG 1.x does not need this and it would be too time
|
||||||
consuming to send it just for the fun of it. */
|
consuming to send it just for the fun of it. */
|
||||||
#if GNUPG_MAJOR_VERSION > 1
|
#if GNUPG_MAJOR_VERSION > 1
|
||||||
unsigned char grip[20];
|
|
||||||
char gripstr[41];
|
|
||||||
char idbuf[50];
|
char idbuf[50];
|
||||||
const char *usage;
|
const char *usage;
|
||||||
|
|
||||||
@ -1809,14 +1829,6 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key)
|
|||||||
if (!app->app_local->pk[keyno].key)
|
if (!app->app_local->pk[keyno].key)
|
||||||
goto leave; /* No such key - ignore. */
|
goto leave; /* No such key - ignore. */
|
||||||
|
|
||||||
err = keygrip_from_canon_sexp (app->app_local->pk[keyno].key,
|
|
||||||
app->app_local->pk[keyno].keylen,
|
|
||||||
grip);
|
|
||||||
if (err)
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
bin2hex (grip, 20, gripstr);
|
|
||||||
|
|
||||||
switch (keyno)
|
switch (keyno)
|
||||||
{
|
{
|
||||||
case 0: usage = "sc"; break;
|
case 0: usage = "sc"; break;
|
||||||
@ -1827,7 +1839,7 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key)
|
|||||||
|
|
||||||
sprintf (idbuf, "OPENPGP.%d", keyno+1);
|
sprintf (idbuf, "OPENPGP.%d", keyno+1);
|
||||||
send_status_info (ctrl, "KEYPAIRINFO",
|
send_status_info (ctrl, "KEYPAIRINFO",
|
||||||
gripstr, 40,
|
app->app_local->pk[keyno].keygrip_str, 40,
|
||||||
idbuf, strlen (idbuf),
|
idbuf, strlen (idbuf),
|
||||||
usage, strlen (usage),
|
usage, strlen (usage),
|
||||||
NULL, (size_t)0);
|
NULL, (size_t)0);
|
||||||
@ -4294,6 +4306,17 @@ check_against_given_fingerprint (app_t app, const char *fpr, int key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check KEYIDSTR, if it's valid.
|
||||||
|
When KEYNO is 0, it means it's for PIN check.
|
||||||
|
Otherwise, KEYNO corresponds to the slot (signing, decipher and auth).
|
||||||
|
KEYIDSTR is either:
|
||||||
|
(1) Serial number
|
||||||
|
(2) Serial number "/" fingerprint
|
||||||
|
(3) keygrip
|
||||||
|
|
||||||
|
When KEYNO is 0 and KEYIDSTR is for a keygrip, the keygrip should
|
||||||
|
be to be compared is the first one (keygrip for signing).
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
check_keyidstr (app_t app, const char *keyidstr, int keyno)
|
check_keyidstr (app_t app, const char *keyidstr, int keyno)
|
||||||
{
|
{
|
||||||
@ -4303,13 +4326,26 @@ check_keyidstr (app_t app, const char *keyidstr, int keyno)
|
|||||||
const char *fpr = NULL;
|
const char *fpr = NULL;
|
||||||
unsigned char tmp_sn[20]; /* Actually 16 bytes but also for the fpr. */
|
unsigned char tmp_sn[20]; /* Actually 16 bytes but also for the fpr. */
|
||||||
|
|
||||||
if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
|
if (strlen (keyidstr) < 32)
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
|
for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
|
||||||
;
|
;
|
||||||
if (n != 32)
|
|
||||||
|
/* Check if it's a keygrip */
|
||||||
|
if (n == 40)
|
||||||
|
{
|
||||||
|
const unsigned char *keygrip_str;
|
||||||
|
|
||||||
|
keygrip_str = app->app_local->pk[keyno?keyno-1:0].keygrip_str;
|
||||||
|
if (!strncmp (keygrip_str, keyidstr, 40))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n != 32 || strncmp (keyidstr, "D27600012401", 12))
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
else if (!*s)
|
else if (!*s)
|
||||||
; /* no fingerprint given: we allow this for now. */
|
; /* no fingerprint given: we allow this for now. */
|
||||||
@ -4864,7 +4900,8 @@ do_check_pin (app_t app, const char *keyidstr,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (strlen (keyidstr) >= 32+6 && !strcmp (keyidstr+32, "[CHV3]"))
|
if ((strlen (keyidstr) >= 32+6 && !strcmp (keyidstr+32, "[CHV3]"))
|
||||||
|
|| (strlen (keyidstr) >= 40+6 && !strcmp (keyidstr+40, "[CHV3]")))
|
||||||
admin_pin = 1;
|
admin_pin = 1;
|
||||||
|
|
||||||
/* Yes, there is a race conditions: The user might pull the card
|
/* Yes, there is a race conditions: The user might pull the card
|
||||||
|
Loading…
x
Reference in New Issue
Block a user