1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

scd:nks: Minor additions to the basic IDLM application support.

* scd/app-nks.c (filelist): Use special value -1 for IDLM pubkeys.
(keygripstr_from_pk_file): Handle special value.
(do_readcert): Ditto.
(do_writecert): Ditto.
--

This allows to get information about the keys from the card.  However
the do_readkey still requires a fallback to readcert.  This does not
work because there are no certificates yet on the card.  The fix is to
fully implement do_readkey.
This commit is contained in:
Werner Koch 2020-11-30 09:57:35 +01:00
parent ad469609b1
commit 806547d9d2
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -104,7 +104,8 @@ static struct
int fid; /* File ID. */ int fid; /* File ID. */
int nks_ver; /* 0 for NKS version 2, 3 for version 3, etc. */ int nks_ver; /* 0 for NKS version 2, 3 for version 3, etc. */
int certtype; /* Type of certificate or 0 if it is not a certificate. */ int certtype; /* Type of certificate or 0 if it is not a certificate. */
int iskeypair; /* If true has the FID of the corresponding certificate. */ int iskeypair; /* If true has the FID of the corresponding certificate.
* If no certificate is known a value of -1 is used. */
int isauthkey; /* True if file is a key usable for authentication. */ int isauthkey; /* True if file is a key usable for authentication. */
int issignkey; /* True if file is a key usable for signing. */ int issignkey; /* True if file is a key usable for signing. */
int isencrkey; /* True if file is a key usable for decryption. */ int isencrkey; /* True if file is a key usable for decryption. */
@ -161,12 +162,12 @@ static struct
{ 2, 0xC001, 15,100 }, /* EF.C.ICC.QES (Cert) */ { 2, 0xC001, 15,100 }, /* EF.C.ICC.QES (Cert) */
{ 2, 0xC00E, 15,111 }, /* EF.C.RCA.QES (RootCA */ { 2, 0xC00E, 15,111 }, /* EF.C.RCA.QES (RootCA */
{ 3, 0x4E03, 3, 100 }, /* EK_PK_03 */ { 3, 0x4E03, 3, 0, -1 }, /* EK_PK_03 */
{ 3, 0x4E04, 3, 100 }, /* EK_PK_04 */ { 3, 0x4E04, 3, 0, -1 }, /* EK_PK_04 */
{ 3, 0x4E05, 3, 100 }, /* EK_PK_05 */ { 3, 0x4E05, 3, 0, -1 }, /* EK_PK_05 */
{ 3, 0x4E06, 3, 100 }, /* EK_PK_06 */ { 3, 0x4E06, 3, 0, -1 }, /* EK_PK_06 */
{ 3, 0x4E07, 3, 100 }, /* EK_PK_07 */ { 3, 0x4E07, 3, 0, -1 }, /* EK_PK_07 */
{ 3, 0x4E08, 3, 100 }, /* EK_PK_08 */ { 3, 0x4E08, 3, 0, -1 }, /* EK_PK_08 */
{ 0, 0 } { 0, 0 }
}; };
@ -272,7 +273,8 @@ get_dispserialno (app_t app)
* used and Read Record needs to be replaced by read binary. Given * used and Read Record needs to be replaced by read binary. Given
* all the ECC parameters required, we don't do that but rely that the * all the ECC parameters required, we don't do that but rely that the
* corresponding certificate at CFID is already available and get the * corresponding certificate at CFID is already available and get the
* public key from there. If R_ALGO is not NULL the public key * public key from there. Note that a CFID of 1 is indicates that a
* certificate is not known. If R_ALGO is not NULL the public key
* algorithm for the returned KEYGRIP is stored there. If R_ALGOSTR * algorithm for the returned KEYGRIP is stored there. If R_ALGOSTR
* is not NULL the public key algo string (e.g. "rsa2048") is stored * is not NULL the public key algo string (e.g. "rsa2048") is stored
* there. */ * there. */
@ -292,7 +294,8 @@ keygripstr_from_pk_file (app_t app, int pkfid, int cfid, char *r_gripstr,
struct fid_cache_s *ci; struct fid_cache_s *ci;
for (ci = app->app_local->fid_cache; ci; ci = ci->next) for (ci = app->app_local->fid_cache; ci; ci = ci->next)
if (ci->fid && ((cfid && ci->fid == cfid) || (!cfid && ci->fid == pkfid))) if (ci->fid && ((cfid > 0 && ci->fid == cfid)
|| (!(cfid > 0) && ci->fid == pkfid)))
{ {
if (!ci->got_keygrip) if (!ci->got_keygrip)
return gpg_error (GPG_ERR_NOT_FOUND); return gpg_error (GPG_ERR_NOT_FOUND);
@ -316,6 +319,12 @@ keygripstr_from_pk_file (app_t app, int pkfid, int cfid, char *r_gripstr,
unsigned char *cert, *pk; unsigned char *cert, *pk;
size_t certlen, pklen; size_t certlen, pklen;
if (cfid == -1)
{
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
goto leave;
}
/* Fall back to certificate reading. */ /* Fall back to certificate reading. */
err = readcert_from_ef (app, cfid, &cert, &certlen); err = readcert_from_ef (app, cfid, &cert, &certlen);
if (err) if (err)
@ -456,7 +465,8 @@ keygripstr_from_pk_file (app_t app, int pkfid, int cfid, char *r_gripstr,
/* FIXME: We need to implement not_found caching. */ /* FIXME: We need to implement not_found caching. */
for (ci = app->app_local->fid_cache; ci; ci = ci->next) for (ci = app->app_local->fid_cache; ci; ci = ci->next)
if (ci->fid if (ci->fid
&& ((cfid && ci->fid == cfid) || (!cfid && ci->fid == pkfid))) && ((cfid > 0 && ci->fid == cfid)
|| (!(cfid > 0) && ci->fid == pkfid)))
{ {
/* Update the keygrip. */ /* Update the keygrip. */
memcpy (ci->keygripstr, r_gripstr, 2*KEYGRIP_LEN+1); memcpy (ci->keygripstr, r_gripstr, 2*KEYGRIP_LEN+1);
@ -477,7 +487,7 @@ keygripstr_from_pk_file (app_t app, int pkfid, int cfid, char *r_gripstr,
; /* Out of memory - it is a cache, so we ignore it. */ ; /* Out of memory - it is a cache, so we ignore it. */
else else
{ {
ci->fid = cfid? cfid : pkfid; ci->fid = (cfid > 0)? cfid : pkfid;
memcpy (ci->keygripstr, r_gripstr, 2*KEYGRIP_LEN+1); memcpy (ci->keygripstr, r_gripstr, 2*KEYGRIP_LEN+1);
ci->algo = algo; ci->algo = algo;
ci->got_keygrip = 1; ci->got_keygrip = 1;
@ -1049,7 +1059,7 @@ do_readcert (app_t app, const char *certid,
return gpg_error (GPG_ERR_INV_ID); return gpg_error (GPG_ERR_INV_ID);
fid = xtoi_4 (certid); fid = xtoi_4 (certid);
for (i=0; filelist[i].fid; i++) for (i=0; filelist[i].fid; i++)
if ((filelist[i].certtype || filelist[i].iskeypair) if ((filelist[i].certtype || filelist[i].iskeypair > 0)
&& filelist[i].nks_app_id == nks_app_id && filelist[i].nks_app_id == nks_app_id
&& filelist[i].fid == fid) && filelist[i].fid == fid)
break; break;
@ -1061,7 +1071,7 @@ do_readcert (app_t app, const char *certid,
because we sometime use the key directly or let the caller because we sometime use the key directly or let the caller
retrieve the key from the certificate. The rationale for retrieve the key from the certificate. The rationale for
that is to support not-yet stored certificates. */ that is to support not-yet stored certificates. */
if (filelist[i].iskeypair) if (filelist[i].iskeypair > 0)
fid = filelist[i].iskeypair; fid = filelist[i].iskeypair;
return readcert_from_ef (app, fid, cert, certlen); return readcert_from_ef (app, fid, cert, certlen);
@ -1178,7 +1188,7 @@ do_writecert (app_t app, ctrl_t ctrl,
return gpg_error (GPG_ERR_INV_ID); return gpg_error (GPG_ERR_INV_ID);
fid = xtoi_4 (certid); fid = xtoi_4 (certid);
for (i=0; filelist[i].fid; i++) for (i=0; filelist[i].fid; i++)
if ((filelist[i].certtype || filelist[i].iskeypair) if ((filelist[i].certtype || filelist[i].iskeypair > 0)
&& filelist[i].nks_app_id == nks_app_id && filelist[i].nks_app_id == nks_app_id
&& filelist[i].fid == fid) && filelist[i].fid == fid)
break; break;
@ -1189,7 +1199,7 @@ do_writecert (app_t app, ctrl_t ctrl,
* the corresponding certificate. This makes it easier for the user * the corresponding certificate. This makes it easier for the user
* to figure out which CERTID to use. For example gpg-card shows * to figure out which CERTID to use. For example gpg-card shows
* the id of the key and not of the certificate. */ * the id of the key and not of the certificate. */
if (filelist[i].iskeypair) if (filelist[i].iskeypair > 0)
fid = filelist[i].iskeypair; fid = filelist[i].iskeypair;
/* We have no selective flush mechanism and given the rare use of /* We have no selective flush mechanism and given the rare use of