aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/oidc_helper.c
diff options
context:
space:
mode:
authorTristan Schwieren <tristan.schwieren@tum.de>2022-04-11 13:29:20 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2022-06-09 11:43:01 +0200
commit349b4e37123368e3f03d563770d72bcbfd8109ad (patch)
tree865732d15ee62fa5c7e5d651445ea276a4d4756d /src/reclaim/oidc_helper.c
parent79eff4349f89d13a8cc707550f6bb7d5fe8c99c3 (diff)
downloadgnunet-349b4e37123368e3f03d563770d72bcbfd8109ad.tar.gz
gnunet-349b4e37123368e3f03d563770d72bcbfd8109ad.zip
-init oidc RSA256 feature
Diffstat (limited to 'src/reclaim/oidc_helper.c')
-rw-r--r--src/reclaim/oidc_helper.c160
1 files changed, 128 insertions, 32 deletions
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 @@
22 * @file reclaim/oidc_helper.c 22 * @file reclaim/oidc_helper.c
23 * @brief helper library for OIDC related functions 23 * @brief helper library for OIDC related functions
24 * @author Martin Schanzenbach 24 * @author Martin Schanzenbach
25 * @author Tristan Schwieren
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include <inttypes.h> 28#include <inttypes.h>
28#include <jansson.h> 29#include <jansson.h>
30#include <jose/jose.h>
29#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
30#include "gnunet_reclaim_lib.h" 32#include "gnunet_reclaim_lib.h"
31#include "gnunet_reclaim_service.h" 33#include "gnunet_reclaim_service.h"
@@ -115,13 +117,13 @@ is_claim_in_address_scope (const char *claim)
115 117
116 118
117static char * 119static char *
118create_jwt_header (void) 120create_jwt_hmac_header (void)
119{ 121{
120 json_t *root; 122 json_t *root;
121 char *json_str; 123 char *json_str;
122 124
123 root = json_object (); 125 root = json_object ();
124 json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE)); 126 json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE_HMAC));
125 json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE)); 127 json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
126 128
127 json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT); 129 json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT);
@@ -356,40 +358,22 @@ OIDC_generate_userinfo (const struct GNUNET_IDENTITY_PublicKey *sub_key,
356} 358}
357 359
358 360
359/**
360 * Create a JWT from attributes
361 *
362 * @param aud_key the public of the audience
363 * @param sub_key the public key of the subject
364 * @param attrs the attribute list
365 * @param presentations credential presentation list (may be empty)
366 * @param expiration_time the validity of the token
367 * @param secret_key the key used to sign the JWT
368 * @return a new base64-encoded JWT string.
369 */
370char * 361char *
371OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key, 362generate_id_token_body (const struct GNUNET_IDENTITY_PublicKey *aud_key,
372 const struct GNUNET_IDENTITY_PublicKey *sub_key, 363 const struct GNUNET_IDENTITY_PublicKey *sub_key,
373 const struct GNUNET_RECLAIM_AttributeList *attrs, 364 const struct GNUNET_RECLAIM_AttributeList *attrs,
374 const struct 365 const struct
375 GNUNET_RECLAIM_PresentationList *presentations, 366 GNUNET_RECLAIM_PresentationList *presentations,
376 const struct GNUNET_TIME_Relative *expiration_time, 367 const struct GNUNET_TIME_Relative *expiration_time,
377 const char *nonce, 368 const char *nonce)
378 const char *secret_key)
379{ 369{
380 struct GNUNET_HashCode signature; 370 struct GNUNET_HashCode signature;
381 struct GNUNET_TIME_Absolute exp_time; 371 struct GNUNET_TIME_Absolute exp_time;
382 struct GNUNET_TIME_Absolute time_now; 372 struct GNUNET_TIME_Absolute time_now;
373 json_t *body;
383 char *audience; 374 char *audience;
384 char *subject; 375 char *subject;
385 char *header;
386 char *body_str; 376 char *body_str;
387 char *result;
388 char *header_base64;
389 char *body_base64;
390 char *signature_target;
391 char *signature_base64;
392 json_t *body;
393 377
394 body = generate_userinfo_json (sub_key, 378 body = generate_userinfo_json (sub_key,
395 attrs, 379 attrs,
@@ -409,7 +393,6 @@ OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key,
409 GNUNET_STRINGS_data_to_string_alloc (aud_key, 393 GNUNET_STRINGS_data_to_string_alloc (aud_key,
410 sizeof(struct 394 sizeof(struct
411 GNUNET_IDENTITY_PublicKey)); 395 GNUNET_IDENTITY_PublicKey));
412 header = create_jwt_header ();
413 396
414 // aud REQUIRED public key client_id must be there 397 // aud REQUIRED public key client_id must be there
415 json_object_set_new (body, "aud", json_string (audience)); 398 json_object_set_new (body, "aud", json_string (audience));
@@ -429,19 +412,132 @@ OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key,
429 if (NULL != nonce) 412 if (NULL != nonce)
430 json_object_set_new (body, "nonce", json_string (nonce)); 413 json_object_set_new (body, "nonce", json_string (nonce));
431 414
432 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); 415 // Error checking
433 json_decref (body); 416 body_str = json_dumps (body, JSON_INDENT (2) | JSON_COMPACT);
434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str); 417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str);
435 418
419 json_decref (body);
420 GNUNET_free (subject);
421 GNUNET_free (audience);
422
423 return body_str;
424}
425
426
427/**
428 * Create a JWT using RSA256 algorithm from attributes
429 *
430 * @param aud_key the public of the audience
431 * @param sub_key the public key of the subject
432 * @param attrs the attribute list
433 * @param presentations credential presentation list (may be empty)
434 * @param expiration_time the validity of the token
435 * @param secret_rsa_key the key used to sign the JWT
436 * @return a new base64-encoded JWT string.
437 */
438char *
439OIDC_generate_id_token_rsa (const struct GNUNET_IDENTITY_PublicKey *aud_key,
440 const struct GNUNET_IDENTITY_PublicKey *sub_key,
441 const struct GNUNET_RECLAIM_AttributeList *attrs,
442 const struct
443 GNUNET_RECLAIM_PresentationList *presentations,
444 const struct GNUNET_TIME_Relative *expiration_time,
445 const char *nonce,
446 const json_t *secret_rsa_key)
447{
448 json_t *jws;
449 char *body_str;
450 char *result;
451
452 // Generate the body of the JSON Web Signature
453 body_str = generate_id_token_body (aud_key,
454 sub_key,
455 attrs,
456 presentations,
457 expiration_time,
458 nonce);
459
460 if (! body_str)
461 {
462 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
463 "Body for the JWS could not be generated\n");
464 }
465
466 // Creating the JSON Web Signature.
467 jws = json_pack ("{s:o}", "payload",
468 jose_b64_enc (body_str, strlen (body_str)));
469
470 if (! jose_jws_sig (NULL, jws, NULL, secret_rsa_key))
471 {
472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
473 "Signature generation failed\n");
474 }
475
476 // Encoding JSON as compact JSON Web Signature
477 GNUNET_asprintf (&result, "%s.%s.%s",
478 json_string_value (json_object_get (jws, "protected")),
479 json_string_value (json_object_get (jws, "payload")),
480 json_string_value (json_object_get (jws, "signature")) );
481
482 json_decref(jws);
483 GNUNET_free(body_str);
484 return result;
485}
486
487/**
488 * Create a JWT using HMAC (HS256) from attributes
489 *
490 * @param aud_key the public of the audience
491 * @param sub_key the public key of the subject
492 * @param attrs the attribute list
493 * @param presentations credential presentation list (may be empty)
494 * @param expiration_time the validity of the token
495 * @param secret_key the key used to sign the JWT
496 * @return a new base64-encoded JWT string.
497 */
498char *
499OIDC_generate_id_token_hmac (const struct GNUNET_IDENTITY_PublicKey *aud_key,
500 const struct GNUNET_IDENTITY_PublicKey *sub_key,
501 const struct GNUNET_RECLAIM_AttributeList *attrs,
502 const struct
503 GNUNET_RECLAIM_PresentationList *presentations,
504 const struct GNUNET_TIME_Relative *expiration_time,
505 const char *nonce,
506 const char *secret_key)
507{
508 struct GNUNET_HashCode signature;
509 struct GNUNET_TIME_Absolute exp_time;
510 struct GNUNET_TIME_Absolute time_now;
511 char *header;
512 char *header_base64;
513 char *body_str;
514 char *body_base64;
515 char *signature_target;
516 char *signature_base64;
517 char *result;
518
519 // Generate and encode Header
520 header = create_jwt_hmac_header ();
436 GNUNET_STRINGS_base64url_encode (header, strlen (header), &header_base64); 521 GNUNET_STRINGS_base64url_encode (header, strlen (header), &header_base64);
437 fix_base64 (header_base64); 522 fix_base64 (header_base64);
438 523
524 // Generate and encode the body of the JSON Web Signature
525 body_str = generate_id_token_body (aud_key,
526 sub_key,
527 attrs,
528 presentations,
529 expiration_time,
530 nonce);
531
532 if (! body_str)
533 {
534 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
535 "Body for the JWS could not be generated\n");
536 }
537
439 GNUNET_STRINGS_base64url_encode (body_str, strlen (body_str), &body_base64); 538 GNUNET_STRINGS_base64url_encode (body_str, strlen (body_str), &body_base64);
440 fix_base64 (body_base64); 539 fix_base64 (body_base64);
441 540
442 GNUNET_free (subject);
443 GNUNET_free (audience);
444
445 /** 541 /**
446 * Creating the JWT signature. This might not be 542 * Creating the JWT signature. This might not be
447 * standards compliant, check. 543 * standards compliant, check.
@@ -463,12 +559,12 @@ OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key,
463 body_base64, 559 body_base64,
464 signature_base64); 560 signature_base64);
465 561
466 GNUNET_free (signature_target);
467 GNUNET_free (header); 562 GNUNET_free (header);
563 GNUNET_free (header_base64);
468 GNUNET_free (body_str); 564 GNUNET_free (body_str);
469 GNUNET_free (signature_base64);
470 GNUNET_free (body_base64); 565 GNUNET_free (body_base64);
471 GNUNET_free (header_base64); 566 GNUNET_free (signature_target);
567 GNUNET_free (signature_base64);
472 return result; 568 return result;
473} 569}
474 570