diff --git a/scd/ChangeLog b/scd/ChangeLog index efc888fd7..e53c8c79f 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,9 @@ +2009-03-10 Werner Koch + + * app-openpgp.c (send_key_attr): New. + (do_getattr): New attribute KEY_ATTR. + * command.c (send_status_direct): New. + 2009-03-06 Werner Koch * app-nks.c (do_learn_status): Factor code out to.. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index b6e6a3565..4bc28d30b 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -151,7 +151,7 @@ struct app_local_s { key. Might be NULL if key is not available. */ size_t keylen; /* The length of the above S-expression. This - is usullay only required for cross checks + is usually only required for cross checks because the length of an S-expression is implicitly available. */ } pk[3]; @@ -746,6 +746,24 @@ send_key_data (ctrl_t ctrl, const char *name, xfree (buf); } + +static void +send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number) +{ + char buffer[200]; + + assert (number >=0 && number < DIM(app->app_local->keyattr)); + + /* We only support RSA thus the algo identifier is fixed to 1. */ + snprintf (buffer, sizeof buffer, "%d 1 %u %u %d", + number+1, + app->app_local->keyattr[number].n_bits, + app->app_local->keyattr[number].e_bits, + app->app_local->keyattr[number].format); + send_status_direct (ctrl, keyword, buffer); +} + + /* Implement the GETATTR command. This is similar to the LEARN command but returns just one value via the status interface. */ static gpg_error_t @@ -763,6 +781,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) { "PUBKEY-URL", 0x5F50 }, { "KEY-FPR", 0x00C5, 3 }, { "KEY-TIME", 0x00CD, 4 }, + { "KEY-ATTR", 0x0000, -5 }, { "CA-FPR", 0x00C6, 3 }, { "CHV-STATUS", 0x00C4, 1 }, { "SIG-COUNTER", 0x0093, 2 }, @@ -811,14 +830,16 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) } if (table[idx].special == -2) { - char tmp[50]; + char tmp[100]; - sprintf (tmp, "gc=%d ki=%d fc=%d pd=%d mcl3=%u", - app->app_local->extcap.get_challenge, - app->app_local->extcap.key_import, - app->app_local->extcap.change_force_chv, - app->app_local->extcap.private_dos, - app->app_local->extcap.max_certlen_3); + snprintf (tmp, sizeof tmp, + "gc=%d ki=%d fc=%d pd=%d mcl3=%u aac=%d", + app->app_local->extcap.get_challenge, + app->app_local->extcap.key_import, + app->app_local->extcap.change_force_chv, + app->app_local->extcap.private_dos, + app->app_local->extcap.max_certlen_3, + app->app_local->extcap.algo_attr_change); send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); return 0; } @@ -845,6 +866,12 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) } return gpg_error (GPG_ERR_INV_NAME); } + if (table[idx].special == -5) + { + for (i=0; i < 3; i++) + send_key_attr (ctrl, app, table[idx].name, i); + return 0; + } relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &rc); if (relptr) diff --git a/scd/command.c b/scd/command.c index 91868a041..2fa1f7c3e 100644 --- a/scd/command.c +++ b/scd/command.c @@ -2018,6 +2018,18 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...) } +/* Send a ready formatted status line via assuan. */ +void +send_status_direct (ctrl_t ctrl, const char *keyword, const char *args) +{ + assuan_context_t ctx = ctrl->server_local->assuan_ctx; + + if (strchr (args, '\n')) + log_error ("error: LF detected in status line - not sending\n"); + else + assuan_write_status (ctx, keyword, args); +} + /* Helper to send the clients a status change notification. */ static void diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 221f84fe0..7c636920b 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -125,6 +125,7 @@ void initialize_module_command (void); int scd_command_handler (ctrl_t, int); void send_status_info (ctrl_t ctrl, const char *keyword, ...) GNUPG_GCC_A_SENTINEL(1); +void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args); void scd_update_reader_status_file (void);