diff options
Diffstat (limited to 'sm/call-agent.c')
-rw-r--r-- | sm/call-agent.c | 93 |
1 files changed, 91 insertions, 2 deletions
diff --git a/sm/call-agent.c b/sm/call-agent.c index 14e2fdf34..1982b228c 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -32,7 +32,7 @@ #include "gpgsm.h" #include "../assuan/assuan.h" #include "i18n.h" - +#include "keydb.h" /* fixme: Move this to import.c */ static ASSUAN_CONTEXT agent_ctx = NULL; static int force_pipe_server = 0; @@ -49,6 +49,11 @@ struct genkey_parm_s { size_t sexplen; }; +struct learn_parm_s { + int error; + ASSUAN_CONTEXT ctx; + struct membuf *data; +}; struct membuf { size_t len; @@ -218,7 +223,8 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length) { struct membuf *data = opaque; - put_membuf (data, buffer, length); + if (buffer) + put_membuf (data, buffer, length); return 0; } @@ -520,3 +526,86 @@ gpgsm_agent_havekey (const char *hexkeygrip) return map_assuan_err (rc); } + +static AssuanError +learn_cb (void *opaque, const void *buffer, size_t length) +{ + struct learn_parm_s *parm = opaque; + size_t len; + char *buf; + KsbaCert cert; + int rc; + + if (parm->error) + return 0; + + if (buffer) + { + put_membuf (parm->data, buffer, length); + return 0; + } + /* END encountered - process what we have */ + buf = get_membuf (parm->data, &len); + if (!buf) + { + parm->error = GNUPG_Out_Of_Core; + return 0; + } + + + /* FIXME: this shoudl go inot import.c */ + cert = ksba_cert_new (); + if (!cert) + { + parm->error = GNUPG_Out_Of_Core; + return 0; + } + rc = ksba_cert_init_from_mem (cert, buf, len); + if (rc) + { + log_error ("failed to parse a certificate: %s\n", ksba_strerror (rc)); + ksba_cert_release (cert); + parm->error = map_ksba_err (rc); + return 0; + } + + rc = gpgsm_basic_cert_check (cert); + if (rc) + log_error ("invalid certificate: %s\n", gnupg_strerror (rc)); + else + { + keydb_store_cert (cert); + log_error ("certificate stored\n"); + } + + ksba_cert_release (cert); + init_membuf (parm->data, 4096); + return 0; +} + +/* Call the agent to learn about a smartcard */ +int +gpgsm_agent_learn () +{ + int rc; + struct learn_parm_s learn_parm; + struct membuf data; + size_t len; + + rc = start_agent (); + if (rc) + return rc; + + init_membuf (&data, 4096); + learn_parm.error = 0; + learn_parm.ctx = agent_ctx; + learn_parm.data = &data; + rc = assuan_transact (agent_ctx, "LEARN --send", + learn_cb, &learn_parm, + NULL, NULL, NULL, NULL); + xfree (get_membuf (&data, &len)); + if (rc) + return map_assuan_err (rc); + return learn_parm.error; +} + |