mirror of git://git.gnupg.org/gnupg.git
* 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.
This commit is contained in:
parent
346b6a32e2
commit
ca7ed726a7
|
@ -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>
|
2002-07-26 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* gpg-agent.c (main): New option --ignore-cache-for-signing.
|
* gpg-agent.c (main): New option --ignore-cache-for-signing.
|
||||||
|
|
|
@ -173,7 +173,9 @@ int divert_pkdecrypt (const unsigned char *cipher,
|
||||||
|
|
||||||
/*-- call-scd.c --*/
|
/*-- call-scd.c --*/
|
||||||
int agent_card_learn (void (*kpinfo_cb)(void*, const char *),
|
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_serialno (char **r_serialno);
|
||||||
int agent_card_pksign (const char *keyid,
|
int agent_card_pksign (const char *keyid,
|
||||||
int (*getpin_cb)(void *, const char *, char*, size_t),
|
int (*getpin_cb)(void *, const char *, char*, size_t),
|
||||||
|
|
|
@ -55,6 +55,8 @@ static pth_mutex_t scd_lock = PTH_MUTEX_INIT;
|
||||||
struct learn_parm_s {
|
struct learn_parm_s {
|
||||||
void (*kpinfo_cb)(void*, const char *);
|
void (*kpinfo_cb)(void*, const char *);
|
||||||
void *kpinfo_cb_arg;
|
void *kpinfo_cb_arg;
|
||||||
|
void (*certinfo_cb)(void*, const char *);
|
||||||
|
void *certinfo_cb_arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct inq_needpin_s {
|
struct inq_needpin_s {
|
||||||
|
@ -230,7 +232,11 @@ learn_status_cb (void *opaque, const char *line)
|
||||||
;
|
;
|
||||||
while (spacep (line))
|
while (spacep (line))
|
||||||
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);
|
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
|
/* Perform the learn command and return a list of all private keys
|
||||||
stored on the card. */
|
stored on the card. */
|
||||||
int
|
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;
|
int rc;
|
||||||
struct learn_parm_s parm;
|
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);
|
memset (&parm, 0, sizeof parm);
|
||||||
parm.kpinfo_cb = kpinfo_cb;
|
parm.kpinfo_cb = kpinfo_cb;
|
||||||
parm.kpinfo_cb_arg = kpinfo_cb_arg;
|
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",
|
rc = assuan_transact (scd_ctx, "LEARN --force",
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
learn_status_cb, &parm);
|
learn_status_cb, &parm);
|
||||||
|
|
|
@ -43,13 +43,10 @@
|
||||||
#include "agent.h"
|
#include "agent.h"
|
||||||
#include "../assuan/assuan.h" /* malloc hooks */
|
#include "../assuan/assuan.h" /* malloc hooks */
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
#include "sysutils.h"
|
#include "sysutils.h"
|
||||||
|
|
||||||
|
|
||||||
#define N_(a) a
|
|
||||||
#define _(a) a
|
|
||||||
|
|
||||||
|
|
||||||
enum cmd_and_opt_values
|
enum cmd_and_opt_values
|
||||||
{ aNull = 0,
|
{ aNull = 0,
|
||||||
oCsh = 'c',
|
oCsh = '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
|
static void
|
||||||
release_keypair_info (KEYPAIR_INFO info)
|
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
|
/* 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
|
static void
|
||||||
kpinfo_cb (void *opaque, const char *line)
|
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. */
|
/* Create an S-expression with the shadow info. */
|
||||||
static unsigned char *
|
static unsigned char *
|
||||||
make_shadow_info (const char *serialno, const char *idstring)
|
make_shadow_info (const char *serialno, const char *idstring)
|
||||||
|
@ -136,6 +200,35 @@ make_shadow_info (const char *serialno, const char *idstring)
|
||||||
return info;
|
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
|
/* Perform the learn operation. If ASSUAN_CONTEXT is not NULL all new
|
||||||
certificates are send via Assuan */
|
certificates are send via Assuan */
|
||||||
|
@ -144,13 +237,22 @@ agent_handle_learn (void *assuan_context)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct kpinfo_cb_parm_s parm;
|
struct kpinfo_cb_parm_s parm;
|
||||||
|
struct certinfo_cb_parm_s cparm;
|
||||||
char *serialno = NULL;
|
char *serialno = NULL;
|
||||||
KEYPAIR_INFO item;
|
KEYPAIR_INFO item;
|
||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
static int certtype_list[] = {
|
||||||
|
101, /* trusted */
|
||||||
|
102, /* useful */
|
||||||
|
100, /* regular */
|
||||||
|
-1 /* end of list */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
memset (&parm, 0, sizeof parm);
|
memset (&parm, 0, sizeof parm);
|
||||||
|
memset (&cparm, 0, sizeof cparm);
|
||||||
|
|
||||||
/* Check whether a card is present and get the serial number */
|
/* Check whether a card is present and get the serial number */
|
||||||
rc = agent_card_serialno (&serialno);
|
rc = agent_card_serialno (&serialno);
|
||||||
|
@ -158,16 +260,40 @@ agent_handle_learn (void *assuan_context)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
/* now gather all the availabe info */
|
/* now gather all the availabe info */
|
||||||
rc = agent_card_learn (kpinfo_cb, &parm);
|
rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm);
|
||||||
if (!rc && parm.error)
|
if (!rc && (parm.error || cparm.error))
|
||||||
rc = parm.error;
|
rc = parm.error? parm.error : cparm.error;
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_debug ("agent_card_learn failed: %s\n", gnupg_strerror (rc));
|
log_debug ("agent_card_learn failed: %s\n", gnupg_strerror (rc));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info ("card has S/N: %s\n", serialno);
|
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)
|
for (item = parm.info; item; item = item->next)
|
||||||
{
|
{
|
||||||
unsigned char *pubkey, *shdkey;
|
unsigned char *pubkey, *shdkey;
|
||||||
|
@ -226,29 +352,19 @@ agent_handle_learn (void *assuan_context)
|
||||||
|
|
||||||
if (assuan_context)
|
if (assuan_context)
|
||||||
{
|
{
|
||||||
char *derbuf;
|
CERTINFO citem;
|
||||||
size_t derbuflen;
|
|
||||||
|
/* only send the certificate if we have not done so before */
|
||||||
rc = agent_card_readcert (item->id, &derbuf, &derbuflen);
|
for (citem = cparm.info; citem; citem = citem->next)
|
||||||
if (rc)
|
|
||||||
{
|
{
|
||||||
log_error ("error reading certificate: %s\n",
|
if (!strcmp (citem->id, item->id))
|
||||||
gnupg_strerror (rc));
|
break;
|
||||||
goto leave;
|
|
||||||
}
|
}
|
||||||
|
if (!citem)
|
||||||
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",
|
rc = send_cert_back (item->id, assuan_context);
|
||||||
assuan_strerror (rc));
|
if (rc)
|
||||||
rc = map_assuan_err (rc);
|
goto leave;
|
||||||
goto leave;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,6 +373,7 @@ agent_handle_learn (void *assuan_context)
|
||||||
leave:
|
leave:
|
||||||
xfree (serialno);
|
xfree (serialno);
|
||||||
release_keypair_info (parm.info);
|
release_keypair_info (parm.info);
|
||||||
|
release_certinfo (cparm.info);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,7 @@
|
||||||
#include "agent.h"
|
#include "agent.h"
|
||||||
#include "minip12.h"
|
#include "minip12.h"
|
||||||
#include "simple-pwquery.h"
|
#include "simple-pwquery.h"
|
||||||
|
#include "i18n.h"
|
||||||
#define N_(a) a
|
|
||||||
#define _(a) a
|
|
||||||
|
|
||||||
|
|
||||||
enum cmd_and_opt_values
|
enum cmd_and_opt_values
|
||||||
{ aNull = 0,
|
{ aNull = 0,
|
||||||
|
|
Loading…
Reference in New Issue