2004-09-25 Moritz Schulte <moritz@g10code.com>

* agent.h: Declare: agent_pksign_do.
	(struct server_control_s): New member: raw_value.

	* pksign.c (do_encode_md): New argument: raw_value; support
	generation of raw (non-pkcs1) data objects; adjust callers.
	(agent_pksign_do): New function, based on code ripped
	out from agent_pksign.
	(agent_pksign): Use agent_pksign_do.

	* command.c (start_command_handler): Set ctrl.digest.raw_value.
This commit is contained in:
Moritz Schulte 2004-09-26 21:48:13 +00:00
parent f100401478
commit 1db08a412c
4 changed files with 113 additions and 40 deletions

View File

@ -1,3 +1,16 @@
2004-09-25 Moritz Schulte <moritz@g10code.com>
* agent.h: Declare: agent_pksign_do.
(struct server_control_s): New member: raw_value.
* pksign.c (do_encode_md): New argument: raw_value; support
generation of raw (non-pkcs1) data objects; adjust callers.
(agent_pksign_do): New function, based on code ripped
out from agent_pksign.
(agent_pksign): Use agent_pksign_do.
* command.c (start_command_handler): Set ctrl.digest.raw_value.
2004-09-09 Werner Koch <wk@g10code.de>
* gpg-agent.c (check_for_running_agent): New.

View File

@ -95,6 +95,7 @@ struct server_control_s {
int algo;
unsigned char value[MAX_DIGEST_LEN];
int valuelen;
int raw_value: 1;
} digest;
char keygrip[20];
int have_keygrip;
@ -159,6 +160,8 @@ void agent_unlock_cache_entry (void **cache_id);
/*-- pksign.c --*/
int agent_pksign_do (CTRL ctrl, const char *desc_text,
gcry_sexp_t *signature_sexp, int ignore_cache);
int agent_pksign (ctrl_t ctrl, const char *desc_text,
FILE *outfp, int ignore_cache);

View File

@ -854,6 +854,7 @@ start_command_handler (int listen_fd, int fd)
ctrl.server_local->assuan_ctx = ctx;
ctrl.server_local->message_fd = -1;
ctrl.server_local->use_cache_for_signing = 1;
ctrl.digest.raw_value = 0;
if (DBG_ASSUAN)
assuan_set_log_stream (ctx, log_get_stream ());

View File

@ -32,41 +32,61 @@
static int
do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash)
do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
int raw_value)
{
gcry_sexp_t hash;
const char *s;
char tmp[16+1];
int i, rc;
int rc;
s = gcry_md_algo_name (algo);
if (s && strlen (s) < 16)
if (! raw_value)
{
for (i=0; i < strlen (s); i++)
tmp[i] = tolower (s[i]);
tmp[i] = '\0';
const char *s;
char tmp[16+1];
int i;
s = gcry_md_algo_name (algo);
if (s && strlen (s) < 16)
{
for (i=0; i < strlen (s); i++)
tmp[i] = tolower (s[i]);
tmp[i] = '\0';
}
rc = gcry_sexp_build (&hash, NULL,
"(data (flags pkcs1) (hash %s %b))",
tmp, mdlen, md);
}
rc = gcry_sexp_build (&hash, NULL,
"(data (flags pkcs1) (hash %s %b))",
tmp,
mdlen, md);
else
{
gcry_mpi_t mpi;
rc = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, md, mdlen, NULL);
if (! rc)
{
rc = gcry_sexp_build (&hash, NULL,
"(data (flags raw) (value %m))",
mpi);
gcry_mpi_release (mpi);
}
}
*r_hash = hash;
return rc;
}
/* SIGN whatever information we have accumulated in CTRL and write it
back to OUTFP. */
/* SIGN whatever information we have accumulated in CTRL and return
the signature S-Expression. */
int
agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
agent_pksign_do (CTRL ctrl, const char *desc_text,
gcry_sexp_t *signature_sexp, int ignore_cache)
{
gcry_sexp_t s_skey = NULL, s_hash = NULL, s_sig = NULL;
gcry_sexp_t s_skey = NULL, s_sig = NULL;
unsigned char *shadow_info = NULL;
int rc;
char *buf = NULL;
size_t len;
unsigned int rc = 0; /* FIXME: gpg-error? */
if (!ctrl->have_keygrip)
if (! ctrl->have_keygrip)
return gpg_error (GPG_ERR_NO_SECKEY);
rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip,
@ -77,32 +97,47 @@ agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
goto leave;
}
if (!s_skey)
{ /* divert operation to the smartcard */
unsigned char *sigbuf;
if (! s_skey)
{
/* divert operation to the smartcard */
unsigned char *buf = NULL;
size_t len = 0;
rc = divert_pksign (ctrl,
ctrl->digest.value,
ctrl->digest.valuelen,
ctrl->digest.algo,
shadow_info, &sigbuf);
shadow_info, &buf);
if (rc)
{
log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
goto leave;
}
len = gcry_sexp_canon_len (sigbuf, 0, NULL, NULL);
len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
assert (len);
buf = sigbuf;
rc = gcry_sexp_sscan (&s_sig, NULL, buf, len);
xfree (buf);
if (rc)
{
log_error ("failed to convert sigbuf returned by divert_pksign "
"into S-Exp: %s", gpg_strerror (rc));
goto leave;
}
}
else
{ /* no smartcard, but a private key */
{
/* no smartcard, but a private key */
gcry_sexp_t s_hash = NULL;
/* put the hash into a sexp */
rc = do_encode_md (ctrl->digest.value,
ctrl->digest.valuelen,
ctrl->digest.algo,
&s_hash);
&s_hash,
ctrl->digest.raw_value);
if (rc)
goto leave;
@ -114,6 +149,7 @@ agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
/* sign */
rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
gcry_sexp_release (s_hash);
if (rc)
{
log_error ("signing failed: %s\n", gpg_strerror (rc));
@ -125,26 +161,46 @@ agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
log_debug ("result: ");
gcry_sexp_dump (s_sig);
}
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0);
assert (len);
buf = xmalloc (len);
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len);
assert (len);
}
leave:
*signature_sexp = s_sig;
gcry_sexp_release (s_skey);
xfree (shadow_info);
return rc;
}
/* SIGN whatever information we have accumulated in CTRL and write it
back to OUTFP. */
int
agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
{
gcry_sexp_t s_sig = NULL;
char *buf = NULL;
size_t len = 0;
int rc = 0;
rc = agent_pksign_do (ctrl, desc_text, &s_sig, ignore_cache);
if (rc)
goto leave;
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0);
assert (len);
buf = xmalloc (len);
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len);
assert (len);
/* FIXME: we must make sure that no buffering takes place or we are
in full control of the buffer memory (easy to do) - should go
into assuan. */
fwrite (buf, 1, len, outfp);
leave:
gcry_sexp_release (s_skey);
gcry_sexp_release (s_hash);
gcry_sexp_release (s_sig);
xfree (buf);
xfree (shadow_info);
return rc;
}