Key generation and signing using the OpenPGP card does rudimentary work.

This commit is contained in:
Werner Koch 2003-06-27 20:53:09 +00:00
parent ed0d33f1d0
commit f5db59fc21
50 changed files with 1535 additions and 449 deletions

View File

@ -1,3 +1,30 @@
2003-06-26 Werner Koch <wk@gnupg.org>
* call-scd.c (agent_card_serialno): Don't do a RESET anymore.
2003-06-25 Werner Koch <wk@gnupg.org>
* command.c (cmd_scd): New.
* call-scd.c (agent_card_scd): New.
* divert-scd.c (divert_generic_cmd): New
* call-scd.c (agent_card_learn): New callback args SINFO.
(learn_status_cb): Pass all other status lines to the sinfo
callback.
* learncard.c (release_sinfo, sinfo_cb): New.
(agent_handle_learn): Pass the new cb to the learn function and
pass the collected information back to the client's assuan
connection.
* gpg-agent.c (main): Moved pth_init before gcry_check_version.
2003-06-24 Werner Koch <wk@gnupg.org>
* gpg-agent.c (handle_connections): Adjusted for Pth 2.0
Adjusted for changes in the libgcrypt API. Some more fixes for the
libgpg-error stuff.
2003-06-04 Werner Koch <wk@gnupg.org> 2003-06-04 Werner Koch <wk@gnupg.org>
Renamed error codes from INVALID to INV and removed _ERROR suffixes. Renamed error codes from INVALID to INV and removed _ERROR suffixes.

View File

@ -1,5 +1,5 @@
/* agent.h - Global definitions for the agent /* agent.h - Global definitions for the agent
* Copyright (C) 2001, 2002 Free Software Foundation, Inc. * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -130,8 +130,9 @@ void start_command_handler (int, int);
/*-- findkey.c --*/ /*-- findkey.c --*/
int agent_write_private_key (const unsigned char *grip, int agent_write_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force); const void *buffer, size_t length, int force);
GCRY_SEXP agent_key_from_file (CTRL ctrl, const unsigned char *grip, gcry_sexp_t agent_key_from_file (CTRL ctrl, const unsigned char *grip,
unsigned char **shadow_info, int ignore_cache); unsigned char **shadow_info,
int ignore_cache);
int agent_key_available (const unsigned char *grip); int agent_key_available (const unsigned char *grip);
/*-- query.c --*/ /*-- query.c --*/
@ -160,7 +161,7 @@ int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
/*-- genkey.c --*/ /*-- genkey.c --*/
int agent_genkey (CTRL ctrl, int agent_genkey (CTRL ctrl,
const char *keyparam, size_t keyparmlen, FILE *outfp); const char *keyparam, size_t keyparmlen, FILE *outfp);
int agent_protect_and_store (CTRL ctrl, GCRY_SEXP s_skey); int agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey);
/*-- protect.c --*/ /*-- protect.c --*/
int agent_protect (const unsigned char *plainkey, const char *passphrase, int agent_protect (const unsigned char *plainkey, const char *passphrase,
@ -189,12 +190,17 @@ int divert_pkdecrypt (CTRL ctrl,
const unsigned char *cipher, const unsigned char *cipher,
const unsigned char *shadow_info, const unsigned char *shadow_info,
char **r_buf, size_t *r_len); char **r_buf, size_t *r_len);
int divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context);
/*-- 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)(void*, const char *),
void *certinfo_cb_arg); void *certinfo_cb_arg,
void (*sinfo_cb)(void*, const char *,
size_t, const char *),
void *sinfo_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),
@ -208,6 +214,9 @@ int agent_card_pkdecrypt (const char *keyid,
char **r_buf, size_t *r_buflen); char **r_buf, size_t *r_buflen);
int agent_card_readcert (const char *id, char **r_buf, size_t *r_buflen); int agent_card_readcert (const char *id, char **r_buf, size_t *r_buflen);
int agent_card_readkey (const char *id, unsigned char **r_buf); int agent_card_readkey (const char *id, unsigned char **r_buf);
int agent_card_scd (const char *cmdline,
int (*getpin_cb)(void *, const char *, char*, size_t),
void *getpin_cb_arg, void *assuan_context);
/*-- learncard.c --*/ /*-- learncard.c --*/

View File

@ -57,6 +57,8 @@ struct learn_parm_s {
void *kpinfo_cb_arg; void *kpinfo_cb_arg;
void (*certinfo_cb)(void*, const char *); void (*certinfo_cb)(void*, const char *);
void *certinfo_cb_arg; void *certinfo_cb_arg;
void (*sinfo_cb)(void*, const char *, size_t, const char *);
void *sinfo_cb_arg;
}; };
struct inq_needpin_s { struct inq_needpin_s {
@ -245,8 +247,10 @@ learn_status_cb (void *opaque, const char *line)
{ {
log_debug ("learn_status_cb: serialno `%s'\n", line); log_debug ("learn_status_cb: serialno `%s'\n", line);
} }
else else if (keywordlen && *line)
log_debug ("learn_status_cb: ignoring `%.*s'\n", keywordlen, keyword); {
parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
}
return 0; return 0;
} }
@ -257,7 +261,9 @@ int
agent_card_learn (void (*kpinfo_cb)(void*, const char *), 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)(void*, const char *),
void *certinfo_cb_arg) void *certinfo_cb_arg,
void (*sinfo_cb)(void*, const char *, size_t, const char *),
void *sinfo_cb_arg)
{ {
int rc; int rc;
struct learn_parm_s parm; struct learn_parm_s parm;
@ -271,6 +277,8 @@ agent_card_learn (void (*kpinfo_cb)(void*, const char *),
parm.kpinfo_cb_arg = kpinfo_cb_arg; parm.kpinfo_cb_arg = kpinfo_cb_arg;
parm.certinfo_cb = certinfo_cb; parm.certinfo_cb = certinfo_cb;
parm.certinfo_cb_arg = certinfo_cb_arg; parm.certinfo_cb_arg = certinfo_cb_arg;
parm.sinfo_cb = sinfo_cb;
parm.sinfo_cb_arg = sinfo_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);
@ -329,9 +337,9 @@ agent_card_serialno (char **r_serialno)
we can do this if we for some reason figure out that the we can do this if we for some reason figure out that the
operation might have failed due to a missing RESET. Hmmm, I feel operation might have failed due to a missing RESET. Hmmm, I feel
this is really SCdaemon's duty */ this is really SCdaemon's duty */
rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); /* rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); */
if (rc) /* if (rc) */
return unlock_scd (map_assuan_err (rc)); /* return unlock_scd (map_assuan_err (rc)); */
rc = assuan_transact (scd_ctx, "SERIALNO", rc = assuan_transact (scd_ctx, "SERIALNO",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@ -592,3 +600,66 @@ agent_card_readkey (const char *id, unsigned char **r_buf)
static AssuanError
pass_status_thru (void *opaque, const char *line)
{
ASSUAN_CONTEXT ctx = opaque;
char keyword[200];
int i;
for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
keyword[i] = *line;
keyword[i] = 0;
/* truncate any remaining keyword stuff. */
for (; *line && !spacep (line); line++)
;
while (spacep (line))
line++;
assuan_write_status (ctx, keyword, line);
return 0;
}
static AssuanError
pass_data_thru (void *opaque, const void *buffer, size_t length)
{
ASSUAN_CONTEXT ctx = opaque;
assuan_send_data (ctx, buffer, length);
return 0;
}
/* Send the line CMDLINE with command for the SCDdaemon to it and send
all status messages back. This command is used as a general quoting
mechanism to pass everything verbatim to SCDAEMOPN. The PIN
inquirey is handled inside gpg-agent. */
int
agent_card_scd (const char *cmdline,
int (*getpin_cb)(void *, const char *, char*, size_t),
void *getpin_cb_arg, void *assuan_context)
{
int rc;
struct inq_needpin_s inqparm;
rc = start_scd ();
if (rc)
return rc;
inqparm.ctx = scd_ctx;
inqparm.getpin_cb = getpin_cb;
inqparm.getpin_cb_arg = getpin_cb_arg;
rc = assuan_transact (scd_ctx, cmdline,
pass_data_thru, assuan_context,
inq_needpin, &inqparm,
pass_status_thru, assuan_context);
if (rc)
{
return unlock_scd (map_assuan_err (rc));
}
return unlock_scd (0);
}

View File

@ -549,7 +549,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
CTRL ctrl = assuan_get_pointer (ctx); CTRL ctrl = assuan_get_pointer (ctx);
int rc; int rc;
unsigned char grip[20]; unsigned char grip[20];
GCRY_SEXP s_skey = NULL; gcry_sexp_t s_skey = NULL;
unsigned char *shadow_info = NULL; unsigned char *shadow_info = NULL;
rc = parse_keygrip (ctx, line, grip); rc = parse_keygrip (ctx, line, grip);
@ -575,6 +575,22 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
return map_to_assuan_status (rc); return map_to_assuan_status (rc);
} }
/* SCD <commands to pass to the scdaemon>
This is a general quote command to redirect everything to the
SCDAEMON. */
static int
cmd_scd (ASSUAN_CONTEXT ctx, char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
int rc;
rc = divert_generic_cmd (ctrl, line, ctx);
return map_to_assuan_status (rc);
}
static int static int
@ -661,6 +677,7 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "PASSWD", cmd_passwd }, { "PASSWD", cmd_passwd },
{ "INPUT", NULL }, { "INPUT", NULL },
{ "OUTPUT", NULL }, { "OUTPUT", NULL },
{ "SCD", cmd_scd },
{ NULL } { NULL }
}; };
int i, rc; int i, rc;

View File

@ -1,5 +1,5 @@
/* divert-scd.c - divert operations to the scdaemon /* divert-scd.c - divert operations to the scdaemon
* Copyright (C) 2002 Free Software Foundation, Inc. * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -103,7 +103,7 @@ ask_for_card (CTRL ctrl, const unsigned char *shadow_info, char **r_kid)
} }
else else
{ {
log_error ("error accesing card: %s\n", gnupg_strerror (rc)); log_error ("error accesing card: %s\n", gpg_strerror (rc));
} }
if (!rc) if (!rc)
@ -305,3 +305,15 @@ divert_pkdecrypt (CTRL ctrl,
xfree (kid); xfree (kid);
return rc; return rc;
} }
int
divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context)
{
return agent_card_scd (cmdline, getpin_cb, ctrl, assuan_context);
}

View File

@ -1,5 +1,5 @@
/* findkey.c - locate the secret key /* findkey.c - locate the secret key
* Copyright (C) 2001,02 Free Software Foundation, Inc. * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -204,7 +204,7 @@ unprotect (CTRL ctrl,
an allocated S-Expression with the shadow_info part from the file. an allocated S-Expression with the shadow_info part from the file.
With IGNORE_CACHE passed as true the passphrase is not taken from With IGNORE_CACHE passed as true the passphrase is not taken from
the cache.*/ the cache.*/
GCRY_SEXP gcry_sexp_t
agent_key_from_file (CTRL ctrl, agent_key_from_file (CTRL ctrl,
const unsigned char *grip, unsigned char **shadow_info, const unsigned char *grip, unsigned char **shadow_info,
int ignore_cache) int ignore_cache)
@ -215,7 +215,7 @@ agent_key_from_file (CTRL ctrl,
struct stat st; struct stat st;
unsigned char *buf; unsigned char *buf;
size_t len, buflen, erroff; size_t len, buflen, erroff;
GCRY_SEXP s_skey; gcry_sexp_t s_skey;
char hexgrip[40+4+1]; char hexgrip[40+4+1];
if (shadow_info) if (shadow_info)
@ -260,7 +260,7 @@ agent_key_from_file (CTRL ctrl,
if (rc) if (rc)
{ {
log_error ("failed to build S-Exp (off=%u): %s\n", log_error ("failed to build S-Exp (off=%u): %s\n",
(unsigned int)erroff, gcry_strerror (rc)); (unsigned int)erroff, gpg_strerror (rc));
return NULL; return NULL;
} }
len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
@ -283,7 +283,7 @@ agent_key_from_file (CTRL ctrl,
rc = unprotect (ctrl, &buf, grip, ignore_cache); rc = unprotect (ctrl, &buf, grip, ignore_cache);
if (rc) if (rc)
log_error ("failed to unprotect the secret key: %s\n", log_error ("failed to unprotect the secret key: %s\n",
gnupg_strerror (rc)); gpg_strerror (rc));
break; break;
case PRIVATE_KEY_SHADOWED: case PRIVATE_KEY_SHADOWED:
if (shadow_info) if (shadow_info)
@ -329,7 +329,7 @@ agent_key_from_file (CTRL ctrl,
if (rc) if (rc)
{ {
log_error ("failed to build S-Exp (off=%u): %s\n", log_error ("failed to build S-Exp (off=%u): %s\n",
(unsigned int)erroff, gcry_strerror (rc)); (unsigned int)erroff, gpg_strerror (rc));
return NULL; return NULL;
} }

View File

@ -1,5 +1,5 @@
/* pksign.c - Generate a keypair /* pksign.c - Generate a keypair
* Copyright (C) 2002 Free Software Foundation, Inc. * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -30,7 +30,7 @@
#include "i18n.h" #include "i18n.h"
static int static int
store_key (GCRY_SEXP private, const char *passphrase, int force) store_key (gcry_sexp_t private, const char *passphrase, int force)
{ {
int rc; int rc;
char *buf; char *buf;
@ -91,7 +91,7 @@ int
agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen, agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
FILE *outfp) FILE *outfp)
{ {
GCRY_SEXP s_keyparam, s_key, s_private, s_public; gcry_sexp_t s_keyparam, s_key, s_private, s_public;
struct pin_entry_info_s *pi, *pi2; struct pin_entry_info_s *pi, *pi2;
int rc; int rc;
size_t len; size_t len;
@ -100,7 +100,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen); rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
if (rc) if (rc)
{ {
log_error ("failed to convert keyparam: %s\n", gcry_strerror (rc)); log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc));
return gpg_error (GPG_ERR_INV_DATA); return gpg_error (GPG_ERR_INV_DATA);
} }
@ -135,7 +135,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
gcry_sexp_release (s_keyparam); gcry_sexp_release (s_keyparam);
if (rc) if (rc)
{ {
log_error ("key generation failed: %s\n", gcry_strerror (rc)); log_error ("key generation failed: %s\n", gpg_strerror (rc));
xfree (pi); xfree (pi);
return map_gcry_err (rc); return map_gcry_err (rc);
} }
@ -204,7 +204,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
/* Apply a new passpahrse to the key S_SKEY and store it. */ /* Apply a new passpahrse to the key S_SKEY and store it. */
int int
agent_protect_and_store (CTRL ctrl, GCRY_SEXP s_skey) agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey)
{ {
struct pin_entry_info_s *pi, *pi2; struct pin_entry_info_s *pi, *pi2;
int rc; int rc;

View File

@ -1,5 +1,5 @@
/* gpg-agent.c - The GnuPG Agent /* gpg-agent.c - The GnuPG Agent
* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -37,11 +37,9 @@
# include <pth.h> # include <pth.h>
#endif #endif
#include <gcrypt.h>
#define JNLIB_NEED_LOG_LOGV #define JNLIB_NEED_LOG_LOGV
#include "agent.h" #include "agent.h"
#include "../assuan/assuan.h" /* malloc hooks */ #include <assuan.h> /* malloc hooks */
#include "i18n.h" #include "i18n.h"
#include "sysutils.h" #include "sysutils.h"
@ -336,6 +334,18 @@ main (int argc, char **argv )
log_set_prefix ("gpg-agent", 1|4); log_set_prefix ("gpg-agent", 1|4);
i18n_init (); i18n_init ();
/* We need to initialize Pth before libgcrypt, because the libgcrypt
initialization done by gcry_check_version internally sets up its
mutex system. Note that one must not link against pth if
USE_GNU_PTH is not defined. */
#ifdef USE_GNU_PTH
if (!pth_init ())
{
log_error ("failed to initialize the Pth library\n");
exit (1);
}
#endif /*USE_GNU_PTH*/
/* check that the libraries are suitable. Do it here because /* check that the libraries are suitable. Do it here because
the option parsing may need services of the library */ the option parsing may need services of the library */
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
@ -715,12 +725,6 @@ main (int argc, char **argv )
{ {
struct sigaction sa; struct sigaction sa;
if (!pth_init ())
{
log_error ("failed to initialize the Pth library\n");
exit (1);
}
sa.sa_handler = SIG_IGN; sa.sa_handler = SIG_IGN;
sigemptyset (&sa.sa_mask); sigemptyset (&sa.sa_mask);
sa.sa_flags = 0; sa.sa_flags = 0;
@ -1030,7 +1034,7 @@ handle_connections (int listen_fd)
fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev); fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
if (fd == -1) if (fd == -1)
{ {
if (pth_event_occurred (ev)) if (pth_event_status (ev) == PTH_STATUS_OCCURRED)
{ {
handle_signal (signo); handle_signal (signo);
continue; continue;

View File

@ -1,5 +1,5 @@
/* learncard.c - Handle the LEARN command /* learncard.c - Handle the LEARN command
* Copyright (C) 2002 Free Software Foundation, Inc. * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -59,6 +59,20 @@ struct certinfo_cb_parm_s {
}; };
struct sinfo_s {
struct sinfo_s *next;
char *data; /* Points into keyword. */
char keyword[1];
};
typedef struct sinfo_s *SINFO;
struct sinfo_cb_parm_s {
int error;;
SINFO info;
};
static void static void
release_keypair_info (KEYPAIR_INFO info) release_keypair_info (KEYPAIR_INFO info)
{ {
@ -81,9 +95,20 @@ release_certinfo (CERTINFO info)
} }
} }
static void
release_sinfo (SINFO info)
{
while (info)
{
SINFO 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_learn and passed the content of
all KEYPAIRINFO lines. It merely stores 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)
@ -134,7 +159,7 @@ kpinfo_cb (void *opaque, const char *line)
} }
/* This callback is used by agent_card_leanr and passed the content of /* This callback is used by agent_card_learn and passed the content of
all CERTINFO lines. It merely stores this data away */ all CERTINFO lines. It merely stores this data away */
static void static void
certinfo_cb (void *opaque, const char *line) certinfo_cb (void *opaque, const char *line)
@ -173,6 +198,35 @@ certinfo_cb (void *opaque, const char *line)
} }
/* This callback is used by agent_card_learn and passed the content of
all SINFO lines. It merely stores this data away */
static void
sinfo_cb (void *opaque, const char *keyword, size_t keywordlen,
const char *data)
{
struct sinfo_cb_parm_s *sparm = opaque;
SINFO item;
if (sparm->error)
return; /* no need to gather data after an error coccured */
item = xtrycalloc (1, sizeof *item + keywordlen + 1 + strlen (data));
if (!item)
{
sparm->error = out_of_core ();
return;
}
memcpy (item->keyword, keyword, keywordlen);
item->data = item->keyword + keywordlen;
*item->data = 0;
item->data++;
strcpy (item->data, data);
/* store it */
item->next = sparm->info;
sparm->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)
@ -211,7 +265,7 @@ send_cert_back (const char *id, void *assuan_context)
if (rc) if (rc)
{ {
log_error ("error reading certificate: %s\n", log_error ("error reading certificate: %s\n",
gnupg_strerror (rc)); gpg_strerror (rc));
return rc; return rc;
} }
@ -238,8 +292,10 @@ 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; struct certinfo_cb_parm_s cparm;
struct sinfo_cb_parm_s sparm;
char *serialno = NULL; char *serialno = NULL;
KEYPAIR_INFO item; KEYPAIR_INFO item;
SINFO sitem;
unsigned char grip[20]; unsigned char grip[20];
char *p; char *p;
int i; int i;
@ -253,24 +309,35 @@ agent_handle_learn (void *assuan_context)
memset (&parm, 0, sizeof parm); memset (&parm, 0, sizeof parm);
memset (&cparm, 0, sizeof cparm); memset (&cparm, 0, sizeof cparm);
memset (&sparm, 0, sizeof sparm);
/* 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);
if (rc) if (rc)
goto leave; goto leave;
/* now gather all the availabe info */ /* now gather all the available info */
rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm); rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm,
if (!rc && (parm.error || cparm.error)) sinfo_cb, &sparm);
rc = parm.error? parm.error : cparm.error; if (!rc && (parm.error || cparm.error || sparm.error))
rc = parm.error? parm.error : cparm.error? cparm.error : sparm.error;
if (rc) if (rc)
{ {
log_debug ("agent_card_learn failed: %s\n", gnupg_strerror (rc)); log_debug ("agent_card_learn failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
log_info ("card has S/N: %s\n", serialno); log_info ("card has S/N: %s\n", serialno);
/* Pass on all the collected status information. */
if (assuan_context)
{
for (sitem = sparm.info; sitem; sitem = sitem->next)
{
assuan_write_status (assuan_context, sitem->keyword, sitem->data);
}
}
/* Write out the certificates in a standard order. */ /* Write out the certificates in a standard order. */
for (i=0; certtype_list[i] != -1; i++) for (i=0; certtype_list[i] != -1; i++)
{ {
@ -315,7 +382,7 @@ agent_handle_learn (void *assuan_context)
rc = agent_card_readkey (item->id, &pubkey); rc = agent_card_readkey (item->id, &pubkey);
if (rc) if (rc)
{ {
log_debug ("agent_card_readkey failed: %s\n", gnupg_strerror (rc)); log_debug ("agent_card_readkey failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -333,7 +400,7 @@ agent_handle_learn (void *assuan_context)
xfree (pubkey); xfree (pubkey);
if (rc) if (rc)
{ {
log_error ("shadowing the key failed: %s\n", gnupg_strerror (rc)); log_error ("shadowing the key failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
@ -343,7 +410,7 @@ agent_handle_learn (void *assuan_context)
xfree (shdkey); xfree (shdkey);
if (rc) if (rc)
{ {
log_error ("error writing key: %s\n", gnupg_strerror (rc)); log_error ("error writing key: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -374,6 +441,7 @@ agent_handle_learn (void *assuan_context)
xfree (serialno); xfree (serialno);
release_keypair_info (parm.info); release_keypair_info (parm.info);
release_certinfo (cparm.info); release_certinfo (cparm.info);
release_sinfo (sparm.info);
return rc; return rc;
} }

View File

@ -1,5 +1,5 @@
/* minip12.c - A minilam pkcs-12 implementation. /* minip12.c - A minimal pkcs-12 implementation.
* Copyright (C) 2002 Free Software Foundation, Inc. * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -211,8 +211,8 @@ string_to_key (int id, char *salt, int iter, const char *pw,
int req_keylen, unsigned char *keybuf) int req_keylen, unsigned char *keybuf)
{ {
int rc, i, j; int rc, i, j;
GcryMDHd md; gcry_md_hd_t md;
GcryMPI num_b1 = NULL; gcry_mpi_t num_b1 = NULL;
int pwlen; int pwlen;
unsigned char hash[20], buf_b[64], buf_i[128], *p; unsigned char hash[20], buf_b[64], buf_i[128], *p;
size_t cur_keylen; size_t cur_keylen;
@ -240,11 +240,11 @@ string_to_key (int id, char *salt, int iter, const char *pw,
for (;;) for (;;)
{ {
md = gcry_md_open (GCRY_MD_SHA1, 0); rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
if (!md) if (rc)
{ {
log_error ( "gcry_md_open failed: %s\n", gcry_strerror (-1)); log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
return -1; return rc;
} }
for(i=0; i < 64; i++) for(i=0; i < 64; i++)
gcry_md_putc (md, id); gcry_md_putc (md, id);
@ -269,20 +269,20 @@ string_to_key (int id, char *salt, int iter, const char *pw,
rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, &n); rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, &n);
if (rc) if (rc)
{ {
log_error ( "gcry_mpi_scan failed: %s\n", gcry_strerror (rc)); log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
return -1; return -1;
} }
gcry_mpi_add_ui (num_b1, num_b1, 1); gcry_mpi_add_ui (num_b1, num_b1, 1);
for (i=0; i < 128; i += 64) for (i=0; i < 128; i += 64)
{ {
GcryMPI num_ij; gcry_mpi_t num_ij;
n = 64; n = 64;
rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, &n); rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, &n);
if (rc) if (rc)
{ {
log_error ( "gcry_mpi_scan failed: %s\n", log_error ( "gcry_mpi_scan failed: %s\n",
gcry_strerror (rc)); gpg_strerror (rc));
return -1; return -1;
} }
gcry_mpi_add (num_ij, num_ij, num_b1); gcry_mpi_add (num_ij, num_ij, num_b1);
@ -292,7 +292,7 @@ string_to_key (int id, char *salt, int iter, const char *pw,
if (rc) if (rc)
{ {
log_error ( "gcry_mpi_print failed: %s\n", log_error ( "gcry_mpi_print failed: %s\n",
gcry_strerror (rc)); gpg_strerror (rc));
return -1; return -1;
} }
gcry_mpi_release (num_ij); gcry_mpi_release (num_ij);
@ -302,7 +302,7 @@ string_to_key (int id, char *salt, int iter, const char *pw,
static int static int
set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw) set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw)
{ {
unsigned char keybuf[24]; unsigned char keybuf[24];
int rc; int rc;
@ -312,7 +312,7 @@ set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw)
rc = gcry_cipher_setkey (chd, keybuf, 24); rc = gcry_cipher_setkey (chd, keybuf, 24);
if (rc) if (rc)
{ {
log_error ( "gcry_cipher_setkey failed: %s\n", gcry_strerror (rc)); log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
return -1; return -1;
} }
@ -321,7 +321,7 @@ set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw)
rc = gcry_cipher_setiv (chd, keybuf, 8); rc = gcry_cipher_setiv (chd, keybuf, 8);
if (rc) if (rc)
{ {
log_error ("gcry_cipher_setiv failed: %s\n", gcry_strerror (rc)); log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
return -1; return -1;
} }
return 0; return 0;
@ -332,13 +332,13 @@ static void
crypt_block (unsigned char *buffer, size_t length, char *salt, int iter, crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
const char *pw, int encrypt) const char *pw, int encrypt)
{ {
GcryCipherHd chd; gcry_cipher_hd_t chd;
int rc; int rc;
chd = gcry_cipher_open (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0); rc = gcry_cipher_open (&chd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
if (!chd) if (rc)
{ {
log_error ( "gcry_cipher_open failed: %s\n", gcry_strerror(-1)); log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(-1));
return; return;
} }
if (set_key_iv (chd, salt, iter, pw)) if (set_key_iv (chd, salt, iter, pw))
@ -349,7 +349,7 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
if (rc) if (rc)
{ {
log_error ( "en/de-crytion failed: %s\n", gcry_strerror (rc)); log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -414,7 +414,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
return -1; return -1;
} }
static GcryMPI * static gcry_mpi_t *
parse_bag_data (const unsigned char *buffer, size_t length, int startoffset, parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
const char *pw) const char *pw)
{ {
@ -427,7 +427,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
unsigned int iter; unsigned int iter;
int len; int len;
unsigned char *plain = NULL; unsigned char *plain = NULL;
GcryMPI *result = NULL; gcry_mpi_t *result = NULL;
int result_count, i; int result_count, i;
where = "start"; where = "start";
@ -593,7 +593,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
if (rc) if (rc)
{ {
log_error ("error parsing key parameter: %s\n", log_error ("error parsing key parameter: %s\n",
gcry_strerror (rc)); gpg_strerror (rc));
goto bailout; goto bailout;
} }
result_count++; result_count++;
@ -625,7 +625,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
that it is only able to look for 3DES encoded enctyptedData and that it is only able to look for 3DES encoded enctyptedData and
tries to extract the first private key object it finds. In case of tries to extract the first private key object it finds. In case of
an error NULL is returned. */ an error NULL is returned. */
GcryMPI * gcry_mpi_t *
p12_parse (const unsigned char *buffer, size_t length, const char *pw) p12_parse (const unsigned char *buffer, size_t length, const char *pw)
{ {
struct tag_info ti; struct tag_info ti;
@ -859,7 +859,7 @@ create_final (struct buffer_s *sequences, size_t *r_length)
PW. Create a PKCS structure from it and return it as well as the PW. Create a PKCS structure from it and return it as well as the
length in R_LENGTH; return NULL in case of an error. */ length in R_LENGTH; return NULL in case of an error. */
unsigned char * unsigned char *
p12_build (GcryMPI *kparms, const char *pw, size_t *r_length) p12_build (gcry_mpi_t *kparms, const char *pw, size_t *r_length)
{ {
int rc, i; int rc, i;
size_t needed, n; size_t needed, n;
@ -877,7 +877,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, &n, kparms[i]); rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, &n, kparms[i]);
if (rc) if (rc)
{ {
log_error ("error formatting parameter: %s\n", gcry_strerror (rc)); log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
return NULL; return NULL;
} }
needed += n; needed += n;
@ -951,7 +951,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
if (rc) if (rc)
{ {
log_error ("oops: error formatting parameter: %s\n", log_error ("oops: error formatting parameter: %s\n",
gcry_strerror (rc)); gpg_strerror (rc));
gcry_free (plain); gcry_free (plain);
return NULL; return NULL;
} }
@ -962,7 +962,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
if (rc) if (rc)
{ {
log_error ("oops: error storing parameter: %s\n", log_error ("oops: error storing parameter: %s\n",
gcry_strerror (rc)); gpg_strerror (rc));
gcry_free (plain); gcry_free (plain);
return NULL; return NULL;
} }
@ -1131,7 +1131,7 @@ main (int argc, char **argv)
NULL, result[i]); NULL, result[i]);
if (rc) if (rc)
printf ("%d: [error printing number: %s]\n", printf ("%d: [error printing number: %s]\n",
i, gcry_strerror (rc)); i, gpg_strerror (rc));
else else
{ {
printf ("%d: %s\n", i, buf); printf ("%d: %s\n", i, buf);

View File

@ -1,5 +1,5 @@
/* minip12.h - Global definitions for the minimal pkcs-12 implementation. /* minip12.h - Global definitions for the minimal pkcs-12 implementation.
* Copyright (C) 2002 Free Software Foundation, Inc. * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -23,10 +23,11 @@
#include <gcrypt.h> #include <gcrypt.h>
GcryMPI *p12_parse (const unsigned char *buffer, size_t length, gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length,
const char *pw); const char *pw);
unsigned char *p12_build (GcryMPI *kparms, const char *pw, size_t *r_length); unsigned char *p12_build (gcry_mpi_t *kparms, const char *pw,
size_t *r_length);
#endif /*MINIP12_H*/ #endif /*MINIP12_H*/

View File

@ -1,5 +1,5 @@
/* pkdecrypt.c - public key decryption (well, acually using a secret key) /* pkdecrypt.c - public key decryption (well, acually using a secret key)
* Copyright (C) 2001 Free Software Foundation, Inc. * Copyright (C) 2001, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -38,7 +38,7 @@ int
agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
FILE *outfp) FILE *outfp)
{ {
GCRY_SEXP s_skey = NULL, s_cipher = NULL, s_plain = NULL; gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL;
unsigned char *shadow_info = NULL; unsigned char *shadow_info = NULL;
int rc; int rc;
char *buf = NULL; char *buf = NULL;
@ -54,7 +54,7 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
rc = gcry_sexp_sscan (&s_cipher, NULL, ciphertext, ciphertextlen); rc = gcry_sexp_sscan (&s_cipher, NULL, ciphertext, ciphertextlen);
if (rc) if (rc)
{ {
log_error ("failed to convert ciphertext: %s\n", gcry_strerror (rc)); log_error ("failed to convert ciphertext: %s\n", gpg_strerror (rc));
rc = gpg_error (GPG_ERR_INV_DATA); rc = gpg_error (GPG_ERR_INV_DATA);
goto leave; goto leave;
} }
@ -84,7 +84,7 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, &buf, &len ); rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, &buf, &len );
if (rc) if (rc)
{ {
log_error ("smartcard decryption failed: %s\n", gnupg_strerror (rc)); log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
/* FIXME: don't use buffering and change the protocol to return /* FIXME: don't use buffering and change the protocol to return
@ -104,7 +104,7 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
rc = gcry_pk_decrypt (&s_plain, s_cipher, s_skey); rc = gcry_pk_decrypt (&s_plain, s_cipher, s_skey);
if (rc) if (rc)
{ {
log_error ("decryption failed: %s\n", gcry_strerror (rc)); log_error ("decryption failed: %s\n", gpg_strerror (rc));
rc = map_gcry_err (rc); rc = map_gcry_err (rc);
goto leave; goto leave;
} }

View File

@ -1,5 +1,5 @@
/* pksign.c - public key signing (well, acually using a secret key) /* pksign.c - public key signing (well, acually using a secret key)
* Copyright (C) 2001, 2002 Free Software Foundation, Inc. * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -33,7 +33,7 @@
static int static int
do_encode_md (const unsigned char *digest, size_t digestlen, int algo, do_encode_md (const unsigned char *digest, size_t digestlen, int algo,
unsigned int nbits, GCRY_MPI *r_val) unsigned int nbits, gcry_mpi_t *r_val)
{ {
int nframe = (nbits+7) / 8; int nframe = (nbits+7) / 8;
byte *frame; byte *frame;
@ -88,8 +88,8 @@ do_encode_md (const unsigned char *digest, size_t digestlen, int algo,
int int
agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache) agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
{ {
GCRY_SEXP s_skey = NULL, s_hash = NULL, s_sig = NULL; gcry_sexp_t s_skey = NULL, s_hash = NULL, s_sig = NULL;
GCRY_MPI frame = NULL; gcry_mpi_t frame = NULL;
unsigned char *shadow_info = NULL; unsigned char *shadow_info = NULL;
int rc; int rc;
char *buf = NULL; char *buf = NULL;
@ -118,7 +118,7 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
shadow_info, &sigbuf); shadow_info, &sigbuf);
if (rc) if (rc)
{ {
log_error ("smartcard signing failed: %s\n", gnupg_strerror (rc)); log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
len = gcry_sexp_canon_len (sigbuf, 0, NULL, NULL); len = gcry_sexp_canon_len (sigbuf, 0, NULL, NULL);
@ -149,7 +149,7 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
rc = gcry_pk_sign (&s_sig, s_hash, s_skey); rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
if (rc) if (rc)
{ {
log_error ("signing failed: %s\n", gcry_strerror (rc)); log_error ("signing failed: %s\n", gpg_strerror (rc));
rc = map_gcry_err (rc); rc = map_gcry_err (rc);
goto leave; goto leave;
} }

View File

@ -1,5 +1,5 @@
/* protect-tool.c - A tool to test the secret key protection /* protect-tool.c - A tool to test the secret key protection
* Copyright (C) 2002 Free Software Foundation, Inc. * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -30,8 +30,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <gcrypt.h>
#define JNLIB_NEED_LOG_LOGV #define JNLIB_NEED_LOG_LOGV
#include "agent.h" #include "agent.h"
#include "minip12.h" #include "minip12.h"
@ -61,12 +59,12 @@ aTest };
struct rsa_secret_key_s struct rsa_secret_key_s
{ {
MPI n; /* public modulus */ gcry_mpi_t n; /* public modulus */
MPI e; /* public exponent */ gcry_mpi_t e; /* public exponent */
MPI d; /* exponent */ gcry_mpi_t d; /* exponent */
MPI p; /* prime p. */ gcry_mpi_t p; /* prime p. */
MPI q; /* prime q. */ gcry_mpi_t q; /* prime q. */
MPI u; /* inverse of p mod q. */ gcry_mpi_t u; /* inverse of p mod q. */
}; };
@ -162,7 +160,7 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
/* static void */ /* static void */
/* print_mpi (const char *text, GcryMPI a) */ /* print_mpi (const char *text, gcry_mpi_t a) */
/* { */ /* { */
/* char *buf; */ /* char *buf; */
/* void *bufaddr = &buf; */ /* void *bufaddr = &buf; */
@ -170,7 +168,7 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
/* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */ /* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */
/* if (rc) */ /* if (rc) */
/* log_info ("%s: [error printing number: %s]\n", text, gcry_strerror (rc)); */ /* log_info ("%s: [error printing number: %s]\n", text, gpg_strerror (rc)); */
/* else */ /* else */
/* { */ /* { */
/* log_info ("%s: %s\n", text, buf); */ /* log_info ("%s: %s\n", text, buf); */
@ -185,14 +183,14 @@ make_canonical (const char *fname, const char *buf, size_t buflen)
{ {
int rc; int rc;
size_t erroff, len; size_t erroff, len;
GCRY_SEXP sexp; gcry_sexp_t sexp;
unsigned char *result; unsigned char *result;
rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen); rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
if (rc) if (rc)
{ {
log_error ("invalid S-Expression in `%s' (off=%u): %s\n", log_error ("invalid S-Expression in `%s' (off=%u): %s\n",
fname, (unsigned int)erroff, gcry_strerror (rc)); fname, (unsigned int)erroff, gpg_strerror (rc));
return NULL; return NULL;
} }
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0); len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
@ -209,14 +207,14 @@ make_advanced (const unsigned char *buf, size_t buflen)
{ {
int rc; int rc;
size_t erroff, len; size_t erroff, len;
GCRY_SEXP sexp; gcry_sexp_t sexp;
unsigned char *result; unsigned char *result;
rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen); rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
if (rc) if (rc)
{ {
log_error ("invalid canonical S-Expression (off=%u): %s\n", log_error ("invalid canonical S-Expression (off=%u): %s\n",
(unsigned int)erroff, gcry_strerror (rc)); (unsigned int)erroff, gpg_strerror (rc));
return NULL; return NULL;
} }
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
@ -453,7 +451,7 @@ static void
show_keygrip (const char *fname) show_keygrip (const char *fname)
{ {
unsigned char *key; unsigned char *key;
GcrySexp private; gcry_sexp_t private;
unsigned char grip[20]; unsigned char grip[20];
int i; int i;
@ -485,10 +483,10 @@ static int
rsa_key_check (struct rsa_secret_key_s *skey) rsa_key_check (struct rsa_secret_key_s *skey)
{ {
int err = 0; int err = 0;
MPI t = gcry_mpi_snew (0); gcry_mpi_t t = gcry_mpi_snew (0);
MPI t1 = gcry_mpi_snew (0); gcry_mpi_t t1 = gcry_mpi_snew (0);
MPI t2 = gcry_mpi_snew (0); gcry_mpi_t t2 = gcry_mpi_snew (0);
MPI phi = gcry_mpi_snew (0); gcry_mpi_t phi = gcry_mpi_snew (0);
/* check that n == p * q */ /* check that n == p * q */
gcry_mpi_mul (t, skey->p, skey->q); gcry_mpi_mul (t, skey->p, skey->q);
@ -501,7 +499,7 @@ rsa_key_check (struct rsa_secret_key_s *skey)
/* check that p is less than q */ /* check that p is less than q */
if (gcry_mpi_cmp (skey->p, skey->q) > 0) if (gcry_mpi_cmp (skey->p, skey->q) > 0)
{ {
GcryMPI tmp; gcry_mpi_t tmp;
log_info ("swapping secret primes\n"); log_info ("swapping secret primes\n");
tmp = gcry_mpi_copy (skey->p); tmp = gcry_mpi_copy (skey->p);
@ -573,9 +571,9 @@ import_p12_file (const char *fname)
size_t buflen, resultlen; size_t buflen, resultlen;
int i; int i;
int rc; int rc;
GcryMPI *kparms; gcry_mpi_t *kparms;
struct rsa_secret_key_s sk; struct rsa_secret_key_s sk;
GcrySexp s_key; gcry_sexp_t s_key;
unsigned char *key; unsigned char *key;
unsigned char grip[20]; unsigned char grip[20];
@ -635,7 +633,7 @@ import_p12_file (const char *fname)
if (rc) if (rc)
{ {
log_error ("failed to created S-expression from key: %s\n", log_error ("failed to created S-expression from key: %s\n",
gcry_strerror (rc)); gpg_strerror (rc));
return; return;
} }
@ -687,16 +685,16 @@ import_p12_file (const char *fname)
static GcryMPI * static gcry_mpi_t *
sexp_to_kparms (GCRY_SEXP sexp) sexp_to_kparms (gcry_sexp_t sexp)
{ {
GcrySexp list, l2; gcry_sexp_t list, l2;
const char *name; const char *name;
const char *s; const char *s;
size_t n; size_t n;
int i, idx; int i, idx;
const char *elems; const char *elems;
GcryMPI *array; gcry_mpi_t *array;
list = gcry_sexp_find_token (sexp, "private-key", 0 ); list = gcry_sexp_find_token (sexp, "private-key", 0 );
if(!list) if(!list)
@ -747,10 +745,10 @@ sexp_to_kparms (GCRY_SEXP sexp)
static void static void
export_p12_file (const char *fname) export_p12_file (const char *fname)
{ {
GcryMPI kparms[9], *kp; gcry_mpi_t kparms[9], *kp;
unsigned char *key; unsigned char *key;
size_t keylen; size_t keylen;
GcrySexp private; gcry_sexp_t private;
struct rsa_secret_key_s sk; struct rsa_secret_key_s sk;
int i; int i;

View File

@ -1,5 +1,6 @@
/* protect.c - Un/Protect a secret key /* protect.c - Un/Protect a secret key
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. * Copyright (C) 1998, 1999, 2000, 2001, 2002,
* 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -135,19 +136,19 @@ do_encryption (const char *protbegin, size_t protlen,
const char *passphrase, const unsigned char *sha1hash, const char *passphrase, const unsigned char *sha1hash,
unsigned char **result, size_t *resultlen) unsigned char **result, size_t *resultlen)
{ {
GCRY_CIPHER_HD hd; gcry_cipher_hd_t hd;
const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"; const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc";
int blklen, enclen, outlen; int blklen, enclen, outlen;
char *iv = NULL; char *iv = NULL;
int rc = 0; int rc;
char *outbuf = NULL; char *outbuf = NULL;
char *p; char *p;
int saltpos, ivpos, encpos; int saltpos, ivpos, encpos;
hd = gcry_cipher_open (PROT_CIPHER, GCRY_CIPHER_MODE_CBC, rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
GCRY_CIPHER_SECURE); GCRY_CIPHER_SECURE);
if (!hd) if (rc)
return map_gcry_err (gcry_errno()); return rc;
/* We need to work on a copy of the data because this makes it /* We need to work on a copy of the data because this makes it
@ -387,7 +388,7 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
{ {
int rc = 0; int rc = 0;
int blklen; int blklen;
GCRY_CIPHER_HD hd; gcry_cipher_hd_t hd;
unsigned char *outbuf; unsigned char *outbuf;
size_t reallen; size_t reallen;
@ -395,10 +396,10 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
if (protectedlen < 4 || (protectedlen%blklen)) if (protectedlen < 4 || (protectedlen%blklen))
return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
hd = gcry_cipher_open (PROT_CIPHER, GCRY_CIPHER_MODE_CBC, rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
GCRY_CIPHER_SECURE); GCRY_CIPHER_SECURE);
if (!hd) if (rc)
return map_gcry_err (gcry_errno()); return rc;
outbuf = gcry_malloc_secure (protectedlen); outbuf = gcry_malloc_secure (protectedlen);
if (!outbuf) if (!outbuf)
@ -750,7 +751,8 @@ hash_passphrase (const char *passphrase, int hashalgo,
unsigned long s2kcount, unsigned long s2kcount,
unsigned char *key, size_t keylen) unsigned char *key, size_t keylen)
{ {
GCRY_MD_HD md; int rc;
gcry_md_hd_t md;
int pass, i; int pass, i;
int used = 0; int used = 0;
int pwlen = strlen (passphrase); int pwlen = strlen (passphrase);
@ -761,9 +763,9 @@ hash_passphrase (const char *passphrase, int hashalgo,
if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt) if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
md = gcry_md_open (hashalgo, GCRY_MD_FLAG_SECURE); rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE);
if (!md) if (rc)
return map_gcry_err (gcry_errno()); return rc;
for (pass=0; used < keylen; pass++) for (pass=0; used < keylen; pass++)
{ {

View File

@ -1,3 +1,7 @@
2003-06-25 Werner Koch <wk@gnupg.org>
* maperror.c (map_to_assuan_status): Directly map 0 to 0.
2003-06-17 Werner Koch <wk@gnupg.org> 2003-06-17 Werner Koch <wk@gnupg.org>
* gettime.c (scan_isodatestr,add_days_to_timestamp,strtimevalue) * gettime.c (scan_isodatestr,add_days_to_timestamp,strtimevalue)

View File

@ -129,6 +129,8 @@ map_to_assuan_status (int rc)
gpg_err_code_t ec = gpg_err_code (rc); gpg_err_code_t ec = gpg_err_code (rc);
gpg_err_source_t es = gpg_err_source (rc); gpg_err_source_t es = gpg_err_source (rc);
if (!rc)
return 0;
if (!es) if (!es)
{ {
es = GPG_ERR_SOURCE_USER_4; /* This should not happen, but we es = GPG_ERR_SOURCE_USER_4; /* This should not happen, but we
@ -149,3 +151,7 @@ map_to_assuan_status (int rc)

View File

@ -26,14 +26,15 @@
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include <gcrypt.h>
#include "../jnlib/logging.h" #include "../jnlib/logging.h"
#include "../jnlib/argparse.h" #include "../jnlib/argparse.h"
#include "../jnlib/stringhelp.h" #include "../jnlib/stringhelp.h"
#include "../common/i18n.h" #include "../common/i18n.h"
#include "keybox-defs.h" #include "keybox-defs.h"
#include <gcrypt.h>
enum cmd_and_opt_values { enum cmd_and_opt_values {
aNull = 0, aNull = 0,
oArmor = 'a', oArmor = 'a',

View File

@ -110,6 +110,8 @@ X.509 specific are noted like [X.509: xxx]
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include "keybox-defs.h"
#include <gcrypt.h> #include <gcrypt.h>
#ifdef KEYBOX_WITH_OPENPGP #ifdef KEYBOX_WITH_OPENPGP
@ -119,7 +121,6 @@ X.509 specific are noted like [X.509: xxx]
#include <ksba.h> #include <ksba.h>
#endif #endif
#include "keybox-defs.h"
/* special values of the signature status */ /* special values of the signature status */

View File

@ -1,3 +1,34 @@
2003-06-26 Werner Koch <wk@gnupg.org>
* app-openpgp.c (find_tlv): Fixed length header parsing.
* app.c (app_genkey): New.
* command.c (cmd_genkey): New.
2003-06-25 Werner Koch <wk@gnupg.org>
* command.c (percent_plus_unescape): New.
(cmd_setattr): New.
2003-06-24 Werner Koch <wk@gnupg.org>
* command.c (send_status_info): New.
* app-openpgp.c (app_select_openpgp): Replace SLOT arg by APP arg
and setup the function pointers in APP on success. Changed callers.
* app.c: New.
* app-common.h: New.
* scdaemon.h (APP): New type to handle applications.
(server_control_s): Add an APP context field.
* command.c (cmd_serialno): Handle applications.
(cmd_pksign): Ditto.
(cmd_pkdecrypt): Ditto.
(reset_notify): Ditto.
(cmd_learn): For now return error for application contexts.
(cmd_readcert): Ditto.
(cmd_readkey): Ditto.
2003-06-04 Werner Koch <wk@gnupg.org> 2003-06-04 Werner Koch <wk@gnupg.org>
* card.c (map_sc_err): Renamed gpg_make_err to gpg_err_make. * card.c (map_sc_err): Renamed gpg_make_err to gpg_err_make.

View File

@ -33,6 +33,7 @@ scdaemon_SOURCES = \
card-p15.c card-dinsig.c \ card-p15.c card-dinsig.c \
apdu.c apdu.h \ apdu.c apdu.h \
iso7816.c iso7816.h \ iso7816.c iso7816.h \
app.c app-common.h \
app-openpgp.c app-openpgp.c
scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \ scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \

90
scd/app-common.h Normal file
View File

@ -0,0 +1,90 @@
/* app-common.h - Common declarations for all card applications
* Copyright (C) 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef GNUPG_SCD_APP_COMMON_H
#define GNUPG_SCD_APP_COMMON_H
struct app_ctx_s {
int initialized; /* The application has been initialied and the
function pointers may be used. Note that for
unsupported operations the particular
function pointer is set to NULL */
int slot; /* Used reader. */
unsigned char *serialno; /* Serialnumber in raw form, allocated. */
size_t serialnolen; /* Length in octets of serialnumber. */
int did_chv1;
int did_chv2;
int did_chv3;
struct {
int (*learn_status) (APP app, CTRL ctrl);
int (*setattr) (APP app, const char *name,
int (*pincb)(void*, const char *, char **),
void *pincb_arg,
const unsigned char *value, size_t valuelen);
int (*sign) (APP app,
const char *keyidstr, int hashalgo,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
void **outdata, size_t *outdatalen );
int (*decipher) (APP app, const char *keyidstr,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
void **outdata, size_t *outdatalen);
int (*genkey) (APP app, CTRL ctrl,
const char *keynostr, unsigned int flags,
int (*pincb)(void*, const char *, char **),
void *pincb_arg);
} fnc;
};
/*-- app.c --*/
APP select_application (void);
int app_get_serial_and_stamp (APP app, char **serial, time_t *stamp);
int app_write_learn_status (APP app, CTRL ctrl);
int app_setattr (APP app, const char *name,
int (*pincb)(void*, const char *, char **),
void *pincb_arg,
const unsigned char *value, size_t valuelen);
int app_sign (APP app, const char *keyidstr, int hashalgo,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
void **outdata, size_t *outdatalen );
int app_decipher (APP app, const char *keyidstr,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
void **outdata, size_t *outdatalen );
int app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
int (*pincb)(void*, const char *, char **),
void *pincb_arg);
/*-- app-openpgp.c --*/
int app_select_openpgp (APP app, unsigned char **sn, size_t *snlen);
#endif /*GNUPG_SCD_APP_COMMON_H*/

View File

@ -26,8 +26,11 @@
#include <dlfcn.h> #include <dlfcn.h>
#include "scdaemon.h" #include "scdaemon.h"
#include "app-common.h"
#include "iso7816.h" #include "iso7816.h"
static struct { static struct {
int tag; int tag;
int constructed; int constructed;
@ -80,6 +83,12 @@ find_tlv (const unsigned char *buffer, size_t length,
buffer = s; buffer = s;
if (n < 2) if (n < 2)
return NULL; /* buffer definitely too short for tag and length. */ return NULL; /* buffer definitely too short for tag and length. */
if (!*s || *s == 0xff)
{ /* Skip optional filler between TLV objects. */
s++;
n--;
continue;
}
composite = !!(*s & 0x20); composite = !!(*s & 0x20);
if ((*s & 0x1f) == 0x1f) if ((*s & 0x1f) == 0x1f)
{ /* more tag bytes to follow */ { /* more tag bytes to follow */
@ -95,13 +104,26 @@ find_tlv (const unsigned char *buffer, size_t length,
this_tag = s[0]; this_tag = s[0];
len = s[1]; len = s[1];
s += 2; n -= 2; s += 2; n -= 2;
if (len == 255) if (len < 0x80)
{ ;
else if (len == 0x81)
{ /* One byte length follows. */
if (!n)
return NULL; /* we expected 1 more bytes with the length. */
len = s[0];
s++; n--;
}
else if (len == 0x82)
{ /* Two byte length follows. */
if (n < 2) if (n < 2)
return NULL; /* we expected 2 more bytes with the length. */ return NULL; /* we expected 2 more bytes with the length. */
len = (s[0] << 8) | s[1]; len = (s[0] << 8) | s[1];
s += 2; n -= 2; s += 2; n -= 2;
} }
else
return NULL; /* APDU limit is 65535, thus it does not make
sense to assume longer length fields. */
if (composite && nestlevel < 100) if (composite && nestlevel < 100)
{ /* Dive into this composite DO after checking for too deep { /* Dive into this composite DO after checking for too deep
nesting. */ nesting. */
@ -128,7 +150,64 @@ find_tlv (const unsigned char *buffer, size_t length,
} }
/* Get the DO identified by TAG from the card in SLOT and return a
buffer with its content in RESULT and NBYTES. The return value is
NULL if not found or a pointer which must be used to release the
buffer holding value. */
static void *
get_one_do (int slot, int tag, unsigned char **result, size_t *nbytes)
{
int rc, i;
unsigned char *buffer;
size_t buflen;
unsigned char *value;
size_t valuelen;
*result = NULL;
*nbytes = 0;
for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++)
;
value = NULL;
rc = -1;
if (data_objects[i].tag && data_objects[i].get_from)
{
rc = iso7816_get_data (slot, data_objects[i].get_from,
&buffer, &buflen);
if (!rc)
{
value = find_tlv (buffer, buflen, tag, &valuelen, 0);
if (!value)
; /* not found */
else if (valuelen > buflen - (value - buffer))
{
log_error ("warning: constructed DO too short\n");
value = NULL;
xfree (buffer); buffer = NULL;
}
}
}
if (!value) /* Not in a constructed DO, try simple. */
{
rc = iso7816_get_data (slot, tag, &buffer, &buflen);
if (!rc)
{
value = buffer;
valuelen = buflen;
}
}
if (!rc)
{
*nbytes = valuelen;
*result = value;
return buffer;
}
return NULL;
}
#if 0 /* not used */
static void static void
dump_one_do (int slot, int tag) dump_one_do (int slot, int tag)
{ {
@ -191,6 +270,7 @@ dump_one_do (int slot, int tag)
xfree (buffer); xfree (buffer);
} }
} }
#endif /*not used*/
static void static void
@ -257,15 +337,15 @@ dump_all_do (int slot)
} }
} }
/* Note, that FPR must be at least 20 bytes. */
static int static int
store_fpr (int slot, int keynumber, u32 timestamp, store_fpr (int slot, int keynumber, u32 timestamp,
const unsigned char *m, size_t mlen, const unsigned char *m, size_t mlen,
const unsigned char *e, size_t elen) const unsigned char *e, size_t elen,
unsigned char *fpr)
{ {
unsigned int n; unsigned int n;
unsigned char *buffer, *p; unsigned char *buffer, *p;
unsigned char fpr[20];
int rc; int rc;
n = 6 + 2 + mlen + 2 + elen; n = 6 + 2 + mlen + 2 + elen;
@ -299,45 +379,189 @@ store_fpr (int slot, int keynumber, u32 timestamp,
return rc; return rc;
} }
static void
send_fpr_if_not_null (CTRL ctrl, const char *keyword,
int number, const unsigned char *fpr)
{
int i;
char buf[41];
char numbuf[25];
for (i=0; i < 20 && !fpr[i]; i++)
;
if (i==20)
return; /* All zero. */
for (i=0; i< 20; i++)
sprintf (buf+2*i, "%02X", fpr[i]);
if (number == -1)
*numbuf = 0; /* Don't print the key number */
else
sprintf (numbuf, "%d", number);
send_status_info (ctrl, keyword,
numbuf, (size_t)strlen(numbuf),
buf, (size_t)strlen (buf), NULL, 0);
}
static void
send_key_data (CTRL ctrl, const char *name,
const unsigned char *a, size_t alen)
{
char *p, *buf = xmalloc (alen*2+1);
for (p=buf; alen; a++, alen--, p += 2)
sprintf (p, "%02X", *a);
send_status_info (ctrl, "KEY-DATA",
name, (size_t)strlen(name),
buf, (size_t)strlen (buf),
NULL, 0);
xfree (buf);
}
/* Generate a new key on the card and store the fingerprint in the
corresponding DO. A KEYNUMBER of 0 creates the digital signature static int
key, 1 the encryption key and 2 the authentication key. If the key do_learn_status (APP app, CTRL ctrl)
already exists an error is returned unless FORCE has been set to {
true. Note, that the function does not return the public key; this void *relptr;
has to be done using openpgp_readkey(). */ unsigned char *value;
int size_t valuelen;
openpgp_genkey (int slot, int keynumber, int force) int i;
relptr = get_one_do (app->slot, 0x005B, &value, &valuelen);
if (relptr)
{
send_status_info (ctrl, "DISP-NAME", value, valuelen, NULL, 0);
xfree (relptr);
}
relptr = get_one_do (app->slot, 0x5FF0, &value, &valuelen);
if (relptr)
{
send_status_info (ctrl, "PUBKEY-URL", value, valuelen, NULL, 0);
xfree (relptr);
}
relptr = get_one_do (app->slot, 0x00C5, &value, &valuelen);
if (relptr && valuelen >= 60)
{
for (i=0; i < 3; i++)
send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20);
}
xfree (relptr);
relptr = get_one_do (app->slot, 0x00C6, &value, &valuelen);
if (relptr && valuelen >= 60)
{
for (i=0; i < 3; i++)
send_fpr_if_not_null (ctrl, "CA-FPR", i+1, value+i*20);
}
xfree (relptr);
return 0;
}
/* Handle the SETATTR operation. All arguments are already basically
checked. */
static int
do_setattr (APP app, const char *name,
int (*pincb)(void*, const char *, char **),
void *pincb_arg,
const unsigned char *value, size_t valuelen)
{
gpg_error_t rc;
log_debug ("app_openpgp#setattr `%s' value of length %u\n",
name, (unsigned int)valuelen); /* fixme: name should be
sanitized. */
if (!app->did_chv3)
{
char *pinvalue;
/* rc = pincb (pincb_arg, "Please enter the card's admin PIN (CHV3)", */
/* &pinvalue); */
pinvalue = xstrdup ("12345678");
rc = 0;
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV3 failed\n");
rc = gpg_error (GPG_ERR_GENERAL);
return rc;
}
app->did_chv3 = 1;
}
log_debug ("setting `%s' to `%.*s'\n", name, (int)valuelen, value);
if (!strcmp (name, "DISP-NAME"))
{
rc = iso7816_put_data (app->slot, 0x005B, value, valuelen);
if (rc)
{
/* FIXME: If this fails we should *once* try again after
doing a verify command, so that in case of a problem with
tracking the verify operation we have a fallback. */
/* FIXME: change this when iso7816 returns correct error
codes. */
log_error ("failed to set `Name'\n");
rc = gpg_error (GPG_ERR_GENERAL);
}
}
else
rc = gpg_error (GPG_ERR_INV_NAME);
return rc;
}
/* Handle the GENKEY command. */
static int
do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
int (*pincb)(void*, const char *, char **),
void *pincb_arg)
{ {
int rc; int rc;
int i; int i;
char numbuf[30];
unsigned char fprbuf[20];
const unsigned char *fpr; const unsigned char *fpr;
const unsigned char *keydata, *m, *e; const unsigned char *keydata, *m, *e;
unsigned char *buffer; unsigned char *buffer;
size_t buflen, keydatalen, n, mlen, elen; size_t buflen, keydatalen, n, mlen, elen;
time_t created_at; time_t created_at;
int keyno = atoi (keynostr);
if (keynumber < 0 || keynumber > 2) int force = (flags & 1);
return -1; /* invalid value */
rc = iso7816_get_data (slot, 0x006E, &buffer, &buflen); if (keyno < 1 || keyno > 3)
return gpg_error (GPG_ERR_INV_ID);
keyno--;
rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen);
if (rc) if (rc)
{ {
log_error ("error reading application data\n"); log_error ("error reading application data\n");
return -1; return gpg_error (GPG_ERR_GENERAL);
} }
fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0); fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0);
if (!fpr || n != 60) if (!fpr || n != 60)
{ {
rc = gpg_error (GPG_ERR_GENERAL);
log_error ("error reading fingerprint DO\n"); log_error ("error reading fingerprint DO\n");
goto leave; goto leave;
} }
fpr += 20*keynumber; fpr += 20*keyno;
for (i=0; i < 20 && !fpr[i]; i++) for (i=0; i < 20 && !fpr[i]; i++)
; ;
if (i!=20 && !force) if (i!=20 && !force)
{ {
rc = gpg_error (GPG_ERR_EEXIST);
log_error ("key already exists\n"); log_error ("key already exists\n");
goto leave; goto leave;
} }
@ -346,8 +570,7 @@ openpgp_genkey (int slot, int keynumber, int force)
else else
log_info ("generating new key\n"); log_info ("generating new key\n");
rc = iso7816_verify (app->slot, 0x83, "12345678", 8);
rc = iso7816_verify (slot, 0x83, "12345678", 8);
if (rc) if (rc)
{ {
log_error ("verify CHV3 failed: rc=%04X\n", rc); log_error ("verify CHV3 failed: rc=%04X\n", rc);
@ -355,13 +578,14 @@ openpgp_genkey (int slot, int keynumber, int force)
} }
xfree (buffer); buffer = NULL; xfree (buffer); buffer = NULL;
rc = iso7816_generate_keypair (slot, rc = iso7816_generate_keypair (app->slot,
keynumber == 0? "\xB6" : keyno == 0? "\xB6" :
keynumber == 1? "\xB8" : "\xA4", keyno == 1? "\xB8" : "\xA4",
2, 2,
&buffer, &buflen); &buffer, &buflen);
if (rc) if (rc)
{ {
rc = gpg_error (GPG_ERR_CARD);
log_error ("generating key failed\n"); log_error ("generating key failed\n");
goto leave; goto leave;
} }
@ -372,7 +596,6 @@ openpgp_genkey (int slot, int keynumber, int force)
goto leave; goto leave;
} }
m = find_tlv (keydata, keydatalen, 0x0081, &mlen, 0); m = find_tlv (keydata, keydatalen, 0x0081, &mlen, 0);
if (!m) if (!m)
{ {
@ -380,6 +603,8 @@ openpgp_genkey (int slot, int keynumber, int force)
goto leave; goto leave;
} }
log_printhex ("RSA n:", m, mlen); log_printhex ("RSA n:", m, mlen);
send_key_data (ctrl, "n", m, mlen);
e = find_tlv (keydata, keydatalen, 0x0082, &elen, 0); e = find_tlv (keydata, keydatalen, 0x0082, &elen, 0);
if (!e) if (!e)
{ {
@ -387,8 +612,18 @@ openpgp_genkey (int slot, int keynumber, int force)
goto leave; goto leave;
} }
log_printhex ("RSA e:", e, elen); log_printhex ("RSA e:", e, elen);
send_key_data (ctrl, "e", e, elen);
created_at = gnupg_get_time (); created_at = gnupg_get_time ();
rc = store_fpr (slot, keynumber, (u32)created_at, m, mlen, e, elen); sprintf (numbuf, "%lu", (unsigned long)created_at);
send_status_info (ctrl, "KEY-CREATED-AT",
numbuf, (size_t)strlen(numbuf), NULL, 0);
rc = store_fpr (app->slot, keyno, (u32)created_at,
m, mlen, e, elen, fprbuf);
if (rc)
goto leave;
send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf);
leave: leave:
@ -397,12 +632,75 @@ openpgp_genkey (int slot, int keynumber, int force)
} }
/* Comopute a digital signature on INDATA which is expected to be the
raw message digest. */
static int
do_sign (APP app, const char *keyidstr, int hashalgo,
int (*pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
void **outdata, size_t *outdatalen )
{
static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
int rc;
unsigned char data[35];
/* We ignore KEYIDSTR, because the OpenPGP application has only one
signing key and no way to specify a different one. */
if (indatalen != 20)
return gpg_error (GPG_ERR_INV_VALUE);
if (hashalgo == GCRY_MD_SHA1)
memcpy (data, sha1_prefix, 15);
else if (hashalgo == GCRY_MD_RMD160)
memcpy (data, rmd160_prefix, 15);
else
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
memcpy (data+15, indata, indatalen);
if (!app->did_chv1)
{
char *pinvalue;
/* rc = pincb (pincb_arg, "signature PIN", &pinvalue); */
pinvalue = xstrdup ("123456");
rc = 0;
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV1 failed\n");
rc = gpg_error (GPG_ERR_GENERAL);
return rc;
}
app->did_chv1 = 1;
}
rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
return rc;
}
/* Select the OpenPGP application on the card in SLOT. This function /* Select the OpenPGP application on the card in SLOT. This function
must be used to before any other OpenPGP application functions. */ must be used before any other OpenPGP application functions. */
int int
app_select_openpgp (int slot) app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
{ {
static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 }; static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
int slot = app->slot;
int rc; int rc;
unsigned char *buffer; unsigned char *buffer;
size_t buflen; size_t buflen;
@ -416,27 +714,31 @@ app_select_openpgp (int slot)
if (rc) if (rc)
goto leave; goto leave;
if (opt.verbose) if (opt.verbose)
log_info ("got AID: "); {
log_printhex ("", buffer, buflen); log_info ("got AID: ");
xfree (buffer); log_printhex ("", buffer, buflen);
}
if (sn)
{
*sn = buffer;
*snlen = buflen;
}
else
xfree (buffer);
dump_all_do (slot); dump_all_do (slot);
/* rc = iso7816_verify (slot, 0x83, "12345678", 8); */ app->fnc.learn_status = do_learn_status;
/* if (rc) */ app->fnc.setattr = do_setattr;
/* log_error ("verify CHV3 failed: rc=%04X\n", rc); */ app->fnc.genkey = do_genkey;
app->fnc.sign = do_sign;
}
/* rc = iso7816_put_data (slot, 0x005B, "Joe Hacker", 10); */
/* if (rc) */
/* log_error ("failed to set `Name': rc=%04X\n", rc); */
/* else */
/* dump_one_do (slot, 0x005B); */
/* fixme: associate the internal state with the slot */
}
leave: leave:
return rc; return rc;
} }

208
scd/app.c Normal file
View File

@ -0,0 +1,208 @@
/* app.c - Application selection.
* Copyright (C) 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include "scdaemon.h"
#include "app-common.h"
#include "apdu.h"
/* The select the best fitting application and return a context.
Returns NULL if no application was found or no card is present. */
APP
select_application (void)
{
int reader_port = 32768; /* First USB reader. */
int slot;
int rc;
APP app;
slot = apdu_open_reader (reader_port);
if (slot == -1)
{
log_error ("card reader not available\n");
return NULL;
}
app = xtrycalloc (1, sizeof *app);
if (!app)
{
rc = out_of_core ();
log_info ("error allocating context: %s\n", gpg_strerror (rc));
/*apdu_close_reader (slot);*/
return NULL;
}
app->slot = slot;
rc = app_select_openpgp (app, &app->serialno, &app->serialnolen);
if (rc)
{
/* apdu_close_reader (slot); */
log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
xfree (app);
return NULL;
}
app->initialized = 1;
return app;
}
/* Retrieve the serial number and the time of the last update of the
card. The serial number is returned as a malloced string (hex
encoded) in SERIAL and the time of update is returned in STAMP. If
no update time is available the returned value is 0. Caller must
free SERIAL unless the function returns an error. */
int
app_get_serial_and_stamp (APP app, char **serial, time_t *stamp)
{
unsigned char *buf, *p;
int i;
if (!app || !serial || !stamp)
return gpg_error (GPG_ERR_INV_VALUE);
*serial = NULL;
*stamp = 0; /* not available */
buf = xtrymalloc (app->serialnolen * 2 + 1);
if (!buf)
return gpg_error_from_errno (errno);
for (p=buf, i=0; i < app->serialnolen; p +=2, i++)
sprintf (p, "%02X", app->serialno[i]);
*p = 0;
*serial = buf;
return 0;
}
/* Write out the application specifig status lines for the LEARN
command. */
int
app_write_learn_status (APP app, CTRL ctrl)
{
if (!app)
return gpg_error (GPG_ERR_INV_VALUE);
if (!app->initialized)
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
if (!app->fnc.learn_status)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
return app->fnc.learn_status (app, ctrl);
}
/* Perform a SETATTR operation. */
int
app_setattr (APP app, const char *name,
int (*pincb)(void*, const char *, char **),
void *pincb_arg,
const unsigned char *value, size_t valuelen)
{
if (!app || !name || !*name || !value)
return gpg_error (GPG_ERR_INV_VALUE);
if (!app->initialized)
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
if (!app->fnc.setattr)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
return app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
}
/* Create the signature and return the allocated result in OUTDATA.
If a PIN is required the PINCB will be used to ask for the PIN; it
should return the PIN in an allocated buffer and put it into PIN. */
int
app_sign (APP app, const char *keyidstr, int hashalgo,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
void **outdata, size_t *outdatalen )
{
int rc;
if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
if (!app->initialized)
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
if (!app->fnc.sign)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = app->fnc.sign (app, keyidstr, hashalgo,
pincb, pincb_arg,
indata, indatalen,
outdata, outdatalen);
if (opt.verbose)
log_info ("operation sign result: %s\n", gpg_strerror (rc));
return rc;
}
/* Decrypt the data in INDATA and return the allocated result in OUTDATA.
If a PIN is required the PINCB will be used to ask for the PIN; it
should return the PIN in an allocated buffer and put it into PIN. */
int
app_decipher (APP app, const char *keyidstr,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
void **outdata, size_t *outdatalen )
{
int rc;
if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
if (!app->initialized)
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
if (!app->fnc.decipher)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = app->fnc.decipher (app, keyidstr,
pincb, pincb_arg,
indata, indatalen,
outdata, outdatalen);
if (opt.verbose)
log_info ("operation decipher result: %s\n", gpg_strerror (rc));
return rc;
}
/* Perform a SETATTR operation. */
int
app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
int (*pincb)(void*, const char *, char **),
void *pincb_arg)
{
int rc;
if (!app || !keynostr || !*keynostr || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
if (!app->initialized)
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
if (!app->fnc.genkey)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg);
if (opt.verbose)
log_info ("operation genkey result: %s\n", gpg_strerror (rc));
return rc;
}

View File

@ -59,7 +59,7 @@ map_sc_err (int rc)
int int
card_help_get_keygrip (KsbaCert cert, unsigned char *array) card_help_get_keygrip (KsbaCert cert, unsigned char *array)
{ {
GCRY_SEXP s_pkey; gcry_sexp_t s_pkey;
int rc; int rc;
KsbaSexp p; KsbaSexp p;
size_t n; size_t n;
@ -558,3 +558,4 @@ card_decipher (CARD card, const char *keyidstr,
log_info ("card operation decipher result: %s\n", gpg_strerror (rc)); log_info ("card operation decipher result: %s\n", gpg_strerror (rc));
return rc; return rc;
} }

View File

@ -30,6 +30,7 @@
#include <assuan.h> #include <assuan.h>
#include "scdaemon.h" #include "scdaemon.h"
#include "app-common.h"
/* maximum length aloowed as a PIN; used for INQUIRE NEEDPIN */ /* maximum length aloowed as a PIN; used for INQUIRE NEEDPIN */
#define MAXLEN_PIN 100 #define MAXLEN_PIN 100
@ -69,6 +70,12 @@ reset_notify (ASSUAN_CONTEXT ctx)
xfree (ctrl->in_data.value); xfree (ctrl->in_data.value);
ctrl->in_data.value = NULL; ctrl->in_data.value = NULL;
} }
if (ctrl->app_ctx)
{
/* FIXME: close the application. */
xfree (ctrl->app_ctx);
ctrl->app_ctx = NULL;
}
} }
@ -85,8 +92,14 @@ option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
static AssuanError static AssuanError
open_card (CTRL ctrl) open_card (CTRL ctrl)
{ {
if (!ctrl->card_ctx) if (ctrl->app_ctx)
{ return 0; /* Already initialized for one specific application. */
if (ctrl->card_ctx)
return 0; /* Already initialized using a card context. */
ctrl->app_ctx = select_application ();
if (!ctrl->app_ctx)
{ /* No application found - fall back to old mode. */
int rc = card_open (&ctrl->card_ctx); int rc = card_open (&ctrl->card_ctx);
if (rc) if (rc)
return map_to_assuan_status (rc); return map_to_assuan_status (rc);
@ -95,6 +108,41 @@ open_card (CTRL ctrl)
} }
/* Do the percent and plus/space unescaping in place and return tghe
length of the valid buffer. */
static size_t
percent_plus_unescape (unsigned char *string)
{
unsigned char *p = string;
size_t n = 0;
while (*string)
{
if (*string == '%' && string[1] && string[2])
{
string++;
*p++ = xtoi_2 (string);
n++;
string+= 2;
}
else if (*string == '+')
{
*p++ = ' ';
n++;
string++;
}
else
{
*p++ = *string++;
n++;
}
}
return n;
}
/* SERIALNO /* SERIALNO
Return the serial number of the card using a status reponse. This Return the serial number of the card using a status reponse. This
@ -106,7 +154,7 @@ open_card (CTRL ctrl)
Background: We want to keep the client clear of handling card Background: We want to keep the client clear of handling card
changes between operations; i.e. the client can assume that all changes between operations; i.e. the client can assume that all
operations are doneon the same card unless he call this function. operations are done on the same card unless he call this function.
*/ */
static int static int
cmd_serialno (ASSUAN_CONTEXT ctx, char *line) cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
@ -120,7 +168,10 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); if (ctrl->app_ctx)
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
else
rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
if (rc) if (rc)
return map_to_assuan_status (rc); return map_to_assuan_status (rc);
rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
@ -149,6 +200,16 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
error message. The response of this command is a list of status error message. The response of this command is a list of status
lines formatted as this: lines formatted as this:
S APPTYPE <apptype>
This returns the type of the application, currently the strings:
P15 = PKCS-15 structure used
DINSIG = DIN SIG
OPENPGP = OpenPGP card
are implemented. These strings are aliases for the AID
S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id> S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
If there is no certificate yet stored on the card a single "X" is If there is no certificate yet stored on the card a single "X" is
@ -157,13 +218,34 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
S CERTINFO <certtype> <hexstring_with_id> S CERTINFO <certtype> <hexstring_with_id>
Where CERTINFO is a number indicating the type of certificate: Where CERTTYPE is a number indicating the type of certificate:
0 := Unknown 0 := Unknown
100 := Regular X.509 cert 100 := Regular X.509 cert
101 := Trusted X.509 cert 101 := Trusted X.509 cert
102 := Useful X.509 cert 102 := Useful X.509 cert
For certain cards, more information will be returned:
S KEY-FPR <no> <hexstring>
For OpenPGP cards this returns the stored fingerprints of the
keys. This can be used check whether a key is available on the
card. NO may be 1, 2 or 3.
S CA-FPR <no> <hexstring>
Similar to above, these are the fingerprints of keys assumed to be
ultimately trusted.
S DISP-NAME <name_of_card_holder>
The name of the card holder as stored on the card; percent
aescaping takes place, spaces are encoded as '+'
S PUBKEY-URL <url>
The URL to be used for locating the entire public key.
*/ */
static int static int
cmd_learn (ASSUAN_CONTEXT ctx, char *line) cmd_learn (ASSUAN_CONTEXT ctx, char *line)
@ -183,8 +265,11 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
char *serial_and_stamp; char *serial_and_stamp;
char *serial; char *serial;
time_t stamp; time_t stamp;
rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); if (ctrl->app_ctx)
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
else
rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
if (rc) if (rc)
return map_to_assuan_status (rc); return map_to_assuan_status (rc);
rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
@ -221,6 +306,8 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
} }
/* Return information about the certificates. */ /* Return information about the certificates. */
if (ctrl->app_ctx)
rc = -1; /* This information is not yet available for applications. */
for (idx=0; !rc; idx++) for (idx=0; !rc; idx++)
{ {
char *certid; char *certid;
@ -248,6 +335,8 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
/* Return information about the keys. */ /* Return information about the keys. */
if (ctrl->app_ctx)
rc = -1; /* This information is not yet available for applications. */
for (idx=0; !rc; idx++) for (idx=0; !rc; idx++)
{ {
unsigned char keygrip[20]; unsigned char keygrip[20];
@ -294,6 +383,9 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
if (rc == -1) if (rc == -1)
rc = 0; rc = 0;
if (!rc && ctrl->app_ctx)
rc = app_write_learn_status (ctrl->app_ctx, ctrl);
return map_to_assuan_status (rc); return map_to_assuan_status (rc);
} }
@ -314,6 +406,9 @@ cmd_readcert (ASSUAN_CONTEXT ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (ctrl->app_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
if (rc) if (rc)
{ {
@ -348,6 +443,9 @@ cmd_readkey (ASSUAN_CONTEXT ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (ctrl->app_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
if (rc) if (rc)
{ {
@ -480,11 +578,19 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
keyidstr = strdup (line); keyidstr = strdup (line);
if (!keyidstr) if (!keyidstr)
return ASSUAN_Out_Of_Core; return ASSUAN_Out_Of_Core;
rc = card_sign (ctrl->card_ctx,
keyidstr, GCRY_MD_SHA1, if (ctrl->app_ctx)
pin_cb, ctx, rc = app_sign (ctrl->app_ctx,
ctrl->in_data.value, ctrl->in_data.valuelen, keyidstr, GCRY_MD_SHA1,
&outdata, &outdatalen); pin_cb, ctx,
ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen);
else
rc = card_sign (ctrl->card_ctx,
keyidstr, GCRY_MD_SHA1,
pin_cb, ctx,
ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen);
free (keyidstr); free (keyidstr);
if (rc) if (rc)
{ {
@ -519,11 +625,18 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
keyidstr = strdup (line); keyidstr = strdup (line);
if (!keyidstr) if (!keyidstr)
return ASSUAN_Out_Of_Core; return ASSUAN_Out_Of_Core;
rc = card_decipher (ctrl->card_ctx, if (ctrl->app_ctx)
keyidstr, rc = app_decipher (ctrl->app_ctx,
pin_cb, ctx, keyidstr,
ctrl->in_data.value, ctrl->in_data.valuelen, pin_cb, ctx,
&outdata, &outdatalen); ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen);
else
rc = card_decipher (ctrl->card_ctx,
keyidstr,
pin_cb, ctx,
ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen);
free (keyidstr); free (keyidstr);
if (rc) if (rc)
{ {
@ -541,6 +654,99 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
} }
/* SETATTR <name> <value>
This command is used to store data on a a smartcard. The allowed
names and values are depend on the currently selected smartcard
application. NAME and VALUE must be percent and '+' escaped.
However, the curent implementation assumes that Name is not escaped;
this works as long as noone uses arbitrary escaping.
A PIN will be requested for most NAMEs. See the corresponding
setattr function of the actually used application (app-*.c) for
details. */
static int
cmd_setattr (ASSUAN_CONTEXT ctx, char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
int rc;
char *keyword;
int keywordlen;
size_t nbytes;
if ((rc = open_card (ctrl)))
return rc;
keyword = line;
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
;
if (*line)
*line++ = 0;
while (spacep (line))
line++;
nbytes = percent_plus_unescape (line);
rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes);
return map_to_assuan_status (rc);
}
/* GENKEY [--force] <no>
Generate a key on-card identified by NO, which is application
specific. Return values are application specific. For OpenPGP
cards 2 status lines are returned:
S KEY-FPR <hexstring>
S KEY-CREATED-AT <seconds_since_epoch>
S KEY-DATA [p|n] <hexdata>
--force is required to overwriet an already existing key. The
KEY-CREATED-AT is required for further processing because it is
part of the hashed key material for the fingerprint.
The public part of the key can also later be retrieved using the
READKEY command.
*/
static int
cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
int rc;
char *keyno;
int force = has_option (line, "--force");
/* Skip over options. */
while ( *line == '-' && line[1] == '-' )
{
while (!spacep (line))
line++;
while (spacep (line))
line++;
}
if (!*line)
return set_error (Parameter_Error, "no key number given");
keyno = line;
while (!spacep (line))
line++;
*line = 0;
if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
return map_to_assuan_status (rc);
}
/* Tell the assuan library about our commands */ /* Tell the assuan library about our commands */
@ -560,6 +766,8 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "PKDECRYPT", cmd_pkdecrypt }, { "PKDECRYPT", cmd_pkdecrypt },
{ "INPUT", NULL }, { "INPUT", NULL },
{ "OUTPUT", NULL }, { "OUTPUT", NULL },
{ "SETATTR", cmd_setattr },
{ "GENKEY", cmd_genkey },
{ NULL } { NULL }
}; };
int i, rc; int i, rc;
@ -646,3 +854,51 @@ scd_command_handler (int listen_fd)
assuan_deinit_server (ctx); assuan_deinit_server (ctx);
} }
/* Send a line with status information via assuan and escape all given
buffers. The variable elements are pairs of (char *, size_t),
terminated with a (NULL, 0). */
void
send_status_info (CTRL ctrl, const char *keyword, ...)
{
va_list arg_ptr;
const unsigned char *value;
size_t valuelen;
char buf[950], *p;
size_t n;
ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx;
va_start (arg_ptr, keyword);
p = buf;
n = 0;
while ( (value = va_arg (arg_ptr, const unsigned char *)) )
{
valuelen = va_arg (arg_ptr, size_t);
if (!valuelen)
continue; /* empty buffer */
if (n)
{
*p++ = ' ';
n++;
}
for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
{
if (*value < ' ' || *value == '+')
{
sprintf (p, "%%%02X", *value);
p += 3;
}
else if (*value == ' ')
*p++ = '+';
else
*p++ = *value;
}
}
*p = 0;
assuan_write_status (ctx, keyword, buf);
va_end (arg_ptr);
}

View File

@ -25,11 +25,12 @@
#include <string.h> #include <string.h>
#define JNLIB_NEED_LOG_LOGV #define JNLIB_NEED_LOG_LOGV
#include <gcrypt.h>
#include "scdaemon.h" #include "scdaemon.h"
#include <gcrypt.h>
#include "apdu.h" /* for open_reader */ #include "apdu.h" /* for open_reader */
#include "atr.h" #include "atr.h"
#include "app-common.h"
#define _(a) (a) #define _(a) (a)
@ -104,6 +105,9 @@ main (int argc, char **argv )
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
int slot, rc; int slot, rc;
int reader_port = 32768; /* First USB reader. */ int reader_port = 32768; /* First USB reader. */
struct app_ctx_s appbuf;
memset (&appbuf, 0, sizeof appbuf);
set_strusage (my_strusage); set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
@ -147,7 +151,8 @@ main (int argc, char **argv )
if (rc) if (rc)
log_error ("can't dump ATR: %s\n", gpg_strerror (rc)); log_error ("can't dump ATR: %s\n", gpg_strerror (rc));
rc = app_select_openpgp (slot); appbuf.slot = slot;
rc = app_select_openpgp (&appbuf, NULL, NULL);
if (rc) if (rc)
log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc)); log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc));
else else
@ -159,3 +164,8 @@ main (int argc, char **argv )
void
send_status_info (CTRL ctrl, const char *keyword, ...)
{
/* DUMMY */
}

View File

@ -34,12 +34,12 @@
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#define JNLIB_NEED_LOG_LOGV
#include "scdaemon.h"
#include <ksba.h> #include <ksba.h>
#include <gcrypt.h> #include <gcrypt.h>
#define JNLIB_NEED_LOG_LOGV
#include <assuan.h> /* malloc hooks */ #include <assuan.h> /* malloc hooks */
#include "scdaemon.h"
#include "i18n.h" #include "i18n.h"
#include "sysutils.h" #include "sysutils.h"

View File

@ -76,18 +76,22 @@ struct {
struct server_local_s; struct server_local_s;
struct card_ctx_s; struct card_ctx_s;
struct app_ctx_s;
struct server_control_s { struct server_control_s {
struct server_local_s *server_local; struct server_local_s *server_local;
struct card_ctx_s *card_ctx; struct card_ctx_s *card_ctx;
struct app_ctx_s *app_ctx;
struct { struct {
unsigned char *value; unsigned char *value;
int valuelen; int valuelen;
} in_data; /* helper to store the value we are going to sign */ } in_data; /* helper to store the value we are going to sign */
}; };
typedef struct server_control_s *CTRL; typedef struct server_control_s *CTRL;
typedef struct card_ctx_s *CARD; typedef struct card_ctx_s *CARD;
typedef struct app_ctx_s *APP;
/*-- scdaemon.c --*/ /*-- scdaemon.c --*/
void scd_exit (int rc); void scd_exit (int rc);
@ -95,6 +99,7 @@ void scd_init_default_ctrl (CTRL ctrl);
/*-- command.c --*/ /*-- command.c --*/
void scd_command_handler (int); void scd_command_handler (int);
void send_status_info (CTRL ctrl, const char *keyword, ...);
/*-- card.c --*/ /*-- card.c --*/
int card_open (CARD *rcard); int card_open (CARD *rcard);

View File

@ -1,3 +1,14 @@
2003-06-24 Werner Koch <wk@gnupg.org>
* server.c (gpgsm_status_with_err_code): New.
* verify.c (gpgsm_verify): Use it here instead of the old
tokenizing version.
* verify.c (strtimestamp): Renamed to strtimestamp_r
Adjusted for changes in the libgcrypt API. Some more fixes for the
libgpg-error stuff.
2003-06-04 Werner Koch <wk@gnupg.org> 2003-06-04 Werner Koch <wk@gnupg.org>
* call-agent.c (init_membuf,put_membuf,get_membuf): Removed. * call-agent.c (init_membuf,put_membuf,get_membuf): Removed.

View File

@ -26,15 +26,17 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include <gcrypt.h>
#ifdef HAVE_LOCALE_H #ifdef HAVE_LOCALE_H
#include <locale.h> #include <locale.h>
#endif #endif
#include <assuan.h>
#include "gpgsm.h" #include "gpgsm.h"
#include <gcrypt.h>
#include <assuan.h>
#include "i18n.h" #include "i18n.h"
#include "keydb.h" /* fixme: Move this to import.c */ #include "keydb.h" /* fixme: Move this to import.c */
#include "../common/membuf.h"
static ASSUAN_CONTEXT agent_ctx = NULL; static ASSUAN_CONTEXT agent_ctx = NULL;
static int force_pipe_server = 0; static int force_pipe_server = 0;
@ -54,77 +56,9 @@ struct genkey_parm_s {
struct learn_parm_s { struct learn_parm_s {
int error; int error;
ASSUAN_CONTEXT ctx; ASSUAN_CONTEXT ctx;
struct membuf *data; membuf_t *data;
}; };
struct membuf {
size_t len;
size_t size;
char *buf;
int out_of_core;
};
/* A simple implemnation of a dynamic buffer. Use init_membuf() to
create a buffer, put_membuf to append bytes and get_membuf to
release and return the buffer. Allocation errors are detected but
only returned at the final get_membuf(), this helps not to clutter
the code with out of core checks. */
static void
init_membuf (struct membuf *mb, int initiallen)
{
mb->len = 0;
mb->size = initiallen;
mb->out_of_core = 0;
mb->buf = xtrymalloc (initiallen);
if (!mb->buf)
mb->out_of_core = 1;
}
static void
put_membuf (struct membuf *mb, const void *buf, size_t len)
{
if (mb->out_of_core)
return;
if (mb->len + len >= mb->size)
{
char *p;
mb->size += len + 1024;
p = xtryrealloc (mb->buf, mb->size);
if (!p)
{
mb->out_of_core = 1;
return;
}
mb->buf = p;
}
memcpy (mb->buf + mb->len, buf, len);
mb->len += len;
}
static void *
get_membuf (struct membuf *mb, size_t *len)
{
char *p;
if (mb->out_of_core)
{
xfree (mb->buf);
mb->buf = NULL;
return NULL;
}
p = mb->buf;
*len = mb->len;
mb->buf = NULL;
mb->out_of_core = 1; /* don't allow a reuse */
return p;
}
/* Try to connect to the agent via socket or fork it off and work by /* Try to connect to the agent via socket or fork it off and work by
@ -354,7 +288,7 @@ start_agent (void)
static AssuanError static AssuanError
membuf_data_cb (void *opaque, const void *buffer, size_t length) membuf_data_cb (void *opaque, const void *buffer, size_t length)
{ {
struct membuf *data = opaque; membuf_t *data = opaque;
if (buffer) if (buffer)
put_membuf (data, buffer, length); put_membuf (data, buffer, length);
@ -373,7 +307,7 @@ gpgsm_agent_pksign (const char *keygrip,
{ {
int rc, i; int rc, i;
char *p, line[ASSUAN_LINELENGTH]; char *p, line[ASSUAN_LINELENGTH];
struct membuf data; membuf_t data;
size_t len; size_t len;
*r_buf = NULL; *r_buf = NULL;
@ -448,7 +382,7 @@ gpgsm_agent_pkdecrypt (const char *keygrip,
{ {
int rc; int rc;
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
struct membuf data; membuf_t data;
struct cipher_parm_s cipher_parm; struct cipher_parm_s cipher_parm;
size_t n, len; size_t n, len;
char *buf, *endp; char *buf, *endp;
@ -534,7 +468,7 @@ gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey)
{ {
int rc; int rc;
struct genkey_parm_s gk_parm; struct genkey_parm_s gk_parm;
struct membuf data; membuf_t data;
size_t len; size_t len;
char *buf; char *buf;
@ -710,7 +644,7 @@ learn_cb (void *opaque, const void *buffer, size_t length)
keydb_store_cert (cert, 1, NULL); keydb_store_cert (cert, 1, NULL);
} }
else if (rc) else if (rc)
log_error ("invalid certificate: %s\n", gnupg_strerror (rc)); log_error ("invalid certificate: %s\n", gpg_strerror (rc));
else else
{ {
int existed; int existed;
@ -735,7 +669,7 @@ gpgsm_agent_learn ()
{ {
int rc; int rc;
struct learn_parm_s learn_parm; struct learn_parm_s learn_parm;
struct membuf data; membuf_t data;
size_t len; size_t len;
rc = start_agent (); rc = start_agent ();

View File

@ -28,10 +28,10 @@
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <assuan.h> #include <assuan.h>
#include "gpgsm.h"
#include "i18n.h" #include "i18n.h"
struct membuf { struct membuf {
@ -263,7 +263,7 @@ inq_certificate (void *opaque, const char *line)
err = gpgsm_find_cert (line, &cert); err = gpgsm_find_cert (line, &cert);
if (err) if (err)
{ {
log_error ("certificate not found: %s\n", gnupg_strerror (err)); log_error ("certificate not found: %s\n", gpg_strerror (err));
rc = ASSUAN_Inquire_Error; rc = ASSUAN_Inquire_Error;
} }
else else
@ -533,7 +533,7 @@ run_command_inq_cb (void *opaque, const char *line)
err = gpgsm_find_cert (line, &cert); err = gpgsm_find_cert (line, &cert);
if (err) if (err)
{ {
log_error ("certificate not found: %s\n", gnupg_strerror (err)); log_error ("certificate not found: %s\n", gpg_strerror (err));
rc = ASSUAN_Inquire_Error; rc = ASSUAN_Inquire_Error;
} }
else else

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
@ -302,7 +302,7 @@ find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
log_info (_("number of issuers matching: %d\n"), count); log_info (_("number of issuers matching: %d\n"), count);
if (rc) if (rc)
{ {
log_error ("external key lookup failed: %s\n", gnupg_strerror (rc)); log_error ("external key lookup failed: %s\n", gpg_strerror (rc));
rc = -1; rc = -1;
} }
else if (!count) else if (!count)
@ -585,7 +585,7 @@ gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
else else
{ {
log_error (_("checking the trust list failed: %s\n"), log_error (_("checking the trust list failed: %s\n"),
gnupg_strerror (rc)); gpg_strerror (rc));
} }
break; /* okay, a self-signed certicate is an end-point */ break; /* okay, a self-signed certicate is an end-point */
@ -655,8 +655,10 @@ gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
rc = gpgsm_cert_use_cert_p (issuer_cert); rc = gpgsm_cert_use_cert_p (issuer_cert);
if (rc) if (rc)
{ {
char numbuf[50];
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage", gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
gnupg_error_token (rc), NULL); numbuf, NULL);
rc = 0; rc = 0;
} }

View File

@ -27,17 +27,17 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
static int static int
do_encode_md (GCRY_MD_HD md, int algo, unsigned int nbits, do_encode_md (gcry_md_hd_t md, int algo, unsigned int nbits,
GCRY_MPI *r_val) gcry_mpi_t *r_val)
{ {
int nframe = (nbits+7) / 8; int nframe = (nbits+7) / 8;
byte *frame; byte *frame;
@ -104,12 +104,12 @@ int
gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert) gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
{ {
const char *algoid; const char *algoid;
GCRY_MD_HD md; gcry_md_hd_t md;
int rc, algo; int rc, algo;
GCRY_MPI frame; gcry_mpi_t frame;
KsbaSexp p; KsbaSexp p;
size_t n; size_t n;
GCRY_SEXP s_sig, s_hash, s_pkey; gcry_sexp_t s_sig, s_hash, s_pkey;
algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert))); algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert)));
if (!algo) if (!algo)
@ -117,11 +117,11 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?"); log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
return gpg_error (GPG_ERR_GENERAL); return gpg_error (GPG_ERR_GENERAL);
} }
md = gcry_md_open (algo, 0); rc = gcry_md_open (&md, algo, 0);
if (!md) if (rc)
{ {
log_error ("md_open failed: %s\n", gcry_strerror (-1)); log_error ("md_open failed: %s\n", gpg_strerror (rc));
return gpg_error (GPG_ERR_GENERAL); return rc;
} }
if (DBG_HASHING) if (DBG_HASHING)
gcry_md_start_debug (md, "hash.cert"); gcry_md_start_debug (md, "hash.cert");
@ -157,9 +157,9 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
ksba_free (p); ksba_free (p);
if (rc) if (rc)
{ {
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
gcry_md_close (md); gcry_md_close (md);
return map_gcry_err (rc); return rc;
} }
p = ksba_cert_get_public_key (issuer_cert); p = ksba_cert_get_public_key (issuer_cert);
@ -176,10 +176,10 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
ksba_free (p); ksba_free (p);
if (rc) if (rc)
{ {
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
gcry_md_close (md); gcry_md_close (md);
gcry_sexp_release (s_sig); gcry_sexp_release (s_sig);
return map_gcry_err (rc); return rc;
} }
rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame); rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame);
@ -199,24 +199,24 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
rc = gcry_pk_verify (s_sig, s_hash, s_pkey); rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
if (DBG_CRYPTO) if (DBG_CRYPTO)
log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc)); log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
gcry_md_close (md); gcry_md_close (md);
gcry_sexp_release (s_sig); gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash); gcry_sexp_release (s_hash);
gcry_sexp_release (s_pkey); gcry_sexp_release (s_pkey);
return map_gcry_err (rc); return rc;
} }
int int
gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval, gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
GCRY_MD_HD md, int algo) gcry_md_hd_t md, int algo)
{ {
int rc; int rc;
KsbaSexp p; KsbaSexp p;
GCRY_MPI frame; gcry_mpi_t frame;
GCRY_SEXP s_sig, s_hash, s_pkey; gcry_sexp_t s_sig, s_hash, s_pkey;
size_t n; size_t n;
n = gcry_sexp_canon_len (sigval, 0, NULL, NULL); n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
@ -228,8 +228,8 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n); rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n);
if (rc) if (rc)
{ {
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
return map_gcry_err (rc); return rc;
} }
p = ksba_cert_get_public_key (cert); p = ksba_cert_get_public_key (cert);
@ -248,9 +248,9 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
ksba_free (p); ksba_free (p);
if (rc) if (rc)
{ {
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
gcry_sexp_release (s_sig); gcry_sexp_release (s_sig);
return map_gcry_err (rc); return rc;
} }
@ -268,17 +268,17 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
rc = gcry_pk_verify (s_sig, s_hash, s_pkey); rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
if (DBG_CRYPTO) if (DBG_CRYPTO)
log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc)); log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
gcry_sexp_release (s_sig); gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash); gcry_sexp_release (s_hash);
gcry_sexp_release (s_pkey); gcry_sexp_release (s_pkey);
return map_gcry_err (rc); return rc;
} }
int int
gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, gpgsm_create_cms_signature (KsbaCert cert, gcry_md_hd_t md, int mdalgo,
char **r_sigval) char **r_sigval)
{ {
int rc; int rc;

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"

View File

@ -96,10 +96,10 @@ EOF
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
@ -489,7 +489,7 @@ proc_parameters (struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
{ {
r = get_parameter (para, pKEYTYPE); r = get_parameter (para, pKEYTYPE);
log_error ("line %d: key generation failed: %s\n", log_error ("line %d: key generation failed: %s\n",
r->lnr, gnupg_strerror (rc)); r->lnr, gpg_strerror (rc));
return rc; return rc;
} }
@ -508,7 +508,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
{ {
KsbaCertreq cr; KsbaCertreq cr;
KsbaError err; KsbaError err;
GCRY_MD_HD md; gcry_md_hd_t md;
KsbaStopReason stopreason; KsbaStopReason stopreason;
int rc = 0; int rc = 0;
const char *s; const char *s;
@ -517,11 +517,10 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
if (!cr) if (!cr)
return gpg_error (GPG_ERR_ENOMEM); return gpg_error (GPG_ERR_ENOMEM);
md = gcry_md_open (GCRY_MD_SHA1, 0); rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
if (!md) if (rc)
{ {
log_error ("md_open failed: %s\n", gcry_strerror (-1)); log_error ("md_open failed: %s\n", gpg_strerror (rc));
rc = map_gcry_err (gcry_errno ());
goto leave; goto leave;
} }
if (DBG_HASHING) if (DBG_HASHING)
@ -585,7 +584,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
} }
if (stopreason == KSBA_SR_NEED_SIG) if (stopreason == KSBA_SR_NEED_SIG)
{ {
GCRY_SEXP s_pkey; gcry_sexp_t s_pkey;
size_t n; size_t n;
unsigned char grip[20], hexgrip[41]; unsigned char grip[20], hexgrip[41];
char *sigval; char *sigval;
@ -601,8 +600,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
rc = gcry_sexp_sscan (&s_pkey, NULL, public, n); rc = gcry_sexp_sscan (&s_pkey, NULL, public, n);
if (rc) if (rc)
{ {
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
rc = map_gcry_err (rc);
goto leave; goto leave;
} }
if ( !gcry_pk_get_keygrip (s_pkey, grip) ) if ( !gcry_pk_get_keygrip (s_pkey, grip) )
@ -623,7 +621,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
&sigval, &siglen); &sigval, &siglen);
if (rc) if (rc)
{ {
log_error ("signing failed: %s\n", gnupg_strerror (rc)); log_error ("signing failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -671,7 +669,7 @@ gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp)
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
if (rc) if (rc)
{ {
log_error ("can't create writer: %s\n", gnupg_strerror (rc)); log_error ("can't create writer: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -679,14 +677,14 @@ gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp)
if (rc) if (rc)
{ {
log_error ("error creating certificate request: %s\n", log_error ("error creating certificate request: %s\n",
gnupg_strerror (rc)); gpg_strerror (rc));
goto leave; goto leave;
} }
rc = gpgsm_finish_writer (b64writer); rc = gpgsm_finish_writer (b64writer);
if (rc) if (rc)
{ {
log_error ("write failed: %s\n", gnupg_strerror (rc)); log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
@ -38,7 +38,7 @@ struct decrypt_filter_parm_s {
int algo; int algo;
int mode; int mode;
int blklen; int blklen;
GCRY_CIPHER_HD hd; gcry_cipher_hd_t hd;
char iv[16]; char iv[16];
size_t ivlen; size_t ivlen;
int any_data; /* dod we push anything through the filter at all? */ int any_data; /* dod we push anything through the filter at all? */
@ -65,7 +65,7 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
&seskey, &seskeylen); &seskey, &seskeylen);
if (rc) if (rc)
{ {
log_error ("error decrypting session key: %s\n", gnupg_strerror (rc)); log_error ("error decrypting session key: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -113,17 +113,15 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
if (DBG_CRYPTO) if (DBG_CRYPTO)
log_printhex ("session key:", seskey+n, seskeylen-n); log_printhex ("session key:", seskey+n, seskeylen-n);
parm->hd = gcry_cipher_open (parm->algo, parm->mode, 0); rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
if (!parm->hd) if (rc)
{ {
rc = gcry_errno (); log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
log_error ("error creating decryptor: %s\n", gcry_strerror (rc));
rc = map_gcry_err (rc);
goto leave; goto leave;
} }
rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n); rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n);
if (rc == GCRYERR_WEAK_KEY) if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
{ {
log_info (_("WARNING: message was encrypted with " log_info (_("WARNING: message was encrypted with "
"a weak key in the symmetric cipher.\n")); "a weak key in the symmetric cipher.\n"));
@ -131,8 +129,7 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
} }
if (rc) if (rc)
{ {
log_error("key setup failed: %s\n", gcry_strerror(rc) ); log_error("key setup failed: %s\n", gpg_strerror(rc) );
rc = map_gcry_err (rc);
goto leave; goto leave;
} }
@ -277,14 +274,14 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, &reader); rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, &reader);
if (rc) if (rc)
{ {
log_error ("can't create reader: %s\n", gnupg_strerror (rc)); log_error ("can't create reader: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
if (rc) if (rc)
{ {
log_error ("can't create writer: %s\n", gnupg_strerror (rc)); log_error ("can't create writer: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -334,8 +331,13 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
else if (!algoid) else if (!algoid)
log_info (_("(this does not seem to be an encrypted" log_info (_("(this does not seem to be an encrypted"
" message)\n")); " message)\n"));
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm", {
gnupg_error_token (rc), algoid?algoid:"?", NULL); char numbuf[50];
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
numbuf, algoid?algoid:"?", NULL);
}
goto leave; goto leave;
} }
dfparm.algo = algo; dfparm.algo = algo;
@ -383,14 +385,14 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
if (rc) if (rc)
{ {
log_error ("failed to find the certificate: %s\n", log_error ("failed to find the certificate: %s\n",
gnupg_strerror(rc)); gpg_strerror(rc));
goto oops; goto oops;
} }
rc = keydb_get_cert (kh, &cert); rc = keydb_get_cert (kh, &cert);
if (rc) if (rc)
{ {
log_error ("failed to get cert: %s\n", gnupg_strerror (rc)); log_error ("failed to get cert: %s\n", gpg_strerror (rc));
goto oops; goto oops;
} }
/* Just in case there is a problem with the own /* Just in case there is a problem with the own
@ -399,8 +401,10 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
rc = gpgsm_cert_use_decrypt_p (cert); rc = gpgsm_cert_use_decrypt_p (cert);
if (rc) if (rc)
{ {
char numbuf[50];
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage", gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
gnupg_error_token (rc), NULL); numbuf, NULL);
rc = 0; rc = 0;
} }
@ -424,7 +428,7 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
if (rc) if (rc)
{ {
log_debug ("decrypting session key failed: %s\n", log_debug ("decrypting session key failed: %s\n",
gnupg_strerror (rc)); gpg_strerror (rc));
} }
else else
{ /* setup the bulk decrypter */ { /* setup the bulk decrypter */
@ -479,7 +483,7 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
rc = gpgsm_finish_writer (b64writer); rc = gpgsm_finish_writer (b64writer);
if (rc) if (rc)
{ {
log_error ("write failed: %s\n", gnupg_strerror (rc)); log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL); gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
@ -49,7 +49,7 @@ delete_one (CTRL ctrl, const char *username)
if (rc) if (rc)
{ {
log_error (_("certificate `%s' not found: %s\n"), log_error (_("certificate `%s' not found: %s\n"),
username, gnupg_strerror (rc)); username, gpg_strerror (rc));
gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL); gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL);
goto leave; goto leave;
} }
@ -100,7 +100,7 @@ delete_one (CTRL ctrl, const char *username)
if (rc == -1) if (rc == -1)
rc = gpg_error (GPG_ERR_NO_PUBKEY); rc = gpg_error (GPG_ERR_NO_PUBKEY);
log_error (_("certificate `%s' not found: %s\n"), log_error (_("certificate `%s' not found: %s\n"),
username, gnupg_strerror (rc)); username, gpg_strerror (rc));
gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL); gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL);
goto leave; goto leave;
} }
@ -113,7 +113,7 @@ delete_one (CTRL ctrl, const char *username)
if (rc) if (rc)
{ {
log_error ("problem re-searching certificate: %s\n", log_error ("problem re-searching certificate: %s\n",
gnupg_strerror (rc)); gpg_strerror (rc));
goto leave; goto leave;
} }
@ -156,7 +156,7 @@ gpgsm_delete (CTRL ctrl, STRLIST names)
if (rc) if (rc)
{ {
log_error (_("deleting certificate \"%s\" failed: %s\n"), log_error (_("deleting certificate \"%s\" failed: %s\n"),
names->d, gnupg_strerror (rc) ); names->d, gpg_strerror (rc) );
return rc; return rc;
} }
} }

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
@ -38,7 +38,7 @@
struct dek_s { struct dek_s {
const char *algoid; const char *algoid;
int algo; int algo;
GCRY_CIPHER_HD chd; gcry_cipher_hd_t chd;
char key[32]; char key[32];
int keylen; int keylen;
char iv[32]; char iv[32];
@ -89,37 +89,37 @@ init_dek (DEK dek)
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
} }
dek->chd = gcry_cipher_open (dek->algo, mode, GCRY_CIPHER_SECURE); rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
if (!dek->chd) if (rc)
{ {
log_error ("failed to create cipher context: %s\n", gcry_strerror (-1)); log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
return gpg_error (GPG_ERR_GENERAL); return rc;
} }
for (i=0; i < 8; i++) for (i=0; i < 8; i++)
{ {
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen); rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen);
if (rc != GCRYERR_WEAK_KEY) if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
break; break;
log_info(_("weak key created - retrying\n") ); log_info(_("weak key created - retrying\n") );
} }
if (rc) if (rc)
{ {
log_error ("failed to set the key: %s\n", gcry_strerror (rc)); log_error ("failed to set the key: %s\n", gpg_strerror (rc));
gcry_cipher_close (dek->chd); gcry_cipher_close (dek->chd);
dek->chd = NULL; dek->chd = NULL;
return map_gcry_err (rc); return rc;
} }
gcry_randomize (dek->iv, dek->ivlen, GCRY_STRONG_RANDOM); gcry_randomize (dek->iv, dek->ivlen, GCRY_STRONG_RANDOM);
rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen); rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen);
if (rc) if (rc)
{ {
log_error ("failed to set the IV: %s\n", gcry_strerror (rc)); log_error ("failed to set the IV: %s\n", gpg_strerror (rc));
gcry_cipher_close (dek->chd); gcry_cipher_close (dek->chd);
dek->chd = NULL; dek->chd = NULL;
return map_gcry_err (rc); return rc;
} }
return 0; return 0;
@ -129,14 +129,14 @@ init_dek (DEK dek)
/* Encode the session key. NBITS is the number of bits which should be /* Encode the session key. NBITS is the number of bits which should be
used for packing the session key. returns: An mpi with the session used for packing the session key. returns: An mpi with the session
key (caller must free) */ key (caller must free) */
static GCRY_MPI static gcry_mpi_t
encode_session_key (DEK dek, unsigned int nbits) encode_session_key (DEK dek, unsigned int nbits)
{ {
int nframe = (nbits+7) / 8; int nframe = (nbits+7) / 8;
byte *p; byte *p;
byte *frame; byte *frame;
int i,n; int i,n;
MPI a; gcry_mpi_t a;
if (dek->keylen + 7 > nframe || !nframe) if (dek->keylen + 7 > nframe || !nframe)
log_bug ("can't encode a %d bit key in a %d bits frame\n", log_bug ("can't encode a %d bit key in a %d bits frame\n",
@ -206,7 +206,7 @@ encode_session_key (DEK dek, unsigned int nbits)
static int static int
encrypt_dek (const DEK dek, KsbaCert cert, char **encval) encrypt_dek (const DEK dek, KsbaCert cert, char **encval)
{ {
GCRY_SEXP s_ciph, s_data, s_pkey; gcry_sexp_t s_ciph, s_data, s_pkey;
int rc; int rc;
KsbaSexp buf; KsbaSexp buf;
size_t len; size_t len;
@ -230,14 +230,14 @@ encrypt_dek (const DEK dek, KsbaCert cert, char **encval)
xfree (buf); buf = NULL; xfree (buf); buf = NULL;
if (rc) if (rc)
{ {
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
return map_gcry_err (rc); return rc;
} }
/* put the encoded cleartext into a simple list */ /* put the encoded cleartext into a simple list */
{ {
/* fixme: actually the pkcs-1 encoding should go into libgcrypt */ /* fixme: actually the pkcs-1 encoding should go into libgcrypt */
GCRY_MPI data = encode_session_key (dek, gcry_pk_get_nbits (s_pkey)); gcry_mpi_t data = encode_session_key (dek, gcry_pk_get_nbits (s_pkey));
if (!data) if (!data)
{ {
gcry_mpi_release (data); gcry_mpi_release (data);
@ -404,7 +404,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
if (rc) if (rc)
{ {
log_error ("can't create writer: %s\n", gnupg_strerror (rc)); log_error ("can't create writer: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -449,7 +449,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
if (rc) if (rc)
{ {
log_error ("failed to create the session key: %s\n", log_error ("failed to create the session key: %s\n",
gnupg_strerror (rc)); gpg_strerror (rc));
goto leave; goto leave;
} }
@ -482,7 +482,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
if (rc) if (rc)
{ {
log_error ("encryption failed for recipient no. %d: %s\n", log_error ("encryption failed for recipient no. %d: %s\n",
recpno, gnupg_strerror (rc)); recpno, gpg_strerror (rc));
goto leave; goto leave;
} }
@ -532,7 +532,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
rc = gpgsm_finish_writer (b64writer); rc = gpgsm_finish_writer (b64writer);
if (rc) if (rc)
{ {
log_error ("write failed: %s\n", gnupg_strerror (rc)); log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
log_info ("encrypted data created\n"); log_info ("encrypted data created\n");

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
static void print_short_info (KsbaCert cert, FILE *fp); static void print_short_info (KsbaCert cert, FILE *fp);
@ -85,7 +85,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
if (rc) if (rc)
{ {
log_error ("key `%s' not found: %s\n", log_error ("key `%s' not found: %s\n",
sl->d, gnupg_strerror (rc)); sl->d, gpg_strerror (rc));
rc = 0; rc = 0;
} }
else else
@ -121,7 +121,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
rc = keydb_get_cert (hd, &cert); rc = keydb_get_cert (hd, &cert);
if (rc) if (rc)
{ {
log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc)); log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -147,7 +147,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer); rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer);
if (rc) if (rc)
{ {
log_error ("can't create writer: %s\n", gnupg_strerror (rc)); log_error ("can't create writer: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
} }
@ -176,7 +176,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
cert = NULL; cert = NULL;
} }
if (rc && rc != -1) if (rc && rc != -1)
log_error ("keydb_search failed: %s\n", gnupg_strerror (rc)); log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
else if (b64writer) else if (b64writer)
{ {
rc = gpgsm_finish_writer (b64writer); rc = gpgsm_finish_writer (b64writer);

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h" #include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
/* Return the fingerprint of the certificate (we can't put this into /* Return the fingerprint of the certificate (we can't put this into
libksba because we need libgcrypt support). The caller must libksba because we need libgcrypt support). The caller must
@ -45,7 +45,7 @@
char * char *
gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len) gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len)
{ {
GCRY_MD_HD md; gcry_md_hd_t md;
int rc, len; int rc, len;
if (!algo) if (!algo)
@ -59,10 +59,10 @@ gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len)
if (r_len) if (r_len)
*r_len = len; *r_len = len;
md = gcry_md_open (algo, 0); rc = gcry_md_open (&md, algo, 0);
if (!md) if (rc)
{ {
log_error ("md_open failed: %s\n", gcry_strerror (-1)); log_error ("md_open failed: %s\n", gpg_strerror (rc));
memset (array, 0xff, len); /* better return an invalid fpr than NULL */ memset (array, 0xff, len); /* better return an invalid fpr than NULL */
return array; return array;
} }
@ -143,7 +143,7 @@ gpgsm_get_short_fingerprint (KsbaCert cert)
char * char *
gpgsm_get_keygrip (KsbaCert cert, char *array) gpgsm_get_keygrip (KsbaCert cert, char *array)
{ {
GCRY_SEXP s_pkey; gcry_sexp_t s_pkey;
int rc; int rc;
KsbaSexp p; KsbaSexp p;
size_t n; size_t n;
@ -164,7 +164,7 @@ gpgsm_get_keygrip (KsbaCert cert, char *array)
xfree (p); xfree (p);
if (rc) if (rc)
{ {
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
return NULL; return NULL;
} }
array = gcry_pk_get_keygrip (s_pkey, array); array = gcry_pk_get_keygrip (s_pkey, array);

View File

@ -27,10 +27,10 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <assuan.h> /* malloc hooks */ #include <assuan.h> /* malloc hooks */
#include "gpgsm.h"
#include "../kbx/keybox.h" /* malloc hooks */ #include "../kbx/keybox.h" /* malloc hooks */
#include "i18n.h" #include "i18n.h"
#include "keydb.h" #include "keydb.h"
@ -1095,7 +1095,7 @@ main ( int argc, char **argv)
if (rc) if (rc)
{ {
log_error (_("can't sign using `%s': %s\n"), log_error (_("can't sign using `%s': %s\n"),
sl->d, gnupg_strerror (rc)); sl->d, gpg_strerror (rc));
gpgsm_status2 (&ctrl, STATUS_INV_RECP, gpgsm_status2 (&ctrl, STATUS_INV_RECP,
gpg_err_code (rc) == -1? "1": gpg_err_code (rc) == -1? "1":
gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1":
@ -1117,7 +1117,7 @@ main ( int argc, char **argv)
if (rc) if (rc)
{ {
log_error (_("can't encrypt to `%s': %s\n"), log_error (_("can't encrypt to `%s': %s\n"),
sl->d, gnupg_strerror (rc)); sl->d, gpg_strerror (rc));
gpgsm_status2 (&ctrl, STATUS_INV_RECP, gpgsm_status2 (&ctrl, STATUS_INV_RECP,
gpg_err_code (rc) == -1? "1": gpg_err_code (rc) == -1? "1":
gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1":

View File

@ -152,6 +152,8 @@ void gpgsm_init_default_ctrl (struct server_control_s *ctrl);
void gpgsm_server (void); void gpgsm_server (void);
void gpgsm_status (CTRL ctrl, int no, const char *text); void gpgsm_status (CTRL ctrl, int no, const char *text);
void gpgsm_status2 (CTRL ctrl, int no, ...); void gpgsm_status2 (CTRL ctrl, int no, ...);
void gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text,
gpg_err_code_t ec);
/*-- fingerprint --*/ /*-- fingerprint --*/
char *gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len); char *gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len);
@ -188,9 +190,9 @@ void gpgsm_dump_string (const char *string);
/*-- certcheck.c --*/ /*-- certcheck.c --*/
int gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert); int gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert);
int gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval, int gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
GCRY_MD_HD md, int hash_algo); gcry_md_hd_t md, int hash_algo);
/* fixme: move create functions to another file */ /* fixme: move create functions to another file */
int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, int gpgsm_create_cms_signature (KsbaCert cert, gcry_md_hd_t md, int mdalgo,
char **r_sigval); char **r_sigval);

View File

@ -27,10 +27,10 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"

View File

@ -231,7 +231,7 @@ keydb_add_resource (const char *url, int force, int secret)
leave: leave:
if (rc) if (rc)
log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc)); log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc));
else if (secret) else if (secret)
any_secret = 1; any_secret = 1;
else else
@ -1255,14 +1255,14 @@ keydb_store_cert (KsbaCert cert, int ephemeral, int *existed)
return 0; /* okay */ return 0; /* okay */
} }
log_error (_("problem looking for existing certificate: %s\n"), log_error (_("problem looking for existing certificate: %s\n"),
gnupg_strerror (rc)); gpg_strerror (rc));
return rc; return rc;
} }
rc = keydb_locate_writable (kh, 0); rc = keydb_locate_writable (kh, 0);
if (rc) if (rc)
{ {
log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc)); log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
keydb_release (kh); keydb_release (kh);
return rc; return rc;
} }
@ -1270,7 +1270,7 @@ keydb_store_cert (KsbaCert cert, int ephemeral, int *existed)
rc = keydb_insert_cert (kh, cert); rc = keydb_insert_cert (kh, cert);
if (rc) if (rc)
{ {
log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc)); log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
keydb_release (kh); keydb_release (kh);
return rc; return rc;
} }

View File

@ -1,5 +1,5 @@
/* keylist.c /* keylist.c
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -27,10 +27,11 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
@ -460,7 +461,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
if (rc) if (rc)
{ {
log_error ("key `%s' not found: %s\n", log_error ("key `%s' not found: %s\n",
sl->d, gnupg_strerror (rc)); sl->d, gpg_strerror (rc));
rc = 0; rc = 0;
} }
else else
@ -535,7 +536,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
cert = NULL; cert = NULL;
} }
if (rc && rc != -1) if (rc && rc != -1)
log_error ("keydb_search failed: %s\n", gnupg_strerror (rc)); log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
leave: leave:
ksba_cert_release (cert); ksba_cert_release (cert);

View File

@ -991,7 +991,18 @@ gpgsm_status (CTRL ctrl, int no, const char *text)
gpgsm_status2 (ctrl, no, text, NULL); gpgsm_status2 (ctrl, no, text, NULL);
} }
void
gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text,
gpg_err_code_t ec)
{
char buf[30];
sprintf (buf, "%u", (unsigned int)ec);
if (text)
gpgsm_status2 (ctrl, no, text, buf, NULL);
else
gpgsm_status2 (ctrl, no, buf, NULL);
}
#if 0 #if 0
/* /*

View File

@ -27,16 +27,16 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
static void static void
hash_data (int fd, GCRY_MD_HD md) hash_data (int fd, gcry_md_hd_t md)
{ {
FILE *fp; FILE *fp;
char buffer[4096]; char buffer[4096];
@ -61,7 +61,7 @@ hash_data (int fd, GCRY_MD_HD md)
} }
static int static int
hash_and_copy_data (int fd, GCRY_MD_HD md, KsbaWriter writer) hash_and_copy_data (int fd, gcry_md_hd_t md, KsbaWriter writer)
{ {
KsbaError err; KsbaError err;
FILE *fp; FILE *fp;
@ -203,7 +203,7 @@ get_default_signer (void)
rc = keydb_classify_name (opt.local_user, &desc); rc = keydb_classify_name (opt.local_user, &desc);
if (rc) if (rc)
{ {
log_error ("failed to find default signer: %s\n", gnupg_strerror (rc)); log_error ("failed to find default signer: %s\n", gpg_strerror (rc));
return NULL; return NULL;
} }
@ -302,7 +302,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
KsbaCMS cms = NULL; KsbaCMS cms = NULL;
KsbaStopReason stopreason; KsbaStopReason stopreason;
KEYDB_HANDLE kh = NULL; KEYDB_HANDLE kh = NULL;
GCRY_MD_HD data_md = NULL; gcry_md_hd_t data_md = NULL;
int signer; int signer;
const char *algoid; const char *algoid;
int algo; int algo;
@ -322,7 +322,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
if (rc) if (rc)
{ {
log_error ("can't create writer: %s\n", gnupg_strerror (rc)); log_error ("can't create writer: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -394,7 +394,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
if (rc) if (rc)
{ {
log_error ("failed to store list of certificates: %s\n", log_error ("failed to store list of certificates: %s\n",
gnupg_strerror(rc)); gpg_strerror(rc));
goto leave; goto leave;
} }
/* Set the hash algorithm we are going to use */ /* Set the hash algorithm we are going to use */
@ -409,11 +409,10 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
} }
/* Prepare hashing (actually we are figuring out what we have set above)*/ /* Prepare hashing (actually we are figuring out what we have set above)*/
data_md = gcry_md_open (0, 0); rc = gcry_md_open (&data_md, 0, 0);
if (!data_md) if (rc)
{ {
rc = map_gcry_err (gcry_errno()); log_error ("md_open failed: %s\n", gpg_strerror (rc));
log_error ("md_open failed: %s\n", gcry_strerror (-1));
goto leave; goto leave;
} }
if (DBG_HASHING) if (DBG_HASHING)
@ -524,18 +523,17 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
} }
else if (stopreason == KSBA_SR_NEED_SIG) else if (stopreason == KSBA_SR_NEED_SIG)
{ /* calculate the signature for all signers */ { /* calculate the signature for all signers */
GCRY_MD_HD md; gcry_md_hd_t md;
algo = GCRY_MD_SHA1; algo = GCRY_MD_SHA1;
md = gcry_md_open (algo, 0); rc = gcry_md_open (&md, algo, 0);
if (DBG_HASHING) if (rc)
gcry_md_start_debug (md, "sign.attr");
if (!md)
{ {
log_error ("md_open failed: %s\n", gcry_strerror (-1)); log_error ("md_open failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
if (DBG_HASHING)
gcry_md_start_debug (md, "sign.attr");
ksba_cms_set_hash_function (cms, HASH_FNC, md); ksba_cms_set_hash_function (cms, HASH_FNC, md);
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
{ {
@ -605,7 +603,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
rc = gpgsm_finish_writer (b64writer); rc = gpgsm_finish_writer (b64writer);
if (rc) if (rc)
{ {
log_error ("write failed: %s\n", gnupg_strerror (rc)); log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }

View File

@ -27,16 +27,15 @@
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h> #include <gcrypt.h>
#include <ksba.h> #include <ksba.h>
#include "gpgsm.h"
#include "keydb.h" #include "keydb.h"
#include "i18n.h" #include "i18n.h"
/* fixme: Move this to jnlib */
static char * static char *
strtimestamp (time_t atime) strtimestamp_r (time_t atime)
{ {
char *buffer = xmalloc (15); char *buffer = xmalloc (15);
@ -59,7 +58,7 @@ strtimestamp (time_t atime)
/* Hash the data for a detached signature */ /* Hash the data for a detached signature */
static void static void
hash_data (int fd, GCRY_MD_HD md) hash_data (int fd, gcry_md_hd_t md)
{ {
FILE *fp; FILE *fp;
char buffer[4096]; char buffer[4096];
@ -102,7 +101,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
KsbaStopReason stopreason; KsbaStopReason stopreason;
KsbaCert cert; KsbaCert cert;
KEYDB_HANDLE kh; KEYDB_HANDLE kh;
GCRY_MD_HD data_md = NULL; gcry_md_hd_t data_md = NULL;
int signer; int signer;
const char *algoid; const char *algoid;
int algo; int algo;
@ -130,7 +129,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader); rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader);
if (rc) if (rc)
{ {
log_error ("can't create reader: %s\n", gnupg_strerror (rc)); log_error ("can't create reader: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
@ -139,7 +138,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
if (rc) if (rc)
{ {
log_error ("can't create writer: %s\n", gnupg_strerror (rc)); log_error ("can't create writer: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
} }
@ -160,11 +159,10 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
goto leave; goto leave;
} }
data_md = gcry_md_open (0, 0); rc = gcry_md_open (&data_md, 0, 0);
if (!data_md) if (rc)
{ {
rc = map_gcry_err (gcry_errno()); log_error ("md_open failed: %s\n", gpg_strerror (rc));
log_error ("md_open failed: %s\n", gcry_strerror (-1));
goto leave; goto leave;
} }
if (DBG_HASHING) if (DBG_HASHING)
@ -225,7 +223,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
rc = gpgsm_finish_writer (b64writer); rc = gpgsm_finish_writer (b64writer);
if (rc) if (rc)
{ {
log_error ("write failed: %s\n", gnupg_strerror (rc)); log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave; goto leave;
} }
} }
@ -364,7 +362,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
} }
else else
log_error ("failed to find the certificate: %s\n", log_error ("failed to find the certificate: %s\n",
gnupg_strerror(rc)); gpg_strerror(rc));
{ {
char numbuf[50]; char numbuf[50];
sprintf (numbuf, "%d", rc); sprintf (numbuf, "%d", rc);
@ -380,7 +378,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
rc = keydb_get_cert (kh, &cert); rc = keydb_get_cert (kh, &cert);
if (rc) if (rc)
{ {
log_error ("failed to get cert: %s\n", gnupg_strerror (rc)); log_error ("failed to get cert: %s\n", gpg_strerror (rc));
goto next_signer; goto next_signer;
} }
@ -395,7 +393,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
if (msgdigest) if (msgdigest)
{ /* Signed attributes are available. */ { /* Signed attributes are available. */
GCRY_MD_HD md; gcry_md_hd_t md;
unsigned char *s; unsigned char *s;
/* check that the message digest in the signed attributes /* check that the message digest in the signed attributes
@ -415,10 +413,10 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
goto next_signer; goto next_signer;
} }
md = gcry_md_open (algo, 0); rc = gcry_md_open (&md, algo, 0);
if (!md) if (rc)
{ {
log_error ("md_open failed: %s\n", gcry_strerror (-1)); log_error ("md_open failed: %s\n", gpg_strerror (rc));
goto next_signer; goto next_signer;
} }
if (DBG_HASHING) if (DBG_HASHING)
@ -445,7 +443,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
{ {
char *fpr; char *fpr;
log_error ("invalid signature: %s\n", gnupg_strerror (rc)); log_error ("invalid signature: %s\n", gpg_strerror (rc));
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
gpgsm_status (ctrl, STATUS_BADSIG, fpr); gpgsm_status (ctrl, STATUS_BADSIG, fpr);
xfree (fpr); xfree (fpr);
@ -454,8 +452,8 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/ rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
if (rc) if (rc)
{ {
gpgsm_status2 (ctrl, STATUS_ERROR, "verify.keyusage", gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
gnupg_error_token (rc), NULL); gpg_err_code (rc));
rc = 0; rc = 0;
} }
@ -474,7 +472,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
char *buf, *fpr, *tstr; char *buf, *fpr, *tstr;
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
tstr = strtimestamp (sigtime); tstr = strtimestamp_r (sigtime);
buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120); buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120);
sprintf (buf, "%s %s %lu %lu", fpr, tstr, sprintf (buf, "%s %s %lu %lu", fpr, tstr,
(unsigned long)sigtime, (unsigned long)keyexptime ); (unsigned long)sigtime, (unsigned long)keyexptime );
@ -486,14 +484,16 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
if (rc) /* of validate_chain */ if (rc) /* of validate_chain */
{ {
log_error ("invalid certification chain: %s\n", gnupg_strerror (rc)); log_error ("invalid certification chain: %s\n", gpg_strerror (rc));
if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN
|| gpg_err_code (rc) == GPG_ERR_BAD_CERT || gpg_err_code (rc) == GPG_ERR_BAD_CERT
|| gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT
|| gpg_err_code (rc) == GPG_ERR_CERT_REVOKED) || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED)
gpgsm_status (ctrl, STATUS_TRUST_NEVER, gnupg_error_token (rc)); gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL,
gpg_err_code (rc));
else else
gpgsm_status (ctrl, STATUS_TRUST_UNDEFINED, gnupg_error_token (rc)); gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL,
gpg_err_code (rc));
goto next_signer; goto next_signer;
} }