mirror of
git://git.gnupg.org/gnupg.git
synced 2024-10-29 19:48:43 +01:00
gpgsm: Use a cache for ISTRUSTED queries.
* sm/call-agent.c (struct istrusted_cache_s): New.
(istrusted_cache, istrusted_cache_valid): New.
(istrusted_cache_disabled): New.
(flush_istrusted_cache): New.
(struct istrusted_status_parm_s): New.
(istrusted_status_cb): Fill the cache.
(gpgsm_agent_istrusted): Implement a cache.
--
Not a really measurable performance improvements on Linux but maybe
somewhat on Windows (not yet tested). However, it does not clutter
the log files with IPC calls returning NOT_TRUSTED.
GnuPG-bug-id: 7308
(cherry picked from commit ef2be95258
)
This commit is contained in:
parent
4fa82eec43
commit
09d4b8f496
145
sm/call-agent.c
145
sm/call-agent.c
@ -82,7 +82,45 @@ struct default_inq_parm_s
|
|||||||
assuan_context_t ctx;
|
assuan_context_t ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* An object and variable to cache ISTRUSTED calls. The cache is
|
||||||
|
* global and reset with each mark trusted. We also have a disabled
|
||||||
|
* flag here in case the gpg-agent did not allow us to query all
|
||||||
|
* trusted keys at once. */
|
||||||
|
struct istrusted_cache_s
|
||||||
|
{
|
||||||
|
struct istrusted_cache_s *next;
|
||||||
|
struct rootca_flags_s flags; /* The flags of this fingerprint. */
|
||||||
|
char fpr[1]; /* The fingerprint of the trusted key in hex format. */
|
||||||
|
};
|
||||||
|
typedef struct istrusted_cache_s *istrusted_cache_t;
|
||||||
|
static istrusted_cache_t istrusted_cache;
|
||||||
|
static int istrusted_cache_valid;
|
||||||
|
static int istrusted_cache_disabled;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
flush_istrusted_cache (void)
|
||||||
|
{
|
||||||
|
istrusted_cache_t mycache;
|
||||||
|
|
||||||
|
/* First unlink the cache to be npth safe. Note that we don't clear
|
||||||
|
* the the disabled flag - this is considered a permantent error. */
|
||||||
|
mycache = istrusted_cache;
|
||||||
|
istrusted_cache = NULL;
|
||||||
|
istrusted_cache_valid = 0;
|
||||||
|
|
||||||
|
while (mycache)
|
||||||
|
{
|
||||||
|
istrusted_cache_t next = mycache->next;
|
||||||
|
xfree (mycache);
|
||||||
|
mycache = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Print a warning if the server's version number is less than our
|
/* Print a warning if the server's version number is less than our
|
||||||
version number. Returns an error code on a connection problem. */
|
version number. Returns an error code on a connection problem. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
@ -861,29 +899,51 @@ gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct istrusted_status_parm_s
|
||||||
|
{
|
||||||
|
struct rootca_flags_s flags;
|
||||||
|
istrusted_cache_t cache;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
istrusted_status_cb (void *opaque, const char *line)
|
istrusted_status_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
struct rootca_flags_s *flags = opaque;
|
struct istrusted_status_parm_s *parm = opaque;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
if ((s = has_leading_keyword (line, "TRUSTLISTFLAG")))
|
if ((s = has_leading_keyword (line, "TRUSTLISTFLAG")))
|
||||||
{
|
{
|
||||||
line = s;
|
line = s;
|
||||||
if (has_leading_keyword (line, "relax"))
|
if (has_leading_keyword (line, "relax"))
|
||||||
flags->relax = 1;
|
parm->flags.relax = 1;
|
||||||
else if (has_leading_keyword (line, "cm"))
|
else if (has_leading_keyword (line, "cm"))
|
||||||
flags->chain_model = 1;
|
parm->flags.chain_model = 1;
|
||||||
else if (has_leading_keyword (line, "qual"))
|
else if (has_leading_keyword (line, "qual"))
|
||||||
flags->qualified = 1;
|
parm->flags.qualified = 1;
|
||||||
else if (has_leading_keyword (line, "de-vs"))
|
else if (has_leading_keyword (line, "de-vs"))
|
||||||
flags->de_vs = 1;
|
parm->flags.de_vs = 1;
|
||||||
|
|
||||||
|
/* Copy the current flags to the current list item. */
|
||||||
|
if (parm->cache)
|
||||||
|
parm->cache->flags = parm->flags;
|
||||||
|
}
|
||||||
|
else if ((s = has_leading_keyword (line, "TRUSTLISTFPR")) && *s)
|
||||||
|
{
|
||||||
|
istrusted_cache_t ci;
|
||||||
|
|
||||||
|
ci = xtrymalloc (sizeof *ci + strlen (s));
|
||||||
|
if (!ci)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
strcpy (ci->fpr, s);
|
||||||
|
memset (&ci->flags, 0, sizeof ci->flags);
|
||||||
|
ci->next = parm->cache;
|
||||||
|
parm->cache = ci;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Ask the agent whether the certificate is in the list of trusted
|
/* Ask the agent whether the certificate is in the list of trusted
|
||||||
keys. The certificate is either specified by the CERT object or by
|
keys. The certificate is either specified by the CERT object or by
|
||||||
the fingerprint HEXFPR. ROOTCA_FLAGS is guaranteed to be cleared
|
the fingerprint HEXFPR. ROOTCA_FLAGS is guaranteed to be cleared
|
||||||
@ -894,8 +954,12 @@ gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert, const char *hexfpr,
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
char *fpr_buffer = NULL;
|
||||||
|
struct istrusted_status_parm_s parm;
|
||||||
|
istrusted_cache_t ci;
|
||||||
|
|
||||||
memset (rootca_flags, 0, sizeof *rootca_flags);
|
memset (rootca_flags, 0, sizeof *rootca_flags);
|
||||||
|
memset (&parm, 0, sizeof parm);
|
||||||
|
|
||||||
if (cert && hexfpr)
|
if (cert && hexfpr)
|
||||||
return gpg_error (GPG_ERR_INV_ARG);
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
@ -904,29 +968,64 @@ gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert, const char *hexfpr,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (hexfpr)
|
if (!hexfpr)
|
||||||
{
|
{
|
||||||
snprintf (line, DIM(line), "ISTRUSTED %s", hexfpr);
|
fpr_buffer = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
||||||
}
|
if (!fpr_buffer)
|
||||||
else
|
|
||||||
{
|
|
||||||
char *fpr;
|
|
||||||
|
|
||||||
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
|
||||||
if (!fpr)
|
|
||||||
{
|
{
|
||||||
log_error ("error getting the fingerprint\n");
|
log_error ("error getting the fingerprint\n");
|
||||||
return gpg_error (GPG_ERR_GENERAL);
|
rc = gpg_error (GPG_ERR_GENERAL);
|
||||||
|
goto leave;
|
||||||
}
|
}
|
||||||
|
hexfpr = fpr_buffer;
|
||||||
snprintf (line, DIM(line), "ISTRUSTED %s", fpr);
|
|
||||||
xfree (fpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First try to get the info from the cache. */
|
||||||
|
if (!istrusted_cache_disabled && !istrusted_cache_valid)
|
||||||
|
{
|
||||||
|
/* Cache is empty - fill it. */
|
||||||
|
rc = assuan_transact (agent_ctx, "LISTTRUSTED --status",
|
||||||
|
NULL, NULL, NULL, NULL,
|
||||||
|
istrusted_status_cb, &parm);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
if (gpg_err_code (rc) != GPG_ERR_FORBIDDEN)
|
||||||
|
log_error ("filling istrusted cache failed: %s\n",
|
||||||
|
gpg_strerror (rc));
|
||||||
|
istrusted_cache_disabled = 1;
|
||||||
|
rc = 0; /* Fallback to single requests. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
istrusted_cache_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (istrusted_cache_valid)
|
||||||
|
{
|
||||||
|
for (ci = istrusted_cache; ci; ci = ci->next)
|
||||||
|
if (!strcmp (ci->fpr, hexfpr))
|
||||||
|
break; /* Found. */
|
||||||
|
if (ci)
|
||||||
|
{
|
||||||
|
*rootca_flags = ci->flags;
|
||||||
|
rootca_flags->valid = 1;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = gpg_error (GPG_ERR_NOT_TRUSTED);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (line, DIM(line), "ISTRUSTED %s", hexfpr);
|
||||||
rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
|
rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
|
||||||
istrusted_status_cb, rootca_flags);
|
istrusted_status_cb, &parm);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rootca_flags->valid = 1;
|
{
|
||||||
|
*rootca_flags = parm.flags;
|
||||||
|
rootca_flags->valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
xfree (fpr_buffer);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,6 +1067,10 @@ gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert)
|
|||||||
|
|
||||||
rc = assuan_transact (agent_ctx, line, NULL, NULL,
|
rc = assuan_transact (agent_ctx, line, NULL, NULL,
|
||||||
default_inq_cb, &inq_parm, NULL, NULL);
|
default_inq_cb, &inq_parm, NULL, NULL);
|
||||||
|
/* Marktrusted changes the trustlist and thus we need to flush the
|
||||||
|
* cache. */
|
||||||
|
if (!rc)
|
||||||
|
flush_istrusted_cache ();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user