diff options
Diffstat (limited to 'g10/call-agent.c')
-rw-r--r-- | g10/call-agent.c | 208 |
1 files changed, 121 insertions, 87 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index 202865f70..30b46fa99 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -218,6 +218,30 @@ unescape_status_string (const unsigned char *s) return buffer; } +/* Copy the text ATEXT into the buffer P and do plus '+' and percent + escaping. Note that the provided buffer needs to be 3 times the + size of ATEXT plus 1. Returns a pointer to the leading Nul in P. */ +static char * +percent_plus_escape (char *p, const char *atext) +{ + const unsigned char *s; + + for (s=atext; *s; s++) + { + if (*s < ' ' || *s == '+') + { + sprintf (p, "%%%02X", *s); + p += 3; + } + else if (*s == ' ') + *p++ = '+'; + else + *p++ = *s; + } + *p = 0; + return p; +} + /* Take a 20 byte hexencoded string and put it into the the provided 20 byte buffer FPR in binary format. */ static int @@ -258,93 +282,6 @@ store_serialno (const char *line) -#if 0 -/* Handle a KEYPARMS inquiry. Note, we only send the data, - assuan_transact takes care of flushing and writing the end */ -static int -inq_genkey_parms (void *opaque, const char *keyword) -{ - struct genkey_parm_s *parm = opaque; - int rc; - - rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen); - return rc; -} - - - -/* Call the agent to generate a new key */ -int -agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey) -{ - int rc; - struct genkey_parm_s gk_parm; - membuf_t data; - size_t len; - char *buf; - - *r_pubkey = NULL; - rc = start_agent (); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, - NULL, NULL, NULL, NULL); - if (rc) - return rc; - - init_membuf (&data, 1024); - gk_parm.ctx = agent_ctx; - gk_parm.sexp = keyparms; - gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL); - if (!gk_parm.sexplen) - return gpg_error (GPG_ERR_INV_VALUE); - rc = assuan_transact (agent_ctx, "GENKEY", - membuf_data_cb, &data, - inq_genkey_parms, &gk_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return rc; - } - buf = get_membuf (&data, &len); - if (!buf) - return gpg_error (GPG_ERR_ENOMEM); - if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) - { - xfree (buf); - return gpg_error (GPG_ERR_INV_SEXP); - } - *r_pubkey = buf; - return 0; -} -#endif /*0*/ - - - -/* Ask the agent whether the corresponding secret key is available for - the given keygrip. */ -int -agent_havekey (const char *hexkeygrip) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); - - snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip); - line[DIM(line)-1] = 0; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return rc; -} - - /* Release the card info structure INFO. */ void agent_release_card_info (struct agent_card_info_s *info) @@ -856,3 +793,100 @@ agent_clear_pin_cache (const char *sn) { } + + + + +/* Note: All strings shall be UTF-8. On success the caler needs to + free the string stored at R_PASSPHRASE. On error NULL will be + stored at R_PASSPHRASE and an appropriate fpf error code + returned. */ +gpg_error_t +agent_get_passphrase (const char *cache_id, + const char *err_msg, + const char *prompt, + const char *desc_msg, + char **r_passphrase) +{ + int rc; + char *line, *p; + char cmd[] = "GET_PASSPHRASE --data -- "; + membuf_t data; + + *r_passphrase = NULL; + + rc = start_agent (); + if (rc) + return rc; + + /* We allocate 3 times the needed space for the texts so that + there is enough space for escaping. */ + line = xtrymalloc ( strlen (cmd) + 1 + + (cache_id? 3*strlen (cache_id): 1) + 1 + + (err_msg? 3*strlen (err_msg): 1) + 1 + + (prompt? 3*strlen (prompt): 1) + 1 + + (desc_msg? 3*strlen (desc_msg): 1) + 1 + + 1); + if (!line) + return gpg_error_from_syserror (); + + p = stpcpy (line, cmd); + if (cache_id && *cache_id) + p = percent_plus_escape (p, cache_id); + else + *p++ = 'X'; + *p++ = ' '; + + if (err_msg && *err_msg) + p = percent_plus_escape (p, err_msg); + else + *p++ = 'X'; + *p++ = ' '; + + if (prompt && *prompt) + p = percent_plus_escape (p, prompt); + else + *p++ = 'X'; + *p++ = ' '; + + if (desc_msg && *desc_msg) + p = percent_plus_escape (p, desc_msg); + else + *p++ = 'X'; + *p = 0; + + init_membuf_secure (&data, 64); + rc = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, NULL, NULL, NULL, NULL); + + if (rc) + xfree (get_membuf (&data, NULL)); + else + { + put_membuf (&data, "", 1); + *r_passphrase = get_membuf (&data, NULL); + if (!*r_passphrase) + rc = gpg_error_from_syserror (); + } + xfree (line); + return rc; +} + + +gpg_error_t +agent_clear_passphrase (const char *cache_id) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + + if (!cache_id || !*cache_id) + return 0; + + rc = start_agent (); + if (rc) + return rc; + + snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id); + line[DIM(line)-1] = 0; + return assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); +} |