aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exchange-tools/taler-exchange-offline.c461
-rw-r--r--src/exchange/taler-exchange-httpd_management_auditors.c38
-rw-r--r--src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c34
-rw-r--r--src/include/taler_crypto_lib.h71
-rw-r--r--src/testing/testing_api_cmd_auditor_add.c23
-rw-r--r--src/testing/testing_api_cmd_auditor_del.c15
-rw-r--r--src/util/offline_signatures.c128
7 files changed, 688 insertions, 82 deletions
diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c
index 28bbbe023..df30f8018 100644
--- a/src/exchange-tools/taler-exchange-offline.c
+++ b/src/exchange-tools/taler-exchange-offline.c
@@ -146,6 +146,62 @@ struct SignkeyRevocationRequest
/**
+ * Data structure for auditor add requests.
+ */
+struct AuditorAddRequest
+{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct AuditorAddRequest *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct AuditorAddRequest *prev;
+
+ /**
+ * Operation handle.
+ */
+ struct TALER_EXCHANGE_ManagementAuditorEnableHandle *h;
+
+ /**
+ * Array index of the associated command.
+ */
+ size_t idx;
+};
+
+
+/**
+ * Data structure for auditor del requests.
+ */
+struct AuditorDelRequest
+{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct AuditorDelRequest *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct AuditorDelRequest *prev;
+
+ /**
+ * Operation handle.
+ */
+ struct TALER_EXCHANGE_ManagementAuditorDisableHandle *h;
+
+ /**
+ * Array index of the associated command.
+ */
+ size_t idx;
+};
+
+
+/**
* Data structure for wire add requests.
*/
struct WireAddRequest
@@ -287,6 +343,26 @@ static struct SignkeyRevocationRequest *srr_head;
static struct SignkeyRevocationRequest *srr_tail;
/**
+ * Active auditor add requests.
+ */
+static struct AuditorAddRequest *aar_head;
+
+/**
+ * Active auditor add requests.
+ */
+static struct AuditorAddRequest *aar_tail;
+
+/**
+ * Active auditor del requests.
+ */
+static struct AuditorDelRequest *adr_head;
+
+/**
+ * Active auditor del requests.
+ */
+static struct AuditorDelRequest *adr_tail;
+
+/**
* Active wire add requests.
*/
static struct WireAddRequest *war_head;
@@ -369,6 +445,36 @@ do_shutdown (void *cls)
}
{
+ struct AuditorAddRequest *aar;
+
+ while (NULL != (aar = aar_head))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Aborting incomplete auditor add #%u\n",
+ (unsigned int) aar->idx);
+ TALER_EXCHANGE_management_enable_auditor_cancel (aar->h);
+ GNUNET_CONTAINER_DLL_remove (aar_head,
+ aar_tail,
+ aar);
+ GNUNET_free (aar);
+ }
+ }
+ {
+ struct AuditorDelRequest *adr;
+
+ while (NULL != (adr = adr_head))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Aborting incomplete auditor del #%u\n",
+ (unsigned int) adr->idx);
+ TALER_EXCHANGE_management_disable_auditor_cancel (adr->h);
+ GNUNET_CONTAINER_DLL_remove (adr_head,
+ adr_tail,
+ adr);
+ GNUNET_free (adr);
+ }
+ }
+ {
struct WireAddRequest *war;
while (NULL != (war = war_head))
@@ -474,6 +580,8 @@ test_shutdown (void)
{
if ( (NULL == drr_head) &&
(NULL == srr_head) &&
+ (NULL == aar_head) &&
+ (NULL == adr_head) &&
(NULL == war_head) &&
(NULL == wdr_head) &&
(NULL == wfr_head) &&
@@ -795,15 +903,206 @@ upload_signkey_revocation (const char *exchange_url,
/**
+ * Function called with information about the post auditor add operation result.
+ *
+ * @param cls closure with a `struct AuditorAddRequest`
+ * @param hr HTTP response data
+ */
+static void
+auditor_add_cb (void *cls,
+ const struct TALER_EXCHANGE_HttpResponse *hr)
+{
+ struct AuditorAddRequest *aar = cls;
+
+ if (MHD_HTTP_NO_CONTENT != hr->http_status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Upload failed for command %u with status %u: %s (%s)\n",
+ (unsigned int) aar->idx,
+ hr->http_status,
+ TALER_ErrorCode_get_hint (hr->ec),
+ hr->hint);
+ global_ret = 10;
+ }
+ GNUNET_CONTAINER_DLL_remove (aar_head,
+ aar_tail,
+ aar);
+ GNUNET_free (aar);
+ test_shutdown ();
+}
+
+
+/**
+ * Upload auditor add data.
+ *
+ * @param exchange_url base URL of the exchange
+ * @param idx index of the operation we are performing (for logging)
+ * @param value argumets for denomination revocation
+ */
+static void
+upload_auditor_add (const char *exchange_url,
+ size_t idx,
+ const json_t *value)
+{
+ struct TALER_MasterSignatureP master_sig;
+ const char *auditor_url;
+ const char *auditor_name;
+ struct GNUNET_TIME_Absolute start_time;
+ struct TALER_AuditorPublicKeyP auditor_pub;
+ struct AuditorAddRequest *aar;
+ const char *err_name;
+ unsigned int err_line;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("auditor_url",
+ &auditor_url),
+ GNUNET_JSON_spec_string ("auditor_name",
+ &auditor_name),
+ GNUNET_JSON_spec_absolute_time ("validity_start",
+ &start_time),
+ GNUNET_JSON_spec_fixed_auto ("auditor_pub",
+ &auditor_pub),
+ GNUNET_JSON_spec_fixed_auto ("master_sig",
+ &master_sig),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (value,
+ spec,
+ &err_name,
+ &err_line))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Invalid input for adding auditor: %s#%u at %u (skipping)\n",
+ err_name,
+ err_line,
+ (unsigned int) idx);
+ json_dumpf (value,
+ stderr,
+ JSON_INDENT (2));
+ global_ret = 7;
+ test_shutdown ();
+ return;
+ }
+ aar = GNUNET_new (struct AuditorAddRequest);
+ aar->idx = idx;
+ aar->h =
+ TALER_EXCHANGE_management_enable_auditor (ctx,
+ exchange_url,
+ &auditor_pub,
+ auditor_url,
+ auditor_name,
+ start_time,
+ &master_sig,
+ &auditor_add_cb,
+ aar);
+ GNUNET_CONTAINER_DLL_insert (aar_head,
+ aar_tail,
+ aar);
+}
+
+
+/**
+ * Function called with information about the post auditor del operation result.
+ *
+ * @param cls closure with a `struct AuditorDelRequest`
+ * @param hr HTTP response data
+ */
+static void
+auditor_del_cb (void *cls,
+ const struct TALER_EXCHANGE_HttpResponse *hr)
+{
+ struct AuditorDelRequest *adr = cls;
+
+ if (MHD_HTTP_NO_CONTENT != hr->http_status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Upload failed for command %u with status %u: %s (%s)\n",
+ (unsigned int) adr->idx,
+ hr->http_status,
+ TALER_ErrorCode_get_hint (hr->ec),
+ hr->hint);
+ global_ret = 10;
+ }
+ GNUNET_CONTAINER_DLL_remove (adr_head,
+ adr_tail,
+ adr);
+ GNUNET_free (adr);
+ test_shutdown ();
+}
+
+
+/**
+ * Upload auditor del data.
+ *
+ * @param exchange_url base URL of the exchange
+ * @param idx index of the operation we are performing (for logging)
+ * @param value argumets for denomination revocation
+ */
+static void
+upload_auditor_del (const char *exchange_url,
+ size_t idx,
+ const json_t *value)
+{
+ struct TALER_AuditorPublicKeyP auditor_pub;
+ struct TALER_MasterSignatureP master_sig;
+ struct GNUNET_TIME_Absolute end_time;
+ struct AuditorDelRequest *adr;
+ const char *err_name;
+ unsigned int err_line;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("auditor_pub",
+ &auditor_pub),
+ GNUNET_JSON_spec_absolute_time ("validity_end",
+ &end_time),
+ GNUNET_JSON_spec_fixed_auto ("master_sig",
+ &master_sig),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (value,
+ spec,
+ &err_name,
+ &err_line))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Invalid input to disable auditor: %s#%u at %u (skipping)\n",
+ err_name,
+ err_line,
+ (unsigned int) idx);
+ json_dumpf (value,
+ stderr,
+ JSON_INDENT (2));
+ global_ret = 7;
+ test_shutdown ();
+ return;
+ }
+ adr = GNUNET_new (struct AuditorDelRequest);
+ adr->idx = idx;
+ adr->h =
+ TALER_EXCHANGE_management_disable_auditor (ctx,
+ exchange_url,
+ &auditor_pub,
+ end_time,
+ &master_sig,
+ &auditor_del_cb,
+ adr);
+ GNUNET_CONTAINER_DLL_insert (adr_head,
+ adr_tail,
+ adr);
+}
+
+
+/**
* Function called with information about the post wire add operation result.
*
* @param cls closure with a `struct WireAddRequest`
* @param hr HTTP response data
*/
static void
-wire_add_cb (
- void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr)
+wire_add_cb (void *cls,
+ const struct TALER_EXCHANGE_HttpResponse *hr)
{
struct WireAddRequest *war = cls;
@@ -898,9 +1197,8 @@ upload_wire_add (const char *exchange_url,
* @param hr HTTP response data
*/
static void
-wire_del_cb (
- void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr)
+wire_del_cb (void *cls,
+ const struct TALER_EXCHANGE_HttpResponse *hr)
{
struct WireDelRequest *wdr = cls;
@@ -1280,6 +1578,14 @@ trigger_upload (const char *exchange_url)
.cb = &upload_signkey_revocation
},
{
+ .key = "enable-auditor",
+ .cb = &upload_auditor_add
+ },
+ {
+ .key = "disable-auditor",
+ .cb = &upload_auditor_del
+ },
+ {
.key = "enable-wire",
.cb = &upload_wire_add
},
@@ -1509,6 +1815,137 @@ do_revoke_signkey (char *const *args)
/**
+ * Add auditor.
+ *
+ * @param args the array of command-line arguments to process next;
+ * args[0] must be the auditor's public key, args[1] the auditor's
+ * API base URL, and args[2] the auditor's name.
+ */
+static void
+do_add_auditor (char *const *args)
+{
+ struct TALER_MasterSignatureP master_sig;
+ struct TALER_AuditorPublicKeyP auditor_pub;
+ struct GNUNET_TIME_Absolute now;
+
+ if (NULL != in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Downloaded data was not consumed, not adding auditor\n");
+ test_shutdown ();
+ global_ret = 4;
+ return;
+ }
+ if ( (NULL == args[0]) ||
+ (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &auditor_pub,
+ sizeof (auditor_pub))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "You must specify an auditor public key as first argument for this subcommand\n");
+ test_shutdown ();
+ global_ret = 5;
+ return;
+ }
+
+ if ( (NULL == args[1]) ||
+ (0 != strncmp ("http",
+ args[1],
+ strlen ("http"))) ||
+ (NULL == args[2]) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "You must specify an auditor URI and auditor name as 2nd and 3rd arguments to this subcommand\n");
+ test_shutdown ();
+ global_ret = 5;
+ return;
+ }
+ if (GNUNET_OK !=
+ load_offline_key ())
+ return;
+ now = GNUNET_TIME_absolute_get ();
+ (void) GNUNET_TIME_round_abs (&now);
+
+ TALER_exchange_offline_auditor_add_sign (&auditor_pub,
+ args[1],
+ now,
+ &master_priv,
+ &master_sig);
+ output_operation ("enable-auditor",
+ json_pack ("{s:s, s:s, s:o, s:o, s:o}",
+ "auditor_url",
+ args[1],
+ "auditor_name",
+ args[2],
+ "validity_start",
+ GNUNET_JSON_from_time_abs (now),
+ "auditor_pub",
+ GNUNET_JSON_from_data_auto (&auditor_pub),
+ "master_sig",
+ GNUNET_JSON_from_data_auto (&master_sig)));
+ next (args + 3);
+}
+
+
+/**
+ * Disable auditor account.
+ *
+ * @param args the array of command-line arguments to process next;
+ * args[0] must be the hash of the denomination key to revoke
+ */
+static void
+do_del_auditor (char *const *args)
+{
+ struct TALER_MasterSignatureP master_sig;
+ struct TALER_AuditorPublicKeyP auditor_pub;
+ struct GNUNET_TIME_Absolute now;
+
+ if (NULL != in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Downloaded data was not consumed, not deleting auditor account\n");
+ test_shutdown ();
+ global_ret = 4;
+ return;
+ }
+ if ( (NULL == args[0]) ||
+ (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &auditor_pub,
+ sizeof (auditor_pub))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "You must specify an auditor public key as first argument for this subcommand\n");
+ test_shutdown ();
+ global_ret = 5;
+ return;
+ }
+ if (GNUNET_OK !=
+ load_offline_key ())
+ return;
+ now = GNUNET_TIME_absolute_get ();
+ (void) GNUNET_TIME_round_abs (&now);
+
+ TALER_exchange_offline_auditor_del_sign (&auditor_pub,
+ now,
+ &master_priv,
+ &master_sig);
+ output_operation ("disable-auditor",
+ json_pack ("{s:o, s:o, s:o}",
+ "auditor_pub",
+ GNUNET_JSON_from_data_auto (&auditor_pub),
+ "validity_end",
+ GNUNET_JSON_from_time_abs (now),
+ "master_sig",
+ GNUNET_JSON_from_data_auto (&master_sig)));
+ next (args + 1);
+}
+
+
+/**
* Add wire account.
*
* @param args the array of command-line arguments to process next;
@@ -2590,6 +3027,18 @@ work (void *cls)
.cb = &do_revoke_signkey
},
{
+ .name = "enable-auditor",
+ .help =
+ "enable auditor for the exchange (auditor-public key, auditor-URI and auditor name must given as arguments)",
+ .cb = &do_add_auditor
+ },
+ {
+ .name = "disable-auditor",
+ .help =
+ "disable auditor at the exchange (auditor-public key must be given as argument)",
+ .cb = &do_del_auditor
+ },
+ {
.name = "enable-account",
.help =
"enable wire account of the exchange (payto-URI must be given as argument)",
diff --git a/src/exchange/taler-exchange-httpd_management_auditors.c b/src/exchange/taler-exchange-httpd_management_auditors.c
index acb8f2c58..6d700d612 100644
--- a/src/exchange/taler-exchange-httpd_management_auditors.c
+++ b/src/exchange/taler-exchange-httpd_management_auditors.c
@@ -176,32 +176,20 @@ TEH_handler_management_auditors (
if (GNUNET_NO == res)
return MHD_YES; /* failure */
}
+ if (GNUNET_OK !=
+ TALER_exchange_offline_auditor_add_verify (
+ &aac.auditor_pub,
+ aac.auditor_url,
+ aac.validity_start,
+ &TEH_master_public_key,
+ &aac.master_sig))
{
- struct TALER_MasterAddAuditorPS aa = {
- .purpose.purpose = htonl (
- TALER_SIGNATURE_MASTER_ADD_AUDITOR),
- .purpose.size = htonl (sizeof (aa)),
- .start_date = GNUNET_TIME_absolute_hton (aac.validity_start),
- .auditor_pub = aac.auditor_pub
- };
-
- GNUNET_CRYPTO_hash (aac.auditor_url,
- strlen (aac.auditor_url) + 1,
- &aa.h_auditor_url);
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_MASTER_ADD_AUDITOR,
- &aa,
- &aac.master_sig.eddsa_signature,
- &TEH_master_public_key.eddsa_pub))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (
- connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_ADD_SIGNATURE_INVALID,
- NULL);
- }
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_ADD_SIGNATURE_INVALID,
+ NULL);
}
qs = TEH_DB_run_transaction (connection,
diff --git a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
index 222af60ec..eba392a00 100644
--- a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
+++ b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
@@ -165,29 +165,19 @@ TEH_handler_management_auditors_AP_disable (
if (GNUNET_NO == res)
return MHD_YES; /* failure */
}
+ if (GNUNET_OK !=
+ TALER_exchange_offline_auditor_del_verify (
+ auditor_pub,
+ dac.validity_end,
+ &TEH_master_public_key,
+ &master_sig))
{
- struct TALER_MasterDelAuditorPS da = {
- .purpose.purpose = htonl (
- TALER_SIGNATURE_MASTER_DEL_AUDITOR),
- .purpose.size = htonl (sizeof (da)),
- .end_date = GNUNET_TIME_absolute_hton (dac.validity_end),
- .auditor_pub = *auditor_pub
- };
-
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_MASTER_DEL_AUDITOR,
- &da,
- &master_sig.eddsa_signature,
- &TEH_master_public_key.eddsa_pub))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (
- connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_DEL_SIGNATURE_INVALID,
- NULL);
- }
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_EXCHANGE_MANAGEMENT_AUDITOR_DEL_SIGNATURE_INVALID,
+ NULL);
}
qs = TEH_DB_run_transaction (connection,
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 1c77bfe64..2154479ac 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1052,6 +1052,77 @@ TALER_CRYPTO_helper_esign_disconnect (
/* ********************* offline signing ************************** */
+
+/**
+ * Create auditor addition signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param auditor_url URL of the auditor
+ * @param start_date when to enable the auditor (for replay detection)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_auditor_add_sign (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ struct GNUNET_TIME_Absolute start_date,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify auditor add signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param auditor_url URL of the auditor
+ * @param start_date when to enable the auditor (for replay detection)
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+int
+TALER_exchange_offline_auditor_add_verify (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ struct GNUNET_TIME_Absolute start_date,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create auditor deletion signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param end_date when to disable the auditor (for replay detection)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_auditor_del_sign (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Absolute end_date,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify auditor del signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param end_date when to disable the auditor (for replay detection)
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+int
+TALER_exchange_offline_auditor_del_verify (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Absolute end_date,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
/**
* Create denomination revocation signature.
*
diff --git a/src/testing/testing_api_cmd_auditor_add.c b/src/testing/testing_api_cmd_auditor_add.c
index 5acb5c1e0..2c59f4194 100644
--- a/src/testing/testing_api_cmd_auditor_add.c
+++ b/src/testing/testing_api_cmd_auditor_add.c
@@ -117,24 +117,11 @@ auditor_add_run (void *cls,
}
else
{
-
- /* now sign */
- {
- struct TALER_MasterAddAuditorPS kv = {
- .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_AUDITOR),
- .purpose.size = htonl (sizeof (kv)),
- .start_date = GNUNET_TIME_absolute_hton (now),
- .auditor_pub = is->auditor_pub,
- };
-
- GNUNET_CRYPTO_hash (is->auditor_url,
- strlen (is->auditor_url) + 1,
- &kv.h_auditor_url);
- /* Finally sign ... */
- GNUNET_CRYPTO_eddsa_sign (&is->master_priv.eddsa_priv,
- &kv,
- &master_sig.eddsa_signature);
- }
+ TALER_exchange_offline_auditor_add_sign (&is->auditor_pub,
+ is->auditor_url,
+ now,
+ &is->master_priv,
+ &master_sig);
}
ds->dh = TALER_EXCHANGE_management_enable_auditor (
is->ctx,
diff --git a/src/testing/testing_api_cmd_auditor_del.c b/src/testing/testing_api_cmd_auditor_del.c
index fd75e8268..71525a10e 100644
--- a/src/testing/testing_api_cmd_auditor_del.c
+++ b/src/testing/testing_api_cmd_auditor_del.c
@@ -117,17 +117,10 @@ auditor_del_run (void *cls,
}
else
{
- struct TALER_MasterDelAuditorPS kv = {
- .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_AUDITOR),
- .purpose.size = htonl (sizeof (kv)),
- .end_date = GNUNET_TIME_absolute_hton (now),
- .auditor_pub = is->auditor_pub,
- };
-
- /* Finally sign ... */
- GNUNET_CRYPTO_eddsa_sign (&is->master_priv.eddsa_priv,
- &kv,
- &master_sig.eddsa_signature);
+ TALER_exchange_offline_auditor_del_sign (&is->auditor_pub,
+ now,
+ &is->master_priv,
+ &master_sig);
}
ds->dh = TALER_EXCHANGE_management_disable_auditor (
is->ctx,
diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c
index be5783df4..7385f47ea 100644
--- a/src/util/offline_signatures.c
+++ b/src/util/offline_signatures.c
@@ -23,6 +23,134 @@
#include "taler_signatures.h"
+/**
+ * Create auditor addition signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param auditor_url URL of the auditor
+ * @param start_date when to enable the auditor (for replay detection)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_auditor_add_sign (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ struct GNUNET_TIME_Absolute start_date,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterAddAuditorPS kv = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_AUDITOR),
+ .purpose.size = htonl (sizeof (kv)),
+ .start_date = GNUNET_TIME_absolute_hton (start_date),
+ .auditor_pub = *auditor_pub,
+ };
+
+ GNUNET_CRYPTO_hash (auditor_url,
+ strlen (auditor_url) + 1,
+ &kv.h_auditor_url);
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &kv,
+ &master_sig->eddsa_signature);
+}
+
+
+/**
+ * Verify auditor add signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param auditor_url URL of the auditor
+ * @param start_date when to enable the auditor (for replay detection)
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+int
+TALER_exchange_offline_auditor_add_verify (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ struct GNUNET_TIME_Absolute start_date,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterAddAuditorPS aa = {
+ .purpose.purpose = htonl (
+ TALER_SIGNATURE_MASTER_ADD_AUDITOR),
+ .purpose.size = htonl (sizeof (aa)),
+ .start_date = GNUNET_TIME_absolute_hton (start_date),
+ .auditor_pub = *auditor_pub
+ };
+
+ GNUNET_CRYPTO_hash (auditor_url,
+ strlen (auditor_url) + 1,
+ &aa.h_auditor_url);
+ return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_ADD_AUDITOR,
+ &aa,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
+/**
+ * Create auditor deletion signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param end_date when to disable the auditor (for replay detection)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_auditor_del_sign (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Absolute end_date,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterDelAuditorPS kv = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_AUDITOR),
+ .purpose.size = htonl (sizeof (kv)),
+ .end_date = GNUNET_TIME_absolute_hton (end_date),
+ .auditor_pub = *auditor_pub,
+ };
+
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &kv,
+ &master_sig->eddsa_signature);
+}
+
+
+/**
+ * Verify auditor del signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param end_date when to disable the auditor (for replay detection)
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+int
+TALER_exchange_offline_auditor_del_verify (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Absolute end_date,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterDelAuditorPS da = {
+ .purpose.purpose = htonl (
+ TALER_SIGNATURE_MASTER_DEL_AUDITOR),
+ .purpose.size = htonl (sizeof (da)),
+ .end_date = GNUNET_TIME_absolute_hton (end_date),
+ .auditor_pub = *auditor_pub
+ };
+
+ return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DEL_AUDITOR,
+ &da,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
void
TALER_exchange_offline_denomination_revoke_sign (
const struct GNUNET_HashCode *h_denom_pub,