1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-12 13:16:57 +01:00

scd:nks: Factor out iteration over filelist.

* scd/app-nks.c (iterate_over_filelist): New.
(do_with_keygrip): Use iterate_over_filelist.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
(cherry picked from commit 6c4365847666cefac73ccc743a99fac473da2186)
This commit is contained in:
NIIBE Yutaka 2020-12-10 10:05:38 +09:00 committed by Werner Koch
parent c9eb4c0632
commit ea7234d2f5
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -1022,6 +1022,105 @@ readcert_from_ef (app_t app, int fid, unsigned char **cert, size_t *certlen)
} }
/*
* Iterate over FILELIST, supporting two use cases:
*
* (1) With WANT_KEYGRIPSTR=<GRIP>, finding matching entry.
* (2) With WANT_KEYGRIPSTR=NULL, listing entries
* by CAPABILITY (possibly == 0, for all entries).
*
* Caller supplies an array KEYGRIPSTR.
* Caller should start *IDX_P == -1, and keep the index value in IDX_P.
*
* Returns 0 on success, otherwise returns error value.
*
* When all entries are tried, returns GPG_ERR_NOT_FOUND for the use
* case of (1). Returns GPG_ERR_TRUE for the use case of (2).
*/
static gpg_error_t
iterate_over_filelist (app_t app, const char *want_keygripstr, int capability,
char keygripstr[2*KEYGRIP_LEN+1], int *idx_p)
{
gpg_error_t err;
int idx = *idx_p;
for (idx++; filelist[idx].fid; idx++)
{
if (filelist[idx].nks_ver > app->appversion)
continue;
if (!filelist[idx].iskeypair)
continue;
if (app->app_local->only_idlm)
{
if (filelist[idx].nks_app_id != NKS_APP_IDLM)
continue;
}
else
{
if (filelist[idx].nks_app_id != NKS_APP_NKS
&& filelist[idx].nks_app_id != app->app_local->qes_app_id)
continue;
err = switch_application (app, filelist[idx].nks_app_id);
if (err)
{
*idx_p = idx;
return err;
}
}
err = keygripstr_from_pk_file (app, filelist[idx].fid,
filelist[idx].iskeypair, keygripstr,
NULL, NULL);
if (err)
{
log_error ("can't get keygrip from FID 0x%04X: %s\n",
filelist[idx].fid, gpg_strerror (err));
continue;
}
if (want_keygripstr)
{
if (!strcmp (keygripstr, want_keygripstr))
{
/* Found */
*idx_p = idx;
return 0;
}
}
else
{
if (capability == GCRY_PK_USAGE_SIGN)
{
if (!filelist[idx].issignkey)
continue;
}
if (capability == GCRY_PK_USAGE_ENCR)
{
if (!filelist[idx].isencrkey)
continue;
}
if (capability == GCRY_PK_USAGE_AUTH)
{
if (!filelist[idx].isauthkey)
continue;
}
/* Found */
*idx_p = idx;
return 0;
}
}
if (!want_keygripstr)
err = gpg_error (GPG_ERR_TRUE);
else
err = gpg_error (GPG_ERR_NOT_FOUND);
return err;
}
/* Read the certificate with id CERTID (as returned by learn_status in /* Read the certificate with id CERTID (as returned by learn_status in
the CERTINFO status lines) and return it in the freshly allocated the CERTINFO status lines) and return it in the freshly allocated
buffer put into CERT and the length of the certificate put into buffer put into CERT and the length of the certificate put into
@ -2050,10 +2149,8 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
gpg_error_t err; gpg_error_t err;
char keygripstr[2*KEYGRIP_LEN+1]; char keygripstr[2*KEYGRIP_LEN+1];
char *serialno = NULL; char *serialno = NULL;
char idbuf[20];
int data = 0; int data = 0;
int idx; int idx = -1;
const char *tagstr;
/* First a quick check for valid parameters. */ /* First a quick check for valid parameters. */
switch (action) switch (action)
@ -2061,8 +2158,7 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
case KEYGRIP_ACTION_LOOKUP: case KEYGRIP_ACTION_LOOKUP:
if (!want_keygripstr) if (!want_keygripstr)
{ {
err = gpg_error (GPG_ERR_NOT_FOUND); return gpg_error (GPG_ERR_NOT_FOUND);
goto leave;
} }
break; break;
case KEYGRIP_ACTION_SEND_DATA: case KEYGRIP_ACTION_SEND_DATA:
@ -2071,8 +2167,7 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
case KEYGRIP_ACTION_WRITE_STATUS: case KEYGRIP_ACTION_WRITE_STATUS:
break; break;
default: default:
err = gpg_error (GPG_ERR_INV_ARG); return gpg_error (GPG_ERR_INV_ARG);
goto leave;
} }
/* Allocate the S/N string if needed. */ /* Allocate the S/N string if needed. */
@ -2080,70 +2175,25 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
{ {
serialno = app_get_serialno (app); serialno = app_get_serialno (app);
if (!serialno) if (!serialno)
{ return gpg_error_from_syserror ();
err = gpg_error_from_syserror ();
goto leave;
}
} }
for (idx=0; filelist[idx].fid; idx++) while (1)
{ {
if (filelist[idx].nks_ver > app->appversion) err = iterate_over_filelist (app, want_keygripstr, capability,
continue; keygripstr, &idx);
if (err)
break;
if (!filelist[idx].iskeypair) if (want_keygripstr)
continue;
if (app->app_local->only_idlm)
{ {
if (filelist[idx].nks_app_id != NKS_APP_IDLM) if (!err)
continue; break;
} }
else else
{ {
if (filelist[idx].nks_app_id != NKS_APP_NKS char idbuf[20];
&& filelist[idx].nks_app_id != app->app_local->qes_app_id) const char *tagstr;
continue;
err = switch_application (app, filelist[idx].nks_app_id);
if (err)
goto leave;
}
err = keygripstr_from_pk_file (app, filelist[idx].fid,
filelist[idx].iskeypair, keygripstr,
NULL, NULL);
if (err)
{
log_error ("can't get keygrip from FID 0x%04X: %s\n",
filelist[idx].fid, gpg_strerror (err));
continue;
}
if (action == KEYGRIP_ACTION_LOOKUP)
{
if (!strcmp (keygripstr, want_keygripstr))
{
err = 0; /* Found */
goto leave;
}
}
else if (!want_keygripstr || !strcmp (keygripstr, want_keygripstr))
{
if (capability == GCRY_PK_USAGE_SIGN)
{
if (!filelist[idx].issignkey)
continue;
}
if (capability == GCRY_PK_USAGE_ENCR)
{
if (!filelist[idx].isencrkey)
continue;
}
if (capability == GCRY_PK_USAGE_AUTH)
{
if (!filelist[idx].isauthkey)
continue;
}
if (app->app_local->active_nks_app == NKS_APP_ESIGN) if (app->app_local->active_nks_app == NKS_APP_ESIGN)
tagstr = "ESIGN"; tagstr = "ESIGN";
@ -2155,27 +2205,13 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
tagstr = "DF01"; tagstr = "DF01";
else else
tagstr = "NKS3"; tagstr = "NKS3";
snprintf (idbuf, sizeof idbuf, "NKS-%s.%04X", snprintf (idbuf, sizeof idbuf, "NKS-%s.%04X",
tagstr, filelist[idx].fid); tagstr, filelist[idx].fid);
send_keyinfo (ctrl, data, keygripstr, serialno, idbuf); send_keyinfo (ctrl, data, keygripstr, serialno, idbuf);
if (want_keygripstr)
{
err = 0; /* Found */
goto leave;
}
} }
} }
/* Return an error so that the dispatcher keeps on looping over the
* other applications. For clarity we use a different error code
* when listing all keys. Note that in lookup mode WANT_KEYGRIPSTR
* is not NULL. */
if (!want_keygripstr)
err = gpg_error (GPG_ERR_TRUE);
else
err = gpg_error (GPG_ERR_NOT_FOUND);
leave:
xfree (serialno); xfree (serialno);
return err; return err;
} }