implementing retrieval of auditor information from /keys in mint API (with updated specification) - #3847
This commit is contained in:
parent
fb14af5ba8
commit
7fbae8f69f
@ -149,6 +149,11 @@ struct TALER_MINT_DenomPublicKey
|
||||
*/
|
||||
struct TALER_DenominationPublicKey key;
|
||||
|
||||
/**
|
||||
* The hash of the public key.
|
||||
*/
|
||||
struct GNUNET_HashCode h_key;
|
||||
|
||||
/**
|
||||
* Timestamp indicating when the denomination key becomes valid
|
||||
*/
|
||||
@ -165,6 +170,15 @@ struct TALER_MINT_DenomPublicKey
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute deposit_valid_until;
|
||||
|
||||
/**
|
||||
* When do signatures with this denomination key become invalid?
|
||||
* After this point, these signatures cannot be used in (legal)
|
||||
* disputes anymore, as the Mint is then allowed to destroy its side
|
||||
* of the evidence. @e expire_legal is expected to be significantly
|
||||
* larger than @e expire_spend (by a year or more).
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute expire_legal;
|
||||
|
||||
/**
|
||||
* The value of this denomination
|
||||
*/
|
||||
@ -204,6 +218,8 @@ struct TALER_MINT_AuditorInformation
|
||||
* that website. We expect that in practice software is going to
|
||||
* often ship with an initial list of accepted auditors, just like
|
||||
* browsers ship with a CA root store.
|
||||
*
|
||||
* This field may be NULL. (#3987).
|
||||
*/
|
||||
const char *auditor_url;
|
||||
|
||||
@ -218,7 +234,7 @@ struct TALER_MINT_AuditorInformation
|
||||
* elements point to the same locations as the entries
|
||||
* in the key's main `denom_keys` array.
|
||||
*/
|
||||
struct TALER_MINT_DenomPublicKey *const*denom_keys;
|
||||
const struct TALER_MINT_DenomPublicKey **denom_keys;
|
||||
};
|
||||
|
||||
|
||||
@ -246,7 +262,7 @@ struct TALER_MINT_Keys
|
||||
/**
|
||||
* Array of the keys of the auditors of the mint.
|
||||
*/
|
||||
struct TALER_AuditorPublicKeyP *auditors;
|
||||
struct TALER_MINT_AuditorInformation *auditors;
|
||||
|
||||
/**
|
||||
* Length of the @e sign_keys array.
|
||||
@ -353,6 +369,18 @@ TALER_MINT_get_denomination_key (const struct TALER_MINT_Keys *keys,
|
||||
const struct TALER_DenominationPublicKey *pk);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the denomination key details from the mint.
|
||||
*
|
||||
* @param keys the mint's key set
|
||||
* @param hc hash of the public key of the denomination to lookup
|
||||
* @return details about the given denomination key
|
||||
*/
|
||||
const struct TALER_MINT_DenomPublicKey *
|
||||
TALER_MINT_get_denomination_key_by_hash (const struct TALER_MINT_Keys *keys,
|
||||
const struct GNUNET_HashCode *hc);
|
||||
|
||||
|
||||
/* ********************* /wire *********************** */
|
||||
|
||||
|
||||
|
@ -653,13 +653,73 @@ struct TALER_MintKeyValidityPS
|
||||
struct TALER_MasterPublicKeyP master;
|
||||
|
||||
/**
|
||||
* Array of hash(es) of the mint's denomination keys.
|
||||
* Specifically, this is the hash over the
|
||||
* `struct TALER_DenominationKeyValidityPS`, not just
|
||||
* the public key (as the auditor needs to check against
|
||||
* the correct valuations and fee structure).
|
||||
* Start time of the validity period for this key.
|
||||
*/
|
||||
/* struct GNUNET_HashCode h_dks; */
|
||||
struct GNUNET_TIME_AbsoluteNBO start;
|
||||
|
||||
/**
|
||||
* The mint will sign fresh coins between @e start and this time.
|
||||
* @e expire_withdraw will be somewhat larger than @e start to
|
||||
* ensure a sufficiently large anonymity set, while also allowing
|
||||
* the Mint to limit the financial damage in case of a key being
|
||||
* compromised. Thus, mints with low volume are expected to have a
|
||||
* longer withdraw period (@e expire_withdraw - @e start) than mints
|
||||
* with high transaction volume. The period may also differ between
|
||||
* types of coins. A mint may also have a few denomination keys
|
||||
* with the same value with overlapping validity periods, to address
|
||||
* issues such as clock skew.
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
|
||||
|
||||
/**
|
||||
* Coins signed with the denomination key must be spent or refreshed
|
||||
* between @e start and this expiration time. After this time, the
|
||||
* mint will refuse transactions involving this key as it will
|
||||
* "drop" the table with double-spending information (shortly after)
|
||||
* this time. Note that wallets should refresh coins significantly
|
||||
* before this time to be on the safe side. @e expire_spend must be
|
||||
* significantly larger than @e expire_withdraw (by months or even
|
||||
* years).
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_spend;
|
||||
|
||||
/**
|
||||
* When do signatures with this denomination key become invalid?
|
||||
* After this point, these signatures cannot be used in (legal)
|
||||
* disputes anymore, as the Mint is then allowed to destroy its side
|
||||
* of the evidence. @e expire_legal is expected to be significantly
|
||||
* larger than @e expire_spend (by a year or more).
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_legal;
|
||||
|
||||
/**
|
||||
* The value of the coins signed with this denomination key.
|
||||
*/
|
||||
struct TALER_AmountNBO value;
|
||||
|
||||
/**
|
||||
* The fee the mint charges when a coin of this type is withdrawn.
|
||||
* (can be zero).
|
||||
*/
|
||||
struct TALER_AmountNBO fee_withdraw;
|
||||
|
||||
/**
|
||||
* The fee the mint charges when a coin of this type is deposited.
|
||||
* (can be zero).
|
||||
*/
|
||||
struct TALER_AmountNBO fee_deposit;
|
||||
|
||||
/**
|
||||
* The fee the mint charges when a coin of this type is refreshed.
|
||||
* (can be zero).
|
||||
*/
|
||||
struct TALER_AmountNBO fee_refresh;
|
||||
|
||||
/**
|
||||
* Hash code of the denomination public key. (Used to avoid having
|
||||
* the variable-size RSA key in this struct.)
|
||||
*/
|
||||
struct GNUNET_HashCode denom_hash GNUNET_PACKED;
|
||||
|
||||
};
|
||||
|
||||
|
@ -325,9 +325,11 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
|
||||
&denom_key_issue.denom_hash,
|
||||
sizeof (struct GNUNET_HashCode));
|
||||
denom_key->key.rsa_public_key = pk;
|
||||
denom_key->h_key = denom_key_issue.denom_hash;
|
||||
denom_key->valid_from = valid_from;
|
||||
denom_key->withdraw_valid_until = withdraw_valid_until;
|
||||
denom_key->deposit_valid_until = deposit_valid_until;
|
||||
denom_key->expire_legal = expire_legal;
|
||||
denom_key->value = value;
|
||||
denom_key->fee_withdraw = fee_withdraw;
|
||||
denom_key->fee_deposit = fee_deposit;
|
||||
@ -340,6 +342,116 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a mint's auditor information encoded in JSON.
|
||||
*
|
||||
* @param[out] auditor where to return the result
|
||||
* @param[in] auditor_obj json to parse
|
||||
* @param key_data information about denomination keys
|
||||
* @return #GNUNET_OK if all is fine, #GNUNET_SYSERR if the signature is
|
||||
* invalid or the json malformed.
|
||||
*/
|
||||
static int
|
||||
parse_json_auditor (struct TALER_MINT_AuditorInformation *auditor,
|
||||
json_t *auditor_obj,
|
||||
const struct TALER_MINT_Keys *key_data)
|
||||
{
|
||||
json_t *keys;
|
||||
json_t *key;
|
||||
unsigned int len;
|
||||
unsigned int off;
|
||||
unsigned int i;
|
||||
struct TALER_MintKeyValidityPS kv;
|
||||
struct MAJ_Specification spec[] = {
|
||||
MAJ_spec_fixed_auto ("auditor_pub",
|
||||
&auditor->auditor_pub),
|
||||
MAJ_spec_json ("denomination_keys",
|
||||
&keys),
|
||||
MAJ_spec_end
|
||||
};
|
||||
|
||||
auditor->auditor_url = NULL; /* #3987 */
|
||||
if (GNUNET_OK !=
|
||||
MAJ_parse_json (auditor_obj,
|
||||
spec))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_MINT_KEYS);
|
||||
kv.purpose.size = htonl (sizeof (struct TALER_MintKeyValidityPS));
|
||||
kv.master = key_data->master_pub;
|
||||
len = json_array_size (keys);
|
||||
auditor->denom_keys = GNUNET_new_array (len,
|
||||
const struct TALER_MINT_DenomPublicKey *);
|
||||
i = 0;
|
||||
off = 0;
|
||||
json_array_foreach (keys, i, key) {
|
||||
struct TALER_AuditorSignatureP auditor_sig;
|
||||
struct GNUNET_HashCode denom_h;
|
||||
const struct TALER_MINT_DenomPublicKey *dk;
|
||||
unsigned int j;
|
||||
struct MAJ_Specification spec[] = {
|
||||
MAJ_spec_fixed_auto ("denom_pub_h",
|
||||
&denom_h),
|
||||
MAJ_spec_fixed_auto ("auditor_sig",
|
||||
&auditor_sig),
|
||||
MAJ_spec_end
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
MAJ_parse_json (key,
|
||||
spec))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
continue;
|
||||
}
|
||||
dk = NULL;
|
||||
for (j=0;j<key_data->num_denom_keys;j++)
|
||||
{
|
||||
if (0 == memcmp (&denom_h,
|
||||
&key_data->denom_keys[j].h_key,
|
||||
sizeof (struct GNUNET_HashCode)))
|
||||
{
|
||||
dk = &key_data->denom_keys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL == dk)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
continue;
|
||||
}
|
||||
kv.start = GNUNET_TIME_absolute_hton (dk->valid_from);
|
||||
kv.expire_withdraw = GNUNET_TIME_absolute_hton (dk->withdraw_valid_until);
|
||||
kv.expire_spend = GNUNET_TIME_absolute_hton (dk->deposit_valid_until);
|
||||
kv.expire_legal = GNUNET_TIME_absolute_hton (dk->expire_legal);
|
||||
TALER_amount_hton (&kv.value,
|
||||
&dk->value);
|
||||
TALER_amount_hton (&kv.fee_withdraw,
|
||||
&dk->fee_withdraw);
|
||||
TALER_amount_hton (&kv.fee_deposit,
|
||||
&dk->fee_deposit);
|
||||
TALER_amount_hton (&kv.fee_refresh,
|
||||
&dk->fee_refresh);
|
||||
kv.denom_hash = dk->h_key;
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_AUDITOR_MINT_KEYS,
|
||||
&kv.purpose,
|
||||
&auditor_sig.eddsa_sig,
|
||||
&auditor->auditor_pub.eddsa_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
continue;
|
||||
}
|
||||
auditor->denom_keys[off] = dk;
|
||||
off++;
|
||||
}
|
||||
auditor->num_denom_keys = off;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode the JSON in @a resp_obj from the /keys response and store the data
|
||||
* in the @a key_data.
|
||||
@ -394,8 +506,8 @@ decode_keys_json (json_t *resp_obj,
|
||||
EXITIF (0 == (key_data->num_sign_keys =
|
||||
json_array_size (sign_keys_array)));
|
||||
key_data->sign_keys
|
||||
= GNUNET_malloc (sizeof (struct TALER_MINT_SigningPublicKey)
|
||||
* key_data->num_sign_keys);
|
||||
= GNUNET_new_array (key_data->num_sign_keys,
|
||||
struct TALER_MINT_SigningPublicKey);
|
||||
index = 0;
|
||||
json_array_foreach (sign_keys_array, index, sign_key_obj) {
|
||||
EXITIF (GNUNET_SYSERR ==
|
||||
@ -415,8 +527,8 @@ decode_keys_json (json_t *resp_obj,
|
||||
json_object_get (resp_obj, "denoms")));
|
||||
EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
|
||||
EXITIF (0 == (key_data->num_denom_keys = json_array_size (denom_keys_array)));
|
||||
key_data->denom_keys = GNUNET_malloc (sizeof (struct TALER_MINT_DenomPublicKey)
|
||||
* key_data->num_denom_keys);
|
||||
key_data->denom_keys = GNUNET_new_array (key_data->num_denom_keys,
|
||||
struct TALER_MINT_DenomPublicKey);
|
||||
index = 0;
|
||||
json_array_foreach (denom_keys_array, index, denom_key_obj) {
|
||||
EXITIF (GNUNET_SYSERR ==
|
||||
@ -427,7 +539,30 @@ decode_keys_json (json_t *resp_obj,
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: parse the auditor keys (#3847) */
|
||||
/* parse the auditor information */
|
||||
{
|
||||
json_t *auditors_array;
|
||||
json_t *auditor_info;
|
||||
unsigned int len;
|
||||
unsigned int index;
|
||||
|
||||
EXITIF (NULL == (auditors_array =
|
||||
json_object_get (resp_obj, "auditors")));
|
||||
EXITIF (JSON_ARRAY != json_typeof (auditors_array));
|
||||
len = json_array_size (auditors_array);
|
||||
if (0 != len)
|
||||
{
|
||||
key_data->auditors = GNUNET_new_array (len,
|
||||
struct TALER_MINT_AuditorInformation);
|
||||
index = 0;
|
||||
json_array_foreach (auditors_array, index, auditor_info) {
|
||||
EXITIF (GNUNET_SYSERR ==
|
||||
parse_json_auditor (&key_data->auditors[index],
|
||||
auditor_info,
|
||||
key_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate signature... */
|
||||
ks.purpose.size = htonl (sizeof (ks));
|
||||
@ -708,6 +843,28 @@ TALER_MINT_get_denomination_key (const struct TALER_MINT_Keys *keys,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the denomination key details from the mint.
|
||||
*
|
||||
* @param keys the mint's key set
|
||||
* @param hc hash of the public key of the denomination to lookup
|
||||
* @return details about the given denomination key
|
||||
*/
|
||||
const struct TALER_MINT_DenomPublicKey *
|
||||
TALER_MINT_get_denomination_key_by_hash (const struct TALER_MINT_Keys *keys,
|
||||
const struct GNUNET_HashCode *hc)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i=0;i<keys->num_denom_keys;i++)
|
||||
if (0 == memcmp (hc,
|
||||
&keys->denom_keys[i].h_key,
|
||||
sizeof (struct GNUNET_HashCode)))
|
||||
return &keys->denom_keys[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the keys from the mint.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user