summaryrefslogtreecommitdiff
path: root/src/util/test_helper_rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/test_helper_rsa.c')
-rw-r--r--src/util/test_helper_rsa.c449
1 files changed, 391 insertions, 58 deletions
diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c
index 14ff2bfab..2bc15879f 100644
--- a/src/util/test_helper_rsa.c
+++ b/src/util/test_helper_rsa.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2020, 2021 Taler Systems SA
+ (C) 2020, 2021, 2022 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
@@ -64,7 +64,7 @@ struct KeyData
/**
* Validity start point.
*/
- struct GNUNET_TIME_Absolute start_time;
+ struct GNUNET_TIME_Timestamp start_time;
/**
* Key expires for signing at @e start_time plus this value.
@@ -129,7 +129,7 @@ free_keys (void)
* @param validity_duration how long does the key remain available for signing;
* zero if the key has been revoked or purged
* @param h_rsa hash of the @a denom_pub that is available (or was purged)
- * @param denom_pub the public key itself, NULL if the key was revoked or purged
+ * @param bs_pub the public key itself, NULL if the key was revoked or purged
* @param sm_pub public key of the security module, NULL if the key was revoked or purged
* @param sm_sig signature from the security module, NULL if the key was revoked or purged
* The signature was already verified against @a sm_pub.
@@ -137,10 +137,10 @@ free_keys (void)
static void
key_cb (void *cls,
const char *section_name,
- struct GNUNET_TIME_Absolute start_time,
+ struct GNUNET_TIME_Timestamp start_time,
struct GNUNET_TIME_Relative validity_duration,
const struct TALER_RsaPubHashP *h_rsa,
- const struct TALER_DenominationPublicKey *denom_pub,
+ struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub,
const struct TALER_SecurityModulePublicKeyP *sm_pub,
const struct TALER_SecurityModuleSignatureP *sm_sig)
{
@@ -155,7 +155,7 @@ key_cb (void *cls,
{
bool found = false;
- GNUNET_break (NULL == denom_pub);
+ GNUNET_break (NULL == bs_pub);
GNUNET_break (NULL == section_name);
for (unsigned int i = 0; i<MAX_KEYS; i++)
if (0 == GNUNET_memcmp (h_rsa,
@@ -176,7 +176,7 @@ key_cb (void *cls,
return;
}
- GNUNET_break (NULL != denom_pub);
+ GNUNET_break (NULL != bs_pub);
for (unsigned int i = 0; i<MAX_KEYS; i++)
if (! keys[i].valid)
{
@@ -184,8 +184,8 @@ key_cb (void *cls,
keys[i].h_rsa = *h_rsa;
keys[i].start_time = start_time;
keys[i].validity_duration = validity_duration;
- TALER_denom_pub_deep_copy (&keys[i].denom_pub,
- denom_pub);
+ keys[i].denom_pub.bsign_pub_key
+ = GNUNET_CRYPTO_bsign_pub_incref (bs_pub);
num_keys++;
return;
}
@@ -267,45 +267,83 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh)
struct TALER_BlindedDenominationSignature ds;
enum TALER_ErrorCode ec;
bool success = false;
- struct TALER_PlanchetSecretsP ps;
- struct TALER_CoinPubHash c_hash;
+ struct TALER_PlanchetMasterSecretP ps;
+ const struct TALER_ExchangeWithdrawValues *alg_values
+ = TALER_denom_ewv_rsa_singleton ();
+ struct TALER_AgeCommitmentHash ach;
+ struct TALER_CoinPubHashP c_hash;
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
+ union GNUNET_CRYPTO_BlindingSecretP bks;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &ps,
+ sizeof (ps));
+ TALER_planchet_setup_coin_priv (&ps,
+ alg_values,
+ &coin_priv);
+ TALER_planchet_blinding_secret_create (&ps,
+ alg_values,
+ &bks);
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &ach,
+ sizeof(ach));
- TALER_planchet_setup_random (&ps);
for (unsigned int i = 0; i<MAX_KEYS; i++)
{
if (! keys[i].valid)
continue;
+ if (GNUNET_CRYPTO_BSA_RSA !=
+ keys[i].denom_pub.bsign_pub_key->cipher)
+ continue;
{
struct TALER_PlanchetDetail pd;
GNUNET_assert (GNUNET_YES ==
TALER_planchet_prepare (&keys[i].denom_pub,
- &ps,
+ alg_values,
+ &bks,
+ NULL,
+ &coin_priv,
+ &ach,
&c_hash,
&pd));
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Requesting signature over %u bytes with key %s\n",
- (unsigned int) pd.coin_ev_size,
- GNUNET_h2s (&keys[i].h_rsa.hash));
- ds = TALER_CRYPTO_helper_rsa_sign (dh,
- &keys[i].h_rsa,
- pd.coin_ev,
- pd.coin_ev_size,
- &ec);
- GNUNET_free (pd.coin_ev);
+ {
+ struct TALER_CRYPTO_RsaSignRequest rsr = {
+ .h_rsa = &keys[i].h_rsa,
+ .msg =
+ pd.blinded_planchet.blinded_message->details.rsa_blinded_message.
+ blinded_msg,
+ .msg_size =
+ pd.blinded_planchet.blinded_message->details.rsa_blinded_message.
+ blinded_msg_size
+ };
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Requesting signature over %u bytes with key %s\n",
+ (unsigned int) rsr.msg_size,
+ GNUNET_h2s (&rsr.h_rsa->hash));
+ ec = TALER_CRYPTO_helper_rsa_sign (dh,
+ &rsr,
+ &ds);
+ }
+ TALER_blinded_planchet_free (&pd.blinded_planchet);
}
switch (ec)
{
case TALER_EC_NONE:
- if (GNUNET_TIME_absolute_get_remaining (keys[i].start_time).rel_value_us >
- GNUNET_TIME_UNIT_SECONDS.rel_value_us)
+ if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_remaining (
+ keys[i].start_time.abs_time),
+ >,
+ GNUNET_TIME_UNIT_SECONDS))
{
/* key worked too early */
GNUNET_break (0);
return 4;
}
- if (GNUNET_TIME_absolute_get_duration (keys[i].start_time).rel_value_us >
- keys[i].validity_duration.rel_value_us)
+ if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_duration (
+ keys[i].start_time.abs_time),
+ >,
+ keys[i].validity_duration))
{
/* key worked too later */
GNUNET_break (0);
@@ -317,7 +355,9 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh)
if (GNUNET_OK !=
TALER_denom_sig_unblind (&rs,
&ds,
- &ps.blinding_key,
+ &bks,
+ &c_hash,
+ alg_values,
&keys[i].denom_pub))
{
GNUNET_break (0);
@@ -344,12 +384,14 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh)
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) &&
- (GNUNET_TIME_absolute_get_duration (
- keys[i].start_time).rel_value_us <
- keys[i].validity_duration.rel_value_us) )
+ if ( (GNUNET_TIME_relative_is_zero (
+ GNUNET_TIME_absolute_get_remaining (
+ keys[i].start_time.abs_time))) &&
+ (GNUNET_TIME_relative_cmp (
+ GNUNET_TIME_absolute_get_duration (
+ keys[i].start_time.abs_time),
+ <,
+ keys[i].validity_duration)) )
{
/* key should have worked! */
GNUNET_break (0);
@@ -359,8 +401,10 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh)
default:
/* unexpected error */
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected error %d\n",
- ec);
+ "Unexpected error %d at %s:%u\n",
+ ec,
+ __FILE__,
+ __LINE__);
return 7;
}
}
@@ -374,15 +418,18 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh)
/* check signing does not work if the key is unknown */
{
struct TALER_RsaPubHashP rnd;
+ struct TALER_CRYPTO_RsaSignRequest rsr = {
+ .h_rsa = &rnd,
+ .msg = "Hello",
+ .msg_size = strlen ("Hello")
+ };
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&rnd,
sizeof (rnd));
- ds = TALER_CRYPTO_helper_rsa_sign (dh,
- &rnd,
- "Hello",
- strlen ("Hello"),
- &ec);
+ ec = TALER_CRYPTO_helper_rsa_sign (dh,
+ &rsr,
+ &ds);
if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec)
{
if (TALER_EC_NONE == ec)
@@ -399,6 +446,227 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh)
/**
+ * Test batch signing logic.
+ *
+ * @param dh handle to the helper
+ * @param batch_size how large should the batch be
+ * @param check_sigs also check unknown key and signatures
+ * @return 0 on success
+ */
+static int
+test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh,
+ unsigned int batch_size,
+ bool check_sigs)
+{
+ struct TALER_BlindedDenominationSignature ds[batch_size];
+ enum TALER_ErrorCode ec;
+ bool success = false;
+ struct TALER_PlanchetMasterSecretP ps[batch_size];
+ const struct TALER_ExchangeWithdrawValues *alg_values;
+ struct TALER_AgeCommitmentHash ach[batch_size];
+ struct TALER_CoinPubHashP c_hash[batch_size];
+ struct TALER_CoinSpendPrivateKeyP coin_priv[batch_size];
+ union GNUNET_CRYPTO_BlindingSecretP bks[batch_size];
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &ps,
+ sizeof (ps));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &ach,
+ sizeof(ach));
+ alg_values = TALER_denom_ewv_rsa_singleton ();
+ for (unsigned int i = 0; i<batch_size; i++)
+ {
+ TALER_planchet_setup_coin_priv (&ps[i],
+ alg_values,
+ &coin_priv[i]);
+ TALER_planchet_blinding_secret_create (&ps[i],
+ alg_values,
+ &bks[i]);
+ }
+ for (unsigned int k = 0; k<MAX_KEYS; k++)
+ {
+ if (success && ! check_sigs)
+ break; /* only do one round */
+ if (! keys[k].valid)
+ continue;
+ if (GNUNET_CRYPTO_BSA_RSA !=
+ keys[k].denom_pub.bsign_pub_key->cipher)
+ continue;
+ {
+ struct TALER_PlanchetDetail pd[batch_size];
+ struct TALER_CRYPTO_RsaSignRequest rsr[batch_size];
+
+ for (unsigned int i = 0; i<batch_size; i++)
+ {
+ GNUNET_assert (GNUNET_YES ==
+ TALER_planchet_prepare (&keys[k].denom_pub,
+ alg_values,
+ &bks[i],
+ NULL,
+ &coin_priv[i],
+ &ach[i],
+ &c_hash[i],
+ &pd[i]));
+ rsr[i].h_rsa
+ = &keys[k].h_rsa;
+ rsr[i].msg
+ = pd[i].blinded_planchet.blinded_message->details.rsa_blinded_message.
+ blinded_msg;
+ rsr[i].msg_size
+ = pd[i].blinded_planchet.blinded_message->details.rsa_blinded_message.
+ blinded_msg_size;
+ }
+ ec = TALER_CRYPTO_helper_rsa_batch_sign (dh,
+ batch_size,
+ rsr,
+ ds);
+ for (unsigned int i = 0; i<batch_size; i++)
+ {
+ if (TALER_EC_NONE == ec)
+ GNUNET_break (GNUNET_CRYPTO_BSA_RSA ==
+ ds[i].blinded_sig->cipher);
+ TALER_blinded_planchet_free (&pd[i].blinded_planchet);
+ }
+ }
+ switch (ec)
+ {
+ case TALER_EC_NONE:
+ if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_remaining (
+ keys[k].start_time.abs_time),
+ >,
+ GNUNET_TIME_UNIT_SECONDS))
+ {
+ /* key worked too early */
+ GNUNET_break (0);
+ return 4;
+ }
+ if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_duration (
+ keys[k].start_time.abs_time),
+ >,
+ keys[k].validity_duration))
+ {
+ /* key worked too later */
+ GNUNET_break (0);
+ return 5;
+ }
+ for (unsigned int i = 0; i<batch_size; i++)
+ {
+ struct TALER_DenominationSignature rs;
+
+ if (check_sigs)
+ {
+ if (GNUNET_OK !=
+ TALER_denom_sig_unblind (&rs,
+ &ds[i],
+ &bks[i],
+ &c_hash[i],
+ alg_values,
+ &keys[k].denom_pub))
+ {
+ GNUNET_break (0);
+ return 6;
+ }
+ }
+ TALER_blinded_denom_sig_free (&ds[i]);
+ if (check_sigs)
+ {
+ if (GNUNET_OK !=
+ TALER_denom_pub_verify (&keys[k].denom_pub,
+ &rs,
+ &c_hash[i]))
+ {
+ /* signature invalid */
+ GNUNET_break (0);
+ TALER_denom_sig_free (&rs);
+ return 7;
+ }
+ TALER_denom_sig_free (&rs);
+ }
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Received valid signature for key %s\n",
+ GNUNET_h2s (&keys[k].h_rsa.hash));
+ success = true;
+ break;
+ case TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY:
+ /* This 'failure' is expected, we're testing also for the
+ error handling! */
+ for (unsigned int i = 0; i<batch_size; i++)
+ TALER_blinded_denom_sig_free (&ds[i]);
+ if ( (GNUNET_TIME_relative_is_zero (
+ GNUNET_TIME_absolute_get_remaining (
+ keys[k].start_time.abs_time))) &&
+ (GNUNET_TIME_relative_cmp (
+ GNUNET_TIME_absolute_get_duration (
+ keys[k].start_time.abs_time),
+ <,
+ keys[k].validity_duration)) )
+ {
+ /* key should have worked! */
+ GNUNET_break (0);
+ return 6;
+ }
+ break;
+ case TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN:
+ for (unsigned int i = 0; i<batch_size; i++)
+ TALER_blinded_denom_sig_free (&ds[i]);
+ break;
+ default:
+ /* unexpected error */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected error %d at %s:%u\n",
+ ec,
+ __FILE__,
+ __LINE__);
+ for (unsigned int i = 0; i<batch_size; i++)
+ TALER_blinded_denom_sig_free (&ds[i]);
+ return 7;
+ }
+ }
+ if (! success)
+ {
+ /* no valid key for signing found, also bad */
+ GNUNET_break (0);
+ return 16;
+ }
+
+ /* check signing does not work if the key is unknown */
+ if (check_sigs)
+ {
+ struct TALER_RsaPubHashP rnd;
+ struct TALER_CRYPTO_RsaSignRequest rsr = {
+ .h_rsa = &rnd,
+ .msg = "Hello",
+ .msg_size = strlen ("Hello")
+ };
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &rnd,
+ sizeof (rnd));
+ ec = TALER_CRYPTO_helper_rsa_batch_sign (dh,
+ 1,
+ &rsr,
+ ds);
+ if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Signing with invalid key returned unexpected status %d\n",
+ ec);
+ if (TALER_EC_NONE == ec)
+ TALER_blinded_denom_sig_free (ds);
+ GNUNET_break (0);
+ return 17;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Signing with invalid key %s failed as desired\n",
+ GNUNET_h2s (&rnd.hash));
+ }
+ return 0;
+}
+
+
+/**
* Benchmark signing logic.
*
* @param dh handle to the helper
@@ -411,9 +679,23 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh,
struct TALER_BlindedDenominationSignature ds;
enum TALER_ErrorCode ec;
struct GNUNET_TIME_Relative duration;
- struct TALER_PlanchetSecretsP ps;
-
- TALER_planchet_setup_random (&ps);
+ struct TALER_PlanchetMasterSecretP ps;
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
+ struct TALER_AgeCommitmentHash ach;
+ union GNUNET_CRYPTO_BlindingSecretP bks;
+ const struct TALER_ExchangeWithdrawValues *alg_values
+ = TALER_denom_ewv_rsa_singleton ();
+
+ TALER_planchet_master_setup_random (&ps);
+ TALER_planchet_setup_coin_priv (&ps,
+ alg_values,
+ &coin_priv);
+ TALER_planchet_blinding_secret_create (&ps,
+ alg_values,
+ &bks);
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &ach,
+ sizeof(ach));
duration = GNUNET_TIME_UNIT_ZERO;
TALER_CRYPTO_helper_rsa_poll (dh);
for (unsigned int j = 0; j<NUM_SIGN_PERFS;)
@@ -422,19 +704,30 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh,
{
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)
+ if (GNUNET_CRYPTO_BSA_RSA !=
+ keys[i].denom_pub.bsign_pub_key->cipher)
+ continue;
+ if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_remaining (
+ keys[i].start_time.abs_time),
+ >,
+ GNUNET_TIME_UNIT_SECONDS))
continue;
- if (GNUNET_TIME_absolute_get_duration (keys[i].start_time).rel_value_us >
- keys[i].validity_duration.rel_value_us)
+ if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_duration (
+ keys[i].start_time.abs_time),
+ >,
+ keys[i].validity_duration))
continue;
{
- struct TALER_CoinPubHash c_hash;
+ struct TALER_CoinPubHashP c_hash;
struct TALER_PlanchetDetail pd;
GNUNET_assert (GNUNET_YES ==
TALER_planchet_prepare (&keys[i].denom_pub,
- &ps,
+ alg_values,
+ &bks,
+ NULL,
+ &coin_priv,
+ &ach,
&c_hash,
&pd));
/* use this key as long as it works */
@@ -442,12 +735,19 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh,
{
struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get ();
struct GNUNET_TIME_Relative delay;
-
- ds = TALER_CRYPTO_helper_rsa_sign (dh,
- &keys[i].h_rsa,
- pd.coin_ev,
- pd.coin_ev_size,
- &ec);
+ struct TALER_CRYPTO_RsaSignRequest rsr = {
+ .h_rsa = &keys[i].h_rsa,
+ .msg =
+ pd.blinded_planchet.blinded_message->details.rsa_blinded_message.
+ blinded_msg,
+ .msg_size =
+ pd.blinded_planchet.blinded_message->details.rsa_blinded_message.
+ blinded_msg_size
+ };
+
+ ec = TALER_CRYPTO_helper_rsa_sign (dh,
+ &rsr,
+ &ds);
if (TALER_EC_NONE != ec)
break;
delay = GNUNET_TIME_absolute_get_duration (start);
@@ -458,7 +758,7 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh,
if (NUM_SIGN_PERFS <= j)
break;
}
- GNUNET_free (pd.coin_ev);
+ TALER_blinded_planchet_free (&pd.blinded_planchet);
}
} /* for i */
} /* for j */
@@ -497,6 +797,7 @@ par_signing (struct GNUNET_CONFIGURATION_Handle *cfg)
int ret;
dh = TALER_CRYPTO_helper_rsa_connect (cfg,
+ "taler-exchange",
&key_cb,
NULL);
GNUNET_assert (NULL != dh);
@@ -548,12 +849,14 @@ run_test (void)
return 77;
}
- fprintf (stderr, "Waiting for helper to start ... ");
+ fprintf (stderr,
+ "Waiting for helper to start ... ");
for (unsigned int i = 0; i<100; i++)
{
nanosleep (&req,
NULL);
dh = TALER_CRYPTO_helper_rsa_connect (cfg,
+ "taler-exchange",
&key_cb,
NULL);
if (NULL != dh)
@@ -584,6 +887,34 @@ run_test (void)
if (0 == ret)
ret = test_signing (dh);
if (0 == ret)
+ ret = test_batch_signing (dh,
+ 2,
+ true);
+ if (0 == ret)
+ ret = test_batch_signing (dh,
+ 256,
+ true);
+ for (unsigned int i = 0; i<5; i++)
+ {
+ static unsigned int batches[] = { 1, 4, 16, 64, 256 };
+ unsigned int batch_size = batches[i];
+ struct GNUNET_TIME_Absolute start;
+ struct GNUNET_TIME_Relative duration;
+
+ start = GNUNET_TIME_absolute_get ();
+ if (0 != ret)
+ break;
+ ret = test_batch_signing (dh,
+ batch_size,
+ false);
+ duration = GNUNET_TIME_absolute_get_duration (start);
+ fprintf (stderr,
+ "%4u (batch) signature operations took %s (total real time)\n",
+ (unsigned int) batch_size,
+ GNUNET_STRINGS_relative_time_to_string (duration,
+ GNUNET_YES));
+ }
+ if (0 == ret)
ret = perf_signing (dh,
"sequential");
TALER_CRYPTO_helper_rsa_disconnect (dh);
@@ -609,6 +940,8 @@ main (int argc,
(void) argc;
(void) argv;
+ unsetenv ("XDG_DATA_HOME");
+ unsetenv ("XDG_CONFIG_HOME");
GNUNET_log_setup ("test-helper-rsa",
"WARNING",
NULL);