summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2021-02-22 18:20:24 +0100
committerMartin Schanzenbach <mschanzenbach@posteo.de>2021-04-20 10:50:36 +0200
commit40458566131dfc85381d8966bb465f455830400b (patch)
treec0fcfeca03bcfa34f9900ba82a6f7326ee89afa4
parent8562992bff092c27d6f589667c74659831da364c (diff)
-add pabc helpers
-rw-r--r--src/reclaim/Makefile.am6
-rw-r--r--src/reclaim/pabc_helper.c336
-rw-r--r--src/reclaim/pabc_helper.h41
-rw-r--r--src/reclaim/plugin_reclaim_credential_jwt.c12
-rw-r--r--src/reclaim/plugin_reclaim_credential_pabc.c140
-rw-r--r--src/reclaim/plugin_rest_pabc.c65
6 files changed, 532 insertions, 68 deletions
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 6ad842789..1a0b7fae4 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -94,7 +94,8 @@ libgnunet_plugin_rest_openid_connect_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
if HAVE_PABC
libgnunet_plugin_rest_pabc_la_SOURCES = \
- plugin_rest_pabc.c
+ plugin_rest_pabc.c \
+ pabc_helper.c
libgnunet_plugin_rest_pabc_la_LIBADD = \
libgnunetreclaim.la \
$(top_builddir)/src/json/libgnunetjson.la \
@@ -160,7 +161,8 @@ libgnunet_plugin_reclaim_attribute_basic_la_LDFLAGS = \
if HAVE_PABC
libgnunet_plugin_reclaim_credential_pabc_la_SOURCES = \
- plugin_reclaim_credential_pabc.c
+ plugin_reclaim_credential_pabc.c \
+ pabc_helper.c
libgnunet_plugin_reclaim_credential_pabc_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
libgnunetreclaim.la \
diff --git a/src/reclaim/pabc_helper.c b/src/reclaim/pabc_helper.c
new file mode 100644
index 000000000..e76977d03
--- /dev/null
+++ b/src/reclaim/pabc_helper.c
@@ -0,0 +1,336 @@
+// 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_PERM_USER_WRITE);
+ 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;
+ 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))
+ {
+ 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];
+ const char *pdir = get_pabcdir ();
+
+ if (ctx == NULL)
+ return GNUNET_SYSERR;
+ if (pp_name == NULL)
+ return GNUNET_SYSERR;
+ if (pp == NULL)
+ return GNUNET_SYSERR;
+
+ if (GNUNET_YES != GNUNET_DISK_directory_test (pdir, GNUNET_YES))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading %s\n", pdir);
+ return GNUNET_SYSERR;
+ }
+ snprintf (fname, PATH_MAX, "%s/%s%s", pdir, pp_name, PABC_PP_EXT);
+ if (GNUNET_YES != GNUNET_DISK_file_test (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;
+ enum pabc_status status;
+ struct pabc_context *ctx = NULL;
+ PABC_ASSERT (pabc_new_ctx (&ctx));
+ // store in json file
+ status = pabc_encode_public_parameters (ctx, pp, &json);
+ if (status != PABC_OK)
+ {
+ 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_name) + strlen (PABC_PP_EXT) + 1;
+ filename = GNUNET_malloc (filename_size);
+ if (! filename)
+ {
+ PABC_FREE_NULL (json);
+ pabc_free_ctx (&ctx);
+ return GNUNET_SYSERR;
+ }
+ snprintf (filename, filename_size, "%s/%s%s", get_pabcdir (), pp_name,
+ PABC_PP_EXT);
+
+ 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)
+{
+
+ 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;
+ }
+
+ char *json = NULL;
+ enum pabc_status status;
+ status = pabc_encode_user_ctx (ctx, pp, usr_ctx, &json);
+ if (PABC_OK != status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
+ return status;
+ }
+
+ char *fname = NULL;
+ size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
+ + strlen (pp_name) + strlen (PABC_USR_EXT) + 1;
+ fname = GNUNET_malloc (fname_size);
+
+ snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name, pp_name,
+ PABC_USR_EXT);
+
+ 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)
+{
+ 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;
+ }
+
+ char *json = NULL;
+ enum pabc_status status;
+
+ char *fname = NULL;
+ size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
+ + strlen (pp_name) + strlen (PABC_USR_EXT) + 1;
+ fname = GNUNET_malloc (fname_size);
+ snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name, pp_name,
+ PABC_USR_EXT);
+
+ if (GNUNET_OK != read_file (fname, &json))
+ {
+ 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;
+}
diff --git a/src/reclaim/pabc_helper.h b/src/reclaim/pabc_helper.h
new file mode 100644
index 000000000..491672a8b
--- /dev/null
+++ b/src/reclaim/pabc_helper.h
@@ -0,0 +1,41 @@
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include <libpabc/libpabc.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+#define PABC_ISK_EXT ".isk"
+
+#define PABC_PP_EXT ".pp"
+
+#define PABC_USR_EXT ".usr"
+
+#define PABC_ATTR_DELIM "="
+
+enum GNUNET_GenericReturnValue
+PABC_write_public_parameters (char const *const pp_name,
+ struct pabc_public_parameters *const pp);
+
+
+enum GNUNET_GenericReturnValue
+PABC_load_public_parameters (struct pabc_context *const ctx,
+ char const *const pp_name,
+ struct pabc_public_parameters **pp);
+
+enum GNUNET_GenericReturnValue
+PABC_write_usr_ctx (char const *const user_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);
+
+enum GNUNET_GenericReturnValue
+PABC_read_usr_ctx (char const *const user_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);
diff --git a/src/reclaim/plugin_reclaim_credential_jwt.c b/src/reclaim/plugin_reclaim_credential_jwt.c
index aac0a6ea5..425ac3450 100644
--- a/src/reclaim/plugin_reclaim_credential_jwt.c
+++ b/src/reclaim/plugin_reclaim_credential_jwt.c
@@ -162,7 +162,7 @@ jwt_parse_attributes (void *cls,
char *decoded_jwt;
char *tmp;
json_t *json_val;
- json_error_t *json_err = NULL;
+ json_error_t json_err;
attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
@@ -173,7 +173,7 @@ jwt_parse_attributes (void *cls,
(void **) &decoded_jwt);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt);
GNUNET_assert (NULL != decoded_jwt);
- json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+ json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
GNUNET_free (decoded_jwt);
const char *key;
const char *addr_key;
@@ -291,14 +291,14 @@ jwt_get_issuer (void *cls,
json_t *issuer_json;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
json_t *json_val;
- json_error_t *json_err = NULL;
+ json_error_t json_err;
jwt_string = GNUNET_strndup (data, data_size);
jwt_body = strtok (jwt_string, delim);
jwt_body = strtok (NULL, delim);
GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
(void **) &decoded_jwt);
- json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+ json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
GNUNET_free (decoded_jwt);
GNUNET_free (jwt_string);
if (NULL == json_val)
@@ -368,14 +368,14 @@ jwt_get_expiration (void *cls,
json_t *exp_json;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
json_t *json_val;
- json_error_t *json_err = NULL;
+ json_error_t json_err;
jwt_string = GNUNET_strndup (data, data_size);
jwt_body = strtok (jwt_string, delim);
jwt_body = strtok (NULL, delim);
GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
(void **) &decoded_jwt);
- json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+ json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
GNUNET_free (decoded_jwt);
GNUNET_free (jwt_string);
if (NULL == json_val)
diff --git a/src/reclaim/plugin_reclaim_credential_pabc.c b/src/reclaim/plugin_reclaim_credential_pabc.c
index 6bc94b404..dae23ab1a 100644
--- a/src/reclaim/plugin_reclaim_credential_pabc.c
+++ b/src/reclaim/plugin_reclaim_credential_pabc.c
@@ -31,6 +31,7 @@
#include <inttypes.h>
#include <jansson.h>
#include <libpabc/libpabc.h>
+#include "pabc_helper.h"
/**
* Convert the 'value' of an credential to a string.
@@ -43,9 +44,9 @@
*/
static char *
pabc_value_to_string (void *cls,
- uint32_t type,
- const void *data,
- size_t data_size)
+ uint32_t type,
+ const void *data,
+ size_t data_size)
{
switch (type)
{
@@ -71,10 +72,10 @@ pabc_value_to_string (void *cls,
*/
static int
pabc_string_to_value (void *cls,
- uint32_t type,
- const char *s,
- void **data,
- size_t *data_size)
+ uint32_t type,
+ const char *s,
+ void **data,
+ size_t *data_size)
{
if (NULL == s)
return GNUNET_SYSERR;
@@ -100,7 +101,7 @@ static struct
const char *name;
uint32_t number;
} pabc_cred_name_map[] = { { "PABC", GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC },
- { NULL, UINT32_MAX } };
+ { NULL, UINT32_MAX } };
/**
* Convert a type name to the corresponding number.
@@ -136,8 +137,8 @@ pabc_number_to_typename (void *cls, uint32_t type)
i = 0;
while ((NULL != pabc_cred_name_map[i].name) && (type !=
- pabc_cred_name_map[i].
- number))
+ pabc_cred_name_map[i].
+ number))
i++;
return pabc_cred_name_map[i].name;
}
@@ -152,8 +153,8 @@ pabc_number_to_typename (void *cls, uint32_t type)
*/
struct GNUNET_RECLAIM_AttributeList *
pabc_parse_attributes (void *cls,
- const char *data,
- size_t data_size)
+ const char *data,
+ size_t data_size)
{
const char *key;
struct GNUNET_RECLAIM_AttributeList *attrs;
@@ -167,7 +168,7 @@ pabc_parse_attributes (void *cls,
json_root = json_loads (data, JSON_DECODE_ANY, json_err);
if ((NULL == json_root) ||
- (!json_is_object (json_root)))
+ (! json_is_object (json_root)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"%s is not a valid pabc credentials (not an object)\n",
@@ -178,7 +179,7 @@ pabc_parse_attributes (void *cls,
}
json_attrs = json_object_get (json_root, "attributes");
if ((NULL == json_attrs) ||
- (!json_is_array (json_attrs)))
+ (! json_is_array (json_attrs)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"%s is not a valid pabc credentials (attributes not an array)\n",
@@ -191,7 +192,7 @@ pabc_parse_attributes (void *cls,
for (int i = 0; i < json_array_size (json_attrs); i++)
{
attr = json_array_get (json_attrs, i);
- if (!json_is_object(attr))
+ if (! json_is_object (attr))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Found json entry is not an object!\n");
@@ -210,12 +211,12 @@ pabc_parse_attributes (void *cls,
continue;
val_str = json_dumps (value, JSON_ENCODE_ANY);
tmp = val_str;
- //Remove leading " from jasson conversion
+ // Remove leading " from jasson conversion
if (tmp[0] == '"')
tmp++;
- //Remove trailing " from jansson conversion
- if (tmp[strlen(tmp)-1] == '"')
- tmp[strlen(tmp)-1] = '\0';
+ // Remove trailing " from jansson conversion
+ if (tmp[strlen (tmp) - 1] == '"')
+ tmp[strlen (tmp) - 1] = '\0';
GNUNET_RECLAIM_attribute_list_add (attrs,
key,
NULL,
@@ -239,7 +240,7 @@ pabc_parse_attributes (void *cls,
*/
struct GNUNET_RECLAIM_AttributeList *
pabc_parse_attributes_c (void *cls,
- const struct GNUNET_RECLAIM_Credential *cred)
+ const struct GNUNET_RECLAIM_Credential *cred)
{
return pabc_parse_attributes (cls, cred->data, cred->data_size);
}
@@ -254,23 +255,26 @@ pabc_parse_attributes_c (void *cls,
*/
struct GNUNET_RECLAIM_AttributeList *
pabc_parse_attributes_p (void *cls,
- const struct GNUNET_RECLAIM_Presentation *cred)
+ const struct GNUNET_RECLAIM_Presentation *cred)
{
return pabc_parse_attributes (cls, cred->data, cred->data_size);
}
/**
- * Parse a pabc and return the issuer
+ * Parse a pabc and return an attribute value.
*
* @param cls the plugin
- * @param cred the pabc credential
+ * @param data the pabc credential data
+ * @param data_size the pabc credential size
+ * @param key the attribute key to look for.
* @return a string, containing the isser
*/
char *
-pabc_get_issuer (void *cls,
- const char *data,
- size_t data_size)
+pabc_get_attribute (void *cls,
+ const char *data,
+ size_t data_size,
+ const char *skey)
{
const char *key;
char *val_str = NULL;
@@ -283,7 +287,7 @@ pabc_get_issuer (void *cls,
json_root = json_loads (data, JSON_DECODE_ANY, json_err);
if ((NULL == json_root) ||
- (!json_is_object (json_root)))
+ (! json_is_object (json_root)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"%s is not a valid pabc credentials (not an object)\n",
@@ -294,7 +298,7 @@ pabc_get_issuer (void *cls,
}
json_attrs = json_object_get (json_root, "attributes");
if ((NULL == json_attrs) ||
- (!json_is_array (json_attrs)))
+ (! json_is_array (json_attrs)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"%s is not a valid pabc credentials (attributes not an array)\n",
@@ -306,23 +310,23 @@ pabc_get_issuer (void *cls,
for (int i = 0; i < json_array_size (json_attrs); i++)
{
attr = json_array_get (json_attrs, i);
- if (!json_is_object(attr))
+ if (! json_is_object (attr))
continue;
/**
* This *should* only contain a single pair.
*/
json_object_foreach (attr, key, value)
{
- if (0 != strcmp ("issuer", key))
+ if (0 != strcmp (skey, key))
continue;
val_str = json_dumps (value, JSON_ENCODE_ANY);
tmp = val_str;
- //Remove leading " from jasson conversion
+ // Remove leading " from jasson conversion
if (tmp[0] == '"')
tmp++;
- //Remove trailing " from jansson conversion
- if (tmp[strlen(tmp)-1] == '"')
- tmp[strlen(tmp)-1] = '\0';
+ // Remove trailing " from jansson conversion
+ if (tmp[strlen (tmp) - 1] == '"')
+ tmp[strlen (tmp) - 1] = '\0';
GNUNET_free (val_str);
json_decref (json_root);
return tmp;
@@ -340,9 +344,25 @@ pabc_get_issuer (void *cls,
* @param cred the pabc credential
* @return a string, containing the isser
*/
+char*
+pabc_get_issuer (void *cls,
+ const char *data,
+ size_t data_size)
+{
+ return pabc_get_attribute (cls, data, data_size, "issuer");
+}
+
+
+/**
+ * Parse a pabc and return the issuer
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
char *
pabc_get_issuer_c (void *cls,
- const struct GNUNET_RECLAIM_Credential *cred)
+ const struct GNUNET_RECLAIM_Credential *cred)
{
if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type)
return NULL;
@@ -359,7 +379,7 @@ pabc_get_issuer_c (void *cls,
*/
char *
pabc_get_issuer_p (void *cls,
- const struct GNUNET_RECLAIM_Presentation *cred)
+ const struct GNUNET_RECLAIM_Presentation *cred)
{
if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type)
return NULL;
@@ -376,20 +396,20 @@ pabc_get_issuer_p (void *cls,
*/
int
pabc_get_expiration (void *cls,
- const char *data,
- size_t data_size,
- struct GNUNET_TIME_Absolute *exp)
+ const char *data,
+ size_t data_size,
+ struct GNUNET_TIME_Absolute *exp)
{
json_t *json_root;
json_t *json_attrs;
json_t *value;
json_t *attr;
json_error_t *json_err = NULL;
- const char* key;
+ const char*key;
json_root = json_loads (data, JSON_DECODE_ANY, json_err);
if ((NULL == json_root) ||
- (!json_is_object (json_root)))
+ (! json_is_object (json_root)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"%s is not a valid pabc credentials (not an object)\n",
@@ -401,7 +421,7 @@ pabc_get_expiration (void *cls,
for (int i = 0; i < json_array_size (json_attrs); i++)
{
attr = json_array_get (json_attrs, i);
- if (!json_is_object(attr))
+ if (! json_is_object (attr))
continue;
/**
* This *should* only contain a single pair.
@@ -410,7 +430,7 @@ pabc_get_expiration (void *cls,
{
if (0 != strcmp ("expiration", key))
continue;
- if (!json_is_integer (value))
+ if (! json_is_integer (value))
continue;
exp->abs_value_us = json_integer_value (value) * 1000 * 1000;
json_decref (json_root);
@@ -431,8 +451,8 @@ pabc_get_expiration (void *cls,
*/
int
pabc_get_expiration_c (void *cls,
- const struct GNUNET_RECLAIM_Credential *cred,
- struct GNUNET_TIME_Absolute *exp)
+ const struct GNUNET_RECLAIM_Credential *cred,
+ struct GNUNET_TIME_Absolute *exp)
{
return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
}
@@ -447,8 +467,8 @@ pabc_get_expiration_c (void *cls,
*/
int
pabc_get_expiration_p (void *cls,
- const struct GNUNET_RECLAIM_Presentation *cred,
- struct GNUNET_TIME_Absolute *exp)
+ const struct GNUNET_RECLAIM_Presentation *cred,
+ struct GNUNET_TIME_Absolute *exp)
{
return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
}
@@ -456,9 +476,9 @@ pabc_get_expiration_p (void *cls,
int
pabc_create_presentation (void *cls,
- const struct GNUNET_RECLAIM_Credential *credential,
- const struct GNUNET_RECLAIM_AttributeList *attrs,
- struct GNUNET_RECLAIM_Presentation **pres)
+ const struct GNUNET_RECLAIM_Credential *credential,
+ const struct GNUNET_RECLAIM_AttributeList *attrs,
+ struct GNUNET_RECLAIM_Presentation **pres)
{
struct pabc_context *ctx = NULL;
struct pabc_user_context *usr_ctx = NULL;
@@ -466,6 +486,8 @@ pabc_create_presentation (void *cls,
struct pabc_credential *cred = NULL;
struct pabc_blinded_proof *proof = NULL;
struct GNUNET_RECLAIM_AttributeListEntry *ale;
+ char *issuer;
+ char *subject;
enum pabc_status status;
if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != credential->type)
@@ -478,16 +500,28 @@ pabc_create_presentation (void *cls,
* Ideal would be an API that allows us to load pp by
* issuer name.
*/
- //status = load_public_parameters (ctx, "issuerXY", &pp);
+ issuer = pabc_get_issuer_c (cls, credential);
+ if (NULL == issuer)
+ {
+ pabc_free_ctx (&ctx);
+ return GNUNET_SYSERR;
+ }
+ status = PABC_load_public_parameters (ctx, issuer, &pp);
if (status != PABC_OK)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to read public parameters.\n");
pabc_free_ctx (&ctx);
+ GNUNET_free (issuer);
return GNUNET_SYSERR;
}
- //FIXME needs API
- //status = read_usr_ctx (usr_name, pp_name, ctx, pp, &usr_ctx);
+ subject = pabc_get_attribute (cls,
+ credential->data,
+ credential->data_size,
+ "subject");
+ status = PABC_read_usr_ctx (subject, issuer, ctx, pp, &usr_ctx);
+ GNUNET_free (issuer);
+ GNUNET_free (subject);
if (PABC_OK != status)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/reclaim/plugin_rest_pabc.c b/src/reclaim/plugin_rest_pabc.c
index c3bb8847f..e5099a012 100644
--- a/src/reclaim/plugin_rest_pabc.c
+++ b/src/reclaim/plugin_rest_pabc.c
@@ -33,6 +33,7 @@
#include "gnunet_rest_lib.h"
#include "gnunet_rest_plugin.h"
#include "gnunet_signatures.h"
+#include "pabc_helper.h"
/**
* REST root namespace
@@ -221,15 +222,44 @@ set_attributes_from_idtoken (const struct pabc_context *ctx,
{
json_t *payload_json;
json_t *value;
+ json_error_t json_err;
const char *key;
+ const char *jwt_body;
+ char *decoded_jwt;
+ char delim[] = ".";
+ char *jwt_string;
+ const char *pabc_key;
enum pabc_status status;
//FIXME parse JWT
+ jwt_string = GNUNET_strndup (id_token, strlen (id_token));
+ jwt_body = strtok (jwt_string, delim);
+ jwt_body = strtok (NULL, delim);
+ GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
+ (void **) &decoded_jwt);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded ID Token: %s\n", decoded_jwt);
+ payload_json = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
+ GNUNET_free (decoded_jwt);
+
json_object_foreach(payload_json, key, value)
{
- //FIXME skip metadata in JWT, map attributes to PP
+ pabc_key = key;
+ if (0 == strcmp ("iss", key))
+ pabc_key = "issuer"; //rename
+ if (0 == strcmp ("sub", key))
+ pabc_key = "subject"; //rename
+ if (0 == strcmp ("jti", key))
+ continue;
+ if (0 == strcmp ("exp", key))
+ pabc_key = "expiration"; //rename
+ if (0 == strcmp ("iat", key))
+ continue;
+ if (0 == strcmp ("nbf", key))
+ continue;
+ if (0 == strcmp ("aud", key))
+ continue;
status = pabc_set_attribute_value_by_name (ctx, pp, usr_ctx,
- key,
+ pabc_key,
json_string_value (value));
if (PABC_OK != status)
{
@@ -254,6 +284,8 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
json_t *nonce_json;
json_t *pp_json;
json_t *idtoken_json;
+ json_t *iss_json;
+ json_t *identity_json;
json_error_t err;
struct pabc_public_parameters *pp = NULL;
struct pabc_context *ctx = NULL;
@@ -302,6 +334,24 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
+ iss_json = json_object_get (data_json, "issuer");
+ if (NULL == iss_json)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to parse issuer\n");
+ json_decref (data_json);
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+ identity_json = json_object_get (data_json, "identity");
+ if (NULL == identity_json)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to parse identity\n");
+ json_decref (data_json);
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
idtoken_json = json_object_get (idtoken_json, "id_token");
if (NULL == idtoken_json)
{
@@ -322,8 +372,9 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
}
PABC_ASSERT (pabc_new_ctx (&ctx));
- // load stuff FIXME: Needs helper
- //status = load_public_parameters (ctx, pp_name, &pp);
+ status = PABC_load_public_parameters (ctx,
+ json_string_value (iss_json),
+ &pp);
if (status != PABC_OK)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to read public parameters.\n");
@@ -332,9 +383,9 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
return;
}
- /*FIXME: Needs helper
- * status = read_usr_ctx (usr_name, pp_name, ctx, pp, &usr_ctx);
- */
+ status = PABC_read_usr_ctx (json_string_value (identity_json),
+ json_string_value (iss_json),
+ ctx, pp, &usr_ctx);
if (PABC_OK != status)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to read user context.\n");