GNUnet  0.10.x
Macros | Functions
oidc_helper.h File Reference

helper library for OIDC related functions More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define JWT_ALG   "alg"
 
#define JWT_ALG_VALUE   "HS512"
 
#define JWT_TYP   "typ"
 
#define JWT_TYP_VALUE   "jwt"
 
#define SERVER_ADDRESS   "https://api.reclaim"
 

Functions

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. More...
 
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, const char *code_challenge)
 Builds an OIDC authorization code including a reclaim ticket and nonce. More...
 
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)
 Parse reclaim ticket and nonce from authorization code. More...
 
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? More...
 
char * OIDC_access_token_new ()
 Generate a new access token. More...
 

Detailed Description

helper library for OIDC related functions

Author
Martin Schanzenbach

Definition in file oidc_helper.h.

Macro Definition Documentation

◆ JWT_ALG

#define JWT_ALG   "alg"

Definition at line 30 of file oidc_helper.h.

Referenced by create_jwt_header().

◆ JWT_ALG_VALUE

#define JWT_ALG_VALUE   "HS512"

Definition at line 33 of file oidc_helper.h.

Referenced by create_jwt_header().

◆ JWT_TYP

#define JWT_TYP   "typ"

Definition at line 35 of file oidc_helper.h.

Referenced by create_jwt_header().

◆ JWT_TYP_VALUE

#define JWT_TYP_VALUE   "jwt"

Definition at line 37 of file oidc_helper.h.

Referenced by create_jwt_header().

◆ SERVER_ADDRESS

#define SERVER_ADDRESS   "https://api.reclaim"

Definition at line 39 of file oidc_helper.h.

Referenced by OIDC_id_token_new().

Function Documentation

◆ OIDC_id_token_new()

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.

Parameters
aud_keythe public of the audience
sub_keythe public key of the subject
attrsthe attribute list
expiration_timethe validity of the token
secret_keythe key used to sign the JWT
Returns
a new base64-encoded JWT string.

Creating the JWT signature. This might not be standards compliant, check.

Definition at line 116 of file oidc_helper.c.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::claim, create_jwt_header(), GNUNET_RECLAIM_ATTRIBUTE_Claim::data, GNUNET_RECLAIM_ATTRIBUTE_Claim::data_size, fix_base64(), GNUNET_asprintf(), GNUNET_CRYPTO_hmac_raw(), GNUNET_free, GNUNET_RECLAIM_ATTRIBUTE_value_to_string(), GNUNET_STRINGS_base64_encode(), GNUNET_STRINGS_data_to_string_alloc(), GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_RECLAIM_ATTRIBUTE_ClaimList::list_head, GNUNET_RECLAIM_ATTRIBUTE_Claim::name, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::next, result, SERVER_ADDRESS, and GNUNET_RECLAIM_ATTRIBUTE_Claim::type.

Referenced by token_endpoint().

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 }
const char * name
The name of the attribute.
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 'claim' of an attribute to a string.
size_t data_size
Number of bytes in data.
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' this be the standard hmac function and the abov...
Definition: crypto_hash.c:383
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
#define SERVER_ADDRESS
Definition: oidc_helper.h:39
const void * data
Binary value stored as attribute value.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static int result
Global testing status.
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:96
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1856
static GNUNET_NETWORK_STRUCT_END char * create_jwt_header(void)
Definition: oidc_helper.c:68
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
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
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * next
DLL.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ OIDC_build_authz_code()

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.

Parameters
issuerthe issuer of the ticket, used to sign the ticket and nonce
ticketthe ticket to include in the code
attrslist of attributes to share
noncethe nonce to include in the code
code_challengePKCE code challenge
Returns
a new authorization code (caller must free)
Parameters
issuerthe issuer of the ticket, used to sign the ticket and nonce
ticketthe ticket to include in the code
attrslist of attributes which are shared
noncethe nonce to include in the code
code_challengePKCE code challenge
Returns
a new authorization code (caller must free)

PLAINTEXT

END

ENCRYPT

Definition at line 455 of file oidc_helper.c.

References OIDC_Parameters::attr_list_len, GNUNET_RECLAIM_Ticket::audience, base64_and_urlencode(), OIDC_Parameters::code_challenge_len, encrypt_payload(), GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_ecdsa_sign(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_RECLAIM_ATTRIBUTE_list_serialize(), GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size(), GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, GNUNET_SYSERR, OIDC_Parameters::nonce, payload, GNUNET_CRYPTO_EccSignaturePurpose::purpose, GNUNET_CRYPTO_EccSignaturePurpose::size, and OIDC_Parameters::ticket.

Referenced by oidc_ticket_issue_cb().

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
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,
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 }
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
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t nonce
The nonce.
Definition: oidc_helper.c:52
#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
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
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
#define GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN
Signature for a GNUid Ticket.
uint32_t code_challenge_len
The length of the PKCE code_challenge.
Definition: oidc_helper.c:57
an ECC signature using ECDSA
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
Private ECC key encoded for transmission.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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
static unsigned long long payload
How much data are we currently storing in the database?
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
static char * base64_and_urlencode(const char *data, size_t data_size)
Returns base64 encoded string urlencoded.
Definition: oidc_helper.c:317
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
#define GNUNET_log(kind,...)
size_t GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size(const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
Get required size for serialization buffer.
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.
The signature used to generate the authorization code.
Definition: oidc_helper.c:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ OIDC_parse_authz_code()

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.

This also verifies the signature in the code.

Parameters
ecdsa_privthe audience of the ticket
codethe string representation of the code
code_verfierPKCE code verifier
ticketwhere to store the ticket
attrsthe attributes found in the code
noncewhere to store the nonce
Returns
GNUNET_OK if successful, else GNUNET_SYSERR

This also verifies the signature in the code.

Parameters
audiencethe expected audience of the code
codethe string representation of the code
code_verfierPKCE code verifier
ticketwhere to store the ticket
attrsthe attributes in the code
noncewhere to store the nonce
Returns
GNUNET_OK if successful, else GNUNET_SYSERR

Definition at line 590 of file oidc_helper.c.

References OIDC_Parameters::attr_list_len, GNUNET_RECLAIM_Ticket::audience, base64url_encode(), OIDC_Parameters::code_challenge_len, decrypt_payload(), GNUNET_asprintf(), GNUNET_CRYPTO_ecdsa_key_get_public(), GNUNET_CRYPTO_ecdsa_verify(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_free_non_null, GNUNET_log, GNUNET_malloc, GNUNET_memcmp, GNUNET_OK, GNUNET_RECLAIM_ATTRIBUTE_list_deserialize(), GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, GNUNET_STRINGS_base64_decode(), GNUNET_SYSERR, GNUNET_RECLAIM_Ticket::identity, OIDC_Parameters::nonce, GNUNET_CRYPTO_EccSignaturePurpose::purpose, and OIDC_Parameters::ticket.

Referenced by token_endpoint().

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 }
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
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t nonce
The nonce.
Definition: oidc_helper.c:52
uint32_t attr_list_len
The length of the attributes list.
Definition: oidc_helper.c:62
#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.
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
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN
Signature for a GNUid Ticket.
uint32_t code_challenge_len
The length of the PKCE code_challenge.
Definition: oidc_helper.c:57
an ECC signature using ECDSA
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1920
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
#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
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
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...
static char * base64url_encode(const char *data, size_t data_size)
Returns base64 encoded string urlencoded.
Definition: oidc_helper.c:336
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
#define GNUNET_log(kind,...)
struct GNUNET_RECLAIM_Ticket ticket
The reclaim ticket.
Definition: oidc_helper.c:47
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * GNUNET_RECLAIM_ATTRIBUTE_list_deserialize(const char *data, size_t data_size)
Deserialize an attribute list.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
The signature used to generate the authorization code.
Definition: oidc_helper.c:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ OIDC_build_token_response()

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?

Parameters
access_tokenthe access token to include
id_tokenthe id_token to include
expiration_timethe expiration time of the token(s)
token_responsewhere to store the response

Definition at line 733 of file oidc_helper.c.

References GNUNET_assert, and GNUNET_TIME_Relative::rel_value_us.

Referenced by token_endpoint().

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 }
uint64_t rel_value_us
The actual value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Here is the caller graph for this function:

◆ OIDC_access_token_new()

char* OIDC_access_token_new ( )

Generate a new access token.

Definition at line 760 of file oidc_helper.c.

References GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u64(), and GNUNET_STRINGS_base64_encode().

Referenced by token_endpoint().

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 }
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
Randomness for IVs etc.
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1856
Here is the call graph for this function:
Here is the caller graph for this function: