[git] Scute - branch, master, updated. scute-1.5.0-11-gd981ad1
by Werner Koch
cvs at cvs.gnupg.org
Mon Feb 18 12:05:18 CET 2019
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PKCS#11 token on top of gpg-agent".
The branch, master has been updated
via d981ad1ed18d5e7d7b63ecf256348a509cc4eb59 (commit)
from ff9e757e352f1b4cf3b4625eb4398415051367af (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit d981ad1ed18d5e7d7b63ecf256348a509cc4eb59
Author: Werner Koch <wk at gnupg.org>
Date: Mon Feb 18 12:03:51 2019 +0100
Let gpgsm do the actual key selection work.
* src/agent.c (scute_agent_is_trusted): Make FPR arg const.
* src/cert.h (enum keylist_modes): new.
* src/cert-gpgsm.c (scute_gpgsm_search_certs_by_fpr): Remove.
(scute_gpgsm_search_certs_by_grip): Rename to ...
(scute_gpgsm_search_certs): this. Remove the same named old
fucntion. Change args and rewrite.
(export_cert_compat): Remove.
(export_cert): Make FPR arg const. Remove trailing LF from assuna
command.
(search_certs): Rename to keylist_cb. Fold the double callbacks into
just one.
(MAX_LINE_LEN): Define based on ASSUAN_LINELENGTH.
--
This patch cleans up a lot of cruft and also replaces the Scute
internal selection of keys by simply asking gpgsm to only return the
requested keys. This speeds up things a lot.
Signed-off-by: Werner Koch <wk at gnupg.org>
diff --git a/src/agent.c b/src/agent.c
index 4fe969b..706fdf3 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -1036,7 +1036,7 @@ scute_agent_sign (const char *hexgrip, unsigned char *data, int len,
/* Determine if FPR is trusted. */
gpg_error_t
-scute_agent_is_trusted (char *fpr, bool *is_trusted)
+scute_agent_is_trusted (const char *fpr, bool *is_trusted)
{
gpg_error_t err;
bool trusted = false;
diff --git a/src/agent.h b/src/agent.h
index 367b7e2..0b75f14 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -132,7 +132,7 @@ gpg_error_t scute_agent_sign (const char *hexgrip,
unsigned char *sig_result, unsigned int *sig_len);
/* Determine if FPR is trusted. */
-gpg_error_t scute_agent_is_trusted (char *fpr, bool *is_trusted);
+gpg_error_t scute_agent_is_trusted (const char *fpr, bool *is_trusted);
/* Try to get certificate for key numer NO. */
gpg_error_t scute_agent_get_cert (const char *certref, struct cert *cert);
diff --git a/src/cert-gpgsm.c b/src/cert-gpgsm.c
index c982b75..14a675a 100644
--- a/src/cert-gpgsm.c
+++ b/src/cert-gpgsm.c
@@ -2,7 +2,7 @@
Copyright (C) 2006, 2007 g10 Code GmbH
This file is part of Scute.
-
+
Scute is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -45,33 +45,39 @@
#include "support.h"
#include "debug.h"
-
-#ifndef HAVE_W32_SYSTEM
-#define COMPAT_FALLBACK
-#endif
-
/* The maximum length of a key listing line. We take the double of
- the allowed Assuan line length to avoid a memmove after a part of a
- line has been processed. FIXME: There is actually no limit on the
- length of the line. */
-#define MAX_LINE_LEN (1024*2)
+ * the allowed Assuan line length plus some extra space to avoid a
+ * memmove after a part of a line has been processed. */
+#define MAX_LINE_LEN (ASSUAN_LINELENGTH*2 + 200)
-struct search_ctx
+struct keylist_ctx
{
/* The pending line in an active key listing. */
char pending[MAX_LINE_LEN + 1];
unsigned int pending_len;
+ /* The current certificate. */
+ struct cert cert;
+
/* The caller's search callback, invoked for each certificate. */
cert_search_cb_t search_cb;
void *search_cb_hook;
-
- /* The current certificate. */
- struct cert cert;
};
+/* Support macros */
+#define atoi_1(p) (*(p) - '0' )
+#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
+#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
+
+
+/*** Local prototypes ***/
+static gpg_error_t export_cert (const char *fpr, struct cert *cert);
+
+
+
+
/* Release allocated storage for the certificate CERT and reset the
certificate. */
static void
@@ -89,12 +95,6 @@ cert_reset (struct cert *cert)
memset (cert, '\0', sizeof (struct cert));
}
-
-/* Support routines for key list processing. */
-
-#define atoi_1(p) (*(p) - '0' )
-#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
-#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
/* Parse the string TIMESTAMP into a time_t. The string may either be
seconds since Epoch or in the ISO 8601 format like
@@ -127,7 +127,7 @@ parse_timestamp (const char *timestamp, char **endp)
memset (&buf, 0, sizeof buf);
buf.tm_year = year - 1900;
- buf.tm_mon = atoi_2 (timestamp+4) - 1;
+ buf.tm_mon = atoi_2 (timestamp+4) - 1;
buf.tm_mday = atoi_2 (timestamp+6);
buf.tm_hour = atoi_2 (timestamp+9);
buf.tm_min = atoi_2 (timestamp+11);
@@ -229,9 +229,9 @@ decode_c_string (const char *src, char **destp, size_t len)
/* A binary zero is not representable in a C
string. */
*(dest++) = '\\';
- *(dest++) = '0';
+ *(dest++) = '0';
}
- else
+ else
*((unsigned char *) dest++) = val;
src += 4;
}
@@ -244,28 +244,19 @@ decode_c_string (const char *src, char **destp, size_t len)
*(dest++) = *(src++);
*(dest++) = *(src++);
}
- }
+ }
}
*(dest++) = 0;
return 0;
}
-
-/* The cert handler for certificate searches. This is invoked for
- each complete certificate found by search_certs_line, and the last
- pending certificate when EOF is encountered by search_certs. */
-static gpg_error_t
-search_certs_cert (struct search_ctx *ctx)
-{
- return (*ctx->search_cb) (ctx->search_cb_hook, &ctx->cert);
-}
-
-/* The line handler for certificate searches. This is invoked for
- each complete line found by search_certs. */
+
+/* Helper for keylist_cb. This fucntion is invoked for each complete
+ * line assembled by keylist_cb. */
static gpg_error_t
-search_certs_line (struct search_ctx *ctx)
+keylist_cb_line (struct keylist_ctx *ctx)
{
char *line;
enum { RT_NONE, RT_CRT, RT_CRS, RT_FPR, RT_GRP, RT_UID } rectype = RT_NONE;
@@ -301,7 +292,7 @@ search_certs_line (struct search_ctx *ctx)
rectype = RT_GRP;
else if (!strcmp (field[0], "uid"))
rectype = RT_UID;
- else
+ else
rectype = RT_NONE;
switch (rectype)
@@ -313,8 +304,11 @@ search_certs_line (struct search_ctx *ctx)
{
gpg_error_t err;
- err = search_certs_cert (ctx);
- if (err)
+ /* Return the cert. */
+ err = export_cert (ctx->cert.fpr, &ctx->cert);
+ if (!err)
+ err = ctx->search_cb (ctx->search_cb_hook, &ctx->cert);
+ if (err)
return err;
cert_reset (cert);
@@ -334,7 +328,7 @@ search_certs_line (struct search_ctx *ctx)
int i = atoi (field[2]);
/* Ignore invalid values. */
if (i > 1)
- cert->length = i;
+ cert->length = i;
}
/* Field 4 has the public key algorithm. */
@@ -433,13 +427,13 @@ search_certs_line (struct search_ctx *ctx)
/* This is the data line callback handler provided to assuan_transact
- in scute_gpgsm_search_certs. It buffers incomplete lines, and also
- handles the EOF signal provided directly by
- scute_gpgsm_search_certs. */
+ * in scute_gpgsm_search_certs_by_{grip,fpr}. It buffers incomplete
+ * lines, and is also used to handle the EOF signal directly outside
+ * of assuan_transact. */
static gpg_error_t
-search_certs (void *hook, const void *line_data, size_t line_len)
+keylist_cb (void *hook, const void *line_data, size_t line_len)
{
- struct search_ctx *ctx = hook;
+ struct keylist_ctx *ctx = hook;
const char *line = line_data;
gpg_error_t err;
@@ -451,23 +445,29 @@ search_certs (void *hook, const void *line_data, size_t line_len)
newline. */
if (ctx->pending_len)
{
- err = search_certs_line (ctx);
+ err = keylist_cb_line (ctx);
if (err)
return err;
}
- /* Check for a pending certificate. */
+ /* Check for a pending certificate and return it. */
if (ctx->cert.valid)
- return search_certs_cert (ctx);
+ {
+ err = export_cert (ctx->cert.fpr, &ctx->cert);
+ if (!err)
+ err = ctx->search_cb (ctx->search_cb_hook, &ctx->cert);
+ }
+ else
+ err = 0;
- return 0;
+ return err;
}
while (line_len)
{
if (*line == '\n')
{
- err = search_certs_line (ctx);
+ err = keylist_cb_line (ctx);
if (err)
return err;
}
@@ -486,132 +486,7 @@ search_certs (void *hook, const void *line_data, size_t line_len)
}
-/* Invoke SEARCH_CB for each certificate found using assuan connection
- CTX to GPGSM. */
-static gpg_error_t
-scute_gpgsm_search_certs (assuan_context_t ctx, cert_search_cb_t search_cb,
- void *search_cb_hook)
-{
- gpg_error_t err;
- struct search_ctx search;
-
- err = assuan_transact (ctx, "OPTION with-key-data", NULL, NULL,
- NULL, NULL, NULL, NULL);
- if (err)
- return err;
-
- search.pending_len = 0;
- search.search_cb = search_cb;
- search.search_cb_hook = search_cb_hook;
- memset (&search.cert, '\0', sizeof (search.cert));
-
- err = assuan_transact (ctx, "DUMPKEYS", &search_certs, &search, NULL,
- NULL, NULL, NULL);
- if (err)
- goto out;
-
- /* Signal the EOF. This is not done by Assuan for us. */
- err = search_certs (&search, NULL, 0);
- if (err)
- goto out;
-
- out:
- cert_reset (&search.cert);
- return err;
-}
-
-struct search_ctx_by_field
-{
- /* What we are searching for. */
- enum { SEARCH_BY_GRIP, SEARCH_BY_FPR } field;
-
- /* The pattern we are looking for. */
- const char *pattern;
-
- cert_search_cb_t search_cb;
- void *search_cb_hook;
-};
-
-
-#ifdef COMPAT_FALLBACK
-/* This is a compatibility function for GPGSM 2.0.0, which does not
- support the --data option with the EXPORT command. */
-static gpg_error_t
-export_cert_compat (char *fpr, struct cert *cert)
-{
- gpg_error_t err;
- assuan_context_t ctx;
- const char *argv[] = { "gpgsm", "--server", NULL };
- int got;
-#define COMMANDLINELEN 80
- char cmd[COMMANDLINELEN];
- int output_fds[2];
- int child_fds[2];
-
-#define MAX_CERT_SIZE 4096
- cert->cert_der = malloc (MAX_CERT_SIZE);
- if (!cert->cert_der)
- return gpg_error_from_syserror ();
-
- if(pipe (output_fds) < 0)
- return gpg_error_from_syserror ();
-
- child_fds[0] = assuan_fd_from_posix_fd (output_fds[1]);
- child_fds[1] = -1;
-
- err = assuan_new (&ctx);
- if (err)
- {
- close (output_fds[0]);
- close (output_fds[1]);
- DEBUG (DBG_CRIT, "failed to allocate assuan context: %s\n",
- gpg_strerror (err));
- return err;
- }
-
- err = assuan_pipe_connect (ctx, get_gpgsm_path (), argv, child_fds,
- NULL, NULL, 128);
- close (output_fds[1]);
- if (err)
- {
- close (output_fds[0]);
- assuan_release (ctx);
- DEBUG (DBG_CRIT, "failed to spawn %s\n", get_gpgsm_path ());
- return err;
- }
-
- snprintf (cmd, sizeof (cmd), "OUTPUT FD=%i", output_fds[1]);
- err = assuan_transact (ctx, cmd, NULL, NULL, NULL, NULL, NULL, NULL);
- if (err)
- goto export_out;
-
- /* FIXME: This will only work if the certificate is small and fits
- into the pipe buffer completely!!! */
- snprintf (cmd, sizeof (cmd), "EXPORT %s\n", cert->fpr);
- err = assuan_transact (ctx, cmd, NULL, NULL, NULL, NULL, NULL, NULL);
- if (err)
- goto export_out;
-
- do
- {
- got = read (output_fds[0], cert->cert_der + cert->cert_der_len,
- MAX_CERT_SIZE - cert->cert_der_len);
- if (got > 0)
- cert->cert_der_len += got;
- }
- while (!err && got > 0 && cert->cert_der_len < MAX_CERT_SIZE);
-
- if (got < 0 || cert->cert_der_len == MAX_CERT_SIZE)
- err = gpg_error (GPG_ERR_GENERAL);
-
- export_out:
- assuan_release (ctx);
- close (output_fds[0]);
- return err;
-}
-#endif
-
struct export_hook
{
@@ -653,8 +528,11 @@ export_cert_cb (void *hook, const void *line_data, size_t line_len)
}
+/* Export the certifciate using a second assuan connection. This is
+ * called during the key listing after a "crt" record has been
+ * received. */
static gpg_error_t
-export_cert (char *fpr, struct cert *cert)
+export_cert (const char *fpr, struct cert *cert)
{
gpg_error_t err;
assuan_context_t ctx;
@@ -684,7 +562,7 @@ export_cert (char *fpr, struct cert *cert)
exp.buffer_len = 0;
exp.buffer_size = 0;
- snprintf (cmd, sizeof (cmd), "EXPORT --data -- %s\n", cert->fpr);
+ snprintf (cmd, sizeof (cmd), "EXPORT --data -- %s", cert->fpr);
err = assuan_transact (ctx, cmd, export_cert_cb, &exp,
NULL, NULL, NULL, NULL);
assuan_release (ctx);
@@ -694,19 +572,6 @@ export_cert (char *fpr, struct cert *cert)
cert->cert_der = exp.buffer;
cert->cert_der_len = exp.buffer_len;
}
-#ifdef COMPAT_FALLBACK
- else if (gpg_err_code (err) == GPG_ERR_ASS_NO_OUTPUT)
- {
- /* For compatibility with GPGSM 2.0.0, we fall back to a work
- around in that case. */
- if (cert->cert_der)
- {
- free (cert->cert_der);
- cert->cert_der = NULL;
- }
- err = export_cert_compat (fpr, cert);
- }
-#endif
if (!err)
err = scute_agent_is_trusted (fpr, &cert->is_trusted);
@@ -715,40 +580,18 @@ export_cert (char *fpr, struct cert *cert)
}
-static gpg_error_t
-search_certs_by_field (void *hook, struct cert *cert)
-{
- struct search_ctx_by_field *ctx = hook;
- gpg_error_t err = 0;
-
- if ((ctx->field == SEARCH_BY_GRIP && !strcmp (ctx->pattern, cert->grip))
- || (ctx->field == SEARCH_BY_FPR && !strcmp (ctx->pattern, cert->fpr)))
- {
- if (strlen (cert->fpr) != 40)
- return gpg_error (GPG_ERR_GENERAL);
-
- err = export_cert (cert->fpr, cert);
- if (err)
- return err;
-
- err = (*ctx->search_cb) (ctx->search_cb_hook, cert);
- }
-
- return err;
-}
-
-
-/* Invoke SEARCH_CB for each certificate found using assuan connection
- CTX to GPGSM. */
+/* Search for certificates using a key listing using PATTERN which is
+ * described by MODE. Invoke SEARCH_CB for each certificate found. */
gpg_error_t
-scute_gpgsm_search_certs_by_grip (const char *grip,
- cert_search_cb_t search_cb,
- void *search_cb_hook)
+scute_gpgsm_search_certs (enum keylist_modes mode, const char *pattern,
+ cert_search_cb_t search_cb,
+ void *search_cb_hook)
{
gpg_error_t err;
assuan_context_t ctx;
const char *argv[] = { "gpgsm", "--server", NULL };
- struct search_ctx_by_field search;
+ char line[ASSUAN_LINELENGTH];
+ struct keylist_ctx keylist_ctx;
err = assuan_new (&ctx);
if (err)
@@ -763,56 +606,37 @@ scute_gpgsm_search_certs_by_grip (const char *grip,
if (err)
{
assuan_release (ctx);
- DEBUG (DBG_CRIT, "spawning %s\n", get_gpgsm_path ());
+ DEBUG (DBG_CRIT, "failed to spawn %s\n", get_gpgsm_path ());
return err;
}
- search.field = SEARCH_BY_GRIP;
- search.pattern = grip;
- search.search_cb = search_cb;
- search.search_cb_hook = search_cb_hook;
+ memset (&keylist_ctx, 0, sizeof keylist_ctx);
+ keylist_ctx.search_cb = search_cb;
+ keylist_ctx.search_cb_hook = search_cb_hook;
- err = scute_gpgsm_search_certs (ctx, &search_certs_by_field, &search);
- assuan_release (ctx);
- return err;
-}
+ err = assuan_transact (ctx, "OPTION with-key-data", NULL, NULL,
+ NULL, NULL, NULL, NULL);
+ if (err)
+ goto leave;
-/* Invoke SEARCH_CB for each certificate found using assuan connection
- CTX to GPGSM. */
-gpg_error_t
-scute_gpgsm_search_certs_by_fpr (const char *fpr,
- cert_search_cb_t search_cb,
- void *search_cb_hook)
-{
- gpg_error_t err;
- assuan_context_t ctx;
- const char *argv[] = { "gpgsm", "--server", NULL };
- struct search_ctx_by_field search;
-
- err = assuan_new (&ctx);
+ snprintf (line, sizeof line, "LISTKEYS %s%s",
+ mode == KEYLIST_BY_GRIP? "&":"",
+ pattern);
+ err = assuan_transact (ctx, line,
+ keylist_cb, &keylist_ctx,
+ NULL, NULL,
+ NULL, NULL);
if (err)
- {
- DEBUG (DBG_CRIT, "failed to allocate assuan context: %s",
- gpg_strerror (err));
- return err;
- }
+ goto leave;
- err = assuan_pipe_connect (ctx, get_gpgsm_path (), argv, NULL,
- NULL, NULL, 128);
+ /* Signal the EOF. This is not done by Assuan for us. */
+ err = keylist_cb (&keylist_ctx, NULL, 0);
if (err)
- {
- assuan_release (ctx);
- DEBUG (DBG_CRIT, "failed to spawn %s\n", get_gpgsm_path ());
- return err;
- }
-
- search.field = SEARCH_BY_FPR;
- search.pattern = fpr;
- search.search_cb = search_cb;
- search.search_cb_hook = search_cb_hook;
+ goto leave;
- err = scute_gpgsm_search_certs (ctx, &search_certs_by_field, &search);
+ leave:
+ cert_reset (&keylist_ctx.cert);
assuan_release (ctx);
return err;
}
diff --git a/src/cert.h b/src/cert.h
index b57db0f..d1a6cb1 100644
--- a/src/cert.h
+++ b/src/cert.h
@@ -92,7 +92,7 @@ struct cert
/* The key grip. */
unsigned char grip[41];
- /* The chain ID. */
+ /* The chain ID as return by a gpgsm key listing. */
unsigned char chain_id[41];
/* The certificate in DER format. This is not entered by the search
@@ -109,22 +109,23 @@ struct cert
/* From cert-gpgsm.c. */
+enum keylist_modes
+ {
+ KEYLIST_BY_GRIP,
+ KEYLIST_BY_FPR
+ };
+
/* The callback type invoked for each certificate found in the
search. */
typedef gpg_error_t (*cert_search_cb_t) (void *hook, struct cert *cert);
-/* Invoke SEARCH_CB for each certificate found using assuan connection
- CTX to GPGSM. */
-gpg_error_t scute_gpgsm_search_certs_by_grip (const char *grip,
- cert_search_cb_t search_cb,
- void *search_cb_hook);
-
-/* Invoke SEARCH_CB for each certificate found using assuan connection
- CTX to GPGSM. */
-gpg_error_t scute_gpgsm_search_certs_by_fpr (const char *fpr,
- cert_search_cb_t search_cb,
- void *search_cb_hook);
+/* Search for certificates using a key listing using PATTERN which is
+ * described by MODE. Invoke SEARCH_CB for each certificate found. */
+gpg_error_t scute_gpgsm_search_certs (enum keylist_modes mode,
+ const char *pattern,
+ cert_search_cb_t search_cb,
+ void *search_cb_hook);
/* From cert-object.c. */
diff --git a/src/gpgsm.c b/src/gpgsm.c
index 27e5036..b0d4c4c 100644
--- a/src/gpgsm.c
+++ b/src/gpgsm.c
@@ -91,7 +91,7 @@ search_cb (void *hook, struct cert *cert)
might still be able to proceed, for example with client
authentication. */
if (ctx->with_chain && strcmp (cert->chain_id, cert->fpr))
- scute_gpgsm_search_certs_by_fpr (cert->chain_id, search_cb, ctx);
+ scute_gpgsm_search_certs (KEYLIST_BY_FPR, cert->chain_id, search_cb, ctx);
/* Turn this certificate into a certificate object. */
err = scute_attr_cert (cert, ctx->grip, &attrp, &attr_countp);
@@ -161,6 +161,6 @@ scute_gpgsm_get_cert (char *grip, const char *certref,
DEBUG (DBG_INFO, "scute_gpgsm_get_cert: falling back to gpgsm");
search.with_chain = true;
- err = scute_gpgsm_search_certs_by_grip (grip, search_cb, &search);
+ err = scute_gpgsm_search_certs (KEYLIST_BY_GRIP, grip, search_cb, &search);
return err;
}
-----------------------------------------------------------------------
Summary of changes:
src/agent.c | 2 +-
src/agent.h | 2 +-
src/cert-gpgsm.c | 344 ++++++++++++++-----------------------------------------
src/cert.h | 25 ++--
src/gpgsm.c | 4 +-
5 files changed, 101 insertions(+), 276 deletions(-)
hooks/post-receive
--
PKCS#11 token on top of gpg-agent
http://git.gnupg.org
More information about the Gnupg-commits
mailing list