diff options
| author | Christian Grothoff <christian@grothoff.org> | 2015-09-17 14:13:41 +0200 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2015-09-17 14:13:41 +0200 | 
| commit | 690019c1758a0cdfd4a1b9ae51cbb9b26d8e5915 (patch) | |
| tree | a2529dfd9ff0fdcab64fa3bf88051c7f510697a8 | |
| parent | a8755be2b768c5896479c75f0fff5ebfe31dd34a (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.h | 103 | ||||
| -rw-r--r-- | src/mint-tools/taler-auditor-sign.c | 40 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_keystate.c | 32 | ||||
| -rw-r--r-- | src/mintdb/mintdb_keyio.c | 201 | 
4 files changed, 333 insertions, 43 deletions
| diff --git a/src/include/taler_mintdb_lib.h b/src/include/taler_mintdb_lib.h index 24f67761..b7f28cff 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 47ada94e..8d180790 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 ec09ab44..dfe78e80 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 7cf77558..b7cdcf50 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 */ | 
