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 + + * 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 * 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) { - 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; } - -