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;
|
struct TALER_ExchangePublicKeyP key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature by the security module affirming it owns this key.
|
||||||
|
*/
|
||||||
|
struct TALER_SecurityModuleSignatureP signkey_secmod_sig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validity start time
|
* Validity start time
|
||||||
*/
|
*/
|
||||||
@ -1957,6 +1962,11 @@ struct TALER_EXCHANGE_FutureDenomPublicKey
|
|||||||
*/
|
*/
|
||||||
struct TALER_DenominationPublicKey key;
|
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
|
* Timestamp indicating when the denomination key becomes valid
|
||||||
*/
|
*/
|
||||||
@ -2026,6 +2036,21 @@ struct TALER_EXCHANGE_FutureKeys
|
|||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGE_FutureDenomPublicKey *denom_keys;
|
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).
|
* 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
|
* Function called when we're done processing the
|
||||||
* HTTP GET /management/keys request.
|
* HTTP GET /management/keys request.
|
||||||
@ -84,129 +279,15 @@ handle_get_keys_finished (void *cls,
|
|||||||
switch (response_code)
|
switch (response_code)
|
||||||
{
|
{
|
||||||
case MHD_HTTP_OK:
|
case MHD_HTTP_OK:
|
||||||
|
if (GNUNET_OK ==
|
||||||
|
handle_ok (gh,
|
||||||
|
response))
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGE_FutureKeys fk;
|
gh->cb = NULL;
|
||||||
json_t *sk;
|
}
|
||||||
json_t *dk;
|
else
|
||||||
bool ok;
|
{
|
||||||
|
response_code = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user