1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-05-24 16:43:28 +02:00

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@fsij.org>
This commit is contained in:
NIIBE Yutaka 2016-11-04 13:45:57 +09:00
parent c1ea0b577a
commit f9da935c3e
5 changed files with 99 additions and 61 deletions

View File

@ -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 (*learn_status) (app_t app, ctrl_t ctrl, unsigned int flags);
gpg_error_t (*readcert) (app_t app, const char *certid, gpg_error_t (*readcert) (app_t app, const char *certid,
unsigned char **cert, size_t *certlen); 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); unsigned char **pk, size_t *pklen);
gpg_error_t (*getattr) (app_t app, ctrl_t ctrl, const char *name); gpg_error_t (*getattr) (app_t app, ctrl_t ctrl, const char *name);
gpg_error_t (*setattr) (app_t app, 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); unsigned int flags);
gpg_error_t app_readcert (app_t app, const char *certid, gpg_error_t app_readcert (app_t app, const char *certid,
unsigned char **cert, size_t *certlen); 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); unsigned char **pk, size_t *pklen);
gpg_error_t app_getattr (app_t app, ctrl_t ctrl, const char *name); 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, gpg_error_t app_setattr (app_t app, const char *name,

View File

@ -618,13 +618,17 @@ do_readcert (app_t app, const char *certid,
certificate parsing code in commands.c:cmd_readkey. For internal certificate parsing code in commands.c:cmd_readkey. For internal
use PK and PKLEN may be NULL to just check for an existing key. */ use PK and PKLEN may be NULL to just check for an existing key. */
static gpg_error_t 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; gpg_error_t err;
unsigned char *buffer[2]; unsigned char *buffer[2];
size_t buflen[2]; size_t buflen[2];
unsigned short path[1] = { 0x4500 }; unsigned short path[1] = { 0x4500 };
if (advanced)
return GPG_ERR_NOT_SUPPORTED;
/* We use a generic name to retrieve PK.AUT.IFD-SPK. */ /* We use a generic name to retrieve PK.AUT.IFD-SPK. */
if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3) if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
; ;
@ -698,7 +702,7 @@ do_writekey (app_t app, ctrl_t ctrl,
else else
return gpg_error (GPG_ERR_INV_ID); 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); return gpg_error (GPG_ERR_EEXIST);
/* Parse the S-expression. */ /* Parse the S-expression. */

View File

@ -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 buffer. On error PK and PKLEN are not changed and an error code is
returned. */ returned. */
static gpg_error_t 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 #if GNUPG_MAJOR_VERSION > 1
gpg_error_t err; gpg_error_t err;
@ -1749,7 +1750,30 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
buf = app->app_local->pk[keyno].key; buf = app->app_local->pk[keyno].key;
if (!buf) if (!buf)
return gpg_error (GPG_ERR_NO_PUBKEY); return gpg_error (GPG_ERR_NO_PUBKEY);
*pklen = app->app_local->pk[keyno].keylen;;
if (advanced)
{
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); *pk = xtrymalloc (*pklen);
if (!*pk) if (!*pk)
{ {
@ -1758,6 +1782,8 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
return err; return err;
} }
memcpy (*pk, buf, *pklen); memcpy (*pk, buf, *pklen);
}
return 0; return 0;
#else #else
return gpg_error (GPG_ERR_NOT_IMPLEMENTED); return gpg_error (GPG_ERR_NOT_IMPLEMENTED);

View File

@ -612,7 +612,8 @@ app_readcert (app_t app, const char *certid,
This function might not be supported by all applications. */ This function might not be supported by all applications. */
gpg_error_t 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; 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*/); err = lock_reader (app->slot, NULL /*FIXME*/);
if (err) if (err)
return err; return err;
err= app->fnc.readkey (app, keyid, pk, pklen); err= app->fnc.readkey (app, advanced, keyid, pk, pklen);
unlock_reader (app->slot); unlock_reader (app->slot);
return err; return err;
} }

View File

@ -729,17 +729,19 @@ cmd_readcert (assuan_context_t ctx, char *line)
static const char hlp_readkey[] = static const char hlp_readkey[] =
"READKEY <keyid>\n" "READKEY [--advanced] <keyid>\n"
"\n" "\n"
"Return the public key for the given cert or key ID as a standard\n" "Return the public key for the given cert or key ID as a standard\n"
"S-expression.\n" "S-expression.\n"
"In --advanced mode it returns the S-expression in advanced format.\n"
"\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 static gpg_error_t
cmd_readkey (assuan_context_t ctx, char *line) cmd_readkey (assuan_context_t ctx, char *line)
{ {
ctrl_t ctrl = assuan_get_pointer (ctx); ctrl_t ctrl = assuan_get_pointer (ctx);
int rc; int rc;
int advanced = 0;
unsigned char *cert = NULL; unsigned char *cert = NULL;
size_t ncert, n; size_t ncert, n;
ksba_cert_t kc = NULL; ksba_cert_t kc = NULL;
@ -750,11 +752,16 @@ cmd_readkey (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl, NULL))) if ((rc = open_card (ctrl, NULL)))
return rc; return rc;
if (has_option (line, "--advanced"))
advanced = 1;
line = skip_options (line);
line = xstrdup (line); /* Need a copy of the line. */ line = xstrdup (line); /* Need a copy of the line. */
/* If the application supports the READKEY function we use that. /* If the application supports the READKEY function we use that.
Otherwise we use the old way by extracting it from the Otherwise we use the old way by extracting it from the
certificate. */ certificate. */
rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen); rc = app_readkey (ctrl->app_ctx, advanced, line, &pk, &pklen);
if (!rc) if (!rc)
{ /* Yeah, got that key - send it back. */ { /* Yeah, got that key - send it back. */
rc = assuan_send_data (ctx, pk, pklen); rc = assuan_send_data (ctx, pk, pklen);