1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-03-28 22:49:59 +01:00

scd: KEYNO cleanup.

* scd/app-openpgp.c (get_public_key, send_keypair_info, do_readkey)
(change_keyattr, change_keyattr_from_string, ecc_writekey, do_genkey)
(compare_fingerprint, check_against_given_fingerprint): KEYNO starts
from 0.
This commit is contained in:
NIIBE Yutaka 2015-09-07 13:09:01 +09:00
parent bd0c902f1d
commit fd689e8542

View File

@ -1224,7 +1224,7 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
the APP handle. On error that field gets cleared. If we already the APP handle. On error that field gets cleared. If we already
know about the public key we will just return. Note that this does know about the public key we will just return. Note that this does
not mean a key is available; this is soley indicated by the not mean a key is available; this is soley indicated by the
presence of the app->app_local->pk[KEYNO-1].key field. presence of the app->app_local->pk[KEYNO].key field.
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. However, given that we consuming to send it just for the fun of it. However, given that we
@ -1246,9 +1246,8 @@ get_public_key (app_t app, int keyno)
gcry_sexp_t s_pkey; gcry_sexp_t s_pkey;
size_t len; size_t len;
if (keyno < 1 || keyno > 3) if (keyno < 0 || keyno > 2)
return gpg_error (GPG_ERR_INV_ID); return gpg_error (GPG_ERR_INV_ID);
keyno--;
/* Already cached? */ /* Already cached? */
if (app->app_local->pk[keyno].read_done) if (app->app_local->pk[keyno].read_done)
@ -1475,11 +1474,12 @@ get_public_key (app_t app, int keyno)
/* Send the KEYPAIRINFO back. KEYNO needs to be in the range [1,3]. /* Send the KEYPAIRINFO back. KEY needs to be in the range [1,3].
This is used by the LEARN command. */ This is used by the LEARN command. */
static gpg_error_t static gpg_error_t
send_keypair_info (app_t app, ctrl_t ctrl, int keyno) send_keypair_info (app_t app, ctrl_t ctrl, int key)
{ {
int keyno = key - 1;
gpg_error_t err = 0; gpg_error_t err = 0;
/* 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. */
@ -1492,19 +1492,19 @@ send_keypair_info (app_t app, ctrl_t ctrl, int keyno)
if (err) if (err)
goto leave; goto leave;
assert (keyno >= 1 && keyno <= 3); assert (keyno >= 0 && keyno <= 2);
if (!app->app_local->pk[keyno-1].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-1].key, err = keygrip_from_canon_sexp (app->app_local->pk[keyno].key,
app->app_local->pk[keyno-1].keylen, app->app_local->pk[keyno].keylen,
grip); grip);
if (err) if (err)
goto leave; goto leave;
bin2hex (grip, 20, gripstr); bin2hex (grip, 20, gripstr);
sprintf (idbuf, "OPENPGP.%d", keyno); sprintf (idbuf, "OPENPGP.%d", keyno+1);
send_status_info (ctrl, "KEYPAIRINFO", send_status_info (ctrl, "KEYPAIRINFO",
gripstr, 40, gripstr, 40,
idbuf, strlen (idbuf), idbuf, strlen (idbuf),
@ -1567,11 +1567,11 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
unsigned char *buf; unsigned char *buf;
if (!strcmp (keyid, "OPENPGP.1")) if (!strcmp (keyid, "OPENPGP.1"))
keyno = 1; keyno = 0;
else if (!strcmp (keyid, "OPENPGP.2")) else if (!strcmp (keyid, "OPENPGP.2"))
keyno = 2; keyno = 1;
else if (!strcmp (keyid, "OPENPGP.3")) else if (!strcmp (keyid, "OPENPGP.3"))
keyno = 3; keyno = 2;
else else
return gpg_error (GPG_ERR_INV_ID); return gpg_error (GPG_ERR_INV_ID);
@ -1579,10 +1579,10 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
if (err) if (err)
return err; return err;
buf = app->app_local->pk[keyno-1].key; buf = app->app_local->pk[keyno].key;
if (!buf) if (!buf)
return gpg_error (GPG_ERR_NO_PUBKEY); return gpg_error (GPG_ERR_NO_PUBKEY);
*pklen = app->app_local->pk[keyno-1].keylen;; *pklen = app->app_local->pk[keyno].keylen;;
*pk = xtrymalloc (*pklen); *pk = xtrymalloc (*pklen);
if (!*pk) if (!*pk)
{ {
@ -2731,8 +2731,8 @@ change_keyattr (app_t app, int keyno, const unsigned char *buf, size_t buflen,
/* Helper to process an setattr command for name KEY-ATTR. /* Helper to process an setattr command for name KEY-ATTR.
In (VALUE,VALUELEN), it expects following string: In (VALUE,VALUELEN), it expects following string:
RSA: "--force <keyno> <algo> rsa<nbits>" RSA: "--force <key> <algo> rsa<nbits>"
ECC: "--force <keyno> <algo> <curvename>" ECC: "--force <key> <algo> <curvename>"
*/ */
static gpg_error_t static gpg_error_t
change_keyattr_from_string (app_t app, change_keyattr_from_string (app_t app,
@ -2742,7 +2742,7 @@ change_keyattr_from_string (app_t app,
{ {
gpg_error_t err = 0; gpg_error_t err = 0;
char *string; char *string;
int keyno, algo; int key, keyno, algo;
int n = 0; int n = 0;
/* VALUE is expected to be a string but not guaranteed to be /* VALUE is expected to be a string but not guaranteed to be
@ -2756,14 +2756,15 @@ change_keyattr_from_string (app_t app,
/* Because this function deletes the key we require the string /* Because this function deletes the key we require the string
"--force" in the data to make clear that something serious might "--force" in the data to make clear that something serious might
happen. */ happen. */
sscanf (string, " --force %d %d %n", &keyno, &algo, &n); sscanf (string, " --force %d %d %n", &key, &algo, &n);
if (n < 13) if (n < 13)
{ {
err = gpg_error (GPG_ERR_INV_DATA); err = gpg_error (GPG_ERR_INV_DATA);
goto leave; goto leave;
} }
if (keyno < 1 || keyno > 3) keyno = key - 1;
if (keyno < 0 || keyno > 2)
err = gpg_error (GPG_ERR_INV_ID); err = gpg_error (GPG_ERR_INV_ID);
else if (algo == PUBKEY_ALGO_RSA) else if (algo == PUBKEY_ALGO_RSA)
{ {
@ -2805,7 +2806,7 @@ change_keyattr_from_string (app_t app,
nbits = ((nbits + 31) / 32) * 32; nbits = ((nbits + 31) / 32) * 32;
buf[1] = (nbits >> 8); buf[1] = (nbits >> 8);
buf[2] = nbits; buf[2] = nbits;
err = change_keyattr (app, keyno-1, buf, buflen, pincb, pincb_arg); err = change_keyattr (app, keyno, buf, buflen, pincb, pincb_arg);
xfree (relptr); xfree (relptr);
} }
} }
@ -2813,29 +2814,29 @@ change_keyattr_from_string (app_t app,
|| algo == PUBKEY_ALGO_EDDSA) || algo == PUBKEY_ALGO_EDDSA)
{ {
const char *oidstr; const char *oidstr;
gcry_mpi_t oid;
const unsigned char *oidbuf;
size_t oid_len;
oidstr = openpgp_curve_to_oid (string+n, NULL); oidstr = openpgp_curve_to_oid (string+n, NULL);
if (!oidstr) if (!oidstr)
err = gpg_error (GPG_ERR_INV_DATA);
else
{ {
gcry_mpi_t m; err = gpg_error (GPG_ERR_INV_DATA);
goto leave;
err = openpgp_oid_from_str (oidstr, &m);
if (!err)
{
unsigned int len;
const unsigned char *buf = gcry_mpi_get_opaque (m, &len);
/* We have enough room at STRING. */
len = buf[0];
string[0] = algo;
memcpy (string+1, buf+1, len++);
err = change_keyattr (app, keyno-1, string, len,
pincb, pincb_arg);
gcry_mpi_release (m);
}
} }
err = openpgp_oid_from_str (oidstr, &oid);
if (err)
goto leave;
oidbuf = gcry_mpi_get_opaque (oid, &n);
oid_len = (n+7)/8;
/* We have enough room at STRING. */
string[0] = algo;
memcpy (string+1, oidbuf+1, oid_len-1);
err = change_keyattr (app, keyno, string, oid_len, pincb, pincb_arg);
gcry_mpi_release (oid);
} }
else else
err = gpg_error (GPG_ERR_PUBKEY_ALGO); err = gpg_error (GPG_ERR_PUBKEY_ALGO);
@ -3167,6 +3168,11 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
const char *oidstr = NULL; const char *oidstr = NULL;
int flag_djb_tweak = 0; int flag_djb_tweak = 0;
int algo; int algo;
gcry_mpi_t oid;
const unsigned char *oidbuf = NULL;
unsigned int n;
size_t oid_len;
unsigned char fprbuf[20];
/* (private-key(ecc(curve%s)(q%m)(d%m))(created-at%d)): /* (private-key(ecc(curve%s)(q%m)(d%m))(created-at%d)):
curve = "NIST P-256" */ curve = "NIST P-256" */
@ -3305,6 +3311,18 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
else else
algo = PUBKEY_ALGO_ECDSA; algo = PUBKEY_ALGO_ECDSA;
err = openpgp_oid_from_str (oidstr, &oid);
if (err)
goto leave;
oidbuf = gcry_mpi_get_opaque (oid, &n);
oid_len = (n+7)/8;
if (!oidbuf)
{
err = gpg_error_from_syserror ();
gcry_mpi_release (oid);
goto leave;
}
if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC
|| app->app_local->keyattr[keyno].ecc.oid != oidstr || app->app_local->keyattr[keyno].ecc.oid != oidstr
|| app->app_local->keyattr[keyno].ecc.flags != flag_djb_tweak) || app->app_local->keyattr[keyno].ecc.flags != flag_djb_tweak)
@ -3364,33 +3382,13 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
log_error (_("failed to store the key: %s\n"), gpg_strerror (err)); log_error (_("failed to store the key: %s\n"), gpg_strerror (err));
goto leave; goto leave;
} }
else
{
gcry_mpi_t oid;
const unsigned char *oidbuf;
unsigned int n;
size_t oid_len;
unsigned char fprbuf[20];
err = openpgp_oid_from_str (oidstr, &oid); err = store_fpr (app, keyno, created_at, fprbuf, algo, oidbuf, oid_len,
if (err) ecc_q, ecc_q_len, "\x03\x01\x08\x07", (size_t)4);
goto leave;
oidbuf = gcry_mpi_get_opaque (oid, &n);
oid_len = (n+7)/8;
if (!oidbuf)
{
err = gpg_error_from_syserror ();
gcry_mpi_release (oid);
goto leave;
}
err = store_fpr (app, keyno, created_at, fprbuf, algo,
oidbuf, oid_len, ecc_q, ecc_q_len,
"\x03\x01\x08\x07", (size_t)4);
gcry_mpi_release (oid);
}
leave: leave:
if (oidbuf)
gcry_mpi_release (oid);
return err; return err;
} }
@ -3486,16 +3484,15 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
unsigned char *buffer = NULL; unsigned char *buffer = NULL;
size_t buflen, keydatalen, mlen, elen; size_t buflen, keydatalen, mlen, elen;
time_t created_at; time_t created_at;
int keyno = atoi (keynostr); int keyno = atoi (keynostr) - 1;
int force = (flags & 1); int force = (flags & 1);
time_t start_at; time_t start_at;
int exmode; int exmode;
int le_value; int le_value;
unsigned int keybits; unsigned int keybits;
if (keyno < 1 || keyno > 3) if (keyno < 0 || keyno > 2)
return gpg_error (GPG_ERR_INV_ID); return gpg_error (GPG_ERR_INV_ID);
keyno--;
/* We flush the cache to increase the traffic before a key /* We flush the cache to increase the traffic before a key
generation. This _might_ help a card to gather more entropy. */ generation. This _might_ help a card to gather more entropy. */
@ -3645,7 +3642,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
size_t buflen, n; size_t buflen, n;
int rc, i; int rc, i;
assert (keyno >= 1 && keyno <= 3); assert (keyno >= 0 && keyno <= 2);
rc = get_cached_data (app, 0x006E, &buffer, &buflen, 0, 0); rc = get_cached_data (app, 0x006E, &buffer, &buflen, 0, 0);
if (rc) if (rc)
@ -3660,7 +3657,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
log_error (_("error reading fingerprint DO\n")); log_error (_("error reading fingerprint DO\n"));
return gpg_error (GPG_ERR_GENERAL); return gpg_error (GPG_ERR_GENERAL);
} }
fpr += (keyno-1)*20; fpr += keyno*20;
for (i=0; i < 20; i++) for (i=0; i < 20; i++)
if (sha1fpr[i] != fpr[i]) if (sha1fpr[i] != fpr[i])
{ {
@ -3679,7 +3676,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
gpg has not been updated. If there is no fingerprint we assume gpg has not been updated. If there is no fingerprint we assume
that this is okay. */ that this is okay. */
static gpg_error_t static gpg_error_t
check_against_given_fingerprint (app_t app, const char *fpr, int keyno) check_against_given_fingerprint (app_t app, const char *fpr, int key)
{ {
unsigned char tmp[20]; unsigned char tmp[20];
const char *s; const char *s;
@ -3696,7 +3693,7 @@ check_against_given_fingerprint (app_t app, const char *fpr, int keyno)
for (s=fpr, n=0; n < 20; s += 2, n++) for (s=fpr, n=0; n < 20; s += 2, n++)
tmp[n] = xtoi_2 (s); tmp[n] = xtoi_2 (s);
return compare_fingerprint (app, keyno, tmp); return compare_fingerprint (app, key-1, tmp);
} }