1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +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

@ -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);
}
memcpy (*pk, buf, *pklen);
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);
}
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