start with testing crypto rsa helper
This commit is contained in:
parent
9b68dbb8e6
commit
a9fb94e916
1
src/util/.gitignore
vendored
1
src/util/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
taler-config
|
taler-config
|
||||||
test_payto
|
test_payto
|
||||||
taler-helper-crypto-rsa
|
taler-helper-crypto-rsa
|
||||||
|
test_helper_rsa
|
||||||
|
@ -7,7 +7,7 @@ if USE_COVERAGE
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
libexecdir = $(pkglibdir)/libexec/
|
libexecdir = $(libdir)/taler/libexec
|
||||||
|
|
||||||
pkgcfgdir = $(prefix)/share/taler/config.d/
|
pkgcfgdir = $(prefix)/share/taler/config.d/
|
||||||
|
|
||||||
@ -17,7 +17,8 @@ pkgcfg_DATA = \
|
|||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
paths.conf \
|
paths.conf \
|
||||||
taler-config.in
|
taler-config.in \
|
||||||
|
test_helper_rsa.conf
|
||||||
|
|
||||||
libexec_PROGRAMS = \
|
libexec_PROGRAMS = \
|
||||||
taler-helper-crypto-rsa
|
taler-helper-crypto-rsa
|
||||||
@ -72,9 +73,12 @@ libtalerutil_la_LDFLAGS = \
|
|||||||
-export-dynamic -no-undefined
|
-export-dynamic -no-undefined
|
||||||
|
|
||||||
|
|
||||||
|
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
|
||||||
|
|
||||||
check_PROGRAMS = \
|
check_PROGRAMS = \
|
||||||
test_amount \
|
test_amount \
|
||||||
test_crypto \
|
test_crypto \
|
||||||
|
test_helper_rsa \
|
||||||
test_payto \
|
test_payto \
|
||||||
test_url
|
test_url
|
||||||
|
|
||||||
@ -100,6 +104,12 @@ test_payto_LDADD = \
|
|||||||
-lgnunetutil \
|
-lgnunetutil \
|
||||||
libtalerutil.la
|
libtalerutil.la
|
||||||
|
|
||||||
|
test_helper_rsa_SOURCES = \
|
||||||
|
test_helper_rsa.c
|
||||||
|
test_helper_rsa_LDADD = \
|
||||||
|
-lgnunetutil \
|
||||||
|
libtalerutil.la
|
||||||
|
|
||||||
test_url_SOURCES = \
|
test_url_SOURCES = \
|
||||||
test_url.c
|
test_url.c
|
||||||
test_url_LDADD = \
|
test_url_LDADD = \
|
||||||
|
@ -41,6 +41,16 @@ struct TALER_CRYPTO_DenominationHelper
|
|||||||
*/
|
*/
|
||||||
struct sockaddr_un sa;
|
struct sockaddr_un sa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Socket address of this process.
|
||||||
|
*/
|
||||||
|
struct sockaddr_un my_sa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template for @e my_sa.
|
||||||
|
*/
|
||||||
|
char *template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The UNIX domain socket, -1 if we are currently not connected.
|
* The UNIX domain socket, -1 if we are currently not connected.
|
||||||
*/
|
*/
|
||||||
@ -58,6 +68,10 @@ static void
|
|||||||
do_disconnect (struct TALER_CRYPTO_DenominationHelper *dh)
|
do_disconnect (struct TALER_CRYPTO_DenominationHelper *dh)
|
||||||
{
|
{
|
||||||
GNUNET_break (0 == close (dh->sock));
|
GNUNET_break (0 == close (dh->sock));
|
||||||
|
if (0 != unlink (dh->my_sa.sun_path))
|
||||||
|
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"unlink",
|
||||||
|
dh->my_sa.sun_path);
|
||||||
dh->sock = -1;
|
dh->sock = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,18 +96,73 @@ try_connect (struct TALER_CRYPTO_DenominationHelper *dh)
|
|||||||
"socket");
|
"socket");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (0 != connect (dh->sock,
|
|
||||||
(const struct sockaddr *) &dh->sa,
|
|
||||||
sizeof (dh->sa)))
|
|
||||||
{
|
{
|
||||||
if (EINPROGRESS != dh->sock)
|
char *tmpdir;
|
||||||
|
|
||||||
|
tmpdir = GNUNET_DISK_mktemp (dh->template);
|
||||||
|
if (NULL == tmpdir)
|
||||||
{
|
{
|
||||||
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
|
||||||
"connect");
|
|
||||||
do_disconnect (dh);
|
do_disconnect (dh);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* we use >= here because we want the sun_path to always
|
||||||
|
be 0-terminated */
|
||||||
|
if (strlen (tmpdir) >= sizeof (dh->sa.sun_path))
|
||||||
|
{
|
||||||
|
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"PATHS",
|
||||||
|
"TALER_RUNTIME_DIR",
|
||||||
|
"path too long");
|
||||||
|
GNUNET_free (tmpdir);
|
||||||
|
do_disconnect (dh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dh->my_sa.sun_family = AF_UNIX;
|
||||||
|
strncpy (dh->my_sa.sun_path,
|
||||||
|
tmpdir,
|
||||||
|
sizeof (dh->sa.sun_path));
|
||||||
|
if (0 != unlink (tmpdir))
|
||||||
|
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"unlink",
|
||||||
|
tmpdir);
|
||||||
|
GNUNET_free (tmpdir);
|
||||||
}
|
}
|
||||||
|
if (0 != bind (dh->sock,
|
||||||
|
(const struct sockaddr *) &dh->my_sa,
|
||||||
|
sizeof (dh->my_sa)))
|
||||||
|
{
|
||||||
|
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"bind");
|
||||||
|
do_disconnect (dh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct GNUNET_MessageHeader hdr = {
|
||||||
|
.size = htons (sizeof (hdr)),
|
||||||
|
.type = htons (TALER_HELPER_RSA_MT_REQ_INIT)
|
||||||
|
};
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
ret = sendto (dh->sock,
|
||||||
|
&hdr,
|
||||||
|
sizeof (hdr),
|
||||||
|
0,
|
||||||
|
(const struct sockaddr *) &dh->sa,
|
||||||
|
sizeof (dh->sa));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"sendto",
|
||||||
|
dh->sa.sun_path);
|
||||||
|
do_disconnect (dh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* We are using SOCK_DGRAM, partial writes should not be possible */
|
||||||
|
GNUNET_break (((size_t) ret) == sizeof (hdr));
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"Successfully sent REQ_INIT\n");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -117,7 +186,9 @@ TALER_CRYPTO_helper_denom_connect (
|
|||||||
"UNIXPATH");
|
"UNIXPATH");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (strlen (unixpath) > sizeof (dh->sa.sun_path))
|
/* we use >= here because we want the sun_path to always
|
||||||
|
be 0-terminated */
|
||||||
|
if (strlen (unixpath) >= sizeof (dh->sa.sun_path))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"taler-helper-crypto-rsa",
|
"taler-helper-crypto-rsa",
|
||||||
@ -129,10 +200,39 @@ TALER_CRYPTO_helper_denom_connect (
|
|||||||
dh = GNUNET_new (struct TALER_CRYPTO_DenominationHelper);
|
dh = GNUNET_new (struct TALER_CRYPTO_DenominationHelper);
|
||||||
dh->dkc = dkc;
|
dh->dkc = dkc;
|
||||||
dh->dkc_cls = dkc_cls;
|
dh->dkc_cls = dkc_cls;
|
||||||
|
dh->sa.sun_family = AF_UNIX;
|
||||||
strncpy (dh->sa.sun_path,
|
strncpy (dh->sa.sun_path,
|
||||||
unixpath,
|
unixpath,
|
||||||
sizeof (dh->sa.sun_path));
|
sizeof (dh->sa.sun_path));
|
||||||
dh->sock = -1;
|
dh->sock = -1;
|
||||||
|
{
|
||||||
|
char *tmpdir;
|
||||||
|
char *template;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CONFIGURATION_get_value_filename (cfg,
|
||||||
|
"PATHS",
|
||||||
|
"TALER_RUNTIME_DIR",
|
||||||
|
&tmpdir))
|
||||||
|
{
|
||||||
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"PATHS",
|
||||||
|
"TALER_RUNTIME_DIR");
|
||||||
|
tmpdir = GNUNET_strdup ("/tmp");
|
||||||
|
}
|
||||||
|
GNUNET_asprintf (&template,
|
||||||
|
"%s/crypto-rsa-client/XXXXXX",
|
||||||
|
tmpdir);
|
||||||
|
GNUNET_free (tmpdir);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_DISK_directory_create_for_file (template))
|
||||||
|
{
|
||||||
|
GNUNET_free (dh);
|
||||||
|
GNUNET_free (template);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dh->template = template;
|
||||||
|
}
|
||||||
TALER_CRYPTO_helper_poll (dh);
|
TALER_CRYPTO_helper_poll (dh);
|
||||||
return dh;
|
return dh;
|
||||||
}
|
}
|
||||||
@ -157,6 +257,8 @@ TALER_CRYPTO_helper_poll (struct TALER_CRYPTO_DenominationHelper *dh)
|
|||||||
MSG_DONTWAIT);
|
MSG_DONTWAIT);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
if (EAGAIN == errno)
|
||||||
|
break;
|
||||||
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"recv");
|
"recv");
|
||||||
do_disconnect (dh);
|
do_disconnect (dh);
|
||||||
@ -180,10 +282,22 @@ TALER_CRYPTO_helper_poll (struct TALER_CRYPTO_DenominationHelper *dh)
|
|||||||
struct TALER_DenominationPublicKey denom_pub;
|
struct TALER_DenominationPublicKey denom_pub;
|
||||||
struct GNUNET_HashCode h_denom_pub;
|
struct GNUNET_HashCode h_denom_pub;
|
||||||
|
|
||||||
if ( (sizeof (*kan) < ret) ||
|
if (sizeof (*kan) > ret)
|
||||||
(sizeof (*kan) + ntohs (kan->pub_size) + ntohs (
|
{
|
||||||
kan->section_name_len)) ||
|
GNUNET_break_op (0);
|
||||||
('\0' != buf[ret - 1]) )
|
do_disconnect (dh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ret !=
|
||||||
|
sizeof (*kan)
|
||||||
|
+ ntohs (kan->pub_size)
|
||||||
|
+ ntohs (kan->section_name_len))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
do_disconnect (dh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ('\0' != buf[ret - 1])
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
do_disconnect (dh);
|
do_disconnect (dh);
|
||||||
@ -267,14 +381,16 @@ TALER_CRYPTO_helper_denom_sign (
|
|||||||
memcpy (&sr[1],
|
memcpy (&sr[1],
|
||||||
msg,
|
msg,
|
||||||
msg_size);
|
msg_size);
|
||||||
ret = send (dh->sock,
|
ret = sendto (dh->sock,
|
||||||
buf,
|
buf,
|
||||||
sizeof (buf),
|
sizeof (buf),
|
||||||
0);
|
0,
|
||||||
|
&dh->sa,
|
||||||
|
sizeof (dh->sa));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"send");
|
"sendto");
|
||||||
do_disconnect (dh);
|
do_disconnect (dh);
|
||||||
*ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
|
*ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
|
||||||
return ds;
|
return ds;
|
||||||
@ -378,14 +494,16 @@ TALER_CRYPTO_helper_denom_revoke (
|
|||||||
try_connect (dh);
|
try_connect (dh);
|
||||||
if (-1 == dh->sock)
|
if (-1 == dh->sock)
|
||||||
return; /* give up */
|
return; /* give up */
|
||||||
ret = send (dh->sock,
|
ret = sendto (dh->sock,
|
||||||
&rr,
|
&rr,
|
||||||
sizeof (rr),
|
sizeof (rr),
|
||||||
0);
|
0,
|
||||||
|
(const struct sockaddr *) &dh->sa,
|
||||||
|
sizeof (dh->sa));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"send");
|
"sendto");
|
||||||
do_disconnect (dh);
|
do_disconnect (dh);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -399,6 +517,7 @@ TALER_CRYPTO_helper_denom_disconnect (
|
|||||||
struct TALER_CRYPTO_DenominationHelper *dh)
|
struct TALER_CRYPTO_DenominationHelper *dh)
|
||||||
{
|
{
|
||||||
do_disconnect (dh);
|
do_disconnect (dh);
|
||||||
|
GNUNET_free (dh->template);
|
||||||
GNUNET_free (dh);
|
GNUNET_free (dh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ struct DenominationKey
|
|||||||
/**
|
/**
|
||||||
* Hash of this denomination's public key.
|
* Hash of this denomination's public key.
|
||||||
*/
|
*/
|
||||||
struct GNUNET_HashCode h_pub;
|
struct GNUNET_HashCode h_denom_pub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time at which this key is supposed to become valid.
|
* Time at which this key is supposed to become valid.
|
||||||
@ -181,26 +181,14 @@ struct Client
|
|||||||
struct Client *prev;
|
struct Client *prev;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Work created by this client, NULL for none.
|
* Client address.
|
||||||
*/
|
*/
|
||||||
struct WorkItem *work;
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client socket.
|
* Number of bytes used in @e addr.
|
||||||
*/
|
*/
|
||||||
struct GNUNET_NETWORK_Handle *sock;
|
socklen_t addr_size;
|
||||||
|
|
||||||
/**
|
|
||||||
* Client task to read from @e sock. NULL if we are working.
|
|
||||||
*/
|
|
||||||
struct GNUNET_SCHEDULER_Task *task;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag set to true if this client has disconnected. Used
|
|
||||||
* by the workers to detect that they must free the client
|
|
||||||
* instead of returning the result.
|
|
||||||
*/
|
|
||||||
bool gone;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -218,11 +206,6 @@ struct WorkItem
|
|||||||
*/
|
*/
|
||||||
struct WorkItem *prev;
|
struct WorkItem *prev;
|
||||||
|
|
||||||
/**
|
|
||||||
* The client that created the request.
|
|
||||||
*/
|
|
||||||
struct Client *client;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key to be used for this operation.
|
* Key to be used for this operation.
|
||||||
*/
|
*/
|
||||||
@ -244,6 +227,16 @@ struct WorkItem
|
|||||||
*/
|
*/
|
||||||
size_t blinded_msg_size;
|
size_t blinded_msg_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client address.
|
||||||
|
*/
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of bytes used in @e addr.
|
||||||
|
*/
|
||||||
|
socklen_t addr_size;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -305,7 +298,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *keys;
|
|||||||
/**
|
/**
|
||||||
* Our listen socket.
|
* Our listen socket.
|
||||||
*/
|
*/
|
||||||
static struct GNUNET_NETWORK_Handle *lsock;
|
static struct GNUNET_NETWORK_Handle *unix_sock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path where we are listening.
|
* Path where we are listening.
|
||||||
@ -315,7 +308,7 @@ static char *unixpath;
|
|||||||
/**
|
/**
|
||||||
* Task run to accept new inbound connections.
|
* Task run to accept new inbound connections.
|
||||||
*/
|
*/
|
||||||
static struct GNUNET_SCHEDULER_Task *accept_task;
|
static struct GNUNET_SCHEDULER_Task *read_task;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task run to generate new keys.
|
* Task run to generate new keys.
|
||||||
@ -464,20 +457,10 @@ sign_worker (void *cls)
|
|||||||
static void
|
static void
|
||||||
free_client (struct Client *client)
|
free_client (struct Client *client)
|
||||||
{
|
{
|
||||||
if (NULL != client->task)
|
|
||||||
{
|
|
||||||
GNUNET_SCHEDULER_cancel (client->task);
|
|
||||||
client->task = NULL;
|
|
||||||
}
|
|
||||||
GNUNET_NETWORK_socket_close (client->sock);
|
|
||||||
client->sock = NULL;
|
|
||||||
GNUNET_CONTAINER_DLL_remove (clients_head,
|
GNUNET_CONTAINER_DLL_remove (clients_head,
|
||||||
clients_tail,
|
clients_tail,
|
||||||
client);
|
client);
|
||||||
if (NULL != client->work)
|
GNUNET_free (client);
|
||||||
client->gone = true;
|
|
||||||
else
|
|
||||||
GNUNET_free (client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -490,21 +473,6 @@ static void
|
|||||||
read_job (void *cls);
|
read_job (void *cls);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start reading requests from the @a client.
|
|
||||||
*
|
|
||||||
* @param client client to read requests from.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
client_next (struct Client *client)
|
|
||||||
{
|
|
||||||
client->task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
|
|
||||||
client->sock,
|
|
||||||
&read_job,
|
|
||||||
client);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free @a dk. It must already have been removed from #keys and the
|
* Free @a dk. It must already have been removed from #keys and the
|
||||||
* denomination's DLL.
|
* denomination's DLL.
|
||||||
@ -524,25 +492,27 @@ free_dk (struct DenominationKey *dk)
|
|||||||
/**
|
/**
|
||||||
* Send a message starting with @a hdr to @a client.
|
* Send a message starting with @a hdr to @a client.
|
||||||
*
|
*
|
||||||
* @param client where to send @a hdr
|
* @param addr address where to send the message
|
||||||
|
* @param addr_size number of bytes in @a addr
|
||||||
* @param hdr beginning of the message, length indicated in size field
|
* @param hdr beginning of the message, length indicated in size field
|
||||||
* @return #GNUNET_OK on success
|
* @return #GNUNET_OK on success
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
transmit_to_client (struct Client *client,
|
transmit (const struct sockaddr_un *addr,
|
||||||
const struct GNUNET_MessageHeader *hdr)
|
socklen_t addr_size,
|
||||||
|
const struct GNUNET_MessageHeader *hdr)
|
||||||
{
|
{
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
ret = send (GNUNET_NETWORK_get_fd (client->sock),
|
ret = GNUNET_NETWORK_socket_sendto (unix_sock,
|
||||||
hdr,
|
hdr,
|
||||||
ntohs (hdr->size),
|
ntohs (hdr->size),
|
||||||
0);
|
(const struct sockaddr *) addr,
|
||||||
|
addr_size);
|
||||||
if (ret != ntohs (hdr->size))
|
if (ret != ntohs (hdr->size))
|
||||||
{
|
{
|
||||||
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO,
|
||||||
"send");
|
"sendto");
|
||||||
free_client (client);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
@ -598,8 +568,9 @@ handle_done (void *cls)
|
|||||||
buf,
|
buf,
|
||||||
buf_size);
|
buf_size);
|
||||||
GNUNET_free (buf);
|
GNUNET_free (buf);
|
||||||
(void) transmit_to_client (wi->client,
|
(void) transmit (&wi->addr,
|
||||||
&sr->header);
|
wi->addr_size,
|
||||||
|
&sr->header);
|
||||||
GNUNET_free (sr);
|
GNUNET_free (sr);
|
||||||
}
|
}
|
||||||
GNUNET_free (wi);
|
GNUNET_free (wi);
|
||||||
@ -615,11 +586,13 @@ handle_done (void *cls)
|
|||||||
* signature using the respective key and return the result to
|
* signature using the respective key and return the result to
|
||||||
* the client.
|
* the client.
|
||||||
*
|
*
|
||||||
* @param client the client making the request
|
* @param addr address of the client making the request
|
||||||
|
* @param addr_size number of bytes in @a addr
|
||||||
* @param sr the request details
|
* @param sr the request details
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_sign_request (struct Client *client,
|
handle_sign_request (const struct sockaddr_un *addr,
|
||||||
|
socklen_t addr_size,
|
||||||
const struct TALER_CRYPTO_SignRequest *sr)
|
const struct TALER_CRYPTO_SignRequest *sr)
|
||||||
{
|
{
|
||||||
struct DenominationKey *dk;
|
struct DenominationKey *dk;
|
||||||
@ -638,15 +611,17 @@ handle_sign_request (struct Client *client,
|
|||||||
};
|
};
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Signing request failed, denomination key unknown\n");
|
"Signing request failed, denomination key %s unknown\n",
|
||||||
transmit_to_client (client,
|
GNUNET_h2s (&sr->h_denom_pub));
|
||||||
&sf.header);
|
(void) transmit (addr,
|
||||||
client_next (client);
|
addr_size,
|
||||||
|
&sf.header);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wi = GNUNET_new (struct WorkItem);
|
wi = GNUNET_new (struct WorkItem);
|
||||||
wi->client = client;
|
wi->addr = *addr;
|
||||||
|
wi->addr_size = addr_size;
|
||||||
wi->dk = dk;
|
wi->dk = dk;
|
||||||
dk->rc++;
|
dk->rc++;
|
||||||
wi->blinded_msg = GNUNET_memdup (blinded_msg,
|
wi->blinded_msg = GNUNET_memdup (blinded_msg,
|
||||||
@ -680,7 +655,6 @@ notify_client_dk_add (struct Client *client,
|
|||||||
void *buf;
|
void *buf;
|
||||||
void *p;
|
void *p;
|
||||||
size_t tlen;
|
size_t tlen;
|
||||||
int ret;
|
|
||||||
|
|
||||||
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.rsa_public_key,
|
||||||
&buf);
|
&buf);
|
||||||
@ -703,10 +677,23 @@ notify_client_dk_add (struct Client *client,
|
|||||||
memcpy (p + buf_len,
|
memcpy (p + buf_len,
|
||||||
denom->section,
|
denom->section,
|
||||||
nlen);
|
nlen);
|
||||||
ret = transmit_to_client (client,
|
{
|
||||||
&an->header);
|
int ret = GNUNET_OK;
|
||||||
GNUNET_free (an);
|
|
||||||
return ret;
|
if (GNUNET_OK !=
|
||||||
|
transmit (&client->addr,
|
||||||
|
client->addr_size,
|
||||||
|
&an->header))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Client %s must have disconnected\n",
|
||||||
|
client->addr.sun_path);
|
||||||
|
free_client (client);
|
||||||
|
ret = GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
GNUNET_free (an);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -724,11 +711,21 @@ notify_client_dk_del (struct Client *client,
|
|||||||
struct TALER_CRYPTO_RsaKeyPurgeNotification pn = {
|
struct TALER_CRYPTO_RsaKeyPurgeNotification pn = {
|
||||||
.header.type = htons (TALER_HELPER_RSA_MT_PURGE),
|
.header.type = htons (TALER_HELPER_RSA_MT_PURGE),
|
||||||
.header.size = htons (sizeof (pn)),
|
.header.size = htons (sizeof (pn)),
|
||||||
.h_denom_pub = dk->h_pub
|
.h_denom_pub = dk->h_denom_pub
|
||||||
};
|
};
|
||||||
|
|
||||||
return transmit_to_client (client,
|
if (GNUNET_OK !=
|
||||||
&pn.header);
|
transmit (&client->addr,
|
||||||
|
client->addr_size,
|
||||||
|
&pn.header))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Client %s must have disconnected\n",
|
||||||
|
client->addr.sun_path);
|
||||||
|
free_client (client);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -767,7 +764,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_pub);
|
&dk->h_denom_pub);
|
||||||
GNUNET_asprintf (&dk->filename,
|
GNUNET_asprintf (&dk->filename,
|
||||||
"%s/%s/%llu",
|
"%s/%s/%llu",
|
||||||
keydir,
|
keydir,
|
||||||
@ -789,13 +786,17 @@ setup_key (struct DenominationKey *dk,
|
|||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
GNUNET_free (buf);
|
GNUNET_free (buf);
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Setup fresh private key %s in `%s'\n",
|
||||||
|
GNUNET_h2s (&dk->h_denom_pub),
|
||||||
|
dk->filename);
|
||||||
dk->denom_priv.rsa_private_key = priv;
|
dk->denom_priv.rsa_private_key = priv;
|
||||||
dk->denom_pub.rsa_public_key = pub;
|
dk->denom_pub.rsa_public_key = pub;
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONTAINER_multihashmap_put (
|
GNUNET_CONTAINER_multihashmap_put (
|
||||||
keys,
|
keys,
|
||||||
&dk->h_pub,
|
&dk->h_denom_pub,
|
||||||
dk,
|
dk,
|
||||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
|
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
|
||||||
{
|
{
|
||||||
@ -839,11 +840,13 @@ setup_key (struct DenominationKey *dk,
|
|||||||
* Check if the key is still in use, and if so replace (!)
|
* Check if the key is still in use, and if so replace (!)
|
||||||
* it with a fresh key.
|
* it with a fresh key.
|
||||||
*
|
*
|
||||||
* @param client the client sending the request
|
* @param addr address of the client making the request
|
||||||
|
* @param addr_size number of bytes in @a addr
|
||||||
* @param rr the revocation request
|
* @param rr the revocation request
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_revoke_request (struct Client *client,
|
handle_revoke_request (const struct sockaddr_un *addr,
|
||||||
|
socklen_t addr_size,
|
||||||
const struct TALER_CRYPTO_RevokeRequest *rr)
|
const struct TALER_CRYPTO_RevokeRequest *rr)
|
||||||
{
|
{
|
||||||
struct DenominationKey *dk;
|
struct DenominationKey *dk;
|
||||||
@ -854,9 +857,9 @@ handle_revoke_request (struct Client *client,
|
|||||||
&rr->h_denom_pub);
|
&rr->h_denom_pub);
|
||||||
if (NULL == dk)
|
if (NULL == dk)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Revocation request ignored, denomination key unknown\n");
|
"Revocation request ignored, denomination key %s unknown\n",
|
||||||
client_next (client);
|
GNUNET_h2s (&rr->h_denom_pub));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -886,11 +889,13 @@ handle_revoke_request (struct Client *client,
|
|||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
GNUNET_CONTAINER_multihashmap_remove (
|
GNUNET_CONTAINER_multihashmap_remove (
|
||||||
keys,
|
keys,
|
||||||
&dk->h_pub,
|
&dk->h_denom_pub,
|
||||||
dk));
|
dk));
|
||||||
GNUNET_CONTAINER_DLL_remove (denom->keys_head,
|
GNUNET_CONTAINER_DLL_remove (denom->keys_head,
|
||||||
denom->keys_tail,
|
denom->keys_tail,
|
||||||
dk);
|
dk);
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Revocation complete\n");
|
||||||
|
|
||||||
/* Tell clients this key is gone */
|
/* Tell clients this key is gone */
|
||||||
{
|
{
|
||||||
@ -910,8 +915,6 @@ handle_revoke_request (struct Client *client,
|
|||||||
}
|
}
|
||||||
if (0 == dk->rc)
|
if (0 == dk->rc)
|
||||||
free_dk (dk);
|
free_dk (dk);
|
||||||
|
|
||||||
client_next (client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -921,129 +924,107 @@ read_job (void *cls)
|
|||||||
struct Client *client = cls;
|
struct Client *client = cls;
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
ssize_t buf_size;
|
ssize_t buf_size;
|
||||||
struct GNUNET_MessageHeader hdr;
|
const struct GNUNET_MessageHeader *hdr;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
socklen_t addr_size = sizeof (addr);
|
||||||
|
|
||||||
client->task = NULL;
|
read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
|
||||||
buf_size = GNUNET_NETWORK_socket_recv (client->sock,
|
unix_sock,
|
||||||
buf,
|
&read_job,
|
||||||
sizeof (buf));
|
NULL);
|
||||||
|
buf_size = GNUNET_NETWORK_socket_recvfrom (unix_sock,
|
||||||
|
buf,
|
||||||
|
sizeof (buf),
|
||||||
|
(struct sockaddr *) &addr,
|
||||||
|
&addr_size);
|
||||||
if (-1 == buf_size)
|
if (-1 == buf_size)
|
||||||
{
|
{
|
||||||
if (EAGAIN == errno)
|
|
||||||
{
|
|
||||||
client_next (client);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"recv");
|
"recv");
|
||||||
free_client (client);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (0 == buf_size)
|
if (0 == buf_size)
|
||||||
{
|
{
|
||||||
free_client (client);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (buf_size < sizeof (hdr))
|
if (buf_size < sizeof (struct GNUNET_MessageHeader))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hdr = (const struct GNUNET_MessageHeader *) buf;
|
||||||
|
if (ntohs (hdr->size) != buf_size)
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
free_client (client);
|
free_client (client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy (&hdr,
|
switch (ntohs (hdr->type))
|
||||||
buf,
|
|
||||||
sizeof (hdr));
|
|
||||||
if (ntohs (hdr.size) != buf_size)
|
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
case TALER_HELPER_RSA_MT_REQ_INIT:
|
||||||
free_client (client);
|
if (ntohs (hdr->size) != sizeof (struct GNUNET_MessageHeader))
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (ntohs (hdr.type))
|
|
||||||
{
|
|
||||||
case TALER_HELPER_RSA_MT_REQ_SIGN:
|
|
||||||
if (ntohs (hdr.size) <= sizeof (struct TALER_CRYPTO_SignRequest))
|
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
free_client (client);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handle_sign_request (client,
|
{
|
||||||
(const struct TALER_CRYPTO_SignRequest *) &hdr);
|
struct Client *client;
|
||||||
|
|
||||||
|
client = GNUNET_new (struct Client);
|
||||||
|
client->addr = addr;
|
||||||
|
client->addr_size = addr_size;
|
||||||
|
GNUNET_CONTAINER_DLL_insert (clients_head,
|
||||||
|
clients_tail,
|
||||||
|
client);
|
||||||
|
for (struct Denomination *denom = denom_head;
|
||||||
|
NULL != denom;
|
||||||
|
denom = denom->next)
|
||||||
|
{
|
||||||
|
for (struct DenominationKey *dk = denom->keys_head;
|
||||||
|
NULL != dk;
|
||||||
|
dk = dk->next)
|
||||||
|
{
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
notify_client_dk_add (client,
|
||||||
|
dk))
|
||||||
|
{
|
||||||
|
/* client died, skip the rest */
|
||||||
|
client = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL == client)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TALER_HELPER_RSA_MT_REQ_SIGN:
|
||||||
|
if (ntohs (hdr->size) <= sizeof (struct TALER_CRYPTO_SignRequest))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handle_sign_request (&addr,
|
||||||
|
addr_size,
|
||||||
|
(const struct TALER_CRYPTO_SignRequest *) buf);
|
||||||
break;
|
break;
|
||||||
case TALER_HELPER_RSA_MT_REQ_REVOKE:
|
case TALER_HELPER_RSA_MT_REQ_REVOKE:
|
||||||
if (ntohs (hdr.size) != sizeof (struct TALER_CRYPTO_RevokeRequest))
|
if (ntohs (hdr->size) != sizeof (struct TALER_CRYPTO_RevokeRequest))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
free_client (client);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handle_revoke_request (client,
|
handle_revoke_request (&addr,
|
||||||
(const struct TALER_CRYPTO_RevokeRequest *) &hdr);
|
addr_size,
|
||||||
|
(const struct TALER_CRYPTO_RevokeRequest *) buf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
free_client (client);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function run to accept incoming connections on #sock.
|
|
||||||
*
|
|
||||||
* @param cls NULL
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
accept_job (void *cls)
|
|
||||||
{
|
|
||||||
struct GNUNET_NETWORK_Handle *sock;
|
|
||||||
struct sockaddr_storage addr;
|
|
||||||
socklen_t alen;
|
|
||||||
|
|
||||||
accept_task = NULL;
|
|
||||||
alen = sizeof (addr);
|
|
||||||
sock = GNUNET_NETWORK_socket_accept (lsock,
|
|
||||||
(struct sockaddr *) &addr,
|
|
||||||
&alen);
|
|
||||||
if (NULL != sock)
|
|
||||||
{
|
|
||||||
struct Client *client;
|
|
||||||
|
|
||||||
client = GNUNET_new (struct Client);
|
|
||||||
client->sock = sock;
|
|
||||||
GNUNET_CONTAINER_DLL_insert (clients_head,
|
|
||||||
clients_tail,
|
|
||||||
client);
|
|
||||||
client_next (client);
|
|
||||||
for (struct Denomination *denom = denom_head;
|
|
||||||
NULL != denom;
|
|
||||||
denom = denom->next)
|
|
||||||
{
|
|
||||||
for (struct DenominationKey *dk = denom->keys_head;
|
|
||||||
NULL != dk;
|
|
||||||
dk = dk->next)
|
|
||||||
{
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
notify_client_dk_add (client,
|
|
||||||
dk))
|
|
||||||
{
|
|
||||||
/* client died, skip the rest */
|
|
||||||
client = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (NULL == client)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
accept_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
|
|
||||||
lsock,
|
|
||||||
&accept_job,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new denomination key (we do not have enough).
|
* Create a new denomination key (we do not have enough).
|
||||||
*
|
*
|
||||||
@ -1137,7 +1118,7 @@ purge_key (struct DenominationKey *dk)
|
|||||||
dk);
|
dk);
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
GNUNET_CONTAINER_multihashmap_remove (keys,
|
GNUNET_CONTAINER_multihashmap_remove (keys,
|
||||||
&dk->h_pub,
|
&dk->h_denom_pub,
|
||||||
dk));
|
dk));
|
||||||
if (0 != unlink (dk->filename))
|
if (0 != unlink (dk->filename))
|
||||||
{
|
{
|
||||||
@ -1325,17 +1306,18 @@ parse_key (struct Denomination *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_pub);
|
&dk->h_denom_pub);
|
||||||
dk->denom_pub.rsa_public_key = pub;
|
dk->denom_pub.rsa_public_key = pub;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONTAINER_multihashmap_put (
|
GNUNET_CONTAINER_multihashmap_put (
|
||||||
keys,
|
keys,
|
||||||
&dk->h_pub,
|
&dk->h_denom_pub,
|
||||||
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 detected in file `%s'. Skipping.\n",
|
"Duplicate private key %s detected in file `%s'. Skipping.\n",
|
||||||
|
GNUNET_h2s (&dk->h_denom_pub),
|
||||||
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);
|
||||||
@ -1355,8 +1337,9 @@ parse_key (struct Denomination *denom,
|
|||||||
denom->keys_tail,
|
denom->keys_tail,
|
||||||
before,
|
before,
|
||||||
dk);
|
dk);
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Imported key from `%s'\n",
|
"Imported key %s from `%s'\n",
|
||||||
|
GNUNET_h2s (&dk->h_denom_pub),
|
||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1566,7 +1549,7 @@ load_denominations (void *cls,
|
|||||||
GNUNET_free (denom);
|
GNUNET_free (denom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Loading keys for denomination %s\n",
|
"Loading keys for denomination %s\n",
|
||||||
denom->section);
|
denom->section);
|
||||||
{
|
{
|
||||||
@ -1576,6 +1559,8 @@ load_denominations (void *cls,
|
|||||||
"%s/%s",
|
"%s/%s",
|
||||||
keydir,
|
keydir,
|
||||||
denom->section);
|
denom->section);
|
||||||
|
GNUNET_break (GNUNET_OK ==
|
||||||
|
GNUNET_DISK_directory_create (dname));
|
||||||
GNUNET_DISK_directory_scan (dname,
|
GNUNET_DISK_directory_scan (dname,
|
||||||
&import_key,
|
&import_key,
|
||||||
denom);
|
denom);
|
||||||
@ -1611,17 +1596,16 @@ load_durations (void)
|
|||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_time (kcfg,
|
GNUNET_CONFIGURATION_get_value_time (kcfg,
|
||||||
"exchange",
|
"taler-helper-crypto-rsa",
|
||||||
"LOOKAHEAD_SIGN",
|
"LOOKAHEAD_SIGN",
|
||||||
&lookahead_sign))
|
&lookahead_sign))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"exchange",
|
"taler-helper-crypto-rsa",
|
||||||
"LOOKAHEAD_SIGN");
|
"LOOKAHEAD_SIGN");
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
GNUNET_TIME_round_rel (&lookahead_sign);
|
GNUNET_TIME_round_rel (&lookahead_sign);
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1635,16 +1619,16 @@ static void
|
|||||||
do_shutdown (void *cls)
|
do_shutdown (void *cls)
|
||||||
{
|
{
|
||||||
(void) cls;
|
(void) cls;
|
||||||
if (NULL != accept_task)
|
if (NULL != read_task)
|
||||||
{
|
{
|
||||||
GNUNET_SCHEDULER_cancel (accept_task);
|
GNUNET_SCHEDULER_cancel (read_task);
|
||||||
accept_task = NULL;
|
read_task = NULL;
|
||||||
}
|
}
|
||||||
if (NULL != lsock)
|
if (NULL != unix_sock)
|
||||||
{
|
{
|
||||||
GNUNET_break (GNUNET_OK ==
|
GNUNET_break (GNUNET_OK ==
|
||||||
GNUNET_NETWORK_socket_close (lsock));
|
GNUNET_NETWORK_socket_close (unix_sock));
|
||||||
lsock = NULL;
|
unix_sock = NULL;
|
||||||
}
|
}
|
||||||
if (0 != unlink (unixpath))
|
if (0 != unlink (unixpath))
|
||||||
{
|
{
|
||||||
@ -1790,7 +1774,7 @@ run (void *cls,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lsock = GNUNET_NETWORK_socket_box_native (sock);
|
unix_sock = GNUNET_NETWORK_socket_box_native (sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
|
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
|
||||||
@ -1823,10 +1807,10 @@ run (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* start job to accept incoming requests on 'sock' */
|
/* start job to accept incoming requests on 'sock' */
|
||||||
accept_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
|
read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
|
||||||
lsock,
|
unix_sock,
|
||||||
&accept_job,
|
&read_job,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* start job to keep keys up-to-date */
|
/* start job to keep keys up-to-date */
|
||||||
keygen_task = GNUNET_SCHEDULER_add_now (&update_denominations,
|
keygen_task = GNUNET_SCHEDULER_add_now (&update_denominations,
|
||||||
@ -1893,7 +1877,7 @@ main (int argc,
|
|||||||
/* force linker to link against libtalerutil; if we do
|
/* force linker to link against libtalerutil; if we do
|
||||||
not do this, the linker may "optimize" libtalerutil
|
not do this, the linker may "optimize" libtalerutil
|
||||||
away and skip #TALER_OS_init(), which we do need */
|
away and skip #TALER_OS_init(), which we do need */
|
||||||
(void) TALER_project_data_default ();
|
GNUNET_OS_init (TALER_project_data_default ());
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
GNUNET_log_setup ("taler-helper-crypto-rsa",
|
GNUNET_log_setup ("taler-helper-crypto-rsa",
|
||||||
"WARNING",
|
"WARNING",
|
||||||
|
@ -24,11 +24,12 @@
|
|||||||
#define TALER_HELPER_RSA_MT_PURGE 1
|
#define TALER_HELPER_RSA_MT_PURGE 1
|
||||||
#define TALER_HELPER_RSA_MT_AVAIL 2
|
#define TALER_HELPER_RSA_MT_AVAIL 2
|
||||||
|
|
||||||
#define TALER_HELPER_RSA_MT_REQ_SIGN 3
|
#define TALER_HELPER_RSA_MT_REQ_INIT 4
|
||||||
#define TALER_HELPER_RSA_MT_REQ_REVOKE 4
|
#define TALER_HELPER_RSA_MT_REQ_SIGN 5
|
||||||
|
#define TALER_HELPER_RSA_MT_REQ_REVOKE 6
|
||||||
|
|
||||||
#define TALER_HELPER_RSA_MT_RES_SIGNATURE 5
|
#define TALER_HELPER_RSA_MT_RES_SIGNATURE 7
|
||||||
#define TALER_HELPER_RSA_MT_RES_SIGN_FAILURE 6
|
#define TALER_HELPER_RSA_MT_RES_SIGN_FAILURE 8
|
||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_BEGIN
|
GNUNET_NETWORK_STRUCT_BEGIN
|
||||||
|
|
||||||
|
314
src/util/test_helper_rsa.c
Normal file
314
src/util/test_helper_rsa.c
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
(C) 2020 Taler Systems SA
|
||||||
|
|
||||||
|
TALER 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 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
TALER 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
|
||||||
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file util/test_helper_rsa.c
|
||||||
|
* @brief Tests for RSA crypto helper
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include "taler_util.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration has 1 minute duration and 5 minutes lookahead, so
|
||||||
|
* we should never have more than 6 active keys, plus for during
|
||||||
|
* key expiration / revocation.
|
||||||
|
*/
|
||||||
|
#define MAX_KEYS 7
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many random key revocations should we test?
|
||||||
|
*/
|
||||||
|
#define NUM_REVOKES 10
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of keys currently in #keys.
|
||||||
|
*/
|
||||||
|
static unsigned int num_keys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys currently managed by the helper.
|
||||||
|
*/
|
||||||
|
struct KeyData
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validity start point.
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_Absolute start_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key expires for signing at @e start_time plus this value.
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_Relative validity_duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash of the public key.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode h_denom_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Full public key.
|
||||||
|
*/
|
||||||
|
struct TALER_DenominationPublicKey denom_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this key currently valid?
|
||||||
|
*/
|
||||||
|
bool valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Did the test driver revoke this key?
|
||||||
|
*/
|
||||||
|
bool revoked;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct KeyData keys[MAX_KEYS];
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
key_cb (void *cls,
|
||||||
|
const char *section_name,
|
||||||
|
struct GNUNET_TIME_Absolute start_time,
|
||||||
|
struct GNUNET_TIME_Relative validity_duration,
|
||||||
|
const struct GNUNET_HashCode *h_denom_pub,
|
||||||
|
const struct TALER_DenominationPublicKey *denom_pub)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Key notification about key %s in `%s'\n",
|
||||||
|
GNUNET_h2s (h_denom_pub),
|
||||||
|
section_name);
|
||||||
|
if (0 == validity_duration.rel_value_us)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
GNUNET_break (NULL == denom_pub);
|
||||||
|
GNUNET_break (NULL == section_name);
|
||||||
|
for (unsigned int i = 0; i<MAX_KEYS; i++)
|
||||||
|
if (0 == GNUNET_memcmp (h_denom_pub,
|
||||||
|
&keys[i].h_denom_pub))
|
||||||
|
{
|
||||||
|
keys[i].valid = false;
|
||||||
|
keys[i].revoked = false;
|
||||||
|
GNUNET_CRYPTO_rsa_public_key_free (keys[i].denom_pub.rsa_public_key);
|
||||||
|
keys[i].denom_pub.rsa_public_key = NULL;
|
||||||
|
GNUNET_assert (num_keys > 0);
|
||||||
|
num_keys--;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! found)
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Error: helper announced expiration of unknown key!\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GNUNET_break (NULL != denom_pub);
|
||||||
|
for (unsigned int i = 0; i<MAX_KEYS; i++)
|
||||||
|
if (! keys[i].valid)
|
||||||
|
{
|
||||||
|
keys[i].valid = true;
|
||||||
|
keys[i].h_denom_pub = *h_denom_pub;
|
||||||
|
keys[i].start_time = start_time;
|
||||||
|
keys[i].validity_duration = validity_duration;
|
||||||
|
keys[i].denom_pub.rsa_public_key
|
||||||
|
= GNUNET_CRYPTO_rsa_public_key_dup (denom_pub->rsa_public_key);
|
||||||
|
num_keys++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* too many keys! */
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Error: received %d live keys from the service!\n",
|
||||||
|
MAX_KEYS + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point into the test logic with the helper already running.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
run_test (void)
|
||||||
|
{
|
||||||
|
struct GNUNET_CONFIGURATION_Handle *cfg;
|
||||||
|
struct TALER_CRYPTO_DenominationHelper *dh;
|
||||||
|
struct timespec req = {
|
||||||
|
.tv_nsec = 250000000
|
||||||
|
};
|
||||||
|
|
||||||
|
cfg = GNUNET_CONFIGURATION_create ();
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CONFIGURATION_load (cfg,
|
||||||
|
"test_helper_rsa.conf"))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return 77;
|
||||||
|
}
|
||||||
|
dh = TALER_CRYPTO_helper_denom_connect (cfg,
|
||||||
|
&key_cb,
|
||||||
|
NULL);
|
||||||
|
GNUNET_CONFIGURATION_destroy (cfg);
|
||||||
|
if (NULL == dh)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* wait for helper to start and give us keys */
|
||||||
|
fprintf (stderr, "Waiting for helper to start ");
|
||||||
|
for (unsigned int i = 0; i<80; i++)
|
||||||
|
{
|
||||||
|
TALER_CRYPTO_helper_poll (dh);
|
||||||
|
if (0 != num_keys)
|
||||||
|
break;
|
||||||
|
nanosleep (&req, NULL);
|
||||||
|
fprintf (stderr, ".");
|
||||||
|
}
|
||||||
|
if (0 == num_keys)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"\nFAILED: timeout trying to connect to helper\n");
|
||||||
|
TALER_CRYPTO_helper_denom_disconnect (dh);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf (stderr,
|
||||||
|
"\nOK: Helper ready (%u keys)\n",
|
||||||
|
num_keys);
|
||||||
|
for (unsigned int i = 0; i<NUM_REVOKES; i++)
|
||||||
|
{
|
||||||
|
uint32_t off;
|
||||||
|
|
||||||
|
off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||||
|
num_keys);
|
||||||
|
/* find index of key to revoke */
|
||||||
|
for (unsigned int j = 0; j < MAX_KEYS; j++)
|
||||||
|
{
|
||||||
|
if (! keys[j].valid)
|
||||||
|
continue;
|
||||||
|
if (0 != off)
|
||||||
|
{
|
||||||
|
off--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
keys[j].revoked = true;
|
||||||
|
fprintf (stderr,
|
||||||
|
"Revoking key %s ...",
|
||||||
|
GNUNET_h2s (&keys[j].h_denom_pub));
|
||||||
|
TALER_CRYPTO_helper_denom_revoke (dh,
|
||||||
|
&keys[j].h_denom_pub);
|
||||||
|
for (unsigned int k = 0; k<80; k++)
|
||||||
|
{
|
||||||
|
TALER_CRYPTO_helper_poll (dh);
|
||||||
|
if (! keys[j].revoked)
|
||||||
|
break;
|
||||||
|
nanosleep (&req, NULL);
|
||||||
|
fprintf (stderr, ".");
|
||||||
|
}
|
||||||
|
if (keys[j].revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"\nFAILED: timeout trying to revoke key %u\n",
|
||||||
|
j);
|
||||||
|
TALER_CRYPTO_helper_denom_disconnect (dh);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TALER_CRYPTO_helper_denom_disconnect (dh);
|
||||||
|
/* clean up our state */
|
||||||
|
for (unsigned int i = 0; i<MAX_KEYS; i++)
|
||||||
|
if (keys[i].valid)
|
||||||
|
{
|
||||||
|
GNUNET_CRYPTO_rsa_public_key_free (keys[i].denom_pub.rsa_public_key);
|
||||||
|
keys[i].denom_pub.rsa_public_key = NULL;
|
||||||
|
GNUNET_assert (num_keys > 0);
|
||||||
|
num_keys--;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
const char *const argv[])
|
||||||
|
{
|
||||||
|
struct GNUNET_OS_Process *helper;
|
||||||
|
char *libexec_dir;
|
||||||
|
char *binary_name;
|
||||||
|
int ret;
|
||||||
|
enum GNUNET_OS_ProcessStatusType type;
|
||||||
|
unsigned long code;
|
||||||
|
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
GNUNET_log_setup ("test-helper-rsa",
|
||||||
|
"INFO",
|
||||||
|
NULL);
|
||||||
|
GNUNET_OS_init (TALER_project_data_default ());
|
||||||
|
libexec_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBEXECDIR);
|
||||||
|
GNUNET_asprintf (&binary_name,
|
||||||
|
"%s/%s",
|
||||||
|
libexec_dir,
|
||||||
|
"taler-helper-crypto-rsa");
|
||||||
|
GNUNET_free (libexec_dir);
|
||||||
|
helper = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
binary_name,
|
||||||
|
binary_name,
|
||||||
|
"-c",
|
||||||
|
"test_helper_rsa.conf",
|
||||||
|
"-L",
|
||||||
|
"INFO",
|
||||||
|
NULL);
|
||||||
|
if (NULL == helper)
|
||||||
|
{
|
||||||
|
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"exec",
|
||||||
|
binary_name);
|
||||||
|
GNUNET_free (binary_name);
|
||||||
|
return 77;
|
||||||
|
}
|
||||||
|
GNUNET_free (binary_name);
|
||||||
|
ret = run_test ();
|
||||||
|
|
||||||
|
GNUNET_OS_process_kill (helper,
|
||||||
|
SIGTERM);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_OS_process_wait_status (helper,
|
||||||
|
&type,
|
||||||
|
&code))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Helper process did not die voluntarily, killing hard\n");
|
||||||
|
GNUNET_OS_process_kill (helper,
|
||||||
|
SIGKILL);
|
||||||
|
ret = 4;
|
||||||
|
}
|
||||||
|
else if ( (GNUNET_OS_PROCESS_EXITED != type) ||
|
||||||
|
(0 != code) )
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Helper died with unexpected status %d/%d\n",
|
||||||
|
(int) type,
|
||||||
|
(int) code);
|
||||||
|
ret = 5;
|
||||||
|
}
|
||||||
|
GNUNET_OS_process_destroy (helper);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end of test_helper_rsa.c */
|
9
src/util/test_helper_rsa.conf
Normal file
9
src/util/test_helper_rsa.conf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[coin_1]
|
||||||
|
duration_withdraw = 1 minute
|
||||||
|
rsa_keysize = 2048
|
||||||
|
|
||||||
|
[taler-helper-crypto-rsa]
|
||||||
|
lookahead_sign = 5 minutes
|
||||||
|
overlap_duration = 1 s
|
||||||
|
KEY_DIR = ${TALER_RUNTIME_DIR}/test_helper_rsa/
|
||||||
|
UNIXPATH = ${TALER_RUNTIME_DIR}test_helper_rsa.unix
|
Loading…
Reference in New Issue
Block a user