keep a most sigs around when serializing

This commit is contained in:
Christian Grothoff 2018-10-13 19:45:50 +02:00
parent 504017bc65
commit 16b0c65470
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 86 additions and 78 deletions

View File

@ -224,11 +224,9 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
const struct TALER_MasterPublicKeyP *master_key) const struct TALER_MasterPublicKeyP *master_key)
{ {
struct TALER_ExchangeSigningKeyValidityPS sign_key_issue; struct TALER_ExchangeSigningKeyValidityPS sign_key_issue;
struct GNUNET_CRYPTO_EddsaSignature sig;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
/* must be first, we skip this one if "check_sigs" is 0! */
GNUNET_JSON_spec_fixed_auto ("master_sig", GNUNET_JSON_spec_fixed_auto ("master_sig",
&sig), &sign_key->master_sig),
GNUNET_JSON_spec_fixed_auto ("key", GNUNET_JSON_spec_fixed_auto ("key",
&sign_key->key), &sign_key->key),
GNUNET_JSON_spec_absolute_time ("stamp_start", GNUNET_JSON_spec_absolute_time ("stamp_start",
@ -242,7 +240,7 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_JSON_parse (sign_key_obj, GNUNET_JSON_parse (sign_key_obj,
check_sigs ? spec : &spec[1], spec,
NULL, NULL)) NULL, NULL))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -264,7 +262,7 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
&sign_key_issue.purpose, &sign_key_issue.purpose,
&sig, &sign_key->master_sig.eddsa_signature,
&master_key->eddsa_pub)) &master_key->eddsa_pub))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -293,12 +291,9 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
struct GNUNET_HashContext *hash_context) struct GNUNET_HashContext *hash_context)
{ {
struct TALER_DenominationKeyValidityPS denom_key_issue; struct TALER_DenominationKeyValidityPS denom_key_issue;
struct GNUNET_CRYPTO_EddsaSignature sig;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("master_sig", GNUNET_JSON_spec_fixed_auto ("master_sig",
&sig), &denom_key->master_sig),
/* master_sig must be first as when 'check_sigs' is set, we
start at &spec[1]! */
GNUNET_JSON_spec_absolute_time ("stamp_expire_deposit", GNUNET_JSON_spec_absolute_time ("stamp_expire_deposit",
&denom_key->expire_deposit), &denom_key->expire_deposit),
GNUNET_JSON_spec_absolute_time ("stamp_expire_withdraw", GNUNET_JSON_spec_absolute_time ("stamp_expire_withdraw",
@ -324,7 +319,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_JSON_parse (denom_key_obj, GNUNET_JSON_parse (denom_key_obj,
(check_sigs) ? spec : &spec[1], spec,
NULL, NULL)) NULL, NULL))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -361,7 +356,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
EXITIF (GNUNET_SYSERR == EXITIF (GNUNET_SYSERR ==
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
&denom_key_issue.purpose, &denom_key_issue.purpose,
&sig, &denom_key->master_sig.eddsa_signature,
&master_key->eddsa_pub)); &master_key->eddsa_pub));
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
&denom_key_issue.denom_hash, &denom_key_issue.denom_hash,
@ -423,8 +418,8 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
&kv.auditor_url_hash); &kv.auditor_url_hash);
kv.master = key_data->master_pub; kv.master = key_data->master_pub;
len = json_array_size (keys); len = json_array_size (keys);
auditor->denom_key_offsets = GNUNET_new_array (len, auditor->denom_keys = GNUNET_new_array (len,
unsigned int); struct TALER_EXCHANGE_AuditorDenominationInfo);
i = 0; i = 0;
off = 0; off = 0;
json_array_foreach (keys, i, key) { json_array_foreach (keys, i, key) {
@ -435,8 +430,6 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
struct GNUNET_JSON_Specification kspec[] = { struct GNUNET_JSON_Specification kspec[] = {
GNUNET_JSON_spec_fixed_auto ("auditor_sig", GNUNET_JSON_spec_fixed_auto ("auditor_sig",
&auditor_sig), &auditor_sig),
/* auditor_sig must be first, as we skip it if
'check_sigs' is false */
GNUNET_JSON_spec_fixed_auto ("denom_pub_h", GNUNET_JSON_spec_fixed_auto ("denom_pub_h",
&denom_h), &denom_h),
GNUNET_JSON_spec_end() GNUNET_JSON_spec_end()
@ -444,7 +437,7 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_JSON_parse (key, GNUNET_JSON_parse (key,
(check_sigs) ? kspec : &kspec[1], kspec,
NULL, NULL)) NULL, NULL))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -497,7 +490,8 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
} }
auditor->denom_key_offsets[off] = dk_off; auditor->denom_keys[off].denom_key_offset = dk_off;
auditor->denom_keys[off].auditor_sig = auditor_sig;
off++; off++;
} }
auditor->num_denom_keys = off; auditor->num_denom_keys = off;
@ -522,18 +516,26 @@ decode_keys_json (const json_t *resp_obj,
struct TALER_EXCHANGE_Keys *key_data, struct TALER_EXCHANGE_Keys *key_data,
enum TALER_EXCHANGE_VersionCompatibility *vc) enum TALER_EXCHANGE_VersionCompatibility *vc)
{ {
struct GNUNET_TIME_Absolute list_issue_date;
struct GNUNET_TIME_Absolute last_denom_issue_date; struct GNUNET_TIME_Absolute last_denom_issue_date;
struct TALER_ExchangeSignatureP sig; struct TALER_ExchangeSignatureP sig;
struct TALER_ExchangeKeySetPS ks;
struct GNUNET_HashContext *hash_context; struct GNUNET_HashContext *hash_context;
struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangePublicKeyP pub;
unsigned int age; unsigned int age;
unsigned int revision; unsigned int revision;
unsigned int current; unsigned int current;
struct GNUNET_JSON_Specification mspec[] = { struct GNUNET_JSON_Specification mspec[] = {
GNUNET_JSON_spec_fixed_auto ("eddsa_sig",
&sig),
GNUNET_JSON_spec_fixed_auto ("eddsa_pub",
&pub),
/* sig and pub must be first, as we skip those if
check_sig is false! */
GNUNET_JSON_spec_fixed_auto ("master_public_key", GNUNET_JSON_spec_fixed_auto ("master_public_key",
&key_data->master_pub), &key_data->master_pub),
GNUNET_JSON_spec_absolute_time ("list_issue_date",
&key_data->list_issue_date),
GNUNET_JSON_spec_relative_time ("reserve_closing_delay",
&key_data->reserve_closing_delay),
GNUNET_JSON_spec_end() GNUNET_JSON_spec_end()
}; };
@ -586,7 +588,7 @@ decode_keys_json (const json_t *resp_obj,
EXITIF (GNUNET_OK != EXITIF (GNUNET_OK !=
GNUNET_JSON_parse (resp_obj, GNUNET_JSON_parse (resp_obj,
mspec, (check_sig) ? mspec : &mspec[2],
NULL, NULL)); NULL, NULL));
/* parse the master public key and issue date of the response */ /* parse the master public key and issue date of the response */
@ -710,12 +712,12 @@ decode_keys_json (const json_t *resp_obj,
found = true; found = true;
/* Merge denomination key signatures of downloaded /keys into existing /* Merge denomination key signatures of downloaded /keys into existing
auditor information 'aix'. */ auditor information 'aix'. */
GNUNET_array_grow (aix->denom_key_offsets, GNUNET_array_grow (aix->denom_keys,
aix->num_denom_keys, aix->num_denom_keys,
aix->num_denom_keys + ai.num_denom_keys); aix->num_denom_keys + ai.num_denom_keys);
memcpy (&aix->denom_key_offsets[aix->num_denom_keys - ai.num_denom_keys], memcpy (&aix->denom_keys[aix->num_denom_keys - ai.num_denom_keys],
ai.denom_key_offsets, ai.denom_keys,
ai.num_denom_keys * sizeof (unsigned int)); ai.num_denom_keys * sizeof (struct TALER_EXCHANGE_AuditorDenominationInfo));
break; break;
} }
} }
@ -731,26 +733,12 @@ decode_keys_json (const json_t *resp_obj,
if (check_sig) if (check_sig)
{ {
struct GNUNET_JSON_Specification spec[] = { struct TALER_ExchangeKeySetPS ks;
GNUNET_JSON_spec_fixed_auto ("eddsa_sig",
&sig),
GNUNET_JSON_spec_fixed_auto ("eddsa_pub",
&pub),
GNUNET_JSON_spec_absolute_time ("list_issue_date",
&list_issue_date),
GNUNET_JSON_spec_relative_time ("reserve_closing_delay",
&key_data->reserve_closing_delay),
GNUNET_JSON_spec_end()
};
EXITIF (GNUNET_OK !=
GNUNET_JSON_parse (resp_obj,
spec,
NULL, NULL));
/* Validate signature... */ /* Validate signature... */
ks.purpose.size = htonl (sizeof (ks)); ks.purpose.size = htonl (sizeof (ks));
ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET); ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET);
ks.list_issue_date = GNUNET_TIME_absolute_hton (list_issue_date); ks.list_issue_date = GNUNET_TIME_absolute_hton (key_data->list_issue_date);
GNUNET_CRYPTO_hash_context_finish (hash_context, GNUNET_CRYPTO_hash_context_finish (hash_context,
&ks.hc); &ks.hc);
hash_context = NULL; hash_context = NULL;
@ -763,24 +751,6 @@ decode_keys_json (const json_t *resp_obj,
&sig.eddsa_signature, &sig.eddsa_signature,
&pub.eddsa_pub)); &pub.eddsa_pub));
} }
else
{
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("master_public_key",
&key_data->master_pub),
GNUNET_JSON_spec_absolute_time ("list_issue_date",
&list_issue_date),
GNUNET_JSON_spec_relative_time ("reserve_closing_delay",
&key_data->reserve_closing_delay),
GNUNET_JSON_spec_end()
};
EXITIF (GNUNET_OK !=
GNUNET_JSON_parse (resp_obj,
spec,
NULL, NULL));
}
key_data->list_issue_date = list_issue_date;
return GNUNET_OK; return GNUNET_OK;
EXITIF_exit: EXITIF_exit:
@ -808,7 +778,7 @@ free_key_data (struct TALER_EXCHANGE_Keys *key_data)
0); 0);
for (unsigned int i=0;i<key_data->num_auditors;i++) for (unsigned int i=0;i<key_data->num_auditors;i++)
{ {
GNUNET_array_grow (key_data->auditors[i].denom_key_offsets, GNUNET_array_grow (key_data->auditors[i].denom_keys,
key_data->auditors[i].num_denom_keys, key_data->auditors[i].num_denom_keys,
0); 0);
GNUNET_free (key_data->auditors[i].auditor_url); GNUNET_free (key_data->auditors[i].auditor_url);
@ -924,12 +894,12 @@ keys_completed_cb (void *cls,
anew->auditor_pub = aold->auditor_pub; anew->auditor_pub = aold->auditor_pub;
anew->auditor_url = GNUNET_strdup (aold->auditor_url); anew->auditor_url = GNUNET_strdup (aold->auditor_url);
GNUNET_array_grow (anew->denom_key_offsets, GNUNET_array_grow (anew->denom_keys,
anew->num_denom_keys, anew->num_denom_keys,
aold->num_denom_keys); aold->num_denom_keys);
memcpy (anew->denom_key_offsets, memcpy (anew->denom_keys,
aold->denom_key_offsets, aold->denom_keys,
aold->num_denom_keys * sizeof (unsigned int)); aold->num_denom_keys * sizeof (struct TALER_EXCHANGE_AuditorDenominationInfo));
} }
if (GNUNET_OK != if (GNUNET_OK !=
@ -943,7 +913,7 @@ keys_completed_cb (void *cls,
{ {
struct TALER_EXCHANGE_AuditorInformation *anew = &kd.auditors[i]; struct TALER_EXCHANGE_AuditorInformation *anew = &kd.auditors[i];
GNUNET_array_grow (anew->denom_key_offsets, GNUNET_array_grow (anew->denom_keys,
anew->num_denom_keys, anew->num_denom_keys,
0); 0);
GNUNET_free (anew->auditor_url); GNUNET_free (anew->auditor_url);
@ -1259,9 +1229,11 @@ TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange)
if (now.abs_value_us > sk->valid_until.abs_value_us) if (now.abs_value_us > sk->valid_until.abs_value_us)
continue; /* skip keys that have expired */ continue; /* skip keys that have expired */
signkey = json_pack ("{s:o, s:o, s:o, s:o}", signkey = json_pack ("{s:o, s:o, s:o, s:o, s:o}",
"key", "key",
GNUNET_JSON_from_data_auto (&sk->key), GNUNET_JSON_from_data_auto (&sk->key),
"master_sig",
GNUNET_JSON_from_data_auto (&sk->master_sig),
"stamp_start", "stamp_start",
GNUNET_JSON_from_time_abs (sk->valid_from), GNUNET_JSON_from_time_abs (sk->valid_from),
"stamp_expire", "stamp_expire",
@ -1285,7 +1257,8 @@ TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange)
if (now.abs_value_us > dk->expire_deposit.abs_value_us) if (now.abs_value_us > dk->expire_deposit.abs_value_us)
continue; /* skip keys that have expired */ continue; /* skip keys that have expired */
denom = json_pack ("{s:o, s:o, s:o, s:o, s:o " denom = json_pack ("{s:o, s:o, s:o, s:o, s:o "
",s:o, s:o, s:o, s:o, s:o}", ",s:o, s:o, s:o, s:o, s:o "
,"s:o}",
"stamp_expire_deposit", "stamp_expire_deposit",
GNUNET_JSON_from_time_abs (dk->expire_deposit), GNUNET_JSON_from_time_abs (dk->expire_deposit),
"stamp_expire_withdraw", "stamp_expire_withdraw",
@ -1305,6 +1278,9 @@ TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange)
TALER_JSON_from_amount (&dk->fee_refresh), TALER_JSON_from_amount (&dk->fee_refresh),
"fee_refund", "fee_refund",
TALER_JSON_from_amount (&dk->fee_refund), TALER_JSON_from_amount (&dk->fee_refund),
"master_sig",
GNUNET_JSON_from_data_auto (&dk->master_sig),
/* #10 */
"denom_pub", "denom_pub",
GNUNET_JSON_from_rsa_public_key (dk->key.rsa_public_key)); GNUNET_JSON_from_rsa_public_key (dk->key.rsa_public_key));
if (NULL == denom) if (NULL == denom)
@ -1325,14 +1301,16 @@ TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange)
adenoms = json_array (); adenoms = json_array ();
for (unsigned int j=0;j<ai->num_denom_keys;j++) for (unsigned int j=0;j<ai->num_denom_keys;j++)
{ {
unsigned int off = ai->denom_key_offsets[j]; const struct TALER_EXCHANGE_AuditorDenominationInfo *adi = &ai->denom_keys[j];
const struct TALER_EXCHANGE_DenomPublicKey *dk = &kd->denom_keys[off]; const struct TALER_EXCHANGE_DenomPublicKey *dk = &kd->denom_keys[adi->denom_key_offset];
json_t *k; json_t *k;
GNUNET_assert (off < kd->num_denom_keys); GNUNET_assert (adi->denom_key_offset < kd->num_denom_keys);
k = json_pack ("{s:s}", k = json_pack ("{s:o, s:o}",
"denom_pub_h", "denom_pub_h",
GNUNET_JSON_from_data_auto (&dk->h_key)); GNUNET_JSON_from_data_auto (&dk->h_key),
"auditor_sig",
GNUNET_JSON_from_data_auto (&adi->auditor_sig));
if (NULL == k) if (NULL == k)
{ {
GNUNET_break (0); GNUNET_break (0);

View File

@ -62,6 +62,11 @@ struct TALER_EXCHANGE_SigningPublicKey
*/ */
struct TALER_ExchangePublicKeyP key; struct TALER_ExchangePublicKeyP key;
/**
* Signature over this signing key by the exchange's master signature.
*/
struct TALER_MasterSignatureP master_sig;
/** /**
* Validity start time * Validity start time
*/ */
@ -94,6 +99,11 @@ struct TALER_EXCHANGE_DenomPublicKey
*/ */
struct GNUNET_HashCode h_key; struct GNUNET_HashCode h_key;
/**
* Exchange's master signature over this denomination record.
*/
struct TALER_MasterSignatureP master_sig;
/** /**
* Timestamp indicating when the denomination key becomes valid * Timestamp indicating when the denomination key becomes valid
*/ */
@ -146,6 +156,27 @@ struct TALER_EXCHANGE_DenomPublicKey
}; };
/**
* Information we track per denomination audited by the auditor.
*/
struct TALER_EXCHANGE_AuditorDenominationInfo
{
/**
* Signature by the auditor affirming that it is monitoring this
* denomination.
*/
struct TALER_AuditorSignatureP auditor_sig;
/**
* Offsets into the key's main `denom_keys` array identifying the
* denomination being audited by this auditor.
*/
unsigned int denom_key_offset;
};
/** /**
* @brief Information we get from the exchange about auditors. * @brief Information we get from the exchange about auditors.
*/ */
@ -168,17 +199,16 @@ struct TALER_EXCHANGE_AuditorInformation
*/ */
char *auditor_url; char *auditor_url;
/**
* Array of length @a num_denom_keys with the denomination
* keys audited by this auditor.
*/
struct TALER_EXCHANGE_AuditorDenominationInfo *denom_keys;
/** /**
* Number of denomination keys audited by this auditor. * Number of denomination keys audited by this auditor.
*/ */
unsigned int num_denom_keys; unsigned int num_denom_keys;
/**
* Array of length @a num_denom_keys with the denomination
* keys audited by this auditor. Offsets into the
* key's main `denom_keys` array.
*/
unsigned int *denom_key_offsets;
}; };