aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2021-04-01 08:28:07 +0000
committerWerner Koch <[email protected]>2021-04-01 08:28:07 +0000
commite17d3f866057543d142d63379fd4f4a36d79147f (patch)
treebc3461cec907ea775c57d125a9b6a609944d8f77
parentscd: Replace all assert macros by the log_assert macro. (diff)
downloadgnupg-e17d3f866057543d142d63379fd4f4a36d79147f.tar.gz
gnupg-e17d3f866057543d142d63379fd4f4a36d79147f.zip
scd:p15: New flag APP_LEARN_FLAG_REREAD.
* scd/app-p15.c (do_deinit): Factor code out to ... (release_lists, release_tokeninfo): new. (read_ef_tokeninfo): Reset all data before reading. (read_p15_info): Ditto. (do_learn_status): Implement reread flag. -- Objects of a card may be protected by a PIN and thus only readble after a verify command. This new flag makes it possible to gather the entire PKCS#15 card info again without a need for a reset (and thus loss of the verify status). Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--scd/app-common.h1
-rw-r--r--scd/app-p15.c99
2 files changed, 73 insertions, 27 deletions
diff --git a/scd/app-common.h b/scd/app-common.h
index ace299ba7..c68fb8609 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -45,6 +45,7 @@
/* Flags used by the app_write_learn_status. */
#define APP_LEARN_FLAG_KEYPAIRINFO 1 /* Return only keypair infos. */
#define APP_LEARN_FLAG_MULTI 2 /* Return info for all apps. */
+#define APP_LEARN_FLAG_REREAD 4 /* Re-read ifnos from the token. */
/* List of supported card types. Generic is the usual ISO7817-4
diff --git a/scd/app-p15.c b/scd/app-p15.c
index 00ee12de6..20c6e06eb 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -589,22 +589,46 @@ release_aodflist (aodf_object_t a)
}
+static void
+release_lists (app_t app)
+{
+ release_cdflist (app->app_local->certificate_info);
+ app->app_local->certificate_info = NULL;
+ release_cdflist (app->app_local->trusted_certificate_info);
+ app->app_local->trusted_certificate_info = NULL;
+ release_cdflist (app->app_local->useful_certificate_info);
+ app->app_local->useful_certificate_info = NULL;
+ release_pukdflist (app->app_local->public_key_info);
+ app->app_local->public_key_info = NULL;
+ release_prkdflist (app->app_local->private_key_info);
+ app->app_local->private_key_info = NULL;
+ release_aodflist (app->app_local->auth_object_info);
+ app->app_local->auth_object_info = NULL;
+}
+
+
+static void
+release_tokeninfo (app_t app)
+{
+ xfree (app->app_local->manufacturer_id);
+ app->app_local->manufacturer_id = NULL;
+ xfree (app->app_local->token_label);
+ app->app_local->token_label = NULL;
+ xfree (app->app_local->tokenflags);
+ app->app_local->tokenflags = NULL;
+ xfree (app->app_local->serialno);
+ app->app_local->serialno = NULL;
+}
+
+
/* Release all local resources. */
static void
do_deinit (app_t app)
{
if (app && app->app_local)
{
- release_cdflist (app->app_local->certificate_info);
- release_cdflist (app->app_local->trusted_certificate_info);
- release_cdflist (app->app_local->useful_certificate_info);
- release_pukdflist (app->app_local->public_key_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->token_label);
- xfree (app->app_local->tokenflags);
- xfree (app->app_local->serialno);
+ release_lists (app);
+ release_tokeninfo (app);
xfree (app->app_local);
app->app_local = NULL;
}
@@ -939,6 +963,17 @@ read_ef_odf (app_t app, unsigned short odf_fid)
size_t offset;
unsigned short home_df = 0;
+
+ app->app_local->odf.private_keys = 0;
+ app->app_local->odf.public_keys = 0;
+ app->app_local->odf.trusted_public_keys = 0;
+ app->app_local->odf.secret_keys = 0;
+ app->app_local->odf.certificates = 0;
+ app->app_local->odf.trusted_certificates = 0;
+ app->app_local->odf.useful_certificates = 0;
+ app->app_local->odf.data_objects = 0;
+ app->app_local->odf.auth_objects = 0;
+
err = select_and_read_binary (app, odf_fid, "ODF",
&buffer, &buflen);
if (err)
@@ -3270,8 +3305,7 @@ 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;
+ release_tokeninfo (app);
app->app_local->card_product = CARD_PRODUCT_UNKNOWN;
err = select_and_read_binary (app, 0x5032, "TokenInfo", &buffer, &buflen);
@@ -3401,22 +3435,24 @@ read_p15_info (app_t app)
prkdf_object_t prkdf;
unsigned int flag;
- if (!read_ef_tokeninfo (app))
- {
- /* If we don't have a serial number yet but the TokenInfo provides
- one, use that. */
- if (!APP_CARD(app)->serialno && app->app_local->serialno)
- {
- APP_CARD(app)->serialno = app->app_local->serialno;
- APP_CARD(app)->serialnolen = app->app_local->serialnolen;
- app->app_local->serialno = NULL;
- app->app_local->serialnolen = 0;
- err = app_munge_serialno (APP_CARD(app));
- if (err)
- return err;
- }
+ err = read_ef_tokeninfo (app);
+ if (err)
+ return err;
+ /* If we don't have a serial number yet but the TokenInfo provides
+ * one, use that. */
+ if (!APP_CARD(app)->serialno && app->app_local->serialno)
+ {
+ APP_CARD(app)->serialno = app->app_local->serialno;
+ APP_CARD(app)->serialnolen = app->app_local->serialnolen;
+ app->app_local->serialno = NULL;
+ app->app_local->serialnolen = 0;
+ err = app_munge_serialno (APP_CARD(app));
+ if (err)
+ return err;
}
+ release_lists (app);
+
/* Read the ODF so that we know the location of all directory
files. */
/* Fixme: We might need to get a non-standard ODF FID from TokenInfo. */
@@ -4009,12 +4045,21 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t prkdf)
-/* This is the handler for the LEARN command. */
+/* This is the handler for the LEARN command. Note that if
+ * APP_LEARN_FLAG_REREAD is set and this function returns an error,
+ * the caller must deinitialize this application. */
static gpg_error_t
do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
gpg_error_t err;
+ if (flags & APP_LEARN_FLAG_REREAD)
+ {
+ err = read_p15_info (app);
+ if (err)
+ return err;
+ }
+
if ((flags & APP_LEARN_FLAG_KEYPAIRINFO))
err = 0;
else