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);
425 const json_t *secret_rsa_key)
439 if (NULL == body_str)
442 "Body for the JWS could not be generated\n");
447 jws = json_pack (
"{s:o}",
"payload",
448 jose_b64_enc (body_str, strlen (body_str)));
451 if (! jose_jws_sig (NULL, jws, NULL, secret_rsa_key))
454 "Signature generation failed\n");
460 json_string_value (json_object_get (jws,
"protected")),
461 json_string_value (json_object_get (jws,
"payload")),
462 json_string_value (json_object_get (jws,
"signature")) );
478 const char *secret_key)
485 char *signature_target;
486 char *signature_base64;
494 "Header for the JWS could not be generated\n");
509 if (NULL == body_str)
512 "Body for the JWS could not be generated\n");
524 GNUNET_asprintf (&signature_target,
"%s.%s", header_base64, body_base64);
528 strlen (signature_target),
568 const char *nonce_str,
569 const char *code_challenge)
576 char *buf_ptr = NULL;
578 size_t code_payload_len;
587 memset (¶ms, 0,
sizeof(params));
592 if ((NULL != nonce_str) && (strcmp (
"", nonce_str) != 0))
599 if (NULL != code_challenge)
610 "Length of serialized attributes: %lu\n",
615 if (NULL != presentations)
625 "Length of serialized presentations: %lu\n",
633 memcpy (
payload, ¶ms,
sizeof(params));
634 tmp =
payload +
sizeof(params);
656 + payload_len + sizeof(struct
660 "Length of data to encode: %lu\n",
671 buf_ptr = (
char *) &
purpose[1];
672 memcpy (buf_ptr,
payload, payload_len);
674 buf_ptr += payload_len;
696 uint32_t code_challenge_len,
697 const char *code_verifier)
699 char *code_verifier_hash;
700 char *expected_code_challenge;
702 if (0 == code_challenge_len)
704 if (NULL == code_verifier)
707 "Expected code verifier!\n");
712 gcry_md_hash_buffer (GCRY_MD_SHA256,
715 strlen (code_verifier));
718 &expected_code_challenge);
721 strncmp (expected_code_challenge, code_challenge, code_challenge_len))
724 "Invalid code verifier! Expected: %s, Got: %.*s\n",
725 expected_code_challenge,
755 const char *code_verifier,
766 char *presentations_ser;
767 char *code_challenge;
771 uint32_t code_challenge_len;
772 uint32_t attrs_ser_len;
773 uint32_t pres_ser_len;
774 size_t plaintext_len;
775 size_t code_payload_len;
776 uint32_t nonce_len = 0;
785 (
void **) &code_payload);
796 plaintext_len = code_payload_len;
801 ptr += plaintext_len;
807 code_challenge = ((
char *) ¶ms[1]);
814 GNUNET_asprintf (emsg,
"Code verifier `%s' invalid for challenge `%s'",
815 code_verifier, code_challenge);
840 if (NULL != *nonce_str)
850 presentations_ser = ((
char*) attrs_ser) + attrs_ser_len;
872 const char *id_token,
874 char **token_response)
878 root_json = json_object ();
883 json_object_set_new (root_json,
"access_token", json_string (access_token));
884 json_object_set_new (root_json,
"token_type", json_string (
"Bearer"));
885 json_object_set_new (root_json,
889 json_object_set_new (root_json,
"id_token", json_string (id_token));
890 *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
891 json_decref (root_json);
928 tkt_str = strtok (tmp,
"-");
930 rp_uri_str = strtok (NULL,
"-");
960 char *scope_variables;
961 char *scope_variable;
962 char delimiter[] =
" ";
966 scope_variable = strtok (scope_variables, delimiter);
967 while (NULL != scope_variable)
969 if (0 == strcmp (
"profile", scope_variable))
971 for (i = 0; i < 14; i++)
980 else if (0 == strcmp (
"address", scope_variable))
982 for (i = 0; i < 5; i++)
991 else if (0 == strcmp (
"email", scope_variable))
993 for (i = 0; i < 2; i++)
1002 else if (0 == strcmp (
"phone", scope_variable))
1004 for (i = 0; i < 2; i++)
1014 else if (0 == strcmp (attr, scope_variable))
1020 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_BlindablePublicKey *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_blinded_key_sign_(const struct GNUNET_CRYPTO_BlindablePrivateKey *priv, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, struct GNUNET_CRYPTO_BlindableKeySignature *sig)
Sign a given block.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_blinded_key_signature_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_SignaturePurpose *validate, const struct GNUNET_CRYPTO_BlindableKeySignature *sig, const struct GNUNET_CRYPTO_BlindablePublicKey *pub)
Verify a given signature.
#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.
static json_t * generate_userinfo_json(const struct GNUNET_CRYPTO_BlindablePublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations)
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_BlindablePublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations)
Generate userinfo JSON as string.
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_BlindablePrivateKey *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.
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)
char * OIDC_generate_id_token_rsa(const char *rp_uri, const struct GNUNET_CRYPTO_BlindablePublicKey *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 * generate_id_token_body(const char *rp_uri, const struct GNUNET_CRYPTO_BlindablePublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce)
char * OIDC_access_token_new(const struct GNUNET_RECLAIM_Ticket *ticket, const char *rp_uri)
Generate a new access token.
int OIDC_parse_authz_code(const char *rp_uri, const struct GNUNET_CRYPTO_BlindablePublicKey *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.
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 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.
char * OIDC_generate_id_token_hmac(const char *rp_uri, const struct GNUNET_CRYPTO_BlindablePublicKey *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.
@ OIDC_VERIFICATION_NO_CODE_VERIFIER
Do not check code verifier even if expected.
#define JWT_ALG_VALUE_HMAC
An identity signature as per LSD0001.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
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...
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.