Add server option with-ephemeral-keys.

Extend SCD LEARN command.
This commit is contained in:
Werner Koch 2009-03-18 11:18:56 +00:00
parent 370f841a01
commit a3b63ac1dc
14 changed files with 117 additions and 74 deletions

View File

@ -1,3 +1,12 @@
2009-03-18 Werner Koch <wk@g10code.com>
* command.c (cmd_learn): Add option --keypairinfo.
* app.c (app_write_learn_status): Add arg FLAGS.
* app-common.h (struct app_ctx_s): Add arg FLAGS to LEARN_STATUS.
Change all implementors.
* app-p15.c (do_learn_status): Take care of flag bit 0.
* app-nks.c (do_learn_status, do_learn_status_core): Ditto.
2009-03-10 Werner Koch <wk@g10code.com>
* app-openpgp.c (send_key_attr): New.

View File

@ -67,7 +67,7 @@ struct app_ctx_s {
struct app_local_s *app_local; /* Local to the application. */
struct {
void (*deinit) (app_t app);
gpg_error_t (*learn_status) (app_t app, ctrl_t ctrl);
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,
@ -145,7 +145,8 @@ char *get_supported_applications (void);
void release_application (app_t app);
gpg_error_t app_munge_serialno (app_t app);
gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp);
gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl);
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,

View File

@ -86,7 +86,7 @@
static gpg_error_t
do_learn_status (app_t app, ctrl_t ctrl)
do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
gpg_error_t err;
char ct_buf[100], id_buf[100];
@ -97,6 +97,8 @@ do_learn_status (app_t app, ctrl_t ctrl)
ksba_cert_t cert;
int fid;
(void)flags;
/* Return the certificate of the card holder. */
fid = 0xC000;
len = app_help_read_length_of_cert (app->slot, fid, &certoff);

View File

@ -147,7 +147,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
static gpg_error_t
do_learn_status (app_t app, ctrl_t ctrl)
do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
static const char *names[] = {
"X-KBLZ",
@ -167,6 +167,8 @@ do_learn_status (app_t app, ctrl_t ctrl)
gpg_error_t err = 0;
int idx;
(void)flags;
for (idx=0; names[idx] && !err; idx++)
err = do_getattr (app, ctrl, names[idx]);
return err;

View File

@ -309,7 +309,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
static void
do_learn_status_core (app_t app, ctrl_t ctrl, int is_sigg)
do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
{
gpg_error_t err;
char ct_buf[100], id_buf[100];
@ -332,7 +332,7 @@ do_learn_status_core (app_t app, ctrl_t ctrl, int is_sigg)
if (!!filelist[i].is_sigg != !!is_sigg)
continue;
if (filelist[i].certtype)
if (filelist[i].certtype && !(flags &1))
{
size_t len;
@ -377,7 +377,7 @@ do_learn_status_core (app_t app, ctrl_t ctrl, int is_sigg)
static gpg_error_t
do_learn_status (app_t app, ctrl_t ctrl)
do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
gpg_error_t err;
@ -385,13 +385,13 @@ do_learn_status (app_t app, ctrl_t ctrl)
if (err)
return err;
do_learn_status_core (app, ctrl, 0);
do_learn_status_core (app, ctrl, flags, 0);
err = switch_application (app, 1);
if (err)
return 0; /* Silently ignore if we can't switch to SigG. */
do_learn_status_core (app, ctrl, 1);
do_learn_status_core (app, ctrl, flags, 1);
return 0;
}

View File

@ -1295,8 +1295,10 @@ send_keypair_info (app_t app, ctrl_t ctrl, int keyno)
/* Handle the LEARN command for OpenPGP. */
static gpg_error_t
do_learn_status (app_t app, ctrl_t ctrl)
do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
(void)flags;
do_getattr (app, ctrl, "EXTCAP");
do_getattr (app, ctrl, "DISP-NAME");
do_getattr (app, ctrl, "DISP-LANG");

View File

@ -2492,17 +2492,23 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
/* This is the handler for the LEARN command. */
static gpg_error_t
do_learn_status (app_t app, ctrl_t ctrl)
do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
gpg_error_t err;
err = send_certinfo (app, ctrl, "100", app->app_local->certificate_info);
if (!err)
err = send_certinfo (app, ctrl, "101",
app->app_local->trusted_certificate_info);
if (!err)
err = send_certinfo (app, ctrl, "102",
app->app_local->useful_certificate_info);
if ((flags & 1))
err = 0;
else
{
err = send_certinfo (app, ctrl, "100", app->app_local->certificate_info);
if (!err)
err = send_certinfo (app, ctrl, "101",
app->app_local->trusted_certificate_info);
if (!err)
err = send_certinfo (app, ctrl, "102",
app->app_local->useful_certificate_info);
}
if (!err)
err = send_keypairinfo (app, ctrl, app->app_local->private_key_info);

View File

@ -542,7 +542,7 @@ app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
/* Write out the application specifig status lines for the LEARN
command. */
gpg_error_t
app_write_learn_status (app_t app, ctrl_t ctrl)
app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
gpg_error_t err;
@ -553,13 +553,14 @@ app_write_learn_status (app_t app, ctrl_t ctrl)
if (!app->fnc.learn_status)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
if (app->apptype)
/* We do not send APPTYPE if only keypairinfo is requested. */
if (app->apptype && !(flags & 1))
send_status_info (ctrl, "APPTYPE",
app->apptype, strlen (app->apptype), NULL, 0);
err = lock_reader (app->slot);
if (err)
return err;
err = app->fnc.learn_status (app, ctrl);
err = app->fnc.learn_status (app, ctrl, flags);
unlock_reader (app->slot);
return err;
}

View File

@ -1,6 +1,6 @@
/* command.c - SCdaemon command handler
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
* 2007, 2008 Free Software Foundation, Inc.
* 2007, 2008, 2009 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -184,7 +184,7 @@ update_card_removed (int slot, int value)
/* Check whether the option NAME appears in LINE */
/* Check whether the option NAME appears in LINE. Returns 1 or 0. */
static int
has_option (const char *line, const char *name)
{
@ -528,7 +528,7 @@ cmd_serialno (assuan_context_t ctx, char *line)
/* LEARN [--force]
/* LEARN [--force] [--keypairinfo]
Learn all useful information of the currently inserted card. When
used without the force options, the command might do an INQUIRE
@ -538,8 +538,13 @@ cmd_serialno (assuan_context_t ctx, char *line)
The client should just send an "END" if the processing should go on
or a "CANCEL" to force the function to terminate with a Cancel
error message. The response of this command is a list of status
lines formatted as this:
error message.
With the option --keypairinfo only KEYPARIINFO lstatus lines are
returned.
The response of this command is a list of status lines formatted as
this:
S APPTYPE <apptype>
@ -589,13 +594,14 @@ cmd_serialno (assuan_context_t ctx, char *line)
The URL to be used for locating the entire public key.
Note, that this function may be even be used on a locked card.
Note, that this function may even be used on a locked card.
*/
static int
cmd_learn (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
int rc = 0;
int only_keypairinfo = has_option (line, "--keypairinfo");
if ((rc = open_card (ctrl, NULL)))
return rc;
@ -604,51 +610,53 @@ cmd_learn (assuan_context_t ctx, char *line)
the card using a serial number and inquiring the client with
that. The client may choose to cancel the operation if he already
knows about this card */
{
char *serial_and_stamp;
char *serial;
time_t stamp;
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
if (rc)
return rc;
rc = estream_asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
xfree (serial);
if (rc < 0)
return out_of_core ();
rc = 0;
assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
if (!has_option (line, "--force"))
{
char *command;
rc = estream_asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
if (rc < 0)
{
xfree (serial_and_stamp);
return out_of_core ();
}
rc = 0;
rc = assuan_inquire (ctx, command, NULL, NULL, 0);
xfree (command);
if (rc)
{
if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
log_error ("inquire KNOWNCARDP failed: %s\n",
gpg_strerror (rc));
xfree (serial_and_stamp);
return rc;
}
/* not canceled, so we have to proceeed */
}
xfree (serial_and_stamp);
}
if (!only_keypairinfo)
{
char *serial_and_stamp;
char *serial;
time_t stamp;
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
if (rc)
return rc;
rc = estream_asprintf (&serial_and_stamp, "%s %lu",
serial, (unsigned long)stamp);
xfree (serial);
if (rc < 0)
return out_of_core ();
rc = 0;
assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
if (!has_option (line, "--force"))
{
char *command;
rc = estream_asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
if (rc < 0)
{
xfree (serial_and_stamp);
return out_of_core ();
}
rc = 0;
rc = assuan_inquire (ctx, command, NULL, NULL, 0);
xfree (command);
if (rc)
{
if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
log_error ("inquire KNOWNCARDP failed: %s\n",
gpg_strerror (rc));
xfree (serial_and_stamp);
return rc;
}
/* Not canceled, so we have to proceeed. */
}
xfree (serial_and_stamp);
}
/* Let the application print out its collection of useful status
information. */
if (!rc)
rc = app_write_learn_status (ctrl->app_ctx, ctrl);
rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
TEST_CARD_REMOVAL (ctrl, rc);
return rc;

View File

@ -1,3 +1,11 @@
2009-03-18 Werner Koch <wk@g10code.com>
* gpgsm.h (struct opt): Move field WITH_EPHEMERAL_KEYS to struct
server_control_s.
* gpgsm.c (main): Change accordingly.
* keylist.c (list_internal_keys): Ditto.
* server.c (option_handler): Add "with-ephemeral-keys".
2009-03-12 Werner Koch <wk@g10code.com>
* certdump.c (gpgsm_dump_time): Remove.

View File

@ -1259,7 +1259,7 @@ main ( int argc, char **argv)
case oWithKeyData: opt.with_key_data=1; /* fall thru */
case oWithColons: ctrl.with_colons = 1; break;
case oWithValidation: ctrl.with_validation=1; break;
case oWithEphemeralKeys: opt.with_ephemeral_keys=1; break;
case oWithEphemeralKeys: ctrl.with_ephemeral_keys=1; break;
case oSkipVerify: opt.skip_verify=1; break;

View File

@ -82,9 +82,6 @@ struct
int with_md5_fingerprint; /* Also print an MD5 fingerprint for
standard key listings. */
int with_ephemeral_keys; /* Include ephemeral flagged keys in the
keylisting. */
int armor; /* force base64 armoring (see also ctrl.with_base64) */
int no_armor; /* don't try to figure out whether data is base64 armored*/
@ -176,6 +173,8 @@ struct server_control_s
int with_colons; /* Use column delimited output format */
int with_chain; /* Include the certifying certs in a listing */
int with_validation;/* Validate each key while listing. */
int with_ephemeral_keys; /* Include ephemeral flagged keys in the
keylisting. */
int autodetect_encoding; /* Try to detect the input encoding */
int is_pem; /* Is in PEM format */

View File

@ -1292,7 +1292,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
gpg_error_t rc = 0;
const char *lastresname, *resname;
int have_secret;
int want_ephemeral = opt.with_ephemeral_keys;
int want_ephemeral = ctrl->with_ephemeral_keys;
hd = keydb_new (0);
if (!hd)

View File

@ -296,6 +296,11 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
}
else if (!strcmp (key, "allow-pinentry-notify"))
ctrl->server_local->allow_pinentry_notify = 1;
else if (!strcmp (key, "with-ephemeral-keys"))
{
int i = *value? atoi (value) : 0;
ctrl->with_ephemeral_keys = i;
}
else
return gpg_error (GPG_ERR_UNKNOWN_OPTION);