79 "name",
"family_name",
"given_name",
"middle_name",
"nickname",
80 "preferred_username",
"profile",
"picture",
"website",
"gender",
"birthdate",
81 "zoneinfo",
"locale",
"updated_at"
88 "email",
"email_verified"
95 "phone_number",
"phone_number_verified"
102 "street_address",
"locality",
"region",
"postal_code",
"country"
109 for (i = 0; i < 5; i++)
126 root = json_object ();
130 json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT);
139 char *current_pos = strchr (str, find);
144 current_pos = strchr (current_pos, find);
175 json_t *aggr_sources;
176 json_t *aggr_sources_jwt;
177 json_t *addr_claim = NULL;
183 body = json_object ();
184 aggr_names = json_object ();
185 aggr_sources = json_object ();
192 json_object_set_new (body,
"sub", json_string (
subject));
197 for (ple = presentations->
list_head; NULL != ple; ple = ple->
next)
204 "Adding new presentation source #%d\n", i);
205 aggr_sources_jwt = json_object ();
212 "Presentation is: %s\n", pres_val_str);
213 json_object_set_new (aggr_sources_jwt,
216 json_string (pres_val_str) );
217 json_object_set_new (aggr_sources, source_name, aggr_sources_jwt);
229 "Processing %s for userinfo body\n",
246 "Address is set as aggregated claim. Skipping self-issued value...\n");
252 if (NULL == addr_claim)
254 addr_claim = json_object ();
255 json_object_set_new (body,
"address", addr_claim);
258 json_string (attr_val_str));
264 json_string (attr_val_str));
272 for (ple = presentations->
list_head; NULL != ple; ple = ple->
next)
283 "Presentation for `%s' missing...\n",
296 "Address is already set as normal claim. Skipping attested value...\n");
301 if (NULL != addr_claim)
303 addr_claim = json_object ();
307 json_object_set_new (aggr_names,
"address",
308 json_string (source_name));
318 json_string (source_name));
325 json_object_set_new (body,
"_claim_names", aggr_names);
326 json_object_set_new (body,
"_claim_sources", aggr_sources);
351 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
388 json_object_set_new (body,
"aud", json_string (rp_uri));
390 json_object_set_new (body,
394 json_object_set_new (body,
398 json_object_set_new (body,
403 json_object_set_new (body,
"nonce", json_string (nonce));
406 body_str = json_dumps (body, JSON_INDENT (2) | JSON_COMPACT);
424 const json_t *secret_rsa_key)
438 if (NULL == body_str)
441 "Body for the JWS could not be generated\n");
446 jws = json_pack (
"{s:o}",
"payload",
447 jose_b64_enc (body_str, strlen (body_str)));
450 if (! jose_jws_sig (NULL, jws, NULL, secret_rsa_key))
453 "Signature generation failed\n");
459 json_string_value (json_object_get (jws,
"protected")),
460 json_string_value (json_object_get (jws,
"payload")),
461 json_string_value (json_object_get (jws,
"signature")) );
476 const char *secret_key)
483 char *signature_target;
484 char *signature_base64;
492 "Header for the JWS could not be generated\n");
507 if (NULL == body_str)
510 "Body for the JWS could not be generated\n");
522 GNUNET_asprintf (&signature_target,
"%s.%s", header_base64, body_base64);
526 strlen (signature_target),
566 const char *nonce_str,
567 const char *code_challenge)
574 char *buf_ptr = NULL;
576 size_t code_payload_len;
585 memset (¶ms, 0,
sizeof(params));
590 if ((NULL != nonce_str) && (strcmp (
"", nonce_str) != 0))
597 if (NULL != code_challenge)
608 "Length of serialized attributes: %lu\n",
613 if (NULL != presentations)
623 "Length of serialized presentations: %lu\n",
631 memcpy (
payload, ¶ms,
sizeof(params));
632 tmp =
payload +
sizeof(params);
654 + payload_len + sizeof(struct
657 "Length of data to encode: %lu\n",
668 buf_ptr = (
char *) &
purpose[1];
669 memcpy (buf_ptr,
payload, payload_len);
671 buf_ptr += payload_len;
692 uint32_t code_challenge_len,
693 const char *code_verifier)
695 char *code_verifier_hash;
696 char *expected_code_challenge;
698 if (0 == code_challenge_len)
700 if (NULL == code_verifier)
703 "Expected code verifier!\n");
708 gcry_md_hash_buffer (GCRY_MD_SHA256,
711 strlen (code_verifier));
714 &expected_code_challenge);
717 strncmp (expected_code_challenge, code_challenge, code_challenge_len))
720 "Invalid code verifier! Expected: %s, Got: %.*s\n",
721 expected_code_challenge,
751 const char *code_verifier,
762 char *presentations_ser;
763 char *code_challenge;
767 uint32_t code_challenge_len;
768 uint32_t attrs_ser_len;
769 uint32_t pres_ser_len;
770 size_t plaintext_len;
771 size_t code_payload_len;
772 uint32_t nonce_len = 0;
781 (
void **) &code_payload);
792 plaintext_len = code_payload_len;
797 ptr += plaintext_len;
803 code_challenge = ((
char *) ¶ms[1]);
810 GNUNET_asprintf (emsg,
"Code verifier `%s' invalid for challenge `%s'",
811 code_verifier, code_challenge);
836 if (NULL != *nonce_str)
846 presentations_ser = ((
char*) attrs_ser) + attrs_ser_len;
868 const char *id_token,
870 char **token_response)
874 root_json = json_object ();
879 json_object_set_new (root_json,
"access_token", json_string (access_token));
880 json_object_set_new (root_json,
"token_type", json_string (
"Bearer"));
881 json_object_set_new (root_json,
885 json_object_set_new (root_json,
"id_token", json_string (id_token));
886 *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
887 json_decref (root_json);
924 tkt_str = strtok (tmp,
"-");
926 rp_uri_str = strtok (NULL,
"-");
956 char *scope_variables;
957 char *scope_variable;
958 char delimiter[] =
" ";
962 scope_variable = strtok (scope_variables, delimiter);
963 while (NULL != scope_variable)
965 if (0 == strcmp (
"profile", scope_variable))
967 for (i = 0; i < 14; i++)
976 else if (0 == strcmp (
"address", scope_variable))
978 for (i = 0; i < 5; i++)
987 else if (0 == strcmp (
"email", scope_variable))
989 for (i = 0; i < 2; i++)
998 else if (0 == strcmp (
"phone", scope_variable))
1000 for (i = 0; i < 2; i++)
1010 else if (0 == strcmp (attr, scope_variable))
1016 scope_variable = strtok (NULL, delimiter);
static char * subject
Subject pubkey string.
static int replace
Replace DID Document Flag.
struct GNUNET_RECLAIM_Attribute * claim
Claim to store.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
static int result
Global testing status.
static unsigned long long payload
How much data are we currently storing in the database?
API that can be used to manipulate GNS record data.
Identity attribute definitions.
reclaim service; implements identity and personal data sharing for GNUnet
#define GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN
Signature for a GNUid Ticket (Reclaim)
enum GNUNET_GenericReturnValue GNUNET_GNS_parse_ztld(const char *name, struct GNUNET_CRYPTO_PublicKey *ztld_key)
Try to parse the zTLD into a public key.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_log(kind,...)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_signature_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_Signature *sig, const struct GNUNET_CRYPTO_PublicKey *pub)
Verify a given signature.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_sign_(const struct GNUNET_CRYPTO_PrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_Signature *sig)
Sign a given block.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
GNUNET_GenericReturnValue
Named constants for return values.
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't this be the standard hmac function and the abo...
#define GNUNET_PACKED
gcc-ism to get packed structs.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_RECLAIM_id_is_equal(a, b)
struct GNUNET_RECLAIM_PresentationList * GNUNET_RECLAIM_presentation_list_deserialize(const char *data, size_t data_size)
Deserialize a presentation list.
#define GNUNET_RECLAIM_id_is_zero(a)
struct GNUNET_RECLAIM_AttributeList * 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_AttributeList *attrs, char *result)
Serialize an attribute list.
const char * GNUNET_RECLAIM_presentation_number_to_typename(uint32_t type)
Convert a presentation type number to the corresponding credential type string.
size_t GNUNET_RECLAIM_presentation_list_serialize(const struct GNUNET_RECLAIM_PresentationList *presentations, char *result)
Serialize a presentation list.
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 GNUNET_RECLAIM_presentation_list_serialize_get_size(const struct GNUNET_RECLAIM_PresentationList *presentations)
Get required size for serialization buffer.
size_t GNUNET_RECLAIM_attribute_list_serialize_get_size(const struct GNUNET_RECLAIM_AttributeList *attrs)
Get required size for serialization buffer.
char * GNUNET_RECLAIM_presentation_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the 'claim' of a presentation to a string.
size_t GNUNET_STRINGS_base64url_decode(const char *data, size_t len, void **out)
Decode from Base64url.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
size_t GNUNET_STRINGS_base64url_encode(const void *in, size_t len, char **output)
Encode into Base64url.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
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.
static void replace_char(char *str, char find, char replace)
static char OIDC_email_claims[2][16]
Standard claims represented by the "email" scope in OIDC.
char * OIDC_generate_id_token_rsa(const char *rp_uri, const struct GNUNET_CRYPTO_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const json_t *secret_rsa_key)
Create a JWT using RSA256 algorithm from attributes.
static char OIDC_address_claims[5][32]
Standard claims represented by the "address" scope in OIDC.
static void fix_base64(char *str)
char * OIDC_generate_userinfo(const struct GNUNET_CRYPTO_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations)
Generate userinfo JSON as string.
static enum GNUNET_GenericReturnValue check_code_challenge(const char *code_challenge, uint32_t code_challenge_len, const char *code_verifier)
static enum GNUNET_GenericReturnValue is_claim_in_address_scope(const char *claim)
int OIDC_parse_authz_code(const char *rp_uri, const struct GNUNET_CRYPTO_PublicKey *cid, const char *code, const char *code_verifier, struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_AttributeList **attrs, struct GNUNET_RECLAIM_PresentationList **presentations, char **nonce_str, enum OIDC_VerificationOptions opts, char **emsg)
Parse reclaim ticket and nonce from authorization code.
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_PrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const char *nonce_str, const char *code_challenge)
Builds an OIDC authorization code including a reclaim ticket and nonce.
char * OIDC_generate_id_token_hmac(const char *rp_uri, const struct GNUNET_CRYPTO_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key)
Create a JWT using HMAC (HS256) from attributes.
char * OIDC_access_token_new(const struct GNUNET_RECLAIM_Ticket *ticket, const char *rp_uri)
Generate a new access token.
static char * generate_id_token_body(const char *rp_uri, const struct GNUNET_CRYPTO_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce)
static char * create_jwt_hmac_header(void)
int OIDC_access_token_parse(const char *token, struct GNUNET_RECLAIM_Ticket **ticket, char **rp_uri)
Parse an access token.
enum GNUNET_GenericReturnValue OIDC_check_scopes_for_claim_request(const char *scopes, const char *attr)
Checks if a claim is implicitly requested through standard scope(s) or explicitly through non-standar...
static json_t * generate_userinfo_json(const struct GNUNET_CRYPTO_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations)
static char OIDC_phone_claims[2][32]
Standard claims represented by the "phone" scope in OIDC.
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?
static GNUNET_NETWORK_STRUCT_END char OIDC_profile_claims[14][32]
Standard claims represented by the "profile" scope in OIDC.
@ OIDC_VERIFICATION_NO_CODE_VERIFIER
Do not check code verifier even if expected.
#define JWT_ALG_VALUE_HMAC
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
An identity signature as per LSD0001.
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
struct GNUNET_RECLAIM_AttributeListEntry * next
DLL.
A list of GNUNET_RECLAIM_Attribute structures.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
const char * name
The name of the attribute.
struct GNUNET_RECLAIM_Identifier credential
Referenced ID of credential (may be GNUNET_RECLAIM_ID_ZERO if self-creded)
uint32_t type
Type of Claim.
const void * data
Binary value stored as attribute value.
size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_Presentation * presentation
The credential.
struct GNUNET_RECLAIM_PresentationListEntry * next
DLL.
A list of GNUNET_RECLAIM_Presentation structures.
struct GNUNET_RECLAIM_PresentationListEntry * list_head
List head.
const void * data
Binary value stored as presentation value.
uint32_t type
Type/Format of Claim.
size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_Identifier credential_id
The credential id of which this is a presentation.
The authorization ticket.
char gns_name[63 *2+2]
The ticket.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
The signature used to generate the authorization code.
struct GNUNET_RECLAIM_Ticket ticket
The reclaim ticket.
uint32_t pres_list_len
The length of the presentation list.
uint32_t nonce_len
The nonce length.
uint32_t attr_list_len
The length of the attributes list.
uint32_t code_challenge_len
The length of the PKCE code_challenge.