diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-04-26 15:42:45 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-04-26 15:42:45 +0200 |
commit | 2b3e57a5122927bbd8a76689b540e6521066ae28 (patch) | |
tree | 9128ea8f74f725d0568098f9a08af222e05ad612 /src/reclaim/oidc_helper.c | |
parent | dba51d34726695de64bca656399ed8f82d225f53 (diff) | |
download | gnunet-2b3e57a5122927bbd8a76689b540e6521066ae28.tar.gz gnunet-2b3e57a5122927bbd8a76689b540e6521066ae28.zip |
RECLAIM/REST: properly urlencode
Diffstat (limited to 'src/reclaim/oidc_helper.c')
-rw-r--r-- | src/reclaim/oidc_helper.c | 100 |
1 files changed, 77 insertions, 23 deletions
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 37387b5e0..91b024c12 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -195,6 +195,78 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
195 | return result; | 195 | return result; |
196 | } | 196 | } |
197 | 197 | ||
198 | /* Converts a hex character to its integer value */ | ||
199 | static char | ||
200 | from_hex (char ch) | ||
201 | { | ||
202 | return isdigit (ch) ? ch - '0' : tolower (ch) - 'a' + 10; | ||
203 | } | ||
204 | |||
205 | /* Converts an integer value to its hex character*/ | ||
206 | static char | ||
207 | to_hex (char code) | ||
208 | { | ||
209 | static char hex[] = "0123456789abcdef"; | ||
210 | return hex[code & 15]; | ||
211 | } | ||
212 | |||
213 | /* Returns a url-encoded version of str */ | ||
214 | /* IMPORTANT: be sure to free() the returned string after use */ | ||
215 | static char * | ||
216 | url_encode (const char *str) | ||
217 | { | ||
218 | char *pstr = (char *) str; | ||
219 | char *buf = malloc (strlen (str) * 3 + 1); | ||
220 | char *pbuf = buf; | ||
221 | while (*pstr) | ||
222 | { | ||
223 | if (isalnum (*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || | ||
224 | *pstr == '~') | ||
225 | *pbuf++ = *pstr; | ||
226 | else if (*pstr == ' ') | ||
227 | *pbuf++ = '+'; | ||
228 | else | ||
229 | *pbuf++ = '%', *pbuf++ = to_hex (*pstr >> 4), | ||
230 | *pbuf++ = to_hex (*pstr & 15); | ||
231 | pstr++; | ||
232 | } | ||
233 | *pbuf = '\0'; | ||
234 | return buf; | ||
235 | } | ||
236 | |||
237 | |||
238 | /* Returns a url-decoded version of str */ | ||
239 | /* IMPORTANT: be sure to free() the returned string after use */ | ||
240 | static char * | ||
241 | url_decode (const char *str) | ||
242 | { | ||
243 | char *pstr = (char *) str; | ||
244 | char *buf = malloc (strlen (str) + 1); | ||
245 | char *pbuf = buf; | ||
246 | while (*pstr) | ||
247 | { | ||
248 | if (*pstr == '%') | ||
249 | { | ||
250 | if (pstr[1] && pstr[2]) | ||
251 | { | ||
252 | *pbuf++ = from_hex (pstr[1]) << 4 | from_hex (pstr[2]); | ||
253 | pstr += 2; | ||
254 | } | ||
255 | } | ||
256 | else if (*pstr == '+') | ||
257 | { | ||
258 | *pbuf++ = ' '; | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | *pbuf++ = *pstr; | ||
263 | } | ||
264 | pstr++; | ||
265 | } | ||
266 | *pbuf = '\0'; | ||
267 | return buf; | ||
268 | } | ||
269 | |||
198 | 270 | ||
199 | /** | 271 | /** |
200 | * Returns base64 encoded string urlencoded | 272 | * Returns base64 encoded string urlencoded |
@@ -203,35 +275,18 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
203 | * @return base64 encoded string | 275 | * @return base64 encoded string |
204 | */ | 276 | */ |
205 | static char * | 277 | static char * |
206 | base64_encode (const char *data, | 278 | base64_encode (const char *data, size_t data_size) |
207 | size_t data_size) | ||
208 | { | 279 | { |
209 | char *enc; | 280 | char *enc; |
210 | char *enc_urlencode; | 281 | char *enc_urlencode; |
211 | char *tmp; | ||
212 | int i; | ||
213 | int num_pads = 0; | ||
214 | 282 | ||
215 | GNUNET_STRINGS_base64_encode (data, data_size, &enc); | 283 | GNUNET_STRINGS_base64_encode (data, data_size, &enc); |
216 | tmp = strchr (enc, '='); | 284 | enc_urlencode = url_encode (enc); |
217 | num_pads = strlen (enc) - (tmp - enc); | ||
218 | GNUNET_assert ((3 > num_pads) && (0 <= num_pads)); | ||
219 | if (0 == num_pads) | ||
220 | return enc; | ||
221 | enc_urlencode = GNUNET_malloc (strlen (enc) + num_pads * 2); | ||
222 | strcpy (enc_urlencode, enc); | ||
223 | GNUNET_free (enc); | 285 | GNUNET_free (enc); |
224 | tmp = strchr (enc_urlencode, '='); | ||
225 | for (i = 0; i < num_pads; i++) { | ||
226 | strcpy (tmp, "%3D"); // replace '=' with '%3D' | ||
227 | tmp += 3; | ||
228 | } | ||
229 | return enc_urlencode; | 286 | return enc_urlencode; |
230 | } | 287 | } |
231 | 288 | ||
232 | 289 | ||
233 | |||
234 | |||
235 | /** | 290 | /** |
236 | * Builds an OIDC authorization code including | 291 | * Builds an OIDC authorization code including |
237 | * a reclaim ticket and nonce | 292 | * a reclaim ticket and nonce |
@@ -308,8 +363,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
308 | return NULL; | 363 | return NULL; |
309 | } | 364 | } |
310 | memcpy (buf_ptr, &signature, sizeof (signature)); | 365 | memcpy (buf_ptr, &signature, sizeof (signature)); |
311 | code_str = base64_encode ((const char *) &code_payload, | 366 | code_str = base64_encode ((const char *) &code_payload, code_payload_len); |
312 | code_payload_len); | ||
313 | GNUNET_free (code_payload); | 367 | GNUNET_free (code_payload); |
314 | GNUNET_free_non_null (attrs_ser); | 368 | GNUNET_free_non_null (attrs_ser); |
315 | return code_str; | 369 | return code_str; |
@@ -351,14 +405,14 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, | |||
351 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; | 405 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; |
352 | attrs_ser_len = code_payload_len; | 406 | attrs_ser_len = code_payload_len; |
353 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose); | 407 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose); |
354 | *ticket = *((struct GNUNET_RECLAIM_Ticket*) &purpose[1]); | 408 | *ticket = *((struct GNUNET_RECLAIM_Ticket *) &purpose[1]); |
355 | attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket); | 409 | attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket); |
356 | nonce = ntohs (((unsigned int *) &ticket[1])); | 410 | nonce = ntohs (((unsigned int *) &ticket[1])); |
357 | attrs_ser_len -= sizeof (unsigned int); | 411 | attrs_ser_len -= sizeof (unsigned int); |
358 | ptr = code_payload; | 412 | ptr = code_payload; |
359 | signature_offset = | 413 | signature_offset = |
360 | code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | 414 | code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); |
361 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *)&ptr[signature_offset]; | 415 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *) &ptr[signature_offset]; |
362 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | 416 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature); |
363 | attrs_ser = ((char *) &ticket[1]) + sizeof (unsigned int); | 417 | attrs_ser = ((char *) &ticket[1]) + sizeof (unsigned int); |
364 | *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attrs_ser, attrs_ser_len); | 418 | *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attrs_ser, attrs_ser_len); |