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:
parent
ed0d33f1d0
commit
f5db59fc21
@ -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.
|
||||
|
@ -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 --*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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
90
scd/app-common.h
Normal 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*/
|
||||
|
||||
|
||||
|
@ -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
208
scd/app.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
264
scd/command.c
264
scd/command.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
11
sm/ChangeLog
11
sm/ChangeLog
@ -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.
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
42
sm/decrypt.c
42
sm/decrypt.c
@ -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);
|
||||
|
10
sm/delete.c
10
sm/delete.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
42
sm/encrypt.c
42
sm/encrypt.c
@ -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");
|
||||
|
10
sm/export.c
10
sm/export.c
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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":
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
11
sm/server.c
11
sm/server.c
@ -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
|
||||
/*
|
||||
|
36
sm/sign.c
36
sm/sign.c
@ -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;
|
||||
}
|
||||
|
||||
|
50
sm/verify.c
50
sm/verify.c
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user