fix #6662: add versioning information to JSON exchanged between taler-exchange-offline invocations

This commit is contained in:
Christian Grothoff 2020-12-19 17:36:10 +01:00
parent b1e305fb05
commit 0ad6cb0a86
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 520 additions and 341 deletions

View File

@ -23,6 +23,24 @@
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
/**
* Name of the input of a denomination key signature for the 'upload' operation.
* The "auditor-" prefix ensures that there is no ambiguity between
* taler-exchange-offline and taler-auditor-offline JSON formats.
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_SIGN_DENOMINATION "auditor-sign-denomination-0"
/**
* Name of the input for the 'sign' and 'show' operations.
* The "auditor-" prefix ensures that there is no ambiguity between
* taler-exchange-offline and taler-auditor-offline JSON formats.
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_INPUT_KEYS "auditor-keys-0"
/**
* Our private key, initialized in #load_offline_key().
@ -452,7 +470,7 @@ trigger_upload (const char *exchange_url)
{
struct UploadHandler uhs[] = {
{
.key = "sign-denomination",
.key = OP_SIGN_DENOMINATION,
.cb = &upload_denomination_add
},
/* array termination */
@ -605,15 +623,18 @@ keys_cb (
global_ret = 4;
return;
}
in = json_pack ("{s:s,s:O}",
"operation",
OP_INPUT_KEYS,
"arguments",
hr->reply);
if (NULL == args[0])
{
json_dumpf (hr->reply,
json_dumpf (in,
stdout,
JSON_INDENT (2));
}
else
{
in = json_incref ((json_t*) hr->reply);
json_decref (in);
in = NULL;
}
TALER_EXCHANGE_disconnect (exchange);
exchange = NULL;
@ -796,13 +817,26 @@ show_denomkeys (const json_t *denomkeys)
/**
* Show exchange denomination keys.
* Parse the '/keys' input for operation called @a command_name.
*
* @param args the array of command-line arguments to process next
* @param command_name name of the command, for logging errors
* @return NULL if the input is malformed
*/
static void
do_show (char *const *args)
static json_t *
parse_keys (const char *command_name)
{
json_t *keys;
const char *op_str;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("arguments",
&keys),
GNUNET_JSON_spec_string ("operation",
&op_str),
GNUNET_JSON_spec_end ()
};
const char *err_name;
unsigned int err_line;
if (NULL == in)
{
json_error_t err;
@ -820,57 +854,105 @@ do_show (char *const *args)
err.position);
global_ret = 2;
test_shutdown ();
return;
return NULL;
}
}
if (GNUNET_OK !=
GNUNET_JSON_parse (in,
spec,
&err_name,
&err_line))
{
const char *err_name;
unsigned int err_line;
json_t *denomkeys;
struct TALER_MasterPublicKeyP mpub;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("denoms",
&denomkeys),
GNUNET_JSON_spec_fixed_auto ("master_public_key",
&mpub),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
GNUNET_JSON_parse (in,
spec,
&err_name,
&err_line))
{
fprintf (stderr,
"Invalid input to 'show': %s#%u (skipping)\n",
err_name,
err_line);
global_ret = 7;
test_shutdown ();
return;
}
if (0 !=
GNUNET_memcmp (&mpub,
&master_pub))
{
fprintf (stderr,
"Exchange master public key does not match key we have configured (aborting)\n");
global_ret = 7;
test_shutdown ();
return;
}
if (GNUNET_OK !=
show_denomkeys (denomkeys))
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
return;
}
GNUNET_JSON_parse_free (spec);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to '%s': %s#%u (skipping)\n",
command_name,
err_name,
err_line);
json_dumpf (in,
stderr,
JSON_INDENT (2));
global_ret = 7;
test_shutdown ();
return NULL;
}
if (0 != strcmp (op_str,
OP_INPUT_KEYS))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to '%s' : operation is `%s', expected `%s'\n",
command_name,
op_str,
OP_INPUT_KEYS);
GNUNET_JSON_parse_free (spec);
return NULL;
}
json_decref (in);
in = NULL;
return keys;
}
/**
* Show exchange denomination keys.
*
* @param args the array of command-line arguments to process next
*/
static void
do_show (char *const *args)
{
json_t *keys;
const char *err_name;
unsigned int err_line;
json_t *denomkeys;
struct TALER_MasterPublicKeyP mpub;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("denoms",
&denomkeys),
GNUNET_JSON_spec_fixed_auto ("master_public_key",
&mpub),
GNUNET_JSON_spec_end ()
};
keys = parse_keys ("show");
if (NULL == keys)
return;
if (GNUNET_OK !=
GNUNET_JSON_parse (keys,
spec,
&err_name,
&err_line))
{
fprintf (stderr,
"Invalid input to 'show': %s#%u (skipping)\n",
err_name,
err_line);
global_ret = 7;
test_shutdown ();
json_decref (keys);
return;
}
if (0 !=
GNUNET_memcmp (&mpub,
&master_pub))
{
fprintf (stderr,
"Exchange master public key does not match key we have configured (aborting)\n");
global_ret = 7;
test_shutdown ();
json_decref (keys);
return;
}
if (GNUNET_OK !=
show_denomkeys (denomkeys))
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
GNUNET_JSON_parse_free (spec);
json_decref (keys);
/* do NOT consume input if next argument is '-' */
if ( (NULL != args[0]) &&
(0 == strcmp ("-",
@ -879,8 +961,6 @@ do_show (char *const *args)
next (args + 1);
return;
}
json_decref (in);
in = NULL;
next (args);
}
@ -996,7 +1076,7 @@ sign_denomkeys (const json_t *denomkeys)
&fee_refund,
&auditor_priv,
&auditor_sig);
output_operation ("sign-denomination",
output_operation (OP_SIGN_DENOMINATION,
json_pack ("{s:o, s:o}",
"h_denom_pub",
GNUNET_JSON_from_data_auto (&h_denom_pub),
@ -1017,79 +1097,67 @@ sign_denomkeys (const json_t *denomkeys)
static void
do_sign (char *const *args)
{
if (NULL == in)
{
json_error_t err;
json_t *keys;
const char *err_name;
unsigned int err_line;
struct TALER_MasterPublicKeyP mpub;
json_t *denomkeys;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("denoms",
&denomkeys),
GNUNET_JSON_spec_fixed_auto ("master_public_key",
&mpub),
GNUNET_JSON_spec_end ()
};
out = json_loadf (stdin,
JSON_REJECT_DUPLICATES,
&err);
if (NULL == in)
{
fprintf (stderr,
"Failed to read JSON input: %s at %d:%s (offset: %d)\n",
err.text,
err.line,
err.source,
err.position);
global_ret = 2;
test_shutdown ();
return;
}
}
keys = parse_keys ("sign");
if (NULL == keys)
return;
if (GNUNET_OK !=
load_offline_key ())
return;
{
const char *err_name;
unsigned int err_line;
struct TALER_MasterPublicKeyP mpub;
json_t *denomkeys;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("denoms",
&denomkeys),
GNUNET_JSON_spec_fixed_auto ("master_public_key",
&mpub),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
GNUNET_JSON_parse (in,
spec,
&err_name,
&err_line))
{
fprintf (stderr,
"Invalid input to 'sign': %s#%u (skipping)\n",
err_name,
err_line);
global_ret = 7;
test_shutdown ();
return;
}
if (0 !=
GNUNET_memcmp (&mpub,
&master_pub))
{
fprintf (stderr,
"Exchange master public key does not match key we have configured (aborting)\n");
global_ret = 7;
test_shutdown ();
return;
}
if (GNUNET_OK !=
sign_denomkeys (denomkeys))
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
return;
}
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
json_decref (in);
in = NULL;
if (GNUNET_OK !=
GNUNET_JSON_parse (keys,
spec,
&err_name,
&err_line))
{
fprintf (stderr,
"Invalid input to 'sign': %s#%u (skipping)\n",
err_name,
err_line);
global_ret = 7;
test_shutdown ();
json_decref (keys);
return;
}
if (0 !=
GNUNET_memcmp (&mpub,
&master_pub))
{
fprintf (stderr,
"Exchange master public key does not match key we have configured (aborting)\n");
global_ret = 7;
test_shutdown ();
json_decref (keys);
return;
}
if (GNUNET_OK !=
sign_denomkeys (denomkeys))
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
GNUNET_JSON_parse_free (spec);
json_decref (keys);
next (args);
}

View File

@ -23,6 +23,69 @@
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
/**
* Name of the input for the 'sign' and 'show' operation.
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_INPUT_KEYS "exchange-input-keys-0"
/**
* Name of the operation to 'disable auditor'
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_DISABLE_AUDITOR "exchange-disable-auditor-0"
/**
* Name of the operation to 'enable auditor'
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_ENABLE_AUDITOR "exchange-enable-auditor-0"
/**
* Name of the operation to 'enable wire'
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_ENABLE_WIRE "exchange-enable-wire-0"
/**
* Name of the operation to 'disable wire'
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_DISABLE_WIRE "exchange-disable-wire-0"
/**
* Name of the operation to set a 'wire-fee'
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_SET_WIRE_FEE "exchange-set-wire-fee-0"
/**
* Name of the operation to 'upload' key signatures
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_UPLOAD_SIGS "exchange-upload-sigs-0"
/**
* Name of the operation to 'revoke-denomination' key
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_REVOKE_DENOMINATION "exchange-revoke-denomination-0"
/**
* Name of the operation to 'revoke-signkey'
* The last component --by convention-- identifies the protocol version
* and should be incremented whenever the JSON format of the 'argument' changes.
*/
#define OP_REVOKE_SIGNKEY "exchange-revoke-signkey-0"
/**
* Our private key, initialized in #load_offline_key().
@ -1570,35 +1633,35 @@ trigger_upload (const char *exchange_url)
{
struct UploadHandler uhs[] = {
{
.key = "revoke-denomination",
.key = OP_REVOKE_DENOMINATION,
.cb = &upload_denom_revocation
},
{
.key = "revoke-signkey",
.key = OP_REVOKE_SIGNKEY,
.cb = &upload_signkey_revocation
},
{
.key = "enable-auditor",
.key = OP_ENABLE_AUDITOR,
.cb = &upload_auditor_add
},
{
.key = "disable-auditor",
.key = OP_DISABLE_AUDITOR,
.cb = &upload_auditor_del
},
{
.key = "enable-wire",
.key = OP_ENABLE_WIRE,
.cb = &upload_wire_add
},
{
.key = "disable-wire",
.key = OP_DISABLE_WIRE,
.cb = &upload_wire_del
},
{
.key = "set-wire-fee",
.key = OP_SET_WIRE_FEE,
.cb = &upload_wire_fee
},
{
.key = "upload-keys",
.key = OP_UPLOAD_SIGS,
.cb = &upload_keys
},
/* array termination */
@ -1755,7 +1818,7 @@ do_revoke_denomination_key (char *const *args)
TALER_exchange_offline_denomination_revoke_sign (&h_denom_pub,
&master_priv,
&master_sig);
output_operation ("revoke-denomination",
output_operation (OP_REVOKE_DENOMINATION,
json_pack ("{s:o, s:o}",
"h_denom_pub",
GNUNET_JSON_from_data_auto (&h_denom_pub),
@ -1804,7 +1867,7 @@ do_revoke_signkey (char *const *args)
TALER_exchange_offline_signkey_revoke_sign (&exchange_pub,
&master_priv,
&master_sig);
output_operation ("revoke-signkey",
output_operation (OP_REVOKE_SIGNKEY,
json_pack ("{s:o, s:o}",
"exchange_pub",
GNUNET_JSON_from_data_auto (&exchange_pub),
@ -1873,7 +1936,7 @@ do_add_auditor (char *const *args)
now,
&master_priv,
&master_sig);
output_operation ("enable-auditor",
output_operation (OP_ENABLE_AUDITOR,
json_pack ("{s:s, s:s, s:o, s:o, s:o}",
"auditor_url",
args[1],
@ -1933,7 +1996,7 @@ do_del_auditor (char *const *args)
now,
&master_priv,
&master_sig);
output_operation ("disable-auditor",
output_operation (OP_DISABLE_AUDITOR,
json_pack ("{s:o, s:o, s:o}",
"auditor_pub",
GNUNET_JSON_from_data_auto (&auditor_pub),
@ -1987,7 +2050,7 @@ do_add_wire (char *const *args)
TALER_exchange_wire_signature_make (args[0],
&master_priv,
&master_sig_wire);
output_operation ("enable-wire",
output_operation (OP_ENABLE_WIRE,
json_pack ("{s:s, s:o, s:o, s:o}",
"payto_uri",
args[0],
@ -2039,7 +2102,7 @@ do_del_wire (char *const *args)
now,
&master_priv,
&master_sig);
output_operation ("disable-wire",
output_operation (OP_DISABLE_WIRE,
json_pack ("{s:s, s:o, s:o}",
"payto_uri",
args[0],
@ -2116,7 +2179,7 @@ do_set_wire_fee (char *const *args)
&closing_fee,
&master_priv,
&master_sig);
output_operation ("set-wire-fee",
output_operation (OP_SET_WIRE_FEE,
json_pack ("{s:s, s:o, s:o, s:o, s:o, s:o}",
"wire_method",
args[1],
@ -2166,15 +2229,18 @@ download_cb (void *cls,
global_ret = 4;
return;
}
in = json_pack ("{s:s,s:O}",
"operation",
OP_INPUT_KEYS,
"arguments",
hr->reply);
if (NULL == args[0])
{
json_dumpf (hr->reply,
json_dumpf (in,
stdout,
JSON_INDENT (2));
}
else
{
in = json_incref ((json_t*) hr->reply);
json_decref (in);
in = NULL;
}
next (args);
}
@ -2516,13 +2582,26 @@ show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
/**
* Show future keys.
* Parse the input of exchange keys for the 'show' and 'sign' commands.
*
* @param args the array of command-line arguments to process next
* @param command_name name of the command, for logging
* @return NULL on error, otherwise the keys details to be free'd by caller
*/
static void
do_show (char *const *args)
static json_t *
parse_keys_input (const char *command_name)
{
const char *op_str;
json_t *keys;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("arguments",
&keys),
GNUNET_JSON_spec_string ("operation",
&op_str),
GNUNET_JSON_spec_end ()
};
const char *err_name;
unsigned int err_line;
if (NULL == in)
{
json_error_t err;
@ -2540,86 +2619,132 @@ do_show (char *const *args)
err.position);
global_ret = 2;
test_shutdown ();
return;
return NULL;
}
}
if (GNUNET_OK !=
load_offline_key ())
return;
GNUNET_JSON_parse (in,
spec,
&err_name,
&err_line))
{
const char *err_name;
unsigned int err_line;
json_t *denomkeys;
json_t *signkeys;
struct TALER_MasterPublicKeyP mpub;
struct TALER_SecurityModulePublicKeyP secm[2];
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("future_denoms",
&denomkeys),
GNUNET_JSON_spec_json ("future_signkeys",
&signkeys),
GNUNET_JSON_spec_fixed_auto ("master_pub",
&mpub),
GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
&secm[0]),
GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
&secm[1]),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
GNUNET_JSON_parse (in,
spec,
&err_name,
&err_line))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to 'show': %s#%u (skipping)\n",
err_name,
err_line);
json_dumpf (in,
stderr,
JSON_INDENT (2));
global_ret = 7;
test_shutdown ();
return;
}
if (0 !=
GNUNET_memcmp (&master_pub,
&mpub))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatal: exchange uses different master key!\n");
global_ret = 6;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
return;
}
if (GNUNET_SYSERR ==
tofu_check (secm))
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
return;
}
if ( (GNUNET_OK !=
show_signkeys (&secm[1],
signkeys)) ||
(GNUNET_OK !=
show_denomkeys (&secm[0],
denomkeys)) )
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to '%s': %s#%u (skipping)\n",
command_name,
err_name,
err_line);
json_dumpf (in,
stderr,
JSON_INDENT (2));
global_ret = 7;
test_shutdown ();
return NULL;
}
if (0 != strcmp (op_str,
OP_INPUT_KEYS))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to '%s' : operation is `%s', expected `%s'\n",
command_name,
op_str,
OP_INPUT_KEYS);
GNUNET_JSON_parse_free (spec);
return NULL;
}
json_decref (in);
in = NULL;
return keys;
}
/**
* Show future keys.
*
* @param args the array of command-line arguments to process next
*/
static void
do_show (char *const *args)
{
json_t *keys;
const char *err_name;
unsigned int err_line;
json_t *denomkeys;
json_t *signkeys;
struct TALER_MasterPublicKeyP mpub;
struct TALER_SecurityModulePublicKeyP secm[2];
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("future_denoms",
&denomkeys),
GNUNET_JSON_spec_json ("future_signkeys",
&signkeys),
GNUNET_JSON_spec_fixed_auto ("master_pub",
&mpub),
GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
&secm[0]),
GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
&secm[1]),
GNUNET_JSON_spec_end ()
};
keys = parse_keys_input ("show");
if (NULL == keys)
return;
if (GNUNET_OK !=
GNUNET_JSON_parse (keys,
spec,
&err_name,
&err_line))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to 'show': %s #%u (skipping)\n",
err_name,
err_line);
json_dumpf (in,
stderr,
JSON_INDENT (2));
global_ret = 7;
test_shutdown ();
json_decref (keys);
return;
}
if (0 !=
GNUNET_memcmp (&master_pub,
&mpub))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatal: exchange uses different master key!\n");
global_ret = 6;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
if (GNUNET_SYSERR ==
tofu_check (secm))
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
if ( (GNUNET_OK !=
show_signkeys (&secm[1],
signkeys)) ||
(GNUNET_OK !=
show_denomkeys (&secm[0],
denomkeys)) )
{
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
json_decref (keys);
GNUNET_JSON_parse_free (spec);
next (args);
}
@ -2670,7 +2795,7 @@ sign_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
&err_line))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input for signing key to 'show': %s#%u at %u (skipping)\n",
"Invalid input for signing key to 'show': %s #%u at %u (skipping)\n",
err_name,
err_line,
(unsigned int) index);
@ -2711,7 +2836,7 @@ sign_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
GNUNET_assert (0 ==
json_array_append_new (
result,
json_pack ("{s:o, s:o}",
json_pack ("{s:o,s:o}",
"exchange_pub",
GNUNET_JSON_from_data_auto (&exchange_pub),
"master_sig",
@ -2791,7 +2916,7 @@ sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
&err_line))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input for denomination key to 'sign': %s#%u at %u (skipping)\n",
"Invalid input for denomination key to 'sign': %s #%u at %u (skipping)\n",
err_name,
err_line,
(unsigned int) index);
@ -2842,11 +2967,12 @@ sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
GNUNET_assert (0 ==
json_array_append_new (
result,
json_pack ("{s:o, s:o}",
"h_denom_pub",
GNUNET_JSON_from_data_auto (&h_denom_pub),
"master_sig",
GNUNET_JSON_from_data_auto (&master_sig))));
json_pack (
"{s:o,s:o}",
"h_denom_pub",
GNUNET_JSON_from_data_auto (&h_denom_pub),
"master_sig",
GNUNET_JSON_from_data_auto (&master_sig))));
}
GNUNET_JSON_parse_free (spec);
}
@ -2862,123 +2988,110 @@ sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
static void
do_sign (char *const *args)
{
if (NULL == in)
{
json_error_t err;
json_t *keys;
const char *err_name;
unsigned int err_line;
json_t *denomkeys;
json_t *signkeys;
struct TALER_MasterPublicKeyP mpub;
struct TALER_SecurityModulePublicKeyP secm[2];
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("future_denoms",
&denomkeys),
GNUNET_JSON_spec_json ("future_signkeys",
&signkeys),
GNUNET_JSON_spec_fixed_auto ("master_pub",
&mpub),
GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
&secm[0]),
GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
&secm[1]),
GNUNET_JSON_spec_end ()
};
in = json_loadf (stdin,
JSON_REJECT_DUPLICATES,
&err);
if (NULL == in)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to read JSON input: %s at %d:%s (offset: %d)\n",
err.text,
err.line,
err.source,
err.position);
global_ret = 2;
test_shutdown ();
return;
}
}
keys = parse_keys_input ("sign");
if (NULL == keys)
return;
if (GNUNET_OK !=
load_offline_key ())
return;
{
const char *err_name;
unsigned int err_line;
json_t *denomkeys;
json_t *signkeys;
struct TALER_MasterPublicKeyP mpub;
struct TALER_SecurityModulePublicKeyP secm[2];
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("future_denoms",
&denomkeys),
GNUNET_JSON_spec_json ("future_signkeys",
&signkeys),
GNUNET_JSON_spec_fixed_auto ("master_pub",
&mpub),
GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
&secm[0]),
GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
&secm[1]),
GNUNET_JSON_spec_end ()
};
json_decref (keys);
return;
}
if (GNUNET_OK !=
GNUNET_JSON_parse (keys,
spec,
&err_name,
&err_line))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to 'sign' : %s #%u (skipping)\n",
err_name,
err_line);
json_dumpf (in,
stderr,
JSON_INDENT (2));
global_ret = 7;
test_shutdown ();
json_decref (keys);
return;
}
if (0 !=
GNUNET_memcmp (&master_pub,
&mpub))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatal: exchange uses different master key!\n");
global_ret = 6;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
if (GNUNET_SYSERR ==
tofu_check (secm))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatal: security module keys changed!\n");
global_ret = 8;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
{
json_t *signkey_sig_array = json_array ();
json_t *denomkey_sig_array = json_array ();
if (GNUNET_OK !=
GNUNET_JSON_parse (in,
spec,
&err_name,
&err_line))
GNUNET_assert (NULL != signkey_sig_array);
GNUNET_assert (NULL != denomkey_sig_array);
if ( (GNUNET_OK !=
sign_signkeys (&secm[1],
signkeys,
signkey_sig_array)) ||
(GNUNET_OK !=
sign_denomkeys (&secm[0],
denomkeys,
denomkey_sig_array)) )
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid input to 'sign': %s#%u (skipping)\n",
err_name,
err_line);
json_dumpf (in,
stderr,
JSON_INDENT (2));
global_ret = 7;
test_shutdown ();
return;
}
if (0 !=
GNUNET_memcmp (&master_pub,
&mpub))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatal: exchange uses different master key!\n");
global_ret = 6;
test_shutdown ();
GNUNET_JSON_parse_free (spec);
return;
}
if (GNUNET_SYSERR ==
tofu_check (secm))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatal: security module keys changed!\n");
global_ret = 8;
test_shutdown ();
json_decref (signkey_sig_array);
json_decref (denomkey_sig_array);
GNUNET_JSON_parse_free (spec);
json_decref (keys);
return;
}
{
json_t *signkey_sig_array = json_array ();
json_t *denomkey_sig_array = json_array ();
GNUNET_assert (NULL != signkey_sig_array);
GNUNET_assert (NULL != denomkey_sig_array);
if ( (GNUNET_OK !=
sign_signkeys (&secm[1],
signkeys,
signkey_sig_array)) ||
(GNUNET_OK !=
sign_denomkeys (&secm[0],
denomkeys,
denomkey_sig_array)) )
{
global_ret = 8;
test_shutdown ();
json_decref (signkey_sig_array);
json_decref (denomkey_sig_array);
GNUNET_JSON_parse_free (spec);
return;
}
output_operation ("upload-keys",
json_pack ("{s:o, s:o}",
"denom_sigs",
denomkey_sig_array,
"signkey_sigs",
signkey_sig_array));
}
GNUNET_JSON_parse_free (spec);
output_operation (OP_UPLOAD_SIGS,
json_pack ("{s:o,s:o}",
"denom_sigs",
denomkey_sig_array,
"signkey_sigs",
signkey_sig_array));
}
json_decref (in);
in = NULL;
GNUNET_JSON_parse_free (spec);
json_decref (keys);
next (args);
}
@ -3002,8 +3115,7 @@ work (void *cls)
},
{
.name = "sign",
.help =
"sing all future public keys from the input",
.help = "sign all future public keys from the input",
.cb = &do_sign
},
{
@ -3021,7 +3133,7 @@ work (void *cls)
{
.name = "enable-auditor",
.help =
"enable auditor for the exchange (auditor-public key, auditor-URI and auditor name must given as arguments)",
"enable auditor for the exchange (auditor-public key, auditor-URI and auditor-name must be given as arguments)",
.cb = &do_add_auditor
},
{
@ -3081,12 +3193,11 @@ work (void *cls)
global_ret = 3;
}
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"Supported subcommands:\n");
for (unsigned int i = 0; NULL != cmds[i].name; i++)
{
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"\t%s - %s\n",
"- %s: %s\n",
cmds[i].name,
cmds[i].help);
}