aboutsummaryrefslogtreecommitdiffstats
path: root/scd/app-nks.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2021-04-08 17:30:51 +0000
committerWerner Koch <[email protected]>2021-04-08 17:30:51 +0000
commit63320ba2f8147ee86f4406c9590f6b28cad4771d (patch)
tree59fd0d0714d66d35ba9784d1843df8626dca38d4 /scd/app-nks.c
parentscd: Fix duplicate output of KEYPAIRINFO by readkey command. (diff)
downloadgnupg-63320ba2f8147ee86f4406c9590f6b28cad4771d.tar.gz
gnupg-63320ba2f8147ee86f4406c9590f6b28cad4771d.zip
scd:nks: Handle APP_READKEY_FLAG_INFO.
* scd/app-nks.c (keygripstr_from_pk_file): Fix ignored error. (get_nks_tag): New. (do_learn_status_core): Use it. Make sure not to mange the KEYPAIRINFO line if no usage is known. (do_readkey): Output the KEYPAIRINFO for the keygrip case. -- Note that this only handles the most common case of providing a keygrip. $AUTHKEYID and ODLM are not yet supported. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'scd/app-nks.c')
-rw-r--r--scd/app-nks.c179
1 files changed, 117 insertions, 62 deletions
diff --git a/scd/app-nks.c b/scd/app-nks.c
index 006e6a92c..bf2ad51b7 100644
--- a/scd/app-nks.c
+++ b/scd/app-nks.c
@@ -440,8 +440,9 @@ keygripstr_from_pk_file (app_t app, int pkfid, int cfid, char *r_gripstr,
}
err = pubkey_from_pk_file (app, pkfid, cfid, &pk, &pklen);
- err = app_help_get_keygrip_string_pk (pk, pklen, r_gripstr, NULL,
- &algo, &algostr);
+ if (!err)
+ err = app_help_get_keygrip_string_pk (pk, pklen, r_gripstr, NULL,
+ &algo, &algostr);
xfree (pk);
if (!err)
@@ -794,14 +795,9 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
}
-
-static void
-do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags,
- int nks_app_id)
+const char *
+get_nks_tag (app_t app, int nks_app_id)
{
- gpg_error_t err;
- char ct_buf[100], id_buf[100];
- int i;
const char *tag;
if (nks_app_id == NKS_APP_ESIGN)
@@ -815,6 +811,18 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags,
else
tag = "NKS3";
+ return tag;
+}
+
+static void
+do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags,
+ int nks_app_id)
+{
+ gpg_error_t err;
+ char ct_buf[100], id_buf[100];
+ int i;
+ const char *tag = get_nks_tag (app, nks_app_id);
+
/* Output information about all useful objects in the NKS application. */
for (i=0; filelist[i].fid; i++)
{
@@ -867,6 +875,8 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags,
usagebuf[usageidx++] = 'a';
if (filelist[i].isencrkey)
usagebuf[usageidx++] = 'e';
+ if (!usageidx)
+ usagebuf[usageidx++] = '-';
usagebuf[usageidx] = 0;
send_status_info (ctrl, "KEYPAIRINFO",
gripstr, 40,
@@ -1198,13 +1208,63 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags,
unsigned char **pk, size_t *pklen)
{
gpg_error_t err;
- unsigned char *buffer[2];
- size_t buflen[2];
- unsigned short path[1] = { 0x4500 };
+ unsigned char *dummy_pk = NULL;
+ size_t dummy_pklen = 0;
+
+ if (!pk)
+ pk = &dummy_pk;
+ if (!pklen)
+ pklen = &dummy_pklen;
/* We use a generic name to retrieve PK.AUT.IFD-SPK. */
if (!strcmp (keyid, "$IFDAUTHKEY") && app->appversion >= 3)
- ;
+ {
+ unsigned short path[1] = { 0x4500 };
+ unsigned char *buffer[2];
+ size_t buflen[2];
+
+ /* Access the KEYD file which is always in the master directory. */
+ err = iso7816_select_path (app_get_slot (app), path, DIM (path), 0);
+ if (err)
+ goto leave;
+ /* Due to the above select we need to re-select our application. */
+ app->app_local->need_app_select = 1;
+ /* Get the two records. */
+ err = iso7816_read_record (app_get_slot (app), 5, 1, 0,
+ &buffer[0], &buflen[0]);
+ if (err)
+ goto leave;
+ if (all_zero_p (buffer[0], buflen[0]))
+ {
+ xfree (buffer[0]);
+ err = gpg_error (GPG_ERR_NOT_FOUND);
+ goto leave;
+ }
+ err = iso7816_read_record (app_get_slot (app), 6, 1, 0,
+ &buffer[1], &buflen[1]);
+ if (err)
+ {
+ xfree (buffer[0]);
+ goto leave;
+ }
+
+ if ((flags & APP_READKEY_FLAG_INFO))
+ {
+ /* FIXME */
+ }
+
+ if (pk && pklen && pk != &dummy_pk)
+ {
+ *pk = make_canon_sexp_from_rsa_pk (buffer[0], buflen[0],
+ buffer[1], buflen[1],
+ pklen);
+ if (!*pk)
+ err = gpg_error_from_syserror ();
+ }
+
+ xfree (buffer[0]);
+ xfree (buffer[1]);
+ }
else if (strlen (keyid) == 40)
{
char keygripstr[2*KEYGRIP_LEN+1];
@@ -1212,10 +1272,42 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags,
err = iterate_over_filelist (app, keyid, 0, keygripstr, &i);
if (err)
- return err;
+ goto leave;
- return pubkey_from_pk_file (app, filelist[i].fid, filelist[i].iskeypair,
- pk, pklen);
+ err = pubkey_from_pk_file (app, filelist[i].fid, filelist[i].iskeypair,
+ pk, pklen);
+ if (!err && (flags & APP_READKEY_FLAG_INFO))
+ {
+ char *algostr;
+ char usagebuf[5];
+ int usageidx = 0;
+ char id_buf[100];
+
+ if (app_help_get_keygrip_string_pk (*pk, *pklen, NULL, NULL, NULL,
+ &algostr))
+ algostr = NULL; /* Ooops. */
+
+ snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
+ get_nks_tag (app, filelist[i].nks_app_id),
+ filelist[i].fid);
+ if (filelist[i].issignkey)
+ usagebuf[usageidx++] = 's';
+ if (filelist[i].isauthkey)
+ usagebuf[usageidx++] = 'a';
+ if (filelist[i].isencrkey)
+ usagebuf[usageidx++] = 'e';
+ if (!usageidx)
+ usagebuf[usageidx++] = '-';
+ usagebuf[usageidx] = 0;
+ send_status_info (ctrl, "KEYPAIRINFO",
+ keygripstr, strlen (keygripstr),
+ id_buf, strlen (id_buf),
+ usagebuf, strlen (usagebuf),
+ "-", (size_t)1,
+ algostr, strlen (algostr?algostr:""),
+ NULL, (size_t)0);
+ xfree (algostr);
+ }
}
else if (!strncmp (keyid, "NKS-IDLM.", 9))
{
@@ -1223,56 +1315,19 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags,
if (!hexdigitp (keyid) || !hexdigitp (keyid+1)
|| !hexdigitp (keyid+2) || !hexdigitp (keyid+3)
|| keyid[4])
- return gpg_error (GPG_ERR_INV_ID);
+ {
+ err = gpg_error (GPG_ERR_INV_ID);
+ goto leave;
+ }
- return pubkey_from_pk_file (app, xtoi_4 (keyid), -1, pk, pklen);
+ err = pubkey_from_pk_file (app, xtoi_4 (keyid), -1, pk, pklen);
+ /* FIXME: Implement KEYPAIRINFO. */
}
else /* Return the error code expected by cmd_readkey. */
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
- /* Access the KEYD file which is always in the master directory. */
- err = iso7816_select_path (app_get_slot (app), path, DIM (path), 0);
- if (err)
- return err;
- /* Due to the above select we need to re-select our application. */
- app->app_local->need_app_select = 1;
- /* Get the two records. */
- err = iso7816_read_record (app_get_slot (app), 5, 1, 0,
- &buffer[0], &buflen[0]);
- if (err)
- return err;
- if (all_zero_p (buffer[0], buflen[0]))
- {
- xfree (buffer[0]);
- return gpg_error (GPG_ERR_NOT_FOUND);
- }
- err = iso7816_read_record (app_get_slot (app), 6, 1, 0,
- &buffer[1], &buflen[1]);
- if (err)
- {
- xfree (buffer[0]);
- return err;
- }
-
- if ((flags & APP_READKEY_FLAG_INFO))
- {
- /* Not yet implemented but we won't get here for any regular
- * keyrefs anyway, thus the top layer will provide the
- * keypairinfo from the certificate. */
- (void)ctrl;
- }
-
- if (pk && pklen)
- {
- *pk = make_canon_sexp_from_rsa_pk (buffer[0], buflen[0],
- buffer[1], buflen[1],
- pklen);
- if (!*pk)
- err = gpg_error_from_syserror ();
- }
-
- xfree (buffer[0]);
- xfree (buffer[1]);
+ leave:
+ xfree (dummy_pk);
return err;
}