GNUnet  0.11.x
oidc_helper.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2010-2015 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #include "platform.h"
27 #include <inttypes.h>
28 #include <jansson.h>
29 #include "gnunet_util_lib.h"
30 #include "gnunet_reclaim_lib.h"
31 #include "gnunet_reclaim_service.h"
32 #include "gnunet_signatures.h"
33 #include "oidc_helper.h"
34 // #include "benchmark.h"
35 #include <gcrypt.h>
36 
38 
43 {
48 
52  uint32_t nonce GNUNET_PACKED;
53 
58 
63 
68 };
69 
71 
72 static char *
74 {
75  json_t *root;
76  char *json_str;
77 
78  root = json_object ();
79  json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
80  json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
81 
82  json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT);
83  json_decref (root);
84  return json_str;
85 }
86 
87 
88 static void
89 replace_char (char *str, char find, char replace)
90 {
91  char *current_pos = strchr (str, find);
92 
93  while (current_pos)
94  {
95  *current_pos = replace;
96  current_pos = strchr (current_pos, find);
97  }
98 }
99 
100 
101 // RFC4648
102 static void
103 fix_base64 (char *str)
104 {
105  // Replace + with -
106  replace_char (str, '+', '-');
107 
108  // Replace / with _
109  replace_char (str, '/', '_');
110 }
111 
112 
123 char *
125  const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
126  struct GNUNET_RECLAIM_AttributeList *attrs,
127  struct GNUNET_RECLAIM_AttestationList *attests,
128  const struct GNUNET_TIME_Relative *expiration_time,
129  const char *nonce,
130  const char *secret_key)
131 {
134  struct GNUNET_HashCode signature;
135  struct GNUNET_TIME_Absolute exp_time;
136  struct GNUNET_TIME_Absolute time_now;
137  char *audience;
138  char *subject;
139  char *header;
140  char *body_str;
141  char *aggr_names_str;
142  char *aggr_sources_str;
143  char *aggr_sources_jwt_str;
144  char *source_name;
145  char *result;
146  char *header_base64;
147  char *body_base64;
148  char *signature_target;
149  char *signature_base64;
150  char *attr_val_str;
151  char *attest_val_str;
152  json_t *body;
153  json_t *aggr_names;
154  json_t *aggr_sources;
155  json_t *aggr_sources_jwt;
156  int num_attestations = 0;
157  for (le = attrs->list_head; NULL != le; le = le->next)
158  {
160  num_attestations++;
161  }
162 
163  // iat REQUIRED time now
164  time_now = GNUNET_TIME_absolute_get ();
165  // exp REQUIRED time expired from config
166  exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time);
167  // auth_time only if max_age
168  // nonce only if nonce
169  // OPTIONAL acr,amr,azp
170  subject =
172  sizeof(struct
174  audience =
176  sizeof(struct
178  header = create_jwt_header ();
179  body = json_object ();
180  aggr_names = json_object ();
181  aggr_sources = json_object ();
182 
183  // iss REQUIRED case sensitive server uri with https
184  // The issuer is the local reclaim instance (e.g.
185  // https://reclaim.id/api/openid)
186  json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
187  // sub REQUIRED public key identity, not exceed 255 ASCII length
188  json_object_set_new (body, "sub", json_string (subject));
189  // aud REQUIRED public key client_id must be there
190  json_object_set_new (body, "aud", json_string (audience));
191  // iat
192  json_object_set_new (body,
193  "iat",
194  json_integer (time_now.abs_value_us / (1000 * 1000)));
195  // exp
196  json_object_set_new (body,
197  "exp",
198  json_integer (exp_time.abs_value_us / (1000 * 1000)));
199  // nbf
200  json_object_set_new (body,
201  "nbf",
202  json_integer (time_now.abs_value_us / (1000 * 1000)));
203  // nonce
204  if (NULL != nonce)
205  json_object_set_new (body, "nonce", json_string (nonce));
206  attest_val_str = NULL;
207  aggr_names_str = NULL;
208  aggr_sources_str = NULL;
209  aggr_sources_jwt_str = NULL;
210  source_name = NULL;
211  int i = 0;
212  for (ale = attests->list_head; NULL != ale; ale = ale->next)
213  {
214  // New Attestation
215  GNUNET_asprintf (&source_name,
216  "src%d",
217  i);
218  aggr_sources_jwt = json_object ();
219  attest_val_str =
221  ale->attestation->data,
222  ale->attestation->data_size);
223  json_object_set_new (aggr_sources_jwt, "JWT",
224  json_string (attest_val_str) );
225  aggr_sources_jwt_str = json_dumps (aggr_sources_jwt, JSON_INDENT (0)
226  | JSON_COMPACT);
227  json_object_set_new (aggr_sources, source_name,json_string (
228  aggr_sources_jwt_str));
229  i++;
230  }
231 
232  for (le = attrs->list_head; NULL != le; le = le->next)
233  {
234 
236  {
237 
238  attr_val_str =
240  le->attribute->data,
241  le->attribute->data_size);
242  json_object_set_new (body, le->attribute->name,
243  json_string (attr_val_str));
244  GNUNET_free (attr_val_str);
245  }
246  else
247  {
248  // Check if attest is there
249  int j = 0;
250  for (ale = attests->list_head; NULL != ale; ale = ale->next)
251  {
252  if (GNUNET_YES ==
254  &le->attribute->attestation))
255  break;
256  j++;
257  }
258  GNUNET_assert (NULL != ale);
259  // Attestation is existing, hence take the respective source str
260  GNUNET_asprintf (&source_name,
261  "src%d",
262  j);
263  json_object_set_new (aggr_names, le->attribute->data,
264  json_string (source_name));
265  }
266  }
267 
268  if (NULL != attest_val_str)
269  GNUNET_free (attest_val_str);
270  if (NULL != source_name)
271  GNUNET_free (source_name);
272  if (0 != i)
273  {
274  aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT);
275  aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0)
276  | JSON_COMPACT);
277  json_object_set_new (body, "_claim_names", json_string (aggr_names_str));
278  json_object_set_new (body, "_claim_sources", json_string (
279  aggr_sources_str));
280  }
281 
282  json_decref (aggr_names);
283  json_decref (aggr_sources);
284  json_decref (aggr_sources_jwt);
285 
286  body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
287  json_decref (body);
288  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str);
289 
290  GNUNET_STRINGS_base64url_encode (header, strlen (header), &header_base64);
291  fix_base64 (header_base64);
292 
293  GNUNET_STRINGS_base64url_encode (body_str, strlen (body_str), &body_base64);
294  fix_base64 (body_base64);
295 
296  GNUNET_free (subject);
297  GNUNET_free (audience);
298 
303  GNUNET_asprintf (&signature_target, "%s.%s", header_base64, body_base64);
304  GNUNET_CRYPTO_hmac_raw (secret_key,
305  strlen (secret_key),
306  signature_target,
307  strlen (signature_target),
308  &signature);
309  GNUNET_STRINGS_base64url_encode ((const char *) &signature,
310  sizeof(struct GNUNET_HashCode),
311  &signature_base64);
312  fix_base64 (signature_base64);
313 
314  GNUNET_asprintf (&result,
315  "%s.%s.%s",
316  header_base64,
317  body_base64,
318  signature_base64);
319 
320  GNUNET_free (signature_target);
321  GNUNET_free (header);
322  GNUNET_free (body_str);
323  if (NULL != aggr_sources_str)
324  GNUNET_free (aggr_sources_str);
325  if (NULL != aggr_names_str)
326  GNUNET_free (aggr_names_str);
327  if (NULL != aggr_sources_jwt_str)
328  GNUNET_free (aggr_sources_jwt_str);
329  GNUNET_free (signature_base64);
330  GNUNET_free (body_base64);
331  GNUNET_free (header_base64);
332  return result;
333 }
334 
335 
336 static void
339  struct GNUNET_HashCode *key_material)
340 {
341  static const char ctx_key[] = "reclaim-aes-ctx-key";
342  static const char ctx_iv[] = "reclaim-aes-ctx-iv";
343 
344  GNUNET_CRYPTO_kdf (key,
345  sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
346  ctx_key,
347  strlen (ctx_key),
348  key_material,
349  sizeof(struct GNUNET_HashCode),
350  NULL);
351  GNUNET_CRYPTO_kdf (iv,
352  sizeof(
354  ctx_iv,
355  strlen (ctx_iv),
356  key_material,
357  sizeof(struct GNUNET_HashCode),
358  NULL);
359 }
360 
361 
362 static void
365  const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
366  const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub)
367 {
368  struct GNUNET_HashCode key_material;
369 
370  GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material);
371  derive_aes_key (key, iv, &key_material);
372 }
373 
374 
375 static void
378  const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
379  const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv)
380 {
381  struct GNUNET_HashCode key_material;
382 
383  GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material);
384  derive_aes_key (key, iv, &key_material);
385 }
386 
387 
388 static void
390  const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub,
391  const char *ct,
392  size_t ct_len,
393  char *buf)
394 {
397 
398  calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub);
399  GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf));
400 }
401 
402 
403 static void
405  const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv,
406  const char *payload,
407  size_t payload_len,
408  char *buf)
409 {
412 
413  calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv);
414  GNUNET_break (
415  GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
416 }
417 
418 
430 char *
432  const struct GNUNET_RECLAIM_Ticket *ticket,
433  struct GNUNET_RECLAIM_AttributeList *attrs,
434  struct GNUNET_RECLAIM_AttestationList *attests,
435  const char *nonce_str,
436  const char *code_challenge)
437 {
438  struct OIDC_Parameters params;
439  char *code_payload;
440  char *payload;
441  char *tmp;
442  char *code_str;
443  char *buf_ptr = NULL;
444  size_t payload_len;
445  size_t code_payload_len;
446  size_t attr_list_len = 0;
447  size_t attests_list_len = 0;
448  size_t code_challenge_len = 0;
449  uint32_t nonce;
450  uint32_t nonce_tmp;
452  struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv;
453  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub;
454 
456  // Assign ticket
457  memset (&params, 0, sizeof(params));
458  params.ticket = *ticket;
459  // Assign nonce
460  nonce = 0;
461  payload_len = sizeof(struct OIDC_Parameters);
462  if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0))
463  {
464  if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
465  {
466  GNUNET_break (0);
467  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
468  return NULL;
469  }
471  "Got nonce: %u from %s\n",
472  nonce,
473  nonce_str);
474  }
475  nonce_tmp = htonl (nonce);
476  params.nonce = nonce_tmp;
477  // Assign code challenge
478  if (NULL != code_challenge)
479  code_challenge_len = strlen (code_challenge);
480  payload_len += code_challenge_len;
481  params.code_challenge_len = htonl (code_challenge_len);
482  // Assign attributes
483  if (NULL != attrs)
484  {
485  // Get length
486  attr_list_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
487  params.attr_list_len = htonl (attr_list_len);
489  "Length of serialized attributes: %lu\n",
490  attr_list_len);
491  // Get serialized attributes
492  payload_len += attr_list_len;
493  }
494  if (NULL != attests)
495  {
496  // Get length
497  attests_list_len =
499  params.attest_list_len = htonl (attests_list_len);
501  "Length of serialized attestations: %lu\n",
502  attests_list_len);
503  // Get serialized attributes
504  payload_len += attests_list_len;
505  }
506 
507  // Get plaintext length
508  payload = GNUNET_malloc (payload_len);
509  memcpy (payload, &params, sizeof(params));
510  tmp = payload + sizeof(params);
511  if (0 < code_challenge_len)
512  {
513  memcpy (tmp, code_challenge, code_challenge_len);
514  tmp += code_challenge_len;
515  }
516  if (0 < attr_list_len)
518  if (0 < attests_list_len)
520 
524  // Get length
525  code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
526  + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
527  + payload_len + sizeof(struct
528  GNUNET_CRYPTO_EcdsaSignature);
530  "Length of data to encode: %lu\n",
531  code_payload_len);
532 
533  // Generate ECDH key
534  ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create ();
535  GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub);
536  // Initialize code payload
537  code_payload = GNUNET_malloc (code_payload_len);
538  GNUNET_assert (NULL != code_payload);
539  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
540  purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
541  + sizeof(ecdh_pub) + payload_len);
543  // Store pubkey
544  buf_ptr = (char *) &purpose[1];
545  memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub));
546  buf_ptr += sizeof(ecdh_pub);
547  // Encrypt plaintext and store
548  encrypt_payload (&ticket->audience, ecdh_priv, payload, payload_len, buf_ptr);
549  GNUNET_free (ecdh_priv);
550  GNUNET_free (payload);
551  buf_ptr += payload_len;
552  // Sign and store signature
553  if (GNUNET_SYSERR ==
554  GNUNET_CRYPTO_ecdsa_sign (issuer,
555  purpose,
556  (struct GNUNET_CRYPTO_EcdsaSignature *)
557  buf_ptr))
558  {
559  GNUNET_break (0);
560  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
561  GNUNET_free (code_payload);
562  return NULL;
563  }
564  GNUNET_STRINGS_base64url_encode (code_payload, code_payload_len, &code_str);
565  GNUNET_free (code_payload);
566  return code_str;
567 }
568 
569 
583 int
585  const char *code,
586  const char *code_verifier,
588  struct GNUNET_RECLAIM_AttributeList **attrs,
589  struct GNUNET_RECLAIM_AttestationList **attests,
590  char **nonce_str)
591 {
592  char *code_payload;
593  char *ptr;
594  char *plaintext;
595  char *attrs_ser;
596  char *expected_code_challenge;
597  char *code_challenge;
598  char *code_verifier_hash;
600  struct GNUNET_CRYPTO_EcdsaSignature *signature;
601  struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
602  struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub;
603  uint32_t code_challenge_len;
604  uint32_t attrs_ser_len;
605  size_t plaintext_len;
606  size_t code_payload_len;
607  uint32_t nonce = 0;
608  struct OIDC_Parameters *params;
609 
610  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
611  code_payload = NULL;
612  code_payload_len =
613  GNUNET_STRINGS_base64url_decode (code, strlen (code),
614  (void **) &code_payload);
615  if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
616  + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
617  + sizeof(struct OIDC_Parameters)
618  + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
619  {
620  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n");
621  GNUNET_free_non_null (code_payload);
622  return GNUNET_SYSERR;
623  }
624 
625  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
626  plaintext_len = code_payload_len;
627  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose);
628  ptr = (char *) &purpose[1];
629  // Public ECDH key
630  ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
631  ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
632  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
633 
634  // Decrypt ciphertext
635  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
636  plaintext = GNUNET_malloc (plaintext_len);
637  decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
638  // ptr = plaintext;
639  ptr += plaintext_len;
640  signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr;
641  params = (struct OIDC_Parameters *) plaintext;
642 
643  // cmp code_challenge code_verifier
644  code_challenge_len = ntohl (params->code_challenge_len);
645  if (0 != code_challenge_len) /* Only check if this code requires a CV */
646  {
647  if (NULL == code_verifier)
648  {
650  "Expected code verifier!\n");
651  GNUNET_free_non_null (code_payload);
652  return GNUNET_SYSERR;
653  }
654  code_verifier_hash = GNUNET_malloc (256 / 8);
655  // hash code verifier
656  gcry_md_hash_buffer (GCRY_MD_SHA256,
657  code_verifier_hash,
658  code_verifier,
659  strlen (code_verifier));
660  // encode code verifier
661  GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, &expected_code_challenge);
662  code_challenge = (char *) &params[1];
663  GNUNET_free (code_verifier_hash);
664  if ((strlen (expected_code_challenge) != code_challenge_len) ||
665  (0 !=
666  strncmp (expected_code_challenge, code_challenge, code_challenge_len)))
667  {
669  "Invalid code verifier! Expected: %s, Got: %.*s\n",
670  expected_code_challenge,
671  code_challenge_len,
672  code_challenge);
673  GNUNET_free_non_null (code_payload);
674  GNUNET_free (expected_code_challenge);
675  return GNUNET_SYSERR;
676  }
677  GNUNET_free (expected_code_challenge);
678  }
679  // Ticket
680  memcpy (ticket, &params->ticket, sizeof(params->ticket));
681  // Nonce
682  nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr));
683  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
684  // Signature
685  GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
686  if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience))
687  {
688  GNUNET_free (code_payload);
689  GNUNET_free (plaintext);
691  "Audience in ticket does not match client!\n");
692  return GNUNET_SYSERR;
693  }
694  if (GNUNET_OK !=
696  purpose,
697  signature,
698  &ticket->identity))
699  {
700  GNUNET_free (code_payload);
701  GNUNET_free (plaintext);
702  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
703  return GNUNET_SYSERR;
704  }
705  // Attributes
706  attrs_ser = ((char *) &params[1]) + code_challenge_len;
707  attrs_ser_len = ntohl (params->attr_list_len);
708  *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len);
709 
710  *nonce_str = NULL;
711  if (nonce != 0)
712  GNUNET_asprintf (nonce_str, "%u", nonce);
713  GNUNET_free (code_payload);
714  GNUNET_free (plaintext);
715  return GNUNET_OK;
716 }
717 
718 
728 void
729 OIDC_build_token_response (const char *access_token,
730  const char *id_token,
731  const struct GNUNET_TIME_Relative *expiration_time,
732  char **token_response)
733 {
734  json_t *root_json;
735 
736  root_json = json_object ();
737 
738  GNUNET_assert (NULL != access_token);
739  GNUNET_assert (NULL != id_token);
740  GNUNET_assert (NULL != expiration_time);
741  json_object_set_new (root_json, "access_token", json_string (access_token));
742  json_object_set_new (root_json, "token_type", json_string ("Bearer"));
743  json_object_set_new (root_json,
744  "expires_in",
745  json_integer (expiration_time->rel_value_us
746  / (1000 * 1000)));
747  json_object_set_new (root_json, "id_token", json_string (id_token));
748  *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
749  json_decref (root_json);
750 }
751 
752 
756 char *
758 {
759  char *access_token;
760  uint64_t random_number;
761 
762  random_number =
764  GNUNET_STRINGS_base64_encode (&random_number,
765  sizeof(uint64_t),
766  &access_token);
767  return access_token;
768 }
int GNUNET_CRYPTO_ecdsa_ecdh(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private ECDSA key.
Definition: crypto_ecc.c:1071
size_t GNUNET_RECLAIM_attestation_list_serialize(const struct GNUNET_RECLAIM_AttestationList *attrs, char *result)
Serialize an attribute list.
The authorization ticket.
static void calculate_key_pub(struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv)
Definition: oidc_helper.c:376
char * OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, struct GNUNET_RECLAIM_AttributeList *attrs, struct GNUNET_RECLAIM_AttestationList *attests, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key)
Create a JWT from attributes.
Definition: oidc_helper.c:124
uint64_t rel_value_us
The actual value.
static void encrypt_payload(const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv, const char *payload, size_t payload_len, char *buf)
Definition: oidc_helper.c:404
int GNUNET_CRYPTO_ecdh_ecdsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EcDSA public key and a private ECDH key.
Definition: crypto_ecc.c:1126
int GNUNET_CRYPTO_ecdsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Verify ECDSA signature.
Definition: crypto_ecc.c:776
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
#define JWT_ALG_VALUE
Definition: oidc_helper.h:33
static void derive_aes_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, struct GNUNET_HashCode *key_material)
Definition: oidc_helper.c:337
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_AttributeList *attrs, struct GNUNET_RECLAIM_AttestationList *attests, const char *nonce_str, const char *code_challenge)
Builds an OIDC authorization code including a reclaim ticket and nonce.
Definition: oidc_helper.c:431
uint32_t nonce
The nonce.
Definition: oidc_helper.c:52
void GNUNET_CRYPTO_hmac_raw(const void *key, size_t key_len, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104) TODO: Shouldn&#39; this be the standard hmac function and the abov...
Definition: crypto_hash.c:403
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
const char * name
The name of the attribute.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_RECLAIM_AttributeList * GNUNET_RECLAIM_attribute_list_deserialize(const char *data, size_t data_size)
Deserialize an attribute list.
uint32_t attr_list_len
The length of the attributes list.
Definition: oidc_helper.c:62
struct GNUNET_RECLAIM_Attestation * attestation
The attestation.
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create(void)
Create a new private key.
Definition: crypto_ecc.c:499
helper library for OIDC related functions
#define GNUNET_NO
Definition: gnunet_common.h:86
A list of GNUNET_RECLAIM_Attribute structures.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
A list of GNUNET_RECLAIM_Attestation structures.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:395
Private ECC key encoded for transmission.
#define SERVER_ADDRESS
Definition: oidc_helper.h:39
void OIDC_build_token_response(const char *access_token, const char *id_token, const struct GNUNET_TIME_Relative *expiration_time, char **token_response)
Build a token response for a token request TODO: Maybe we should add the scope here?
Definition: oidc_helper.c:729
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
static void decrypt_payload(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub, const char *ct, size_t ct_len, char *buf)
Definition: oidc_helper.c:389
size_t GNUNET_STRINGS_base64url_encode(const void *in, size_t len, char **output)
Encode into Base64url.
Definition: strings.c:1930
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
char * GNUNET_RECLAIM_attestation_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the &#39;claim&#39; of an attestation to a string.
struct GNUNET_RECLAIM_Identifier attestation
Referenced ID of Attestation (may be 0 if self-attested)
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
int GNUNET_CRYPTO_ecdsa_sign(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
Definition: crypto_ecc.c:687
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
int OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, const char *code, const char *code_verifier, struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_AttributeList **attrs, struct GNUNET_RECLAIM_AttestationList **attests, char **nonce_str)
Parse reclaim ticket and nonce from authorization code.
Definition: oidc_helper.c:584
#define GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN
Signature for a GNUid Ticket.
static void replace_char(char *str, char find, char replace)
Definition: oidc_helper.c:89
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
uint32_t code_challenge_len
The length of the PKCE code_challenge.
Definition: oidc_helper.c:57
Randomness for IVs etc.
an ECC signature using ECDSA
#define JWT_TYP
Definition: oidc_helper.h:35
static char buf[2048]
static int result
Global testing status.
size_t data_size
Number of bytes in data.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
size_t data_size
Number of bytes in data.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static void fix_base64(char *str)
Definition: oidc_helper.c:103
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1874
struct GNUNET_RECLAIM_Identifier id
ID.
Private ECC key encoded for transmission.
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
uint32_t type
Type/Format of Claim.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:172
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:206
size_t GNUNET_RECLAIM_attribute_list_serialize(const struct GNUNET_RECLAIM_AttributeList *attrs, char *result)
Serialize an attribute list.
struct GNUNET_RECLAIM_AttestationListEntry * list_head
List head.
struct GNUNET_RECLAIM_AttributeListEntry * next
DLL.
static unsigned long long payload
How much data are we currently storing in the database?
static GNUNET_NETWORK_STRUCT_END char * create_jwt_header(void)
Definition: oidc_helper.c:73
uint32_t attest_list_len
The length of the attestation list.
Definition: oidc_helper.c:67
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
const void * data
Binary value stored as attribute value.
static char * subject
Subject pubkey string.
Definition: gnunet-abd.c:86
char * OIDC_access_token_new()
Generate a new access token.
Definition: oidc_helper.c:757
#define GNUNET_PACKED
gcc-ism to get packed structs.
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_RECLAIM_id_is_equal(a, b)
static void calculate_key_priv(struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub)
Definition: oidc_helper.c:363
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
#define GNUNET_log(kind,...)
const void * data
Binary value stored as attribute value.
char * GNUNET_RECLAIM_attribute_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the &#39;claim&#39; of an attribute to a string.
size_t GNUNET_RECLAIM_attribute_list_serialize_get_size(const struct GNUNET_RECLAIM_AttributeList *attrs)
Get required size for serialization buffer.
uint32_t type
Type of Claim.
#define JWT_ALG
Definition: oidc_helper.h:30
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:85
struct GNUNET_RECLAIM_AttestationListEntry * next
DLL.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:935
#define JWT_TYP_VALUE
Definition: oidc_helper.h:37
struct GNUNET_RECLAIM_Ticket ticket
The reclaim ticket.
Definition: oidc_helper.c:47
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
size_t GNUNET_RECLAIM_attestation_list_serialize_get_size(const struct GNUNET_RECLAIM_AttestationList *attestations)
Get required size for serialization buffer.
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:89
size_t GNUNET_STRINGS_base64url_decode(const char *data, size_t len, void **out)
Decode from Base64url.
Definition: strings.c:2048
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
The signature used to generate the authorization code.
Definition: oidc_helper.c:42
#define GNUNET_RECLAIM_id_is_zero(a)