35#include "gnunet_signatures.h"
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;
178 int num_presentations = 0;
189 body = json_object ();
190 aggr_names = json_object ();
191 aggr_sources = json_object ();
198 json_object_set_new (body,
"sub", json_string (
subject));
203 for (ple = presentations->
list_head; NULL != ple; ple = ple->
next)
210 "Adding new presentation source #%d\n", i);
211 aggr_sources_jwt = json_object ();
218 "Presentation is: %s\n", pres_val_str);
219 json_object_set_new (aggr_sources_jwt,
222 json_string (pres_val_str) );
223 json_object_set_new (aggr_sources, source_name, aggr_sources_jwt);
235 "Processing %s for userinfo body\n",
252 "Address is set as aggregated claim. Skipping self-issued value...\n");
258 if (NULL == addr_claim)
260 addr_claim = json_object ();
261 json_object_set_new (body,
"address", addr_claim);
264 json_string (attr_val_str));
270 json_string (attr_val_str));
278 for (ple = presentations->
list_head; NULL != ple; ple = ple->
next)
289 "Presentation for `%s' missing...\n",
302 "Address is already set as normal claim. Skipping attested value...\n");
307 if (NULL != addr_claim)
309 addr_claim = json_object ();
313 json_object_set_new (aggr_names,
"address",
314 json_string (source_name));
324 json_string (source_name));
331 json_object_set_new (body,
"_claim_names", aggr_names);
332 json_object_set_new (body,
"_claim_sources", aggr_sources);
357 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
394 json_object_set_new (body,
"aud", json_string (rp_uri));
396 json_object_set_new (body,
400 json_object_set_new (body,
404 json_object_set_new (body,
409 json_object_set_new (body,
"nonce", json_string (nonce));
412 body_str = json_dumps (body, JSON_INDENT (2) | JSON_COMPACT);
430 const json_t *secret_rsa_key)
444 if (NULL == body_str)
447 "Body for the JWS could not be generated\n");
452 jws = json_pack (
"{s:o}",
"payload",
453 jose_b64_enc (body_str, strlen (body_str)));
456 if (! jose_jws_sig (NULL, jws, NULL, secret_rsa_key))
459 "Signature generation failed\n");
465 json_string_value (json_object_get (jws,
"protected")),
466 json_string_value (json_object_get (jws,
"payload")),
467 json_string_value (json_object_get (jws,
"signature")) );
482 const char *secret_key)
489 char *signature_target;
490 char *signature_base64;
498 "Header for the JWS could not be generated\n");
513 if (NULL == body_str)
516 "Body for the JWS could not be generated\n");
528 GNUNET_asprintf (&signature_target,
"%s.%s", header_base64, body_base64);
532 strlen (signature_target),
572 const char *nonce_str,
573 const char *code_challenge)
580 char *buf_ptr = NULL;
582 size_t code_payload_len;
591 memset (¶ms, 0,
sizeof(params));
596 if ((NULL != nonce_str) && (strcmp (
"", nonce_str) != 0))
603 if (NULL != code_challenge)
614 "Length of serialized attributes: %lu\n",
619 if (NULL != presentations)
629 "Length of serialized presentations: %lu\n",
637 memcpy (
payload, ¶ms,
sizeof(params));
638 tmp =
payload +
sizeof(params);
660 + payload_len + sizeof(struct
663 "Length of data to encode: %lu\n",
674 buf_ptr = (
char *) &
purpose[1];
675 memcpy (buf_ptr,
payload, payload_len);
677 buf_ptr += payload_len;
698 uint32_t code_challenge_len,
699 const char *code_verifier)
701 char *code_verifier_hash;
702 char *expected_code_challenge;
704 if (0 == code_challenge_len)
706 if (NULL == code_verifier)
709 "Expected code verifier!\n");
714 gcry_md_hash_buffer (GCRY_MD_SHA256,
717 strlen (code_verifier));
720 &expected_code_challenge);
723 strncmp (expected_code_challenge, code_challenge, code_challenge_len))
726 "Invalid code verifier! Expected: %s, Got: %.*s\n",
727 expected_code_challenge,
757 const char *code_verifier,
768 char *presentations_ser;
769 char *code_challenge;
773 uint32_t code_challenge_len;
774 uint32_t attrs_ser_len;
775 uint32_t pres_ser_len;
776 size_t plaintext_len;
777 size_t code_payload_len;
778 uint32_t nonce_len = 0;
787 (
void **) &code_payload);
798 plaintext_len = code_payload_len;
803 ptr += plaintext_len;
809 code_challenge = ((
char *) ¶ms[1]);
816 GNUNET_asprintf (emsg,
"Code verifier `%s' invalid for challenge `%s'",
817 code_verifier, code_challenge);
842 if (NULL != *nonce_str)
852 presentations_ser = ((
char*) attrs_ser) + attrs_ser_len;
874 const char *id_token,
876 char **token_response)
880 root_json = json_object ();
885 json_object_set_new (root_json,
"access_token", json_string (access_token));
886 json_object_set_new (root_json,
"token_type", json_string (
"Bearer"));
887 json_object_set_new (root_json,
891 json_object_set_new (root_json,
"id_token", json_string (id_token));
892 *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
893 json_decref (root_json);
930 tkt_str = strtok (tmp,
"-");
932 rp_uri_str = strtok (NULL,
"-");
962 char *scope_variables;
963 char *scope_variable;
964 char delimiter[] =
" ";
968 scope_variable = strtok (scope_variables, delimiter);
969 while (NULL != scope_variable)
971 if (0 == strcmp (
"profile", scope_variable))
973 for (i = 0; i < 14; i++)
982 else if (0 == strcmp (
"address", scope_variable))
984 for (i = 0; i < 5; i++)
993 else if (0 == strcmp (
"email", scope_variable))
995 for (i = 0; i < 2; i++)
1004 else if (0 == strcmp (
"phone", scope_variable))
1006 for (i = 0; i < 2; i++)
1016 else if (0 == strcmp (attr, scope_variable))
1022 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
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
#define GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN
Signature for a GNUid Ticket (Reclaim)
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.