summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------contrib/gana0
-rw-r--r--src/util/Makefile.am2
-rw-r--r--src/util/crypto_helper_denom.c (renamed from src/util/crypto_helper.c)205
-rw-r--r--src/util/taler-helper-crypto-rsa.c49
-rw-r--r--src/util/test_helper_rsa.c171
5 files changed, 324 insertions, 103 deletions
diff --git a/contrib/gana b/contrib/gana
-Subproject e5ae01eeb4dedd8599473e64e098ea97fb7dadd
+Subproject 8341d17cd88b1e88943f192a47fbc61ce925816
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 505634381..73edce2cd 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -51,7 +51,7 @@ libtalerutil_la_SOURCES = \
amount.c \
config.c \
crypto.c \
- crypto_helper.c \
+ crypto_helper_denom.c \
crypto_wire.c \
getopt.c \
lang.c \
diff --git a/src/util/crypto_helper.c b/src/util/crypto_helper_denom.c
index 20ab61ff4..b999be02a 100644
--- a/src/util/crypto_helper.c
+++ b/src/util/crypto_helper_denom.c
@@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
- * @file util/crypto_helper.c
+ * @file util/crypto_helper_denom.c
* @brief utility functions for running out-of-process private key operations
* @author Christian Grothoff
*/
@@ -238,6 +238,97 @@ TALER_CRYPTO_helper_denom_connect (
}
+/**
+ * Handle a #TALER_HELPER_RSA_MT_AVAIL message from the helper.
+ *
+ * @param dh helper context
+ * @param hdr message that we received
+ * @return #GNUNET_OK on success
+ */
+static int
+handle_mt_avail (struct TALER_CRYPTO_DenominationHelper *dh,
+ const struct GNUNET_MessageHeader *hdr)
+{
+ const struct TALER_CRYPTO_RsaKeyAvailableNotification *kan
+ = (const struct TALER_CRYPTO_RsaKeyAvailableNotification *) hdr;
+ const char *buf = (const char *) &kan[1];
+ const char *section_name;
+
+ if (sizeof (*kan) > ntohs (hdr->size))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ if (ntohs (hdr->size) !=
+ sizeof (*kan)
+ + ntohs (kan->pub_size)
+ + ntohs (kan->section_name_len))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ section_name = &buf[ntohs (kan->pub_size)];
+ if ('\0' != section_name[ntohs (kan->section_name_len) - 1])
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+
+ {
+ struct TALER_DenominationPublicKey denom_pub;
+ struct GNUNET_HashCode h_denom_pub;
+
+ denom_pub.rsa_public_key
+ = GNUNET_CRYPTO_rsa_public_key_decode (buf,
+ ntohs (kan->pub_size));
+ if (NULL == denom_pub.rsa_public_key)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key,
+ &h_denom_pub);
+ dh->dkc (dh->dkc_cls,
+ section_name,
+ GNUNET_TIME_absolute_ntoh (kan->anchor_time),
+ GNUNET_TIME_relative_ntoh (kan->duration_withdraw),
+ &h_denom_pub,
+ &denom_pub);
+ GNUNET_CRYPTO_rsa_public_key_free (denom_pub.rsa_public_key);
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Handle a #TALER_HELPER_RSA_MT_PURGE message from the helper.
+ *
+ * @param dh helper context
+ * @param hdr message that we received
+ * @return #GNUNET_OK on success
+ */
+static int
+handle_mt_purge (struct TALER_CRYPTO_DenominationHelper *dh,
+ const struct GNUNET_MessageHeader *hdr)
+{
+ const struct TALER_CRYPTO_RsaKeyPurgeNotification *pn
+ = (const struct TALER_CRYPTO_RsaKeyPurgeNotification *) hdr;
+
+ if (sizeof (*pn) != ntohs (hdr->size))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ dh->dkc (dh->dkc_cls,
+ NULL,
+ GNUNET_TIME_UNIT_ZERO_ABS,
+ GNUNET_TIME_UNIT_ZERO,
+ &pn->h_denom_pub,
+ NULL);
+ return GNUNET_OK;
+}
+
+
void
TALER_CRYPTO_helper_poll (struct TALER_CRYPTO_DenominationHelper *dh)
{
@@ -275,73 +366,23 @@ TALER_CRYPTO_helper_poll (struct TALER_CRYPTO_DenominationHelper *dh)
switch (ntohs (hdr->type))
{
case TALER_HELPER_RSA_MT_AVAIL:
+ if (GNUNET_OK !=
+ handle_mt_avail (dh,
+ hdr))
{
- const struct TALER_CRYPTO_RsaKeyAvailableNotification *kan
- = (const struct TALER_CRYPTO_RsaKeyAvailableNotification *) buf;
- const char *section_name;
- struct TALER_DenominationPublicKey denom_pub;
- struct GNUNET_HashCode h_denom_pub;
-
- if (sizeof (*kan) > ret)
- {
- GNUNET_break_op (0);
- 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);
- do_disconnect (dh);
- return;
- }
- denom_pub.rsa_public_key
- = GNUNET_CRYPTO_rsa_public_key_decode (&buf[sizeof (*kan)],
- ntohs (kan->pub_size));
- if (NULL == denom_pub.rsa_public_key)
- {
- GNUNET_break_op (0);
- do_disconnect (dh);
- return;
- }
- section_name = &buf[sizeof (*kan) + ntohs (kan->pub_size)];
- GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key,
- &h_denom_pub);
- dh->dkc (dh->dkc_cls,
- section_name,
- GNUNET_TIME_absolute_ntoh (kan->anchor_time),
- GNUNET_TIME_relative_ntoh (kan->duration_withdraw),
- &h_denom_pub,
- &denom_pub);
- GNUNET_CRYPTO_rsa_public_key_free (denom_pub.rsa_public_key);
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ return;
}
break;
case TALER_HELPER_RSA_MT_PURGE:
+ if (GNUNET_OK !=
+ handle_mt_purge (dh,
+ hdr))
{
- const struct TALER_CRYPTO_RsaKeyPurgeNotification *pn
- = (const struct TALER_CRYPTO_RsaKeyPurgeNotification *) buf;
-
- if (sizeof (*pn) != ret)
- {
- GNUNET_break_op (0);
- do_disconnect (dh);
- return;
- }
-
- dh->dkc (dh->dkc_cls,
- NULL,
- GNUNET_TIME_UNIT_ZERO_ABS,
- GNUNET_TIME_UNIT_ZERO,
- &pn->h_denom_pub,
- NULL);
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ return;
}
break;
default:
@@ -399,6 +440,7 @@ TALER_CRYPTO_helper_denom_sign (
GNUNET_break (((size_t) ret) == sizeof (buf));
}
+ while (1)
{
char buf[UINT16_MAX];
ssize_t ret;
@@ -433,7 +475,7 @@ TALER_CRYPTO_helper_denom_sign (
GNUNET_break_op (0);
do_disconnect (dh);
*ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
- break;
+ return ds;
}
{
const struct TALER_CRYPTO_SignResponse *sr =
@@ -447,7 +489,7 @@ TALER_CRYPTO_helper_denom_sign (
GNUNET_break_op (0);
do_disconnect (dh);
*ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
- break;
+ return ds;
}
*ec = TALER_EC_NONE;
ds.rsa_signature = rsa_signature;
@@ -459,25 +501,44 @@ TALER_CRYPTO_helper_denom_sign (
GNUNET_break_op (0);
do_disconnect (dh);
*ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
- break;
+ return ds;
}
{
const struct TALER_CRYPTO_SignFailure *sf =
(const struct TALER_CRYPTO_SignFailure *) buf;
*ec = (enum TALER_ErrorCode) ntohl (sf->ec);
- break;
+ return ds;
+ }
+ case TALER_HELPER_RSA_MT_AVAIL:
+ if (GNUNET_OK !=
+ handle_mt_avail (dh,
+ hdr))
+ {
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ return ds;
+ }
+ break; /* while(1) loop ensures we recvfrom() again */
+ case TALER_HELPER_RSA_MT_PURGE:
+ if (GNUNET_OK !=
+ handle_mt_purge (dh,
+ hdr))
+ {
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ return ds;
}
- // FIXME: *could* also receive change in key status!
- // Handle that here, and then try again!
+ break; /* while(1) loop ensures we recvfrom() again */
default:
GNUNET_break_op (0);
do_disconnect (dh);
*ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
- break;
+ return ds;
}
}
- return ds;
}
@@ -524,4 +585,4 @@ TALER_CRYPTO_helper_denom_disconnect (
}
-/* end of crypto_helper.c */
+/* end of crypto_helper_denom.c */
diff --git a/src/util/taler-helper-crypto-rsa.c b/src/util/taler-helper-crypto-rsa.c
index 6fda5fec1..abd8014fd 100644
--- a/src/util/taler-helper-crypto-rsa.c
+++ b/src/util/taler-helper-crypto-rsa.c
@@ -551,6 +551,21 @@ handle_done (void *cls)
done_tail,
wi);
GNUNET_assert (0 == pthread_mutex_unlock (&done_lock));
+ if (NULL == wi->rsa_signature)
+ {
+ struct TALER_CRYPTO_SignFailure sf = {
+ .header.size = htons (sizeof (sf)),
+ .header.type = htons (TALER_HELPER_RSA_MT_RES_SIGN_FAILURE),
+ .ec = htonl (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE)
+ };
+
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Signing request failed, worker failed to produce signature\n");
+ (void) transmit (&wi->addr,
+ wi->addr_size,
+ &sf.header);
+ }
+ else
{
struct TALER_CRYPTO_SignResponse *sr;
void *buf;
@@ -598,7 +613,7 @@ handle_sign_request (const struct sockaddr_un *addr,
struct DenominationKey *dk;
struct WorkItem *wi;
const void *blinded_msg = &sr[1];
- size_t blinded_msg_size = ntohs (sr->header.size) - sizeof (sr);
+ size_t blinded_msg_size = ntohs (sr->header.size) - sizeof (*sr);
dk = GNUNET_CONTAINER_multihashmap_get (keys,
&sr->h_denom_pub);
@@ -618,9 +633,29 @@ handle_sign_request (const struct sockaddr_un *addr,
&sf.header);
return;
}
- // FIXME: check denomination key is valid for signing
- // at this time!
+ if (0 !=
+ GNUNET_TIME_absolute_get_remaining (dk->anchor).rel_value_us)
+ {
+ /* it is too early */
+ struct TALER_CRYPTO_SignFailure sf = {
+ .header.size = htons (sizeof (sr)),
+ .header.type = htons (TALER_HELPER_RSA_MT_RES_SIGN_FAILURE),
+ .ec = htonl (TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY)
+ };
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Signing request failed, denomination key %s is not yet valid\n",
+ GNUNET_h2s (&sr->h_denom_pub));
+ (void) transmit (addr,
+ addr_size,
+ &sf.header);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Received request to sign over %u bytes with key %s\n",
+ (unsigned int) blinded_msg_size,
+ GNUNET_h2s (&sr->h_denom_pub));
wi = GNUNET_new (struct WorkItem);
wi->addr = *addr;
wi->addr_size = addr_size;
@@ -1038,11 +1073,13 @@ create_key (struct Denomination *denom)
{
struct DenominationKey *dk;
struct GNUNET_TIME_Absolute anchor;
+ struct GNUNET_TIME_Absolute now;
+ now = GNUNET_TIME_absolute_get ();
+ (void) GNUNET_TIME_round_abs (&now);
if (NULL == denom->keys_tail)
{
- anchor = GNUNET_TIME_absolute_get ();
- (void) GNUNET_TIME_round_abs (&anchor);
+ anchor = now;
}
else
{
@@ -1050,6 +1087,8 @@ create_key (struct Denomination *denom)
GNUNET_TIME_relative_subtract (
denom->duration_withdraw,
overlap_duration));
+ if (now.abs_value_us > anchor.abs_value_us)
+ anchor = now;
}
dk = GNUNET_new (struct DenominationKey);
dk->denom = denom;
diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c
index 14b3c4a56..2b6c850f8 100644
--- a/src/util/test_helper_rsa.c
+++ b/src/util/test_helper_rsa.c
@@ -33,6 +33,11 @@
*/
#define NUM_REVOKES 10
+/**
+ * How many iterations of the successful signing test should we run?
+ */
+#define NUM_SIGN_TESTS 100
+
/**
* Number of keys currently in #keys.
@@ -189,7 +194,7 @@ test_revocation (struct TALER_CRYPTO_DenominationHelper *dh)
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++)
+ for (unsigned int k = 0; k<1000; k++)
{
TALER_CRYPTO_helper_poll (dh);
if (! keys[j].revoked)
@@ -205,6 +210,7 @@ test_revocation (struct TALER_CRYPTO_DenominationHelper *dh)
TALER_CRYPTO_helper_denom_disconnect (dh);
return 2;
}
+ fprintf (stderr, "\n");
break;
}
}
@@ -225,7 +231,11 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
enum TALER_ErrorCode ec;
bool success = false;
struct GNUNET_HashCode m_hash;
+ struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &bks,
+ sizeof (bks));
GNUNET_CRYPTO_hash ("Hello",
strlen ("Hello"),
&m_hash);
@@ -233,11 +243,26 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
{
if (! keys[i].valid)
continue;
- ds = TALER_CRYPTO_helper_denom_sign (dh,
- &keys[i].h_denom_pub,
- &m_hash,
- sizeof (m_hash),
- &ec);
+ {
+ void *buf;
+ size_t buf_size;
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CRYPTO_rsa_blind (&m_hash,
+ &bks,
+ keys[i].denom_pub.rsa_public_key,
+ &buf,
+ &buf_size));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Requesting signature over %u bytes with key %s\n",
+ (unsigned int) buf_size,
+ GNUNET_h2s (&keys[i].h_denom_pub));
+ ds = TALER_CRYPTO_helper_denom_sign (dh,
+ &keys[i].h_denom_pub,
+ buf,
+ buf_size,
+ &ec);
+ GNUNET_free (buf);
+ }
switch (ec)
{
case TALER_EC_NONE:
@@ -255,21 +280,38 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
GNUNET_break (0);
return 5;
}
- if (GNUNET_OK !=
- GNUNET_CRYPTO_rsa_verify (&m_hash,
- ds.rsa_signature,
- keys[i].denom_pub.rsa_public_key))
{
- /* signature invalid */
- GNUNET_break (0);
+ struct GNUNET_CRYPTO_RsaSignature *rs;
+
+ rs = GNUNET_CRYPTO_rsa_unblind (ds.rsa_signature,
+ &bks,
+ keys[i].denom_pub.rsa_public_key);
+ if (NULL == rs)
+ {
+ GNUNET_break (0);
+ return 6;
+ }
GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature);
- return 6;
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_rsa_verify (&m_hash,
+ rs,
+ keys[i].denom_pub.rsa_public_key))
+ {
+ /* signature invalid */
+ GNUNET_break (0);
+ GNUNET_CRYPTO_rsa_signature_free (rs);
+ return 7;
+ }
+ GNUNET_CRYPTO_rsa_signature_free (rs);
}
- GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Received valid signature for key %s\n",
+ GNUNET_h2s (&keys[i].h_denom_pub));
success = true;
break;
-#if FIXME
- case TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_INVALID:
+ case TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY:
+ /* This 'failure' is expected, we're testing also for the
+ error handling! */
if ( (0 ==
GNUNET_TIME_absolute_get_remaining (
keys[i].start_time).rel_value_us) &&
@@ -282,7 +324,6 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
return 6;
}
break;
-#endif
default:
/* unexpected error */
GNUNET_break (0);
@@ -313,12 +354,95 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh)
GNUNET_break (0);
return 17;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Signing with invalid key %s failed as desired\n",
+ GNUNET_h2s (&rnd));
}
return 0;
}
/**
+ * Benchmark signing logic.
+ *
+ * @param dh handle to the helper
+ * @return 0 on success
+ */
+static int
+perf_signing (struct TALER_CRYPTO_DenominationHelper *dh)
+{
+ struct TALER_DenominationSignature ds;
+ enum TALER_ErrorCode ec;
+ bool success = false;
+ struct GNUNET_HashCode m_hash;
+ struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
+ struct GNUNET_TIME_Relative duration;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &bks,
+ sizeof (bks));
+ GNUNET_CRYPTO_hash ("Hello",
+ strlen ("Hello"),
+ &m_hash);
+ duration = GNUNET_TIME_UNIT_ZERO;
+ for (unsigned int j = 0; j<NUM_SIGN_TESTS;)
+ {
+ TALER_CRYPTO_helper_poll (dh);
+ for (unsigned int i = 0; i<MAX_KEYS; i++)
+ {
+ if (! keys[i].valid)
+ continue;
+ if (GNUNET_TIME_absolute_get_remaining (keys[i].start_time).rel_value_us >
+ GNUNET_TIME_UNIT_SECONDS.rel_value_us)
+ continue;
+ if (GNUNET_TIME_absolute_get_duration (keys[i].start_time).rel_value_us >
+ keys[i].validity_duration.rel_value_us)
+ continue;
+ {
+ void *buf;
+ size_t buf_size;
+
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CRYPTO_rsa_blind (&m_hash,
+ &bks,
+ keys[i].denom_pub.rsa_public_key,
+ &buf,
+ &buf_size));
+ /* use this key as long as it works */
+ while (1)
+ {
+ struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get ();
+ struct GNUNET_TIME_Relative delay;
+
+ ds = TALER_CRYPTO_helper_denom_sign (dh,
+ &keys[i].h_denom_pub,
+ buf,
+ buf_size,
+ &ec);
+ if (TALER_EC_NONE != ec)
+ break;
+ delay = GNUNET_TIME_absolute_get_duration (start);
+ duration = GNUNET_TIME_relative_add (duration,
+ delay);
+ GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature);
+ j++;
+ if (NUM_SIGN_TESTS == j)
+ break;
+ }
+ GNUNET_free (buf);
+ }
+ } /* for i */
+ } /* for j */
+ fprintf (stderr,
+ "%u (sequential) signature operations took %s\n",
+ (unsigned int) NUM_SIGN_TESTS,
+ GNUNET_STRINGS_relative_time_to_string (duration,
+ GNUNET_YES));
+ return 0;
+}
+
+
+/**
* Main entry point into the test logic with the helper already running.
*/
static int
@@ -350,7 +474,7 @@ run_test (void)
}
/* wait for helper to start and give us keys */
fprintf (stderr, "Waiting for helper to start ");
- for (unsigned int i = 0; i<80; i++)
+ for (unsigned int i = 0; i<1000; i++)
{
TALER_CRYPTO_helper_poll (dh);
if (0 != num_keys)
@@ -370,15 +494,12 @@ run_test (void)
num_keys);
ret = 0;
-#if 1
if (0 == ret)
ret = test_revocation (dh);
-#endif
-#if 0
if (0 == ret)
ret = test_signing (dh);
-#endif
-
+ if (0 == ret)
+ ret = perf_signing (dh);
TALER_CRYPTO_helper_denom_disconnect (dh);
/* clean up our state */
for (unsigned int i = 0; i<MAX_KEYS; i++)
@@ -407,7 +528,7 @@ main (int argc,
(void) argc;
(void) argv;
GNUNET_log_setup ("test-helper-rsa",
- "INFO",
+ "WARNING",
NULL);
GNUNET_OS_init (TALER_project_data_default ());
libexec_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBEXECDIR);
@@ -423,7 +544,7 @@ main (int argc,
"-c",
"test_helper_rsa.conf",
"-L",
- "INFO",
+ "WARNING",
NULL);
if (NULL == helper)
{