diff options
author | Moritz Schulte <mo@g10code.com> | 2004-09-26 23:48:13 +0200 |
---|---|---|
committer | Moritz Schulte <mo@g10code.com> | 2004-09-26 23:48:13 +0200 |
commit | 1db08a412cc349bc38786de78ed460cf71f8467f (patch) | |
tree | 7faa93fa9fd639ae33b6225570d3cc4fad6eebf3 /agent/pksign.c | |
parent | (show_key_with_all_names): Print the card S/N. (diff) | |
download | gnupg2-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.c | 136 |
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; } - - |