add support for #4840 (/keys cherry picking) to libtalerexchange
This commit is contained in:
parent
7d21331d5f
commit
7aa23a39bd
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014, 2015 GNUnet e.V.
|
Copyright (C) 2014-2017 GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
terms of the GNU General Public License as published by the Free Software
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -436,7 +436,7 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
|
|||||||
GNUNET_JSON_parse (key,
|
GNUNET_JSON_parse (key,
|
||||||
kspec,
|
kspec,
|
||||||
NULL, NULL))
|
NULL, NULL))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -509,32 +509,22 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
struct TALER_ExchangeKeySetPS ks;
|
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 revision;
|
||||||
|
unsigned int current;
|
||||||
|
|
||||||
/* FIXME: #4840: handle incremental / cherry-picked /keys! */
|
|
||||||
memset (key_data,
|
memset (key_data,
|
||||||
0,
|
0,
|
||||||
sizeof (struct TALER_EXCHANGE_Keys));
|
sizeof (struct TALER_EXCHANGE_Keys));
|
||||||
if (JSON_OBJECT != json_typeof (resp_obj))
|
if (JSON_OBJECT != json_typeof (resp_obj))
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
|
|
||||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
/* check the version */
|
||||||
/* parse the master public key and issue date of the response */
|
|
||||||
{
|
{
|
||||||
const char *ver;
|
const char *ver;
|
||||||
unsigned int age;
|
|
||||||
unsigned int revision;
|
|
||||||
unsigned int current;
|
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_string ("version",
|
GNUNET_JSON_spec_string ("version",
|
||||||
&ver),
|
&ver),
|
||||||
GNUNET_JSON_spec_fixed_auto ("master_public_key",
|
|
||||||
&key_data->master_pub),
|
|
||||||
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_end()
|
GNUNET_JSON_spec_end()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -549,7 +539,6 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
&age))
|
&age))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
*vc = TALER_EXCHANGE_VC_MATCH;
|
*vc = TALER_EXCHANGE_VC_MATCH;
|
||||||
@ -568,6 +557,27 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
key_data->version = GNUNET_strdup (ver);
|
key_data->version = GNUNET_strdup (ver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* parse the master public key and issue date of the response */
|
||||||
|
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
{
|
||||||
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("master_public_key",
|
||||||
|
&key_data->master_pub),
|
||||||
|
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_end()
|
||||||
|
};
|
||||||
|
|
||||||
|
EXITIF (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (resp_obj,
|
||||||
|
spec,
|
||||||
|
NULL, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
/* parse the signing keys */
|
/* parse the signing keys */
|
||||||
{
|
{
|
||||||
json_t *sign_keys_array;
|
json_t *sign_keys_array;
|
||||||
@ -578,17 +588,37 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
json_object_get (resp_obj,
|
json_object_get (resp_obj,
|
||||||
"signkeys")));
|
"signkeys")));
|
||||||
EXITIF (JSON_ARRAY != json_typeof (sign_keys_array));
|
EXITIF (JSON_ARRAY != json_typeof (sign_keys_array));
|
||||||
EXITIF (0 == (key_data->num_sign_keys =
|
|
||||||
json_array_size (sign_keys_array)));
|
|
||||||
key_data->sign_keys
|
|
||||||
= GNUNET_new_array (key_data->num_sign_keys,
|
|
||||||
struct TALER_EXCHANGE_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) {
|
||||||
|
struct TALER_EXCHANGE_SigningPublicKey sk;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
EXITIF (GNUNET_SYSERR ==
|
EXITIF (GNUNET_SYSERR ==
|
||||||
parse_json_signkey (&key_data->sign_keys[index],
|
parse_json_signkey (&sk,
|
||||||
sign_key_obj,
|
sign_key_obj,
|
||||||
&key_data->master_pub));
|
&key_data->master_pub));
|
||||||
|
for (unsigned int j=0;j<key_data->num_sign_keys;j++)
|
||||||
|
{
|
||||||
|
if (0 == memcmp (&sk,
|
||||||
|
&key_data->sign_keys[j],
|
||||||
|
sizeof (sk)))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
/* 0:0:0 did not support /keys cherry picking */
|
||||||
|
GNUNET_break_op (0 == current);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key_data->sign_keys_size == key_data->num_sign_keys)
|
||||||
|
GNUNET_array_grow (key_data->sign_keys,
|
||||||
|
key_data->sign_keys_size,
|
||||||
|
key_data->sign_keys_size * 2 + 2);
|
||||||
|
key_data->sign_keys[key_data->num_sign_keys++] = sk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,21 +631,41 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
EXITIF (NULL == (denom_keys_array =
|
EXITIF (NULL == (denom_keys_array =
|
||||||
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));
|
||||||
if (0 == (key_data->num_denom_keys = json_array_size (denom_keys_array)))
|
|
||||||
{
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
||||||
"Found no denomination keys at this exchange\n");
|
|
||||||
goto EXITIF_exit;
|
|
||||||
}
|
|
||||||
key_data->denom_keys = GNUNET_new_array (key_data->num_denom_keys,
|
key_data->denom_keys = GNUNET_new_array (key_data->num_denom_keys,
|
||||||
struct TALER_EXCHANGE_DenomPublicKey);
|
struct TALER_EXCHANGE_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) {
|
||||||
|
struct TALER_EXCHANGE_DenomPublicKey dk;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
EXITIF (GNUNET_SYSERR ==
|
EXITIF (GNUNET_SYSERR ==
|
||||||
parse_json_denomkey (&key_data->denom_keys[index],
|
parse_json_denomkey (&dk,
|
||||||
denom_key_obj,
|
denom_key_obj,
|
||||||
&key_data->master_pub,
|
&key_data->master_pub,
|
||||||
hash_context));
|
hash_context));
|
||||||
|
for (unsigned int j=0;j<key_data->num_denom_keys;j++)
|
||||||
|
{
|
||||||
|
if (0 == memcmp (&dk,
|
||||||
|
&key_data->denom_keys[j],
|
||||||
|
sizeof (dk)))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
/* 0:0:0 did not support /keys cherry picking */
|
||||||
|
GNUNET_break_op (0 == current);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key_data->denom_keys_size == key_data->num_denom_keys)
|
||||||
|
GNUNET_array_grow (key_data->denom_keys,
|
||||||
|
key_data->denom_keys_size,
|
||||||
|
key_data->denom_keys_size * 2 + 2);
|
||||||
|
key_data->denom_keys[key_data->num_denom_keys++] = dk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +705,7 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
hash_context = NULL;
|
hash_context = NULL;
|
||||||
EXITIF (GNUNET_OK !=
|
EXITIF (GNUNET_OK !=
|
||||||
TALER_EXCHANGE_test_signing_key (key_data,
|
TALER_EXCHANGE_test_signing_key (key_data,
|
||||||
&pub));
|
&pub));
|
||||||
EXITIF (GNUNET_OK !=
|
EXITIF (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
|
||||||
&ks.purpose,
|
&ks.purpose,
|
||||||
@ -679,12 +729,12 @@ static void
|
|||||||
free_key_data (struct TALER_EXCHANGE_Keys *key_data)
|
free_key_data (struct TALER_EXCHANGE_Keys *key_data)
|
||||||
{
|
{
|
||||||
GNUNET_array_grow (key_data->sign_keys,
|
GNUNET_array_grow (key_data->sign_keys,
|
||||||
key_data->num_sign_keys,
|
key_data->sign_keys_size,
|
||||||
0);
|
0);
|
||||||
for (unsigned int i=0;i<key_data->num_denom_keys;i++)
|
for (unsigned int i=0;i<key_data->num_denom_keys;i++)
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (key_data->denom_keys[i].key.rsa_public_key);
|
GNUNET_CRYPTO_rsa_public_key_free (key_data->denom_keys[i].key.rsa_public_key);
|
||||||
GNUNET_array_grow (key_data->denom_keys,
|
GNUNET_array_grow (key_data->denom_keys,
|
||||||
key_data->num_denom_keys,
|
key_data->denom_keys_size,
|
||||||
0);
|
0);
|
||||||
for (unsigned int i=0;i<key_data->num_auditors;i++)
|
for (unsigned int i=0;i<key_data->num_auditors;i++)
|
||||||
{
|
{
|
||||||
|
@ -2704,6 +2704,11 @@ postgres_get_ready_deposit (void *cls,
|
|||||||
};
|
};
|
||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Finding ready deposits by deadline %s (%llu)\n",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (now),
|
||||||
|
(unsigned long long) now.abs_value_us);
|
||||||
|
|
||||||
qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
|
qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
|
||||||
"deposits_get_ready",
|
"deposits_get_ready",
|
||||||
params,
|
params,
|
||||||
@ -3027,6 +3032,11 @@ postgres_insert_deposit (void *cls,
|
|||||||
session,
|
session,
|
||||||
&deposit->coin)))
|
&deposit->coin)))
|
||||||
return qs;
|
return qs;
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Inserting deposit to be executed at %s (%llu/%llu)\n",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline),
|
||||||
|
(unsigned long long) deposit->wire_deadline.abs_value_us,
|
||||||
|
(unsigned long long) deposit->refund_deadline.abs_value_us);
|
||||||
return GNUNET_PQ_eval_prepared_non_select (session->conn,
|
return GNUNET_PQ_eval_prepared_non_select (session->conn,
|
||||||
"insert_deposit",
|
"insert_deposit",
|
||||||
params);
|
params);
|
||||||
|
@ -213,7 +213,7 @@ struct TALER_EXCHANGE_Keys
|
|||||||
struct GNUNET_TIME_Absolute last_issue_date;
|
struct GNUNET_TIME_Absolute last_issue_date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of the @e sign_keys array.
|
* Length of the @e sign_keys array (number of valid entries).
|
||||||
*/
|
*/
|
||||||
unsigned int num_sign_keys;
|
unsigned int num_sign_keys;
|
||||||
|
|
||||||
@ -227,6 +227,16 @@ struct TALER_EXCHANGE_Keys
|
|||||||
*/
|
*/
|
||||||
unsigned int num_auditors;
|
unsigned int num_auditors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actual length of the @e sign_keys array (size of allocation).
|
||||||
|
*/
|
||||||
|
unsigned int sign_keys_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actual length of the @e denom_keys array (size of allocation).
|
||||||
|
*/
|
||||||
|
unsigned int denom_keys_size;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user