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 *source_name;
144  char *result;
145  char *header_base64;
146  char *body_base64;
147  char *signature_target;
148  char *signature_base64;
149  char *attr_val_str;
150  char *attest_val_str;
151  json_t *body;
152  json_t *aggr_names;
153  json_t *aggr_sources;
154  json_t *aggr_sources_jwt;
155  int num_attestations = 0;
156  for (le = attrs->list_head; NULL != le; le = le->next)
157  {
159  num_attestations++;
160  }
161 
162  // iat REQUIRED time now
163  time_now = GNUNET_TIME_absolute_get ();
164  // exp REQUIRED time expired from config
165  exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time);
166  // auth_time only if max_age
167  // nonce only if nonce
168  // OPTIONAL acr,amr,azp
169  subject =
171  sizeof(struct
173  audience =
175  sizeof(struct
177  header = create_jwt_header ();
178  body = json_object ();
179  aggr_names = json_object ();
180  aggr_sources = json_object ();
181 
182  // iss REQUIRED case sensitive server uri with https
183  // The issuer is the local reclaim instance (e.g.
184  // https://reclaim.id/api/openid)
185  json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
186  // sub REQUIRED public key identity, not exceed 255 ASCII length
187  json_object_set_new (body, "sub", json_string (subject));
188  // aud REQUIRED public key client_id must be there
189  json_object_set_new (body, "aud", json_string (audience));
190  // iat
191  json_object_set_new (body,
192  "iat",
193  json_integer (time_now.abs_value_us / (1000 * 1000)));
194  // exp
195  json_object_set_new (body,
196  "exp",
197  json_integer (exp_time.abs_value_us / (1000 * 1000)));
198  // nbf
199  json_object_set_new (body,
200  "nbf",
201  json_integer (time_now.abs_value_us / (1000 * 1000)));
202  // nonce
203  if (NULL != nonce)
204  json_object_set_new (body, "nonce", json_string (nonce));
205  attest_val_str = NULL;
206  aggr_names_str = NULL;
207  aggr_sources_str = NULL;
208  source_name = NULL;
209  int i = 0;
210  for (ale = attests->list_head; NULL != ale; ale = ale->next)
211  {
212  // New Attestation
213  GNUNET_asprintf (&source_name,
214  "src%d",
215  i);
216  aggr_sources_jwt = json_object ();
217  attest_val_str =
219  ale->attestation->data,
220  ale->attestation->data_size);
221  json_object_set_new (aggr_sources_jwt, "JWT",
222  json_string (attest_val_str) );
223  json_object_set_new (aggr_sources, source_name, aggr_sources_jwt);
224  GNUNET_free (source_name);
225  source_name = NULL;
226  i++;
227  }
228 
229  for (le = attrs->list_head; NULL != le; le = le->next)
230  {
231 
233  {
234 
235  attr_val_str =
237  le->attribute->data,
238  le->attribute->data_size);
239  json_object_set_new (body, le->attribute->name,
240  json_string (attr_val_str));
241  GNUNET_free (attr_val_str);
242  }
243  else
244  {
245  // Check if attest is there
246  int j = 0;
247  for (ale = attests->list_head; NULL != ale; ale = ale->next)
248  {
249  if (GNUNET_YES ==
251  &le->attribute->attestation))
252  break;
253  j++;
254  }
255  GNUNET_assert (NULL != ale);
256  // Attestation is existing, hence take the respective source str
257  GNUNET_asprintf (&source_name,
258  "src%d",
259  j);
260  json_object_set_new (aggr_names, le->attribute->data,
261  json_string (source_name));
262  GNUNET_free (source_name);
263  }
264  }
265 
266  if (NULL != attest_val_str)
267  GNUNET_free (attest_val_str);
268  if (0 != i)
269  {
270  aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT);
271  aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0)
272  | JSON_COMPACT);
273  json_object_set_new (body, "_claim_names", json_string (aggr_names_str));
274  json_object_set_new (body, "_claim_sources", json_string (
275  aggr_sources_str));
276  }
277 
278  json_decref (aggr_names);
279  json_decref (aggr_sources);
280 
281  body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
282  json_decref (body);
283  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str);
284 
285  GNUNET_STRINGS_base64url_encode (header, strlen (header), &header_base64);
286  fix_base64 (header_base64);
287 
288  GNUNET_STRINGS_base64url_encode (body_str, strlen (body_str), &body_base64);
289  fix_base64 (body_base64);
290 
291  GNUNET_free (subject);
292  GNUNET_free (audience);
293 
298  GNUNET_asprintf (&signature_target, "%s.%s", header_base64, body_base64);
299  GNUNET_CRYPTO_hmac_raw (secret_key,
300  strlen (secret_key),
301  signature_target,
302  strlen (signature_target),
303  &signature);
304  GNUNET_STRINGS_base64url_encode ((const char *) &signature,
305  sizeof(struct GNUNET_HashCode),
306  &signature_base64);
307  fix_base64 (signature_base64);
308 
309  GNUNET_asprintf (&result,
310  "%s.%s.%s",
311  header_base64,
312  body_base64,
313  signature_base64);
314 
315  GNUNET_free (signature_target);
316  GNUNET_free (header);
317  GNUNET_free (body_str);
318  if (NULL != aggr_sources_str)
319  GNUNET_free (aggr_sources_str);
320  if (NULL != aggr_names_str)
321  GNUNET_free (aggr_names_str);
322  GNUNET_free (signature_base64);
323  GNUNET_free (body_base64);
324  GNUNET_free (header_base64);
325  return result;
326 }
327 
328 
329 static void
332  struct GNUNET_HashCode *key_material)
333 {
334  static const char ctx_key[] = "reclaim-aes-ctx-key";
335  static const char ctx_iv[] = "reclaim-aes-ctx-iv";
336 
337  GNUNET_CRYPTO_kdf (key,
338  sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
339  ctx_key,
340  strlen (ctx_key),
341  key_material,
342  sizeof(struct GNUNET_HashCode),
343  NULL);
344  GNUNET_CRYPTO_kdf (iv,
345  sizeof(
347  ctx_iv,
348  strlen (ctx_iv),
349  key_material,
350  sizeof(struct GNUNET_HashCode),
351  NULL);
352 }
353 
354 
355 static void
358  const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
359  const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub)
360 {
361  struct GNUNET_HashCode key_material;
362 
363  GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material);
364  derive_aes_key (key, iv, &key_material);
365 }
366 
367 
368 static void
371  const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
372  const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv)
373 {
374  struct GNUNET_HashCode key_material;
375 
376  GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material);
377  derive_aes_key (key, iv, &key_material);
378 }
379 
380 
381 static void
383  const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub,
384  const char *ct,
385  size_t ct_len,
386  char *buf)
387 {
390 
391  calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub);
392  GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf));
393 }
394 
395 
396 static void
398  const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv,
399  const char *payload,
400  size_t payload_len,
401  char *buf)
402 {
405 
406  calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv);
407  GNUNET_break (
408  GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
409 }
410 
411 
423 char *
425  const struct GNUNET_RECLAIM_Ticket *ticket,
426  struct GNUNET_RECLAIM_AttributeList *attrs,
427  struct GNUNET_RECLAIM_AttestationList *attests,
428  const char *nonce_str,
429  const char *code_challenge)
430 {
431  struct OIDC_Parameters params;
432  char *code_payload;
433  char *payload;
434  char *tmp;
435  char *code_str;
436  char *buf_ptr = NULL;
437  size_t payload_len;
438  size_t code_payload_len;
439  size_t attr_list_len = 0;
440  size_t attests_list_len = 0;
441  size_t code_challenge_len = 0;
442  uint32_t nonce;
443  uint32_t nonce_tmp;
445  struct GNUNET_CRYPTO_EcdhePrivateKey ecdh_priv;
446  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub;
447 
449  // Assign ticket
450  memset (&params, 0, sizeof(params));
451  params.ticket = *ticket;
452  // Assign nonce
453  nonce = 0;
454  payload_len = sizeof(struct OIDC_Parameters);
455  if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0))
456  {
457  if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
458  {
459  GNUNET_break (0);
460  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
461  return NULL;
462  }
464  "Got nonce: %u from %s\n",
465  nonce,
466  nonce_str);
467  }
468  nonce_tmp = htonl (nonce);
469  params.nonce = nonce_tmp;
470  // Assign code challenge
471  if (NULL != code_challenge)
472  code_challenge_len = strlen (code_challenge);
473  payload_len += code_challenge_len;
474  params.code_challenge_len = htonl (code_challenge_len);
475  // Assign attributes
476  if (NULL != attrs)
477  {
478  // Get length
479  attr_list_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
480  params.attr_list_len = htonl (attr_list_len);
482  "Length of serialized attributes: %lu\n",
483  attr_list_len);
484  // Get serialized attributes
485  payload_len += attr_list_len;
486  }
487  if (NULL != attests)
488  {
489  // Get length
490  attests_list_len =
492  params.attest_list_len = htonl (attests_list_len);
494  "Length of serialized attestations: %lu\n",
495  attests_list_len);
496  // Get serialized attributes
497  payload_len += attests_list_len;
498  }
499 
500  // Get plaintext length
501  payload = GNUNET_malloc (payload_len);
502  memcpy (payload, &params, sizeof(params));
503  tmp = payload + sizeof(params);
504  if (0 < code_challenge_len)
505  {
506  memcpy (tmp, code_challenge, code_challenge_len);
507  tmp += code_challenge_len;
508  }
509  if (0 < attr_list_len)
511  if (0 < attests_list_len)
513 
517  // Get length
518  code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
519  + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
520  + payload_len + sizeof(struct
521  GNUNET_CRYPTO_EcdsaSignature);
523  "Length of data to encode: %lu\n",
524  code_payload_len);
525 
526  // Generate ECDH key
527  GNUNET_CRYPTO_ecdhe_key_create (&ecdh_priv);
528  GNUNET_CRYPTO_ecdhe_key_get_public (&ecdh_priv, &ecdh_pub);
529  // Initialize code payload
530  code_payload = GNUNET_malloc (code_payload_len);
531  GNUNET_assert (NULL != code_payload);
532  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
533  purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
534  + sizeof(ecdh_pub) + payload_len);
536  // Store pubkey
537  buf_ptr = (char *) &purpose[1];
538  memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub));
539  buf_ptr += sizeof(ecdh_pub);
540  // Encrypt plaintext and store
541  encrypt_payload (&ticket->audience,
542  &ecdh_priv,
543  payload,
544  payload_len,
545  buf_ptr);
546  GNUNET_free (payload);
547  buf_ptr += payload_len;
548  // Sign and store signature
549  if (GNUNET_SYSERR ==
551  purpose,
552  (struct GNUNET_CRYPTO_EcdsaSignature *)
553  buf_ptr))
554  {
555  GNUNET_break (0);
556  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
557  GNUNET_free (code_payload);
558  return NULL;
559  }
560  GNUNET_STRINGS_base64url_encode (code_payload, code_payload_len, &code_str);
561  GNUNET_free (code_payload);
562  return code_str;
563 }
564 
565 
579 int
581  const char *code,
582  const char *code_verifier,
584  struct GNUNET_RECLAIM_AttributeList **attrs,
585  struct GNUNET_RECLAIM_AttestationList **attests,
586  char **nonce_str)
587 {
588  char *code_payload;
589  char *ptr;
590  char *plaintext;
591  char *attrs_ser;
592  char *attests_ser;
593  char *expected_code_challenge;
594  char *code_challenge;
595  char *code_verifier_hash;
597  struct GNUNET_CRYPTO_EcdsaSignature *signature;
598  struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
599  struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub;
600  uint32_t code_challenge_len;
601  uint32_t attrs_ser_len;
602  uint32_t attests_ser_len;
603  size_t plaintext_len;
604  size_t code_payload_len;
605  uint32_t nonce = 0;
606  struct OIDC_Parameters *params;
607 
608  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
609  code_payload = NULL;
610  code_payload_len =
611  GNUNET_STRINGS_base64url_decode (code, strlen (code),
612  (void **) &code_payload);
613  if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
614  + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
615  + sizeof(struct OIDC_Parameters)
616  + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
617  {
618  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n");
619  GNUNET_free (code_payload);
620  return GNUNET_SYSERR;
621  }
622 
623  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
624  plaintext_len = code_payload_len;
625  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose);
626  ptr = (char *) &purpose[1];
627  // Public ECDH key
628  ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
629  ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
630  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
631 
632  // Decrypt ciphertext
633  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
634  plaintext = GNUNET_malloc (plaintext_len);
635  decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
636  // ptr = plaintext;
637  ptr += plaintext_len;
638  signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr;
639  params = (struct OIDC_Parameters *) plaintext;
640 
641  // cmp code_challenge code_verifier
642  code_challenge_len = ntohl (params->code_challenge_len);
643  if (0 != code_challenge_len) /* Only check if this code requires a CV */
644  {
645  if (NULL == code_verifier)
646  {
648  "Expected code verifier!\n");
649  GNUNET_free (code_payload);
650  return GNUNET_SYSERR;
651  }
652  code_verifier_hash = GNUNET_malloc (256 / 8);
653  // hash code verifier
654  gcry_md_hash_buffer (GCRY_MD_SHA256,
655  code_verifier_hash,
656  code_verifier,
657  strlen (code_verifier));
658  // encode code verifier
659  GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8,
660  &expected_code_challenge);
661  code_challenge = (char *) &params[1];
662  GNUNET_free (code_verifier_hash);
663  if ((strlen (expected_code_challenge) != code_challenge_len) ||
664  (0 !=
665  strncmp (expected_code_challenge, code_challenge, code_challenge_len)))
666  {
668  "Invalid code verifier! Expected: %s, Got: %.*s\n",
669  expected_code_challenge,
670  code_challenge_len,
671  code_challenge);
672  GNUNET_free (code_payload);
673  GNUNET_free (expected_code_challenge);
674  return GNUNET_SYSERR;
675  }
676  GNUNET_free (expected_code_challenge);
677  }
678  // Ticket
679  memcpy (ticket, &params->ticket, sizeof(params->ticket));
680  // Nonce
681  nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr));
682  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
683  // Signature
684  GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
685  if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience))
686  {
687  GNUNET_free (code_payload);
688  GNUNET_free (plaintext);
690  "Audience in ticket does not match client!\n");
691  return GNUNET_SYSERR;
692  }
693  if (GNUNET_OK !=
695  purpose,
696  signature,
697  &ticket->identity))
698  {
699  GNUNET_free (code_payload);
700  GNUNET_free (plaintext);
701  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
702  return GNUNET_SYSERR;
703  }
704  // Attributes
705  attrs_ser = ((char *) &params[1]) + code_challenge_len;
706  attrs_ser_len = ntohl (params->attr_list_len);
707  *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len);
708  attests_ser = ((char*) attrs_ser) + attrs_ser_len;
709  attests_ser_len = ntohl (params->attest_list_len);
710  *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser,
711  attests_ser_len);
712 
713  *nonce_str = NULL;
714  if (nonce != 0)
715  GNUNET_asprintf (nonce_str, "%u", nonce);
716  GNUNET_free (code_payload);
717  GNUNET_free (plaintext);
718  return GNUNET_OK;
719 }
720 
721 
731 void
732 OIDC_build_token_response (const char *access_token,
733  const char *id_token,
734  const struct GNUNET_TIME_Relative *expiration_time,
735  char **token_response)
736 {
737  json_t *root_json;
738 
739  root_json = json_object ();
740 
741  GNUNET_assert (NULL != access_token);
742  GNUNET_assert (NULL != id_token);
743  GNUNET_assert (NULL != expiration_time);
744  json_object_set_new (root_json, "access_token", json_string (access_token));
745  json_object_set_new (root_json, "token_type", json_string ("Bearer"));
746  json_object_set_new (root_json,
747  "expires_in",
748  json_integer (expiration_time->rel_value_us
749  / (1000 * 1000)));
750  json_object_set_new (root_json, "id_token", json_string (id_token));
751  *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
752  json_decref (root_json);
753 }
754 
755 
759 char *
761 {
762  char *access_token;
763  uint64_t random_number;
764 
765  random_number =
767  GNUNET_STRINGS_base64_encode (&random_number,
768  sizeof(uint64_t),
769  &access_token);
770  return access_token;
771 }
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:1056
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:369
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:397
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:1111
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:330
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:424
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:420
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.
helper library for OIDC related functions
A list of GNUNET_RECLAIM_Attribute structures.
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:732
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:382
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 ...
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:508
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:580
#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.
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:176
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:215
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.
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:645
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.
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:745
#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:760
#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:356
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.
struct GNUNET_RECLAIM_AttestationList * GNUNET_RECLAIM_attestation_list_deserialize(const char *data, size_t data_size)
Deserialize an attribute list.
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)