[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-exchange] 18/37: implement TALER_CRYPTO_helper_cs_r_derive and re
From: |
gnunet |
Subject: |
[taler-exchange] 18/37: implement TALER_CRYPTO_helper_cs_r_derive and related tests |
Date: |
Fri, 04 Feb 2022 16:53:48 +0100 |
This is an automated email from the git hooks/post-receive script.
gian-demarmels pushed a commit to branch master
in repository exchange.
commit 106664ed0c50621bd20568c948ad30fccd0689ea
Author: Lucien Heuzeveldt <lucienclaude.heuzeveldt@students.bfh.ch>
AuthorDate: Tue Jan 4 17:26:01 2022 +0100
implement TALER_CRYPTO_helper_cs_r_derive and related tests
---
src/include/taler_crypto_lib.h | 28 +++++-
src/util/crypto_helper_cs.c | 195 ++++++++++++++++++++++++++++++++++++
src/util/taler-exchange-secmod-cs.c | 3 +-
src/util/test_helper_cs.c | 132 +++++++++++++++++++++++-
4 files changed, 353 insertions(+), 5 deletions(-)
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index bd889b35..a20e5120 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1800,7 +1800,7 @@ TALER_CRYPTO_helper_cs_sign (
/**
- * Ask the helper to revoke the public key associated with @param h_denom_pub .
+ * Ask the helper to revoke the public key associated with @param h_cs .
* Will cause the helper to tell all clients that the key is now unavailable,
* and to create a replacement key.
*
@@ -1812,7 +1812,7 @@ TALER_CRYPTO_helper_cs_sign (
* callback.
*
* @param dh helper to process connection
- * @param h_rsa hash of the RSA public key to revoke
+ * @param h_cs hash of the CS public key to revoke
*/
void
TALER_CRYPTO_helper_cs_revoke (
@@ -1820,6 +1820,30 @@ TALER_CRYPTO_helper_cs_revoke (
const struct TALER_CsPubHashP *h_cs);
+/**
+ * Ask the helper to derive R using the @param nonce and denomination key
+ * associated with @param h_cs.
+ *
+ * This operation will block until the R has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper to process connection
+ * @param h_cs hash of the CS public key to revoke
+ * @param nonce witdhraw nonce
+ * @param[out] ec set to the error code (or #TALER_EC_NONE on success)
+ * @return R, the value inside the structure will be NULL on failure,
+ * see @a ec for details about the failure
+ */
+struct TALER_DenominationCsPublicR
+TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_WithdrawNonce *nonce,
+ enum TALER_ErrorCode *ec);
+
+
/**
* Close connection to @a dh.
*
diff --git a/src/util/crypto_helper_cs.c b/src/util/crypto_helper_cs.c
index 95050a1f..5b299934 100644
--- a/src/util/crypto_helper_cs.c
+++ b/src/util/crypto_helper_cs.c
@@ -633,6 +633,201 @@ TALER_CRYPTO_helper_cs_revoke (
}
+struct TALER_DenominationCsPublicR
+TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_WithdrawNonce *nonce,
+ enum TALER_ErrorCode *ec)
+{
+ struct TALER_DenominationCsPublicR r_pub;
+
+ memset (&r_pub,
+ 0,
+ sizeof (r_pub));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Starting R derivation process\n");
+ if (GNUNET_OK !=
+ try_connect (dh))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to connect to helper\n");
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
+ return r_pub;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Requesting R\n");
+ {
+ struct TALER_CRYPTO_CsRDeriveRequest rdr;
+
+ rdr.header.size = htons (sizeof (rdr));
+ rdr.header.type = htons (TALER_HELPER_CS_MT_REQ_RDERIVE);
+ rdr.reserved = htonl (0);
+ rdr.h_cs = *h_cs;
+ rdr.nonce = *nonce;
+ if (GNUNET_OK !=
+ TALER_crypto_helper_send_all (dh->sock,
+ &rdr,
+ sizeof (rdr)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "send");
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
+ return r_pub;
+ }
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Awaiting reply\n");
+ {
+ char buf[UINT16_MAX];
+ size_t off = 0;
+ const struct GNUNET_MessageHeader *hdr
+ = (const struct GNUNET_MessageHeader *) buf;
+ bool finished = false;
+
+ *ec = TALER_EC_INVALID;
+ while (1)
+ {
+ uint16_t msize;
+ ssize_t ret;
+
+ ret = recv (dh->sock,
+ &buf[off],
+ sizeof (buf) - off,
+ (finished && (0 == off))
+ ? MSG_DONTWAIT
+ : 0);
+ if (ret < 0)
+ {
+ if (EINTR == errno)
+ continue;
+ if (EAGAIN == errno)
+ {
+ GNUNET_assert (finished);
+ GNUNET_assert (0 == off);
+ return r_pub;
+ }
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "recv");
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
+ break;
+ }
+ if (0 == ret)
+ {
+ GNUNET_break (0 == off);
+ if (! finished)
+ *ec = TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
+ return r_pub;
+ }
+ off += ret;
+more:
+ if (off < sizeof (struct GNUNET_MessageHeader))
+ continue;
+ msize = ntohs (hdr->size);
+ if (off < msize)
+ continue;
+ switch (ntohs (hdr->type))
+ {
+ case TALER_HELPER_CS_MT_RES_RDERIVE:
+ if (msize != sizeof (struct TALER_CRYPTO_RDeriveResponse))
+ {
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ goto end;
+ }
+ if (finished)
+ {
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ goto end;
+ }
+ {
+ const struct TALER_CRYPTO_RDeriveResponse *rdr =
+ (const struct TALER_CRYPTO_RDeriveResponse *) buf;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received R\n");
+ *ec = TALER_EC_NONE;
+ finished = true;
+ r_pub = rdr->r_pub;
+ break;
+ }
+ case TALER_HELPER_CS_MT_RES_RDERIVE_FAILURE:
+ if (msize != sizeof (struct TALER_CRYPTO_RDeriveFailure))
+ {
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ goto end;
+ }
+ {
+ const struct TALER_CRYPTO_RDeriveFailure *rdf =
+ (const struct TALER_CRYPTO_RDeriveFailure *) buf;
+
+ *ec = (enum TALER_ErrorCode) ntohl (rdf->ec);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "R derivation failed!\n");
+ finished = true;
+ break;
+ }
+ case TALER_HELPER_CS_MT_AVAIL:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received new key!\n");
+ if (GNUNET_OK !=
+ handle_mt_avail (dh,
+ hdr))
+ {
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ goto end;
+ }
+ break; /* while(1) loop ensures we recvfrom() again */
+ case TALER_HELPER_CS_MT_PURGE:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received revocation!\n");
+ if (GNUNET_OK !=
+ handle_mt_purge (dh,
+ hdr))
+ {
+ GNUNET_break_op (0);
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ goto end;
+ }
+ break; /* while(1) loop ensures we recvfrom() again */
+ case TALER_HELPER_CS_SYNCED:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Synchronized add odd time with CS helper!\n");
+ dh->synced = true;
+ break;
+ default:
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Received unexpected message of type %u\n",
+ ntohs (hdr->type));
+ do_disconnect (dh);
+ *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
+ goto end;
+ }
+ memmove (buf,
+ &buf[msize],
+ off - msize);
+ off -= msize;
+ goto more;
+ } /* while(1) */
+end:
+ return r_pub;
+ }
+}
+
+
void
TALER_CRYPTO_helper_cs_disconnect (
struct TALER_CRYPTO_CsDenominationHelper *dh)
diff --git a/src/util/taler-exchange-secmod-cs.c
b/src/util/taler-exchange-secmod-cs.c
index 14f0a5d1..0df7c3dd 100644
--- a/src/util/taler-exchange-secmod-cs.c
+++ b/src/util/taler-exchange-secmod-cs.c
@@ -618,7 +618,6 @@ handle_r_derive_request (struct TES_Client *client,
&rdf.header);
}
- // TODO: print nonce too?
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received request to derive R with key %s\n",
GNUNET_h2s (&rdr->h_cs.hash));
@@ -692,7 +691,7 @@ cs_work_dispatch (struct TES_Client *client,
return handle_revoke_request (
client,
(const struct TALER_CRYPTO_CsRevokeRequest *) hdr);
- case TALER_HELPER_CS_MT_RES_RDERIVE:
+ case TALER_HELPER_CS_MT_REQ_RDERIVE:
if (msize != sizeof (struct TALER_CRYPTO_CsRDeriveRequest))
{
GNUNET_break_op (0);
diff --git a/src/util/test_helper_cs.c b/src/util/test_helper_cs.c
index 41d363fd..d59c2163 100644
--- a/src/util/test_helper_cs.c
+++ b/src/util/test_helper_cs.c
@@ -255,6 +255,133 @@ test_revocation (struct TALER_CRYPTO_CsDenominationHelper
*dh)
}
+/**
+ * Test R derivation logic.
+ *
+ * @param dh handle to the helper
+ * @return 0 on success
+ */
+static int
+test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh)
+{
+ struct TALER_DenominationCsPublicR r_pub;
+ enum TALER_ErrorCode ec;
+ bool success = false;
+ struct TALER_PlanchetSecretsP ps;
+ struct TALER_CoinPubHash c_hash;
+
+ TALER_planchet_setup_random (&ps, TALER_DENOMINATION_RSA);
+ for (unsigned int i = 0; i<MAX_KEYS; i++)
+ {
+ if (! keys[i].valid)
+ continue;
+ // TODO: insert assertion into other checks
+ GNUNET_assert (TALER_DENOMINATION_CS == keys[i].denom_pub.cipher);
+ {
+ struct TALER_PlanchetDetail pd;
+ pd.blinded_planchet.cipher = TALER_DENOMINATION_CS;
+
+ TALER_cs_withdraw_nonce_derive (&ps.coin_priv,
+ &pd.blinded_planchet.details.
+ cs_blinded_planchet.nonce);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Requesting R derivation with key %s\n",
+ GNUNET_h2s (&keys[i].h_cs.hash));
+ r_pub = TALER_CRYPTO_helper_cs_r_derive (dh,
+ &keys[i].h_cs,
+ &pd.blinded_planchet.details.
+ cs_blinded_planchet.nonce,
+ &ec);
+ }
+ switch (ec)
+ {
+ case TALER_EC_NONE:
+ 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_relative_cmp (GNUNET_TIME_absolute_get_duration (
+ keys[i].start_time.abs_time),
+ >,
+ keys[i].validity_duration))
+ {
+ /* key worked too later */
+ GNUNET_break (0);
+ return 5;
+ }
+
+ // since R is part of the signature creation process, it can't be tested
fully here
+ // instead it will be further tested in the signature creation process
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Received valid R for key %s\n",
+ GNUNET_h2s (&keys[i].h_cs.hash));
+ success = true;
+ break;
+ case TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY:
+ /* This 'failure' is expected, we're testing also for the
+ error handling! */
+ 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);
+ return 6;
+ }
+ break;
+ default:
+ /* unexpected error */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected error %d\n",
+ ec);
+ return 7;
+ }
+ }
+ if (! success)
+ {
+ /* no valid key for signing found, also bad */
+ GNUNET_break (0);
+ return 16;
+ }
+
+ /* check R derivation does not work if the key is unknown */
+ {
+ struct TALER_CsPubHashP rnd;
+ struct TALER_WithdrawNonce nonce;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &rnd,
+ sizeof (rnd));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &nonce,
+ sizeof (nonce));
+ r_pub = TALER_CRYPTO_helper_cs_r_derive (dh,
+ &rnd,
+ &nonce,
+ &ec);
+ if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec)
+ {
+ GNUNET_break (0);
+ return 17;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "R derivation with invalid key %s failed as desired\n",
+ GNUNET_h2s (&rnd.hash));
+ }
+ return 0;
+}
+
+
/**
* Test signing logic.
*
@@ -600,9 +727,11 @@ run_test (void)
" Done (%u keys)\n",
num_keys);
ret = 0;
- // TODO: implement other tests
if (0 == ret)
ret = test_revocation (dh);
+ if (0 == ret)
+ ret = test_r_derive (dh);
+ // TODO: implement other tests
// if (0 == ret)
// ret = test_signing (dh);
// if (0 == ret)
@@ -685,6 +814,7 @@ main (int argc,
(int) code);
ret = 5;
}
+ // TODO: remove
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"I am here");
GNUNET_OS_process_destroy (helper);
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-exchange] branch master updated (0a459aeb -> a6778607), gnunet, 2022/02/04
- [taler-exchange] 03/37: added CS get R functionality and planchet setup, gnunet, 2022/02/04
- [taler-exchange] 01/37: added CS data structures, implemented CS keypair, gnunet, 2022/02/04
- [taler-exchange] 04/37: implemented planchet_prepare for CS, gnunet, 2022/02/04
- [taler-exchange] 05/37: sign_blinded implementation, gnunet, 2022/02/04
- [taler-exchange] 09/37: utility functions, gnunet, 2022/02/04
- [taler-exchange] 02/37: CS planchet create and withdraw create, gnunet, 2022/02/04
- [taler-exchange] 12/37: fix const due to changes in TALER_planchet_prepare, gnunet, 2022/02/04
- [taler-exchange] 18/37: implement TALER_CRYPTO_helper_cs_r_derive and related tests,
gnunet <=
- [taler-exchange] 06/37: add sign and verify implementation, gnunet, 2022/02/04
- [taler-exchange] 07/37: implement exchange_api_csr, gnunet, 2022/02/04
- [taler-exchange] 13/37: secmod cs signatures implementation, gnunet, 2022/02/04
- [taler-exchange] 11/37: clean up cs implementation, gnunet, 2022/02/04
- [taler-exchange] 16/37: revocation, gnunet, 2022/02/04
- [taler-exchange] 17/37: implement secmod cs derive R, gnunet, 2022/02/04
- [taler-exchange] 08/37: fixed CS signatures and cleanup/refactoring, gnunet, 2022/02/04
- [taler-exchange] 14/37: initial cs_secmod implementation, gnunet, 2022/02/04
- [taler-exchange] 15/37: setup_key for cs secmod helper, gnunet, 2022/02/04
- [taler-exchange] 34/37: include denom_pub into coin_ev_hash, gnunet, 2022/02/04