summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-12-05 21:33:30 +0100
committerChristian Grothoff <christian@grothoff.org>2020-12-05 21:33:30 +0100
commite0b62b0a49672bd259ed47c9448b78c9be8823f7 (patch)
treec4c78b825f88ed6c01b2b2b5b9f78970f3a75f7a /src
parent719779577a4c336126f0bbb77f947ea892a3cdd3 (diff)
downloadexchange-e0b62b0a49672bd259ed47c9448b78c9be8823f7.tar.gz
exchange-e0b62b0a49672bd259ed47c9448b78c9be8823f7.tar.bz2
exchange-e0b62b0a49672bd259ed47c9448b78c9be8823f7.zip
towards offline tool uploading /management/keys
Diffstat (limited to 'src')
-rw-r--r--src/exchange-tools/taler-exchange-offline.c475
-rw-r--r--src/exchange/taler-exchange-httpd_management_post_keys.c40
-rw-r--r--src/include/taler_crypto_lib.h65
-rw-r--r--src/lib/exchange_api_handle.c46
-rw-r--r--src/util/offline_signatures.c91
5 files changed, 651 insertions, 66 deletions
diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c
index c4804fead..e8a2fb39f 100644
--- a/src/exchange-tools/taler-exchange-offline.c
+++ b/src/exchange-tools/taler-exchange-offline.c
@@ -230,6 +230,33 @@ struct WireFeeRequest
/**
+ * Ongoing /keys request.
+ */
+struct UploadKeysRequest
+{
+ /**
+ * Kept in a DLL.
+ */
+ struct UploadKeysRequest *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct UploadKeysRequest *prev;
+
+ /**
+ * Operation handle.
+ */
+ struct TALER_EXCHANGE_ManagementPostKeysHandle *h;
+
+ /**
+ * Operation index.
+ */
+ size_t idx;
+};
+
+
+/**
* Next work item to perform.
*/
static struct GNUNET_SCHEDULER_Task *nxt;
@@ -249,7 +276,6 @@ static struct DenomRevocationRequest *drr_head;
*/
static struct DenomRevocationRequest *drr_tail;
-
/**
* Active signkey revocation requests.
*/
@@ -260,7 +286,6 @@ static struct SignkeyRevocationRequest *srr_head;
*/
static struct SignkeyRevocationRequest *srr_tail;
-
/**
* Active wire add requests.
*/
@@ -291,6 +316,16 @@ static struct WireFeeRequest *wfr_head;
*/
static struct WireFeeRequest *wfr_tail;
+/**
+ * Active keys upload requests.
+ */
+static struct UploadKeysRequest *ukr_head;
+
+/**
+ * Active keys upload requests.
+ */
+static struct UploadKeysRequest *ukr_tail;
+
/**
* Shutdown task. Invoked when the application is being terminated.
@@ -378,6 +413,21 @@ do_shutdown (void *cls)
GNUNET_free (wfr);
}
}
+ {
+ struct UploadKeysRequest *ukr;
+
+ while (NULL != (ukr = ukr_head))
+ {
+ fprintf (stderr,
+ "Aborting incomplete key signature upload #%u\n",
+ (unsigned int) ukr->idx);
+ TALER_EXCHANGE_post_management_keys_cancel (ukr->h);
+ GNUNET_CONTAINER_DLL_remove (ukr_head,
+ ukr_tail,
+ ukr);
+ GNUNET_free (ukr);
+ }
+ }
if (NULL != out)
{
json_dumpf (out,
@@ -427,6 +477,7 @@ test_shutdown (void)
(NULL == war_head) &&
(NULL == wdr_head) &&
(NULL == wfr_head) &&
+ (NULL == ukr_head) &&
(NULL == mgkh) &&
(NULL == nxt) )
GNUNET_SCHEDULER_shutdown ();
@@ -1017,6 +1068,67 @@ upload_wire_fee (const char *exchange_url,
/**
+ * Function called with information about the post upload keys operation result.
+ *
+ * @param cls closure with a `struct UploadKeysRequest`
+ * @param hr HTTP response data
+ */
+static void
+keys_cb (
+ void *cls,
+ const struct TALER_EXCHANGE_HttpResponse *hr)
+{
+ struct UploadKeysRequest *ukr = cls;
+
+ if (MHD_HTTP_NO_CONTENT != hr->http_status)
+ {
+ fprintf (stderr,
+ "Upload failed for command %u with status %u: %s (%s)\n",
+ (unsigned int) ukr->idx,
+ hr->http_status,
+ TALER_ErrorCode_get_hint (hr->ec),
+ hr->hint);
+ }
+ GNUNET_CONTAINER_DLL_remove (ukr_head,
+ ukr_tail,
+ ukr);
+ GNUNET_free (ukr);
+ test_shutdown ();
+}
+
+
+/**
+ * Upload (denomination and signing) key master signatures.
+ *
+ * @param exchange_url base URL of the exchange
+ * @param idx index of the operation we are performing (for logging)
+ * @param value argumets for POSTing keys
+ */
+static void
+upload_keys (const char *exchange_url,
+ size_t idx,
+ const json_t *value)
+{
+ struct TALER_EXCHANGE_ManagementPostKeysData pkd;
+ struct UploadKeysRequest *ukr;
+
+ // FIXME: initialize 'pkd' from 'value'!
+
+ ukr = GNUNET_new (struct UploadKeysRequest);
+ ukr->idx = idx;
+ ukr->h =
+ TALER_EXCHANGE_post_management_keys (ctx,
+ exchange_url,
+ &pkd,
+ &keys_cb,
+ ukr);
+ GNUNET_CONTAINER_DLL_insert (ukr_head,
+ ukr_tail,
+ ukr);
+}
+
+
+/**
* Perform uploads based on the JSON in #io.
*
* @param exchange_url base URL of the exchange to use
@@ -1045,7 +1157,10 @@ trigger_upload (const char *exchange_url)
.key = "set-wire-fee",
.cb = &upload_wire_fee
},
- // FIXME: Add POST /management/keys handlers here!
+ {
+ .key = "upload-keys",
+ .cb = &upload_keys
+ },
/* array termination */
{
.key = NULL
@@ -1697,6 +1812,7 @@ show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
struct TALER_DenominationPublicKey denom_pub;
struct GNUNET_TIME_Absolute stamp_start;
struct GNUNET_TIME_Absolute stamp_expire_withdraw;
+ struct GNUNET_TIME_Absolute stamp_expire_deposit;
struct GNUNET_TIME_Absolute stamp_expire_legal;
struct TALER_Amount coin_value;
struct TALER_Amount fee_withdraw;
@@ -1723,6 +1839,8 @@ show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
&stamp_start),
GNUNET_JSON_spec_absolute_time ("stamp_expire_withdraw",
&stamp_expire_withdraw),
+ GNUNET_JSON_spec_absolute_time ("stamp_expire_deposit",
+ &stamp_expire_deposit),
GNUNET_JSON_spec_absolute_time ("stamp_expire_legal",
&stamp_expire_legal),
GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
@@ -1739,7 +1857,7 @@ show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
&err_line))
{
fprintf (stderr,
- "Invalid input for signing key to 'show': %s#%u at %u (skipping)\n",
+ "Invalid input for denomination key to 'show': %s#%u at %u (skipping)\n",
err_name,
err_line,
(unsigned int) index);
@@ -1768,7 +1886,45 @@ show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
return GNUNET_SYSERR;
}
- // FIXME: print
+ {
+ char *withdraw_fee_s;
+ char *deposit_fee_s;
+ char *refresh_fee_s;
+ char *refund_fee_s;
+ char *deposit_s;
+ char *legal_s;
+
+ withdraw_fee_s = TALER_amount_to_string (&fee_withdraw);
+ deposit_fee_s = TALER_amount_to_string (&fee_deposit);
+ refresh_fee_s = TALER_amount_to_string (&fee_refresh);
+ refund_fee_s = TALER_amount_to_string (&fee_refund);
+ deposit_s = GNUNET_strdup (
+ GNUNET_STRINGS_absolute_time_to_string (stamp_expire_deposit));
+ legal_s = GNUNET_strdup (
+ GNUNET_STRINGS_absolute_time_to_string (stamp_expire_legal));
+
+ printf (
+ "DENOMINATION-KEY(%s) %s of value %s starting at %s "
+ "(used for: %s, deposit until: %s legal end: %s) with fees %s/%s/%s/%s\n",
+ section_name,
+ TALER_B2S (&h_denom_pub),
+ TALER_amount2s (&coin_value),
+ GNUNET_STRINGS_absolute_time_to_string (stamp_start),
+ GNUNET_STRINGS_relative_time_to_string (duration,
+ GNUNET_NO),
+ deposit_s,
+ legal_s,
+ withdraw_fee_s,
+ deposit_fee_s,
+ refresh_fee_s,
+ refund_fee_s);
+ GNUNET_free (withdraw_fee_s);
+ GNUNET_free (deposit_fee_s);
+ GNUNET_free (refresh_fee_s);
+ GNUNET_free (refund_fee_s);
+ GNUNET_free (deposit_s);
+ GNUNET_free (legal_s);
+ }
GNUNET_JSON_parse_free (spec);
}
@@ -1890,6 +2046,227 @@ do_show (char *const *args)
/**
+ * Sign @a signkeys with offline key.
+ *
+ * @param secm_pub security module public key used to sign the denominations
+ * @param signkeys keys to output
+ * @param[in,out] result array where to output the signatures
+ * @return #GNUNET_OK on success
+ */
+static int
+sign_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
+ const json_t *signkeys,
+ json_t *result)
+{
+ size_t index;
+ json_t *value;
+
+ json_array_foreach (signkeys, index, value) {
+ const char *err_name;
+ unsigned int err_line;
+ struct TALER_ExchangePublicKeyP exchange_pub;
+ struct TALER_SecurityModuleSignatureP secm_sig;
+ struct GNUNET_TIME_Absolute start_time;
+ struct GNUNET_TIME_Absolute sign_end;
+ struct GNUNET_TIME_Absolute legal_end;
+ struct GNUNET_TIME_Relative duration;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_absolute_time ("stamp_start",
+ &start_time),
+ GNUNET_JSON_spec_absolute_time ("stamp_expire",
+ &sign_end),
+ GNUNET_JSON_spec_absolute_time ("stamp_end",
+ &legal_end),
+ GNUNET_JSON_spec_fixed_auto ("key",
+ &exchange_pub),
+ GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig",
+ &secm_sig),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (value,
+ spec,
+ &err_name,
+ &err_line))
+ {
+ fprintf (stderr,
+ "Invalid input for signing key to 'show': %s#%u at %u (skipping)\n",
+ err_name,
+ err_line,
+ (unsigned int) index);
+ global_ret = 7;
+ test_shutdown ();
+ return GNUNET_SYSERR;
+ }
+
+ duration = GNUNET_TIME_absolute_get_difference (start_time,
+ sign_end);
+ if (GNUNET_OK !=
+ TALER_exchange_secmod_eddsa_verify (&exchange_pub,
+ start_time,
+ duration,
+ secm_pub,
+ &secm_sig))
+ {
+ fprintf (stderr,
+ "Invalid security module signature for key %s (aborting)\n",
+ TALER_B2S (&exchange_pub));
+ global_ret = 9;
+ test_shutdown ();
+ return GNUNET_SYSERR;
+ }
+ {
+ struct TALER_MasterSignatureP master_sig;
+
+ TALER_exchange_offline_signkey_validity_sign (&exchange_pub,
+ start_time,
+ sign_end,
+ legal_end,
+ &master_priv,
+ &master_sig);
+ GNUNET_assert (0 ==
+ json_array_append_new (
+ result,
+ json_pack ("{s:o,s:o}",
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&exchange_pub),
+ "master_sig",
+ GNUNET_JSON_from_data_auto (&master_sig))));
+ }
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Sign @a denomkeys with offline key.
+ *
+ * @param secm_pub security module public key used to sign the denominations
+ * @param denomkeys keys to output
+ * @param[in,out] result array where to output the signatures
+ * @return #GNUNET_OK on success
+ */
+static int
+sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
+ const json_t *denomkeys,
+ json_t *result)
+{
+ size_t index;
+ json_t *value;
+
+ json_array_foreach (denomkeys, index, value) {
+ const char *err_name;
+ unsigned int err_line;
+ const char *section_name;
+ struct TALER_DenominationPublicKey denom_pub;
+ struct GNUNET_TIME_Absolute stamp_start;
+ struct GNUNET_TIME_Absolute stamp_expire_withdraw;
+ struct GNUNET_TIME_Absolute stamp_expire_deposit;
+ struct GNUNET_TIME_Absolute stamp_expire_legal;
+ struct TALER_Amount coin_value;
+ struct TALER_Amount fee_withdraw;
+ struct TALER_Amount fee_deposit;
+ struct TALER_Amount fee_refresh;
+ struct TALER_Amount fee_refund;
+ struct TALER_SecurityModuleSignatureP secm_sig;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("section_name",
+ &section_name),
+ GNUNET_JSON_spec_rsa_public_key ("denom_pub",
+ &denom_pub.rsa_public_key),
+ TALER_JSON_spec_amount ("value",
+ &coin_value),
+ TALER_JSON_spec_amount ("fee_withdraw",
+ &fee_withdraw),
+ TALER_JSON_spec_amount ("fee_deposit",
+ &fee_deposit),
+ TALER_JSON_spec_amount ("fee_refresh",
+ &fee_refresh),
+ TALER_JSON_spec_amount ("fee_refund",
+ &fee_refund),
+ GNUNET_JSON_spec_absolute_time ("stamp_start",
+ &stamp_start),
+ GNUNET_JSON_spec_absolute_time ("stamp_expire_withdraw",
+ &stamp_expire_withdraw),
+ GNUNET_JSON_spec_absolute_time ("stamp_expire_deposit",
+ &stamp_expire_deposit),
+ GNUNET_JSON_spec_absolute_time ("stamp_expire_legal",
+ &stamp_expire_legal),
+ GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
+ &secm_sig),
+ GNUNET_JSON_spec_end ()
+ };
+ struct GNUNET_TIME_Relative duration;
+ struct GNUNET_HashCode h_denom_pub;
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (value,
+ spec,
+ &err_name,
+ &err_line))
+ {
+ fprintf (stderr,
+ "Invalid input for denomination key to 'sign': %s#%u at %u (skipping)\n",
+ err_name,
+ err_line,
+ (unsigned int) index);
+ GNUNET_JSON_parse_free (spec);
+ global_ret = 7;
+ test_shutdown ();
+ return GNUNET_SYSERR;
+ }
+ duration = GNUNET_TIME_absolute_get_difference (stamp_start,
+ stamp_expire_withdraw);
+ GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key,
+ &h_denom_pub);
+ if (GNUNET_OK !=
+ TALER_exchange_secmod_rsa_verify (&h_denom_pub,
+ section_name,
+ stamp_start,
+ duration,
+ secm_pub,
+ &secm_sig))
+ {
+ fprintf (stderr,
+ "Invalid security module signature for key %s (aborting)\n",
+ TALER_B2S (&h_denom_pub));
+ global_ret = 9;
+ test_shutdown ();
+ return GNUNET_SYSERR;
+ }
+
+ {
+ struct TALER_MasterSignatureP master_sig;
+
+ TALER_exchange_offline_denom_validity_sign (&h_denom_pub,
+ stamp_start,
+ stamp_expire_withdraw,
+ stamp_expire_deposit,
+ stamp_expire_legal,
+ &coin_value,
+ &fee_withdraw,
+ &fee_deposit,
+ &fee_refresh,
+ &fee_refund,
+ &master_priv,
+ &master_sig);
+ GNUNET_assert (0 ==
+ json_array_append_new (
+ result,
+ json_pack ("{s:o,s:o}",
+ "h_denomn_pub",
+ GNUNET_JSON_from_data_auto (&h_denom_pub),
+ "master_sig",
+ GNUNET_JSON_from_data_auto (&master_sig))));
+ }
+ GNUNET_JSON_parse_free (spec);
+ }
+ return GNUNET_OK;
+}
+
+
+/**
* Sign future keys.
*
* @param args the array of command-line arguments to process next
@@ -1918,10 +2295,94 @@ do_sign (char *const *args)
}
}
+ {
+ const char *err_name;
+ unsigned int err_line;
+ json_t *denomkeys;
+ json_t *signkeys;
+ struct TALER_MasterPublicKeyP mpub;
+ struct TALER_SecurityModulePublicKeyP secm[2];
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_json ("future_denoms",
+ &denomkeys),
+ GNUNET_JSON_spec_json ("future_signkeys",
+ &signkeys),
+ GNUNET_JSON_spec_fixed_auto ("master_pub",
+ &mpub),
+ GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
+ &secm[0]),
+ GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
+ &secm[1]),
+ GNUNET_JSON_spec_end ()
+ };
- // FIXME: do work here!
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (in,
+ spec,
+ &err_name,
+ &err_line))
+ {
+ fprintf (stderr,
+ "Invalid input to 'sign': %s#%u (skipping)\n",
+ err_name,
+ err_line);
+ global_ret = 7;
+ test_shutdown ();
+ return;
+ }
+ if (0 !=
+ GNUNET_memcmp (&master_pub,
+ &mpub))
+ {
+ fprintf (stderr,
+ "Fatal: exchange uses different master key!\n");
+ global_ret = 6;
+ test_shutdown ();
+ GNUNET_JSON_parse_free (spec);
+ return;
+ }
+ if (GNUNET_SYSERR ==
+ tofu_check (secm))
+ {
+ fprintf (stderr,
+ "Fatal: security module keys changed!\n");
+ global_ret = 8;
+ test_shutdown ();
+ GNUNET_JSON_parse_free (spec);
+ return;
+ }
+ {
+ json_t *signkey_sig_array = json_array ();
+ json_t *denomkey_sig_array = json_array ();
+
+ GNUNET_assert (NULL != signkey_sig_array);
+ GNUNET_assert (NULL != denomkey_sig_array);
+ if ( (GNUNET_OK !=
+ sign_signkeys (&secm[0],
+ signkeys,
+ signkey_sig_array)) ||
+ (GNUNET_OK !=
+ sign_denomkeys (&secm[1],
+ denomkeys,
+ denomkey_sig_array)) )
+ {
+ global_ret = 8;
+ test_shutdown ();
+ json_decref (signkey_sig_array);
+ json_decref (denomkey_sig_array);
+ GNUNET_JSON_parse_free (spec);
+ return;
+ }
- /* consume input */
+ output_operation ("upload-keys",
+ json_pack ("{s:o, s:o}",
+ "denom_sigs",
+ denomkey_sig_array,
+ "signkey_sigs",
+ signkey_sig_array));
+ }
+ GNUNET_JSON_parse_free (spec);
+ }
json_decref (in);
in = NULL;
next (args);
diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c
index 43ca5f8c4..cc52f5cf2 100644
--- a/src/exchange/taler-exchange-httpd_management_post_keys.c
+++ b/src/exchange/taler-exchange-httpd_management_post_keys.c
@@ -164,34 +164,20 @@ add_keys (void *cls,
/* check signature is valid */
{
- struct TALER_DenominationKeyValidityPS dkv = {
- .purpose.purpose = htonl (
- TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
- .purpose.size = htonl (sizeof (dkv)),
- .master = TEH_master_public_key,
- .start = GNUNET_TIME_absolute_hton (meta.start),
- .expire_withdraw = GNUNET_TIME_absolute_hton (meta.expire_withdraw),
- .expire_deposit = GNUNET_TIME_absolute_hton (meta.expire_deposit),
- .expire_legal = GNUNET_TIME_absolute_hton (meta.expire_legal),
- .denom_hash = akc->d_sigs[i].h_denom_pub
- };
-
- TALER_amount_hton (&dkv.value,
- &meta.value);
- TALER_amount_hton (&dkv.fee_withdraw,
- &meta.fee_withdraw);
- TALER_amount_hton (&dkv.fee_deposit,
- &meta.fee_deposit);
- TALER_amount_hton (&dkv.fee_refresh,
- &meta.fee_refresh);
- TALER_amount_hton (&dkv.fee_refund,
- &meta.fee_refund);
if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
- &dkv,
- &akc->d_sigs[i].master_sig.eddsa_signature,
- &TEH_master_public_key.eddsa_pub))
+ TALER_exchange_offline_denomkey_validity_verify (
+ &akc->d_sigs[i].h_denom_pub,
+ meta.start,
+ meta.expire_withdraw,
+ meta.expire_deposit,
+ meta.expire_legal,
+ &meta.value,
+ &meta.fee_withdraw,
+ &meta.fee_deposit,
+ &meta.fee_refresh,
+ &meta.fee_refund,
+ &TEH_master_public_key,
+ &akc->d_sigs[i].master_sig))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index b6c7ac72c..757dee675 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1152,6 +1152,71 @@ TALER_exchange_offline_signkey_validity_verify (
/**
+ * Create denomination key validity signature.
+ *
+ * @param h_denom_pub hash of the denomination's public key
+ * @param stamp_start when does the exchange begin signing with this key
+ * @param stamp_expire_withdraw when does the exchange end signing with this key
+ * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key
+ * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key
+ * @param coin_value what is the value of coins signed with this key
+ * @param fee_withdraw what withdraw fee does the exchange charge for this denomination
+ * @param fee_deposit what deposit fee does the exchange charge for this denomination
+ * @param fee_refresh what refresh fee does the exchange charge for this denomination
+ * @param fee_refund what refund fee does the exchange charge for this denomination
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_denom_validity_sign (
+ const struct GNUNET_HashCode *h_denom_pub,
+ struct GNUNET_TIME_Absolute stamp_start,
+ struct GNUNET_TIME_Absolute stamp_expire_withdraw,
+ struct GNUNET_TIME_Absolute stamp_expire_deposit,
+ struct GNUNET_TIME_Absolute stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_Amount *fee_withdraw,
+ const struct TALER_Amount *fee_deposit,
+ const struct TALER_Amount *fee_refresh,
+ const struct TALER_Amount *fee_refund,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify denomination key validity signature.
+ *
+ * @param h_denom_pub hash of the denomination's public key
+ * @param stamp_start when does the exchange begin signing with this key
+ * @param stamp_expire_withdraw when does the exchange end signing with this key
+ * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key
+ * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key
+ * @param coin_value what is the value of coins signed with this key
+ * @param fee_withdraw what withdraw fee does the exchange charge for this denomination
+ * @param fee_deposit what deposit fee does the exchange charge for this denomination
+ * @param fee_refresh what refresh fee does the exchange charge for this denomination
+ * @param fee_refund what refund fee does the exchange charge for this denomination
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+int
+TALER_exchange_offline_denom_validity_verify (
+ const struct GNUNET_HashCode *h_denom_pub,
+ struct GNUNET_TIME_Absolute stamp_start,
+ struct GNUNET_TIME_Absolute stamp_expire_withdraw,
+ struct GNUNET_TIME_Absolute stamp_expire_deposit,
+ struct GNUNET_TIME_Absolute stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_Amount *fee_withdraw,
+ const struct TALER_Amount *fee_deposit,
+ const struct TALER_Amount *fee_refresh,
+ const struct TALER_Amount *fee_refund,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
* Create security module EdDSA signature.
*
* @param exchange_pub public signing key to validate
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index ed6093556..e630adf91 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -472,39 +472,21 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
sizeof (struct GNUNET_HashCode));
if (! check_sigs)
return GNUNET_OK;
- {
- struct TALER_DenominationKeyValidityPS denom_key_issue = {
- .purpose.purpose
- = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
- .purpose.size = htonl (sizeof (denom_key_issue)),
- .master = *master_key,
- .denom_hash = denom_key->h_key,
- .start = GNUNET_TIME_absolute_hton (denom_key->valid_from),
- .expire_withdraw
- = GNUNET_TIME_absolute_hton (denom_key->withdraw_valid_until),
- .expire_deposit = GNUNET_TIME_absolute_hton (denom_key->expire_deposit),
- .expire_legal = GNUNET_TIME_absolute_hton (denom_key->expire_legal)
- };
-
- TALER_amount_hton (&denom_key_issue.value,
- &denom_key->value);
- TALER_amount_hton (&denom_key_issue.fee_withdraw,
- &denom_key->fee_withdraw);
- TALER_amount_hton (&denom_key_issue.fee_deposit,
- &denom_key->fee_deposit);
- TALER_amount_hton (&denom_key_issue.fee_refresh,
- &denom_key->fee_refresh);
- TALER_amount_hton (&denom_key_issue.fee_refund,
- &denom_key->fee_refund);
- EXITIF (GNUNET_SYSERR ==
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
- &denom_key_issue,
- &denom_key->master_sig.eddsa_signature,
- &master_key->eddsa_pub));
- }
+ EXITIF (GNUNET_SYSERR ==
+ TALER_exchange_offline_denom_validity_verify (
+ &denom_key->h_key,
+ denom_key->valid_from,
+ denom_key->withdraw_valid_until,
+ denom_key->expire_deposit,
+ denom_key->expire_legal,
+ &denom_key->value,
+ &denom_key->fee_withdraw,
+ &denom_key->fee_deposit,
+ &denom_key->fee_refresh,
+ &denom_key->fee_refund,
+ master_key,
+ &denom_key->master_sig));
return GNUNET_OK;
-
EXITIF_exit:
/* invalidate denom_key, just to be sure */
memset (denom_key,
diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c
index af7876b93..d8f040321 100644
--- a/src/util/offline_signatures.c
+++ b/src/util/offline_signatures.c
@@ -156,6 +156,97 @@ TALER_exchange_offline_signkey_validity_verify (
void
+TALER_exchange_offline_denom_validity_sign (
+ const struct GNUNET_HashCode *h_denom_pub,
+ struct GNUNET_TIME_Absolute stamp_start,
+ struct GNUNET_TIME_Absolute stamp_expire_withdraw,
+ struct GNUNET_TIME_Absolute stamp_expire_deposit,
+ struct GNUNET_TIME_Absolute stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_Amount *fee_withdraw,
+ const struct TALER_Amount *fee_deposit,
+ const struct TALER_Amount *fee_refresh,
+ const struct TALER_Amount *fee_refund,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_DenominationKeyValidityPS issue = {
+ .purpose.purpose
+ = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
+ .purpose.size
+ = htonl (sizeof (issue)),
+ .start = GNUNET_TIME_absolute_hton (stamp_start),
+ .expire_withdraw = GNUNET_TIME_absolute_hton (stamp_expire_withdraw),
+ .expire_deposit = GNUNET_TIME_absolute_hton (stamp_expire_deposit),
+ .expire_legal = GNUNET_TIME_absolute_hton (stamp_expire_legal),
+ .denom_hash = *h_denom_pub
+ };
+
+ GNUNET_CRYPTO_eddsa_key_get_public (&master_priv->eddsa_priv,
+ &issue.master.eddsa_pub);
+ TALER_amount_hton (&issue.value,
+ coin_value);
+ TALER_amount_hton (&issue.fee_withdraw,
+ fee_withdraw);
+ TALER_amount_hton (&issue.fee_deposit,
+ fee_deposit);
+ TALER_amount_hton (&issue.fee_refresh,
+ fee_refresh);
+ TALER_amount_hton (&issue.fee_refund,
+ fee_refund);
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &issue,
+ &master_sig->eddsa_signature);
+}
+
+
+int
+TALER_exchange_offline_denom_validity_verify (
+ const struct GNUNET_HashCode *h_denom_pub,
+ struct GNUNET_TIME_Absolute stamp_start,
+ struct GNUNET_TIME_Absolute stamp_expire_withdraw,
+ struct GNUNET_TIME_Absolute stamp_expire_deposit,
+ struct GNUNET_TIME_Absolute stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_Amount *fee_withdraw,
+ const struct TALER_Amount *fee_deposit,
+ const struct TALER_Amount *fee_refresh,
+ const struct TALER_Amount *fee_refund,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_DenominationKeyValidityPS dkv = {
+ .purpose.purpose = htonl (
+ TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
+ .purpose.size = htonl (sizeof (dkv)),
+ .master = *master_pub,
+ .start = GNUNET_TIME_absolute_hton (stamp_start),
+ .expire_withdraw = GNUNET_TIME_absolute_hton (stamp_expire_withdraw),
+ .expire_deposit = GNUNET_TIME_absolute_hton (stamp_expire_deposit),
+ .expire_legal = GNUNET_TIME_absolute_hton (stamp_expire_legal),
+ .denom_hash = *h_denom_pub
+ };
+
+ TALER_amount_hton (&dkv.value,
+ coin_value);
+ TALER_amount_hton (&dkv.fee_withdraw,
+ fee_withdraw);
+ TALER_amount_hton (&dkv.fee_deposit,
+ fee_deposit);
+ TALER_amount_hton (&dkv.fee_refresh,
+ fee_refresh);
+ TALER_amount_hton (&dkv.fee_refund,
+ fee_refund);
+ return
+ GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
+ &dkv,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
+void
TALER_exchange_offline_wire_add_sign (
const char *payto_uri,
struct GNUNET_TIME_Absolute now,