summaryrefslogtreecommitdiffstats
path: root/agent/pksign.c
diff options
context:
space:
mode:
authorMoritz Schulte <mo@g10code.com>2004-09-26 23:48:13 +0200
committerMoritz Schulte <mo@g10code.com>2004-09-26 23:48:13 +0200
commit1db08a412cc349bc38786de78ed460cf71f8467f (patch)
tree7faa93fa9fd639ae33b6225570d3cc4fad6eebf3 /agent/pksign.c
parent(show_key_with_all_names): Print the card S/N. (diff)
downloadgnupg2-1db08a412cc349bc38786de78ed460cf71f8467f.tar.xz
gnupg2-1db08a412cc349bc38786de78ed460cf71f8467f.zip
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.
Diffstat (limited to '')
-rw-r--r--agent/pksign.c136
1 files changed, 96 insertions, 40 deletions
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;
}
-
-