gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] 01/02: -init oidc RSA256 feature


From: gnunet
Subject: [gnunet] 01/02: -init oidc RSA256 feature
Date: Thu, 09 Jun 2022 11:50:21 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

commit 349b4e37123368e3f03d563770d72bcbfd8109ad
Author: Tristan Schwieren <tristan.schwieren@tum.de>
AuthorDate: Mon Apr 11 13:29:20 2022 +0200

    -init oidc RSA256 feature
---
 configure.ac                             |   5 +
 src/reclaim/Makefile.am                  |   2 +-
 src/reclaim/oidc_helper.c                | 160 +++++++++++++++----
 src/reclaim/oidc_helper.h                |  47 ++++--
 src/reclaim/plugin_rest_openid_connect.c | 256 ++++++++++++++++++++++++++++---
 src/reclaim/reclaim.conf                 |   4 +-
 6 files changed, 403 insertions(+), 71 deletions(-)

diff --git a/configure.ac b/configure.ac
index 733eea06e..3553d93b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -719,6 +719,11 @@ CHECK_WITH_LIB([jansson], [json_loads], [jansson.h], 
[HAVE_JANSSON])
 AS_IF([test "x$jansson" = "x0"],
   [AC_MSG_ERROR([GNUnet requires jansson])])
 
+# check for jose
+CHECK_WITH_LIB([jose], [jose_jwk_gen], [jose/jose.h], [HAVE_JOSE])
+AS_IF([test "x$jose" = "x0"],
+  [AC_MSG_ERROR([GNUnet requires jose])])
+
 # check for libpulse (pulseaudio)
 CHECK_WITH_LIB([pulse], [pa_stream_peek], [pulse/simple.h], [HAVE_PULSE])
 
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index a8300d6af..710207d8b 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -79,7 +79,7 @@ libgnunet_plugin_rest_openid_connect_la_LIBADD = \
   $(top_builddir)/src/gns/libgnunetgns.la \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
-  $(LTLIBINTL) -ljansson $(MHD_LIBS) \
+  $(LTLIBINTL) -ljansson -ljose $(MHD_LIBS) \
        $(LIBGCRYPT_LIBS)
 libgnunet_plugin_rest_openid_connect_la_LDFLAGS = \
   $(GN_PLUGIN_LDFLAGS)
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index 9237902ce..cfa71b26c 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -22,10 +22,12 @@
  * @file reclaim/oidc_helper.c
  * @brief helper library for OIDC related functions
  * @author Martin Schanzenbach
+ * @author Tristan Schwieren
  */
 #include "platform.h"
 #include <inttypes.h>
 #include <jansson.h>
+#include <jose/jose.h>
 #include "gnunet_util_lib.h"
 #include "gnunet_reclaim_lib.h"
 #include "gnunet_reclaim_service.h"
@@ -115,13 +117,13 @@ is_claim_in_address_scope (const char *claim)
 
 
 static char *
-create_jwt_header (void)
+create_jwt_hmac_header (void)
 {
   json_t *root;
   char *json_str;
 
   root = json_object ();
-  json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
+  json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE_HMAC));
   json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
 
   json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT);
@@ -356,40 +358,22 @@ OIDC_generate_userinfo (const struct 
GNUNET_IDENTITY_PublicKey *sub_key,
 }
 
 
-/**
- * Create a JWT from attributes
- *
- * @param aud_key the public of the audience
- * @param sub_key the public key of the subject
- * @param attrs the attribute list
- * @param presentations credential presentation list (may be empty)
- * @param expiration_time the validity of the token
- * @param secret_key the key used to sign the JWT
- * @return a new base64-encoded JWT string.
- */
 char *
-OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key,
+generate_id_token_body (const struct GNUNET_IDENTITY_PublicKey *aud_key,
                         const struct GNUNET_IDENTITY_PublicKey *sub_key,
                         const struct GNUNET_RECLAIM_AttributeList *attrs,
                         const struct
                         GNUNET_RECLAIM_PresentationList *presentations,
                         const struct GNUNET_TIME_Relative *expiration_time,
-                        const char *nonce,
-                        const char *secret_key)
+                        const char *nonce)
 {
   struct GNUNET_HashCode signature;
   struct GNUNET_TIME_Absolute exp_time;
   struct GNUNET_TIME_Absolute time_now;
+  json_t *body;
   char *audience;
   char *subject;
-  char *header;
   char *body_str;
-  char *result;
-  char *header_base64;
-  char *body_base64;
-  char *signature_target;
-  char *signature_base64;
-  json_t *body;
 
   body = generate_userinfo_json (sub_key,
                                  attrs,
@@ -409,7 +393,6 @@ OIDC_generate_id_token (const struct 
GNUNET_IDENTITY_PublicKey *aud_key,
     GNUNET_STRINGS_data_to_string_alloc (aud_key,
                                          sizeof(struct
                                                 GNUNET_IDENTITY_PublicKey));
-  header = create_jwt_header ();
 
   // aud REQUIRED public key client_id must be there
   json_object_set_new (body, "aud", json_string (audience));
@@ -429,19 +412,132 @@ OIDC_generate_id_token (const struct 
GNUNET_IDENTITY_PublicKey *aud_key,
   if (NULL != nonce)
     json_object_set_new (body, "nonce", json_string (nonce));
 
-  body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
-  json_decref (body);
+  // Error checking
+  body_str = json_dumps (body, JSON_INDENT (2) | JSON_COMPACT);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str);
 
+  json_decref (body);
+  GNUNET_free (subject);
+  GNUNET_free (audience);
+
+  return body_str;
+}
+
+
+/**
+ * Create a JWT using RSA256 algorithm from attributes
+ *
+ * @param aud_key the public of the audience
+ * @param sub_key the public key of the subject
+ * @param attrs the attribute list
+ * @param presentations credential presentation list (may be empty)
+ * @param expiration_time the validity of the token
+ * @param secret_rsa_key the key used to sign the JWT
+ * @return a new base64-encoded JWT string.
+ */
+char *
+OIDC_generate_id_token_rsa (const struct GNUNET_IDENTITY_PublicKey *aud_key,
+                            const struct GNUNET_IDENTITY_PublicKey *sub_key,
+                            const struct GNUNET_RECLAIM_AttributeList *attrs,
+                            const struct
+                            GNUNET_RECLAIM_PresentationList *presentations,
+                            const struct GNUNET_TIME_Relative *expiration_time,
+                            const char *nonce,
+                            const json_t *secret_rsa_key)
+{
+  json_t *jws;
+  char *body_str;
+  char *result;
+
+  // Generate the body of the JSON Web Signature
+  body_str = generate_id_token_body (aud_key,
+                                     sub_key,
+                                     attrs,
+                                     presentations,
+                                     expiration_time,
+                                     nonce);
+
+  if (! body_str)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Body for the JWS could not be generated\n");
+  }
+
+  // Creating the JSON Web Signature.
+  jws = json_pack ("{s:o}", "payload",
+                           jose_b64_enc (body_str, strlen (body_str)));
+
+  if (! jose_jws_sig (NULL, jws, NULL, secret_rsa_key))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Signature generation failed\n");
+  }
+
+  // Encoding JSON as compact JSON Web Signature 
+  GNUNET_asprintf (&result, "%s.%s.%s",
+                   json_string_value (json_object_get (jws, "protected")),
+                   json_string_value (json_object_get (jws, "payload")),
+                   json_string_value (json_object_get (jws, "signature")) );
+
+  json_decref(jws);
+  GNUNET_free(body_str);
+  return result;
+}
+
+/**
+ * Create a JWT using HMAC (HS256) from attributes
+ *
+ * @param aud_key the public of the audience
+ * @param sub_key the public key of the subject
+ * @param attrs the attribute list
+ * @param presentations credential presentation list (may be empty)
+ * @param expiration_time the validity of the token
+ * @param secret_key the key used to sign the JWT
+ * @return a new base64-encoded JWT string.
+ */
+char *
+OIDC_generate_id_token_hmac (const struct GNUNET_IDENTITY_PublicKey *aud_key,
+                             const struct GNUNET_IDENTITY_PublicKey *sub_key,
+                             const struct GNUNET_RECLAIM_AttributeList *attrs,
+                             const struct
+                             GNUNET_RECLAIM_PresentationList *presentations,
+                             const struct GNUNET_TIME_Relative 
*expiration_time,
+                             const char *nonce,
+                             const char *secret_key)
+{
+  struct GNUNET_HashCode signature;
+  struct GNUNET_TIME_Absolute exp_time;
+  struct GNUNET_TIME_Absolute time_now;
+  char *header;
+  char *header_base64;
+  char *body_str;
+  char *body_base64;
+  char *signature_target;
+  char *signature_base64;
+  char *result;
+
+  // Generate and encode Header
+  header = create_jwt_hmac_header ();
   GNUNET_STRINGS_base64url_encode (header, strlen (header), &header_base64);
   fix_base64 (header_base64);
 
+  // Generate and encode the body of the JSON Web Signature
+  body_str = generate_id_token_body (aud_key,
+                                     sub_key,
+                                     attrs,
+                                     presentations,
+                                     expiration_time,
+                                     nonce);
+
+  if (! body_str)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Body for the JWS could not be generated\n");
+  }
+
   GNUNET_STRINGS_base64url_encode (body_str, strlen (body_str), &body_base64);
   fix_base64 (body_base64);
 
-  GNUNET_free (subject);
-  GNUNET_free (audience);
-
   /**
    * Creating the JWT signature. This might not be
    * standards compliant, check.
@@ -463,12 +559,12 @@ OIDC_generate_id_token (const struct 
GNUNET_IDENTITY_PublicKey *aud_key,
                    body_base64,
                    signature_base64);
 
-  GNUNET_free (signature_target);
   GNUNET_free (header);
+  GNUNET_free (header_base64);
   GNUNET_free (body_str);
-  GNUNET_free (signature_base64);
   GNUNET_free (body_base64);
-  GNUNET_free (header_base64);
+  GNUNET_free (signature_target);
+  GNUNET_free (signature_base64);
   return result;
 }
 
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h
index 2a8b7bbae..ea106b4f2 100644
--- a/src/reclaim/oidc_helper.h
+++ b/src/reclaim/oidc_helper.h
@@ -28,14 +28,12 @@
 #define JWT_H
 
 #define JWT_ALG "alg"
-
-/* Use 512bit HMAC */
-#define JWT_ALG_VALUE "HS512"
-
 #define JWT_TYP "typ"
-
 #define JWT_TYP_VALUE "jwt"
 
+#define JWT_ALG_VALUE_HMAC "HS512"
+#define JWT_ALG_VALUE_RSA "RS256"
+
 #define SERVER_ADDRESS "https://api.reclaim";
 
 enum OIDC_VerificationOptions
@@ -52,7 +50,28 @@ enum OIDC_VerificationOptions
 };
 
 /**
- * Create a JWT from attributes
+ * Create a JWT using RSA256 from attributes
+ *
+ * @param aud_key the public of the audience
+ * @param sub_key the public key of the subject
+ * @param attrs the attribute list
+ * @param presentations credential presentation list (may be empty)
+ * @param expiration_time the validity of the token
+ * @param secret_key the key used to sign the JWT
+ * @return a new base64-encoded JWT string.
+ */
+char *
+OIDC_generate_id_token_rsa (const struct GNUNET_IDENTITY_PublicKey *aud_key,
+                            const struct GNUNET_IDENTITY_PublicKey *sub_key,
+                            const struct GNUNET_RECLAIM_AttributeList *attrs,
+                            const struct
+                            GNUNET_RECLAIM_PresentationList *presentations,
+                            const struct GNUNET_TIME_Relative *expiration_time,
+                            const char *nonce,
+                            const json_t *secret_rsa_key);
+
+/**
+ * Create a JWT using HMAC (HS256) from attributes
  *
  * @param aud_key the public of the audience
  * @param sub_key the public key of the subject
@@ -63,14 +82,14 @@ enum OIDC_VerificationOptions
  * @return a new base64-encoded JWT string.
  */
 char*
-OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key,
-                        const struct GNUNET_IDENTITY_PublicKey *sub_key,
-                        const struct GNUNET_RECLAIM_AttributeList *attrs,
-                        const struct
-                        GNUNET_RECLAIM_PresentationList *presentations,
-                        const struct GNUNET_TIME_Relative *expiration_time,
-                        const char *nonce,
-                        const char *secret_key);
+OIDC_generate_id_token_hmac (const struct GNUNET_IDENTITY_PublicKey *aud_key,
+                             const struct GNUNET_IDENTITY_PublicKey *sub_key,
+                             const struct GNUNET_RECLAIM_AttributeList *attrs,
+                             const struct
+                             GNUNET_RECLAIM_PresentationList *presentations,
+                             const struct GNUNET_TIME_Relative 
*expiration_time,
+                             const char *nonce,
+                             const char *secret_key);
 
 /**
  * Builds an OIDC authorization code including
diff --git a/src/reclaim/plugin_rest_openid_connect.c 
b/src/reclaim/plugin_rest_openid_connect.c
index 1c00abcbd..bb8e1cd1e 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -20,6 +20,7 @@
 /**
  * @author Martin Schanzenbach
  * @author Philippe Buschmann
+ * @author Tristan Schwieren
  * @file identity/plugin_rest_openid_connect.c
  * @brief GNUnet Namestore REST plugin
  *
@@ -27,6 +28,7 @@
 #include "platform.h"
 #include <inttypes.h>
 #include <jansson.h>
+#include <jose/jose.h>
 
 #include "gnunet_buffer_lib.h"
 #include "gnunet_strings_lib.h"
@@ -62,6 +64,11 @@
  */
 #define GNUNET_REST_API_NS_TOKEN "/openid/token"
 
+/**
+ * JSON Web Keys endpoint
+ */
+#define GNUNET_REST_API_JWKS "/jwks.json"
+
 /**
  * UserInfo endpoint
  */
@@ -227,6 +234,11 @@
  */
 #define OIDC_ERROR_KEY_ACCESS_DENIED "access_denied"
 
+/**
+ * OIDC key store file name
+ */
+#define OIDC_JWK_RSA_FILENAME "jwk_rsa.json"
+
 /**
  * How long to wait for a consume in userinfo endpoint
  */
@@ -302,6 +314,11 @@ struct Plugin
   const struct GNUNET_CONFIGURATION_Handle *cfg;
 };
 
+/**
+ * @brief The RSA key used by the oidc enpoint
+ */
+json_t *oidc_jwk;
+
 /**
  * OIDC needed variables
  */
@@ -858,6 +875,103 @@ cookie_identity_interpretation (struct RequestHandle 
*handle)
 }
 
 
+/**
+ * @brief Read the the JSON Web Key in the given file and return it.
+ * Return NULL and emit warning if JSON can not be decoded or the key is
+ * invalid
+ *
+ * @param filename the file to read the JWK from
+ * @return json_t* the reed JWK
+ */
+json_t *
+read_jwk_from_file (const char *filename)
+{
+  json_t *jwk;
+  json_error_t error;
+
+  jwk = json_load_file (filename, JSON_DECODE_ANY, &error);
+
+  if (! jwk)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                ("Could not read OIDC RSA key from config file; %s\n"),
+                error.text);
+  }
+
+  return jwk;
+}
+
+/**
+ * @brief Write the JWK to file. If unsuccessful emit warning
+ *
+ * @param filename the name of the file the JWK is writen to
+ * @param jwk the JWK that is going to be written
+ * @return int Return GNUNET_OK if write is sucessfull
+ */
+static int
+write_jwk_to_file (const char *filename,
+                   json_t *jwk)
+{
+  if (json_dump_file (jwk, filename, JSON_INDENT (2)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                ("Could not write OIDC RSA key to file %s\n"),
+                filename);
+    return GNUNET_ERROR_TYPE_WARNING;
+  }
+  else
+    return GNUNET_OK;
+}
+
+/**
+ * @brief Generate a new RSA JSON Web Key
+ *
+ * @return json_t* the generated JWK
+ */
+json_t *
+generate_jwk ()
+{
+  json_t *jwk;
+  jwk = json_pack ("{s:s,s:i}", "kty", "RSA", "bits", 2048);
+  jose_jwk_gen (NULL, jwk);
+  json_incref (jwk);
+  return jwk;
+}
+
+/**
+ * Return the path to the RSA JWK key file
+ *
+ * @param cls the RequestHandle
+ */
+char *
+get_oidc_jwk_path (void *cls)
+{
+  char *oidc_directory;
+  char *oidc_jwk_path;
+  struct RequestHandle *handle = cls;
+
+  // Read OIDC directory from config
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                                            
"reclaim-rest-plugin",
+                                                            "oidc_dir",
+                                                            &oidc_directory))
+  {
+    // Could not read Config file
+    handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR);
+    handle->edesc = GNUNET_strdup ("gnunet configuration failed");
+    handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return NULL;
+  }
+
+  // Create path to file
+  GNUNET_asprintf (&oidc_jwk_path, "%s/%s", oidc_directory,
+                   OIDC_JWK_RSA_FILENAME);
+
+  return oidc_jwk_path;
+}
+
+
 /**
  * Redirects to login page stored in configuration file
  */
@@ -1954,7 +2068,7 @@ check_authorization (struct RequestHandle *handle,
   // check client password
   if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
                                                           
"reclaim-rest-plugin",
-                                                          "OIDC_CLIENT_SECRET",
+                                                          
"OIDC_CLIENT_HMAC_SECRET",
                                                           &expected_pass))
   {
     if (0 != strcmp (expected_pass, received_cpw))
@@ -2047,9 +2161,12 @@ token_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
   char *json_response;
   char *id_token;
   char *access_token;
+  char *jwa;
   char *jwt_secret;
   char *nonce = NULL;
   char *code_verifier;
+  json_t *oidc_jwk;
+  char *oidc_jwk_path;
 
   /*
    * Check Authorization
@@ -2156,32 +2273,66 @@ token_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
 
-
-  // TODO OPTIONAL acr,amr,azp
+  // Check if HMAC or RSA should be used
   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
                                                           
"reclaim-rest-plugin",
-                                                          "jwt_secret",
-                                                          &jwt_secret))
+                                                          
"oidc_json_web_algorithm",
+                                                          &jwa))
   {
-    handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
-    handle->edesc = GNUNET_strdup ("No signing secret configured!");
-    handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
-    GNUNET_free (code);
-    GNUNET_RECLAIM_attribute_list_destroy (cl);
-    GNUNET_RECLAIM_presentation_list_destroy (pl);
-    if (NULL != nonce)
-      GNUNET_free (nonce);
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Could not read OIDC JSON Web Algorithm config attribute."
+                "Defaulting to RS256.");
+    jwa = JWT_ALG_VALUE_RSA;
+  }
+
+  if (strcmp(jwa, JWT_ALG_VALUE_RSA))
+  {
+    // Replace for now
+    oidc_jwk_path = get_oidc_jwk_path (cls);
+    oidc_jwk = read_jwk_from_file (oidc_jwk_path);
+    id_token = OIDC_generate_id_token_rsa (&ticket.audience,
+                                           &ticket.identity,
+                                           cl,
+                                           pl,
+                                           &expiration_time,
+                                           (NULL != nonce) ? nonce : NULL,
+                                           oidc_jwk);
+  }
+  else if (strcmp(jwa, JWT_ALG_VALUE_HMAC))
+  {
+    // TODO OPTIONAL acr,amr,azp
+    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
+                                                            
"reclaim-rest-plugin",
+                                                            "jwt_secret",
+                                                            &jwt_secret))
+    {
+      handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
+      handle->edesc = GNUNET_strdup ("No signing secret configured!");
+      handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+      GNUNET_free (code);
+      GNUNET_RECLAIM_attribute_list_destroy (cl);
+      GNUNET_RECLAIM_presentation_list_destroy (pl);
+      if (NULL != nonce)
+        GNUNET_free (nonce);
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
+
+    id_token = OIDC_generate_id_token_hmac (&ticket.audience,
+                                            &ticket.identity,
+                                            cl,
+                                            pl,
+                                            &expiration_time,
+                                            (NULL != nonce) ? nonce : NULL,
+                                            jwt_secret);
+
+    GNUNET_free (jwt_secret);
+  }
+  else 
+  {
+    // TODO: OPTION NOT FOUND ERROR
   }
-  id_token = OIDC_generate_id_token (&ticket.audience,
-                                     &ticket.identity,
-                                     cl,
-                                     pl,
-                                     &expiration_time,
-                                     (NULL != nonce) ? nonce : NULL,
-                                     jwt_secret);
-  GNUNET_free (jwt_secret);
+
   if (NULL != nonce)
     GNUNET_free (nonce);
   access_token = OIDC_access_token_new (&ticket);
@@ -2474,6 +2625,59 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
   GNUNET_free (authorization);
 }
 
+/**
+ * Responds to /jwks.json
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+jwks_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
+               const char *url,
+               void *cls)
+{
+  char *oidc_directory;
+  char *oidc_jwk_path;
+  char *oidc_jwk_pub_str;
+  json_t *oidc_jwk;
+  struct MHD_Response *resp;
+  struct RequestHandle *handle = cls;
+
+  oidc_jwk_path = get_oidc_jwk_path (cls);
+  oidc_jwk = read_jwk_from_file (oidc_jwk_path);
+
+  // Check if secret JWK exists
+  if (! oidc_jwk)
+  {
+    // Generate and save a new key
+    oidc_jwk = generate_jwk ();
+
+    // Create new oidc directory
+    if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  ("Failed to create directory `%s' for storing oidc data\n"),
+                  oidc_directory);
+    }
+    else
+    {
+      write_jwk_to_file (oidc_jwk_path, oidc_jwk);
+    }
+  }
+
+  // Convert secret JWK to public JWK
+  jose_jwk_pub (NULL, oidc_jwk);
+
+  // Encode JWK as string and return to API endpoint
+  oidc_jwk_pub_str = json_dumps (oidc_jwk, JSON_INDENT (1));
+  resp = GNUNET_REST_create_response (oidc_jwk_pub_str);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  json_decref (oidc_jwk);
+  GNUNET_free (oidc_jwk_pub_str);
+  free (oidc_jwk_pub_str);
+  cleanup_handle (handle);
+}
 
 /**
  * If listing is enabled, prints information about the egos.
@@ -2621,9 +2825,14 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
   sig_algs = json_array ();
   json_array_append_new (sig_algs,
                          json_string ("HS512"));
+  json_array_append_new (sig_algs,
+                         json_string ("RS256"));
   json_object_set_new (oidc_config,
                        "id_token_signing_alg_values_supported",
                        sig_algs);
+  json_object_set_new (oidc_config,
+                       "jwks_uri",
+                       json_string ("http://localhost:7776/jwks.json";));
   json_object_set_new (oidc_config,
                        "userinfo_endpoint",
                        json_string ("http://localhost:7776/openid/userinfo";));
@@ -2719,6 +2928,7 @@ rest_identity_process_request (struct 
GNUNET_REST_RequestHandle *rest_handle,
     { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
     { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
     { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
+    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_JWKS, &jwks_endpoint },
     { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG,
       &oidc_config_endpoint },
     { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG,
diff --git a/src/reclaim/reclaim.conf b/src/reclaim/reclaim.conf
index 8655f2e0b..c685042db 100644
--- a/src/reclaim/reclaim.conf
+++ b/src/reclaim/reclaim.conf
@@ -14,6 +14,8 @@ TICKET_REFRESH_INTERVAL = 6h
 [reclaim-rest-plugin]
 #ADDRESS = https://identity.gnu:8000#/login
 ADDRESS = https://ui.reclaim/#/login
-OIDC_CLIENT_SECRET = secret
+OIDC_JSON_WEB_ALGORITHM = RS256
+OIDC_CLIENT_HMAC_SECRET = secret
+OIDC_DIR = $GNUNET_DATA_HOME/oidc
 JWT_SECRET = secret
 EXPIRATION_TIME = 1d

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]