diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2020-08-05 11:35:05 +0200 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2020-08-05 11:35:05 +0200 |
commit | 6e764f4abd8a3f14f03a5a167af7d5cb703fd1d5 (patch) | |
tree | d5efbc30c698cdf191bf3ffa96e6c80ee5e9154c /src | |
parent | ade9b5e5248a97438ecb979f3be353f565a27ba1 (diff) | |
download | gnunet-6e764f4abd8a3f14f03a5a167af7d5cb703fd1d5.tar.gz gnunet-6e764f4abd8a3f14f03a5a167af7d5cb703fd1d5.zip |
reclaim: Make SPAs work with public clients. No longer encrypt code.
Diffstat (limited to 'src')
-rw-r--r-- | src/reclaim/oidc_helper.c | 185 | ||||
-rw-r--r-- | src/reclaim/oidc_helper.h | 2 | ||||
-rw-r--r-- | src/reclaim/plugin_rest_openid_connect.c | 58 |
3 files changed, 93 insertions, 152 deletions
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index b48738cc4..4da387564 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -47,9 +47,9 @@ struct OIDC_Parameters | |||
47 | struct GNUNET_RECLAIM_Ticket ticket; | 47 | struct GNUNET_RECLAIM_Ticket ticket; |
48 | 48 | ||
49 | /** | 49 | /** |
50 | * The nonce | 50 | * The nonce length |
51 | */ | 51 | */ |
52 | uint32_t nonce GNUNET_PACKED; | 52 | uint32_t nonce_len GNUNET_PACKED; |
53 | 53 | ||
54 | /** | 54 | /** |
55 | * The length of the PKCE code_challenge | 55 | * The length of the PKCE code_challenge |
@@ -326,89 +326,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
326 | } | 326 | } |
327 | 327 | ||
328 | 328 | ||
329 | static void | ||
330 | derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
331 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
332 | struct GNUNET_HashCode *key_material) | ||
333 | { | ||
334 | static const char ctx_key[] = "reclaim-aes-ctx-key"; | ||
335 | static const char ctx_iv[] = "reclaim-aes-ctx-iv"; | ||
336 | |||
337 | GNUNET_CRYPTO_kdf (key, | ||
338 | sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
339 | ctx_key, | ||
340 | strlen (ctx_key), | ||
341 | key_material, | ||
342 | sizeof(struct GNUNET_HashCode), | ||
343 | NULL); | ||
344 | GNUNET_CRYPTO_kdf (iv, | ||
345 | sizeof( | ||
346 | struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
347 | ctx_iv, | ||
348 | strlen (ctx_iv), | ||
349 | key_material, | ||
350 | sizeof(struct GNUNET_HashCode), | ||
351 | NULL); | ||
352 | } | ||
353 | |||
354 | |||
355 | static void | ||
356 | calculate_key_priv (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
357 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
358 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | ||
359 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub) | ||
360 | { | ||
361 | struct GNUNET_HashCode key_material; | ||
362 | |||
363 | GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material); | ||
364 | derive_aes_key (key, iv, &key_material); | ||
365 | } | ||
366 | |||
367 | |||
368 | static void | ||
369 | calculate_key_pub (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
370 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
371 | const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | ||
372 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv) | ||
373 | { | ||
374 | struct GNUNET_HashCode key_material; | ||
375 | |||
376 | GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material); | ||
377 | derive_aes_key (key, iv, &key_material); | ||
378 | } | ||
379 | |||
380 | |||
381 | static void | ||
382 | decrypt_payload (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | ||
383 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub, | ||
384 | const char *ct, | ||
385 | size_t ct_len, | ||
386 | char *buf) | ||
387 | { | ||
388 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
389 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
390 | |||
391 | calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub); | ||
392 | GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf)); | ||
393 | } | ||
394 | |||
395 | |||
396 | static void | ||
397 | encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | ||
398 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv, | ||
399 | const char *payload, | ||
400 | size_t payload_len, | ||
401 | char *buf) | ||
402 | { | ||
403 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
404 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
405 | |||
406 | calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv); | ||
407 | GNUNET_break ( | ||
408 | GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf)); | ||
409 | } | ||
410 | |||
411 | |||
412 | /** | 329 | /** |
413 | * Builds an OIDC authorization code including | 330 | * Builds an OIDC authorization code including |
414 | * a reclaim ticket and nonce | 331 | * a reclaim ticket and nonce |
@@ -439,34 +356,21 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
439 | size_t attr_list_len = 0; | 356 | size_t attr_list_len = 0; |
440 | size_t attests_list_len = 0; | 357 | size_t attests_list_len = 0; |
441 | size_t code_challenge_len = 0; | 358 | size_t code_challenge_len = 0; |
442 | uint32_t nonce; | 359 | uint32_t nonce_len = 0; |
443 | uint32_t nonce_tmp; | ||
444 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 360 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
445 | struct GNUNET_CRYPTO_EcdhePrivateKey ecdh_priv; | ||
446 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub; | ||
447 | 361 | ||
448 | /** PLAINTEXT **/ | 362 | /** PLAINTEXT **/ |
449 | // Assign ticket | 363 | // Assign ticket |
450 | memset (¶ms, 0, sizeof(params)); | 364 | memset (¶ms, 0, sizeof(params)); |
451 | params.ticket = *ticket; | 365 | params.ticket = *ticket; |
452 | // Assign nonce | 366 | // Assign nonce |
453 | nonce = 0; | ||
454 | payload_len = sizeof(struct OIDC_Parameters); | 367 | payload_len = sizeof(struct OIDC_Parameters); |
455 | if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) | 368 | if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) |
456 | { | 369 | { |
457 | if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) | 370 | nonce_len = strlen (nonce_str); |
458 | { | 371 | payload_len += nonce_len; |
459 | GNUNET_break (0); | ||
460 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); | ||
461 | return NULL; | ||
462 | } | ||
463 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
464 | "Got nonce: %u from %s\n", | ||
465 | nonce, | ||
466 | nonce_str); | ||
467 | } | 372 | } |
468 | nonce_tmp = htonl (nonce); | 373 | params.nonce_len = htonl (nonce_len); |
469 | params.nonce = nonce_tmp; | ||
470 | // Assign code challenge | 374 | // Assign code challenge |
471 | if (NULL != code_challenge) | 375 | if (NULL != code_challenge) |
472 | code_challenge_len = strlen (code_challenge); | 376 | code_challenge_len = strlen (code_challenge); |
@@ -506,6 +410,11 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
506 | memcpy (tmp, code_challenge, code_challenge_len); | 410 | memcpy (tmp, code_challenge, code_challenge_len); |
507 | tmp += code_challenge_len; | 411 | tmp += code_challenge_len; |
508 | } | 412 | } |
413 | if (0 < nonce_len) | ||
414 | { | ||
415 | memcpy (tmp, nonce_str, nonce_len); | ||
416 | tmp += nonce_len; | ||
417 | } | ||
509 | if (0 < attr_list_len) | 418 | if (0 < attr_list_len) |
510 | GNUNET_RECLAIM_attribute_list_serialize (attrs, tmp); | 419 | GNUNET_RECLAIM_attribute_list_serialize (attrs, tmp); |
511 | if (0 < attests_list_len) | 420 | if (0 < attests_list_len) |
@@ -513,36 +422,24 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
513 | 422 | ||
514 | /** END **/ | 423 | /** END **/ |
515 | 424 | ||
516 | /** ENCRYPT **/ | ||
517 | // Get length | 425 | // Get length |
518 | code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 426 | code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
519 | + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) | ||
520 | + payload_len + sizeof(struct | 427 | + payload_len + sizeof(struct |
521 | GNUNET_CRYPTO_EcdsaSignature); | 428 | GNUNET_CRYPTO_EcdsaSignature); |
522 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 429 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
523 | "Length of data to encode: %lu\n", | 430 | "Length of data to encode: %lu\n", |
524 | code_payload_len); | 431 | code_payload_len); |
525 | 432 | ||
526 | // Generate ECDH key | ||
527 | GNUNET_CRYPTO_ecdhe_key_create (&ecdh_priv); | ||
528 | GNUNET_CRYPTO_ecdhe_key_get_public (&ecdh_priv, &ecdh_pub); | ||
529 | // Initialize code payload | 433 | // Initialize code payload |
530 | code_payload = GNUNET_malloc (code_payload_len); | 434 | code_payload = GNUNET_malloc (code_payload_len); |
531 | GNUNET_assert (NULL != code_payload); | 435 | GNUNET_assert (NULL != code_payload); |
532 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; | 436 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; |
533 | purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 437 | purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
534 | + sizeof(ecdh_pub) + payload_len); | 438 | + payload_len); |
535 | purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); | 439 | purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); |
536 | // Store pubkey | 440 | // Store pubkey |
537 | buf_ptr = (char *) &purpose[1]; | 441 | buf_ptr = (char *) &purpose[1]; |
538 | memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub)); | 442 | memcpy (buf_ptr, payload, payload_len); |
539 | buf_ptr += sizeof(ecdh_pub); | ||
540 | // Encrypt plaintext and store | ||
541 | encrypt_payload (&ticket->audience, | ||
542 | &ecdh_priv, | ||
543 | payload, | ||
544 | payload_len, | ||
545 | buf_ptr); | ||
546 | GNUNET_free (payload); | 443 | GNUNET_free (payload); |
547 | buf_ptr += payload_len; | 444 | buf_ptr += payload_len; |
548 | // Sign and store signature | 445 | // Sign and store signature |
@@ -570,14 +467,16 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
570 | * | 467 | * |
571 | * @param audience the expected audience of the code | 468 | * @param audience the expected audience of the code |
572 | * @param code the string representation of the code | 469 | * @param code the string representation of the code |
573 | * @param code_verfier PKCE code verifier | 470 | * @param code_verfier PKCE code verifier. Optional, must be provided |
471 | * if used in request. | ||
574 | * @param ticket where to store the ticket | 472 | * @param ticket where to store the ticket |
575 | * @param attrs the attributes in the code | 473 | * @param attrs the attributes in the code |
576 | * @param nonce where to store the nonce | 474 | * @param attests the attestations in the code (if any) |
475 | * @param nonce_str where to store the nonce (if contained) | ||
577 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 476 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
578 | */ | 477 | */ |
579 | int | 478 | int |
580 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 479 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, |
581 | const char *code, | 480 | const char *code, |
582 | const char *code_verifier, | 481 | const char *code_verifier, |
583 | struct GNUNET_RECLAIM_Ticket *ticket, | 482 | struct GNUNET_RECLAIM_Ticket *ticket, |
@@ -595,14 +494,12 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
595 | char *code_verifier_hash; | 494 | char *code_verifier_hash; |
596 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 495 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
597 | struct GNUNET_CRYPTO_EcdsaSignature *signature; | 496 | struct GNUNET_CRYPTO_EcdsaSignature *signature; |
598 | struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub; | ||
599 | struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub; | ||
600 | uint32_t code_challenge_len; | 497 | uint32_t code_challenge_len; |
601 | uint32_t attrs_ser_len; | 498 | uint32_t attrs_ser_len; |
602 | uint32_t attests_ser_len; | 499 | uint32_t attests_ser_len; |
603 | size_t plaintext_len; | 500 | size_t plaintext_len; |
604 | size_t code_payload_len; | 501 | size_t code_payload_len; |
605 | uint32_t nonce = 0; | 502 | uint32_t nonce_len = 0; |
606 | struct OIDC_Parameters *params; | 503 | struct OIDC_Parameters *params; |
607 | 504 | ||
608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); | 505 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); |
@@ -624,16 +521,10 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
624 | plaintext_len = code_payload_len; | 521 | plaintext_len = code_payload_len; |
625 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); | 522 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); |
626 | ptr = (char *) &purpose[1]; | 523 | ptr = (char *) &purpose[1]; |
627 | // Public ECDH key | ||
628 | ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr; | ||
629 | ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); | ||
630 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); | 524 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); |
631 | 525 | ||
632 | // Decrypt ciphertext | ||
633 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); | 526 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); |
634 | plaintext = GNUNET_malloc (plaintext_len); | 527 | plaintext = ptr; |
635 | decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); | ||
636 | // ptr = plaintext; | ||
637 | ptr += plaintext_len; | 528 | ptr += plaintext_len; |
638 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; | 529 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; |
639 | params = (struct OIDC_Parameters *) plaintext; | 530 | params = (struct OIDC_Parameters *) plaintext; |
@@ -658,11 +549,10 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
658 | // encode code verifier | 549 | // encode code verifier |
659 | GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, | 550 | GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, |
660 | &expected_code_challenge); | 551 | &expected_code_challenge); |
661 | code_challenge = (char *) ¶ms[1]; | 552 | code_challenge = ((char *) ¶ms[1]); |
662 | GNUNET_free (code_verifier_hash); | 553 | GNUNET_free (code_verifier_hash); |
663 | if ((strlen (expected_code_challenge) != code_challenge_len) || | 554 | if (0 != |
664 | (0 != | 555 | strncmp (expected_code_challenge, code_challenge, code_challenge_len)) |
665 | strncmp (expected_code_challenge, code_challenge, code_challenge_len))) | ||
666 | { | 556 | { |
667 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 557 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
668 | "Invalid code verifier! Expected: %s, Got: %.*s\n", | 558 | "Invalid code verifier! Expected: %s, Got: %.*s\n", |
@@ -675,17 +565,23 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
675 | } | 565 | } |
676 | GNUNET_free (expected_code_challenge); | 566 | GNUNET_free (expected_code_challenge); |
677 | } | 567 | } |
568 | nonce_len = ntohl (params->nonce_len); | ||
569 | if (0 != nonce_len) | ||
570 | { | ||
571 | *nonce_str = GNUNET_strndup (code_challenge + code_challenge_len, | ||
572 | nonce_len); | ||
573 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %s\n", *nonce_str); | ||
574 | } | ||
575 | |||
678 | // Ticket | 576 | // Ticket |
679 | memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); | 577 | memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); |
680 | // Nonce | 578 | // Signature |
681 | nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr)); | 579 | //GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); |
682 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); | 580 | if (0 != GNUNET_memcmp (audience, &ticket->audience)) |
683 | // Signature | ||
684 | GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); | ||
685 | if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience)) | ||
686 | { | 581 | { |
687 | GNUNET_free (code_payload); | 582 | GNUNET_free (code_payload); |
688 | GNUNET_free (plaintext); | 583 | if (NULL != nonce_str) |
584 | GNUNET_free (nonce_str); | ||
689 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 585 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
690 | "Audience in ticket does not match client!\n"); | 586 | "Audience in ticket does not match client!\n"); |
691 | return GNUNET_SYSERR; | 587 | return GNUNET_SYSERR; |
@@ -697,12 +593,13 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
697 | &ticket->identity)) | 593 | &ticket->identity)) |
698 | { | 594 | { |
699 | GNUNET_free (code_payload); | 595 | GNUNET_free (code_payload); |
700 | GNUNET_free (plaintext); | 596 | if (NULL != nonce_str) |
597 | GNUNET_free (nonce_str); | ||
701 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); | 598 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); |
702 | return GNUNET_SYSERR; | 599 | return GNUNET_SYSERR; |
703 | } | 600 | } |
704 | // Attributes | 601 | // Attributes |
705 | attrs_ser = ((char *) ¶ms[1]) + code_challenge_len; | 602 | attrs_ser = ((char *) ¶ms[1]) + code_challenge_len + nonce_len; |
706 | attrs_ser_len = ntohl (params->attr_list_len); | 603 | attrs_ser_len = ntohl (params->attr_list_len); |
707 | *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len); | 604 | *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len); |
708 | attests_ser = ((char*) attrs_ser) + attrs_ser_len; | 605 | attests_ser = ((char*) attrs_ser) + attrs_ser_len; |
@@ -710,11 +607,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
710 | *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser, | 607 | *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser, |
711 | attests_ser_len); | 608 | attests_ser_len); |
712 | 609 | ||
713 | *nonce_str = NULL; | ||
714 | if (nonce != 0) | ||
715 | GNUNET_asprintf (nonce_str, "%u", nonce); | ||
716 | GNUNET_free (code_payload); | 610 | GNUNET_free (code_payload); |
717 | GNUNET_free (plaintext); | ||
718 | return GNUNET_OK; | 611 | return GNUNET_OK; |
719 | } | 612 | } |
720 | 613 | ||
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index e84087fc3..e71a7ad1c 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h | |||
@@ -90,7 +90,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
90 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 90 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
91 | */ | 91 | */ |
92 | int | 92 | int |
93 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 93 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, |
94 | const char *code, | 94 | const char *code, |
95 | const char *code_verifier, | 95 | const char *code_verifier, |
96 | struct GNUNET_RECLAIM_Ticket *ticket, | 96 | struct GNUNET_RECLAIM_Ticket *ticket, |
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 39eb9701a..238cffb85 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c | |||
@@ -525,6 +525,11 @@ struct RequestHandle | |||
525 | * Reponse code | 525 | * Reponse code |
526 | */ | 526 | */ |
527 | int response_code; | 527 | int response_code; |
528 | |||
529 | /** | ||
530 | * Public client | ||
531 | */ | ||
532 | int public_client; | ||
528 | }; | 533 | }; |
529 | 534 | ||
530 | 535 | ||
@@ -1872,6 +1877,7 @@ check_authorization (struct RequestHandle *handle, | |||
1872 | char *expected_pass; | 1877 | char *expected_pass; |
1873 | char *received_cid; | 1878 | char *received_cid; |
1874 | char *received_cpw; | 1879 | char *received_cpw; |
1880 | char *pkce_cv; | ||
1875 | 1881 | ||
1876 | if (GNUNET_OK == parse_credentials_basic_auth (handle, | 1882 | if (GNUNET_OK == parse_credentials_basic_auth (handle, |
1877 | &received_cid, | 1883 | &received_cid, |
@@ -1889,9 +1895,24 @@ check_authorization (struct RequestHandle *handle, | |||
1889 | } | 1895 | } |
1890 | else | 1896 | else |
1891 | { | 1897 | { |
1892 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | 1898 | /** Allow public clients with PKCE **/ |
1893 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | 1899 | pkce_cv = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY); |
1894 | return GNUNET_SYSERR; | 1900 | if (NULL == pkce_cv) |
1901 | { | ||
1902 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1903 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1904 | return GNUNET_SYSERR; | ||
1905 | } | ||
1906 | handle->public_client = GNUNET_YES; | ||
1907 | GNUNET_free (pkce_cv); | ||
1908 | received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); | ||
1909 | GNUNET_STRINGS_string_to_data (received_cid, | ||
1910 | strlen (received_cid), | ||
1911 | cid, | ||
1912 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
1913 | GNUNET_free (received_cid); | ||
1914 | return GNUNET_OK; | ||
1915 | |||
1895 | } | 1916 | } |
1896 | 1917 | ||
1897 | // check client password | 1918 | // check client password |
@@ -2063,7 +2084,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2063 | } | 2084 | } |
2064 | 2085 | ||
2065 | // decode code | 2086 | // decode code |
2066 | if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket, | 2087 | if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket, |
2067 | &cl, &al, &nonce)) | 2088 | &cl, &al, &nonce)) |
2068 | { | 2089 | { |
2069 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 2090 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); |
@@ -2452,7 +2473,7 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2452 | oidc_config = json_object (); | 2473 | oidc_config = json_object (); |
2453 | // FIXME get from config? | 2474 | // FIXME get from config? |
2454 | json_object_set_new (oidc_config, | 2475 | json_object_set_new (oidc_config, |
2455 | "issuer", json_string ("https://api.reclaim")); | 2476 | "issuer", json_string ("http://localhost:7776")); |
2456 | json_object_set_new (oidc_config, | 2477 | json_object_set_new (oidc_config, |
2457 | "authorization_endpoint", | 2478 | "authorization_endpoint", |
2458 | json_string ("https://api.reclaim/openid/authorize")); | 2479 | json_string ("https://api.reclaim/openid/authorize")); |
@@ -2514,6 +2535,31 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2514 | cleanup_handle (handle); | 2535 | cleanup_handle (handle); |
2515 | } | 2536 | } |
2516 | 2537 | ||
2538 | /** | ||
2539 | * Respond to OPTIONS request | ||
2540 | * | ||
2541 | * @param con_handle the connection handle | ||
2542 | * @param url the url | ||
2543 | * @param cls the RequestHandle | ||
2544 | */ | ||
2545 | static void | ||
2546 | oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, | ||
2547 | const char *url, | ||
2548 | void *cls) | ||
2549 | { | ||
2550 | struct MHD_Response *resp; | ||
2551 | struct RequestHandle *handle = cls; | ||
2552 | |||
2553 | // For now, independent of path return all options | ||
2554 | resp = GNUNET_REST_create_response (NULL); | ||
2555 | MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); | ||
2556 | MHD_add_response_header (resp, "Access-Control-Allow-Origin", "*"); | ||
2557 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
2558 | cleanup_handle (handle); | ||
2559 | return; | ||
2560 | } | ||
2561 | |||
2562 | |||
2517 | 2563 | ||
2518 | static enum GNUNET_GenericReturnValue | 2564 | static enum GNUNET_GenericReturnValue |
2519 | rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | 2565 | rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, |
@@ -2532,6 +2578,8 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | |||
2532 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, | 2578 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, |
2533 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG, | 2579 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG, |
2534 | &oidc_config_endpoint }, | 2580 | &oidc_config_endpoint }, |
2581 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG, | ||
2582 | &oidc_config_cors }, | ||
2535 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, | 2583 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, |
2536 | GNUNET_REST_HANDLER_END }; | 2584 | GNUNET_REST_HANDLER_END }; |
2537 | 2585 | ||