1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-23 10:29:58 +01:00

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>
Renamed error codes from INVALID to INV and removed _ERROR suffixes.

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -130,8 +130,9 @@ void start_command_handler (int, int);
/*-- findkey.c --*/
int agent_write_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force);
GCRY_SEXP agent_key_from_file (CTRL ctrl, const unsigned char *grip,
unsigned char **shadow_info, int ignore_cache);
gcry_sexp_t agent_key_from_file (CTRL ctrl, const unsigned char *grip,
unsigned char **shadow_info,
int ignore_cache);
int agent_key_available (const unsigned char *grip);
/*-- query.c --*/
@ -160,7 +161,7 @@ int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
/*-- genkey.c --*/
int agent_genkey (CTRL ctrl,
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 --*/
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 *shadow_info,
char **r_buf, size_t *r_len);
int divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context);
/*-- call-scd.c --*/
int agent_card_learn (void (*kpinfo_cb)(void*, const char *),
void *kpinfo_cb_arg,
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_pksign (const char *keyid,
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);
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_scd (const char *cmdline,
int (*getpin_cb)(void *, const char *, char*, size_t),
void *getpin_cb_arg, void *assuan_context);
/*-- learncard.c --*/

View File

@ -57,6 +57,8 @@ struct learn_parm_s {
void *kpinfo_cb_arg;
void (*certinfo_cb)(void*, const char *);
void *certinfo_cb_arg;
void (*sinfo_cb)(void*, const char *, size_t, const char *);
void *sinfo_cb_arg;
};
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);
}
else
log_debug ("learn_status_cb: ignoring `%.*s'\n", keywordlen, keyword);
else if (keywordlen && *line)
{
parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
}
return 0;
}
@ -257,7 +261,9 @@ int
agent_card_learn (void (*kpinfo_cb)(void*, const char *),
void *kpinfo_cb_arg,
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;
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.certinfo_cb = certinfo_cb;
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",
NULL, NULL, NULL, NULL,
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
operation might have failed due to a missing RESET. Hmmm, I feel
this is really SCdaemon's duty */
rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return unlock_scd (map_assuan_err (rc));
/* rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); */
/* if (rc) */
/* return unlock_scd (map_assuan_err (rc)); */
rc = assuan_transact (scd_ctx, "SERIALNO",
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);
int rc;
unsigned char grip[20];
GCRY_SEXP s_skey = NULL;
gcry_sexp_t s_skey = NULL;
unsigned char *shadow_info = NULL;
rc = parse_keygrip (ctx, line, grip);
@ -575,6 +575,22 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
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
@ -661,6 +677,7 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "PASSWD", cmd_passwd },
{ "INPUT", NULL },
{ "OUTPUT", NULL },
{ "SCD", cmd_scd },
{ NULL }
};
int i, rc;

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -103,7 +103,7 @@ ask_for_card (CTRL ctrl, const unsigned char *shadow_info, char **r_kid)
}
else
{
log_error ("error accesing card: %s\n", gnupg_strerror (rc));
log_error ("error accesing card: %s\n", gpg_strerror (rc));
}
if (!rc)
@ -305,3 +305,15 @@ divert_pkdecrypt (CTRL ctrl,
xfree (kid);
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
* Copyright (C) 2001,02 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* 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.
With IGNORE_CACHE passed as true the passphrase is not taken from
the cache.*/
GCRY_SEXP
gcry_sexp_t
agent_key_from_file (CTRL ctrl,
const unsigned char *grip, unsigned char **shadow_info,
int ignore_cache)
@ -215,7 +215,7 @@ agent_key_from_file (CTRL ctrl,
struct stat st;
unsigned char *buf;
size_t len, buflen, erroff;
GCRY_SEXP s_skey;
gcry_sexp_t s_skey;
char hexgrip[40+4+1];
if (shadow_info)
@ -260,7 +260,7 @@ agent_key_from_file (CTRL ctrl,
if (rc)
{
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;
}
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);
if (rc)
log_error ("failed to unprotect the secret key: %s\n",
gnupg_strerror (rc));
gpg_strerror (rc));
break;
case PRIVATE_KEY_SHADOWED:
if (shadow_info)
@ -329,7 +329,7 @@ agent_key_from_file (CTRL ctrl,
if (rc)
{
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;
}

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -30,7 +30,7 @@
#include "i18n.h"
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;
char *buf;
@ -91,7 +91,7 @@ int
agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
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;
int rc;
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);
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);
}
@ -135,7 +135,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
gcry_sexp_release (s_keyparam);
if (rc)
{
log_error ("key generation failed: %s\n", gcry_strerror (rc));
log_error ("key generation failed: %s\n", gpg_strerror (rc));
xfree (pi);
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. */
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;
int rc;

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -37,11 +37,9 @@
# include <pth.h>
#endif
#include <gcrypt.h>
#define JNLIB_NEED_LOG_LOGV
#include "agent.h"
#include "../assuan/assuan.h" /* malloc hooks */
#include <assuan.h> /* malloc hooks */
#include "i18n.h"
#include "sysutils.h"
@ -336,6 +334,18 @@ main (int argc, char **argv )
log_set_prefix ("gpg-agent", 1|4);
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
the option parsing may need services of the library */
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
@ -715,12 +725,6 @@ main (int argc, char **argv )
{
struct sigaction sa;
if (!pth_init ())
{
log_error ("failed to initialize the Pth library\n");
exit (1);
}
sa.sa_handler = SIG_IGN;
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
@ -1030,7 +1034,7 @@ handle_connections (int listen_fd)
fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
if (fd == -1)
{
if (pth_event_occurred (ev))
if (pth_event_status (ev) == PTH_STATUS_OCCURRED)
{
handle_signal (signo);
continue;

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -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
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 */
static void
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 */
static void
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. */
static unsigned char *
make_shadow_info (const char *serialno, const char *idstring)
@ -211,7 +265,7 @@ send_cert_back (const char *id, void *assuan_context)
if (rc)
{
log_error ("error reading certificate: %s\n",
gnupg_strerror (rc));
gpg_strerror (rc));
return rc;
}
@ -238,8 +292,10 @@ agent_handle_learn (void *assuan_context)
int rc;
struct kpinfo_cb_parm_s parm;
struct certinfo_cb_parm_s cparm;
struct sinfo_cb_parm_s sparm;
char *serialno = NULL;
KEYPAIR_INFO item;
SINFO sitem;
unsigned char grip[20];
char *p;
int i;
@ -253,24 +309,35 @@ agent_handle_learn (void *assuan_context)
memset (&parm, 0, sizeof parm);
memset (&cparm, 0, sizeof cparm);
memset (&sparm, 0, sizeof sparm);
/* Check whether a card is present and get the serial number */
rc = agent_card_serialno (&serialno);
if (rc)
goto leave;
/* now gather all the availabe info */
rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm);
if (!rc && (parm.error || cparm.error))
rc = parm.error? parm.error : cparm.error;
/* now gather all the available info */
rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm,
sinfo_cb, &sparm);
if (!rc && (parm.error || cparm.error || sparm.error))
rc = parm.error? parm.error : cparm.error? cparm.error : sparm.error;
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;
}
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. */
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);
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;
}
@ -333,7 +400,7 @@ agent_handle_learn (void *assuan_context)
xfree (pubkey);
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;
}
n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
@ -343,7 +410,7 @@ agent_handle_learn (void *assuan_context)
xfree (shdkey);
if (rc)
{
log_error ("error writing key: %s\n", gnupg_strerror (rc));
log_error ("error writing key: %s\n", gpg_strerror (rc));
goto leave;
}
@ -374,6 +441,7 @@ agent_handle_learn (void *assuan_context)
xfree (serialno);
release_keypair_info (parm.info);
release_certinfo (cparm.info);
release_sinfo (sparm.info);
return rc;
}

View File

@ -1,5 +1,5 @@
/* minip12.c - A minilam pkcs-12 implementation.
* Copyright (C) 2002 Free Software Foundation, Inc.
/* minip12.c - A minimal pkcs-12 implementation.
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
*
* 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 rc, i, j;
GcryMDHd md;
GcryMPI num_b1 = NULL;
gcry_md_hd_t md;
gcry_mpi_t num_b1 = NULL;
int pwlen;
unsigned char hash[20], buf_b[64], buf_i[128], *p;
size_t cur_keylen;
@ -240,11 +240,11 @@ string_to_key (int id, char *salt, int iter, const char *pw,
for (;;)
{
md = gcry_md_open (GCRY_MD_SHA1, 0);
if (!md)
rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
if (rc)
{
log_error ( "gcry_md_open failed: %s\n", gcry_strerror (-1));
return -1;
log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
return rc;
}
for(i=0; i < 64; i++)
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);
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;
}
gcry_mpi_add_ui (num_b1, num_b1, 1);
for (i=0; i < 128; i += 64)
{
GcryMPI num_ij;
gcry_mpi_t num_ij;
n = 64;
rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, &n);
if (rc)
{
log_error ( "gcry_mpi_scan failed: %s\n",
gcry_strerror (rc));
gpg_strerror (rc));
return -1;
}
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)
{
log_error ( "gcry_mpi_print failed: %s\n",
gcry_strerror (rc));
gpg_strerror (rc));
return -1;
}
gcry_mpi_release (num_ij);
@ -302,7 +302,7 @@ string_to_key (int id, char *salt, int iter, const char *pw,
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];
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);
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;
}
@ -321,7 +321,7 @@ set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw)
rc = gcry_cipher_setiv (chd, keybuf, 8);
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 0;
@ -332,13 +332,13 @@ static void
crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
const char *pw, int encrypt)
{
GcryCipherHd chd;
gcry_cipher_hd_t chd;
int rc;
chd = gcry_cipher_open (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
if (!chd)
rc = gcry_cipher_open (&chd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
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;
}
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)
{
log_error ( "en/de-crytion failed: %s\n", gcry_strerror (rc));
log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
goto leave;
}
@ -414,7 +414,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
return -1;
}
static GcryMPI *
static gcry_mpi_t *
parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
const char *pw)
{
@ -427,7 +427,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
unsigned int iter;
int len;
unsigned char *plain = NULL;
GcryMPI *result = NULL;
gcry_mpi_t *result = NULL;
int result_count, i;
where = "start";
@ -593,7 +593,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
if (rc)
{
log_error ("error parsing key parameter: %s\n",
gcry_strerror (rc));
gpg_strerror (rc));
goto bailout;
}
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
tries to extract the first private key object it finds. In case of
an error NULL is returned. */
GcryMPI *
gcry_mpi_t *
p12_parse (const unsigned char *buffer, size_t length, const char *pw)
{
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
length in R_LENGTH; return NULL in case of an error. */
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;
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]);
if (rc)
{
log_error ("error formatting parameter: %s\n", gcry_strerror (rc));
log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
return NULL;
}
needed += n;
@ -951,7 +951,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
if (rc)
{
log_error ("oops: error formatting parameter: %s\n",
gcry_strerror (rc));
gpg_strerror (rc));
gcry_free (plain);
return NULL;
}
@ -962,7 +962,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
if (rc)
{
log_error ("oops: error storing parameter: %s\n",
gcry_strerror (rc));
gpg_strerror (rc));
gcry_free (plain);
return NULL;
}
@ -1131,7 +1131,7 @@ main (int argc, char **argv)
NULL, result[i]);
if (rc)
printf ("%d: [error printing number: %s]\n",
i, gcry_strerror (rc));
i, gpg_strerror (rc));
else
{
printf ("%d: %s\n", i, buf);

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -23,10 +23,11 @@
#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);
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*/

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -38,7 +38,7 @@ int
agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
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;
int rc;
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);
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);
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 );
if (rc)
{
log_error ("smartcard decryption failed: %s\n", gnupg_strerror (rc));
log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
goto leave;
}
/* 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);
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);
goto leave;
}

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -33,7 +33,7 @@
static int
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;
byte *frame;
@ -88,8 +88,8 @@ do_encode_md (const unsigned char *digest, size_t digestlen, int algo,
int
agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
{
GCRY_SEXP s_skey = NULL, s_hash = NULL, s_sig = NULL;
GCRY_MPI frame = NULL;
gcry_sexp_t s_skey = NULL, s_hash = NULL, s_sig = NULL;
gcry_mpi_t frame = NULL;
unsigned char *shadow_info = NULL;
int rc;
char *buf = NULL;
@ -118,7 +118,7 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
shadow_info, &sigbuf);
if (rc)
{
log_error ("smartcard signing failed: %s\n", gnupg_strerror (rc));
log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
goto leave;
}
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);
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);
goto leave;
}

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -30,8 +30,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include <gcrypt.h>
#define JNLIB_NEED_LOG_LOGV
#include "agent.h"
#include "minip12.h"
@ -61,12 +59,12 @@ aTest };
struct rsa_secret_key_s
{
MPI n; /* public modulus */
MPI e; /* public exponent */
MPI d; /* exponent */
MPI p; /* prime p. */
MPI q; /* prime q. */
MPI u; /* inverse of p mod q. */
gcry_mpi_t n; /* public modulus */
gcry_mpi_t e; /* public exponent */
gcry_mpi_t d; /* exponent */
gcry_mpi_t p; /* prime p. */
gcry_mpi_t q; /* prime 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 */
/* print_mpi (const char *text, GcryMPI a) */
/* print_mpi (const char *text, gcry_mpi_t a) */
/* { */
/* char *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); */
/* 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 */
/* { */
/* log_info ("%s: %s\n", text, buf); */
@ -185,14 +183,14 @@ make_canonical (const char *fname, const char *buf, size_t buflen)
{
int rc;
size_t erroff, len;
GCRY_SEXP sexp;
gcry_sexp_t sexp;
unsigned char *result;
rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
if (rc)
{
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;
}
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;
size_t erroff, len;
GCRY_SEXP sexp;
gcry_sexp_t sexp;
unsigned char *result;
rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
if (rc)
{
log_error ("invalid canonical S-Expression (off=%u): %s\n",
(unsigned int)erroff, gcry_strerror (rc));
(unsigned int)erroff, gpg_strerror (rc));
return NULL;
}
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
@ -453,7 +451,7 @@ static void
show_keygrip (const char *fname)
{
unsigned char *key;
GcrySexp private;
gcry_sexp_t private;
unsigned char grip[20];
int i;
@ -485,10 +483,10 @@ static int
rsa_key_check (struct rsa_secret_key_s *skey)
{
int err = 0;
MPI t = gcry_mpi_snew (0);
MPI t1 = gcry_mpi_snew (0);
MPI t2 = gcry_mpi_snew (0);
MPI phi = gcry_mpi_snew (0);
gcry_mpi_t t = gcry_mpi_snew (0);
gcry_mpi_t t1 = gcry_mpi_snew (0);
gcry_mpi_t t2 = gcry_mpi_snew (0);
gcry_mpi_t phi = gcry_mpi_snew (0);
/* check that n == p * 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 */
if (gcry_mpi_cmp (skey->p, skey->q) > 0)
{
GcryMPI tmp;
gcry_mpi_t tmp;
log_info ("swapping secret primes\n");
tmp = gcry_mpi_copy (skey->p);
@ -573,9 +571,9 @@ import_p12_file (const char *fname)
size_t buflen, resultlen;
int i;
int rc;
GcryMPI *kparms;
gcry_mpi_t *kparms;
struct rsa_secret_key_s sk;
GcrySexp s_key;
gcry_sexp_t s_key;
unsigned char *key;
unsigned char grip[20];
@ -635,7 +633,7 @@ import_p12_file (const char *fname)
if (rc)
{
log_error ("failed to created S-expression from key: %s\n",
gcry_strerror (rc));
gpg_strerror (rc));
return;
}
@ -687,16 +685,16 @@ import_p12_file (const char *fname)
static GcryMPI *
sexp_to_kparms (GCRY_SEXP sexp)
static gcry_mpi_t *
sexp_to_kparms (gcry_sexp_t sexp)
{
GcrySexp list, l2;
gcry_sexp_t list, l2;
const char *name;
const char *s;
size_t n;
int i, idx;
const char *elems;
GcryMPI *array;
gcry_mpi_t *array;
list = gcry_sexp_find_token (sexp, "private-key", 0 );
if(!list)
@ -747,10 +745,10 @@ sexp_to_kparms (GCRY_SEXP sexp)
static void
export_p12_file (const char *fname)
{
GcryMPI kparms[9], *kp;
gcry_mpi_t kparms[9], *kp;
unsigned char *key;
size_t keylen;
GcrySexp private;
gcry_sexp_t private;
struct rsa_secret_key_s sk;
int i;

View File

@ -1,5 +1,6 @@
/* 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.
*
@ -135,19 +136,19 @@ do_encryption (const char *protbegin, size_t protlen,
const char *passphrase, const unsigned char *sha1hash,
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";
int blklen, enclen, outlen;
char *iv = NULL;
int rc = 0;
int rc;
char *outbuf = NULL;
char *p;
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);
if (!hd)
return map_gcry_err (gcry_errno());
if (rc)
return rc;
/* 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 blklen;
GCRY_CIPHER_HD hd;
gcry_cipher_hd_t hd;
unsigned char *outbuf;
size_t reallen;
@ -395,10 +396,10 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
if (protectedlen < 4 || (protectedlen%blklen))
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);
if (!hd)
return map_gcry_err (gcry_errno());
if (rc)
return rc;
outbuf = gcry_malloc_secure (protectedlen);
if (!outbuf)
@ -750,7 +751,8 @@ hash_passphrase (const char *passphrase, int hashalgo,
unsigned long s2kcount,
unsigned char *key, size_t keylen)
{
GCRY_MD_HD md;
int rc;
gcry_md_hd_t md;
int pass, i;
int used = 0;
int pwlen = strlen (passphrase);
@ -761,9 +763,9 @@ hash_passphrase (const char *passphrase, int hashalgo,
if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt)
return gpg_error (GPG_ERR_INV_VALUE);
md = gcry_md_open (hashalgo, GCRY_MD_FLAG_SECURE);
if (!md)
return map_gcry_err (gcry_errno());
rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE);
if (rc)
return rc;
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>
* 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_source_t es = gpg_err_source (rc);
if (!rc)
return 0;
if (!es)
{
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 <unistd.h>
#include <gcrypt.h>
#include "../jnlib/logging.h"
#include "../jnlib/argparse.h"
#include "../jnlib/stringhelp.h"
#include "../common/i18n.h"
#include "keybox-defs.h"
#include <gcrypt.h>
enum cmd_and_opt_values {
aNull = 0,
oArmor = 'a',

View File

@ -110,6 +110,8 @@ X.509 specific are noted like [X.509: xxx]
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "keybox-defs.h"
#include <gcrypt.h>
#ifdef KEYBOX_WITH_OPENPGP
@ -119,7 +121,6 @@ X.509 specific are noted like [X.509: xxx]
#include <ksba.h>
#endif
#include "keybox-defs.h"
/* 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>
* 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 \
apdu.c apdu.h \
iso7816.c iso7816.h \
app.c app-common.h \
app-openpgp.c
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 "scdaemon.h"
#include "app-common.h"
#include "iso7816.h"
static struct {
int tag;
int constructed;
@ -80,6 +83,12 @@ find_tlv (const unsigned char *buffer, size_t length,
buffer = s;
if (n < 2)
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);
if ((*s & 0x1f) == 0x1f)
{ /* more tag bytes to follow */
@ -95,13 +104,26 @@ find_tlv (const unsigned char *buffer, size_t length,
this_tag = s[0];
len = s[1];
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)
return NULL; /* we expected 2 more bytes with the length. */
len = (s[0] << 8) | s[1];
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)
{ /* Dive into this composite DO after checking for too deep
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
dump_one_do (int slot, int tag)
{
@ -191,6 +270,7 @@ dump_one_do (int slot, int tag)
xfree (buffer);
}
}
#endif /*not used*/
static void
@ -257,15 +337,15 @@ dump_all_do (int slot)
}
}
/* Note, that FPR must be at least 20 bytes. */
static int
store_fpr (int slot, int keynumber, u32 timestamp,
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 char *buffer, *p;
unsigned char fpr[20];
int rc;
n = 6 + 2 + mlen + 2 + elen;
@ -300,44 +380,188 @@ store_fpr (int slot, int keynumber, u32 timestamp,
}
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];
/* Generate a new key on the card and store the fingerprint in the
corresponding DO. A KEYNUMBER of 0 creates the digital signature
key, 1 the encryption key and 2 the authentication key. If the key
already exists an error is returned unless FORCE has been set to
true. Note, that the function does not return the public key; this
has to be done using openpgp_readkey(). */
int
openpgp_genkey (int slot, int keynumber, int force)
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);
}
static int
do_learn_status (APP app, CTRL ctrl)
{
void *relptr;
unsigned char *value;
size_t valuelen;
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 i;
char numbuf[30];
unsigned char fprbuf[20];
const unsigned char *fpr;
const unsigned char *keydata, *m, *e;
unsigned char *buffer;
size_t buflen, keydatalen, n, mlen, elen;
time_t created_at;
int keyno = atoi (keynostr);
int force = (flags & 1);
if (keynumber < 0 || keynumber > 2)
return -1; /* invalid value */
if (keyno < 1 || keyno > 3)
return gpg_error (GPG_ERR_INV_ID);
keyno--;
rc = iso7816_get_data (slot, 0x006E, &buffer, &buflen);
rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen);
if (rc)
{
log_error ("error reading application data\n");
return -1;
return gpg_error (GPG_ERR_GENERAL);
}
fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0);
if (!fpr || n != 60)
{
rc = gpg_error (GPG_ERR_GENERAL);
log_error ("error reading fingerprint DO\n");
goto leave;
}
fpr += 20*keynumber;
fpr += 20*keyno;
for (i=0; i < 20 && !fpr[i]; i++)
;
if (i!=20 && !force)
{
rc = gpg_error (GPG_ERR_EEXIST);
log_error ("key already exists\n");
goto leave;
}
@ -346,8 +570,7 @@ openpgp_genkey (int slot, int keynumber, int force)
else
log_info ("generating new key\n");
rc = iso7816_verify (slot, 0x83, "12345678", 8);
rc = iso7816_verify (app->slot, 0x83, "12345678", 8);
if (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;
rc = iso7816_generate_keypair (slot,
keynumber == 0? "\xB6" :
keynumber == 1? "\xB8" : "\xA4",
rc = iso7816_generate_keypair (app->slot,
keyno == 0? "\xB6" :
keyno == 1? "\xB8" : "\xA4",
2,
&buffer, &buflen);
if (rc)
{
rc = gpg_error (GPG_ERR_CARD);
log_error ("generating key failed\n");
goto leave;
}
@ -372,7 +596,6 @@ openpgp_genkey (int slot, int keynumber, int force)
goto leave;
}
m = find_tlv (keydata, keydatalen, 0x0081, &mlen, 0);
if (!m)
{
@ -380,6 +603,8 @@ openpgp_genkey (int slot, int keynumber, int force)
goto leave;
}
log_printhex ("RSA n:", m, mlen);
send_key_data (ctrl, "n", m, mlen);
e = find_tlv (keydata, keydatalen, 0x0082, &elen, 0);
if (!e)
{
@ -387,8 +612,18 @@ openpgp_genkey (int slot, int keynumber, int force)
goto leave;
}
log_printhex ("RSA e:", e, elen);
send_key_data (ctrl, "e", e, elen);
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:
@ -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
must be used to before any other OpenPGP application functions. */
must be used before any other OpenPGP application functions. */
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 };
int slot = app->slot;
int rc;
unsigned char *buffer;
size_t buflen;
@ -416,27 +714,31 @@ app_select_openpgp (int slot)
if (rc)
goto leave;
if (opt.verbose)
{
log_info ("got AID: ");
log_printhex ("", buffer, buflen);
}
if (sn)
{
*sn = buffer;
*snlen = buflen;
}
else
xfree (buffer);
dump_all_do (slot);
/* rc = iso7816_verify (slot, 0x83, "12345678", 8); */
/* if (rc) */
/* log_error ("verify CHV3 failed: rc=%04X\n", rc); */
/* 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 */
app->fnc.learn_status = do_learn_status;
app->fnc.setattr = do_setattr;
app->fnc.genkey = do_genkey;
app->fnc.sign = do_sign;
}
leave:
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
card_help_get_keygrip (KsbaCert cert, unsigned char *array)
{
GCRY_SEXP s_pkey;
gcry_sexp_t s_pkey;
int rc;
KsbaSexp p;
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));
return rc;
}

View File

@ -30,6 +30,7 @@
#include <assuan.h>
#include "scdaemon.h"
#include "app-common.h"
/* maximum length aloowed as a PIN; used for INQUIRE NEEDPIN */
#define MAXLEN_PIN 100
@ -69,6 +70,12 @@ reset_notify (ASSUAN_CONTEXT ctx)
xfree (ctrl->in_data.value);
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
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);
if (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
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
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
cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
@ -120,6 +168,9 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
if ((rc = open_card (ctrl)))
return rc;
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)
return map_to_assuan_status (rc);
@ -149,6 +200,16 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
error message. The response of this command is a list of status
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>
If there is no certificate yet stored on the card a single "X" is
@ -157,12 +218,33 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
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
100 := Regular X.509 cert
101 := Trusted 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
@ -184,6 +266,9 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
char *serial;
time_t 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)
return map_to_assuan_status (rc);
@ -221,6 +306,8 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
}
/* Return information about the certificates. */
if (ctrl->app_ctx)
rc = -1; /* This information is not yet available for applications. */
for (idx=0; !rc; idx++)
{
char *certid;
@ -248,6 +335,8 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
/* Return information about the keys. */
if (ctrl->app_ctx)
rc = -1; /* This information is not yet available for applications. */
for (idx=0; !rc; idx++)
{
unsigned char keygrip[20];
@ -294,6 +383,9 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
if (rc == -1)
rc = 0;
if (!rc && ctrl->app_ctx)
rc = app_write_learn_status (ctrl->app_ctx, ctrl);
return map_to_assuan_status (rc);
}
@ -314,6 +406,9 @@ cmd_readcert (ASSUAN_CONTEXT ctx, char *line)
if ((rc = open_card (ctrl)))
return rc;
if (ctrl->app_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
if (rc)
{
@ -348,6 +443,9 @@ cmd_readkey (ASSUAN_CONTEXT ctx, char *line)
if ((rc = open_card (ctrl)))
return rc;
if (ctrl->app_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
if (rc)
{
@ -480,6 +578,14 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
keyidstr = strdup (line);
if (!keyidstr)
return ASSUAN_Out_Of_Core;
if (ctrl->app_ctx)
rc = app_sign (ctrl->app_ctx,
keyidstr, GCRY_MD_SHA1,
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,
@ -519,6 +625,13 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
keyidstr = strdup (line);
if (!keyidstr)
return ASSUAN_Out_Of_Core;
if (ctrl->app_ctx)
rc = app_decipher (ctrl->app_ctx,
keyidstr,
pin_cb, ctx,
ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen);
else
rc = card_decipher (ctrl->card_ctx,
keyidstr,
pin_cb, ctx,
@ -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 */
@ -560,6 +766,8 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "PKDECRYPT", cmd_pkdecrypt },
{ "INPUT", NULL },
{ "OUTPUT", NULL },
{ "SETATTR", cmd_setattr },
{ "GENKEY", cmd_genkey },
{ NULL }
};
int i, rc;
@ -646,3 +854,51 @@ scd_command_handler (int listen_fd)
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>
#define JNLIB_NEED_LOG_LOGV
#include <gcrypt.h>
#include "scdaemon.h"
#include <gcrypt.h>
#include "apdu.h" /* for open_reader */
#include "atr.h"
#include "app-common.h"
#define _(a) (a)
@ -104,6 +105,9 @@ main (int argc, char **argv )
ARGPARSE_ARGS pargs;
int slot, rc;
int reader_port = 32768; /* First USB reader. */
struct app_ctx_s appbuf;
memset (&appbuf, 0, sizeof appbuf);
set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
@ -147,7 +151,8 @@ main (int argc, char **argv )
if (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)
log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc));
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 <signal.h>
#define JNLIB_NEED_LOG_LOGV
#include "scdaemon.h"
#include <ksba.h>
#include <gcrypt.h>
#define JNLIB_NEED_LOG_LOGV
#include <assuan.h> /* malloc hooks */
#include "scdaemon.h"
#include "i18n.h"
#include "sysutils.h"

View File

@ -76,18 +76,22 @@ struct {
struct server_local_s;
struct card_ctx_s;
struct app_ctx_s;
struct server_control_s {
struct server_local_s *server_local;
struct card_ctx_s *card_ctx;
struct app_ctx_s *app_ctx;
struct {
unsigned char *value;
int valuelen;
} in_data; /* helper to store the value we are going to sign */
};
typedef struct server_control_s *CTRL;
typedef struct card_ctx_s *CARD;
typedef struct app_ctx_s *APP;
/*-- scdaemon.c --*/
void scd_exit (int rc);
@ -95,6 +99,7 @@ void scd_init_default_ctrl (CTRL ctrl);
/*-- command.c --*/
void scd_command_handler (int);
void send_status_info (CTRL ctrl, const char *keyword, ...);
/*-- card.c --*/
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>
* call-agent.c (init_membuf,put_membuf,get_membuf): Removed.

View File

@ -26,15 +26,17 @@
#include <unistd.h>
#include <time.h>
#include <assert.h>
#include <gcrypt.h>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#include <assuan.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <assuan.h>
#include "i18n.h"
#include "keydb.h" /* fixme: Move this to import.c */
#include "../common/membuf.h"
static ASSUAN_CONTEXT agent_ctx = NULL;
static int force_pipe_server = 0;
@ -54,77 +56,9 @@ struct genkey_parm_s {
struct learn_parm_s {
int error;
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
@ -354,7 +288,7 @@ start_agent (void)
static AssuanError
membuf_data_cb (void *opaque, const void *buffer, size_t length)
{
struct membuf *data = opaque;
membuf_t *data = opaque;
if (buffer)
put_membuf (data, buffer, length);
@ -373,7 +307,7 @@ gpgsm_agent_pksign (const char *keygrip,
{
int rc, i;
char *p, line[ASSUAN_LINELENGTH];
struct membuf data;
membuf_t data;
size_t len;
*r_buf = NULL;
@ -448,7 +382,7 @@ gpgsm_agent_pkdecrypt (const char *keygrip,
{
int rc;
char line[ASSUAN_LINELENGTH];
struct membuf data;
membuf_t data;
struct cipher_parm_s cipher_parm;
size_t n, len;
char *buf, *endp;
@ -534,7 +468,7 @@ gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey)
{
int rc;
struct genkey_parm_s gk_parm;
struct membuf data;
membuf_t data;
size_t len;
char *buf;
@ -710,7 +644,7 @@ learn_cb (void *opaque, const void *buffer, size_t length)
keydb_store_cert (cert, 1, NULL);
}
else if (rc)
log_error ("invalid certificate: %s\n", gnupg_strerror (rc));
log_error ("invalid certificate: %s\n", gpg_strerror (rc));
else
{
int existed;
@ -735,7 +669,7 @@ gpgsm_agent_learn ()
{
int rc;
struct learn_parm_s learn_parm;
struct membuf data;
membuf_t data;
size_t len;
rc = start_agent ();

View File

@ -28,10 +28,10 @@
#include <assert.h>
#include <ctype.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <assuan.h>
#include "gpgsm.h"
#include "i18n.h"
struct membuf {
@ -263,7 +263,7 @@ inq_certificate (void *opaque, const char *line)
err = gpgsm_find_cert (line, &cert);
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;
}
else
@ -533,7 +533,7 @@ run_command_inq_cb (void *opaque, const char *line)
err = gpgsm_find_cert (line, &cert);
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;
}
else

View File

@ -27,10 +27,10 @@
#include <time.h>
#include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h"
#include "keydb.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);
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;
}
else if (!count)
@ -585,7 +585,7 @@ gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
else
{
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 */
@ -655,8 +655,10 @@ gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
rc = gpgsm_cert_use_cert_p (issuer_cert);
if (rc)
{
char numbuf[50];
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
gnupg_error_token (rc), NULL);
numbuf, NULL);
rc = 0;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -27,10 +27,10 @@
#include <time.h>
#include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h"
#include "keydb.h"
#include "i18n.h"
@ -38,7 +38,7 @@ struct decrypt_filter_parm_s {
int algo;
int mode;
int blklen;
GCRY_CIPHER_HD hd;
gcry_cipher_hd_t hd;
char iv[16];
size_t ivlen;
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);
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;
}
@ -113,17 +113,15 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
if (DBG_CRYPTO)
log_printhex ("session key:", seskey+n, seskeylen-n);
parm->hd = gcry_cipher_open (parm->algo, parm->mode, 0);
if (!parm->hd)
rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
if (rc)
{
rc = gcry_errno ();
log_error ("error creating decryptor: %s\n", gcry_strerror (rc));
rc = map_gcry_err (rc);
log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
goto leave;
}
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 "
"a weak key in the symmetric cipher.\n"));
@ -131,8 +129,7 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
}
if (rc)
{
log_error("key setup failed: %s\n", gcry_strerror(rc) );
rc = map_gcry_err (rc);
log_error("key setup failed: %s\n", gpg_strerror(rc) );
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);
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;
}
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
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;
}
@ -334,8 +331,13 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
else if (!algoid)
log_info (_("(this does not seem to be an encrypted"
" message)\n"));
{
char numbuf[50];
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
gnupg_error_token (rc), algoid?algoid:"?", NULL);
numbuf, algoid?algoid:"?", NULL);
}
goto leave;
}
dfparm.algo = algo;
@ -383,14 +385,14 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
if (rc)
{
log_error ("failed to find the certificate: %s\n",
gnupg_strerror(rc));
gpg_strerror(rc));
goto oops;
}
rc = keydb_get_cert (kh, &cert);
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;
}
/* 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);
if (rc)
{
char numbuf[50];
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
gnupg_error_token (rc), NULL);
numbuf, NULL);
rc = 0;
}
@ -424,7 +428,7 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
if (rc)
{
log_debug ("decrypting session key failed: %s\n",
gnupg_strerror (rc));
gpg_strerror (rc));
}
else
{ /* setup the bulk decrypter */
@ -479,7 +483,7 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
rc = gpgsm_finish_writer (b64writer);
if (rc)
{
log_error ("write failed: %s\n", gnupg_strerror (rc));
log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave;
}
gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);

View File

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

View File

@ -27,10 +27,10 @@
#include <time.h>
#include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h"
#include "keydb.h"
#include "i18n.h"
@ -38,7 +38,7 @@
struct dek_s {
const char *algoid;
int algo;
GCRY_CIPHER_HD chd;
gcry_cipher_hd_t chd;
char key[32];
int keylen;
char iv[32];
@ -89,37 +89,37 @@ init_dek (DEK dek)
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
}
dek->chd = gcry_cipher_open (dek->algo, mode, GCRY_CIPHER_SECURE);
if (!dek->chd)
rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
if (rc)
{
log_error ("failed to create cipher context: %s\n", gcry_strerror (-1));
return gpg_error (GPG_ERR_GENERAL);
log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
return rc;
}
for (i=0; i < 8; i++)
{
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
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;
log_info(_("weak key created - retrying\n") );
}
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);
dek->chd = NULL;
return map_gcry_err (rc);
return rc;
}
gcry_randomize (dek->iv, dek->ivlen, GCRY_STRONG_RANDOM);
rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen);
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);
dek->chd = NULL;
return map_gcry_err (rc);
return rc;
}
return 0;
@ -129,14 +129,14 @@ init_dek (DEK dek)
/* 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
key (caller must free) */
static GCRY_MPI
static gcry_mpi_t
encode_session_key (DEK dek, unsigned int nbits)
{
int nframe = (nbits+7) / 8;
byte *p;
byte *frame;
int i,n;
MPI a;
gcry_mpi_t a;
if (dek->keylen + 7 > nframe || !nframe)
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
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;
KsbaSexp buf;
size_t len;
@ -230,14 +230,14 @@ encrypt_dek (const DEK dek, KsbaCert cert, char **encval)
xfree (buf); buf = NULL;
if (rc)
{
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
return map_gcry_err (rc);
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
return rc;
}
/* put the encoded cleartext into a simple list */
{
/* 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)
{
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);
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;
}
@ -449,7 +449,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
if (rc)
{
log_error ("failed to create the session key: %s\n",
gnupg_strerror (rc));
gpg_strerror (rc));
goto leave;
}
@ -482,7 +482,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
if (rc)
{
log_error ("encryption failed for recipient no. %d: %s\n",
recpno, gnupg_strerror (rc));
recpno, gpg_strerror (rc));
goto leave;
}
@ -532,7 +532,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
rc = gpgsm_finish_writer (b64writer);
if (rc)
{
log_error ("write failed: %s\n", gnupg_strerror (rc));
log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave;
}
log_info ("encrypted data created\n");

View File

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

View File

@ -27,10 +27,10 @@
#include <time.h>
#include <assert.h>
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
/* Return the fingerprint of the certificate (we can't put this into
libksba because we need libgcrypt support). The caller must
@ -45,7 +45,7 @@
char *
gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len)
{
GCRY_MD_HD md;
gcry_md_hd_t md;
int rc, len;
if (!algo)
@ -59,10 +59,10 @@ gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len)
if (r_len)
*r_len = len;
md = gcry_md_open (algo, 0);
if (!md)
rc = gcry_md_open (&md, algo, 0);
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 */
return array;
}
@ -143,7 +143,7 @@ gpgsm_get_short_fingerprint (KsbaCert cert)
char *
gpgsm_get_keygrip (KsbaCert cert, char *array)
{
GCRY_SEXP s_pkey;
gcry_sexp_t s_pkey;
int rc;
KsbaSexp p;
size_t n;
@ -164,7 +164,7 @@ gpgsm_get_keygrip (KsbaCert cert, char *array)
xfree (p);
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;
}
array = gcry_pk_get_keygrip (s_pkey, array);

View File

@ -27,10 +27,10 @@
#include <unistd.h>
#include <fcntl.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <assuan.h> /* malloc hooks */
#include "gpgsm.h"
#include "../kbx/keybox.h" /* malloc hooks */
#include "i18n.h"
#include "keydb.h"
@ -1095,7 +1095,7 @@ main ( int argc, char **argv)
if (rc)
{
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,
gpg_err_code (rc) == -1? "1":
gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1":
@ -1117,7 +1117,7 @@ main ( int argc, char **argv)
if (rc)
{
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,
gpg_err_code (rc) == -1? "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_status (CTRL ctrl, int no, const char *text);
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 --*/
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 --*/
int gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert);
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 */
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);

View File

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

View File

@ -231,7 +231,7 @@ keydb_add_resource (const char *url, int force, int secret)
leave:
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)
any_secret = 1;
else
@ -1255,14 +1255,14 @@ keydb_store_cert (KsbaCert cert, int ephemeral, int *existed)
return 0; /* okay */
}
log_error (_("problem looking for existing certificate: %s\n"),
gnupg_strerror (rc));
gpg_strerror (rc));
return rc;
}
rc = keydb_locate_writable (kh, 0);
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);
return rc;
}
@ -1270,7 +1270,7 @@ keydb_store_cert (KsbaCert cert, int ephemeral, int *existed)
rc = keydb_insert_cert (kh, cert);
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);
return rc;
}

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -27,10 +27,11 @@
#include <time.h>
#include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h"
#include "keydb.h"
#include "i18n.h"
@ -460,7 +461,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
if (rc)
{
log_error ("key `%s' not found: %s\n",
sl->d, gnupg_strerror (rc));
sl->d, gpg_strerror (rc));
rc = 0;
}
else
@ -535,7 +536,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
cert = NULL;
}
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:
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);
}
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
/*

View File

@ -27,16 +27,16 @@
#include <time.h>
#include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h"
#include "keydb.h"
#include "i18n.h"
static void
hash_data (int fd, GCRY_MD_HD md)
hash_data (int fd, gcry_md_hd_t md)
{
FILE *fp;
char buffer[4096];
@ -61,7 +61,7 @@ hash_data (int fd, GCRY_MD_HD md)
}
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;
FILE *fp;
@ -203,7 +203,7 @@ get_default_signer (void)
rc = keydb_classify_name (opt.local_user, &desc);
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;
}
@ -302,7 +302,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
KsbaCMS cms = NULL;
KsbaStopReason stopreason;
KEYDB_HANDLE kh = NULL;
GCRY_MD_HD data_md = NULL;
gcry_md_hd_t data_md = NULL;
int signer;
const char *algoid;
int algo;
@ -322,7 +322,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
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;
}
@ -394,7 +394,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
if (rc)
{
log_error ("failed to store list of certificates: %s\n",
gnupg_strerror(rc));
gpg_strerror(rc));
goto leave;
}
/* 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)*/
data_md = gcry_md_open (0, 0);
if (!data_md)
rc = gcry_md_open (&data_md, 0, 0);
if (rc)
{
rc = map_gcry_err (gcry_errno());
log_error ("md_open failed: %s\n", gcry_strerror (-1));
log_error ("md_open failed: %s\n", gpg_strerror (rc));
goto leave;
}
if (DBG_HASHING)
@ -524,18 +523,17 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
}
else if (stopreason == KSBA_SR_NEED_SIG)
{ /* calculate the signature for all signers */
GCRY_MD_HD md;
gcry_md_hd_t md;
algo = GCRY_MD_SHA1;
md = gcry_md_open (algo, 0);
if (DBG_HASHING)
gcry_md_start_debug (md, "sign.attr");
if (!md)
rc = gcry_md_open (&md, algo, 0);
if (rc)
{
log_error ("md_open failed: %s\n", gcry_strerror (-1));
log_error ("md_open failed: %s\n", gpg_strerror (rc));
goto leave;
}
if (DBG_HASHING)
gcry_md_start_debug (md, "sign.attr");
ksba_cms_set_hash_function (cms, HASH_FNC, md);
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);
if (rc)
{
log_error ("write failed: %s\n", gnupg_strerror (rc));
log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave;
}

View File

@ -27,16 +27,15 @@
#include <time.h>
#include <assert.h>
#include "gpgsm.h"
#include <gcrypt.h>
#include <ksba.h>
#include "gpgsm.h"
#include "keydb.h"
#include "i18n.h"
/* fixme: Move this to jnlib */
static char *
strtimestamp (time_t atime)
strtimestamp_r (time_t atime)
{
char *buffer = xmalloc (15);
@ -59,7 +58,7 @@ strtimestamp (time_t atime)
/* Hash the data for a detached signature */
static void
hash_data (int fd, GCRY_MD_HD md)
hash_data (int fd, gcry_md_hd_t md)
{
FILE *fp;
char buffer[4096];
@ -102,7 +101,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
KsbaStopReason stopreason;
KsbaCert cert;
KEYDB_HANDLE kh;
GCRY_MD_HD data_md = NULL;
gcry_md_hd_t data_md = NULL;
int signer;
const char *algoid;
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);
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;
}
@ -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);
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;
}
}
@ -160,11 +159,10 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
goto leave;
}
data_md = gcry_md_open (0, 0);
if (!data_md)
rc = gcry_md_open (&data_md, 0, 0);
if (rc)
{
rc = map_gcry_err (gcry_errno());
log_error ("md_open failed: %s\n", gcry_strerror (-1));
log_error ("md_open failed: %s\n", gpg_strerror (rc));
goto leave;
}
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);
if (rc)
{
log_error ("write failed: %s\n", gnupg_strerror (rc));
log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave;
}
}
@ -364,7 +362,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
}
else
log_error ("failed to find the certificate: %s\n",
gnupg_strerror(rc));
gpg_strerror(rc));
{
char numbuf[50];
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);
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;
}
@ -395,7 +393,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
if (msgdigest)
{ /* Signed attributes are available. */
GCRY_MD_HD md;
gcry_md_hd_t md;
unsigned char *s;
/* 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;
}
md = gcry_md_open (algo, 0);
if (!md)
rc = gcry_md_open (&md, algo, 0);
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;
}
if (DBG_HASHING)
@ -445,7 +443,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
{
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);
gpgsm_status (ctrl, STATUS_BADSIG, 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)*/
if (rc)
{
gpgsm_status2 (ctrl, STATUS_ERROR, "verify.keyusage",
gnupg_error_token (rc), NULL);
gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
gpg_err_code (rc));
rc = 0;
}
@ -474,7 +472,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
char *buf, *fpr, *tstr;
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
tstr = strtimestamp (sigtime);
tstr = strtimestamp_r (sigtime);
buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120);
sprintf (buf, "%s %s %lu %lu", fpr, tstr,
(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 */
{
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
|| gpg_err_code (rc) == GPG_ERR_BAD_CERT
|| gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT
|| 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
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;
}