[Pkg-gnupg-commit] [gnupg2] 204/292: scd: Add --advanced option for READKEY.
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Mon Nov 21 06:31:42 UTC 2016
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch master
in repository gnupg2.
commit f9da935c3eb302e75a80def51128fb6f669661d7
Author: NIIBE Yutaka <gniibe at fsij.org>
Date: Fri Nov 4 13:45:57 2016 +0900
scd: Add --advanced option for READKEY.
* scd/command.c (cmd_readkey) : Support ADVANCED arg.
* scd/app.c (app_readcert): Add ADVANCED arg.
* scd/app-openpgp.c (do_readkey): Implement ADVANCED arg.
* scd/app-nks.c (do_readkey): Error return with GPG_ERR_NOT_SUPPORTED.
--
"SCD READKEY --advanced OPENPGP.3" returns key in advanced format.
With this suport, poldi-ctrl will be no longer needed.
Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
---
scd/app-common.h | 4 +-
scd/app-nks.c | 8 +++-
scd/app-openpgp.c | 130 ++++++++++++++++++++++++++++++++----------------------
scd/app.c | 5 ++-
scd/command.c | 13 ++++--
5 files changed, 99 insertions(+), 61 deletions(-)
diff --git a/scd/app-common.h b/scd/app-common.h
index b4bb55b..cda657f 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -72,7 +72,7 @@ struct app_ctx_s {
gpg_error_t (*learn_status) (app_t app, ctrl_t ctrl, unsigned int flags);
gpg_error_t (*readcert) (app_t app, const char *certid,
unsigned char **cert, size_t *certlen);
- gpg_error_t (*readkey) (app_t app, const char *certid,
+ gpg_error_t (*readkey) (app_t app, int advanced, const char *certid,
unsigned char **pk, size_t *pklen);
gpg_error_t (*getattr) (app_t app, ctrl_t ctrl, const char *name);
gpg_error_t (*setattr) (app_t app, const char *name,
@@ -154,7 +154,7 @@ gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl,
unsigned int flags);
gpg_error_t app_readcert (app_t app, const char *certid,
unsigned char **cert, size_t *certlen);
-gpg_error_t app_readkey (app_t app, const char *keyid,
+gpg_error_t app_readkey (app_t app, int advanced, const char *keyid,
unsigned char **pk, size_t *pklen);
gpg_error_t app_getattr (app_t app, ctrl_t ctrl, const char *name);
gpg_error_t app_setattr (app_t app, const char *name,
diff --git a/scd/app-nks.c b/scd/app-nks.c
index 458516b..598dee1 100644
--- a/scd/app-nks.c
+++ b/scd/app-nks.c
@@ -618,13 +618,17 @@ do_readcert (app_t app, const char *certid,
certificate parsing code in commands.c:cmd_readkey. For internal
use PK and PKLEN may be NULL to just check for an existing key. */
static gpg_error_t
-do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
+do_readkey (app_t app, int advanced, const char *keyid,
+ unsigned char **pk, size_t *pklen)
{
gpg_error_t err;
unsigned char *buffer[2];
size_t buflen[2];
unsigned short path[1] = { 0x4500 };
+ if (advanced)
+ return GPG_ERR_NOT_SUPPORTED;
+
/* We use a generic name to retrieve PK.AUT.IFD-SPK. */
if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
;
@@ -698,7 +702,7 @@ do_writekey (app_t app, ctrl_t ctrl,
else
return gpg_error (GPG_ERR_INV_ID);
- if (!force && !do_readkey (app, keyid, NULL, NULL))
+ if (!force && !do_readkey (app, 0, keyid, NULL, NULL))
return gpg_error (GPG_ERR_EEXIST);
/* Parse the S-expression. */
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index d75721f..4bf99ad 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -1115,8 +1115,8 @@ retrieve_fpr_from_card (app_t app, int keyno, char *fpr)
#if GNUPG_MAJOR_VERSION > 1
static gpg_error_t
retrieve_key_material (FILE *fp, const char *hexkeyid,
- const unsigned char **m, size_t *mlen,
- const unsigned char **e, size_t *elen)
+ const unsigned char **m, size_t *mlen,
+ const unsigned char **e, size_t *elen)
{
gcry_error_t err = 0;
char *line = NULL; /* read_line() buffer. */
@@ -1146,10 +1146,10 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
if (!i)
break; /* EOF. */
if (i < 0)
- {
- err = gpg_error_from_syserror ();
- goto leave; /* Error. */
- }
+ {
+ err = gpg_error_from_syserror ();
+ goto leave; /* Error. */
+ }
if (!max_length)
{
err = gpg_error (GPG_ERR_TRUNCATED);
@@ -1173,7 +1173,7 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
&& nfields > 4 && !strcmp (fields[4], hexkeyid))
found_key = 1;
continue;
- }
+ }
if ( !strcmp (fields[0], "sub") || !strcmp (fields[0], "pub") )
break; /* Next key - stop. */
@@ -1561,8 +1561,8 @@ get_public_key (app_t app, int keyno)
Clearly that is not an option and thus we try to locate the
key using an external helper.
- The helper we use here is gpg itself, which should know about
- the key in any case. */
+ The helper we use here is gpg itself, which should know about
+ the key in any case. */
char fpr[41];
char *hexkeyid;
@@ -1574,38 +1574,38 @@ get_public_key (app_t app, int keyno)
err = retrieve_fpr_from_card (app, keyno, fpr);
if (err)
- {
- log_error ("error while retrieving fpr from card: %s\n",
- gpg_strerror (err));
- goto leave;
- }
+ {
+ log_error ("error while retrieving fpr from card: %s\n",
+ gpg_strerror (err));
+ goto leave;
+ }
hexkeyid = fpr + 24;
ret = gpgrt_asprintf
(&command, "gpg --list-keys --with-colons --with-key-data '%s'", fpr);
if (ret < 0)
- {
- err = gpg_error_from_syserror ();
- goto leave;
- }
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
fp = popen (command, "r");
xfree (command);
if (!fp)
- {
- err = gpg_error_from_syserror ();
- log_error ("running gpg failed: %s\n", gpg_strerror (err));
- goto leave;
- }
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("running gpg failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
err = retrieve_key_material (fp, hexkeyid, &m, &mlen, &e, &elen);
pclose (fp);
if (err)
- {
- log_error ("error while retrieving key material through pipe: %s\n",
+ {
+ log_error ("error while retrieving key material through pipe: %s\n",
gpg_strerror (err));
- goto leave;
- }
+ goto leave;
+ }
err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))",
(int)mlen, m, (int)elen, e);
@@ -1726,7 +1726,8 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
buffer. On error PK and PKLEN are not changed and an error code is
returned. */
static gpg_error_t
-do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
+do_readkey (app_t app, int advanced, const char *keyid,
+ unsigned char **pk, size_t *pklen)
{
#if GNUPG_MAJOR_VERSION > 1
gpg_error_t err;
@@ -1749,15 +1750,40 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
buf = app->app_local->pk[keyno].key;
if (!buf)
return gpg_error (GPG_ERR_NO_PUBKEY);
- *pklen = app->app_local->pk[keyno].keylen;;
- *pk = xtrymalloc (*pklen);
- if (!*pk)
+
+ if (advanced)
{
- err = gpg_error_from_syserror ();
- *pklen = 0;
- return err;
+ gcry_sexp_t s_key;
+
+ err = gcry_sexp_new (&s_key, buf, app->app_local->pk[keyno].keylen, 0);
+ if (err)
+ return err;
+
+ *pklen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ *pk = xtrymalloc (*pklen);
+ if (!*pk)
+ {
+ err = gpg_error_from_syserror ();
+ *pklen = 0;
+ return err;
+ }
+
+ gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, *pk, *pklen);
+ gcry_sexp_release (s_key);
+ }
+ else
+ {
+ *pklen = app->app_local->pk[keyno].keylen;
+ *pk = xtrymalloc (*pklen);
+ if (!*pk)
+ {
+ err = gpg_error_from_syserror ();
+ *pklen = 0;
+ return err;
+ }
+ memcpy (*pk, buf, *pklen);
}
- memcpy (*pk, buf, *pklen);
+
return 0;
#else
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
@@ -2366,7 +2392,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
}
else if (chvno == 1 || chvno == 3)
{
- if (!use_pinpad)
+ if (!use_pinpad)
{
char *promptbuf = NULL;
const char *prompt;
@@ -3990,23 +4016,23 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
else
{
for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
- ;
+ ;
if (n != 32)
- return gpg_error (GPG_ERR_INV_ID);
+ return gpg_error (GPG_ERR_INV_ID);
else if (!*s)
- ; /* no fingerprint given: we allow this for now. */
+ ; /* no fingerprint given: we allow this for now. */
else if (*s == '/')
- fpr = s + 1;
+ fpr = s + 1;
else
- return gpg_error (GPG_ERR_INV_ID);
+ return gpg_error (GPG_ERR_INV_ID);
for (s=keyidstr, n=0; n < 16; s += 2, n++)
- tmp_sn[n] = xtoi_2 (s);
+ tmp_sn[n] = xtoi_2 (s);
if (app->serialnolen != 16)
- return gpg_error (GPG_ERR_INV_CARD);
+ return gpg_error (GPG_ERR_INV_CARD);
if (memcmp (app->serialno, tmp_sn, 16))
- return gpg_error (GPG_ERR_WRONG_CARD);
+ return gpg_error (GPG_ERR_WRONG_CARD);
}
/* If a fingerprint has been specified check it against the one on
@@ -4244,23 +4270,23 @@ do_decipher (app_t app, const char *keyidstr,
else
{
for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
- ;
+ ;
if (n != 32)
- return gpg_error (GPG_ERR_INV_ID);
+ return gpg_error (GPG_ERR_INV_ID);
else if (!*s)
- ; /* no fingerprint given: we allow this for now. */
+ ; /* no fingerprint given: we allow this for now. */
else if (*s == '/')
- fpr = s + 1;
+ fpr = s + 1;
else
- return gpg_error (GPG_ERR_INV_ID);
+ return gpg_error (GPG_ERR_INV_ID);
for (s=keyidstr, n=0; n < 16; s += 2, n++)
- tmp_sn[n] = xtoi_2 (s);
+ tmp_sn[n] = xtoi_2 (s);
if (app->serialnolen != 16)
- return gpg_error (GPG_ERR_INV_CARD);
+ return gpg_error (GPG_ERR_INV_CARD);
if (memcmp (app->serialno, tmp_sn, 16))
- return gpg_error (GPG_ERR_WRONG_CARD);
+ return gpg_error (GPG_ERR_WRONG_CARD);
}
/* If a fingerprint has been specified check it against the one on
diff --git a/scd/app.c b/scd/app.c
index 55b8edd..1f21dc1 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -612,7 +612,8 @@ app_readcert (app_t app, const char *certid,
This function might not be supported by all applications. */
gpg_error_t
-app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
+app_readkey (app_t app, int advanced, const char *keyid,
+ unsigned char **pk, size_t *pklen)
{
gpg_error_t err;
@@ -630,7 +631,7 @@ app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
err = lock_reader (app->slot, NULL /*FIXME*/);
if (err)
return err;
- err= app->fnc.readkey (app, keyid, pk, pklen);
+ err= app->fnc.readkey (app, advanced, keyid, pk, pklen);
unlock_reader (app->slot);
return err;
}
diff --git a/scd/command.c b/scd/command.c
index 9d978ab..edea01c 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -729,17 +729,19 @@ cmd_readcert (assuan_context_t ctx, char *line)
static const char hlp_readkey[] =
- "READKEY <keyid>\n"
+ "READKEY [--advanced] <keyid>\n"
"\n"
"Return the public key for the given cert or key ID as a standard\n"
"S-expression.\n"
+ "In --advanced mode it returns the S-expression in advanced format.\n"
"\n"
- "Note, that this function may even be used on a locked card.";
+ "Note that this function may even be used on a locked card.";
static gpg_error_t
cmd_readkey (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
int rc;
+ int advanced = 0;
unsigned char *cert = NULL;
size_t ncert, n;
ksba_cert_t kc = NULL;
@@ -750,11 +752,16 @@ cmd_readkey (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl, NULL)))
return rc;
+ if (has_option (line, "--advanced"))
+ advanced = 1;
+
+ line = skip_options (line);
+
line = xstrdup (line); /* Need a copy of the line. */
/* If the application supports the READKEY function we use that.
Otherwise we use the old way by extracting it from the
certificate. */
- rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
+ rc = app_readkey (ctrl->app_ctx, advanced, line, &pk, &pklen);
if (!rc)
{ /* Yeah, got that key - send it back. */
rc = assuan_send_data (ctx, pk, pklen);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git
More information about the Pkg-gnupg-commit
mailing list