aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/ChangeLog13
-rw-r--r--agent/agent.h3
-rw-r--r--agent/command.c1
-rw-r--r--agent/pksign.c136
4 files changed, 113 insertions, 40 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 470c70162..032308608 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,16 @@
+2004-09-25 Moritz Schulte <[email protected]>
+
+ * 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 <[email protected]>
* gpg-agent.c (check_for_running_agent): New.
diff --git a/agent/agent.h b/agent/agent.h
index 89fc4285e..8112c258a 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -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);
diff --git a/agent/command.c b/agent/command.c
index 1d1ae9704..02bbf3429 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -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 ());
diff --git a/agent/pksign.c b/agent/pksign.c
index acde66029..11e964837 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -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)
+ {
+ 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);
+ }
+ else
{
- for (i=0; i < strlen (s); i++)
- tmp[i] = tolower (s[i]);
- tmp[i] = '\0';
+ 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);
+ }
+
}
- rc = gcry_sexp_build (&hash, NULL,
- "(data (flags pkcs1) (hash %s %b))",
- tmp,
- mdlen, md);
+
*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;
}
-
-