summaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-08-16 16:24:38 +0200
committerWerner Koch <wk@gnupg.org>2002-08-16 16:24:38 +0200
commitca7ed726a7f35a3154ecdb8f6f9e4f848cc963b5 (patch)
tree836406c1c3a75e7a8940a0eab6e95883706f6ea3 /agent
parent* assuan.h: Renamed Bad_Certificate_Path to Bad_Certificate_Chain. (diff)
downloadgnupg2-ca7ed726a7f35a3154ecdb8f6f9e4f848cc963b5.tar.xz
gnupg2-ca7ed726a7f35a3154ecdb8f6f9e4f848cc963b5.zip
* call-scd.c (learn_status_cb): Handle CERTINFO status.
(agent_card_learn): Add args for certinfo cb. * learncard.c (release_certinfo,certinfo_cb): New. (send_cert_back): New. With factored out code from .. (agent_handle_learn): here. Return certinfo stuff.
Diffstat (limited to 'agent')
-rw-r--r--agent/ChangeLog8
-rw-r--r--agent/agent.h4
-rw-r--r--agent/call-scd.c15
-rw-r--r--agent/gpg-agent.c5
-rw-r--r--agent/learncard.c167
-rw-r--r--agent/protect-tool.c5
6 files changed, 168 insertions, 36 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index ac4eb1db6..006d53ebe 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,11 @@
+2002-08-16 Werner Koch <wk@gnupg.org>
+
+ * call-scd.c (learn_status_cb): Handle CERTINFO status.
+ (agent_card_learn): Add args for certinfo cb.
+ * learncard.c (release_certinfo,certinfo_cb): New.
+ (send_cert_back): New. With factored out code from ..
+ (agent_handle_learn): here. Return certinfo stuff.
+
2002-07-26 Werner Koch <wk@gnupg.org>
* gpg-agent.c (main): New option --ignore-cache-for-signing.
diff --git a/agent/agent.h b/agent/agent.h
index 41654a46f..4446cf206 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -173,7 +173,9 @@ int divert_pkdecrypt (const unsigned char *cipher,
/*-- call-scd.c --*/
int agent_card_learn (void (*kpinfo_cb)(void*, const char *),
- void *kpinfo_cb_arg);
+ void *kpinfo_cb_arg,
+ void (*certinfo_cb)(void*, const char *),
+ void *certinfo_cb_arg);
int agent_card_serialno (char **r_serialno);
int agent_card_pksign (const char *keyid,
int (*getpin_cb)(void *, const char *, char*, size_t),
diff --git a/agent/call-scd.c b/agent/call-scd.c
index af8258a0f..a9123daca 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -55,6 +55,8 @@ static pth_mutex_t scd_lock = PTH_MUTEX_INIT;
struct learn_parm_s {
void (*kpinfo_cb)(void*, const char *);
void *kpinfo_cb_arg;
+ void (*certinfo_cb)(void*, const char *);
+ void *certinfo_cb_arg;
};
struct inq_needpin_s {
@@ -230,7 +232,11 @@ learn_status_cb (void *opaque, const char *line)
;
while (spacep (line))
line++;
- if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
+ if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
+ {
+ parm->certinfo_cb (parm->certinfo_cb_arg, line);
+ }
+ else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
{
parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
}
@@ -247,7 +253,10 @@ learn_status_cb (void *opaque, const char *line)
/* Perform the learn command and return a list of all private keys
stored on the card. */
int
-agent_card_learn (void (*kpinfo_cb)(void*, const char *), void *kpinfo_cb_arg)
+agent_card_learn (void (*kpinfo_cb)(void*, const char *),
+ void *kpinfo_cb_arg,
+ void (*certinfo_cb)(void*, const char *),
+ void *certinfo_cb_arg)
{
int rc;
struct learn_parm_s parm;
@@ -259,6 +268,8 @@ agent_card_learn (void (*kpinfo_cb)(void*, const char *), void *kpinfo_cb_arg)
memset (&parm, 0, sizeof parm);
parm.kpinfo_cb = kpinfo_cb;
parm.kpinfo_cb_arg = kpinfo_cb_arg;
+ parm.certinfo_cb = certinfo_cb;
+ parm.certinfo_cb_arg = certinfo_cb_arg;
rc = assuan_transact (scd_ctx, "LEARN --force",
NULL, NULL, NULL, NULL,
learn_status_cb, &parm);
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 54d04d23f..96c220bb8 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -43,13 +43,10 @@
#include "agent.h"
#include "../assuan/assuan.h" /* malloc hooks */
+#include "i18n.h"
#include "sysutils.h"
-#define N_(a) a
-#define _(a) a
-
-
enum cmd_and_opt_values
{ aNull = 0,
oCsh = 'c',
diff --git a/agent/learncard.c b/agent/learncard.c
index fe3e9eff3..93229f4cf 100644
--- a/agent/learncard.c
+++ b/agent/learncard.c
@@ -45,6 +45,20 @@ struct kpinfo_cb_parm_s {
};
+struct certinfo_s {
+ struct certinfo_s *next;
+ int type;
+ int done;
+ char id[1];
+};
+typedef struct certinfo_s *CERTINFO;
+
+struct certinfo_cb_parm_s {
+ int error;
+ CERTINFO info;
+};
+
+
static void
release_keypair_info (KEYPAIR_INFO info)
{
@@ -56,10 +70,21 @@ release_keypair_info (KEYPAIR_INFO info)
}
}
+static void
+release_certinfo (CERTINFO info)
+{
+ while (info)
+ {
+ CERTINFO tmp = info->next;
+ xfree (info);
+ info = tmp;
+ }
+}
+
/* This callback is used by agent_card_leanr and passed the content of
- all KEYPAIRINFO lines. It merely store this data away */
+ all KEYPAIRINFO lines. It merely stores this data away */
static void
kpinfo_cb (void *opaque, const char *line)
{
@@ -109,6 +134,45 @@ kpinfo_cb (void *opaque, const char *line)
}
+/* This callback is used by agent_card_leanr and passed the content of
+ all CERTINFO lines. It merely stores this data away */
+static void
+certinfo_cb (void *opaque, const char *line)
+{
+ struct certinfo_cb_parm_s *parm = opaque;
+ CERTINFO item;
+ int type;
+ char *p, *pend;
+
+ if (parm->error)
+ return; /* no need to gather data after an error coccured */
+
+ type = strtol (line, &p, 10);
+ while (spacep (p))
+ p++;
+ for (pend = p; *pend && !spacep (pend); pend++)
+ ;
+ if (p == pend || !*p)
+ {
+ parm->error = GNUPG_Invalid_Response;
+ return;
+ }
+ *pend = 0; /* ignore trailing stuff */
+
+ item = xtrycalloc (1, sizeof *item + strlen (p));
+ if (!item)
+ {
+ parm->error = GNUPG_Out_Of_Core;
+ return;
+ }
+ item->type = type;
+ strcpy (item->id, p);
+ /* store it */
+ item->next = parm->info;
+ parm->info = item;
+}
+
+
/* Create an S-expression with the shadow info. */
static unsigned char *
make_shadow_info (const char *serialno, const char *idstring)
@@ -136,6 +200,35 @@ make_shadow_info (const char *serialno, const char *idstring)
return info;
}
+static int
+send_cert_back (const char *id, void *assuan_context)
+{
+ int rc;
+ char *derbuf;
+ size_t derbuflen;
+
+ rc = agent_card_readcert (id, &derbuf, &derbuflen);
+ if (rc)
+ {
+ log_error ("error reading certificate: %s\n",
+ gnupg_strerror (rc));
+ return rc;
+ }
+
+ rc = assuan_send_data (assuan_context, derbuf, derbuflen);
+ xfree (derbuf);
+ if (!rc)
+ rc = assuan_send_data (assuan_context, NULL, 0);
+ if (!rc)
+ rc = assuan_write_line (assuan_context, "END");
+ if (rc)
+ {
+ log_error ("sending certificate failed: %s\n",
+ assuan_strerror (rc));
+ return map_assuan_err (rc);
+ }
+ return 0;
+}
/* Perform the learn operation. If ASSUAN_CONTEXT is not NULL all new
certificates are send via Assuan */
@@ -144,13 +237,22 @@ agent_handle_learn (void *assuan_context)
{
int rc;
struct kpinfo_cb_parm_s parm;
+ struct certinfo_cb_parm_s cparm;
char *serialno = NULL;
KEYPAIR_INFO item;
unsigned char grip[20];
char *p;
int i;
+ static int certtype_list[] = {
+ 101, /* trusted */
+ 102, /* useful */
+ 100, /* regular */
+ -1 /* end of list */
+ };
+
memset (&parm, 0, sizeof parm);
+ memset (&cparm, 0, sizeof cparm);
/* Check whether a card is present and get the serial number */
rc = agent_card_serialno (&serialno);
@@ -158,16 +260,40 @@ agent_handle_learn (void *assuan_context)
goto leave;
/* now gather all the availabe info */
- rc = agent_card_learn (kpinfo_cb, &parm);
- if (!rc && parm.error)
- rc = parm.error;
+ rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm);
+ if (!rc && (parm.error || cparm.error))
+ rc = parm.error? parm.error : cparm.error;
if (rc)
{
log_debug ("agent_card_learn failed: %s\n", gnupg_strerror (rc));
goto leave;
}
-
+
log_info ("card has S/N: %s\n", serialno);
+
+ /* Write out the certificates in a standard order. */
+ for (i=0; certtype_list[i] != -1; i++)
+ {
+ CERTINFO citem;
+ for (citem = cparm.info; citem; citem = citem->next)
+ {
+ if (certtype_list[i] != citem->type)
+ continue;
+
+ if (opt.verbose)
+ log_info (" id: %s (type=%d)\n",
+ citem->id, citem->type);
+
+ if (assuan_context)
+ {
+ rc = send_cert_back (citem->id, assuan_context);
+ if (rc)
+ goto leave;
+ citem->done = 1;
+ }
+ }
+ }
+
for (item = parm.info; item; item = item->next)
{
unsigned char *pubkey, *shdkey;
@@ -226,29 +352,19 @@ agent_handle_learn (void *assuan_context)
if (assuan_context)
{
- char *derbuf;
- size_t derbuflen;
-
- rc = agent_card_readcert (item->id, &derbuf, &derbuflen);
- if (rc)
+ CERTINFO citem;
+
+ /* only send the certificate if we have not done so before */
+ for (citem = cparm.info; citem; citem = citem->next)
{
- log_error ("error reading certificate: %s\n",
- gnupg_strerror (rc));
- goto leave;
+ if (!strcmp (citem->id, item->id))
+ break;
}
-
- rc = assuan_send_data (assuan_context, derbuf, derbuflen);
- xfree (derbuf);
- if (!rc)
- rc = assuan_send_data (assuan_context, NULL, 0);
- if (!rc)
- rc = assuan_write_line (assuan_context, "END");
- if (rc)
+ if (!citem)
{
- log_error ("sending certificate failed: %s\n",
- assuan_strerror (rc));
- rc = map_assuan_err (rc);
- goto leave;
+ rc = send_cert_back (item->id, assuan_context);
+ if (rc)
+ goto leave;
}
}
}
@@ -257,6 +373,7 @@ agent_handle_learn (void *assuan_context)
leave:
xfree (serialno);
release_keypair_info (parm.info);
+ release_certinfo (cparm.info);
return rc;
}
diff --git a/agent/protect-tool.c b/agent/protect-tool.c
index 25129d662..d9bbf8b4b 100644
--- a/agent/protect-tool.c
+++ b/agent/protect-tool.c
@@ -36,10 +36,7 @@
#include "agent.h"
#include "minip12.h"
#include "simple-pwquery.h"
-
-#define N_(a) a
-#define _(a) a
-
+#include "i18n.h"
enum cmd_and_opt_values
{ aNull = 0,