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 @@ -1930,6 +1930,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 */ @@ -1957,6 +1962,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 */ @@ -2026,6 +2036,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). */ 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 @@ -60,6 +60,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; ikey), + 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; idenom_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; ikey), - 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; iexpire_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; icb = NULL; + } + else + { + response_code = 0; } break; default: