aboutsummaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
Diffstat (limited to 'agent')
-rw-r--r--agent/agent.h25
-rw-r--r--agent/cache.c1
-rw-r--r--agent/call-pinentry.c156
-rw-r--r--agent/call-scd.c174
-rw-r--r--agent/command-ssh.c11
-rw-r--r--agent/command.c98
-rw-r--r--agent/cvt-openpgp.c14
-rw-r--r--agent/divert-scd.c73
-rw-r--r--agent/findkey.c232
-rw-r--r--agent/genkey.c42
-rw-r--r--agent/gpg-agent.c6
-rw-r--r--agent/keyformat.txt66
-rw-r--r--agent/learncard.c1
-rw-r--r--agent/pkdecrypt.c9
-rw-r--r--agent/pksign.c26
-rw-r--r--agent/preset-passphrase.c1
-rw-r--r--agent/protect-tool.c22
-rw-r--r--agent/protect.c17
-rw-r--r--agent/trans.c1
-rw-r--r--agent/trustlist.c3
20 files changed, 709 insertions, 269 deletions
diff --git a/agent/agent.h b/agent/agent.h
index 0f804cd8b..84e5e782b 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -361,6 +361,15 @@ typedef int (*lookup_ttl_t)(const char *hexgrip);
#endif
+/* Information from scdaemon for card keys. */
+struct card_key_info_s
+{
+ struct card_key_info_s *next;
+ char keygrip[40];
+ char *serialno;
+ char *idstr;
+};
+
/*-- gpg-agent.c --*/
void agent_exit (int rc)
GPGRT_ATTR_NORETURN; /* Also implemented in other tools */
@@ -389,8 +398,11 @@ void bump_key_eventcounter (void);
void bump_card_eventcounter (void);
void start_command_handler (ctrl_t, gnupg_fd_t, gnupg_fd_t);
gpg_error_t pinentry_loopback (ctrl_t, const char *keyword,
- unsigned char **buffer, size_t *size,
- size_t max_length);
+ unsigned char **buffer, size_t *size,
+ size_t max_length);
+gpg_error_t pinentry_loopback_confirm (ctrl_t ctrl, const char *desc,
+ int ask_confirmation,
+ const char *ok, const char *notok);
#ifdef HAVE_W32_SYSTEM
int serve_mmapped_ssh_request (ctrl_t ctrl,
@@ -414,7 +426,8 @@ void start_command_handler_ssh (ctrl_t, gnupg_fd_t);
gpg_error_t agent_modify_description (const char *in, const char *comment,
const gcry_sexp_t key, char **result);
int agent_write_private_key (const unsigned char *grip,
- const void *buffer, size_t length, int force);
+ const void *buffer, size_t length, int force,
+ const char *serialno, const char *keyref);
gpg_error_t agent_key_from_file (ctrl_t ctrl,
const char *cache_nonce,
const char *desc_text,
@@ -543,10 +556,12 @@ void agent_reload_trustlist (void);
/*-- divert-scd.c --*/
int divert_pksign (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *grip,
const unsigned char *digest, size_t digestlen, int algo,
const unsigned char *shadow_info, unsigned char **r_sig,
size_t *r_siglen);
int divert_pkdecrypt (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *grip,
const unsigned char *cipher,
const unsigned char *shadow_info,
char **r_buf, size_t *r_len, int *r_padding);
@@ -603,6 +618,10 @@ int agent_card_scd (ctrl_t ctrl, const char *cmdline,
int (*getpin_cb)(void *, const char *,
const char *, char*, size_t),
void *getpin_cb_arg, void *assuan_context);
+void agent_card_free_keyinfo (struct card_key_info_s *l);
+gpg_error_t agent_card_keyinfo (ctrl_t ctrl, const char *keygrip,
+ struct card_key_info_s **result);
+void agent_card_killscd (void);
/*-- learncard.c --*/
diff --git a/agent/cache.c b/agent/cache.c
index 799d595ab..4a3e5a547 100644
--- a/agent/cache.c
+++ b/agent/cache.c
@@ -23,7 +23,6 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include <assert.h>
#include <npth.h>
#include "agent.h"
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 34dde3744..a895a8b8f 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -24,7 +24,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
#ifndef HAVE_W32_SYSTEM
@@ -424,7 +423,17 @@ start_pinentry (ctrl_t ctrl)
opt.no_grab? "OPTION no-grab":"OPTION grab",
NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
- return unlock_pinentry (ctrl, rc);
+ {
+ if (gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED
+ || gpg_err_code (rc) == GPG_ERR_UNKNOWN_OPTION)
+ {
+ if (opt.verbose)
+ log_info ("Option no-grab/grab is ignored by pinentry.\n");
+ /* Keep going even if the feature is not supported. */
+ }
+ else
+ return unlock_pinentry (ctrl, rc);
+ }
value = session_env_getenv (ctrl->session_env, "GPG_TTY");
if (value)
@@ -439,7 +448,7 @@ start_pinentry (ctrl_t ctrl)
return unlock_pinentry (ctrl, rc);
}
value = session_env_getenv (ctrl->session_env, "TERM");
- if (value)
+ if (value && *value)
{
char *optstr;
if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 )
@@ -949,15 +958,14 @@ build_cmd_setdesc (char *line, size_t linelen, const char *desc)
static void *
watch_sock (void *arg)
{
- gnupg_fd_t *p = (gnupg_fd_t *)arg;
pid_t pid = assuan_get_pid (entry_ctx);
while (1)
{
int err;
- gnupg_fd_t sock = *p;
fd_set fdset;
struct timeval timeout = { 0, 500000 };
+ gnupg_fd_t sock = *(gnupg_fd_t *)arg;
if (sock == GNUPG_INVALID_FD)
return NULL;
@@ -995,18 +1003,11 @@ watch_sock (void *arg)
}
-/* Ask pinentry to get a pin by "GETPIN" command, spawning a thread
- detecting the socket's EOF.
- */
static gpg_error_t
-do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
+watch_sock_start (gnupg_fd_t *sock_p, npth_t *thread_p)
{
npth_attr_t tattr;
- gpg_error_t rc;
int err;
- npth_t thread;
- int saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
- gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
err = npth_attr_init (&tattr);
if (err)
@@ -1016,7 +1017,7 @@ do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
}
npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
- err = npth_create (&thread, &tattr, watch_sock, (void *)&sock_watched);
+ err = npth_create (thread_p, &tattr, watch_sock, sock_p);
npth_attr_destroy (&tattr);
if (err)
{
@@ -1024,6 +1025,36 @@ do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
return gpg_error_from_errno (err);
}
+ return 0;
+}
+
+static void
+watch_sock_end (gnupg_fd_t *sock_p, npth_t *thread_p)
+{
+ int err;
+
+ *sock_p = GNUPG_INVALID_FD;
+ err = npth_join (*thread_p, NULL);
+ if (err)
+ log_error ("watch_sock_end: error joining thread: %s\n", strerror (err));
+}
+
+
+/* Ask pinentry to get a pin by "GETPIN" command, spawning a thread
+ detecting the socket's EOF.
+ */
+static gpg_error_t
+do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
+{
+ gpg_error_t rc;
+ int saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
+ gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
+ npth_t thread;
+
+ rc = watch_sock_start (&sock_watched, &thread);
+ if (rc)
+ return rc;
+
assuan_begin_confidential (entry_ctx);
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm,
inq_quality, entry_ctx,
@@ -1040,10 +1071,7 @@ do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
&& gpg_err_code (rc) == GPG_ERR_CANCELED)
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
- sock_watched = GNUPG_INVALID_FD;
- err = npth_join (thread, NULL);
- if (err)
- log_error ("do_getpin: error joining thread: %s\n", strerror (err));
+ watch_sock_end (&sock_watched, &thread);
return rc;
}
@@ -1392,6 +1420,9 @@ agent_get_confirmation (ctrl_t ctrl,
if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
return gpg_error (GPG_ERR_CANCELED);
+ if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
+ return pinentry_loopback_confirm (ctrl, desc, 1, ok, notok);
+
return gpg_error (GPG_ERR_NO_PIN_ENTRY);
}
@@ -1445,70 +1476,38 @@ agent_get_confirmation (ctrl_t ctrl,
return unlock_pinentry (ctrl, rc);
}
- rc = assuan_transact (entry_ctx, "CONFIRM",
- NULL, NULL, NULL, NULL, NULL, NULL);
- if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
- rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
-
- return unlock_pinentry (ctrl, rc);
-}
-
-
-
-/* Pop up the PINentry, display the text DESC and a button with the
- text OK_BTN (which may be NULL to use the default of "OK") and wait
- for the user to hit this button. The return value is not
- relevant. */
-int
-agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
-{
- int rc;
- char line[ASSUAN_LINELENGTH];
+ {
+ gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
+ npth_t thread;
- if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
- return gpg_error (GPG_ERR_CANCELED);
+ rc = watch_sock_start (&sock_watched, &thread);
+ if (rc)
+ return rc;
- rc = start_pinentry (ctrl);
- if (rc)
- return rc;
+ rc = assuan_transact (entry_ctx, "CONFIRM",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
+ rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
- if (desc)
- build_cmd_setdesc (line, DIM(line), desc);
- else
- snprintf (line, DIM(line), "RESET");
- rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
- /* Most pinentries out in the wild return the old Assuan error code
- for canceled which gets translated to an assuan Cancel error and
- not to the code for a user cancel. Fix this here. */
- if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
- rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
+ watch_sock_end (&sock_watched, &thread);
- if (rc)
return unlock_pinentry (ctrl, rc);
-
- if (ok_btn)
- {
- snprintf (line, DIM(line), "SETOK %s", ok_btn);
- rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
- NULL, NULL, NULL);
- if (rc)
- return unlock_pinentry (ctrl, rc);
- }
-
- rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL,
- NULL, NULL, NULL);
- if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
- rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
-
- return unlock_pinentry (ctrl, rc);
+ }
}
+
/* The thread running the popup message. */
static void *
popup_message_thread (void *arg)
{
- (void)arg;
+ gpg_error_t rc;
+ gnupg_fd_t sock_watched = *(gnupg_fd_t *)arg;
+ npth_t thread;
+
+ rc = watch_sock_start (&sock_watched, &thread);
+ if (rc)
+ return NULL;
/* We use the --one-button hack instead of the MESSAGE command to
allow the use of old Pinentries. Those old Pinentries will then
@@ -1516,6 +1515,7 @@ popup_message_thread (void *arg)
annoyance. */
assuan_transact (entry_ctx, "CONFIRM --one-button",
NULL, NULL, NULL, NULL, NULL, NULL);
+ watch_sock_end (&sock_watched, &thread);
popup_finished = 1;
return NULL;
}
@@ -1536,7 +1536,15 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
int err;
if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
- return gpg_error (GPG_ERR_CANCELED);
+ {
+ if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
+ return gpg_error (GPG_ERR_CANCELED);
+
+ if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
+ return pinentry_loopback_confirm (ctrl, desc, 0, ok_btn, NULL);
+
+ return gpg_error (GPG_ERR_NO_PIN_ENTRY);
+ }
rc = start_pinentry (ctrl);
if (rc)
@@ -1564,7 +1572,8 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
popup_finished = 0;
- err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL);
+ err = npth_create (&popup_tid, &tattr, popup_message_thread,
+ &ctrl->thread_startup.fd);
npth_attr_destroy (&tattr);
if (err)
{
@@ -1587,6 +1596,9 @@ agent_popup_message_stop (ctrl_t ctrl)
(void)ctrl;
+ if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
+ return;
+
if (!popup_tid || !entry_ctx)
{
log_debug ("agent_popup_message_stop called with no active popup\n");
diff --git a/agent/call-scd.c b/agent/call-scd.c
index b2266225e..a96f5b783 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -25,7 +25,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
#include <unistd.h>
#ifdef HAVE_SIGNAL_H
# include <signal.h>
@@ -330,13 +329,13 @@ start_scd (ctrl_t ctrl)
{
ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
if (!ctrl->scd_local)
- {
- err = gpg_error_from_syserror ();
- rc = npth_mutex_unlock (&start_scd_lock);
- if (rc)
- log_error ("failed to release the start_scd lock: %s\n", strerror (rc));
- return err;
- }
+ {
+ err = gpg_error_from_syserror ();
+ rc = npth_mutex_unlock (&start_scd_lock);
+ if (rc)
+ log_error ("failed to release the start_scd lock: %s\n", strerror (rc));
+ return err;
+ }
ctrl->scd_local->next_local = scd_local_list;
scd_local_list = ctrl->scd_local;
}
@@ -1282,6 +1281,156 @@ agent_card_cardlist (ctrl_t ctrl, strlist_t *result)
}
+struct card_keyinfo_parm_s {
+ int error;
+ struct card_key_info_s *list;
+};
+
+/* Callback function for agent_card_keylist. */
+static gpg_error_t
+card_keyinfo_cb (void *opaque, const char *line)
+{
+ struct card_keyinfo_parm_s *parm = opaque;
+ const char *keyword = line;
+ int keywordlen;
+
+ for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+ ;
+ while (spacep (line))
+ line++;
+
+ if (keywordlen == 7 && !memcmp (keyword, "KEYINFO", keywordlen))
+ {
+ const char *s;
+ int n;
+ struct card_key_info_s *keyinfo;
+ struct card_key_info_s **l_p = &parm->list;
+
+ while ((*l_p))
+ l_p = &(*l_p)->next;
+
+ keyinfo = xtrycalloc (1, sizeof *keyinfo);
+ if (!keyinfo)
+ {
+ alloc_error:
+ if (!parm->error)
+ parm->error = gpg_error_from_syserror ();
+ return 0;
+ }
+
+ for (n=0,s=line; hexdigitp (s); s++, n++)
+ ;
+
+ if (n != 40)
+ {
+ parm_error:
+ if (!parm->error)
+ parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
+ return 0;
+ }
+
+ memcpy (keyinfo->keygrip, line, 40);
+
+ line = s;
+
+ if (!*line)
+ goto parm_error;
+
+ while (spacep (line))
+ line++;
+
+ if (*line++ != 'T')
+ goto parm_error;
+
+ if (!*line)
+ goto parm_error;
+
+ while (spacep (line))
+ line++;
+
+ for (n=0,s=line; hexdigitp (s); s++, n++)
+ ;
+
+ if (!n)
+ goto parm_error;
+
+ keyinfo->serialno = xtrymalloc (n+1);
+ if (!keyinfo->serialno)
+ goto alloc_error;
+
+ memcpy (keyinfo->serialno, line, n);
+ keyinfo->serialno[n] = 0;
+
+ line = s;
+
+ if (!*line)
+ goto parm_error;
+
+ while (spacep (line))
+ line++;
+
+ if (!*line)
+ goto parm_error;
+
+ keyinfo->idstr = xtrystrdup (line);
+ if (!keyinfo->idstr)
+ goto alloc_error;
+
+ *l_p = keyinfo;
+ }
+
+ return 0;
+}
+
+
+void
+agent_card_free_keyinfo (struct card_key_info_s *l)
+{
+ struct card_key_info_s *l_next;
+
+ for (; l; l = l_next)
+ {
+ l_next = l->next;
+ free (l->serialno);
+ free (l->idstr);
+ free (l);
+ }
+}
+
+/* Call the scdaemon to check if a key of KEYGRIP is available, or
+ retrieve list of available keys on cards. On success the allocated
+ structure is stored at RESULT. On error an error code is returned
+ and NULL is stored at RESULT. */
+gpg_error_t
+agent_card_keyinfo (ctrl_t ctrl, const char *keygrip,
+ struct card_key_info_s **result)
+{
+ int err;
+ struct card_keyinfo_parm_s parm;
+ char line[ASSUAN_LINELENGTH];
+
+ *result = NULL;
+
+ memset (&parm, 0, sizeof parm);
+ snprintf (line, sizeof line, "KEYINFO %s", keygrip ? keygrip : "--list");
+
+ err = start_scd (ctrl);
+ if (err)
+ return err;
+
+ err = assuan_transact (ctrl->scd_local->ctx, line,
+ NULL, NULL, NULL, NULL,
+ card_keyinfo_cb, &parm);
+ if (!err && parm.error)
+ err = parm.error;
+
+ if (!err)
+ *result = parm.list;
+ else
+ agent_card_free_keyinfo (parm.list);
+
+ return unlock_scd (ctrl, err);
+}
static gpg_error_t
pass_status_thru (void *opaque, const char *line)
@@ -1366,3 +1515,12 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
return unlock_scd (ctrl, 0);
}
+
+void
+agent_card_killscd (void)
+{
+ if (primary_scd_ctx == NULL)
+ return;
+ assuan_transact (primary_scd_ctx, "KILLSCD",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+}
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index ebd28ab5a..0849a06fc 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -41,7 +41,6 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <assert.h>
#ifndef HAVE_W32_SYSTEM
#include <sys/socket.h>
#include <sys/un.h>
@@ -1030,7 +1029,7 @@ search_control_file (ssh_control_file_t cf, const char *hexgrip,
{
gpg_error_t err;
- assert (strlen (hexgrip) == 40 );
+ log_assert (strlen (hexgrip) == 40 );
if (r_disabled)
*r_disabled = 0;
@@ -2646,7 +2645,7 @@ ssh_handler_request_identities (ctrl_t ctrl,
continue; /* Should not happen. */
if (cf->item.disabled)
continue;
- assert (strlen (cf->item.hexgrip) == 40);
+ log_assert (strlen (cf->item.hexgrip) == 40);
hex2bin (cf->item.hexgrip, grip, sizeof (grip));
err = agent_public_key_from_file (ctrl, grip, &key_public);
@@ -3008,8 +3007,8 @@ ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
goto out;
}
- gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
- /* FIXME: guarantee? */
+ buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON,
+ buffer_new, buffer_new_n);
if (*passphrase)
err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0, -1);
@@ -3142,7 +3141,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
goto out;
/* Store this key to our key storage. */
- err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
+ err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0, NULL, NULL);
if (err)
goto out;
diff --git a/agent/command.c b/agent/command.c
index 5e2b6df2b..b59532ce5 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -30,7 +30,6 @@
#include <string.h>
#include <ctype.h>
#include <unistd.h>
-#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
@@ -1075,7 +1074,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
static const char hlp_keyinfo[] =
- "KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>\n"
+ "KEYINFO [--[ssh-]list] [--data] [--ssh-fpr[=algo]] [--with-ssh] <keygrip>\n"
"\n"
"Return information about the key specified by the KEYGRIP. If the\n"
"key is not available GPG_ERR_NOT_FOUND is returned. If the option\n"
@@ -1111,7 +1110,9 @@ static const char hlp_keyinfo[] =
" '-' - Unknown protection.\n"
"\n"
"FPR returns the formatted ssh-style fingerprint of the key. It is only\n"
- " printed if the option --ssh-fpr has been used. It defaults to '-'.\n"
+ " printed if the option --ssh-fpr has been used. If ALGO is not given\n"
+ " to that option the default ssh fingerprint algo is used. Without the\n"
+ " option a '-' is printed.\n"
"\n"
"TTL is the TTL in seconds for that key or '-' if n/a.\n"
"\n"
@@ -1119,13 +1120,14 @@ static const char hlp_keyinfo[] =
" 'D' - The key has been disabled,\n"
" 'S' - The key is listed in sshcontrol (requires --with-ssh),\n"
" 'c' - Use of the key needs to be confirmed,\n"
+ " 'A' - The key is available on card,\n"
" '-' - No flags given.\n"
"\n"
"More information may be added in the future.";
static gpg_error_t
do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
int data, int with_ssh_fpr, int in_ssh,
- int ttl, int disabled, int confirm)
+ int ttl, int disabled, int confirm, int on_card)
{
gpg_error_t err;
char hexgrip[40+1];
@@ -1166,6 +1168,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
strcat (flagsbuf, "S");
if (confirm)
strcat (flagsbuf, "c");
+ if (on_card)
+ strcat (flagsbuf, "A");
if (!*flagsbuf)
strcpy (flagsbuf, "-");
@@ -1198,7 +1202,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
if (!agent_raw_key_from_file (ctrl, grip, &key))
{
- ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
+ ssh_get_fingerprint_string (key, with_ssh_fpr, &fpr);
gcry_sexp_release (key);
}
}
@@ -1256,8 +1260,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
}
-/* Entry int for the command KEYINFO. This function handles the
- command option processing. For details see hlp_keyinfo above. */
+/* Entry into the command KEYINFO. This function handles the
+ * command option processing. For details see hlp_keyinfo above. */
static gpg_error_t
cmd_keyinfo (assuan_context_t ctx, char *line)
{
@@ -1270,6 +1274,9 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
ssh_control_file_t cf = NULL;
char hexgrip[41];
int disabled, ttl, confirm, is_ssh;
+ struct card_key_info_s *keyinfo_on_cards;
+ struct card_key_info_s *l;
+ int on_card;
if (ctrl->restricted)
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
@@ -1279,13 +1286,29 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
else
list_mode = has_option (line, "--list");
opt_data = has_option (line, "--data");
- opt_ssh_fpr = has_option (line, "--ssh-fpr");
+
+ if (has_option_name (line, "--ssh-fpr"))
+ {
+ if (has_option (line, "--ssh-fpr=md5"))
+ opt_ssh_fpr = GCRY_MD_MD5;
+ else if (has_option (line, "--ssh-fpr=sha1"))
+ opt_ssh_fpr = GCRY_MD_SHA1;
+ else if (has_option (line, "--ssh-fpr=sha256"))
+ opt_ssh_fpr = GCRY_MD_SHA256;
+ else
+ opt_ssh_fpr = opt.ssh_fingerprint_digest;
+ }
+ else
+ opt_ssh_fpr = 0;
+
opt_with_ssh = has_option (line, "--with-ssh");
line = skip_options (line);
if (opt_with_ssh || list_mode == 2)
cf = ssh_open_control_file ();
+ agent_card_keyinfo (ctrl, NULL, &keyinfo_on_cards);
+
if (list_mode == 2)
{
if (cf)
@@ -1295,8 +1318,14 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
{
if (hex2bin (hexgrip, grip, 20) < 0 )
continue; /* Bad hex string. */
+
+ on_card = 0;
+ for (l = keyinfo_on_cards; l; l = l->next)
+ if (!memcmp (l->keygrip, hexgrip, 40))
+ on_card = 1;
+
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, 1,
- ttl, disabled, confirm);
+ ttl, disabled, confirm, on_card);
if (err)
goto leave;
}
@@ -1346,8 +1375,13 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
goto leave;
}
+ on_card = 0;
+ for (l = keyinfo_on_cards; l; l = l->next)
+ if (!memcmp (l->keygrip, hexgrip, 40))
+ on_card = 1;
+
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
- ttl, disabled, confirm);
+ ttl, disabled, confirm, on_card);
if (err)
goto leave;
}
@@ -1369,11 +1403,17 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
goto leave;
}
+ on_card = 0;
+ for (l = keyinfo_on_cards; l; l = l->next)
+ if (!memcmp (l->keygrip, line, 40))
+ on_card = 1;
+
err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
- ttl, disabled, confirm);
+ ttl, disabled, confirm, on_card);
}
leave:
+ agent_card_free_keyinfo (keyinfo_on_cards);
ssh_close_control_file (cf);
if (dir)
closedir (dir);
@@ -2196,7 +2236,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
goto leave; /* Invalid canonical encoded S-expression. */
if (passphrase)
{
- assert (!opt_unattended);
+ log_assert (!opt_unattended);
if (!cache_nonce)
{
char buf[12];
@@ -2239,10 +2279,11 @@ cmd_import_key (assuan_context_t ctx, char *line)
err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
ctrl->s2k_count, -1);
if (!err)
- err = agent_write_private_key (grip, finalkey, finalkeylen, force);
+ err = agent_write_private_key (grip, finalkey, finalkeylen, force,
+ NULL, NULL);
}
else
- err = agent_write_private_key (grip, key, realkeylen, force);
+ err = agent_write_private_key (grip, key, realkeylen, force, NULL, NULL);
leave:
gcry_sexp_release (openpgp_sexp);
@@ -3069,7 +3110,7 @@ cmd_getinfo (assuan_context_t ctx, char *line)
{
cmdopt = line;
if (!command_has_option (cmd, cmdopt))
- rc = gpg_error (GPG_ERR_GENERAL);
+ rc = gpg_error (GPG_ERR_FALSE);
}
}
}
@@ -3083,7 +3124,7 @@ cmd_getinfo (assuan_context_t ctx, char *line)
}
else if (!strcmp (line, "restricted"))
{
- rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_GENERAL);
+ rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_FALSE);
}
else if (ctrl->restricted)
{
@@ -3117,7 +3158,7 @@ cmd_getinfo (assuan_context_t ctx, char *line)
}
else if (!strcmp (line, "scd_running"))
{
- rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
+ rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_FALSE);
}
else if (!strcmp (line, "std_env_names"))
{
@@ -3639,3 +3680,26 @@ pinentry_loopback(ctrl_t ctrl, const char *keyword,
assuan_end_confidential (ctx);
return rc;
}
+
+/* Helper for the pinentry loopback mode to ask confirmation
+ or just to show message. */
+gpg_error_t
+pinentry_loopback_confirm (ctrl_t ctrl, const char *desc,
+ int ask_confirmation,
+ const char *ok, const char *notok)
+{
+ gpg_error_t err = 0;
+ assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+
+ if (desc)
+ err = print_assuan_status (ctx, "SETDESC", "%s", desc);
+ if (!err && ok)
+ err = print_assuan_status (ctx, "SETOK", "%s", ok);
+ if (!err && notok)
+ err = print_assuan_status (ctx, "SETNOTOK", "%s", notok);
+
+ if (!err)
+ err = assuan_inquire (ctx, ask_confirmation ? "CONFIRM 1" : "CONFIRM 0",
+ NULL, NULL, 0);
+ return err;
+}
diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
index 06cd1c840..003402956 100644
--- a/agent/cvt-openpgp.c
+++ b/agent/cvt-openpgp.c
@@ -22,7 +22,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
#include "agent.h"
#include "../common/i18n.h"
@@ -571,7 +570,7 @@ do_unprotect (const char *passphrase,
}
skey[i] = NULL;
skeylen = i;
- assert (skeylen <= skeysize);
+ log_assert (skeylen <= skeysize);
/* Note: at this point NDATA should be 2 for a simple
checksum or 20 for the sha1 digest. */
@@ -1067,7 +1066,8 @@ convert_from_openpgp_native (ctrl_t ctrl,
if (!agent_protect (*r_key, passphrase,
&protectedkey, &protectedkeylen,
ctrl->s2k_count, -1))
- agent_write_private_key (grip, protectedkey, protectedkeylen, 1);
+ agent_write_private_key (grip, protectedkey, protectedkeylen, 1,
+ NULL, NULL);
xfree (protectedkey);
}
else
@@ -1076,7 +1076,7 @@ convert_from_openpgp_native (ctrl_t ctrl,
agent_write_private_key (grip,
*r_key,
gcry_sexp_canon_len (*r_key, 0, NULL,NULL),
- 1);
+ 1, NULL, NULL);
}
}
@@ -1104,8 +1104,8 @@ apply_protection (gcry_mpi_t *array, int npkey, int nskey,
int ndata;
unsigned char *p, *data;
- assert (npkey < nskey);
- assert (nskey < DIM (bufarr));
+ log_assert (npkey < nskey);
+ log_assert (nskey < DIM (bufarr));
/* Collect only the secret key parameters into BUFARR et al and
compute the required size of the data buffer. */
@@ -1142,7 +1142,7 @@ apply_protection (gcry_mpi_t *array, int npkey, int nskey,
xfree (bufarr[i]);
bufarr[i] = NULL;
}
- assert (p == data + ndata - 20);
+ log_assert (p == data + ndata - 20);
/* Append a hash of the secret key parameters. */
gcry_md_hash_buffer (GCRY_MD_SHA1, p, data, ndata - 20);
diff --git a/agent/divert-scd.c b/agent/divert-scd.c
index e89c74a19..cfa2347c7 100644
--- a/agent/divert-scd.c
+++ b/agent/divert-scd.c
@@ -32,28 +32,50 @@
#include "../common/sexp-parse.h"
-static int
-ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
+static gpg_error_t
+ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info,
+ const unsigned char *grip, char **r_kid)
{
- int rc, i;
+ int i;
char *serialno;
int no_card = 0;
char *desc;
char *want_sn, *want_kid, *want_sn_disp;
int len;
+ struct card_key_info_s *keyinfo;
+ gpg_error_t err;
+ char hexgrip[41];
*r_kid = NULL;
- rc = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL);
- if (rc)
- return rc;
+ /* Scan device(s), and check if key for GRIP is available. */
+ err = agent_card_serialno (ctrl, &serialno, NULL);
+ if (!err)
+ {
+ xfree (serialno);
+ bin2hex (grip, 20, hexgrip);
+ err = agent_card_keyinfo (ctrl, hexgrip, &keyinfo);
+ if (!err)
+ {
+ /* Key for GRIP found, use it directly. */
+ agent_card_free_keyinfo (keyinfo);
+ if ((*r_kid = xtrystrdup (hexgrip)))
+ return 0;
+ else
+ return gpg_error_from_syserror ();
+ }
+ }
+
+ err = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL);
+ if (err)
+ return err;
want_sn_disp = xtrystrdup (want_sn);
if (!want_sn_disp)
{
- rc = gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
xfree (want_sn);
xfree (want_kid);
- return rc;
+ return err;
}
len = strlen (want_sn_disp);
@@ -76,8 +98,8 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
for (;;)
{
- rc = agent_card_serialno (ctrl, &serialno, want_sn);
- if (!rc)
+ err = agent_card_serialno (ctrl, &serialno, want_sn);
+ if (!err)
{
log_debug ("detected card with S/N %s\n", serialno);
i = strcmp (serialno, want_sn);
@@ -91,24 +113,24 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
return 0; /* yes, we have the correct card */
}
}
- else if (gpg_err_code (rc) == GPG_ERR_ENODEV)
+ else if (gpg_err_code (err) == GPG_ERR_ENODEV)
{
log_debug ("no device present\n");
- rc = 0;
+ err = 0;
no_card = 1;
}
- else if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT)
+ else if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
{
log_debug ("no card present\n");
- rc = 0;
+ err = 0;
no_card = 2;
}
else
{
- log_error ("error accessing card: %s\n", gpg_strerror (rc));
+ log_error ("error accessing card: %s\n", gpg_strerror (err));
}
- if (!rc)
+ if (!err)
{
if (asprintf (&desc,
"%s:%%0A%%0A"
@@ -119,24 +141,24 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
"insert the one with serial number"),
want_sn_disp) < 0)
{
- rc = out_of_core ();
+ err = out_of_core ();
}
else
{
- rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
+ err = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK &&
- gpg_err_code (rc) == GPG_ERR_NO_PIN_ENTRY)
- rc = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
+ gpg_err_code (err) == GPG_ERR_NO_PIN_ENTRY)
+ err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
xfree (desc);
}
}
- if (rc)
+ if (err)
{
xfree (want_sn_disp);
xfree (want_sn);
xfree (want_kid);
- return rc;
+ return err;
}
}
}
@@ -434,7 +456,7 @@ getpin_cb (void *opaque, const char *desc_text, const char *info,
*
* FIXME: Explain the other args. */
int
-divert_pksign (ctrl_t ctrl, const char *desc_text,
+divert_pksign (ctrl_t ctrl, const char *desc_text, const unsigned char *grip,
const unsigned char *digest, size_t digestlen, int algo,
const unsigned char *shadow_info, unsigned char **r_sig,
size_t *r_siglen)
@@ -446,7 +468,7 @@ divert_pksign (ctrl_t ctrl, const char *desc_text,
(void)desc_text;
- rc = ask_for_card (ctrl, shadow_info, &kid);
+ rc = ask_for_card (ctrl, shadow_info, grip, &kid);
if (rc)
return rc;
@@ -490,6 +512,7 @@ divert_pksign (ctrl_t ctrl, const char *desc_text,
R_PADDING with -1 for not known. */
int
divert_pkdecrypt (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *grip,
const unsigned char *cipher,
const unsigned char *shadow_info,
char **r_buf, size_t *r_len, int *r_padding)
@@ -581,7 +604,7 @@ divert_pkdecrypt (ctrl_t ctrl, const char *desc_text,
ciphertext = s;
ciphertextlen = n;
- rc = ask_for_card (ctrl, shadow_info, &kid);
+ rc = ask_for_card (ctrl, shadow_info, grip, &kid);
if (rc)
return rc;
diff --git a/agent/findkey.c b/agent/findkey.c
index 89a18fa9e..370050d8b 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -1,7 +1,7 @@
/* findkey.c - Locate the secret key
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
* 2010, 2011 Free Software Foundation, Inc.
- * Copyright (C) 2014 Werner Koch
+ * Copyright (C) 2014, 2019 Werner Koch
*
* This file is part of GnuPG.
*
@@ -26,10 +26,8 @@
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
-#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
-#include <assert.h>
#include <npth.h> /* (we use pth_sleep) */
#include "agent.h"
@@ -52,15 +50,47 @@ struct try_unprotect_arg_s
};
+/* Repalce all linefeeds in STRING by "%0A" and return a new malloced
+ * string. May return NULL on memory error. */
+static char *
+linefeed_to_percent0A (const char *string)
+{
+ const char *s;
+ size_t n;
+ char *buf, *p;
+
+ for (n=0, s=string; *s; s++)
+ if (*s == '\n')
+ n += 3;
+ else
+ n++;
+ p = buf = xtrymalloc (n+1);
+ if (!buf)
+ return NULL;
+ for (s=string; *s; s++)
+ if (*s == '\n')
+ {
+ memcpy (p, "%0A", 3);
+ p += 3;
+ }
+ else
+ *p++ = *s;
+ *p = 0;
+ return buf;
+}
+
+
/* Note: Ownership of FNAME and FP are moved to this function. */
static gpg_error_t
write_extended_private_key (char *fname, estream_t fp, int update,
- const void *buf, size_t len)
+ const void *buf, size_t len,
+ const char *serialno, const char *keyref)
{
gpg_error_t err;
nvc_t pk = NULL;
gcry_sexp_t key = NULL;
int remove = 0;
+ char *token = NULL;
if (update)
{
@@ -93,6 +123,37 @@ write_extended_private_key (char *fname, estream_t fp, int update,
if (err)
goto leave;
+ /* If requested write a Token line. */
+ if (serialno && keyref)
+ {
+ nve_t item;
+ const char *s;
+
+ token = strconcat (serialno, " ", keyref, NULL);
+ if (!token)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ /* fixme: the strcmp should compare only the first two strings. */
+ for (item = nvc_lookup (pk, "Token:");
+ item;
+ item = nve_next_value (item, "Token:"))
+ if ((s = nve_value (item)) && !strcmp (s, token))
+ break;
+ if (!item)
+ {
+ /* No token or no token with that value exists. Add a new
+ * one so that keys which have been stored on several cards
+ * are well supported. */
+ err = nvc_add (pk, "Token:", token);
+ if (err)
+ goto leave;
+ }
+ }
+
+
err = es_fseek (fp, 0, SEEK_SET);
if (err)
goto leave;
@@ -132,15 +193,18 @@ write_extended_private_key (char *fname, estream_t fp, int update,
xfree (fname);
gcry_sexp_release (key);
nvc_release (pk);
+ xfree (token);
return err;
}
/* Write an S-expression formatted key to our key storage. With FORCE
- passed as true an existing key with the given GRIP will get
- overwritten. */
+ * passed as true an existing key with the given GRIP will get
+ * overwritten. If SERIALNO and KEYREF are give an a Token line is added to
+ * th key if the extended format ist used. */
int
agent_write_private_key (const unsigned char *grip,
- const void *buffer, size_t length, int force)
+ const void *buffer, size_t length, int force,
+ const char *serialno, const char *keyref)
{
char *fname;
estream_t fp;
@@ -208,17 +272,20 @@ agent_write_private_key (const unsigned char *grip,
if (first != '(')
{
/* Key is already in the extended format. */
- return write_extended_private_key (fname, fp, 1, buffer, length);
+ return write_extended_private_key (fname, fp, 1, buffer, length,
+ serialno, keyref);
}
if (first == '(' && opt.enable_extended_key_format)
{
/* Key is in the old format - but we want the extended format. */
- return write_extended_private_key (fname, fp, 0, buffer, length);
+ return write_extended_private_key (fname, fp, 0, buffer, length,
+ serialno, keyref);
}
}
if (opt.enable_extended_key_format)
- return write_extended_private_key (fname, fp, 0, buffer, length);
+ return write_extended_private_key (fname, fp, 0, buffer, length,
+ serialno, keyref);
if (es_fwrite (buffer, length, 1, fp) != 1)
{
@@ -267,7 +334,7 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
gnupg_isotime_t now, protected_at, tmptime;
char *desc = NULL;
- assert (!arg->unprotected_key);
+ log_assert (!arg->unprotected_key);
arg->change_required = 0;
err = agent_unprotect (ctrl, arg->protected_key, pi->pin, protected_at,
@@ -332,6 +399,33 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
}
+/* Return true if the STRING has an %C or %c expando. */
+static int
+has_comment_expando (const char *string)
+{
+ const char *s;
+ int percent = 0;
+
+ if (!string)
+ return 0;
+
+ for (s = string; *s; s++)
+ {
+ if (percent)
+ {
+ if (*s == 'c' || *s == 'C')
+ return 1;
+ percent = 0;
+ }
+ else if (*s == '%')
+ percent = 1;
+ }
+ return 0;
+}
+
+
+
+
/* Modify a Key description, replacing certain special format
characters. List of currently supported replacements:
@@ -644,7 +738,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
}
else
{
- assert (arg.unprotected_key);
+ log_assert (arg.unprotected_key);
if (arg.change_required)
{
/* The callback told as that the user should change their
@@ -652,7 +746,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
size_t canlen, erroff;
gcry_sexp_t s_skey;
- assert (arg.unprotected_key);
+ log_assert (arg.unprotected_key);
canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
rc = gcry_sexp_sscan (&s_skey, &erroff,
(char*)arg.unprotected_key, canlen);
@@ -695,10 +789,13 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
/* Read the key identified by GRIP from the private key directory and
- return it as an gcrypt S-expression object in RESULT. On failure
- returns an error code and stores NULL at RESULT. */
+ * return it as an gcrypt S-expression object in RESULT. If R_KEYMETA
+ * is not NULl and the extended key format is used, the meta data
+ * items are stored there. However the "Key:" item is removed from
+ * it. On failure returns an error code and stores NULL at RESULT and
+ * R_KEYMETA. */
static gpg_error_t
-read_key_file (const unsigned char *grip, gcry_sexp_t *result)
+read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta)
{
gpg_error_t err;
char *fname;
@@ -711,6 +808,8 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
char first;
*result = NULL;
+ if (r_keymeta)
+ *r_keymeta = NULL;
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");
@@ -749,7 +848,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
if (first != '(')
{
/* Key is in extended format. */
- nvc_t pk;
+ nvc_t pk = NULL;
int line;
err = nvc_parse_private_key (&pk, &line, fp);
@@ -761,12 +860,17 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
else
{
err = nvc_get_private_key (pk, result);
- nvc_release (pk);
if (err)
log_error ("error getting private key from '%s': %s\n",
fname, gpg_strerror (err));
+ else
+ nvc_delete_named (pk, "Key:");
}
+ if (!err && r_keymeta)
+ *r_keymeta = pk;
+ else
+ nvc_release (pk);
xfree (fname);
return err;
}
@@ -866,6 +970,8 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
unsigned char *buf;
size_t len, buflen, erroff;
gcry_sexp_t s_skey;
+ nvc_t keymeta = NULL;
+ char *desc_text_buffer = NULL; /* Used in case we extend DESC_TEXT. */
*result = NULL;
if (shadow_info)
@@ -873,7 +979,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
if (r_passphrase)
*r_passphrase = NULL;
- err = read_key_file (grip, &s_skey);
+ err = read_key_file (grip, &s_skey, &keymeta);
if (err)
{
if (gpg_err_code (err) == GPG_ERR_ENOENT)
@@ -886,7 +992,11 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
now. */
err = make_canon_sexp (s_skey, &buf, &len);
if (err)
- return err;
+ {
+ nvc_release (keymeta);
+ xfree (desc_text_buffer);
+ return err;
+ }
switch (agent_private_key_type (buf))
{
@@ -911,25 +1021,43 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
case PRIVATE_KEY_PROTECTED:
{
char *desc_text_final;
- char *comment = NULL;
+ char *comment_buffer = NULL;
+ const char *comment = NULL;
/* Note, that we will take the comment as a C string for
- display purposes; i.e. all stuff beyond a Nul character is
- ignored. */
- {
- gcry_sexp_t comment_sexp;
+ * display purposes; i.e. all stuff beyond a Nul character is
+ * ignored. If a "Label" entry is available in the meta data
+ * this is used instead of the s-ecpression comment. */
+ if (keymeta && (comment = nvc_get_string (keymeta, "Label:")))
+ {
+ if (strchr (comment, '\n')
+ && (comment_buffer = linefeed_to_percent0A (comment)))
+ comment = comment_buffer;
+ /* In case DESC_TEXT has no escape pattern for a comment
+ * we append one. */
+ if (desc_text && !has_comment_expando (desc_text))
+ {
+ desc_text_buffer = strconcat (desc_text, "%0A%C", NULL);
+ if (desc_text_buffer)
+ desc_text = desc_text_buffer;
+ }
+ }
+ else
+ {
+ gcry_sexp_t comment_sexp;
- comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
- if (comment_sexp)
- comment = gcry_sexp_nth_string (comment_sexp, 1);
- gcry_sexp_release (comment_sexp);
- }
+ comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
+ if (comment_sexp)
+ comment_buffer = gcry_sexp_nth_string (comment_sexp, 1);
+ gcry_sexp_release (comment_sexp);
+ comment = comment_buffer;
+ }
desc_text_final = NULL;
if (desc_text)
err = agent_modify_description (desc_text, comment, s_skey,
&desc_text_final);
- gcry_free (comment);
+ gcry_free (comment_buffer);
if (!err)
{
@@ -984,6 +1112,8 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
xfree (*r_passphrase);
*r_passphrase = NULL;
}
+ nvc_release (keymeta);
+ xfree (desc_text_buffer);
return err;
}
@@ -1000,10 +1130,14 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
xfree (*r_passphrase);
*r_passphrase = NULL;
}
+ nvc_release (keymeta);
+ xfree (desc_text_buffer);
return err;
}
*result = s_skey;
+ nvc_release (keymeta);
+ xfree (desc_text_buffer);
return 0;
}
@@ -1203,7 +1337,7 @@ agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
*result = NULL;
- err = read_key_file (grip, &s_skey);
+ err = read_key_file (grip, &s_skey, NULL);
if (!err)
*result = s_skey;
return err;
@@ -1230,6 +1364,7 @@ agent_public_key_from_file (ctrl_t ctrl,
gcry_sexp_t uri_sexp, comment_sexp;
const char *uri, *comment;
size_t uri_length, comment_length;
+ int uri_intlen, comment_intlen;
char *format, *p;
void *args[2+7+2+2+1]; /* Size is 2 + max. # of elements + 2 for uri + 2
for comment + end-of-list. */
@@ -1241,7 +1376,7 @@ agent_public_key_from_file (ctrl_t ctrl,
*result = NULL;
- err = read_key_file (grip, &s_skey);
+ err = read_key_file (grip, &s_skey, NULL);
if (err)
return err;
@@ -1278,7 +1413,7 @@ agent_public_key_from_file (ctrl_t ctrl,
such a task. After all that is what we do in protect.c. Need
to find common patterns and write a straightformward API to use
them. */
- assert (sizeof (size_t) <= sizeof (void*));
+ log_assert (sizeof (size_t) <= sizeof (void*));
format = xtrymalloc (15+4+7*npkey+10+15+1+1);
if (!format)
@@ -1303,27 +1438,29 @@ agent_public_key_from_file (ctrl_t ctrl,
*p++ = '(';
*p++ = *s++;
p = stpcpy (p, " %m)");
- assert (argidx < DIM (args));
+ log_assert (argidx < DIM (args));
args[argidx++] = &array[idx];
}
*p++ = ')';
if (uri)
{
p = stpcpy (p, "(uri %b)");
- assert (argidx+1 < DIM (args));
- args[argidx++] = (void *)&uri_length;
+ log_assert (argidx+1 < DIM (args));
+ uri_intlen = (int)uri_length;
+ args[argidx++] = (void *)&uri_intlen;
args[argidx++] = (void *)&uri;
}
if (comment)
{
p = stpcpy (p, "(comment %b)");
- assert (argidx+1 < DIM (args));
- args[argidx++] = (void *)&comment_length;
+ log_assert (argidx+1 < DIM (args));
+ comment_intlen = (int)comment_length;
+ args[argidx++] = (void *)&comment_intlen;
args[argidx++] = (void*)&comment;
}
*p++ = ')';
*p = 0;
- assert (argidx < DIM (args));
+ log_assert (argidx < DIM (args));
args[argidx] = NULL;
err = gcry_sexp_build_array (&list, NULL, format, args);
@@ -1386,7 +1523,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
{
gcry_sexp_t sexp;
- err = read_key_file (grip, &sexp);
+ err = read_key_file (grip, &sexp, NULL);
if (err)
{
if (gpg_err_code (err) == GPG_ERR_ENOENT)
@@ -1420,7 +1557,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
if (!err)
{
n = gcry_sexp_canon_len (s, 0, NULL, NULL);
- assert (n);
+ log_assert (n);
*r_shadow_info = xtrymalloc (n);
if (!*r_shadow_info)
err = gpg_error_from_syserror ();
@@ -1470,7 +1607,7 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
char *default_desc = NULL;
int key_type;
- err = read_key_file (grip, &s_skey);
+ err = read_key_file (grip, &s_skey, NULL);
if (gpg_err_code (err) == GPG_ERR_ENOENT)
err = gpg_error (GPG_ERR_NO_SECKEY);
if (err)
@@ -1580,6 +1717,13 @@ agent_write_shadow_key (const unsigned char *grip,
unsigned char *shdkey;
size_t len;
+ /* Just in case some caller did not parse the stuff correctly, skip
+ * leading spaces. */
+ while (spacep (serialno))
+ serialno++;
+ while (spacep (keyid))
+ keyid++;
+
shadow_info = make_shadow_info (serialno, keyid);
if (!shadow_info)
return gpg_error_from_syserror ();
@@ -1593,7 +1737,7 @@ agent_write_shadow_key (const unsigned char *grip,
}
len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
- err = agent_write_private_key (grip, shdkey, len, force);
+ err = agent_write_private_key (grip, shdkey, len, force, serialno, keyid);
xfree (shdkey);
if (err)
log_error ("error writing key: %s\n", gpg_strerror (err));
diff --git a/agent/genkey.c b/agent/genkey.c
index d5c80d0aa..0d2038016 100644
--- a/agent/genkey.c
+++ b/agent/genkey.c
@@ -24,7 +24,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
#include "agent.h"
#include "../common/i18n.h"
@@ -47,12 +46,12 @@ store_key (gcry_sexp_t private, const char *passphrase, int force,
}
len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, NULL, 0);
- assert (len);
+ log_assert (len);
buf = gcry_malloc_secure (len);
if (!buf)
return out_of_core ();
len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len);
- assert (len);
+ log_assert (len);
if (passphrase)
{
@@ -68,7 +67,7 @@ store_key (gcry_sexp_t private, const char *passphrase, int force,
buf = p;
}
- rc = agent_write_private_key (grip, buf, len, force);
+ rc = agent_write_private_key (grip, buf, len, force, NULL, NULL);
xfree (buf);
return rc;
}
@@ -127,7 +126,7 @@ check_passphrase_pattern (ctrl_t ctrl, const char *pw)
argv[i++] = "--",
argv[i++] = opt.check_passphrase_pattern,
argv[i] = NULL;
- assert (i < sizeof argv);
+ log_assert (i < sizeof argv);
if (gnupg_spawn_process_fd (pgmname, argv, fileno (infp), -1, -1, &pid))
result = 1; /* Execute error - assume password should no be used. */
@@ -149,27 +148,10 @@ check_passphrase_pattern (ctrl_t ctrl, const char *pw)
static int
-take_this_one_anyway2 (ctrl_t ctrl, const char *desc, const char *anyway_btn)
+take_this_one_anyway (ctrl_t ctrl, const char *desc, const char *anyway_btn)
{
- gpg_error_t err;
-
- if (opt.enforce_passphrase_constraints)
- {
- err = agent_show_message (ctrl, desc, L_("Enter new passphrase"));
- if (!err)
- err = gpg_error (GPG_ERR_CANCELED);
- }
- else
- err = agent_get_confirmation (ctrl, desc,
- anyway_btn, L_("Enter new passphrase"), 0);
- return err;
-}
-
-
-static int
-take_this_one_anyway (ctrl_t ctrl, const char *desc)
-{
- return take_this_one_anyway2 (ctrl, desc, L_("Take this one anyway"));
+ return agent_get_confirmation (ctrl, desc,
+ anyway_btn, L_("Enter new passphrase"), 0);
}
@@ -212,8 +194,8 @@ check_passphrase_constraints (ctrl_t ctrl, const char *pw,
if (opt.enforce_passphrase_constraints)
*failed_constraint = xstrdup (desc);
else
- err = take_this_one_anyway2 (ctrl, desc,
- L_("Yes, protection is not needed"));
+ err = take_this_one_anyway (ctrl, desc,
+ L_("Yes, protection is not needed"));
}
goto leave;
@@ -311,7 +293,7 @@ check_passphrase_constraints (ctrl_t ctrl, const char *pw,
*failed_constraint = msg;
else
{
- err = take_this_one_anyway (ctrl, msg);
+ err = take_this_one_anyway (ctrl, msg, L_("Take this one anyway"));
xfree (msg);
}
}
@@ -557,7 +539,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
if (DBG_CRYPTO)
log_debug ("returning public key\n");
len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0);
- assert (len);
+ log_assert (len);
buf = xtrymalloc (len);
if (!buf)
{
@@ -567,7 +549,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
return tmperr;
}
len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len);
- assert (len);
+ log_assert (len);
put_membuf (outbuf, buf, len);
gcry_sexp_release (s_public);
xfree (buf);
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index d9e2bbf25..57d5a459c 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -26,7 +26,6 @@
#include <stdarg.h>
#include <string.h>
#include <errno.h>
-#include <assert.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
@@ -1952,7 +1951,7 @@ agent_set_progress_cb (void (*cb)(ctrl_t ctrl, const char *what,
static void
agent_init_default_ctrl (ctrl_t ctrl)
{
- assert (ctrl->session_env);
+ log_assert (ctrl->session_env);
/* Note we ignore malloc errors because we can't do much about it
and the request will fail anyway shortly after this
@@ -2442,6 +2441,9 @@ agent_sighup_action (void)
"pinentry" binary that one can be used in case the
"pinentry-basic" fallback was in use. */
gnupg_module_name_flush_some ();
+
+ if (opt.disable_scdaemon)
+ agent_card_killscd ();
}
diff --git a/agent/keyformat.txt b/agent/keyformat.txt
index c7426db9d..e2ca05c84 100644
--- a/agent/keyformat.txt
+++ b/agent/keyformat.txt
@@ -18,7 +18,8 @@ hexadecimal representation of the keygrip[2] and suffixed with ".key".
* Extended Private Key Format
-GnuPG 2.3+ will use a new format to store private keys that is both
+** Overview
+GnuPG 2.3+ uses a new format to store private keys that is both
more flexible and easier to read and edit by human beings. The new
format stores name,value-pairs using the common mail and http header
convention. Example (here indented with two spaces):
@@ -28,6 +29,8 @@ convention. Example (here indented with two spaces):
Use-for-ssh: yes
OpenSSH-cert: long base64 encoded string wrapped so that this
key file can be easily edited with a standard editor.
+ Token: D2760001240102000005000011730000 OPENPGP.1
+ Token: FF020001008A77C1 PIV.9C
Key: (shadowed-private-key
(rsa
(n #00AA1AD2A55FD8C8FDE9E1941772D9CC903FA43B268CB1B5A1BAFDC900
@@ -52,33 +55,66 @@ Keys in the extended format can be recognized by looking at the first
byte of the file. If it starts with a '(' it is a naked S-expression,
otherwise it is a key in extended format.
-** Names
-
+*** Names
A name must start with a letter and end with a colon. Valid
characters are all ASCII letters, numbers and the hyphen. Comparison
of names is done case insensitively. Names may be used several times
-to represent an array of values.
-
-The name "Key:" is special in that it may occur only once and the
-associated value holds the actual S-expression with the cryptographic
-key. The S-expression is formatted using the 'Advanced Format'
-(GCRYSEXP_FMT_ADVANCED) that avoids non-printable characters so that
-the file can be easily inspected and edited. See section 'Private Key
-Format' below for details.
-
-** Values
+to represent an array of values. Note that the name "Key" is special
+in that it is madandory must occur only once.
+*** Values
Values are UTF-8 encoded strings. Values can be wrapped at any point,
and continued in the next line indicated by leading whitespace. A
continuation line with one leading space does not introduce a blank so
that the lines can be effectively concatenated. A blank line as part
of a continuation line encodes a newline.
-** Comments
-
+*** Comments
Lines containing only whitespace, and lines starting with whitespace
followed by '#' are considered to be comments and are ignored.
+** Well defined names
+
+*** Description
+This is a human readable string describing the key.
+
+*** Key
+The name "Key" is special in that it is mandatory and must occur only
+once. The associated value holds the actual S-expression with the
+cryptographic key. The S-expression is formatted using the 'Advanced
+Format' (GCRYSEXP_FMT_ADVANCED) that avoids non-printable characters
+so that the file can be easily inspected and edited. See section
+'Private Key Format' below for details.
+
+*** Label
+This is a short human readable description for the key which can be
+used by the software to describe the key in a user interface. For
+example as part of the description in a prompt for a PIN or
+passphrase. It is often used instead of a comment element as present
+in the S-expression of the "Key" item.
+
+*** OpenSSH-cert
+This takes a base64 encoded string wrapped so that this
+key file can be easily edited with a standard editor. Several of such
+items can be used.
+
+*** Token
+If such an item exists it overrides the info given by the "shadow"
+parameter in the S-expression. Using this item makes it possible to
+describe a key which is stored on several tokens and also makes it
+easy to update this info using a standard editor. The syntax is the
+same as with the "shadow" parameter:
+
+- Serialnumber of the token
+- Key reference from the token in full format (e.g. "OpenPGP.2")
+- An optional fixed length of the PIN.
+
+*** Use-for-ssh
+If given and the value is "yes" or "1" the key is allowed for use by
+gpg-agent's ssh-agent implementation. This is thus the same as
+putting the keygrip into the 'sshcontrol' file. Only one such item
+should exist.
+
* Private Key Format
** Unprotected Private Key Format
diff --git a/agent/learncard.c b/agent/learncard.c
index f3219ed8f..f40f5ac4d 100644
--- a/agent/learncard.c
+++ b/agent/learncard.c
@@ -23,7 +23,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c
index 06a8e0b6f..ec23daf83 100644
--- a/agent/pkdecrypt.c
+++ b/agent/pkdecrypt.c
@@ -23,7 +23,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -86,8 +85,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
goto leave;
}
- rc = divert_pkdecrypt (ctrl, desc_text, ciphertext, shadow_info,
- &buf, &len, r_padding);
+ rc = divert_pkdecrypt (ctrl, desc_text, ctrl->keygrip, ciphertext,
+ shadow_info, &buf, &len, r_padding);
if (rc)
{
log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
@@ -119,10 +118,10 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
gcry_sexp_dump (s_plain);
}
len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, NULL, 0);
- assert (len);
+ log_assert (len);
buf = xmalloc (len);
len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, buf, len);
- assert (len);
+ log_assert (len);
if (*buf == '(')
put_membuf (outbuf, buf, len);
else
diff --git a/agent/pksign.c b/agent/pksign.c
index 828e63f58..4a43b09de 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -24,8 +24,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
-#include <unistd.h>
#include <sys/stat.h>
#include "agent.h"
@@ -46,16 +44,21 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
int i;
s = gcry_md_algo_name (algo);
- if (s && strlen (s) < 16)
+ if (!s || strlen (s) >= 16)
+ {
+ hash = NULL;
+ rc = gpg_error (GPG_ERR_DIGEST_ALGO);
+ }
+ else
{
- for (i=0; i < strlen (s); i++)
- tmp[i] = tolower (s[i]);
+ for (i=0; s[i]; i++)
+ tmp[i] = ascii_tolower (s[i]);
tmp[i] = '\0';
- }
- rc = gcry_sexp_build (&hash, NULL,
- "(data (flags pkcs1) (hash %s %b))",
- tmp, (int)mdlen, md);
+ rc = gcry_sexp_build (&hash, NULL,
+ "(data (flags pkcs1) (hash %s %b))",
+ tmp, (int)mdlen, md);
+ }
}
else
{
@@ -250,13 +253,13 @@ do_encode_raw_pkcs1 (const byte *md, size_t mdlen, unsigned int nbits,
frame[n++] = 0;
frame[n++] = 1; /* Block type. */
i = nframe - mdlen - 3 ;
- assert (i >= 8); /* At least 8 bytes of padding. */
+ log_assert (i >= 8); /* At least 8 bytes of padding. */
memset (frame+n, 0xff, i );
n += i;
frame[n++] = 0;
memcpy (frame+n, md, mdlen );
n += mdlen;
- assert (n == nframe);
+ log_assert (n == nframe);
/* Create the S-expression. */
rc = gcry_sexp_build (&hash, NULL,
@@ -354,6 +357,7 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
agent_modify_description (desc_text, NULL, s_skey, &desc2);
err = divert_pksign (ctrl, desc2? desc2 : desc_text,
+ ctrl->keygrip,
data, datalen,
ctrl->digest.algo,
shadow_info, &buf, &len);
diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c
index 7a9ea1b44..e22e9d58d 100644
--- a/agent/preset-passphrase.c
+++ b/agent/preset-passphrase.c
@@ -25,7 +25,6 @@
#include <stdarg.h>
#include <string.h>
#include <errno.h>
-#include <assert.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_LOCALE_H
diff --git a/agent/protect-tool.c b/agent/protect-tool.c
index ec7b47695..059a9bdbd 100644
--- a/agent/protect-tool.c
+++ b/agent/protect-tool.c
@@ -25,7 +25,6 @@
#include <stdarg.h>
#include <string.h>
#include <errno.h>
-#include <assert.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_LOCALE_H
@@ -198,10 +197,10 @@ make_canonical (const char *fname, const char *buf, size_t buflen)
return NULL;
}
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
- assert (len);
+ log_assert (len);
result = xmalloc (len);
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, result, len);
- assert (len);
+ log_assert (len);
gcry_sexp_release (sexp);
return result;
}
@@ -222,10 +221,10 @@ make_advanced (const unsigned char *buf, size_t buflen)
return NULL;
}
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
- assert (len);
+ log_assert (len);
result = xmalloc (len);
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len);
- assert (len);
+ log_assert (len);
gcry_sexp_release (sexp);
return result;
}
@@ -433,7 +432,7 @@ read_and_shadow (const char *fname)
return;
}
resultlen = gcry_sexp_canon_len (result, 0, NULL,NULL);
- assert (resultlen);
+ log_assert (resultlen);
if (opt_armor)
{
@@ -469,7 +468,7 @@ show_shadow_info (const char *fname)
return;
}
infolen = gcry_sexp_canon_len (info, 0, NULL,NULL);
- assert (infolen);
+ log_assert (infolen);
if (opt_armor)
{
@@ -496,7 +495,7 @@ show_file (const char *fname)
return;
keylen = gcry_sexp_canon_len (key, 0, NULL,NULL);
- assert (keylen);
+ log_assert (keylen);
if (opt_canonical)
{
@@ -723,7 +722,7 @@ get_passphrase (int promptno)
gpg_strerror (err));
agent_exit (0);
}
- assert (pw);
+ log_assert (pw);
return pw;
}
@@ -799,12 +798,15 @@ agent_askpin (ctrl_t ctrl,
* to stdout. */
int
agent_write_private_key (const unsigned char *grip,
- const void *buffer, size_t length, int force)
+ const void *buffer, size_t length, int force,
+ const char *serialno, const char *keyref)
{
char hexgrip[40+4+1];
char *p;
(void)force;
+ (void)serialno;
+ (void)keyref;
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");
diff --git a/agent/protect.c b/agent/protect.c
index 61fb8f45d..e3bbf3ed5 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -528,7 +528,7 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
memcpy (p, iv+blklen, blklen); /* Add padding. */
p += blklen;
}
- assert ( p - outbuf == outlen);
+ log_assert ( p - outbuf == outlen);
if (use_ocb)
{
gcry_cipher_final (hd);
@@ -718,11 +718,11 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
hash_end = s;
s++;
/* Skip to the end of the S-expression. */
- assert (depth == 1);
+ log_assert (depth == 1);
rc = sskip (&s, &depth);
if (rc)
return rc;
- assert (!depth);
+ log_assert (!depth);
real_end = s-1;
rc = do_encryption (hash_begin, hash_end - hash_begin + 1,
@@ -760,7 +760,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
memcpy (p, prot_end+1, real_end - prot_end);
p += real_end - prot_end;
- assert ( p - *result == *resultlen);
+ log_assert ( p - *result == *resultlen);
xfree (protected);
return 0;
@@ -999,7 +999,7 @@ merge_lists (const unsigned char *protectedkey,
/* Skip over the protected list element in the original list. */
s = protectedkey + replacepos;
- assert (*s == '(');
+ log_assert (*s == '(');
s++;
i = 1;
rc = sskip (&s, &i);
@@ -1026,7 +1026,7 @@ merge_lists (const unsigned char *protectedkey,
rc = sskip (&s, &i);
if (rc)
goto failure;
- assert (s[-1] == ')');
+ log_assert (s[-1] == ')');
endpos = s; /* one behind the end of the list */
/* Append the rest. */
@@ -1571,7 +1571,7 @@ agent_shadow_key (const unsigned char *pubkey,
point = s; /* insert right before the point */
depth--;
s++;
- assert (depth == 1);
+ log_assert (depth == 1);
/* Calculate required length by taking in account: the "shadowed-"
prefix, the "shadowed", "t1-v1" as well as some parenthesis */
@@ -1667,7 +1667,8 @@ agent_get_shadow_info (const unsigned char *shadowkey,
R_HEXSN and the Id string as a malloced string at R_IDSTR. On
error an error code is returned and NULL is stored at the result
parameters addresses. If the serial number or the ID string is not
- required, NULL may be passed for them. */
+ required, NULL may be passed for them. Note that R_PINLEN is
+ currently not used by any caller. */
gpg_error_t
parse_shadow_info (const unsigned char *shadow_info,
char **r_hexsn, char **r_idstr, int *r_pinlen)
diff --git a/agent/trans.c b/agent/trans.c
index ff1a34e68..9d090ff86 100644
--- a/agent/trans.c
+++ b/agent/trans.c
@@ -28,7 +28,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
diff --git a/agent/trustlist.c b/agent/trustlist.c
index af177b2e2..d91e92e07 100644
--- a/agent/trustlist.c
+++ b/agent/trustlist.c
@@ -24,7 +24,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
#include <npth.h>
@@ -550,7 +549,7 @@ insert_colons (const char *string)
}
}
*p = 0;
- assert (strlen (buffer) <= nnew);
+ log_assert (strlen (buffer) <= nnew);
return buffer;
}