aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-09-17 14:13:41 +0200
committerChristian Grothoff <christian@grothoff.org>2015-09-17 14:13:41 +0200
commit690019c1758a0cdfd4a1b9ae51cbb9b26d8e5915 (patch)
treea2529dfd9ff0fdcab64fa3bf88051c7f510697a8
parenta8755be2b768c5896479c75f0fff5ebfe31dd34a (diff)
implement mintdb API for mint to read auditor keys from disk -- and form auditor-sign tool to write them in the right format
-rw-r--r--src/include/taler_mintdb_lib.h103
-rw-r--r--src/mint-tools/taler-auditor-sign.c40
-rw-r--r--src/mint/taler-mint-httpd_keystate.c32
-rw-r--r--src/mintdb/mintdb_keyio.c201
4 files changed, 333 insertions, 43 deletions
diff --git a/src/include/taler_mintdb_lib.h b/src/include/taler_mintdb_lib.h
index 24f677617..b7f28cffe 100644
--- a/src/include/taler_mintdb_lib.h
+++ b/src/include/taler_mintdb_lib.h
@@ -37,6 +37,12 @@
*/
#define TALER_MINTDB_DIR_DENOMINATION_KEYS "denomkeys"
+/**
+ * Subdirectory under the mint's base directory which contains
+ * the mint's auditing information.
+ */
+#define TALER_MINTDB_DIR_AUDITORS "auditors"
+
GNUNET_NETWORK_STRUCT_BEGIN
@@ -62,7 +68,7 @@ struct TALER_MINTDB_PrivateSigningKeyInformationP
/**
* Information about a denomination key.
- */
+ */
struct TALER_MINTDB_DenominationKeyInformationP
{
@@ -124,23 +130,6 @@ typedef int
/**
- * @brief Iterator over denomination keys.
- *
- * @param cls closure
- * @param dki the denomination key
- * @param alias coin alias
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-typedef int
-(*TALER_MINTDB_DenominationKeyIterator)(void *cls,
- const char *alias,
- const struct TALER_MINTDB_DenominationKeyIssueInformation *dki);
-
-
-
-/**
* Call @a it for each signing key found in the @a mint_base_dir.
*
* @param mint_base_dir base directory for the mint,
@@ -158,6 +147,23 @@ TALER_MINTDB_signing_keys_iterate (const char *mint_base_dir,
void *it_cls);
+
+/**
+ * @brief Iterator over denomination keys.
+ *
+ * @param cls closure
+ * @param dki the denomination key
+ * @param alias coin alias
+ * @return #GNUNET_OK to continue to iterate,
+ * #GNUNET_NO to stop iteration with no error,
+ * #GNUNET_SYSERR to abort iteration with error!
+ */
+typedef int
+(*TALER_MINTDB_DenominationKeyIterator)(void *cls,
+ const char *alias,
+ const struct TALER_MINTDB_DenominationKeyIssueInformation *dki);
+
+
/**
* Call @a it for each denomination key found in the @a mint_base_dir.
*
@@ -202,6 +208,67 @@ TALER_MINTDB_denomination_key_read (const char *filename,
/**
+ * @brief Iterator over auditor information.
+ *
+ * @param cls closure
+ * @param apub the auditor's public key
+ * @param asig the auditor's signature
+ * @param mpub the mint's public key (as expected by the auditor)
+ * @param dki_len length of @a dki
+ * @param dki array of denomination coin data signed by the auditor
+ * @return #GNUNET_OK to continue to iterate,
+ * #GNUNET_NO to stop iteration with no error,
+ * #GNUNET_SYSERR to abort iteration with error!
+ */
+typedef int
+(*TALER_MINTDB_AuditorIterator)(void *cls,
+ const struct TALER_AuditorPublicKeyP *apub,
+ const struct TALER_AuditorSignatureP *asig,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_DenominationKeyValidityPS *dki);
+
+
+/**
+ * Call @a it with information for each auditor found in the @a mint_base_dir.
+ *
+ * @param mint_base_dir base directory for the mint,
+ * the signing keys must be in the #TALER_MINTDB_DIR_DENOMINATION_KEYS
+ * subdirectory
+ * @param it function to call with auditor information
+ * @param it_cls closure for @a it
+ * @return -1 on error, 0 if no files were found, otherwise
+ * a positive number (however, even with a positive
+ * number it is possible that @a it was never called
+ * as maybe none of the files were well-formed)
+ */
+int
+TALER_MINTDB_auditor_iterate (const char *mint_base_dir,
+ TALER_MINTDB_AuditorIterator it,
+ void *it_cls);
+
+
+/**
+ * Write auditor information to the given file.
+ *
+ * @param filename the file where to write the auditor information to
+ * @param apub the auditor's public key
+ * @param asig the auditor's signature
+ * @param mpub the mint's public key (as expected by the auditor)
+ * @param dki_len length of @a dki
+ * @param dki array of denomination coin data signed by the auditor
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
+ */
+int
+TALER_MINTDB_auditor_write (const char *filename,
+ const struct TALER_AuditorPublicKeyP *apub,
+ const struct TALER_AuditorSignatureP *asig,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_DenominationKeyValidityPS *dki);
+
+
+/**
* Initialize the plugin.
*
* @param cfg configuration to use
diff --git a/src/mint-tools/taler-auditor-sign.c b/src/mint-tools/taler-auditor-sign.c
index 47ada94ed..8d180790f 100644
--- a/src/mint-tools/taler-auditor-sign.c
+++ b/src/mint-tools/taler-auditor-sign.c
@@ -151,9 +151,10 @@ main (int argc,
};
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
struct TALER_AuditorSignatureP sig;
+ struct TALER_AuditorPublicKeyP apub;
struct GNUNET_DISK_FileHandle *fh;
- struct GNUNET_DISK_FileHandle *fout;
struct TALER_DenominationKeyValidityPS *dks;
+ unsigned int dks_len;
struct TALER_MintKeyValidityPS *ap;
off_t in_size;
unsigned int i;
@@ -180,6 +181,8 @@ main (int argc,
auditor_key_file);
return 1;
}
+ GNUNET_CRYPTO_eddsa_key_get_public (eddsa_priv,
+ &apub.eddsa_pub);
if (NULL == mint_public_key)
{
fprintf (stderr,
@@ -233,6 +236,7 @@ main (int argc,
GNUNET_DISK_file_close (fh);
return 1;
}
+ dks_len = in_size / sizeof (struct TALER_DenominationKeyValidityPS);
ap = GNUNET_malloc (sizeof (struct TALER_MintKeyValidityPS) +
in_size);
ap.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_MINT_KEYS);
@@ -256,7 +260,7 @@ main (int argc,
GNUNET_DISK_file_close (fh);
if (verbose)
{
- for (i=0;i<in_size / sizeof (struct TALER_DenominationKeyValidityPS);i++)
+ for (i=0;i<dks_len;i++)
print_dk (&dks[i]);
}
@@ -267,43 +271,29 @@ main (int argc,
GNUNET_free (ap);
return 1;
}
- fout = GNUNET_DISK_file_open (output_file,
- GNUNET_DISK_OPEN_READ |
- GNUNET_DISK_OPEN_TRUNCATE |
- GNUNET_DISK_OPEN_CREATE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE |
- GNUNET_DISK_PERM_GROUP_READ |
- GNUNET_DISK_PERM_OTHER_READ);
- if (NULL == fout)
- {
- fprintf (stderr,
- "Failed to open file `%s': %s\n",
- output_file,
- STRERROR (errno));
- GNUNET_free (ap);
- return 1;
- }
/* Finally sign ... */
GNUNET_CRYPTO_eddsa_sign (eddsa_priv,
&ap->purpose,
&sig.eddsa_sig);
- if (sizeof (struct TALER_AuditorSignatureP) !=
- GNUNET_DISK_file_write (out,
- &sig,
- sizeof (sig)))
+
+ /* write result to disk */
+ if (GNUNET_OK !=
+ TALER_MINTDB_auditor_write (output_file,
+ &apub,
+ &sig,
+ &master_public_key,
+ dks_len,
+ dks))
{
fprintf (stderr,
"Failed to write to file `%s': %s\n",
output_file,
STRERROR (errno));
GNUNET_free (ap);
- GNUNET_DISK_file_close (output_file);
return 1;
}
GNUNET_free (ap);
- GNUNET_DISK_file_close (out);
GNUNET_free (eddsa_priv);
return 0;
}
diff --git a/src/mint/taler-mint-httpd_keystate.c b/src/mint/taler-mint-httpd_keystate.c
index ec09ab441..dfe78e807 100644
--- a/src/mint/taler-mint-httpd_keystate.c
+++ b/src/mint/taler-mint-httpd_keystate.c
@@ -408,6 +408,35 @@ reload_keys_sign_iter (void *cls,
/**
+ * @brief Iterator called with auditor information.
+ * Check that the @a mpub actually matches this mint, and then
+ * add the auditor information to our /keys response (if it is
+ * (still) applicable).
+ *
+ * @param cls closure
+ * @param apub the auditor's public key
+ * @param asig the auditor's signature
+ * @param mpub the mint's public key (as expected by the auditor)
+ * @param dki_len length of @a dki
+ * @param dki array of denomination coin data signed by the auditor
+ * @return #GNUNET_OK to continue to iterate,
+ * #GNUNET_NO to stop iteration with no error,
+ * #GNUNET_SYSERR to abort iteration with error!
+ */
+static int
+reload_auditor_iter (void *cls,
+ const struct TALER_AuditorPublicKeyP *apub,
+ const struct TALER_AuditorSignatureP *asig,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_DenominationKeyValidityPS *dki)
+{
+ GNUNET_break (0); // FIXME: not implemented: #3847
+ return GNUNET_SYSERR;
+}
+
+
+/**
* Iterator for freeing denomination keys.
*
* @param cls closure with the `struct TMH_KS_StateHandle`
@@ -526,6 +555,9 @@ TMH_KS_acquire (void)
TALER_MINTDB_signing_keys_iterate (TMH_mint_directory,
&reload_keys_sign_iter,
key_state);
+ TALER_MINTDB_auditor_iterate (TMH_mint_directory,
+ &reload_auditor_iter,
+ key_state);
ks.purpose.size = htonl (sizeof (ks));
ks.purpose.purpose = htonl (TALER_SIGNATURE_MINT_KEY_SET);
ks.list_issue_date = GNUNET_TIME_absolute_hton (key_state->reload_time);
diff --git a/src/mintdb/mintdb_keyio.c b/src/mintdb/mintdb_keyio.c
index 7cf77558b..b7cdcf506 100644
--- a/src/mintdb/mintdb_keyio.c
+++ b/src/mintdb/mintdb_keyio.c
@@ -351,4 +351,205 @@ TALER_MINTDB_denomination_keys_iterate (const char *mint_base_dir,
}
+/**
+ * Closure for #auditor_iter() and
+ */
+struct AuditorIterateContext
+{
+
+ /**
+ * Function to call with the information for each auditor.
+ */
+ TALER_MINTDB_AuditorIterator it;
+
+ /**
+ * Closure for @e it.
+ */
+ void *it_cls;
+};
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Header of a file with auditing information.
+ */
+struct AuditorFileHeaderP
+{
+
+ /**
+ * Public key of the auditor.
+ */
+ struct TALER_AuditorPublicKeyP apub;
+
+ /**
+ * Signature from the auditor.
+ */
+ struct TALER_AuditorSignatureP asig;
+
+ /**
+ * Master public key of the mint the auditor is signing
+ * information for.
+ */
+ struct TALER_MasterPublicKeyP mpub;
+
+};
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Load the auditor signature and the information signed by the
+ * auditor and call the callback in @a cls with the information.
+ *
+ * @param cls the `struct AuditorIterateContext *`
+ * @param filename name of a file that should contain
+ * a denomination key
+ * @return #GNUNET_OK to continue to iterate
+ * #GNUNET_NO to abort iteration with success
+ * #GNUNET_SYSERR to abort iteration with failure
+ */
+static int
+auditor_iter (void *cls,
+ const char *filename)
+{
+ struct AuditorIterateContext *aic = cls;
+ uint64_t size;
+ struct AuditorFileHeaderP *af;
+ const struct TALER_DenominationKeyValidityPS *dki;
+ unsigned int len;
+ int ret;
+
+ if (GNUNET_OK != GNUNET_DISK_file_size (filename,
+ &size,
+ GNUNET_YES,
+ GNUNET_YES))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Skipping inaccessable auditor information file `%s'\n",
+ filename);
+ return GNUNET_SYSERR;
+ }
+ if ( (size < sizeof (struct AuditorFileHeaderP)) ||
+ (0 != (len = ((size - sizeof (struct AuditorFileHeaderP)) %
+ sizeof (struct TALER_DenominationKeyValidityPS)))) )
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ af = GNUNET_malloc (size);
+ if (size !=
+ GNUNET_DISK_fn_read (filename,
+ af,
+ size))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "read",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
+ dki = (const struct TALER_DenominationKeyValidityPS *) &af[1];
+ ret = aic->it (aic->it_cls,
+ &af->apub,
+ &af->asig,
+ &af->mpub,
+ len,
+ dki);
+ GNUNET_free (af);
+ return ret;
+}
+
+
+/**
+ * Call @a it with information for each auditor found in the @a mint_base_dir.
+ *
+ * @param mint_base_dir base directory for the mint,
+ * the signing keys must be in the #TALER_MINTDB_DIR_DENOMINATION_KEYS
+ * subdirectory
+ * @param it function to call with auditor information
+ * @param it_cls closure for @a it
+ * @return -1 on error, 0 if no files were found, otherwise
+ * a positive number (however, even with a positive
+ * number it is possible that @a it was never called
+ * as maybe none of the files were well-formed)
+ */
+int
+TALER_MINTDB_auditor_iterate (const char *mint_base_dir,
+ TALER_MINTDB_AuditorIterator it,
+ void *it_cls)
+{
+ char *dir;
+ struct AuditorIterateContext aic;
+ int ret;
+
+ GNUNET_asprintf (&dir,
+ "%s" DIR_SEPARATOR_STR TALER_MINTDB_DIR_AUDITORS,
+ mint_base_dir);
+ aic.it = it;
+ aic.it_cls = it_cls;
+ ret = GNUNET_DISK_directory_scan (dir,
+ &auditor_iter,
+ &aic);
+ GNUNET_free (dir);
+ return ret;
+}
+
+
+/**
+ * Write auditor information to the given file.
+ *
+ * @param filename the file where to write the auditor information to
+ * @param apub the auditor's public key
+ * @param asig the auditor's signature
+ * @param mpub the mint's public key (as expected by the auditor)
+ * @param dki_len length of @a dki
+ * @param dki array of denomination coin data signed by the auditor
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
+ */
+int
+TALER_MINTDB_auditor_write (const char *filename,
+ const struct TALER_AuditorPublicKeyP *apub,
+ const struct TALER_AuditorSignatureP *asig,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_DenominationKeyValidityPS *dki)
+{
+ struct AuditorFileHeaderP af;
+ struct GNUNET_DISK_FileHandle *fh;
+ ssize_t wrote;
+ size_t wsize;
+ int ret;
+ int eno;
+
+ af.apub = *apub;
+ af.asig = *asig;
+ af.mpub = *mpub;
+ ret = GNUNET_SYSERR;
+ if (NULL == (fh = GNUNET_DISK_file_open
+ (filename,
+ GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
+ GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
+ goto cleanup;
+ wsize = sizeof (struct AuditorFileHeaderP);
+ if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
+ &af,
+ wsize)))
+ goto cleanup;
+ if (wrote != wsize)
+ goto cleanup;
+ wsize = dki_len * sizeof (struct TALER_DenominationKeyValidityPS);
+ if (wsize ==
+ GNUNET_DISK_file_write (fh,
+ dki,
+ wsize))
+ ret = GNUNET_OK;
+ cleanup:
+ eno = errno;
+ if (NULL != fh)
+ (void) GNUNET_DISK_file_close (fh);
+ errno = eno;
+ return ret;
+}
+
+
/* end of mintdb_keyio.c */