summaryrefslogtreecommitdiffstats
path: root/scd
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-04-03 11:21:32 +0200
committerWerner Koch <wk@gnupg.org>2020-04-03 11:21:32 +0200
commitaa60645b997d23ac2958f75fd349c1cd7b8af902 (patch)
tree430bbc62775fbf01330abc7e03d0c78d7a309a67 /scd
parentgpg,card: Use the new MANUFACTURER attribute. (diff)
downloadgnupg2-aa60645b997d23ac2958f75fd349c1cd7b8af902.tar.xz
gnupg2-aa60645b997d23ac2958f75fd349c1cd7b8af902.zip
scd:p15: Emit MANUFACTURER, $ENCRKEYID, $SIGNKEYID.
* scd/app-p15.c (read_ef_tokeninfo): Store manufacturer_id. (do_getattr): Implement MANUFACTURER, $ENCRKEYID and $SIGNKEYID. (send_keypairinfo): Also print usage flags. -- Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'scd')
-rw-r--r--scd/app-p15.c80
1 files changed, 62 insertions, 18 deletions
diff --git a/scd/app-p15.c b/scd/app-p15.c
index 23ed19191..509759069 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -330,6 +330,9 @@ struct app_local_s
unsigned char *serialno;
size_t serialnolen;
+ /* The manufacturerID from the TokenInfo EF. Malloced. */
+ char *manufacturer_id;
+
/* Information on all certificates. */
cdf_object_t certificate_info;
/* Information on all trusted certificates. */
@@ -350,6 +353,7 @@ struct app_local_s
static gpg_error_t keygrip_from_prkdf (app_t app, prkdf_object_t prkdf);
static gpg_error_t readcert_by_cdf (app_t app, cdf_object_t cdf,
unsigned char **r_cert, size_t *r_certlen);
+static gpg_error_t do_getattr (app_t app, ctrl_t ctrl, const char *name);
@@ -418,6 +422,7 @@ do_deinit (app_t app)
release_cdflist (app->app_local->useful_certificate_info);
release_prkdflist (app->app_local->private_key_info);
release_aodflist (app->app_local->auth_object_info);
+ xfree (app->app_local->manufacturer_id);
xfree (app->app_local->serialno);
xfree (app->app_local);
app->app_local = NULL;
@@ -2368,6 +2373,9 @@ read_ef_tokeninfo (app_t app)
int class, tag, constructed, ndef;
unsigned long ul;
+ xfree (app->app_local->manufacturer_id);
+ app->app_local->manufacturer_id = NULL;
+
err = select_and_read_binary (app_get_slot (app), 0x5032, "TokenInfo",
&buffer, &buflen);
if (err)
@@ -2448,6 +2456,8 @@ read_ef_tokeninfo (app_t app)
{
if (opt.verbose)
log_info ("p15: manufacturerID: %.*s\n", (int)objlen, p);
+ app->app_local->manufacturer_id = percent_data_escape (0, NULL,
+ p, objlen);
p += objlen;
n -= objlen;
/* Get next TLV. */
@@ -2725,10 +2735,28 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t prkdf)
}
else
{
+ char usage[5];
+ size_t usagelen = 0;
+
+ if (prkdf->usageflags.sign
+ || prkdf->usageflags.sign_recover
+ || prkdf->usageflags.non_repudiation)
+ usage[usagelen++] = 's';
+ if (prkdf->usageflags.sign
+ || prkdf->usageflags.sign_recover)
+ usage[usagelen++] = 'c';
+ if (prkdf->usageflags.decrypt
+ || prkdf->usageflags.unwrap)
+ usage[usagelen++] = 'e';
+ if (prkdf->usageflags.sign
+ || prkdf->usageflags.sign_recover)
+ usage[usagelen++] = 'a';
+
log_assert (strlen (prkdf->keygrip) == 40);
send_status_info (ctrl, "KEYPAIRINFO",
prkdf->keygrip, 2*KEYGRIP_LEN,
buf, strlen (buf),
+ usage, usagelen,
NULL, (size_t)0);
}
xfree (buf);
@@ -2748,7 +2776,10 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
err = 0;
else
{
- err = send_certinfo (app, ctrl, "100", app->app_local->certificate_info);
+ err = do_getattr (app, ctrl, "MANUFACTURER");
+ if (!err)
+ err = send_certinfo (app, ctrl, "100",
+ app->app_local->certificate_info);
if (!err)
err = send_certinfo (app, ctrl, "101",
app->app_local->trusted_certificate_info);
@@ -2919,36 +2950,41 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
{
gpg_error_t err;
- if (!strcmp (name, "$AUTHKEYID"))
+ if (!strcmp (name, "$AUTHKEYID")
+ || !strcmp (name, "$ENCRKEYID")
+ || !strcmp (name, "$SIGNKEYID"))
{
- char *buf, *p;
+ char *buf;
prkdf_object_t prkdf;
- /* We return the ID of the first private keycapable of
- signing. */
+ /* We return the ID of the first private key capable of the
+ * requested action. Note that we do not yet return
+ * non_repudiation keys for $SIGNKEYID because our D-Trust
+ * testcard uses rsaPSS, which is not supported by gpgsm and not
+ * covered by the VS-NfD approval. */
for (prkdf = app->app_local->private_key_info; prkdf;
prkdf = prkdf->next)
- if (prkdf->usageflags.sign)
- break;
+ {
+ if (name[1] == 'A' && (prkdf->usageflags.sign
+ || prkdf->usageflags.sign_recover))
+ break;
+ else if (name[1] == 'E' && (prkdf->usageflags.decrypt
+ || prkdf->usageflags.unwrap))
+ break;
+ else if (name[1] == 'S' && (prkdf->usageflags.sign
+ || prkdf->usageflags.sign_recover))
+ break;
+ }
if (prkdf)
{
- buf = xtrymalloc (9 + prkdf->objidlen*2 + 1);
+ buf = keyref_from_prkdf (app, prkdf);
if (!buf)
return gpg_error_from_syserror ();
- p = stpcpy (buf, "P15");
- if (app->app_local->home_df)
- {
- snprintf (p, 6, "-%04X",
- (unsigned int)(app->app_local->home_df & 0xffff));
- p += 5;
- }
- p = stpcpy (p, ".");
- bin2hex (prkdf->objid, prkdf->objidlen, p);
send_status_info (ctrl, name, buf, strlen (buf), NULL, 0);
xfree (buf);
- return 0;
}
+ return 0;
}
else if (!strcmp (name, "$DISPSERIALNO"))
{
@@ -2992,6 +3028,14 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
}
}
+ else if (!strcmp (name, "MANUFACTURER"))
+ {
+ if (app->app_local->manufacturer_id)
+ return send_status_printf (ctrl, "MANUFACTURER", "0 %s",
+ app->app_local->manufacturer_id);
+ else
+ return 0;
+ }
return gpg_error (GPG_ERR_INV_NAME);
}