aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-11-26 15:00:34 +0100
committerChristian Grothoff <christian@grothoff.org>2020-11-26 15:00:34 +0100
commit2c88cff2837cb6f8b1b95822dd53f1d338055474 (patch)
treed7dcb40051c669a4140c21e26660edcbf2e16323
parent440d0e6ea4ddc677d6e3046bc64cdf0013f5b7ad (diff)
add logic to parse and check secmod signatures
-rw-r--r--src/include/taler_exchange_service.h25
-rw-r--r--src/lib/exchange_api_management_get_keys.c325
2 files changed, 228 insertions, 122 deletions
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index 92b220e1d..8b1feb157 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1931,6 +1931,11 @@ struct TALER_EXCHANGE_FutureSigningPublicKey
struct TALER_ExchangePublicKeyP key;
/**
+ * Signature by the security module affirming it owns this key.
+ */
+ struct TALER_SecurityModuleSignatureP signkey_secmod_sig;
+
+ /**
* Validity start time
*/
struct GNUNET_TIME_Absolute valid_from;
@@ -1958,6 +1963,11 @@ struct TALER_EXCHANGE_FutureDenomPublicKey
struct TALER_DenominationPublicKey key;
/**
+ * Signature by the security module affirming it owns this key.
+ */
+ struct TALER_SecurityModuleSignatureP denom_secmod_sig;
+
+ /**
* Timestamp indicating when the denomination key becomes valid
*/
struct GNUNET_TIME_Absolute valid_from;
@@ -2027,6 +2037,21 @@ struct TALER_EXCHANGE_FutureKeys
struct TALER_EXCHANGE_FutureDenomPublicKey *denom_keys;
/**
+ * Public key of the signkey security module.
+ */
+ struct TALER_SecurityModulePublicKeyP signkey_secmod_public_key;
+
+ /**
+ * Public key of the denomination security module.
+ */
+ struct TALER_SecurityModulePublicKeyP denom_secmod_public_key;
+
+ /**
+ * Offline master public key used by this exchange.
+ */
+ struct TALER_MasterPublicKeyP master_pub;
+
+ /**
* Length of the @e sign_keys array (number of valid entries).
*/
unsigned int num_sign_keys;
diff --git a/src/lib/exchange_api_management_get_keys.c b/src/lib/exchange_api_management_get_keys.c
index 7148af516..dfee6776e 100644
--- a/src/lib/exchange_api_management_get_keys.c
+++ b/src/lib/exchange_api_management_get_keys.c
@@ -61,6 +61,201 @@ struct TALER_EXCHANGE_ManagementGetKeysHandle
/**
+ * Handle the case that the response was of type #MHD_HTTP_OK.
+ *
+ * @param[in,out] gh request handle
+ * @param response the response
+ * @return #MHD_OK if the response was well-formed
+ */
+static int
+handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
+ const json_t *response)
+{
+ struct TALER_EXCHANGE_FutureKeys fk;
+ json_t *sk;
+ json_t *dk;
+ bool ok;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_json ("future_denoms",
+ &dk),
+ GNUNET_JSON_spec_json ("future_signkeys",
+ &sk),
+ GNUNET_JSON_spec_fixed_auto ("master_pub",
+ &fk.master_pub),
+ GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
+ &fk.denom_secmod_public_key),
+ GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
+ &fk.signkey_secmod_public_key),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (response,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ fk.num_sign_keys = json_array_size (sk);
+ fk.num_denom_keys = json_array_size (dk);
+ fk.sign_keys = GNUNET_new_array (
+ fk.num_sign_keys,
+ struct TALER_EXCHANGE_FutureSigningPublicKey);
+ fk.denom_keys = GNUNET_new_array (
+ fk.num_denom_keys,
+ struct TALER_EXCHANGE_FutureDenomPublicKey);
+ ok = true;
+ for (unsigned int i = 0; i<fk.num_sign_keys; i++)
+ {
+ json_t *j = json_array_get (sk,
+ i);
+ struct TALER_EXCHANGE_FutureSigningPublicKey *sign_key
+ = &fk.sign_keys[i];
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("key",
+ &sign_key->key),
+ GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig",
+ &sign_key->signkey_secmod_sig),
+ TALER_JSON_spec_absolute_time ("stamp_start",
+ &sign_key->valid_from),
+ TALER_JSON_spec_absolute_time ("stamp_expire",
+ &sign_key->valid_until),
+ TALER_JSON_spec_absolute_time ("stamp_end",
+ &sign_key->valid_legal),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (j,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ ok = false;
+ break;
+ }
+ {
+ struct GNUNET_TIME_Relative duration
+ = GNUNET_TIME_absolute_get_difference (sign_key->valid_from,
+ sign_key->valid_until);
+ struct TALER_SigningKeyAnnouncementPS ska = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_SM_SIGNING_KEY),
+ .purpose.size = htonl (sizeof (ska)),
+ .exchange_pub = sign_key->key,
+ .anchor_time = GNUNET_TIME_absolute_hton (sign_key->valid_from),
+ .duration = GNUNET_TIME_relative_hton (duration)
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_SM_SIGNING_KEY,
+ &ska,
+ &sign_key->signkey_secmod_sig.eddsa_signature,
+ &fk.signkey_secmod_public_key.eddsa_pub))
+ {
+ GNUNET_break_op (0);
+ ok = false;
+ break;
+ }
+ }
+ }
+ for (unsigned int i = 0; i<fk.num_denom_keys; i++)
+ {
+ json_t *j = json_array_get (dk,
+ i);
+ struct TALER_EXCHANGE_FutureDenomPublicKey *denom_key
+ = &fk.denom_keys[i];
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
+ &denom_key->denom_secmod_sig),
+ TALER_JSON_spec_absolute_time ("stamp_expire_deposit",
+ &denom_key->expire_deposit),
+ TALER_JSON_spec_absolute_time ("stamp_expire_withdraw",
+ &denom_key->withdraw_valid_until),
+ TALER_JSON_spec_absolute_time ("stamp_start",
+ &denom_key->valid_from),
+ TALER_JSON_spec_absolute_time ("stamp_expire_legal",
+ &denom_key->expire_legal),
+ TALER_JSON_spec_amount ("value",
+ &denom_key->value),
+ TALER_JSON_spec_amount ("fee_withdraw",
+ &denom_key->fee_withdraw),
+ TALER_JSON_spec_amount ("fee_deposit",
+ &denom_key->fee_deposit),
+ TALER_JSON_spec_amount ("fee_refresh",
+ &denom_key->fee_refresh),
+ TALER_JSON_spec_amount ("fee_refund",
+ &denom_key->fee_refund),
+ GNUNET_JSON_spec_rsa_public_key ("denom_pub",
+ &denom_key->key.rsa_public_key),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (j,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ ok = false;
+ break;
+ }
+
+ {
+ struct GNUNET_TIME_Relative duration
+ = GNUNET_TIME_absolute_get_difference (denom_key->valid_from,
+ denom_key->withdraw_valid_until);
+ struct TALER_DenominationKeyAnnouncementPS dka = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_SM_DENOMINATION_KEY),
+ .purpose.size = htonl (sizeof (dka)),
+ .anchor_time = GNUNET_TIME_absolute_hton (denom_key->valid_from),
+ .duration_withdraw = GNUNET_TIME_relative_hton (duration)
+ };
+
+ GNUNET_CRYPTO_rsa_public_key_hash (denom_key->key.rsa_public_key,
+ &dka.h_denom_pub);
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_SM_DENOMINATION_KEY,
+ &dka,
+ &denom_key->denom_secmod_sig.eddsa_signature,
+ &fk.denom_secmod_public_key.eddsa_pub))
+ {
+ GNUNET_break_op (0);
+ ok = false;
+ break;
+ }
+ }
+ }
+ if (ok)
+ {
+ struct TALER_EXCHANGE_HttpResponse hr = {
+ .http_status = MHD_HTTP_OK,
+ .reply = response
+ };
+
+ gh->cb (gh->cb_cls,
+ &hr,
+ &fk);
+ }
+ for (unsigned int i = 0; i<fk.num_denom_keys; i++)
+ {
+ if (NULL != fk.denom_keys[i].key.rsa_public_key)
+ {
+ GNUNET_CRYPTO_rsa_public_key_free (
+ fk.denom_keys[i].key.rsa_public_key);
+ fk.denom_keys[i].key.rsa_public_key = NULL;
+ }
+ }
+ GNUNET_free (fk.sign_keys);
+ GNUNET_free (fk.denom_keys);
+ GNUNET_JSON_parse_free (spec);
+ return (ok) ? GNUNET_OK : GNUNET_SYSERR;
+}
+
+
+/**
* Function called when we're done processing the
* HTTP GET /management/keys request.
*
@@ -84,129 +279,15 @@ handle_get_keys_finished (void *cls,
switch (response_code)
{
case MHD_HTTP_OK:
+ if (GNUNET_OK ==
+ handle_ok (gh,
+ response))
{
- struct TALER_EXCHANGE_FutureKeys fk;
- json_t *sk;
- json_t *dk;
- bool ok;
-
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_json ("future_denoms",
- &dk),
- GNUNET_JSON_spec_json ("future_signkeys",
- &sk),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- response_code = 0;
- break;
- }
- fk.num_sign_keys = json_array_size (sk);
- fk.num_denom_keys = json_array_size (dk);
- fk.sign_keys = GNUNET_new_array (
- fk.num_sign_keys,
- struct TALER_EXCHANGE_FutureSigningPublicKey);
- fk.denom_keys = GNUNET_new_array (
- fk.num_denom_keys,
- struct TALER_EXCHANGE_FutureDenomPublicKey);
- ok = true;
- for (unsigned int i = 0; i<fk.num_sign_keys; i++)
- {
- json_t *j = json_array_get (sk,
- i);
- struct TALER_EXCHANGE_FutureSigningPublicKey *sign_key
- = &fk.sign_keys[i];
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("key",
- &sign_key->key),
- TALER_JSON_spec_absolute_time ("stamp_start",
- &sign_key->valid_from),
- TALER_JSON_spec_absolute_time ("stamp_expire",
- &sign_key->valid_until),
- TALER_JSON_spec_absolute_time ("stamp_end",
- &sign_key->valid_legal),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ok = false;
- break;
- }
- }
- for (unsigned int i = 0; i<fk.num_denom_keys; i++)
- {
- json_t *j = json_array_get (dk,
- i);
- struct TALER_EXCHANGE_FutureDenomPublicKey *denom_key
- = &fk.denom_keys[i];
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_absolute_time ("stamp_expire_deposit",
- &denom_key->expire_deposit),
- TALER_JSON_spec_absolute_time ("stamp_expire_withdraw",
- &denom_key->withdraw_valid_until),
- TALER_JSON_spec_absolute_time ("stamp_start",
- &denom_key->valid_from),
- TALER_JSON_spec_absolute_time ("stamp_expire_legal",
- &denom_key->expire_legal),
- TALER_JSON_spec_amount ("value",
- &denom_key->value),
- TALER_JSON_spec_amount ("fee_withdraw",
- &denom_key->fee_withdraw),
- TALER_JSON_spec_amount ("fee_deposit",
- &denom_key->fee_deposit),
- TALER_JSON_spec_amount ("fee_refresh",
- &denom_key->fee_refresh),
- TALER_JSON_spec_amount ("fee_refund",
- &denom_key->fee_refund),
- GNUNET_JSON_spec_rsa_public_key ("denom_pub",
- &denom_key->key.rsa_public_key),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ok = false;
- break;
- }
- }
- if (ok)
- {
- gh->cb (gh->cb_cls,
- &hr,
- &fk);
- gh->cb = NULL;
- }
- for (unsigned int i = 0; i<fk.num_denom_keys; i++)
- {
- if (NULL != fk.denom_keys[i].key.rsa_public_key)
- {
- GNUNET_CRYPTO_rsa_public_key_free (
- fk.denom_keys[i].key.rsa_public_key);
- fk.denom_keys[i].key.rsa_public_key = NULL;
- }
- }
- GNUNET_free (fk.sign_keys);
- GNUNET_free (fk.denom_keys);
- if (! ok)
- {
- response_code = 0;
- break;
- }
+ gh->cb = NULL;
+ }
+ else
+ {
+ response_code = 0;
}
break;
default: