aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-03-21 01:45:53 +0100
committerChristian Grothoff <christian@grothoff.org>2016-03-21 01:45:53 +0100
commit6f8fa678c1f4672165cd82ddb43ec3546d9552a9 (patch)
tree71b8948519f4b94d087f098393c49a523d96b8fc /src
parent737e3f4bf67a2048381785328206c595bffe632a (diff)
implementing #3987
Diffstat (limited to 'src')
-rw-r--r--src/exchange-lib/exchange_api_handle.c12
-rw-r--r--src/exchange-tools/taler-auditor-sign.c31
-rw-r--r--src/exchange/taler-exchange-httpd_keystate.c10
-rw-r--r--src/exchangedb/exchangedb_keyio.c92
-rw-r--r--src/include/taler_exchange_service.h20
-rw-r--r--src/include/taler_exchangedb_lib.h51
-rw-r--r--src/include/taler_signatures.h7
7 files changed, 155 insertions, 68 deletions
diff --git a/src/exchange-lib/exchange_api_handle.c b/src/exchange-lib/exchange_api_handle.c
index aaca8bac1..26f5e7e15 100644
--- a/src/exchange-lib/exchange_api_handle.c
+++ b/src/exchange-lib/exchange_api_handle.c
@@ -360,16 +360,18 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
unsigned int len;
unsigned int off;
unsigned int i;
+ const char *auditor_url;
struct TALER_ExchangeKeyValidityPS kv;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("auditor_pub",
- &auditor->auditor_pub),
+ &auditor->auditor_pub),
+ GNUNET_JSON_spec_string ("auditor_url",
+ &auditor_url),
GNUNET_JSON_spec_json ("denomination_keys",
- &keys),
+ &keys),
GNUNET_JSON_spec_end()
};
- auditor->auditor_url = NULL; /* #3987 */
if (GNUNET_OK !=
GNUNET_JSON_parse (auditor_obj,
spec,
@@ -378,8 +380,12 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
+ auditor->auditor_url = GNUNET_strdup (auditor_url);
kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS);
kv.purpose.size = htonl (sizeof (struct TALER_ExchangeKeyValidityPS));
+ GNUNET_CRYPTO_hash (auditor_url,
+ strlen (auditor_url) + 1,
+ &kv.auditor_url_hash);
kv.master = key_data->master_pub;
len = json_array_size (keys);
auditor->denom_keys = GNUNET_new_array (len,
diff --git a/src/exchange-tools/taler-auditor-sign.c b/src/exchange-tools/taler-auditor-sign.c
index e4821f411..bde34b2a3 100644
--- a/src/exchange-tools/taler-auditor-sign.c
+++ b/src/exchange-tools/taler-auditor-sign.c
@@ -50,6 +50,11 @@ static char *exchange_request_file;
static char *output_file;
/**
+ * URL of the auditor (informative for the user).
+ */
+static char *auditor_url;
+
+/**
* Master public key of the exchange.
*/
static struct TALER_MasterPublicKeyP master_public_key;
@@ -134,6 +139,10 @@ main (int argc,
{'m', "exchange-key", "KEY",
"public key of the exchange (Crockford base32 encoded)", 1,
&GNUNET_GETOPT_set_filename, &exchange_public_key},
+ {'u', "auditor-url", "URL",
+ "URL of the auditor (informative link for the user)", 1,
+ &GNUNET_GETOPT_set_string, &auditor_url},
+ TALER_GETOPT_OPTION_HELP ("Private key of the auditor to use for signing"),
{'r', "exchange-request", "FILE",
"set of keys the exchange requested the auditor to sign", 1,
&GNUNET_GETOPT_set_string, &exchange_request_file},
@@ -168,6 +177,12 @@ main (int argc,
"Auditor key file not given\n");
return 1;
}
+ if (NULL == auditor_url)
+ {
+ fprintf (stderr,
+ "Auditor URL not given\n");
+ return 1;
+ }
eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (auditor_key_file);
if (NULL == eddsa_priv)
{
@@ -240,6 +255,9 @@ main (int argc,
dks_len = in_size / sizeof (struct TALER_DenominationKeyValidityPS);
kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS);
kv.purpose.size = htonl (sizeof (struct TALER_ExchangeKeyValidityPS));
+ GNUNET_CRYPTO_hash (auditor_url,
+ strlen (auditor_url) + 1,
+ &kv.auditor_url_hash);
kv.master = master_public_key;
dks = GNUNET_new_array (dks_len,
struct TALER_DenominationKeyValidityPS);
@@ -281,8 +299,6 @@ main (int argc,
GNUNET_CRYPTO_eddsa_sign (eddsa_priv,
&kv.purpose,
&sigs[i].eddsa_sig);
-
-
}
if (NULL == output_file)
@@ -298,11 +314,12 @@ main (int argc,
/* write result to disk */
if (GNUNET_OK !=
TALER_EXCHANGEDB_auditor_write (output_file,
- &apub,
- sigs,
- &master_public_key,
- dks_len,
- dks))
+ &apub,
+ auditor_url,
+ sigs,
+ &master_public_key,
+ dks_len,
+ dks))
{
fprintf (stderr,
"Failed to write to file `%s': %s\n",
diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c
index bf91b8183..dbb72fab2 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -419,6 +419,7 @@ reload_keys_sign_iter (void *cls,
* Convert information from an auditor to a JSON object.
*
* @param apub the auditor's public key
+ * @param auditor_url URL of the auditor
* @param dki_len length of @a dki and @a asigs arrays
* @param asigs the auditor's signatures
* @param dki array of denomination coin data signed by the auditor
@@ -426,6 +427,7 @@ reload_keys_sign_iter (void *cls,
*/
static json_t *
auditor_to_json (const struct TALER_AuditorPublicKeyP *apub,
+ const char *auditor_url,
unsigned int dki_len,
const struct TALER_AuditorSignatureP **asigs,
const struct TALER_DenominationKeyValidityPS **dki)
@@ -442,10 +444,11 @@ auditor_to_json (const struct TALER_AuditorPublicKeyP *apub,
sizeof (struct GNUNET_HashCode)),
"auditor_sig",
GNUNET_JSON_from_data (asigs[i],
- sizeof (struct TALER_AuditorSignatureP))));
+ sizeof (struct TALER_AuditorSignatureP))));
return
- json_pack ("{s:o, s:o}",
+ json_pack ("{s:o, s:s, s:o}",
"denomination_keys", ja,
+ "auditor_url", auditor_url,
"auditor_pub",
GNUNET_JSON_from_data (apub,
sizeof (struct TALER_AuditorPublicKeyP)));
@@ -460,6 +463,7 @@ auditor_to_json (const struct TALER_AuditorPublicKeyP *apub,
*
* @param cls closure with the `struct TMH_KS_StateHandle *`
* @param apub the auditor's public key
+ * @param auditor_url URL of the auditor
* @param mpub the exchange's public key (as expected by the auditor)
* @param dki_len length of @a dki and @a asigs
* @param asigs array with the auditor's signatures, of length @a dki_len
@@ -471,6 +475,7 @@ auditor_to_json (const struct TALER_AuditorPublicKeyP *apub,
static int
reload_auditor_iter (void *cls,
const struct TALER_AuditorPublicKeyP *apub,
+ const char *auditor_url,
const struct TALER_MasterPublicKeyP *mpub,
unsigned int dki_len,
const struct TALER_AuditorSignatureP *asigs,
@@ -508,6 +513,7 @@ reload_auditor_iter (void *cls,
/* add auditor information to our /keys response */
json_array_append_new (ctx->auditors_array,
auditor_to_json (apub,
+ auditor_url,
keep,
kept_asigs,
kept_dkis));
diff --git a/src/exchangedb/exchangedb_keyio.c b/src/exchangedb/exchangedb_keyio.c
index 6b8ca24e3..e560e8d6b 100644
--- a/src/exchangedb/exchangedb_keyio.c
+++ b/src/exchangedb/exchangedb_keyio.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
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
@@ -93,8 +93,8 @@ signkeys_iterate_dir_iter (void *cls,
*/
int
TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_SigningKeyIterator it,
- void *it_cls)
+ TALER_EXCHANGEDB_SigningKeyIterator it,
+ void *it_cls)
{
char *signkey_dir;
struct SignkeysIterateContext skc;
@@ -123,7 +123,7 @@ TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
*/
int
TALER_EXCHANGEDB_denomination_key_read (const char *filename,
- struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
+ struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
{
uint64_t size;
size_t offset;
@@ -186,7 +186,7 @@ TALER_EXCHANGEDB_denomination_key_read (const char *filename,
*/
int
TALER_EXCHANGEDB_denomination_key_write (const char *filename,
- const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
+ const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
{
char *priv_enc;
size_t priv_enc_size;
@@ -331,8 +331,8 @@ denomkeys_iterate_topdir_iter (void *cls,
*/
int
TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_DenominationKeyIterator it,
- void *it_cls)
+ TALER_EXCHANGEDB_DenominationKeyIterator it,
+ void *it_cls)
{
char *dir;
struct DenomkeysIterateContext dic;
@@ -388,6 +388,11 @@ struct AuditorFileHeaderP
*/
struct TALER_MasterPublicKeyP mpub;
+ /**
+ * Number of signatures and DKI entries in this file.
+ */
+ uint32_t dki_len;
+
};
GNUNET_NETWORK_STRUCT_END
@@ -412,7 +417,9 @@ auditor_iter (void *cls,
struct AuditorFileHeaderP *af;
const struct TALER_AuditorSignatureP *sigs;
const struct TALER_DenominationKeyValidityPS *dki;
- unsigned int len;
+ const char *auditor_url;
+ unsigned int dki_len;
+ size_t url_len;
int ret;
if (GNUNET_OK != GNUNET_DISK_file_size (filename,
@@ -425,10 +432,7 @@ auditor_iter (void *cls,
filename);
return GNUNET_SYSERR;
}
- if ( (size < sizeof (struct AuditorFileHeaderP)) ||
- (0 != (len = ((size - sizeof (struct AuditorFileHeaderP)) %
- (sizeof (struct TALER_DenominationKeyValidityPS) +
- sizeof (struct TALER_AuditorSignatureP))))) )
+ if (size < sizeof (struct AuditorFileHeaderP))
{
GNUNET_break (0);
return GNUNET_SYSERR;
@@ -445,12 +449,49 @@ auditor_iter (void *cls,
GNUNET_free (af);
return GNUNET_SYSERR;
}
+ dki_len = ntohl (af->dki_len);
+ if (0 == dki_len)
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "No signed keys in %s\n",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
+ if ( (size - sizeof (struct AuditorFileHeaderP)) / dki_len <
+ (sizeof (struct TALER_DenominationKeyValidityPS) +
+ sizeof (struct TALER_AuditorSignatureP)) )
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Malformed key file %s\n",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
+ url_len = size
+ - sizeof (struct AuditorFileHeaderP)
+ - dki_len * (sizeof (struct TALER_DenominationKeyValidityPS) +
+ sizeof (struct TALER_AuditorSignatureP));
sigs = (const struct TALER_AuditorSignatureP *) &af[1];
- dki = (const struct TALER_DenominationKeyValidityPS *) &sigs[len];
+ dki = (const struct TALER_DenominationKeyValidityPS *) &sigs[dki_len];
+ auditor_url = (const char *) &dki[dki_len];
+ if ( (0 == url_len) ||
+ ('\0' != auditor_url[url_len - 1]) )
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Malformed key file %s\n",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
ret = aic->it (aic->it_cls,
&af->apub,
+ auditor_url,
&af->mpub,
- len,
+ dki_len,
sigs,
dki);
GNUNET_free (af);
@@ -473,8 +514,8 @@ auditor_iter (void *cls,
*/
int
TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_AuditorIterator it,
- void *it_cls)
+ TALER_EXCHANGEDB_AuditorIterator it,
+ void *it_cls)
{
char *dir;
struct AuditorIterateContext aic;
@@ -498,6 +539,7 @@ TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir,
*
* @param filename the file where to write the auditor information to
* @param apub the auditor's public key
+ * @param auditor_url the URL of the auditor
* @param asigs the auditor's signatures, array of length @a dki_len
* @param mpub the exchange's public key (as expected by the auditor)
* @param dki_len length of @a dki
@@ -506,11 +548,12 @@ TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir,
*/
int
TALER_EXCHANGEDB_auditor_write (const char *filename,
- const struct TALER_AuditorPublicKeyP *apub,
- const struct TALER_AuditorSignatureP *asigs,
- const struct TALER_MasterPublicKeyP *mpub,
- unsigned int dki_len,
- const struct TALER_DenominationKeyValidityPS *dki)
+ const struct TALER_AuditorPublicKeyP *apub,
+ const char *auditor_url,
+ const struct TALER_AuditorSignatureP *asigs,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_DenominationKeyValidityPS *dki)
{
struct AuditorFileHeaderP af;
struct GNUNET_DISK_FileHandle *fh;
@@ -521,6 +564,7 @@ TALER_EXCHANGEDB_auditor_write (const char *filename,
af.apub = *apub;
af.mpub = *mpub;
+ af.dki_len = htonl ((uint32_t) dki_len);
ret = GNUNET_SYSERR;
if (NULL == (fh = GNUNET_DISK_file_open
(filename,
@@ -546,6 +590,12 @@ TALER_EXCHANGEDB_auditor_write (const char *filename,
dki,
wsize))
ret = GNUNET_OK;
+ wsize = strlen (auditor_url) + 1;
+ if (wsize ==
+ GNUNET_DISK_file_write (fh,
+ auditor_url,
+ wsize))
+ ret = GNUNET_OK;
cleanup:
eno = errno;
if (NULL != fh)
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index c3ecba968..cb1bd12aa 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -208,19 +208,19 @@ struct TALER_EXCHANGE_DenomPublicKey
struct TALER_EXCHANGE_AuditorInformation
{
/**
- * Public key of the auditing institution.
+ * Public key of the auditing institution. Wallets and merchants
+ * are expected to be configured with a set of public keys of
+ * auditors that they deem acceptable. These public keys are
+ * the roots of the Taler PKI.
*/
struct TALER_AuditorPublicKeyP auditor_pub;
/**
- * URL of the auditing institution. The application must check that
- * this is an acceptable auditor for its purpose and also verify
- * that the @a auditor_pub matches the auditor's public key given at
- * that website. We expect that in practice software is going to
- * often ship with an initial list of accepted auditors, just like
- * browsers ship with a CA root store.
- *
- * This field may be NULL. (#3987).
+ * URL of the auditing institution. Signed by the auditor's public
+ * key, this URL is a place where applications can direct users for
+ * additional information about the auditor. In the future, there
+ * should also be an auditor API for automated submission about
+ * claims of misbehaving exchange providers.
*/
const char *auditor_url;
@@ -230,7 +230,7 @@ struct TALER_EXCHANGE_AuditorInformation
unsigned int num_denom_keys;
/**
- * Array of length @a denom_keys with the denomination
+ * Array of length @a num_denom_keys with the denomination
* keys audited by this auditor. Note that the array
* elements point to the same locations as the entries
* in the key's main `denom_keys` array.
diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h
index 347ad0650..e13df2d46 100644
--- a/src/include/taler_exchangedb_lib.h
+++ b/src/include/taler_exchangedb_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
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
@@ -125,8 +125,8 @@ struct TALER_EXCHANGEDB_DenominationKeyIssueInformation
*/
typedef int
(*TALER_EXCHANGEDB_SigningKeyIterator)(void *cls,
- const char *filename,
- const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski);
+ const char *filename,
+ const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski);
/**
@@ -143,8 +143,8 @@ typedef int
*/
int
TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_SigningKeyIterator it,
- void *it_cls);
+ TALER_EXCHANGEDB_SigningKeyIterator it,
+ void *it_cls);
@@ -160,8 +160,8 @@ TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
*/
typedef int
(*TALER_EXCHANGEDB_DenominationKeyIterator)(void *cls,
- const char *alias,
- const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki);
+ const char *alias,
+ const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki);
/**
@@ -179,8 +179,8 @@ typedef int
*/
int
TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_DenominationKeyIterator it,
- void *it_cls);
+ TALER_EXCHANGEDB_DenominationKeyIterator it,
+ void *it_cls);
/**
@@ -192,7 +192,7 @@ TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
*/
int
TALER_EXCHANGEDB_denomination_key_write (const char *filename,
- const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki);
+ const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki);
/**
@@ -204,7 +204,7 @@ TALER_EXCHANGEDB_denomination_key_write (const char *filename,
*/
int
TALER_EXCHANGEDB_denomination_key_read (const char *filename,
- struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki);
+ struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki);
/**
@@ -212,6 +212,7 @@ TALER_EXCHANGEDB_denomination_key_read (const char *filename,
*
* @param cls closure
* @param apub the auditor's public key
+ * @param auditor_url URL of the auditor
* @param mpub the exchange's public key (as expected by the auditor)
* @param dki_len length of @a asig and @a dki arrays
* @param asigs array of the auditor's signatures over the @a dks, of length @a dki_len
@@ -222,11 +223,12 @@ TALER_EXCHANGEDB_denomination_key_read (const char *filename,
*/
typedef int
(*TALER_EXCHANGEDB_AuditorIterator)(void *cls,
- const struct TALER_AuditorPublicKeyP *apub,
- const struct TALER_MasterPublicKeyP *mpub,
- unsigned int dki_len,
- const struct TALER_AuditorSignatureP *asigs,
- const struct TALER_DenominationKeyValidityPS *dki);
+ const struct TALER_AuditorPublicKeyP *apub,
+ const char *auditor_url,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_AuditorSignatureP *asigs,
+ const struct TALER_DenominationKeyValidityPS *dki);
/**
@@ -244,8 +246,8 @@ typedef int
*/
int
TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_AuditorIterator it,
- void *it_cls);
+ TALER_EXCHANGEDB_AuditorIterator it,
+ void *it_cls);
/**
@@ -253,6 +255,7 @@ TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir,
*
* @param filename the file where to write the auditor information to
* @param apub the auditor's public key
+ * @param auditor_url the URL of the auditor
* @param asigs the auditor's signatures, array of length @a dki_len
* @param mpub the exchange's public key (as expected by the auditor)
* @param dki_len length of @a dki and @a asigs arrays
@@ -261,11 +264,12 @@ TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir,
*/
int
TALER_EXCHANGEDB_auditor_write (const char *filename,
- const struct TALER_AuditorPublicKeyP *apub,
- const struct TALER_AuditorSignatureP *asigs,
- const struct TALER_MasterPublicKeyP *mpub,
- unsigned int dki_len,
- const struct TALER_DenominationKeyValidityPS *dki);
+ const struct TALER_AuditorPublicKeyP *apub,
+ const char *auditor_url,
+ const struct TALER_AuditorSignatureP *asigs,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_DenominationKeyValidityPS *dki);
/**
@@ -287,5 +291,4 @@ void
TALER_EXCHANGEDB_plugin_unload (struct TALER_EXCHANGEDB_Plugin *plugin);
-
#endif
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 729bed262..d958f16ba 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -656,8 +656,13 @@ struct TALER_ExchangeKeyValidityPS
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
+ * Hash of the auditor's URL.
+ */
+ struct GNUNET_HashCode auditor_url_hash;
+
+ /**
* The long-term offline master key of the exchange, affirmed by the
- * auditor.
+ * auditor. Hashed string, including 0-terminator.
*/
struct TALER_MasterPublicKeyP master;