-fix crypto_helper FTBFS

This commit is contained in:
Christian Grothoff 2021-11-17 20:31:08 +01:00
parent cc74bf311d
commit f76888378c
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 531 additions and 159 deletions

View File

@ -238,63 +238,19 @@ TALER_CRYPTO_helper_denom_connect (
sizeof (dh->sa.sun_path) - 1); sizeof (dh->sa.sun_path) - 1);
GNUNET_free (unixpath); GNUNET_free (unixpath);
dh->sock = -1; dh->sock = -1;
/* Extract the age groups from the config, if the extension has been set,
* and serialize them into the age mask
*/
if (GNUNET_OK !=
TALER_get_age_mask (cfg, &dh->age_mask))
{ {
char *tmpdir; /* FIXME: maybe more specific error? */
char *template; GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"extensions", /* FIXME: right section etc? */
if (GNUNET_OK != "age-restriction",
GNUNET_CONFIGURATION_get_value_filename (cfg, "invalid age groups");
"taler-exchange-secmod-rsa", TALER_CRYPTO_helper_denom_disconnect (dh);
"CLIENT_DIR", return NULL;
&tmpdir))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-exchange-secmod-rsa",
"CLIENT_DIR");
return NULL;
}
GNUNET_asprintf (&template,
"%s/cli",
tmpdir);
/* We expect the service to create the client directory */
if (GNUNET_OK !=
GNUNET_DISK_directory_test (tmpdir,
GNUNET_YES))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unable to read secmod client directory (%s)\n",
tmpdir);
GNUNET_free (dh);
GNUNET_free (template);
GNUNET_free (tmpdir);
return NULL;
}
GNUNET_free (tmpdir);
dh->template = template;
if (strlen (template) >= sizeof (dh->sa.sun_path))
{
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"PATHS",
"TALER_RUNTIME_DIR",
"path too long");
TALER_CRYPTO_helper_denom_disconnect (dh);
return NULL;
}
/* Extract the age groups from the config, if the extension has been set,
* and serialize them into the age mask
*/
if (GNUNET_OK !=
TALER_get_age_mask (cfg, &dh->age_mask))
{
/* FIXME: maybe more specific error? */
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"extensions", /* FIXME: right section etc? */
"age-restriction",
"invalid age groups");
TALER_CRYPTO_helper_denom_disconnect (dh);
return NULL;
}
} }
TALER_CRYPTO_helper_denom_poll (dh); TALER_CRYPTO_helper_denom_poll (dh);
return dh; return dh;

View File

@ -21,6 +21,97 @@
#include "platform.h" #include "platform.h"
#include "taler_util.h" #include "taler_util.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include "secmod_common.h"
#include <poll.h>
#include <sys/eventfd.h>
/**
* Head of DLL of clients connected to us.
*/
struct TES_Client *TES_clients_head;
/**
* Tail of DLL of clients connected to us.
*/
struct TES_Client *TES_clients_tail;
/**
* Lock for the client queue.
*/
pthread_mutex_t TES_clients_lock;
/**
* Private key of this security module. Used to sign denomination key
* announcements.
*/
struct TALER_SecurityModulePrivateKeyP TES_smpriv;
/**
* Public key of this security module.
*/
struct TALER_SecurityModulePublicKeyP TES_smpub;
/**
* Our listen socket.
*/
static struct GNUNET_NETWORK_Handle *unix_sock;
/**
* Path where we are listening.
*/
static char *unixpath;
/**
* Task run to accept new inbound connections.
*/
static struct GNUNET_SCHEDULER_Task *listen_task;
/**
* Set once we are in shutdown and workers should terminate.
*/
static volatile bool in_shutdown;
enum GNUNET_GenericReturnValue
TES_transmit (int sock,
const struct GNUNET_MessageHeader *hdr)
{
ssize_t off = 0;
const void *pos = hdr;
uint16_t end = ntohs (hdr->size);
while (off < end)
{
ssize_t ret = send (sock,
pos,
end - off,
0 /* no flags => blocking! */);
if ( (-1 == ret) &&
( (EAGAIN == errno) ||
(EINTR == errno) ) )
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
"send");
continue;
}
if (-1 == ret)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"send");
return GNUNET_SYSERR;
}
if (0 == ret)
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
off += ret;
pos += ret;
}
return GNUNET_OK;
}
struct GNUNET_NETWORK_Handle * struct GNUNET_NETWORK_Handle *
TES_open_socket (const char *unixpath) TES_open_socket (const char *unixpath)
@ -37,7 +128,7 @@ TES_open_socket (const char *unixpath)
old_umask = umask (S_IROTH | S_IWOTH | S_IXOTH); old_umask = umask (S_IROTH | S_IWOTH | S_IXOTH);
sock = socket (PF_UNIX, sock = socket (PF_UNIX,
SOCK_DGRAM, SOCK_STREAM,
0); 0);
if (-1 == sock) if (-1 == sock)
{ {
@ -80,8 +171,349 @@ TES_open_socket (const char *unixpath)
goto cleanup; goto cleanup;
} }
ret = GNUNET_NETWORK_socket_box_native (sock); ret = GNUNET_NETWORK_socket_box_native (sock);
if (GNUNET_OK !=
GNUNET_NETWORK_socket_listen (ret,
512))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"listen",
unixpath);
GNUNET_break (GNUNET_OK ==
GNUNET_NETWORK_socket_close (ret));
ret = NULL;
}
} }
cleanup: cleanup:
(void) umask (old_umask); (void) umask (old_umask);
return ret; return ret;
} }
/**
* Send a signal to all clients to notify them about a key generation change.
*/
void
TES_wake_clients (void)
{
uint64_t num = 1;
GNUNET_assert (0 == pthread_mutex_lock (&TES_clients_lock));
for (struct TES_Client *client = TES_clients_head;
NULL != client;
client = client->next)
{
GNUNET_assert (sizeof (num) ==
write (client->esock,
&num,
sizeof (num)));
}
GNUNET_assert (0 == pthread_mutex_unlock (&TES_clients_lock));
}
/**
* Read work request from the client.
*
* @param cls a `struct TES_Client *`
* @param dispatch function to call with work requests received
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
TES_read_work (void *cls,
TES_MessageDispatch dispatch)
{
struct TES_Client *client = cls;
char *buf = client->iobuf;
ssize_t buf_size;
size_t off = 0;
uint16_t msize;
const struct GNUNET_MessageHeader *hdr;
do
{
buf_size = recv (client->csock,
&buf[off],
sizeof (client->iobuf) - off,
0);
if (-1 == buf_size)
{
if ( (0 == off) &&
(EAGAIN == errno) )
return GNUNET_NO;
if ( (EINTR == errno) ||
(EAGAIN == errno) )
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
"recv");
continue;
}
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"recv");
return GNUNET_SYSERR;
}
if (0 == buf_size)
{
/* regular disconnect? */
GNUNET_break_op (0 == off);
return GNUNET_SYSERR;
}
off += buf_size;
if (off < sizeof (struct GNUNET_MessageHeader))
continue;
hdr = (const struct GNUNET_MessageHeader *) buf;
msize = ntohs (hdr->size);
} while (off < msize);
if (off > msize)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
return dispatch (client,
hdr);
}
bool
TES_await_ready (struct TES_Client *client)
{
/* wait for reply with 1s timeout */
struct pollfd pfds[] = {
{
.fd = client->csock,
.events = POLLIN
},
{
.fd = client->esock,
.events = POLLIN
},
};
int ret;
ret = poll (pfds,
2,
-1);
if ( (-1 == ret) &&
(EINTR != errno) )
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"poll");
for (int i = 0; i<2; i++)
{
if ( (pfds[i].fd == client->esock) &&
(POLLIN == pfds[i].revents) )
{
uint64_t num;
GNUNET_assert (sizeof (num) ==
read (client->esock,
&num,
sizeof (num)));
return true;
}
}
return false;
}
void
TES_free_client (struct TES_Client *client)
{
GNUNET_assert (0 == pthread_mutex_lock (&TES_clients_lock));
GNUNET_CONTAINER_DLL_remove (TES_clients_head,
TES_clients_tail,
client);
GNUNET_assert (0 == pthread_mutex_unlock (&TES_clients_lock));
GNUNET_break (0 == close (client->csock));
GNUNET_break (0 == close (client->esock));
pthread_detach (client->worker);
GNUNET_free (client);
}
/**
* Main function of a worker thread that signs.
*
* @param cls the client we are working on
* @return NULL
*/
static void *
sign_worker (void *cls)
{
struct TES_Client *client = cls;
if (GNUNET_OK !=
client->cb.init (client))
{
GNUNET_break (0);
TES_free_client (client);
return NULL;
}
while (! in_shutdown)
{
if (TES_await_ready (client))
{
if (GNUNET_OK !=
client->cb.updater (client))
break;
}
if (GNUNET_SYSERR ==
TES_read_work (client,
client->cb.dispatch))
break;
}
TES_free_client (client);
return NULL;
}
/**
* Task that listens for incoming clients.
*
* @param cls a `struct TES_Callbacks`
*/
static void
listen_job (void *cls)
{
const struct TES_Callbacks *cb = cls;
int s;
int e;
struct sockaddr_storage sa;
socklen_t sa_len = sizeof (sa);
listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
unix_sock,
&listen_job,
cls);
s = accept (GNUNET_NETWORK_get_fd (unix_sock),
(struct sockaddr *) &sa,
&sa_len);
if (-1 == s)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"accept");
return;
}
e = eventfd (0,
EFD_CLOEXEC);
if (-1 == e)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"eventfd");
GNUNET_break (0 == close (s));
return;
}
{
struct TES_Client *client;
client = GNUNET_new (struct TES_Client);
client->cb = *cb;
client->csock = s;
client->esock = e;
GNUNET_assert (0 == pthread_mutex_lock (&TES_clients_lock));
GNUNET_CONTAINER_DLL_insert (TES_clients_head,
TES_clients_tail,
client);
GNUNET_assert (0 == pthread_mutex_unlock (&TES_clients_lock));
if (0 !=
pthread_create (&client->worker,
NULL,
&sign_worker,
client))
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"pthread_create");
TES_free_client (client);
}
}
}
int
TES_listen_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
const char *section,
const struct TES_Callbacks *cb)
{
{
char *pfn;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
section,
"SM_PRIV_KEY",
&pfn))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"SM_PRIV_KEY");
return EXIT_NOTCONFIGURED;
}
if (GNUNET_SYSERR ==
GNUNET_CRYPTO_eddsa_key_from_file (pfn,
GNUNET_YES,
&TES_smpriv.eddsa_priv))
{
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
section,
"SM_PRIV_KEY",
"Could not use file to persist private key");
GNUNET_free (pfn);
return EXIT_NOPERMISSION;
}
GNUNET_free (pfn);
GNUNET_CRYPTO_eddsa_key_get_public (&TES_smpriv.eddsa_priv,
&TES_smpub.eddsa_pub);
}
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
section,
"UNIXPATH",
&unixpath))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"UNIXPATH");
return EXIT_NOTCONFIGURED;
}
GNUNET_assert (NULL != unixpath);
unix_sock = TES_open_socket (unixpath);
if (NULL == unix_sock)
{
GNUNET_free (unixpath);
GNUNET_break (0);
return EXIT_NOPERMISSION;
}
/* start job to accept incoming requests on 'sock' */
listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
unix_sock,
&listen_job,
(void *) cb);
return 0;
}
void
TES_listen_stop (void)
{
if (NULL != listen_task)
{
GNUNET_SCHEDULER_cancel (listen_task);
listen_task = NULL;
}
if (NULL != unix_sock)
{
GNUNET_break (GNUNET_OK ==
GNUNET_NETWORK_socket_close (unix_sock));
unix_sock = NULL;
}
if (0 != unlink (unixpath))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
"unlink",
unixpath);
}
GNUNET_free (unixpath);
in_shutdown = true;
TES_wake_clients ();
}

View File

@ -78,17 +78,17 @@ struct DenominationKey
/** /**
* The private key of the denomination. * The private key of the denomination.
*/ */
struct TALER_DenominationPrivateKey denom_priv; struct GNUNET_CRYPTO_RsaPrivateKey *denom_priv;
/** /**
* The public key of the denomination. * The public key of the denomination.
*/ */
struct TALER_DenominationPublicKey denom_pub; struct GNUNET_CRYPTO_RsaPublicKey *denom_pub;
/** /**
* Hash of this denomination's public key. * Hash of this denomination's public key.
*/ */
struct GNUNET_HashCode h_denom_pub; struct TALER_DenominationHash h_denom_pub;
/** /**
* Time at which this key is supposed to become valid. * Time at which this key is supposed to become valid.
@ -245,7 +245,7 @@ notify_client_dk_add (struct TES_Client *client,
void *p; void *p;
size_t tlen; size_t tlen;
buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dk->denom_pub.rsa_public_key, buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dk->denom_pub,
&buf); &buf);
GNUNET_assert (buf_len < UINT16_MAX); GNUNET_assert (buf_len < UINT16_MAX);
GNUNET_assert (nlen < UINT16_MAX); GNUNET_assert (nlen < UINT16_MAX);
@ -258,12 +258,12 @@ notify_client_dk_add (struct TES_Client *client,
an->section_name_len = htons ((uint16_t) nlen); an->section_name_len = htons ((uint16_t) nlen);
an->anchor_time = GNUNET_TIME_absolute_hton (dk->anchor); an->anchor_time = GNUNET_TIME_absolute_hton (dk->anchor);
an->duration_withdraw = GNUNET_TIME_relative_hton (denom->duration_withdraw); an->duration_withdraw = GNUNET_TIME_relative_hton (denom->duration_withdraw);
TALER_exchange_secmod_rsa_sign (&dk->h_denom_pub, TALER_exchange_secmod_denom_sign (&dk->h_denom_pub,
denom->section, denom->section,
dk->anchor, dk->anchor,
denom->duration_withdraw, denom->duration_withdraw,
&TES_smpriv, &TES_smpriv,
&an->secm_sig); &an->secm_sig);
an->secm_pub = TES_smpub; an->secm_pub = TES_smpub;
p = (void *) &an[1]; p = (void *) &an[1];
memcpy (p, memcpy (p,
@ -275,7 +275,7 @@ notify_client_dk_add (struct TES_Client *client,
nlen); nlen);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Sending RSA denomination key %s (%s)\n", "Sending RSA denomination key %s (%s)\n",
GNUNET_h2s (&dk->h_denom_pub), GNUNET_h2s (&dk->h_denom_pub.hash),
denom->section); denom->section);
if (GNUNET_OK != if (GNUNET_OK !=
TES_transmit (client->csock, TES_transmit (client->csock,
@ -311,7 +311,7 @@ notify_client_dk_del (struct TES_Client *client,
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Sending RSA denomination expiration %s\n", "Sending RSA denomination expiration %s\n",
GNUNET_h2s (&dk->h_denom_pub)); GNUNET_h2s (&dk->h_denom_pub.hash));
if (GNUNET_OK != if (GNUNET_OK !=
TES_transmit (client->csock, TES_transmit (client->csock,
&pn.header)) &pn.header))
@ -345,7 +345,7 @@ handle_sign_request (struct TES_Client *client,
GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
dk = GNUNET_CONTAINER_multihashmap_get (keys, dk = GNUNET_CONTAINER_multihashmap_get (keys,
&sr->h_denom_pub); &sr->h_denom_pub.hash);
if (NULL == dk) if (NULL == dk)
{ {
struct TALER_CRYPTO_SignFailure sf = { struct TALER_CRYPTO_SignFailure sf = {
@ -357,7 +357,7 @@ handle_sign_request (struct TES_Client *client,
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Signing request failed, denomination key %s unknown\n", "Signing request failed, denomination key %s unknown\n",
GNUNET_h2s (&sr->h_denom_pub)); GNUNET_h2s (&sr->h_denom_pub.hash));
return TES_transmit (client->csock, return TES_transmit (client->csock,
&sf.header); &sf.header);
} }
@ -374,7 +374,7 @@ handle_sign_request (struct TES_Client *client,
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Signing request failed, denomination key %s is not yet valid\n", "Signing request failed, denomination key %s is not yet valid\n",
GNUNET_h2s (&sr->h_denom_pub)); GNUNET_h2s (&sr->h_denom_pub.hash));
return TES_transmit (client->csock, return TES_transmit (client->csock,
&sf.header); &sf.header);
} }
@ -382,12 +382,12 @@ handle_sign_request (struct TES_Client *client,
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received request to sign over %u bytes with key %s\n", "Received request to sign over %u bytes with key %s\n",
(unsigned int) blinded_msg_size, (unsigned int) blinded_msg_size,
GNUNET_h2s (&sr->h_denom_pub)); GNUNET_h2s (&sr->h_denom_pub.hash));
GNUNET_assert (dk->rc < UINT_MAX); GNUNET_assert (dk->rc < UINT_MAX);
dk->rc++; dk->rc++;
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
rsa_signature rsa_signature
= GNUNET_CRYPTO_rsa_sign_blinded (dk->denom_priv.rsa_private_key, = GNUNET_CRYPTO_rsa_sign_blinded (dk->denom_priv,
blinded_msg, blinded_msg,
blinded_msg_size); blinded_msg_size);
GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
@ -471,7 +471,7 @@ setup_key (struct DenominationKey *dk,
buf_size = GNUNET_CRYPTO_rsa_private_key_encode (priv, buf_size = GNUNET_CRYPTO_rsa_private_key_encode (priv,
&buf); &buf);
GNUNET_CRYPTO_rsa_public_key_hash (pub, GNUNET_CRYPTO_rsa_public_key_hash (pub,
&dk->h_denom_pub); &dk->h_denom_pub.hash);
GNUNET_asprintf (&dk->filename, GNUNET_asprintf (&dk->filename,
"%s/%s/%llu", "%s/%s/%llu",
keydir, keydir,
@ -495,24 +495,24 @@ setup_key (struct DenominationKey *dk,
GNUNET_free (buf); GNUNET_free (buf);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Setup fresh private key %s at %s in `%s' (generation #%llu)\n", "Setup fresh private key %s at %s in `%s' (generation #%llu)\n",
GNUNET_h2s (&dk->h_denom_pub), GNUNET_h2s (&dk->h_denom_pub.hash),
GNUNET_STRINGS_absolute_time_to_string (dk->anchor), GNUNET_STRINGS_absolute_time_to_string (dk->anchor),
dk->filename, dk->filename,
(unsigned long long) key_gen); (unsigned long long) key_gen);
dk->denom_priv.rsa_private_key = priv; dk->denom_priv = priv;
dk->denom_pub.rsa_public_key = pub; dk->denom_pub = pub;
dk->key_gen = key_gen; dk->key_gen = key_gen;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CONTAINER_multihashmap_put ( GNUNET_CONTAINER_multihashmap_put (
keys, keys,
&dk->h_denom_pub, &dk->h_denom_pub.hash,
dk, dk,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Duplicate private key created! Terminating.\n"); "Duplicate private key created! Terminating.\n");
GNUNET_CRYPTO_rsa_private_key_free (dk->denom_priv.rsa_private_key); GNUNET_CRYPTO_rsa_private_key_free (dk->denom_priv);
GNUNET_CRYPTO_rsa_public_key_free (dk->denom_pub.rsa_public_key); GNUNET_CRYPTO_rsa_public_key_free (dk->denom_pub);
GNUNET_free (dk->filename); GNUNET_free (dk->filename);
GNUNET_free (dk); GNUNET_free (dk);
return GNUNET_SYSERR; return GNUNET_SYSERR;
@ -563,13 +563,13 @@ handle_revoke_request (struct TES_Client *client,
GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
dk = GNUNET_CONTAINER_multihashmap_get (keys, dk = GNUNET_CONTAINER_multihashmap_get (keys,
&rr->h_denom_pub); &rr->h_denom_pub.hash);
if (NULL == dk) if (NULL == dk)
{ {
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Revocation request ignored, denomination key %s unknown\n", "Revocation request ignored, denomination key %s unknown\n",
GNUNET_h2s (&rr->h_denom_pub)); GNUNET_h2s (&rr->h_denom_pub.hash));
return GNUNET_OK; return GNUNET_OK;
} }
@ -877,7 +877,7 @@ update_keys (struct Denomination *denom,
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_remove ( GNUNET_CONTAINER_multihashmap_remove (
keys, keys,
&key->h_denom_pub, &key->h_denom_pub.hash,
key)); key));
if ( (! key->purge) && if ( (! key->purge) &&
(0 != unlink (key->filename)) ) (0 != unlink (key->filename)) )
@ -885,8 +885,8 @@ update_keys (struct Denomination *denom,
"unlink", "unlink",
key->filename); key->filename);
GNUNET_free (key->filename); GNUNET_free (key->filename);
GNUNET_CRYPTO_rsa_private_key_free (key->denom_priv.rsa_private_key); GNUNET_CRYPTO_rsa_private_key_free (key->denom_priv);
GNUNET_CRYPTO_rsa_public_key_free (key->denom_pub.rsa_public_key); GNUNET_CRYPTO_rsa_public_key_free (key->denom_pub);
GNUNET_free (key); GNUNET_free (key);
key = nxt; key = nxt;
} }
@ -1025,23 +1025,23 @@ parse_key (struct Denomination *denom,
return; return;
} }
dk = GNUNET_new (struct DenominationKey); dk = GNUNET_new (struct DenominationKey);
dk->denom_priv.rsa_private_key = priv; dk->denom_priv = priv;
dk->denom = denom; dk->denom = denom;
dk->anchor = anchor; dk->anchor = anchor;
dk->filename = GNUNET_strdup (filename); dk->filename = GNUNET_strdup (filename);
GNUNET_CRYPTO_rsa_public_key_hash (pub, GNUNET_CRYPTO_rsa_public_key_hash (pub,
&dk->h_denom_pub); &dk->h_denom_pub.hash);
dk->denom_pub.rsa_public_key = pub; dk->denom_pub = pub;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CONTAINER_multihashmap_put ( GNUNET_CONTAINER_multihashmap_put (
keys, keys,
&dk->h_denom_pub, &dk->h_denom_pub.hash,
dk, dk,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Duplicate private key %s detected in file `%s'. Skipping.\n", "Duplicate private key %s detected in file `%s'. Skipping.\n",
GNUNET_h2s (&dk->h_denom_pub), GNUNET_h2s (&dk->h_denom_pub.hash),
filename); filename);
GNUNET_CRYPTO_rsa_private_key_free (priv); GNUNET_CRYPTO_rsa_private_key_free (priv);
GNUNET_CRYPTO_rsa_public_key_free (pub); GNUNET_CRYPTO_rsa_public_key_free (pub);
@ -1063,7 +1063,7 @@ parse_key (struct Denomination *denom,
dk); dk);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Imported key %s from `%s'\n", "Imported key %s from `%s'\n",
GNUNET_h2s (&dk->h_denom_pub), GNUNET_h2s (&dk->h_denom_pub.hash),
filename); filename);
} }
} }

View File

@ -74,7 +74,7 @@ struct KeyData
/** /**
* Hash of the public key. * Hash of the public key.
*/ */
struct GNUNET_HashCode h_denom_pub; struct TALER_DenominationHash h_denom_pub;
/** /**
* Full public key. * Full public key.
@ -122,7 +122,7 @@ key_cb (void *cls,
const char *section_name, const char *section_name,
struct GNUNET_TIME_Absolute start_time, struct GNUNET_TIME_Absolute start_time,
struct GNUNET_TIME_Relative validity_duration, struct GNUNET_TIME_Relative validity_duration,
const struct GNUNET_HashCode *h_denom_pub, const struct TALER_DenominationHash *h_denom_pub,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModulePublicKeyP *sm_pub,
const struct TALER_SecurityModuleSignatureP *sm_sig) const struct TALER_SecurityModuleSignatureP *sm_sig)
@ -131,7 +131,7 @@ key_cb (void *cls,
(void) sm_sig; (void) sm_sig;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Key notification about key %s in `%s'\n", "Key notification about key %s in `%s'\n",
GNUNET_h2s (h_denom_pub), GNUNET_h2s (&h_denom_pub->hash),
section_name); section_name);
if (0 == validity_duration.rel_value_us) if (0 == validity_duration.rel_value_us)
{ {
@ -145,8 +145,7 @@ key_cb (void *cls,
{ {
keys[i].valid = false; keys[i].valid = false;
keys[i].revoked = false; keys[i].revoked = false;
GNUNET_CRYPTO_rsa_public_key_free (keys[i].denom_pub.rsa_public_key); TALER_denom_pub_free (&keys[i].denom_pub);
keys[i].denom_pub.rsa_public_key = NULL;
GNUNET_assert (num_keys > 0); GNUNET_assert (num_keys > 0);
num_keys--; num_keys--;
found = true; found = true;
@ -167,8 +166,8 @@ key_cb (void *cls,
keys[i].h_denom_pub = *h_denom_pub; keys[i].h_denom_pub = *h_denom_pub;
keys[i].start_time = start_time; keys[i].start_time = start_time;
keys[i].validity_duration = validity_duration; keys[i].validity_duration = validity_duration;
keys[i].denom_pub.rsa_public_key TALER_denom_pub_deep_copy (&keys[i].denom_pub,
= GNUNET_CRYPTO_rsa_public_key_dup (denom_pub->rsa_public_key); denom_pub);
num_keys++; num_keys++;
return; return;
} }
@ -211,7 +210,7 @@ test_revocation (struct TALER_CRYPTO_DenominationHelper *dh)
keys[j].revoked = true; keys[j].revoked = true;
fprintf (stderr, fprintf (stderr,
"Revoking key %s ...", "Revoking key %s ...",
GNUNET_h2s (&keys[j].h_denom_pub)); GNUNET_h2s (&keys[j].h_denom_pub.hash));
TALER_CRYPTO_helper_denom_revoke (dh, TALER_CRYPTO_helper_denom_revoke (dh,
&keys[j].h_denom_pub); &keys[j].h_denom_pub);
for (unsigned int k = 0; k<1000; k++) for (unsigned int k = 0; k<1000; k++)
@ -247,42 +246,35 @@ test_revocation (struct TALER_CRYPTO_DenominationHelper *dh)
static int static int
test_signing (struct TALER_CRYPTO_DenominationHelper *dh) test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
{ {
struct TALER_DenominationSignature ds; struct TALER_BlindedDenominationSignature ds;
enum TALER_ErrorCode ec; enum TALER_ErrorCode ec;
bool success = false; bool success = false;
struct GNUNET_HashCode m_hash; struct TALER_PlanchetSecretsP ps;
struct GNUNET_CRYPTO_RsaBlindingKeySecret bks; struct TALER_CoinPubHash c_hash;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, TALER_planchet_setup_random (&ps);
&bks,
sizeof (bks));
GNUNET_CRYPTO_hash ("Hello",
strlen ("Hello"),
&m_hash);
for (unsigned int i = 0; i<MAX_KEYS; i++) for (unsigned int i = 0; i<MAX_KEYS; i++)
{ {
if (! keys[i].valid) if (! keys[i].valid)
continue; continue;
{ {
void *buf; struct TALER_PlanchetDetail pd;
size_t buf_size;
GNUNET_assert (GNUNET_YES == GNUNET_assert (GNUNET_YES ==
TALER_rsa_blind (&m_hash, TALER_planchet_prepare (&keys[i].denom_pub,
&bks, &ps,
keys[i].denom_pub.rsa_public_key, &c_hash,
&buf, &pd));
&buf_size));
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Requesting signature over %u bytes with key %s\n", "Requesting signature over %u bytes with key %s\n",
(unsigned int) buf_size, (unsigned int) pd.coin_ev_size,
GNUNET_h2s (&keys[i].h_denom_pub)); GNUNET_h2s (&keys[i].h_denom_pub.hash));
ds = TALER_CRYPTO_helper_denom_sign (dh, ds = TALER_CRYPTO_helper_denom_sign (dh,
&keys[i].h_denom_pub, &keys[i].h_denom_pub,
buf, pd.coin_ev,
buf_size, pd.coin_ev_size,
&ec); &ec);
GNUNET_free (buf); GNUNET_free (pd.coin_ev);
} }
switch (ec) switch (ec)
{ {
@ -302,32 +294,33 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
return 5; return 5;
} }
{ {
struct GNUNET_CRYPTO_RsaSignature *rs; struct TALER_DenominationSignature rs;
rs = TALER_rsa_unblind (ds.rsa_signature, if (GNUNET_OK !=
&bks, TALER_denom_sig_unblind (&rs,
keys[i].denom_pub.rsa_public_key); &ds,
if (NULL == rs) &ps.blinding_key,
&keys[i].denom_pub))
{ {
GNUNET_break (0); GNUNET_break (0);
return 6; return 6;
} }
GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature); TALER_blinded_denom_sig_free (&ds);
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_rsa_verify (&m_hash, TALER_denom_pub_verify (&keys[i].denom_pub,
rs, &rs,
keys[i].denom_pub.rsa_public_key)) &c_hash))
{ {
/* signature invalid */ /* signature invalid */
GNUNET_break (0); GNUNET_break (0);
GNUNET_CRYPTO_rsa_signature_free (rs); TALER_denom_sig_free (&rs);
return 7; return 7;
} }
GNUNET_CRYPTO_rsa_signature_free (rs); TALER_denom_sig_free (&rs);
} }
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received valid signature for key %s\n", "Received valid signature for key %s\n",
GNUNET_h2s (&keys[i].h_denom_pub)); GNUNET_h2s (&keys[i].h_denom_pub.hash));
success = true; success = true;
break; break;
case TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY: case TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY:
@ -362,8 +355,7 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
/* check signing does not work if the key is unknown */ /* check signing does not work if the key is unknown */
{ {
struct GNUNET_HashCode rnd; struct TALER_DenominationHash rnd;
struct TALER_DenominationSignature ds;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&rnd, &rnd,
@ -376,13 +368,13 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec) if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec)
{ {
if (TALER_EC_NONE == ec) if (TALER_EC_NONE == ec)
GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature); TALER_blinded_denom_sig_free (&ds);
GNUNET_break (0); GNUNET_break (0);
return 17; return 17;
} }
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Signing with invalid key %s failed as desired\n", "Signing with invalid key %s failed as desired\n",
GNUNET_h2s (&rnd)); GNUNET_h2s (&rnd.hash));
} }
return 0; return 0;
} }
@ -398,18 +390,12 @@ static int
perf_signing (struct TALER_CRYPTO_DenominationHelper *dh, perf_signing (struct TALER_CRYPTO_DenominationHelper *dh,
const char *type) const char *type)
{ {
struct TALER_DenominationSignature ds; struct TALER_BlindedDenominationSignature ds;
enum TALER_ErrorCode ec; enum TALER_ErrorCode ec;
struct GNUNET_HashCode m_hash;
struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
struct GNUNET_TIME_Relative duration; struct GNUNET_TIME_Relative duration;
struct TALER_PlanchetSecretsP ps;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, TALER_planchet_setup_random (&ps);
&bks,
sizeof (bks));
GNUNET_CRYPTO_hash ("Hello",
strlen ("Hello"),
&m_hash);
duration = GNUNET_TIME_UNIT_ZERO; duration = GNUNET_TIME_UNIT_ZERO;
TALER_CRYPTO_helper_denom_poll (dh); TALER_CRYPTO_helper_denom_poll (dh);
for (unsigned int j = 0; j<NUM_SIGN_PERFS;) for (unsigned int j = 0; j<NUM_SIGN_PERFS;)
@ -425,15 +411,14 @@ perf_signing (struct TALER_CRYPTO_DenominationHelper *dh,
keys[i].validity_duration.rel_value_us) keys[i].validity_duration.rel_value_us)
continue; continue;
{ {
void *buf; struct TALER_CoinPubHash c_hash;
size_t buf_size; struct TALER_PlanchetDetail pd;
GNUNET_assert (GNUNET_YES == GNUNET_assert (GNUNET_YES ==
TALER_rsa_blind (&m_hash, TALER_planchet_prepare (&keys[i].denom_pub,
&bks, &ps,
keys[i].denom_pub.rsa_public_key, &c_hash,
&buf, &pd));
&buf_size));
/* use this key as long as it works */ /* use this key as long as it works */
while (1) while (1)
{ {
@ -442,20 +427,20 @@ perf_signing (struct TALER_CRYPTO_DenominationHelper *dh,
ds = TALER_CRYPTO_helper_denom_sign (dh, ds = TALER_CRYPTO_helper_denom_sign (dh,
&keys[i].h_denom_pub, &keys[i].h_denom_pub,
buf, pd.coin_ev,
buf_size, pd.coin_ev_size,
&ec); &ec);
if (TALER_EC_NONE != ec) if (TALER_EC_NONE != ec)
break; break;
delay = GNUNET_TIME_absolute_get_duration (start); delay = GNUNET_TIME_absolute_get_duration (start);
duration = GNUNET_TIME_relative_add (duration, duration = GNUNET_TIME_relative_add (duration,
delay); delay);
GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature); TALER_blinded_denom_sig_free (&ds);
j++; j++;
if (NUM_SIGN_PERFS <= j) if (NUM_SIGN_PERFS <= j)
break; break;
} }
GNUNET_free (buf); GNUNET_free (pd.coin_ev);
} }
} /* for i */ } /* for i */
} /* for j */ } /* for j */
@ -592,8 +577,7 @@ run_test (void)
for (unsigned int i = 0; i<MAX_KEYS; i++) for (unsigned int i = 0; i<MAX_KEYS; i++)
if (keys[i].valid) if (keys[i].valid)
{ {
GNUNET_CRYPTO_rsa_public_key_free (keys[i].denom_pub.rsa_public_key); TALER_denom_pub_free (&keys[i].denom_pub);
keys[i].denom_pub.rsa_public_key = NULL;
GNUNET_assert (num_keys > 0); GNUNET_assert (num_keys > 0);
num_keys--; num_keys--;
} }