GNUnet  0.10.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"
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 };
64 
66 
67 static char *
69 {
70  json_t *root;
71  char *json_str;
72 
73  root = json_object ();
74  json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
75  json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
76 
77  json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT);
78  json_decref (root);
79  return json_str;
80 }
81 
82 static void
83 replace_char (char *str, char find, char replace)
84 {
85  char *current_pos = strchr (str, find);
86 
87  while (current_pos)
88  {
89  *current_pos = replace;
90  current_pos = strchr (current_pos, find);
91  }
92 }
93 
94 // RFC4648
95 static void
96 fix_base64 (char *str)
97 {
98  // Replace + with -
99  replace_char (str, '+', '-');
100 
101  // Replace / with _
102  replace_char (str, '/', '_');
103 }
104 
115 char *
117  const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
118  const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
119  const struct GNUNET_TIME_Relative *expiration_time,
120  const char *nonce,
121  const char *secret_key)
122 {
124  struct GNUNET_HashCode signature;
125  struct GNUNET_TIME_Absolute exp_time;
126  struct GNUNET_TIME_Absolute time_now;
127  char *audience;
128  char *subject;
129  char *header;
130  char *body_str;
131  char *result;
132  char *header_base64;
133  char *body_base64;
134  char *signature_target;
135  char *signature_base64;
136  char *attr_val_str;
137  json_t *body;
138 
139  // iat REQUIRED time now
140  time_now = GNUNET_TIME_absolute_get ();
141  // exp REQUIRED time expired from config
142  exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time);
143  // auth_time only if max_age
144  // nonce only if nonce
145  // OPTIONAL acr,amr,azp
146  subject =
148  sizeof(struct
150  audience =
152  sizeof(struct
154  header = create_jwt_header ();
155  body = json_object ();
156 
157  // iss REQUIRED case sensitive server uri with https
158  // The issuer is the local reclaim instance (e.g.
159  // https://reclaim.id/api/openid)
160  json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
161  // sub REQUIRED public key identity, not exceed 255 ASCII length
162  json_object_set_new (body, "sub", json_string (subject));
163  // aud REQUIRED public key client_id must be there
164  json_object_set_new (body, "aud", json_string (audience));
165  // iat
166  json_object_set_new (body,
167  "iat",
168  json_integer (time_now.abs_value_us / (1000 * 1000)));
169  // exp
170  json_object_set_new (body,
171  "exp",
172  json_integer (exp_time.abs_value_us / (1000 * 1000)));
173  // nbf
174  json_object_set_new (body,
175  "nbf",
176  json_integer (time_now.abs_value_us / (1000 * 1000)));
177  // nonce
178  if (NULL != nonce)
179  json_object_set_new (body, "nonce", json_string (nonce));
180 
181  for (le = attrs->list_head; NULL != le; le = le->next)
182  {
183  attr_val_str =
185  le->claim->data,
186  le->claim->data_size);
187  json_object_set_new (body, le->claim->name, json_string (attr_val_str));
188  GNUNET_free (attr_val_str);
189  }
190  body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
191  json_decref (body);
192 
193  GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64);
194  fix_base64 (header_base64);
195 
196  GNUNET_STRINGS_base64_encode (body_str, strlen (body_str), &body_base64);
197  fix_base64 (body_base64);
198 
199  GNUNET_free (subject);
200  GNUNET_free (audience);
201 
206  GNUNET_asprintf (&signature_target, "%s.%s", header_base64, body_base64);
207  GNUNET_CRYPTO_hmac_raw (secret_key,
208  strlen (secret_key),
209  signature_target,
210  strlen (signature_target),
211  &signature);
212  GNUNET_STRINGS_base64_encode ((const char *) &signature,
213  sizeof(struct GNUNET_HashCode),
214  &signature_base64);
215  fix_base64 (signature_base64);
216 
217  GNUNET_asprintf (&result,
218  "%s.%s.%s",
219  header_base64,
220  body_base64,
221  signature_base64);
222 
223  GNUNET_free (signature_target);
224  GNUNET_free (header);
225  GNUNET_free (body_str);
226  GNUNET_free (signature_base64);
227  GNUNET_free (body_base64);
228  GNUNET_free (header_base64);
229  return result;
230 }
231 
232 /* Converts a hex character to its integer value */
233 static char
234 from_hex (char ch)
235 {
236  return isdigit (ch) ? ch - '0' : tolower (ch) - 'a' + 10;
237 }
238 
239 /* Converts an integer value to its hex character*/
240 static char
241 to_hex (char code)
242 {
243  static char hex[] = "0123456789abcdef";
244 
245  return hex[code & 15];
246 }
247 
248 /* Returns a url-encoded version of str */
249 /* IMPORTANT: be sure to free() the returned string after use */
250 static char *
251 url_encode (const char *str)
252 {
253  char *pstr = (char *) str;
254  char *buf = GNUNET_malloc (strlen (str) * 3 + 1);
255  char *pbuf = buf;
256 
257  while (*pstr)
258  {
259  if (isalnum (*pstr) || (*pstr == '-') || (*pstr == '_') || (*pstr == '.') ||
260  (*pstr == '~') )
261  *pbuf++ = *pstr;
262  else if (*pstr == ' ')
263  *pbuf++ = '+';
264  else
265  {
266  *pbuf++ = '%';
267  *pbuf++ = to_hex (*pstr >> 4);
268  *pbuf++ = to_hex (*pstr & 15);
269  }
270  pstr++;
271  }
272  *pbuf = '\0';
273  return buf;
274 }
275 
276 
277 /* Returns a url-decoded version of str */
278 /* IMPORTANT: be sure to free() the returned string after use */
279 static char *
280 url_decode (const char *str)
281 {
282  char *pstr = (char *) str;
283  char *buf = GNUNET_malloc (strlen (str) + 1);
284  char *pbuf = buf;
285 
286  while (*pstr)
287  {
288  if (*pstr == '%')
289  {
290  if (pstr[1] && pstr[2])
291  {
292  *pbuf++ = from_hex (pstr[1]) << 4 | from_hex (pstr[2]);
293  pstr += 2;
294  }
295  }
296  else if (*pstr == '+')
297  {
298  *pbuf++ = ' ';
299  }
300  else
301  {
302  *pbuf++ = *pstr;
303  }
304  pstr++;
305  }
306  *pbuf = '\0';
307  return buf;
308 }
309 
316 static char *
317 base64_and_urlencode (const char *data, size_t data_size)
318 {
319  char *enc;
320  char *urlenc;
321 
322  GNUNET_STRINGS_base64_encode (data, data_size, &enc);
323  urlenc = url_encode (enc);
324  GNUNET_free (enc);
325  return urlenc;
326 }
327 
328 
335 static char *
336 base64url_encode (const char *data, size_t data_size)
337 {
338  char *enc;
339  size_t pos;
340 
341  GNUNET_STRINGS_base64_encode (data, data_size, &enc);
342  // Replace with correct characters for base64url
343  pos = 0;
344  while ('\0' != enc[pos])
345  {
346  if ('+' == enc[pos])
347  enc[pos] = '-';
348  if ('/' == enc[pos])
349  enc[pos] = '_';
350  if ('=' == enc[pos])
351  {
352  enc[pos] = '\0';
353  break;
354  }
355  pos++;
356  }
357  return enc;
358 }
359 
360 
361 static void
364  struct GNUNET_HashCode *key_material)
365 {
366  static const char ctx_key[] = "reclaim-aes-ctx-key";
367  static const char ctx_iv[] = "reclaim-aes-ctx-iv";
368 
369  GNUNET_CRYPTO_kdf (key,
370  sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
371  ctx_key,
372  strlen (ctx_key),
373  key_material,
374  sizeof(struct GNUNET_HashCode),
375  NULL);
376  GNUNET_CRYPTO_kdf (iv,
377  sizeof(
379  ctx_iv,
380  strlen (ctx_iv),
381  key_material,
382  sizeof(struct GNUNET_HashCode),
383  NULL);
384 }
385 
386 
387 static void
390  const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
391  const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub)
392 {
393  struct GNUNET_HashCode key_material;
394 
395  GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material);
396  derive_aes_key (key, iv, &key_material);
397 }
398 
399 
400 static void
403  const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
404  const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv)
405 {
406  struct GNUNET_HashCode key_material;
407 
408  GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material);
409  derive_aes_key (key, iv, &key_material);
410 }
411 
412 
413 static void
415  const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub,
416  const char *ct,
417  size_t ct_len,
418  char *buf)
419 {
422 
423  calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub);
424  GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf));
425 }
426 
427 
428 static void
430  const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv,
431  const char *payload,
432  size_t payload_len,
433  char *buf)
434 {
437 
438  calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv);
439  GNUNET_break (
440  GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
441 }
442 
454 char *
456  const struct GNUNET_RECLAIM_Ticket *ticket,
458  const char *nonce_str,
459  const char *code_challenge)
460 {
461  struct OIDC_Parameters params;
462  char *code_payload;
463  char *payload;
464  char *tmp;
465  char *code_str;
466  char *buf_ptr = NULL;
467  size_t payload_len;
468  size_t code_payload_len;
469  size_t attr_list_len = 0;
470  size_t code_challenge_len = 0;
471  uint32_t nonce;
472  uint32_t nonce_tmp;
474  struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv;
475  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub;
476 
478  // Assign ticket
479  memset (&params, 0, sizeof(params));
480  params.ticket = *ticket;
481  // Assign nonce
482  nonce = 0;
483  payload_len = sizeof(struct OIDC_Parameters);
484  if ((NULL != nonce_str)&& (strcmp ("", nonce_str) != 0))
485  {
486  if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
487  {
488  GNUNET_break (0);
489  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
490  return NULL;
491  }
493  "Got nonce: %u from %s\n",
494  nonce,
495  nonce_str);
496  }
497  nonce_tmp = htonl (nonce);
498  params.nonce = nonce_tmp;
499  // Assign code challenge
500  if (NULL != code_challenge)
501  code_challenge_len = strlen (code_challenge);
502  payload_len += code_challenge_len;
503  params.code_challenge_len = htonl (code_challenge_len);
504  // Assign attributes
505  if (NULL != attrs)
506  {
507  // Get length
508  attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
509  params.attr_list_len = htonl (attr_list_len);
511  "Length of serialized attributes: %lu\n",
512  attr_list_len);
513  // Get serialized attributes
514  payload_len += attr_list_len;
515  }
516  // Get plaintext length
517  payload = GNUNET_malloc (payload_len);
518  memcpy (payload, &params, sizeof(params));
519  tmp = payload + sizeof(params);
520  if (0 < code_challenge_len)
521  {
522  memcpy (tmp, code_challenge, code_challenge_len);
523  tmp += code_challenge_len;
524  }
525  if (0 < attr_list_len)
530  // Get length
531  code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
532  + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
533  + payload_len + sizeof(struct
534  GNUNET_CRYPTO_EcdsaSignature);
536  "Length of data to encode: %lu\n",
537  code_payload_len);
538 
539  // Generate ECDH key
540  ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create ();
541  GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub);
542  // Initialize code payload
543  code_payload = GNUNET_malloc (code_payload_len);
544  GNUNET_assert (NULL != code_payload);
545  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
546  purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
547  + sizeof(ecdh_pub) + payload_len);
549  // Store pubkey
550  buf_ptr = (char *) &purpose[1];
551  memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub));
552  buf_ptr += sizeof(ecdh_pub);
553  // Encrypt plaintext and store
554  encrypt_payload (&ticket->audience, ecdh_priv, payload, payload_len, buf_ptr);
555  GNUNET_free (ecdh_priv);
556  GNUNET_free (payload);
557  buf_ptr += payload_len;
558  // Sign and store signature
559  if (GNUNET_SYSERR ==
560  GNUNET_CRYPTO_ecdsa_sign (issuer,
561  purpose,
562  (struct GNUNET_CRYPTO_EcdsaSignature *)
563  buf_ptr))
564  {
565  GNUNET_break (0);
566  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
567  GNUNET_free (code_payload);
568  return NULL;
569  }
570  code_str = base64_and_urlencode (code_payload, code_payload_len);
571  GNUNET_free (code_payload);
572  return code_str;
573 }
574 
575 
589 int
591  const char *code,
592  const char *code_verifier,
594  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs,
595  char **nonce_str)
596 {
597  char *code_payload;
598  char *ptr;
599  char *plaintext;
600  char *attrs_ser;
601  char *expected_code_challenge;
602  char *code_challenge;
603  char *code_verifier_hash;
605  struct GNUNET_CRYPTO_EcdsaSignature *signature;
606  struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
607  struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub;
608  uint32_t code_challenge_len;
609  uint32_t attrs_ser_len;
610  size_t plaintext_len;
611  size_t code_payload_len;
612  uint32_t nonce = 0;
613  struct OIDC_Parameters *params;
614 
615  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
616  code_payload = NULL;
617  code_payload_len =
618  GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload);
619  if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
620  + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
621  + sizeof(struct OIDC_Parameters)
622  + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
623  {
624  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n");
625  GNUNET_free_non_null (code_payload);
626  return GNUNET_SYSERR;
627  }
628 
629  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
630  plaintext_len = code_payload_len;
631  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose);
632  ptr = (char *) &purpose[1];
633  // Public ECDH key
634  ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
635  ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
636  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
637 
638  // Decrypt ciphertext
639  plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
640  plaintext = GNUNET_malloc (plaintext_len);
641  decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
642  // ptr = plaintext;
643  ptr += plaintext_len;
644  signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr;
645  params = (struct OIDC_Parameters *) plaintext;
646 
647  // cmp code_challenge code_verifier
648  code_challenge_len = ntohl (params->code_challenge_len);
649  if (0 != code_challenge_len) /* Only check if this code requires a CV */
650  {
651  if (NULL == code_verifier)
652  {
654  "Expected code verifier!\n");
655  GNUNET_free_non_null (code_payload);
656  return GNUNET_SYSERR;
657  }
658  code_verifier_hash = GNUNET_malloc (256 / 8);
659  // hash code verifier
660  gcry_md_hash_buffer (GCRY_MD_SHA256,
661  code_verifier_hash,
662  code_verifier,
663  strlen (code_verifier));
664  // encode code verifier
665  expected_code_challenge = base64url_encode (code_verifier_hash, 256 / 8);
666  code_challenge = (char *) &params[1];
667  GNUNET_free (code_verifier_hash);
668  if ((strlen (expected_code_challenge) != code_challenge_len) ||
669  (0 !=
670  strncmp (expected_code_challenge, code_challenge, code_challenge_len)))
671  {
673  "Invalid code verifier! Expected: %s, Got: %.*s\n",
674  expected_code_challenge,
675  code_challenge_len,
676  code_challenge);
677  GNUNET_free_non_null (code_payload);
678  GNUNET_free (expected_code_challenge);
679  return GNUNET_SYSERR;
680  }
681  GNUNET_free (expected_code_challenge);
682  }
683  // Ticket
684  memcpy (ticket, &params->ticket, sizeof(params->ticket));
685  // Nonce
686  nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr));
687  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
688  // Signature
689  GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
690  if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience))
691  {
692  GNUNET_free (code_payload);
693  GNUNET_free (plaintext);
695  "Audience in ticket does not match client!\n");
696  return GNUNET_SYSERR;
697  }
698  if (GNUNET_OK !=
700  purpose,
701  signature,
702  &ticket->identity))
703  {
704  GNUNET_free (code_payload);
705  GNUNET_free (plaintext);
706  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
707  return GNUNET_SYSERR;
708  }
709  // Attributes
710  attrs_ser = ((char *) &params[1]) + code_challenge_len;
711  attrs_ser_len = ntohl (params->attr_list_len);
712  *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attrs_ser, attrs_ser_len);
713 
714  *nonce_str = NULL;
715  if (nonce != 0)
716  GNUNET_asprintf (nonce_str, "%u", nonce);
717  GNUNET_free (code_payload);
718  GNUNET_free (plaintext);
719  return GNUNET_OK;
720 }
721 
722 
732 void
733 OIDC_build_token_response (const char *access_token,
734  const char *id_token,
735  const struct GNUNET_TIME_Relative *expiration_time,
736  char **token_response)
737 {
738  json_t *root_json;
739 
740  root_json = json_object ();
741 
742  GNUNET_assert (NULL != access_token);
743  GNUNET_assert (NULL != id_token);
744  GNUNET_assert (NULL != expiration_time);
745  json_object_set_new (root_json, "access_token", json_string (access_token));
746  json_object_set_new (root_json, "token_type", json_string ("Bearer"));
747  json_object_set_new (root_json,
748  "expires_in",
749  json_integer (expiration_time->rel_value_us
750  / (1000 * 1000)));
751  json_object_set_new (root_json, "id_token", json_string (id_token));
752  *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
753  json_decref (root_json);
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 }
const char * name
The name of the attribute.
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:1562
struct GNUNET_RECLAIM_ATTRIBUTE_Claim * claim
The attribute claim.
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.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
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:401
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:429
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:1667
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:1048
size_t data_size
Number of bytes in data.
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:362
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:383
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint32_t attr_list_len
The length of the attributes list.
Definition: oidc_helper.c:62
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create(void)
Create a new private key.
Definition: crypto_ecc.c:610
helper library for OIDC related functions
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
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:393
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:733
static char to_hex(char code)
Definition: oidc_helper.c:241
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:414
const void * data
Binary value stored as attribute value.
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:931
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#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:83
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.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1920
static void fix_base64(char *str)
Definition: oidc_helper.c:96
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1856
Private ECC key encoded for transmission.
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:241
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:303
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_ATTRIBUTE_ClaimList **attrs, char **nonce_str)
Parse reclaim ticket and nonce from authorization code.
Definition: oidc_helper.c:590
static char from_hex(char ch)
Definition: oidc_helper.c:234
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:68
#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;.
static char * url_decode(const char *str)
Definition: oidc_helper.c:280
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)
static char * url_encode(const char *str)
Definition: oidc_helper.c:251
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
static char * base64_and_urlencode(const char *data, size_t data_size)
Returns base64 encoded string urlencoded.
Definition: oidc_helper.c:317
static OpusEncoder * enc
OPUS encoder.
A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
static char * base64url_encode(const char *data, size_t data_size)
Returns base64 encoded string urlencoded.
Definition: oidc_helper.c:336
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:388
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
#define GNUNET_log(kind,...)
#define JWT_ALG
Definition: oidc_helper.h:30
Time for absolute times used by GNUnet, in microseconds.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:921
#define JWT_TYP_VALUE
Definition: oidc_helper.h:37
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const char *nonce_str, const char *code_challenge)
Builds an OIDC authorization code including a reclaim ticket and nonce.
Definition: oidc_helper.c:455
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.
uint32_t data
The data value.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * next
DLL.
static size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
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:91
char * OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key)
Create a JWT from attributes.
Definition: oidc_helper.c:116
size_t GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size(const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
Get required size for serialization buffer.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * GNUNET_RECLAIM_ATTRIBUTE_list_deserialize(const char *data, size_t data_size)
Deserialize an attribute list.
size_t GNUNET_RECLAIM_ATTRIBUTE_list_serialize(const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, char *result)
Serialize an attribute list.
#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