123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- // maximilian.kaul@aisec.fraunhofer.de
- // WIP implementation of
- // https://github.com/ontio/ontology-crypto/wiki/Anonymous-Credential
- // using the relic library https://github.com/relic-toolkit/relic/
- #include "pabc_helper.h"
- #include <pwd.h>
- #include <stdlib.h>
- #include <unistd.h>
- static char pabc_dir[PATH_MAX + 1];
- static const char *
- get_homedir ()
- {
- const char *homedir;
- if ((homedir = getenv ("HOME")) == NULL)
- {
- homedir = getpwuid (getuid ())->pw_dir;
- }
- return homedir;
- }
- static enum GNUNET_GenericReturnValue
- write_file (char const *const filename, const char *buffer)
- {
- struct GNUNET_DISK_FileHandle *fh;
- fh = GNUNET_DISK_file_open (filename,
- GNUNET_DISK_OPEN_WRITE
- | GNUNET_DISK_OPEN_TRUNCATE
- | GNUNET_DISK_OPEN_CREATE,
- GNUNET_DISK_PERM_USER_WRITE
- | GNUNET_DISK_PERM_USER_READ);
- if (fh == NULL)
- return GNUNET_SYSERR;
- if (GNUNET_SYSERR == GNUNET_DISK_file_write (fh,
- buffer, strlen (buffer) + 1))
- goto fail;
- GNUNET_DISK_file_close (fh);
- return GNUNET_OK;
- fail:
- GNUNET_DISK_file_close (fh);
- return GNUNET_SYSERR;
- }
- static enum GNUNET_GenericReturnValue
- init_pabc_dir ()
- {
- size_t filename_size = strlen (get_homedir ()) + 1 + strlen (".local") + 1
- + strlen ("pabc-reclaim") + 1;
- snprintf (pabc_dir, filename_size, "%s/%s/%s",
- get_homedir (), ".local", "pabc-reclaim");
- return GNUNET_DISK_directory_create (pabc_dir);
- }
- static const char *
- get_pabcdir ()
- {
- init_pabc_dir ();
- return pabc_dir;
- }
- enum GNUNET_GenericReturnValue
- read_file (char const *const filename, char **buffer)
- {
- struct GNUNET_DISK_FileHandle *fh;
- if (GNUNET_YES != GNUNET_DISK_file_test (filename))
- return GNUNET_SYSERR;
- fh = GNUNET_DISK_file_open (filename,
- GNUNET_DISK_OPEN_READ,
- GNUNET_DISK_PERM_USER_READ);
- if (fh == NULL)
- return GNUNET_SYSERR;
- long lSize = GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_END);
- if (lSize < 0)
- goto fail;
- GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET);
- *buffer = calloc ((size_t) lSize + 1, sizeof(char));
- if (*buffer == NULL)
- goto fail;
- // copy the file into the buffer:
- size_t r = GNUNET_DISK_file_read (fh, *buffer, (size_t) lSize);
- if (r != (size_t) lSize)
- goto fail;
- GNUNET_DISK_file_close (fh);
- return GNUNET_OK;
- fail:
- GNUNET_DISK_file_close (fh);
- return GNUNET_SYSERR;
- }
- struct pabc_public_parameters *
- PABC_read_issuer_ppfile (const char *f, struct pabc_context *const ctx)
- {
- if (NULL == ctx)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No global context provided\n");
- return NULL;
- }
- struct pabc_public_parameters *pp;
- char *buffer;
- int r;
- r = read_file (f, &buffer);
- if (GNUNET_OK != r)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading file\n");
- return NULL;
- }
- if (PABC_OK != pabc_decode_and_new_public_parameters (ctx, &pp, buffer))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to decode public parameters\n");
- PABC_FREE_NULL (buffer);
- return NULL;
- }
- PABC_FREE_NULL (buffer);
- return pp;
- }
- enum GNUNET_GenericReturnValue
- PABC_load_public_parameters (struct pabc_context *const ctx,
- char const *const pp_name,
- struct pabc_public_parameters **pp)
- {
- char fname[PATH_MAX];
- char *pp_filename;
- const char *pdir = get_pabcdir ();
- if (ctx == NULL)
- return GNUNET_SYSERR;
- if (pp_name == NULL)
- return GNUNET_SYSERR;
- GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
- if (GNUNET_YES != GNUNET_DISK_directory_test (pdir, GNUNET_YES))
- {
- GNUNET_free (pp_filename);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading %s\n", pdir);
- return GNUNET_SYSERR;
- }
- snprintf (fname, PATH_MAX, "%s/%s%s", pdir, pp_filename, PABC_PP_EXT);
- if (GNUNET_YES != GNUNET_DISK_file_test (fname))
- {
- GNUNET_free (pp_filename);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error testing %s\n", fname);
- return GNUNET_SYSERR;
- }
- *pp = PABC_read_issuer_ppfile (fname, ctx);
- if (*pp)
- return GNUNET_OK;
- else
- return GNUNET_SYSERR;
- }
- enum GNUNET_GenericReturnValue
- PABC_write_public_parameters (char const *const pp_name,
- struct pabc_public_parameters *const pp)
- {
- char *json;
- char *filename;
- char *pp_filename;
- enum pabc_status status;
- struct pabc_context *ctx = NULL;
- GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
- PABC_ASSERT (pabc_new_ctx (&ctx));
- // store in json file
- status = pabc_encode_public_parameters (ctx, pp, &json);
- if (status != PABC_OK)
- {
- GNUNET_free (pp_filename);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to encode public parameters.\n");
- pabc_free_ctx (&ctx);
- return GNUNET_SYSERR;
- }
- size_t filename_size =
- strlen (get_pabcdir ()) + 1 + strlen (pp_filename) + strlen (PABC_PP_EXT)
- + 1;
- filename = GNUNET_malloc (filename_size);
- if (! filename)
- {
- GNUNET_free (pp_filename);
- PABC_FREE_NULL (json);
- pabc_free_ctx (&ctx);
- return GNUNET_SYSERR;
- }
- snprintf (filename, filename_size, "%s/%s%s", get_pabcdir (), pp_filename,
- PABC_PP_EXT);
- GNUNET_free (pp_filename);
- if (GNUNET_OK != write_file (filename, json))
- {
- PABC_FREE_NULL (filename);
- PABC_FREE_NULL (json);
- pabc_free_ctx (&ctx);
- return GNUNET_SYSERR;
- }
- PABC_FREE_NULL (filename);
- PABC_FREE_NULL (json);
- pabc_free_ctx (&ctx);
- return GNUNET_OK;
- }
- enum GNUNET_GenericReturnValue
- PABC_write_usr_ctx (char const *const usr_name,
- char const *const pp_name,
- struct pabc_context const *const ctx,
- struct pabc_public_parameters const *const pp,
- struct pabc_user_context *const usr_ctx)
- {
- char *pp_filename;
- char *json = NULL;
- enum pabc_status status;
- char *fname = NULL;
- if (NULL == usr_name)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == pp_name)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == ctx)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == pp)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == usr_ctx)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
- return GNUNET_SYSERR;
- }
- GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
- status = pabc_encode_user_ctx (ctx, pp, usr_ctx, &json);
- if (PABC_OK != status)
- {
- GNUNET_free (pp_filename);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
- return status;
- }
- size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
- + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
- fname = GNUNET_malloc (fname_size);
- snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
- pp_filename,
- PABC_USR_EXT);
- GNUNET_free (pp_filename);
- if (GNUNET_OK == write_file (fname, json))
- {
- GNUNET_free (fname);
- GNUNET_free (json);
- return GNUNET_OK;
- }
- else
- {
- GNUNET_free (fname);
- GNUNET_free (json);
- return GNUNET_SYSERR;
- }
- }
- enum GNUNET_GenericReturnValue
- PABC_read_usr_ctx (char const *const usr_name,
- char const *const pp_name,
- struct pabc_context const *const ctx,
- struct pabc_public_parameters const *const pp,
- struct pabc_user_context **usr_ctx)
- {
- char *json = NULL;
- char *pp_filename;
- enum pabc_status status;
- char *fname = NULL;
- if (NULL == usr_name)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == pp_name)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == ctx)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == pp)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
- return GNUNET_SYSERR;
- }
- if (NULL == usr_ctx)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
- return GNUNET_SYSERR;
- }
- GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
- size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
- + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
- fname = GNUNET_malloc (fname_size);
- snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
- pp_filename,
- PABC_USR_EXT);
- GNUNET_free (pp_filename);
- if (GNUNET_OK != read_file (fname, &json))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to read `%s'\n", fname);
- PABC_FREE_NULL (fname);
- return GNUNET_SYSERR;
- }
- GNUNET_free (fname);
- status = pabc_new_user_context (ctx, pp, usr_ctx);
- if (PABC_OK != status)
- {
- GNUNET_free (json);
- return GNUNET_SYSERR;
- }
- status = pabc_decode_user_ctx (ctx, pp, *usr_ctx, json);
- GNUNET_free (json);
- if (PABC_OK != status)
- {
- pabc_free_user_context (ctx, pp, usr_ctx);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
- }
|