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;
|
struct TALER_DenominationPublicKey key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hash of the public key.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode h_key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timestamp indicating when the denomination key becomes valid
|
* Timestamp indicating when the denomination key becomes valid
|
||||||
*/
|
*/
|
||||||
@ -165,6 +170,15 @@ struct TALER_MINT_DenomPublicKey
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_TIME_Absolute deposit_valid_until;
|
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
|
* The value of this denomination
|
||||||
*/
|
*/
|
||||||
@ -204,6 +218,8 @@ struct TALER_MINT_AuditorInformation
|
|||||||
* that website. We expect that in practice software is going to
|
* that website. We expect that in practice software is going to
|
||||||
* often ship with an initial list of accepted auditors, just like
|
* often ship with an initial list of accepted auditors, just like
|
||||||
* browsers ship with a CA root store.
|
* browsers ship with a CA root store.
|
||||||
|
*
|
||||||
|
* This field may be NULL. (#3987).
|
||||||
*/
|
*/
|
||||||
const char *auditor_url;
|
const char *auditor_url;
|
||||||
|
|
||||||
@ -218,7 +234,7 @@ struct TALER_MINT_AuditorInformation
|
|||||||
* elements point to the same locations as the entries
|
* elements point to the same locations as the entries
|
||||||
* in the key's main `denom_keys` array.
|
* 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.
|
* 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.
|
* 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);
|
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 *********************** */
|
/* ********************* /wire *********************** */
|
||||||
|
|
||||||
|
|
||||||
|
@ -653,13 +653,73 @@ struct TALER_MintKeyValidityPS
|
|||||||
struct TALER_MasterPublicKeyP master;
|
struct TALER_MasterPublicKeyP master;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of hash(es) of the mint's denomination keys.
|
* Start time of the validity period for this key.
|
||||||
* 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).
|
|
||||||
*/
|
*/
|
||||||
/* 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,
|
&denom_key_issue.denom_hash,
|
||||||
sizeof (struct GNUNET_HashCode));
|
sizeof (struct GNUNET_HashCode));
|
||||||
denom_key->key.rsa_public_key = pk;
|
denom_key->key.rsa_public_key = pk;
|
||||||
|
denom_key->h_key = denom_key_issue.denom_hash;
|
||||||
denom_key->valid_from = valid_from;
|
denom_key->valid_from = valid_from;
|
||||||
denom_key->withdraw_valid_until = withdraw_valid_until;
|
denom_key->withdraw_valid_until = withdraw_valid_until;
|
||||||
denom_key->deposit_valid_until = deposit_valid_until;
|
denom_key->deposit_valid_until = deposit_valid_until;
|
||||||
|
denom_key->expire_legal = expire_legal;
|
||||||
denom_key->value = value;
|
denom_key->value = value;
|
||||||
denom_key->fee_withdraw = fee_withdraw;
|
denom_key->fee_withdraw = fee_withdraw;
|
||||||
denom_key->fee_deposit = fee_deposit;
|
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
|
* Decode the JSON in @a resp_obj from the /keys response and store the data
|
||||||
* in the @a key_data.
|
* in the @a key_data.
|
||||||
@ -394,8 +506,8 @@ decode_keys_json (json_t *resp_obj,
|
|||||||
EXITIF (0 == (key_data->num_sign_keys =
|
EXITIF (0 == (key_data->num_sign_keys =
|
||||||
json_array_size (sign_keys_array)));
|
json_array_size (sign_keys_array)));
|
||||||
key_data->sign_keys
|
key_data->sign_keys
|
||||||
= GNUNET_malloc (sizeof (struct TALER_MINT_SigningPublicKey)
|
= GNUNET_new_array (key_data->num_sign_keys,
|
||||||
* key_data->num_sign_keys);
|
struct TALER_MINT_SigningPublicKey);
|
||||||
index = 0;
|
index = 0;
|
||||||
json_array_foreach (sign_keys_array, index, sign_key_obj) {
|
json_array_foreach (sign_keys_array, index, sign_key_obj) {
|
||||||
EXITIF (GNUNET_SYSERR ==
|
EXITIF (GNUNET_SYSERR ==
|
||||||
@ -415,8 +527,8 @@ decode_keys_json (json_t *resp_obj,
|
|||||||
json_object_get (resp_obj, "denoms")));
|
json_object_get (resp_obj, "denoms")));
|
||||||
EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
|
EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
|
||||||
EXITIF (0 == (key_data->num_denom_keys = json_array_size (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->denom_keys = GNUNET_new_array (key_data->num_denom_keys,
|
||||||
* key_data->num_denom_keys);
|
struct TALER_MINT_DenomPublicKey);
|
||||||
index = 0;
|
index = 0;
|
||||||
json_array_foreach (denom_keys_array, index, denom_key_obj) {
|
json_array_foreach (denom_keys_array, index, denom_key_obj) {
|
||||||
EXITIF (GNUNET_SYSERR ==
|
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... */
|
/* Validate signature... */
|
||||||
ks.purpose.size = htonl (sizeof (ks));
|
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.
|
* Obtain the keys from the mint.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user