diff options
| -rw-r--r-- | src/exchange-tools/taler-auditor-offline.c | 314 | ||||
| -rw-r--r-- | src/exchange-tools/taler-exchange-offline.c | 535 | 
2 files changed, 514 insertions, 335 deletions
diff --git a/src/exchange-tools/taler-auditor-offline.c b/src/exchange-tools/taler-auditor-offline.c index b712ac67..507dd744 100644 --- a/src/exchange-tools/taler-auditor-offline.c +++ b/src/exchange-tools/taler-auditor-offline.c @@ -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 () -    }; +    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; +} -    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; -    } + +/** + * 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 ()) +  { +    json_decref (keys);      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; -    } +  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;    } -  json_decref (in); -  in = NULL; +  GNUNET_JSON_parse_free (spec); +  json_decref (keys);    next (args);  } diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c index 5e065b5b..b45274ff 100644 --- a/src/exchange-tools/taler-exchange-offline.c +++ b/src/exchange-tools/taler-exchange-offline.c @@ -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 ()) +  { +    json_decref (keys);      return; - +  } +  if (GNUNET_OK != +      GNUNET_JSON_parse (keys, +                         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 () -    }; +    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_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_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, -                  "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);    }  | 
