From 6cceb617af887df49df74729bb1813bbd75a1346 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 4 Dec 2020 20:29:18 +0100 Subject: centralize (most) offline signing/verifying operations into offline_signatures.c --- .../taler-auditor-httpd_deposit-confirmation.c | 11 +- src/auditor/taler-helper-auditor-aggregation.c | 26 +- src/auditor/taler-helper-auditor-coins.c | 16 +- src/auditor/taler-helper-auditor-reserves.c | 17 +- src/exchange-tools/taler-exchange-offline.c | 4 +- ...nge-httpd_management_denominations_HDP_revoke.c | 32 +-- .../taler-exchange-httpd_management_post_keys.c | 24 +- ...r-exchange-httpd_management_signkey_EP_revoke.c | 31 +- .../taler-exchange-httpd_management_wire.c | 33 +-- .../taler-exchange-httpd_management_wire_disable.c | 35 +-- .../taler-exchange-httpd_management_wire_fees.c | 45 ++- src/exchangedb/exchangedb_denomkeys.c | 58 ++-- src/include/taler_crypto_lib.h | 214 +++++++++++++- src/lib/auditor_api_deposit_confirmation.c | 31 +- src/lib/exchange_api_handle.c | 29 +- src/testing/testing_api_cmd_revoke_denom_key.c | 13 +- src/testing/testing_api_cmd_revoke_sign_key.c | 13 +- src/testing/testing_api_cmd_set_wire_fee.c | 24 +- src/testing/testing_api_cmd_wire_add.c | 15 +- src/testing/testing_api_cmd_wire_del.c | 15 +- src/util/Makefile.am | 1 + src/util/offline_signatures.c | 314 +++++++++++++++++++++ src/util/payto.c | 13 +- src/util/test_payto.c | 2 +- 24 files changed, 692 insertions(+), 324 deletions(-) create mode 100644 src/util/offline_signatures.c (limited to 'src') diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 67bac1b79..08a781f30 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -111,10 +111,13 @@ verify_and_execute_deposit_confirmation ( { /* Not in cache, need to verify the signature, persist it, and possibly cache it */ if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY, - &skv, - &es->master_sig.eddsa_signature, - &es->master_public_key.eddsa_pub)) + TALER_exchange_offline_signkey_validity_verify ( + &es->exchange_pub, + es->ep_start, + es->ep_expire, + es->ep_end, + &es->master_public_key, + &es->master_sig)) { TALER_LOG_WARNING ("Invalid signature on exchange signing key\n"); return TALER_MHD_reply_with_error (connection, diff --git a/src/auditor/taler-helper-auditor-aggregation.c b/src/auditor/taler-helper-auditor-aggregation.c index e3e840e8e..f3f65ffb3 100644 --- a/src/auditor/taler-helper-auditor-aggregation.c +++ b/src/auditor/taler-helper-auditor-aggregation.c @@ -944,25 +944,15 @@ get_wire_fee (struct AggregationContext *ac, easily make this one up, but it means that we have proof that the master key was used for inconsistent wire fees if a merchant complains.) */ { - struct TALER_MasterWireFeePS wf = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES), - .purpose.size = htonl (sizeof (wf)), - .start_date = GNUNET_TIME_absolute_hton (wfi->start_date), - .end_date = GNUNET_TIME_absolute_hton (wfi->end_date) - }; - - GNUNET_CRYPTO_hash (method, - strlen (method) + 1, - &wf.h_wire_method); - TALER_amount_hton (&wf.wire_fee, - &wfi->wire_fee); - TALER_amount_hton (&wf.closing_fee, - &wfi->closing_fee); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES, - &wf, - &master_sig.eddsa_signature, - &TALER_ARL_master_pub.eddsa_pub)) + TALER_exchange_offline_wire_fee_verify ( + method, + wfi->start_date, + wfi->end_date, + &wfi->wire_fee, + &wfi->closing_fee, + &TALER_ARL_master_pub, + &master_sig)) { report_row_inconsistency ("wire-fee", timestamp.abs_value_us, diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 067d6703a..55feeec36 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -715,19 +715,11 @@ init_denomination (const struct GNUNET_HashCode *denom_hash, if (0 < qs) { /* check revocation signature */ - struct TALER_MasterDenominationKeyRevocationPS rm = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), - .purpose.size = htonl (sizeof (rm)), - .h_denom_pub = *denom_hash - }; - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED, - &rm, - &msig.eddsa_signature, - &TALER_ARL_master_pub.eddsa_pub)) + TALER_exchange_offline_denomination_revoke_verify ( + denom_hash, + &TALER_ARL_master_pub, + &msig)) { report_row_inconsistency ("denomination revocations", rowid, diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c index d666aae85..8f7921fa8 100644 --- a/src/auditor/taler-helper-auditor-reserves.c +++ b/src/auditor/taler-helper-auditor-reserves.c @@ -747,20 +747,11 @@ handle_recoup_by_reserve ( } else { - /* verify msig */ - struct TALER_MasterDenominationKeyRevocationPS kr = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), - .purpose.size = htonl (sizeof (kr)), - .h_denom_pub = coin->denom_pub_hash - }; - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED, - &kr, - &msig.eddsa_signature, - &TALER_ARL_master_pub.eddsa_pub)) + TALER_exchange_offline_denomination_revoke_verify ( + &coin->denom_pub_hash, + &TALER_ARL_master_pub, + &msig)) { rev = "master signature invalid"; } diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c index a33b09eab..506bb9afb 100644 --- a/src/exchange-tools/taler-exchange-offline.c +++ b/src/exchange-tools/taler-exchange-offline.c @@ -574,7 +574,9 @@ do_revoke_denomination_key (char *const *args) if (GNUNET_OK != load_offline_key ()) return; - // FIXME: do sign, create master_sig! + TALER_exchange_offline_denomination_revoke_sign (&h_denom_pub, + &master_priv, + &master_sig); output_operation ("revoke-denomination", json_pack ("{s:o, s:o}", "h_denom_pub", diff --git a/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c b/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c index eade5cd1a..75ce3d76b 100644 --- a/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c +++ b/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c @@ -56,28 +56,18 @@ TEH_handler_management_denominations_HDP_revoke ( if (GNUNET_NO == res) return MHD_YES; /* failure */ } + if (GNUNET_OK != + TALER_exchange_offline_denomination_revoke_verify ( + h_denom_pub, + &TEH_master_public_key, + &master_sig)) { - struct TALER_MasterDenominationKeyRevocationPS rm = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), - .purpose.size = htonl (sizeof (rm)), - .h_denom_pub = *h_denom_pub - }; - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED, - &rm, - &master_sig.eddsa_signature, - &TEH_master_public_key.eddsa_pub)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_MANAGEMENT_DENOMINATION_REVOKE_SIGNATURE_INVALID, - NULL); - } + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_MANAGEMENT_DENOMINATION_REVOKE_SIGNATURE_INVALID, + NULL); } qs = TEH_plugin->insert_denomination_revocation (TEH_plugin->cls, NULL, diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c index 2ac69a1db..43ca5f8c4 100644 --- a/src/exchange/taler-exchange-httpd_management_post_keys.c +++ b/src/exchange/taler-exchange-httpd_management_post_keys.c @@ -269,23 +269,15 @@ add_keys (void *cls, /* check signature is valid */ { - struct TALER_ExchangeSigningKeyValidityPS skv = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY), - .purpose.size = htonl (sizeof (skv)), - .master_public_key = TEH_master_public_key, - .start = x, - .expire = y, - .end = z, - .signkey_pub = akc->s_sigs[i].exchange_pub - }; - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY, - &skv, - &akc->s_sigs[i].master_sig.eddsa_signature, - &TEH_master_public_key.eddsa_pub)) + TALER_exchange_offline_signkey_validity_verify ( + &akc->s_sigs[i].exchange_pub, + x, + y, + z, + &TEH_master_public_key, + & + & akc->s_sigs[i].master_sig)) { GNUNET_break_op (0); return TALER_MHD_reply_with_error ( diff --git a/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c b/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c index 63a4f0c65..8a462f967 100644 --- a/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c +++ b/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c @@ -56,28 +56,17 @@ TEH_handler_management_signkeys_EP_revoke ( if (GNUNET_NO == res) return MHD_YES; /* failure */ } + if (GNUNET_OK != + TALER_exchange_offline_signkey_revoke_verify (exchange_pub, + &TEH_master_public_key, + &master_sig)) { - struct TALER_MasterSigningKeyRevocationPS rm = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED), - .purpose.size = htonl (sizeof (rm)), - .exchange_pub = *exchange_pub - }; - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED, - &rm, - &master_sig.eddsa_signature, - &TEH_master_public_key.eddsa_pub)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_MANAGEMENT_SIGNKEY_REVOKE_SIGNATURE_INVALID, - NULL); - } + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_MANAGEMENT_SIGNKEY_REVOKE_SIGNATURE_INVALID, + NULL); } qs = TEH_plugin->insert_signkey_revocation (TEH_plugin->cls, NULL, diff --git a/src/exchange/taler-exchange-httpd_management_wire.c b/src/exchange/taler-exchange-httpd_management_wire.c index 2ec42c3bc..15e5b3610 100644 --- a/src/exchange/taler-exchange-httpd_management_wire.c +++ b/src/exchange/taler-exchange-httpd_management_wire.c @@ -168,29 +168,18 @@ TEH_handler_management_denominations_wire ( if (GNUNET_NO == res) return MHD_YES; /* failure */ } + if (GNUNET_OK != + TALER_exchange_offline_wire_add_verify (awc.payto_uri, + awc.validity_start, + &TEH_master_public_key, + &awc.master_sig_add)) { - struct TALER_MasterAddWirePS aw = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE), - .purpose.size = htonl (sizeof (aw)), - .start_date = GNUNET_TIME_absolute_hton (awc.validity_start), - }; - - TALER_exchange_wire_signature_hash (awc.payto_uri, - &aw.h_wire); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_ADD_WIRE, - &aw, - &awc.master_sig_add.eddsa_signature, - &TEH_master_public_key.eddsa_pub)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_MANAGEMENT_WIRE_ADD_SIGNATURE_INVALID, - NULL); - } + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_MANAGEMENT_WIRE_ADD_SIGNATURE_INVALID, + NULL); } if (GNUNET_OK != TALER_exchange_wire_signature_check (awc.payto_uri, diff --git a/src/exchange/taler-exchange-httpd_management_wire_disable.c b/src/exchange/taler-exchange-httpd_management_wire_disable.c index af5942a1b..51b811604 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_disable.c +++ b/src/exchange/taler-exchange-httpd_management_wire_disable.c @@ -161,30 +161,19 @@ TEH_handler_management_denominations_wire_disable ( if (GNUNET_NO == res) return MHD_YES; /* failure */ } + if (GNUNET_OK != + TALER_exchange_offline_wire_del_verify ( + awc.payto_uri, + awc.validity_end, + &TEH_master_public_key, + &awc.master_sig)) { - struct TALER_MasterDelWirePS aw = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DEL_WIRE), - .purpose.size = htonl (sizeof (aw)), - .end_date = GNUNET_TIME_absolute_hton (awc.validity_end), - }; - - TALER_exchange_wire_signature_hash (awc.payto_uri, - &aw.h_wire); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_DEL_WIRE, - &aw, - &awc.master_sig.eddsa_signature, - &TEH_master_public_key.eddsa_pub)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_MANAGEMENT_WIRE_DEL_SIGNATURE_INVALID, - NULL); - } + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_MANAGEMENT_WIRE_DEL_SIGNATURE_INVALID, + NULL); } qs = TEH_DB_run_transaction (connection, "del wire", diff --git a/src/exchange/taler-exchange-httpd_management_wire_fees.c b/src/exchange/taler-exchange-httpd_management_wire_fees.c index 58f2c41d7..9878821c1 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_fees.c +++ b/src/exchange/taler-exchange-httpd_management_wire_fees.c @@ -221,36 +221,23 @@ TEH_handler_management_post_wire_fees ( TEH_currency); } + if (GNUNET_OK != + TALER_exchange_offline_wire_fee_verify ( + afc.wire_method, + afc.start_time, + afc.end_time, + &afc.wire_fee, + &afc.closing_fee, + &TEH_master_public_key, + &afc.master_sig)) { - struct TALER_MasterWireFeePS wf = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES), - .purpose.size = htonl (sizeof (wf)), - .start_date = GNUNET_TIME_absolute_hton (afc.start_time), - .end_date = GNUNET_TIME_absolute_hton (afc.end_time), - }; - - TALER_amount_hton (&wf.wire_fee, - &afc.wire_fee); - TALER_amount_hton (&wf.closing_fee, - &afc.closing_fee); - GNUNET_CRYPTO_hash (afc.wire_method, - strlen (afc.wire_method) + 1, - &wf.h_wire_method); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_WIRE_FEES, - &wf, - &afc.master_sig.eddsa_signature, - &TEH_master_public_key.eddsa_pub)) - { - /* signature invalid */ - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_MANAGEMENT_WIRE_FEE_SIGNATURE_INVALID, - NULL); - } + /* signature invalid */ + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_MANAGEMENT_WIRE_FEE_SIGNATURE_INVALID, + NULL); } qs = TEH_DB_run_transaction (connection, diff --git a/src/exchangedb/exchangedb_denomkeys.c b/src/exchangedb/exchangedb_denomkeys.c index ec77d7f0b..81828aaee 100644 --- a/src/exchangedb/exchangedb_denomkeys.c +++ b/src/exchangedb/exchangedb_denomkeys.c @@ -22,6 +22,7 @@ * @author Christian Grothoff */ #include "platform.h" +#include "taler_crypto_lib.h" #include "taler_exchangedb_lib.h" @@ -67,18 +68,9 @@ TALER_EXCHANGEDB_denomination_key_revoke ( int ret; struct RevocationFileP rd; - { - struct TALER_MasterDenominationKeyRevocationPS rm = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), - .purpose.size = htonl (sizeof (rm)), - .h_denom_pub = *denom_hash - }; - - GNUNET_CRYPTO_eddsa_sign (&mpriv->eddsa_priv, - &rm, - &rd.msig.eddsa_signature); - } + TALER_exchange_offline_denomination_revoke_sign (denom_hash, + mpriv, + &rd.msig); GNUNET_asprintf (&fn, "%s" DIR_SEPARATOR_STR "%s.rev", @@ -464,34 +456,24 @@ revocations_iterate_cb (void *cls, return GNUNET_OK; } + if (GNUNET_OK != + TALER_exchange_offline_denomination_revoke_verify ( + &rf.denom_hash, + ric->master_pub, + &rf.msig)) { - struct TALER_MasterDenominationKeyRevocationPS rm = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), - .purpose.size = htonl (sizeof (rm)), - .h_denom_pub = rf.denom_hash - }; - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED, - &rm, - &rf.msig.eddsa_signature, - &ric->master_pub->eddsa_pub)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Invalid revocation file `%s' found and ignored (bad signature)\n", - filename); - return GNUNET_OK; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Denomination key `%s' was revoked!\n", - GNUNET_h2s (&rm.h_denom_pub)); - return ric->it (ric->it_cls, - &rm.h_denom_pub, - &rf.msig); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid revocation file `%s' found and ignored (bad signature)\n", + filename); + return GNUNET_OK; } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Denomination key `%s' was revoked!\n", + GNUNET_h2s (&rf.denom_hash)); + return ric->it (ric->it_cls, + &rf.denom_hash, + &rf.msig); } diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 5e50ddd3f..8203bb9af 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1050,9 +1050,221 @@ TALER_CRYPTO_helper_esign_disconnect ( struct TALER_CRYPTO_ExchangeSignHelper *esh); +/* ********************* offline signing ************************** */ + +/** + * Create denomination revocation signature. + * + * @param h_denom_pub hash of public denomination key to revoke + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_denomination_revoke_sign ( + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify denomination revocation signature. + * + * @param h_denom_pub hash of public denomination key to revoke + * @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_denomination_revoke_verify ( + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + +/** + * Create signkey revocation signature. + * + * @param exchange_pub public signing key to revoke + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_signkey_revoke_sign ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify signkey revocation signature. + * + * @param exchange_pub public signkey key to revoke + * @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_signkey_revoke_verify ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + +/** + * Create signkey validity signature. + * + * @param exchange_pub public signing key to validate + * @param start_sign starting point of validity for signing + * @param end_sign end point (exclusive) for validity for signing + * @param end_legal legal end point of signature validity + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_signkey_validity_sign ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct GNUNET_TIME_Absolute start_sign, + struct GNUNET_TIME_Absolute end_sign, + struct GNUNET_TIME_Absolute end_legal, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify signkey validitity signature. + * + * @param exchange_pub public signkey key to validate + * @param start_sign starting point of validity for signing + * @param end_sign end point (exclusive) for validity for signing + * @param end_legal legal end point of signature validity + * @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_signkey_validity_verify ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct GNUNET_TIME_Absolute start_sign, + struct GNUNET_TIME_Absolute end_sign, + struct GNUNET_TIME_Absolute end_legal, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + /* **************** /wire account offline signing **************** */ +/** + * Create wire fee signature. + * + * @param payment_method the payment method + * @param start_time when do the fees start to apply + * @param end_time when do the fees start to apply + * @param wire_fee the wire fee + * @param closing_fee the closing fee + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_wire_fee_sign ( + const char *payment_method, + struct GNUNET_TIME_Absolute start_time, + struct GNUNET_TIME_Absolute end_time, + const struct TALER_Amount *wire_fee, + const struct TALER_Amount *closing_fee, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify wire fee signature. + * + * @param payment_method the payment method + * @param start_time when do the fees start to apply + * @param end_time when do the fees start to apply + * @param wire_fee the wire fee + * @param closing_fee the closing fee + * @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_wire_fee_verify ( + const char *payment_method, + struct GNUNET_TIME_Absolute start_time, + struct GNUNET_TIME_Absolute end_time, + const struct TALER_Amount *wire_fee, + const struct TALER_Amount *closing_fee, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + +/** + * Create wire account addition signature. + * + * @param payto_uri bank account + * @param now timestamp to use for the signature (rounded) + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_wire_add_sign ( + const char *payto_uri, + struct GNUNET_TIME_Absolute now, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify wire account addition signature. + * + * @param payto_uri bank account + * @param sign_time timestamp when signature was created + * @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_wire_add_verify ( + const char *payto_uri, + struct GNUNET_TIME_Absolute sign_time, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + +/** + * Create wire account removal signature. + * + * @param payto_uri bank account + * @param now timestamp to use for the signature (rounded) + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_wire_del_sign ( + const char *payto_uri, + struct GNUNET_TIME_Absolute now, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify wire account deletion signature. + * + * @param payto_uri bank account + * @param sign_time timestamp when signature was created + * @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_wire_del_verify ( + const char *payto_uri, + struct GNUNET_TIME_Absolute sign_time, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + /** * Compute the hash of the given wire details. The resulting * hash is what is signed by the master key. @@ -1068,7 +1280,7 @@ TALER_exchange_wire_signature_hash (const char *payto_uri, /** * Check the signature in @a master_sig. * - * @param payto_uri URL that is signed + * @param payto_uri URI that is signed * @param master_pub master public key of the exchange * @param master_sig signature of the exchange * @return #GNUNET_OK if signature is valid diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index ff65036e0..bea5a78a5 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -208,27 +208,18 @@ verify_signatures (const struct GNUNET_HashCode *h_wire, return GNUNET_SYSERR; } } + if (GNUNET_OK != + TALER_exchange_offline_signkey_validity_verify ( + exchange_pub, + ep_start, + ep_expire, + ep_end, + master_pub, + master_sig)) { - struct TALER_ExchangeSigningKeyValidityPS sv = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY), - .purpose.size = htonl (sizeof (sv)), - .master_public_key = *master_pub, - .start = GNUNET_TIME_absolute_hton (ep_start), - .expire = GNUNET_TIME_absolute_hton (ep_expire), - .end = GNUNET_TIME_absolute_hton (ep_end), - .signkey_pub = *exchange_pub - }; - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY, - &sv, - &master_sig->eddsa_signature, - &master_pub->eddsa_pub)) - { - GNUNET_break (0); - TALER_LOG_WARNING ("Invalid signature on exchange signing key!\n"); - return GNUNET_SYSERR; - } + GNUNET_break (0); + TALER_LOG_WARNING ("Invalid signature on exchange signing key!\n"); + return GNUNET_SYSERR; } if (0 == GNUNET_TIME_absolute_get_remaining (ep_end).rel_value_us) { diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 4d8f0d037..ed6093556 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -394,26 +394,17 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key, if (! check_sigs) return GNUNET_OK; + if (GNUNET_OK != + TALER_exchange_offline_signkey_validity_verify + (&sign_key->key, + sign_key->valid_from, + sign_key->valid_until, + sign_key->valid_legal, + master_key, + &sign_key_issue_sig)) { - struct TALER_ExchangeSigningKeyValidityPS sign_key_issue = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY), - .purpose.size = htonl (sizeof (sign_key_issue)), - .signkey_pub = sign_key->key, - .master_public_key = *master_key, - .start = GNUNET_TIME_absolute_hton (sign_key->valid_from), - .expire = GNUNET_TIME_absolute_hton (sign_key->valid_until), - .end = GNUNET_TIME_absolute_hton (sign_key->valid_legal) - }; - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY, - &sign_key_issue, - &sign_key_issue_sig.eddsa_signature, - &master_key->eddsa_pub)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } + GNUNET_break_op (0); + return GNUNET_SYSERR; } sign_key->master_sig = sign_key_issue_sig; return GNUNET_OK; diff --git a/src/testing/testing_api_cmd_revoke_denom_key.c b/src/testing/testing_api_cmd_revoke_denom_key.c index 7dffcf395..fd7695bce 100644 --- a/src/testing/testing_api_cmd_revoke_denom_key.c +++ b/src/testing/testing_api_cmd_revoke_denom_key.c @@ -187,16 +187,9 @@ revoke_run (void *cls, } else { - struct TALER_MasterDenominationKeyRevocationPS kv = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), - .purpose.size = htonl (sizeof (kv)), - .h_denom_pub = denom_pub->h_key - }; - - GNUNET_CRYPTO_eddsa_sign (&is->master_priv.eddsa_priv, - &kv, - &master_sig.eddsa_signature); + TALER_exchange_offline_denomination_revoke_sign (&denom_pub->h_key, + &is->master_priv, + &master_sig); } rs->kh = TALER_EXCHANGE_management_revoke_denomination_key ( is->ctx, diff --git a/src/testing/testing_api_cmd_revoke_sign_key.c b/src/testing/testing_api_cmd_revoke_sign_key.c index d85f63053..599fe180b 100644 --- a/src/testing/testing_api_cmd_revoke_sign_key.c +++ b/src/testing/testing_api_cmd_revoke_sign_key.c @@ -187,16 +187,9 @@ revoke_run (void *cls, } else { - struct TALER_MasterSigningKeyRevocationPS kv = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED), - .purpose.size = htonl (sizeof (kv)), - .exchange_pub = *exchange_pub - }; - - GNUNET_CRYPTO_eddsa_sign (&is->master_priv.eddsa_priv, - &kv, - &master_sig.eddsa_signature); + TALER_exchange_offline_signkey_revoke_sign (exchange_pub, + &is->master_priv, + &master_sig); } rs->kh = TALER_EXCHANGE_management_revoke_signing_key ( is->ctx, diff --git a/src/testing/testing_api_cmd_set_wire_fee.c b/src/testing/testing_api_cmd_set_wire_fee.c index 1f8b3994a..613e0f713 100644 --- a/src/testing/testing_api_cmd_set_wire_fee.c +++ b/src/testing/testing_api_cmd_set_wire_fee.c @@ -152,23 +152,13 @@ wire_add_run (void *cls, } else { - struct TALER_MasterWireFeePS kv = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES), - .purpose.size = htonl (sizeof (kv)), - .start_date = GNUNET_TIME_absolute_hton (start_time), - .end_date = GNUNET_TIME_absolute_hton (end_time), - }; - - GNUNET_CRYPTO_hash (ds->wire_method, - strlen (ds->wire_method) + 1, - &kv.h_wire_method); - TALER_amount_hton (&kv.wire_fee, - &wire_fee); - TALER_amount_hton (&kv.closing_fee, - &closing_fee); - GNUNET_CRYPTO_eddsa_sign (&is->master_priv.eddsa_priv, - &kv, - &master_sig.eddsa_signature); + TALER_exchange_offline_wire_fee_sign (ds->wire_method, + start_time, + end_time, + &wire_fee, + &closing_fee, + &is->master_priv, + &master_sig); } ds->dh = TALER_EXCHANGE_management_set_wire_fees ( is->ctx, diff --git a/src/testing/testing_api_cmd_wire_add.c b/src/testing/testing_api_cmd_wire_add.c index 6f25a0f86..8d8a3a4f6 100644 --- a/src/testing/testing_api_cmd_wire_add.c +++ b/src/testing/testing_api_cmd_wire_add.c @@ -126,17 +126,10 @@ wire_add_run (void *cls, } else { - struct TALER_MasterAddWirePS kv = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE), - .purpose.size = htonl (sizeof (kv)), - .start_date = GNUNET_TIME_absolute_hton (now), - }; - - TALER_exchange_wire_signature_hash (ds->payto_uri, - &kv.h_wire); - GNUNET_CRYPTO_eddsa_sign (&is->master_priv.eddsa_priv, - &kv, - &master_sig1.eddsa_signature); + TALER_exchange_offline_wire_add_sign (ds->payto_uri, + now, + &is->master_priv, + &master_sig1); TALER_exchange_wire_signature_make (ds->payto_uri, &is->master_priv, &master_sig2); diff --git a/src/testing/testing_api_cmd_wire_del.c b/src/testing/testing_api_cmd_wire_del.c index 2019d1366..2a1c9e455 100644 --- a/src/testing/testing_api_cmd_wire_del.c +++ b/src/testing/testing_api_cmd_wire_del.c @@ -122,17 +122,10 @@ wire_del_run (void *cls, } else { - struct TALER_MasterDelWirePS kv = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_WIRE), - .purpose.size = htonl (sizeof (kv)), - .end_date = GNUNET_TIME_absolute_hton (now), - }; - - TALER_exchange_wire_signature_hash (ds->payto_uri, - &kv.h_wire); - GNUNET_CRYPTO_eddsa_sign (&is->master_priv.eddsa_priv, - &kv, - &master_sig.eddsa_signature); + TALER_exchange_offline_wire_del_sign (ds->payto_uri, + now, + &is->master_priv, + &master_sig); } ds->dh = TALER_EXCHANGE_management_disable_wire ( is->ctx, diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 95ac60a96..c65a3ef17 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -68,6 +68,7 @@ libtalerutil_la_SOURCES = \ getopt.c \ lang.c \ mhd.c \ + offline_signatures.c \ payto.c \ taler_error_codes.c \ url.c \ diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c new file mode 100644 index 000000000..af7876b93 --- /dev/null +++ b/src/util/offline_signatures.c @@ -0,0 +1,314 @@ +/* + This file is part of TALER + Copyright (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 +*/ +/** + * @file offline_signatures.c + * @brief Utility functions for Taler exchange offline signatures + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_signatures.h" + + +void +TALER_exchange_offline_denomination_revoke_sign ( + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterDenominationKeyRevocationPS rm = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), + .purpose.size = htonl (sizeof (rm)), + .h_denom_pub = *h_denom_pub + }; + + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &rm, + &master_sig->eddsa_signature); +} + + +int +TALER_exchange_offline_denomination_revoke_verify ( + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterDenominationKeyRevocationPS kr = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED), + .purpose.size = htonl (sizeof (kr)), + .h_denom_pub = *h_denom_pub + }; + + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED, + &kr, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + +void +TALER_exchange_offline_signkey_revoke_sign ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterSigningKeyRevocationPS kv = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED), + .purpose.size = htonl (sizeof (kv)), + .exchange_pub = *exchange_pub + }; + + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &kv, + &master_sig->eddsa_signature); +} + + +int +TALER_exchange_offline_signkey_revoke_verify ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterSigningKeyRevocationPS rm = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED), + .purpose.size = htonl (sizeof (rm)), + .exchange_pub = *exchange_pub + }; + + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED, + &rm, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + +void +TALER_exchange_offline_signkey_validity_sign ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct GNUNET_TIME_Absolute start_sign, + struct GNUNET_TIME_Absolute end_sign, + struct GNUNET_TIME_Absolute end_legal, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_ExchangeSigningKeyValidityPS skv = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY), + .purpose.size = htonl (sizeof (skv)), + .start = GNUNET_TIME_absolute_hton (start_sign), + .expire = GNUNET_TIME_absolute_hton (end_sign), + .end = GNUNET_TIME_absolute_hton (end_legal), + .signkey_pub = *exchange_pub + }; + + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &skv, + &master_sig->eddsa_signature); +} + + +int +TALER_exchange_offline_signkey_validity_verify ( + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct GNUNET_TIME_Absolute start_sign, + struct GNUNET_TIME_Absolute end_sign, + struct GNUNET_TIME_Absolute end_legal, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_ExchangeSigningKeyValidityPS skv = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY), + .purpose.size = htonl (sizeof (skv)), + .start = GNUNET_TIME_absolute_hton (start_sign), + .expire = GNUNET_TIME_absolute_hton (end_sign), + .end = GNUNET_TIME_absolute_hton (end_legal), + .signkey_pub = *exchange_pub + }; + + return + GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY, + &skv, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + +void +TALER_exchange_offline_wire_add_sign ( + const char *payto_uri, + struct GNUNET_TIME_Absolute now, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterAddWirePS kv = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE), + .purpose.size = htonl (sizeof (kv)), + .start_date = GNUNET_TIME_absolute_hton (now), + }; + + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&now)); + TALER_exchange_wire_signature_hash (payto_uri, + &kv.h_wire); + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &kv, + &master_sig->eddsa_signature); +} + + +int +TALER_exchange_offline_wire_add_verify ( + const char *payto_uri, + struct GNUNET_TIME_Absolute sign_time, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterAddWirePS aw = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE), + .purpose.size = htonl (sizeof (aw)), + .start_date = GNUNET_TIME_absolute_hton (sign_time), + }; + + TALER_exchange_wire_signature_hash (payto_uri, + &aw.h_wire); + return + GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_MASTER_ADD_WIRE, + &aw, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + +void +TALER_exchange_offline_wire_del_sign ( + const char *payto_uri, + struct GNUNET_TIME_Absolute now, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterDelWirePS kv = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_WIRE), + .purpose.size = htonl (sizeof (kv)), + .end_date = GNUNET_TIME_absolute_hton (now), + }; + + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&now)); + TALER_exchange_wire_signature_hash (payto_uri, + &kv.h_wire); + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &kv, + &master_sig->eddsa_signature); +} + + +int +TALER_exchange_offline_wire_del_verify ( + const char *payto_uri, + struct GNUNET_TIME_Absolute sign_time, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterDelWirePS aw = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_MASTER_DEL_WIRE), + .purpose.size = htonl (sizeof (aw)), + .end_date = GNUNET_TIME_absolute_hton (sign_time), + }; + + TALER_exchange_wire_signature_hash (payto_uri, + &aw.h_wire); + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_MASTER_DEL_WIRE, + &aw, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + +void +TALER_exchange_offline_wire_fee_sign ( + const char *payment_method, + struct GNUNET_TIME_Absolute start_time, + struct GNUNET_TIME_Absolute end_time, + const struct TALER_Amount *wire_fee, + const struct TALER_Amount *closing_fee, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterWireFeePS kv = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES), + .purpose.size = htonl (sizeof (kv)), + .start_date = GNUNET_TIME_absolute_hton (start_time), + .end_date = GNUNET_TIME_absolute_hton (end_time), + }; + + GNUNET_CRYPTO_hash (payment_method, + strlen (payment_method) + 1, + &kv.h_wire_method); + TALER_amount_hton (&kv.wire_fee, + wire_fee); + TALER_amount_hton (&kv.closing_fee, + closing_fee); + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &kv, + &master_sig->eddsa_signature); +} + + +int +TALER_exchange_offline_wire_fee_verify ( + const char *payment_method, + struct GNUNET_TIME_Absolute start_time, + struct GNUNET_TIME_Absolute end_time, + const struct TALER_Amount *wire_fee, + const struct TALER_Amount *closing_fee, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterWireFeePS wf = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES), + .purpose.size = htonl (sizeof (wf)), + .start_date = GNUNET_TIME_absolute_hton (start_time), + .end_date = GNUNET_TIME_absolute_hton (end_time) + }; + + GNUNET_CRYPTO_hash (payment_method, + strlen (payment_method) + 1, + &wf.h_wire_method); + TALER_amount_hton (&wf.wire_fee, + wire_fee); + TALER_amount_hton (&wf.closing_fee, + closing_fee); + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES, + &wf, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + +/* end of offline_signatures.c */ diff --git a/src/util/payto.c b/src/util/payto.c index 4b2bbf4e3..54072d667 100644 --- a/src/util/payto.c +++ b/src/util/payto.c @@ -49,24 +49,25 @@ TALER_payto_get_subject (const char *payto_uri) do { if (0 == strncasecmp (++key, - "subject", - strlen ("subject"))) + "subject", + strlen ("subject"))) { value_start = strchr (key, - (unsigned char) '='); + (unsigned char) '='); if (NULL == value_start) return NULL; value_end = strchrnul (value_start, - (unsigned char) '&'); + (unsigned char) '&'); return GNUNET_strndup (value_start + 1, - value_end - value_start - 1); + value_end - value_start - 1); } } while ( (key = strchr (key, - (unsigned char) '&')) ); + (unsigned char) '&')) ); return NULL; } + /** * Obtain the payment method from a @a payto_uri. The * format of a payto URI is 'payto://$METHOD/$SOMETHING'. diff --git a/src/util/test_payto.c b/src/util/test_payto.c index c809a0396..321e998b7 100644 --- a/src/util/test_payto.c +++ b/src/util/test_payto.c @@ -58,7 +58,7 @@ main (int argc, r = TALER_payto_get_subject ( "payto://x-taler-bank/localhost:1080/alice?subject=hello&amount=EUR:1"); CHECK ("hello", - r); + r); r = TALER_payto_get_subject ( "payto://x-taler-bank/localhost:1080/alice"); -- cgit v1.2.3