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 --- src/util/Makefile.am | 1 + src/util/offline_signatures.c | 314 ++++++++++++++++++++++++++++++++++++++++++ src/util/payto.c | 13 +- src/util/test_payto.c | 2 +- 4 files changed, 323 insertions(+), 7 deletions(-) create mode 100644 src/util/offline_signatures.c (limited to 'src/util') 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