aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb/exchangedb_denomkeys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb/exchangedb_denomkeys.c')
-rw-r--r--src/exchangedb/exchangedb_denomkeys.c518
1 files changed, 0 insertions, 518 deletions
diff --git a/src/exchangedb/exchangedb_denomkeys.c b/src/exchangedb/exchangedb_denomkeys.c
deleted file mode 100644
index 81828aaee..000000000
--- a/src/exchangedb/exchangedb_denomkeys.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2019 Taler Systems SA
-
- 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file exchangedb/exchangedb_denomkeys.c
- * @brief I/O operations for the Exchange's denomination private keys
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Sree Harsha Totakura
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_crypto_lib.h"
-#include "taler_exchangedb_lib.h"
-
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-/**
- * Contents of a file with a revocation certificate.
- */
-struct RevocationFileP
-{
-
- /**
- * Hash of the denomination public key being revoked.
- */
- struct GNUNET_HashCode denom_hash;
-
- /**
- * Master signature over the revocation, must match purpose
- * #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED.
- */
- struct TALER_MasterSignatureP msig;
-};
-
-GNUNET_NETWORK_STRUCT_END
-
-
-/**
- * Mark the given denomination key as revoked and request the wallets
- * to initiate /recoup.
- *
- * @param revocation_dir where to write the revocation certificate
- * @param denom_hash hash of the denomination key to revoke
- * @param mpriv master private key to sign with
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_denomination_key_revoke (
- const char *revocation_dir,
- const struct GNUNET_HashCode *denom_hash,
- const struct TALER_MasterPrivateKeyP *mpriv)
-{
- char *fn;
- int ret;
- struct RevocationFileP rd;
-
- TALER_exchange_offline_denomination_revoke_sign (denom_hash,
- mpriv,
- &rd.msig);
- GNUNET_asprintf (&fn,
- "%s" DIR_SEPARATOR_STR
- "%s.rev",
- revocation_dir,
- GNUNET_h2s_full (denom_hash));
- rd.denom_hash = *denom_hash;
- ret = (sizeof (rd) !=
- GNUNET_DISK_fn_write (fn,
- &rd,
- sizeof (rd),
- GNUNET_DISK_PERM_USER_READ
- | GNUNET_DISK_PERM_USER_WRITE))
- ? GNUNET_SYSERR
- : GNUNET_OK;
- GNUNET_free (fn);
- return ret;
-}
-
-
-/**
- * Import a denomination key from the given file.
- *
- * @param filename the file to import the key from
- * @param[out] dki set to the imported denomination key
- * @return #GNUNET_OK upon success;
- * #GNUNET_SYSERR upon failure
- */
-int
-TALER_EXCHANGEDB_denomination_key_read (
- const char *filename,
- struct TALER_EXCHANGEDB_DenominationKey *dki)
-{
- uint64_t size;
- size_t offset;
- void *data;
- struct GNUNET_CRYPTO_RsaPrivateKey *priv;
-
- if (GNUNET_OK !=
- GNUNET_DISK_file_size (filename,
- &size,
- GNUNET_YES,
- GNUNET_YES))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Skipping inaccessible denomination key file `%s'\n",
- filename);
- return GNUNET_SYSERR;
- }
- offset = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
- if (size <= offset)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "File size (%llu bytes) too small for file `%s' to contain denomination key data. Skipping it.\n",
- (unsigned long long) size,
- filename);
- return GNUNET_SYSERR;
- }
- if (size >= GNUNET_MAX_MALLOC_CHECKED)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "File size (%llu bytes) too large for file `%s' to contain denomination key data. Skipping it.\n",
- (unsigned long long) size,
- filename);
- return GNUNET_OK;
- }
- data = GNUNET_malloc (size);
- if (((ssize_t) size) !=
- GNUNET_DISK_fn_read (filename,
- data,
- size))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "read",
- filename);
- GNUNET_free (data);
- return GNUNET_SYSERR;
- }
- if (NULL ==
- (priv = GNUNET_CRYPTO_rsa_private_key_decode (data + offset,
- size - offset)))
- {
- GNUNET_free (data);
- return GNUNET_SYSERR;
- }
- GNUNET_assert (NULL == dki->denom_priv.rsa_private_key);
- dki->denom_priv.rsa_private_key = priv;
- dki->denom_pub.rsa_public_key
- = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
- memcpy (&dki->issue,
- data,
- offset);
- GNUNET_free (data);
- if (0 == GNUNET_TIME_absolute_get_remaining
- (GNUNET_TIME_absolute_ntoh
- (dki->issue.properties.expire_withdraw)).rel_value_us)
- {
- /* key expired for withdrawal, remove private key to
- minimize chance of compromise */
- if (0 != unlink (filename))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "unlink",
- filename);
- /* yes, we had an error, but the file content
- was fine and is being returned */
- return GNUNET_OK;
- }
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Exports a denomination key to the given file.
- *
- * @param filename the file where to write the denomination key
- * @param dki the denomination key
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_denomination_key_write (
- const char *filename,
- const struct TALER_EXCHANGEDB_DenominationKey *dki)
-{
- struct GNUNET_DISK_FileHandle *fh;
- ssize_t wrote;
- size_t wsize;
- int eno;
-
- if (GNUNET_OK !=
- GNUNET_DISK_directory_create_for_file (filename))
- {
- eno = errno;
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "mkdir (for file)",
- filename);
- errno = eno;
- return GNUNET_SYSERR;
- }
- if (NULL == (fh = GNUNET_DISK_file_open
- (filename,
- GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE
- | GNUNET_DISK_OPEN_TRUNCATE
- | GNUNET_DISK_OPEN_FAILIFEXISTS,
- GNUNET_DISK_PERM_USER_READ
- | GNUNET_DISK_PERM_USER_WRITE)))
- {
- eno = errno;
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- filename);
- errno = eno;
- return GNUNET_SYSERR;
- }
- wsize = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
- if ( (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
- &dki->issue,
- wsize))) ||
- (wrote != (ssize_t) wsize) )
- goto cleanup;
- {
- void *priv_enc;
- size_t priv_enc_size;
-
- priv_enc_size
- = GNUNET_CRYPTO_rsa_private_key_encode (dki->denom_priv.rsa_private_key,
- &priv_enc);
- wrote = GNUNET_DISK_file_write (fh,
- priv_enc,
- priv_enc_size);
- GNUNET_free (priv_enc);
- if ( (GNUNET_SYSERR == wrote) ||
- (wrote != (ssize_t) priv_enc_size) )
- goto cleanup;
- }
- GNUNET_assert (GNUNET_OK ==
- GNUNET_DISK_file_close (fh));
- return GNUNET_OK;
-
-cleanup:
- eno = errno;
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "write",
- filename);
- GNUNET_break (GNUNET_OK ==
- GNUNET_DISK_file_close (fh));
- /* try to remove the file, as it must be malformed */
- if (0 != unlink (filename))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "unlink",
- filename);
- errno = eno;
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Closure for #denomkeys_iterate_keydir_iter() and
- * #denomkeys_iterate_topdir_iter().
- */
-struct DenomkeysIterateContext
-{
-
- /**
- * Set to the name of the directory below the top-level directory
- * during the call to #denomkeys_iterate_keydir_iter().
- */
- const char *alias;
-
- /**
- * Function to call on each denomination key.
- */
- TALER_EXCHANGEDB_DenominationKeyIterator it;
-
- /**
- * Closure for @e it.
- */
- void *it_cls;
-};
-
-
-/**
- * Decode the denomination key in the given file @a filename and call
- * the callback in @a cls with the information.
- *
- * @param cls the `struct DenomkeysIterateContext *`
- * @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
-denomkeys_iterate_keydir_iter (void *cls,
- const char *filename)
-{
- struct DenomkeysIterateContext *dic = cls;
- struct TALER_EXCHANGEDB_DenominationKey issue;
- int ret;
-
- memset (&issue, 0, sizeof (issue));
- if (GNUNET_OK !=
- TALER_EXCHANGEDB_denomination_key_read (filename,
- &issue))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid denomkey file: '%s'\n",
- filename);
- return GNUNET_OK;
- }
- ret = dic->it (dic->it_cls,
- dic->alias,
- &issue);
- GNUNET_CRYPTO_rsa_private_key_free (issue.denom_priv.rsa_private_key);
- GNUNET_CRYPTO_rsa_public_key_free (issue.denom_pub.rsa_public_key);
- return ret;
-}
-
-
-/**
- * Function called on each subdirectory in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS. Will
- * call the #denomkeys_iterate_keydir_iter() on each file in the
- * subdirectory.
- *
- * @param cls the `struct DenomkeysIterateContext *`
- * @param filename name of the subdirectory to scan
- * @return #GNUNET_OK on success,
- * #GNUNET_SYSERR if we need to abort
- */
-static int
-denomkeys_iterate_topdir_iter (void *cls,
- const char *filename)
-{
- struct DenomkeysIterateContext *dic = cls;
-
- dic->alias = GNUNET_STRINGS_get_short_name (filename);
- if (0 > GNUNET_DISK_directory_scan (filename,
- &denomkeys_iterate_keydir_iter,
- dic))
- return GNUNET_SYSERR;
- return GNUNET_OK;
-}
-
-
-/**
- * Call @a it for each denomination key found in the @a exchange_base_dir.
- *
- * @param exchange_base_dir base directory for the exchange,
- * the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
- * subdirectory
- * @param it function to call on each denomination key found
- * @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_EXCHANGEDB_denomination_keys_iterate (
- const char *exchange_base_dir,
- TALER_EXCHANGEDB_DenominationKeyIterator it,
- void *it_cls)
-{
- struct DenomkeysIterateContext dic = {
- .it = it,
- .it_cls = it_cls
- };
- char *dir;
- int ret;
-
- GNUNET_asprintf (&dir,
- "%s" DIR_SEPARATOR_STR
- TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
- exchange_base_dir);
- ret = GNUNET_DISK_directory_scan (dir,
- &denomkeys_iterate_topdir_iter,
- &dic);
- GNUNET_free (dir);
- return ret;
-}
-
-
-/**
- * Closure for #revocations_iterate_cb().
- */
-struct RevocationsIterateContext
-{
-
- /**
- * Function to call on each revoked denomination key.
- */
- TALER_EXCHANGEDB_RevocationIterator it;
-
- /**
- * Closure for @e it.
- */
- void *it_cls;
-
- /**
- * Master public key to use to validate revocations.
- */
- const struct TALER_MasterPublicKeyP *master_pub;
-
-};
-
-
-/**
- * Decode the revocation certificate in the given file @a filename and call
- * the callback in @a cls with the information.
- *
- * @param cls the `struct RevocationsIterateContext *`
- * @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
-revocations_iterate_cb (void *cls,
- const char *filename)
-{
- struct RevocationsIterateContext *ric = cls;
- struct RevocationFileP rf;
- ssize_t rd;
-
- /* Check if revocation is valid... */
- rd = GNUNET_DISK_fn_read (filename,
- &rf,
- sizeof (rf));
- if (GNUNET_SYSERR == rd)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "read",
- filename);
- return GNUNET_OK;
- }
- if (sizeof (rf) != (size_t) rd)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Invalid revocation file `%s' found and ignored (bad size: %llu)\n",
- filename,
- (unsigned long long) rd);
- return GNUNET_OK;
- }
-
- if (GNUNET_OK !=
- TALER_exchange_offline_denomination_revoke_verify (
- &rf.denom_hash,
- ric->master_pub,
- &rf.msig))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Invalid revocation file `%s' found and ignored (bad signature)\n",
- filename);
- return GNUNET_OK;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Denomination key `%s' was revoked!\n",
- GNUNET_h2s (&rf.denom_hash));
- return ric->it (ric->it_cls,
- &rf.denom_hash,
- &rf.msig);
-}
-
-
-/**
- * Call @a it for each revoked denomination key found in the @a revocation_dir.
- *
- * @param revocation_dir base directory where revocations are stored
- * @param master_pub master public key (used to check revocations)
- * @param it function to call on each revoked denomination key found
- * @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_EXCHANGEDB_revocations_iterate (const char *revocation_dir,
- const struct
- TALER_MasterPublicKeyP *master_pub,
- TALER_EXCHANGEDB_RevocationIterator it,
- void *it_cls)
-{
- struct RevocationsIterateContext ric = {
- .it = it,
- .it_cls = it_cls,
- .master_pub = master_pub
- };
-
- if (GNUNET_OK !=
- GNUNET_DISK_directory_create (revocation_dir))
- {
- /* directory doesn't exist and we couldn't even create it,
- clearly means there are no revocations there */
- return 0;
- }
- return GNUNET_DISK_directory_scan (revocation_dir,
- &revocations_iterate_cb,
- &ric);
-}
-
-
-/* end of exchangedb_denomkeys.c */