mirror of
git://git.gnupg.org/gnupg.git
synced 2024-06-14 00:19:50 +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:
parent
c1ea0b577a
commit
f9da935c3e
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,7 +1750,30 @@ 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;;
|
||||
|
||||
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);
|
||||
if (!*pk)
|
||||
{
|
||||
|
@ -1758,6 +1782,8 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
|
|||
return err;
|
||||
}
|
||||
memcpy (*pk, buf, *pklen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user