GNUnet  0.10.x
Functions
oidc_helper.c File Reference

helper library for OIDC related functions More...

#include "platform.h"
#include <inttypes.h>
#include <jansson.h>
#include "gnunet_util_lib.h"
#include "gnunet_reclaim_attribute_lib.h"
#include "gnunet_reclaim_service.h"
#include "gnunet_signatures.h"
#include "oidc_helper.h"
Include dependency graph for oidc_helper.c:

Go to the source code of this file.

Functions

static char * create_jwt_header (void)
 
static void replace_char (char *str, char find, char replace)
 
static void fix_base64 (char *str)
 
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...
 
static char from_hex (char ch)
 
static char to_hex (char code)
 
static char * url_encode (const char *str)
 
static char * url_decode (const char *str)
 
static char * base64_encode (const char *data, size_t data_size)
 Returns base64 encoded string urlencoded. More...
 
static void derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, struct GNUNET_HashCode *key_material)
 
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)
 
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)
 
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)
 
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)
 
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)
 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, struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, char **nonce_str)
 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.c.

Function Documentation

◆ create_jwt_header()

static char* create_jwt_header ( void  )
static

Definition at line 37 of file oidc_helper.c.

References JWT_ALG, JWT_ALG_VALUE, JWT_TYP, and JWT_TYP_VALUE.

Referenced by OIDC_id_token_new().

38 {
39  json_t *root;
40  char *json_str;
41 
42  root = json_object ();
43  json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
44  json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
45 
46  json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT);
47  json_decref (root);
48  return json_str;
49 }
#define JWT_ALG_VALUE
Definition: oidc_helper.h:33
#define JWT_TYP
Definition: oidc_helper.h:35
#define JWT_ALG
Definition: oidc_helper.h:30
#define JWT_TYP_VALUE
Definition: oidc_helper.h:37
Here is the caller graph for this function:

◆ replace_char()

static void replace_char ( char *  str,
char  find,
char  replace 
)
static

Definition at line 52 of file oidc_helper.c.

Referenced by fix_base64().

53 {
54  char *current_pos = strchr (str, find);
55  while (current_pos)
56  {
57  *current_pos = replace;
58  current_pos = strchr (current_pos, find);
59  }
60 }
Here is the caller graph for this function:

◆ fix_base64()

static void fix_base64 ( char *  str)
static

Definition at line 64 of file oidc_helper.c.

References replace_char().

Referenced by OIDC_id_token_new().

65 {
66  // Replace + with -
67  replace_char (str, '+', '-');
68 
69  // Replace / with _
70  replace_char (str, '/', '_');
71 }
static void replace_char(char *str, char find, char replace)
Definition: oidc_helper.c:52
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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 84 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().

90 {
92  struct GNUNET_HashCode signature;
93  struct GNUNET_TIME_Absolute exp_time;
94  struct GNUNET_TIME_Absolute time_now;
95  char *audience;
96  char *subject;
97  char *header;
98  char *body_str;
99  char *result;
100  char *header_base64;
101  char *body_base64;
102  char *signature_target;
103  char *signature_base64;
104  char *attr_val_str;
105  json_t *body;
106 
107  // iat REQUIRED time now
108  time_now = GNUNET_TIME_absolute_get ();
109  // exp REQUIRED time expired from config
110  exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time);
111  // auth_time only if max_age
112  // nonce only if nonce
113  // OPTIONAL acr,amr,azp
114  subject =
116  sizeof (struct
118  audience =
120  sizeof (struct
122  header = create_jwt_header ();
123  body = json_object ();
124 
125  // iss REQUIRED case sensitive server uri with https
126  // The issuer is the local reclaim instance (e.g.
127  // https://reclaim.id/api/openid)
128  json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
129  // sub REQUIRED public key identity, not exceed 255 ASCII length
130  json_object_set_new (body, "sub", json_string (subject));
131  // aud REQUIRED public key client_id must be there
132  json_object_set_new (body, "aud", json_string (audience));
133  // iat
134  json_object_set_new (body,
135  "iat",
136  json_integer (time_now.abs_value_us / (1000 * 1000)));
137  // exp
138  json_object_set_new (body,
139  "exp",
140  json_integer (exp_time.abs_value_us / (1000 * 1000)));
141  // nbf
142  json_object_set_new (body,
143  "nbf",
144  json_integer (time_now.abs_value_us / (1000 * 1000)));
145  // nonce
146  if (NULL != nonce)
147  json_object_set_new (body, "nonce", json_string (nonce));
148 
149  for (le = attrs->list_head; NULL != le; le = le->next)
150  {
151  attr_val_str =
153  le->claim->data,
154  le->claim->data_size);
155  json_object_set_new (body, le->claim->name, json_string (attr_val_str));
156  GNUNET_free (attr_val_str);
157  }
158  body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
159  json_decref (body);
160 
161  GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64);
162  fix_base64 (header_base64);
163 
164  GNUNET_STRINGS_base64_encode (body_str, strlen (body_str), &body_base64);
165  fix_base64 (body_base64);
166 
167  GNUNET_free (subject);
168  GNUNET_free (audience);
169 
174  GNUNET_asprintf (&signature_target, "%s.%s", header_base64, body_base64);
175  GNUNET_CRYPTO_hmac_raw (secret_key,
176  strlen (secret_key),
177  signature_target,
178  strlen (signature_target),
179  &signature);
180  GNUNET_STRINGS_base64_encode ((const char *) &signature,
181  sizeof (struct GNUNET_HashCode),
182  &signature_base64);
183  fix_base64 (signature_base64);
184 
185  GNUNET_asprintf (&result,
186  "%s.%s.%s",
187  header_base64,
188  body_base64,
189  signature_base64);
190 
191  GNUNET_free (signature_target);
192  GNUNET_free (header);
193  GNUNET_free (body_str);
194  GNUNET_free (signature_base64);
195  GNUNET_free (body_base64);
196  GNUNET_free (header_base64);
197  return result;
198 }
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 &#39;claim&#39; 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&#39; this be the standard hmac function and the abov...
Definition: crypto_hash.c:383
static char * create_jwt_header(void)
Definition: oidc_helper.c:37
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:64
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:2004
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:988
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:

◆ from_hex()

static char from_hex ( char  ch)
static

Definition at line 202 of file oidc_helper.c.

Referenced by url_decode().

203 {
204  return isdigit (ch) ? ch - '0' : tolower (ch) - 'a' + 10;
205 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
Here is the caller graph for this function:

◆ to_hex()

static char to_hex ( char  code)
static

Definition at line 209 of file oidc_helper.c.

Referenced by url_encode().

210 {
211  static char hex[] = "0123456789abcdef";
212  return hex[code & 15];
213 }
Here is the caller graph for this function:

◆ url_encode()

static char* url_encode ( const char *  str)
static

Definition at line 218 of file oidc_helper.c.

References buf, GNUNET_malloc, and to_hex().

Referenced by base64_encode().

219 {
220  char *pstr = (char *) str;
221  char *buf = GNUNET_malloc (strlen (str) * 3 + 1);
222  char *pbuf = buf;
223  while (*pstr)
224  {
225  if (isalnum (*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' ||
226  *pstr == '~')
227  *pbuf++ = *pstr;
228  else if (*pstr == ' ')
229  *pbuf++ = '+';
230  else
231  {
232  *pbuf++ = '%';
233  *pbuf++ = to_hex (*pstr >> 4);
234  *pbuf++ = to_hex (*pstr & 15);
235  }
236  pstr++;
237  }
238  *pbuf = '\0';
239  return buf;
240 }
static char to_hex(char code)
Definition: oidc_helper.c:209
static char buf[2048]
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ url_decode()

static char* url_decode ( const char *  str)
static

Definition at line 246 of file oidc_helper.c.

References buf, from_hex(), and GNUNET_malloc.

247 {
248  char *pstr = (char *) str;
249  char *buf = GNUNET_malloc (strlen (str) + 1);
250  char *pbuf = buf;
251  while (*pstr)
252  {
253  if (*pstr == '%')
254  {
255  if (pstr[1] && pstr[2])
256  {
257  *pbuf++ = from_hex (pstr[1]) << 4 | from_hex (pstr[2]);
258  pstr += 2;
259  }
260  }
261  else if (*pstr == '+')
262  {
263  *pbuf++ = ' ';
264  }
265  else
266  {
267  *pbuf++ = *pstr;
268  }
269  pstr++;
270  }
271  *pbuf = '\0';
272  return buf;
273 }
static char buf[2048]
static char from_hex(char ch)
Definition: oidc_helper.c:202
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the call graph for this function:

◆ base64_encode()

static char* base64_encode ( const char *  data,
size_t  data_size 
)
static

Returns base64 encoded string urlencoded.

Parameters
stringthe string to encode
Returns
base64 encoded string

Definition at line 283 of file oidc_helper.c.

References enc, GNUNET_free, GNUNET_STRINGS_base64_encode(), and url_encode().

Referenced by OIDC_build_authz_code().

284 {
285  char *enc;
286  char *enc_urlencode;
287 
289  enc_urlencode = url_encode (enc);
290  GNUNET_free (enc);
291  return enc_urlencode;
292 }
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:2004
static char * url_encode(const char *str)
Definition: oidc_helper.c:218
static OpusEncoder * enc
OPUS encoder.
uint32_t data
The data value.
static size_t data_size
Number of bytes in data.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ derive_aes_key()

static void derive_aes_key ( struct GNUNET_CRYPTO_SymmetricSessionKey key,
struct GNUNET_CRYPTO_SymmetricInitializationVector iv,
struct GNUNET_HashCode key_material 
)
static

Definition at line 296 of file oidc_helper.c.

References GNUNET_CRYPTO_kdf().

Referenced by calculate_key_priv(), and calculate_key_pub().

299 {
300  static const char ctx_key[] = "reclaim-aes-ctx-key";
301  static const char ctx_iv[] = "reclaim-aes-ctx-iv";
302  GNUNET_CRYPTO_kdf (key,
303  sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
304  ctx_key,
305  strlen (ctx_key),
306  key_material,
307  sizeof (struct GNUNET_HashCode),
308  NULL);
309  GNUNET_CRYPTO_kdf (iv,
310  sizeof (
312  ctx_iv,
313  strlen (ctx_iv),
314  key_material,
315  sizeof (struct GNUNET_HashCode),
316  NULL);
317 }
A 512-bit hashcode.
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculate_key_priv()

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 
)
static

Definition at line 321 of file oidc_helper.c.

References derive_aes_key(), and GNUNET_CRYPTO_ecdsa_ecdh().

Referenced by decrypt_payload().

325 {
326  struct GNUNET_HashCode key_material;
327  GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material);
328  derive_aes_key (key, iv, &key_material);
329 }
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:1561
static void derive_aes_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, struct GNUNET_HashCode *key_material)
Definition: oidc_helper.c:296
A 512-bit hashcode.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculate_key_pub()

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 
)
static

Definition at line 333 of file oidc_helper.c.

References derive_aes_key(), and GNUNET_CRYPTO_ecdh_ecdsa().

Referenced by encrypt_payload().

337 {
338  struct GNUNET_HashCode key_material;
339  GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material);
340  derive_aes_key (key, iv, &key_material);
341 }
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:1666
static void derive_aes_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, struct GNUNET_HashCode *key_material)
Definition: oidc_helper.c:296
A 512-bit hashcode.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decrypt_payload()

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 
)
static

Definition at line 345 of file oidc_helper.c.

References calculate_key_priv(), GNUNET_break, and GNUNET_CRYPTO_symmetric_decrypt().

Referenced by OIDC_parse_authz_code().

350 {
353 
354  calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub);
355  GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf));
356 }
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char buf[2048]
struct GNUNET_HashCode key
The key used in the DHT.
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:321
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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ encrypt_payload()

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 
)
static

Definition at line 360 of file oidc_helper.c.

References calculate_key_pub(), GNUNET_break, and GNUNET_CRYPTO_symmetric_encrypt().

Referenced by OIDC_build_authz_code().

365 {
368 
369  calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv);
370  GNUNET_break (
371  GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
372 }
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:333
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
static char buf[2048]
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned long long payload
How much data are we currently storing in the database?
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 
)

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 whicha re shared
noncethe nonce to include in the code
Returns
a new authorization code (caller must free)

Definition at line 386 of file oidc_helper.c.

References GNUNET_RECLAIM_Ticket::audience, base64_encode(), 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_free_non_null, GNUNET_log, GNUNET_malloc, GNUNET_RECLAIM_ATTRIBUTE_list_serialize(), GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size(), GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, GNUNET_SYSERR, GNUNET_CRYPTO_EccSignaturePurpose::purpose, GNUNET_CRYPTO_EccSignaturePurpose::size, and SSCANF.

Referenced by oidc_ticket_issue_cb().

390 {
391  char *code_payload;
392  char *plaintext;
393  char *attrs_ser;
394  char *code_str;
395  char *buf_ptr;
396  size_t signature_payload_len;
397  size_t attr_list_len;
398  size_t code_payload_len;
399  uint32_t nonce;
400  uint32_t nonce_tmp;
402  struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv;
403  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub;
404 
405  attrs_ser = NULL;
406  signature_payload_len =
407  sizeof (struct GNUNET_RECLAIM_Ticket) + sizeof (uint32_t);
408 
409  if (NULL != attrs)
410  {
411  attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
413  "Length of serialized attributes: %lu\n",
414  attr_list_len);
415  signature_payload_len += attr_list_len;
416  attrs_ser = GNUNET_malloc (attr_list_len);
417  GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, attrs_ser);
418  }
419 
420  code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
421  sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
422  signature_payload_len +
423  sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
425  "Length of data to encode: %lu\n",
426  code_payload_len);
427  plaintext = GNUNET_malloc (signature_payload_len);
428  // First, copy ticket
429  buf_ptr = plaintext;
430  memcpy (buf_ptr, ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
431  buf_ptr += sizeof (struct GNUNET_RECLAIM_Ticket);
432 
433  // Then copy nonce
434  nonce = 0;
435  if (NULL != nonce_str && strcmp("", nonce_str) != 0)
436  {
437  if ((1 != SSCANF (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
438  {
439  GNUNET_break (0);
440  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
441  GNUNET_free (plaintext);
442  GNUNET_free_non_null (attrs_ser);
443  return NULL;
444  }
446  "Got nonce: %u from %s\n",
447  nonce,
448  nonce_str);
449  }
450  nonce_tmp = htonl (nonce);
451  memcpy (buf_ptr, &nonce_tmp, sizeof (uint32_t));
452  buf_ptr += sizeof (uint32_t);
453 
454  // Finally, attributes
455  if (NULL != attrs_ser)
456  {
457  memcpy (buf_ptr, attrs_ser, attr_list_len);
458  GNUNET_free (attrs_ser);
459  }
460  // Generate ECDH key
461  ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create ();
462  GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub);
463  // Initialize code payload
464  code_payload = GNUNET_malloc (code_payload_len);
465  GNUNET_assert (NULL != code_payload);
466  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
467  purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
468  sizeof (ecdh_pub) + signature_payload_len);
470  // Store pubkey
471  buf_ptr = (char *) &purpose[1];
472  memcpy (buf_ptr, &ecdh_pub, sizeof (ecdh_pub));
473  buf_ptr += sizeof (ecdh_pub);
474  // Encrypt plaintext and store
475  encrypt_payload (&ticket->audience,
476  ecdh_priv,
477  plaintext,
478  signature_payload_len,
479  buf_ptr);
480  GNUNET_free (ecdh_priv);
481  GNUNET_free (plaintext);
482  buf_ptr += signature_payload_len;
483  // Sign and store signature
484  if (GNUNET_SYSERR ==
485  GNUNET_CRYPTO_ecdsa_sign (issuer,
486  purpose,
488  buf_ptr))
489  {
490  GNUNET_break (0);
491  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
492  GNUNET_free (code_payload);
493  return NULL;
494  }
495  code_str = base64_encode (code_payload, code_payload_len);
496  GNUNET_free (code_payload);
497  return code_str;
498 }
The authorization ticket.
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:360
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
static char * base64_encode(const char *data, size_t data_size)
Returns base64 encoded string urlencoded.
Definition: oidc_helper.c:283
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create(void)
Create a new private key.
Definition: crypto_ecc.c:610
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#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 ...
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.
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:79
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
#define SSCANF
Definition: plibc.h:691
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 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.
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,
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
audiencethe expected audience of the code
codethe string representation of the code
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 514 of file oidc_helper.c.

References GNUNET_RECLAIM_Ticket::audience, 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_RECLAIM_ATTRIBUTE_list_destroy(), GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, GNUNET_STRINGS_base64_decode(), GNUNET_SYSERR, GNUNET_RECLAIM_Ticket::identity, and GNUNET_CRYPTO_EccSignaturePurpose::purpose.

Referenced by token_endpoint().

519 {
520  char *code_payload;
521  char *ptr;
522  char *plaintext;
524  struct GNUNET_CRYPTO_EcdsaSignature *signature;
525  struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
526  struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub;
527  size_t code_payload_len;
528  size_t attrs_ser_len;
529  size_t signature_offset;
530  size_t plaintext_len;
531  uint32_t nonce = 0;
532 
533  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
534  code_payload = NULL;
535  code_payload_len =
536  GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload);
537  if (code_payload_len < sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
538  sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
539  sizeof (struct GNUNET_RECLAIM_Ticket) +
540  sizeof (uint32_t) +
541  sizeof (struct GNUNET_CRYPTO_EcdsaSignature))
542  {
543  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n");
544  GNUNET_free_non_null (code_payload);
545  return GNUNET_SYSERR;
546  }
547 
548  purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
549  attrs_ser_len = code_payload_len;
550  attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose);
551  ptr = (char *) &purpose[1];
552  // Public ECDH key
553  ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
554  ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
555  attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
556 
557  // Decrypt ciphertext
558  plaintext_len = attrs_ser_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
559  plaintext = GNUNET_malloc (plaintext_len);
560  decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
561  ptr = plaintext;
562  // Ticket
563  *ticket = *((struct GNUNET_RECLAIM_Ticket *) ptr);
564  attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket);
565  ptr += sizeof (struct GNUNET_RECLAIM_Ticket);
566  // Nonce
567  nonce = ntohl (*((uint32_t *) ptr));
568  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
569  attrs_ser_len -= sizeof (uint32_t);
570  ptr += sizeof (uint32_t);
571  // Attributes
572  attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
573  *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (ptr, attrs_ser_len);
574  // Signature
575  signature_offset =
576  code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
577  signature =
578  (struct GNUNET_CRYPTO_EcdsaSignature *) &code_payload[signature_offset];
579  GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
580  if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience))
581  {
583  GNUNET_free (code_payload);
584  GNUNET_free (plaintext);
586  "Audience in ticket does not match client!\n");
587  return GNUNET_SYSERR;
588  }
589  if (GNUNET_OK !=
591  purpose,
592  signature,
593  &ticket->identity))
594  {
596  GNUNET_free (code_payload);
597  GNUNET_free (plaintext);
598  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
599  return GNUNET_SYSERR;
600  }
601  *nonce_str = NULL;
602  if (nonce != 0)
603  GNUNET_asprintf (nonce_str, "%u", nonce);
604  GNUNET_free (code_payload);
605  GNUNET_free (plaintext);
606  return GNUNET_OK;
607 }
The authorization ticket.
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...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:345
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
void GNUNET_RECLAIM_ATTRIBUTE_list_destroy(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
Destroy claim list.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN
Signature for a GNUid Ticket.
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:2067
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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...
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
#define GNUNET_log(kind,...)
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.
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 620 of file oidc_helper.c.

References GNUNET_assert, and GNUNET_TIME_Relative::rel_value_us.

Referenced by token_endpoint().

624 {
625  json_t *root_json;
626 
627  root_json = json_object ();
628 
629  GNUNET_assert (NULL != access_token);
630  GNUNET_assert (NULL != id_token);
631  GNUNET_assert (NULL != expiration_time);
632  json_object_set_new (root_json, "access_token", json_string (access_token));
633  json_object_set_new (root_json, "token_type", json_string ("Bearer"));
634  json_object_set_new (root_json,
635  "expires_in",
636  json_integer (expiration_time->rel_value_us /
637  (1000 * 1000)));
638  json_object_set_new (root_json, "id_token", json_string (id_token));
639  *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
640  json_decref (root_json);
641 }
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 647 of file oidc_helper.c.

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

Referenced by token_endpoint().

648 {
649  char *access_token;
650  uint64_t random_number;
651 
652  random_number =
654  GNUNET_STRINGS_base64_encode (&random_number,
655  sizeof (uint64_t),
656  &access_token);
657  return access_token;
658 }
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:2004
Here is the call graph for this function:
Here is the caller graph for this function: