add logic to parse and check secmod signatures
This commit is contained in:
parent
440d0e6ea4
commit
2c88cff283
@ -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).
|
||||
*/
|
||||
|
@ -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; 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:
|
||||
|
Loading…
Reference in New Issue
Block a user