aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-22 16:37:49 +0200
committerSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-22 16:37:49 +0200
commitb68e69365b355f3ef5104f3b682457b0844a70df (patch)
treea9ba9e95d105af07f59401991188b6a2693a1837
parent214f2e90aff373771838d4504d77444c43194e49 (diff)
downloadgnunet-b68e69365b355f3ef5104f3b682457b0844a70df.tar.gz
gnunet-b68e69365b355f3ef5104f3b682457b0844a70df.zip
add signature check to token endpoint
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c250
1 files changed, 162 insertions, 88 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index 0a6dd2b61..a2d32e126 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -794,66 +794,160 @@ oidc_iteration_error (void *cls)
794 GNUNET_SCHEDULER_add_now (&do_error, handle); 794 GNUNET_SCHEDULER_add_now (&do_error, handle);
795} 795}
796 796
797static int
798parse_authz_code (const char* code,
799 struct GNUNET_RECLAIM_Ticket **ticket,
800 char **nonce)
801{
802 json_error_t error;
803 json_t *code_json;
804 json_t *ticket_json;
805 json_t *nonce_json;
806 json_t *signature_json;
807 const char *ticket_str;
808 const char *signature_str;
809 const char *nonce_str;
810 char *code_output;
811 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
812 struct GNUNET_CRYPTO_EcdsaSignature signature;
813 size_t signature_payload_len;
814
815 code_output = NULL;
816 GNUNET_STRINGS_base64_decode (code,
817 strlen(code),
818 (void**)&code_output);
819 code_json = json_loads (code_output, 0 , &error);
820 GNUNET_free (code_output);
821 ticket_json = json_object_get (code_json, "ticket");
822 nonce_json = json_object_get (code_json, "nonce");
823 signature_json = json_object_get (code_json, "signature");
824 *ticket = NULL;
825 *nonce = NULL;
826
827 if ((NULL == ticket_json || !json_is_string (ticket_json)) ||
828 (NULL == signature_json || !json_is_string (signature_json)))
829 {
830 json_decref (code_json);
831 return GNUNET_SYSERR;
832 }
833 ticket_str = json_string_value (ticket_json);
834 signature_str = json_string_value (signature_json);
835 nonce_str = NULL;
836 if (NULL != nonce_json)
837 nonce_str = json_string_value (nonce_json);
838 signature_payload_len = sizeof (struct GNUNET_RECLAIM_Ticket);
839 if (NULL != nonce_str)
840 signature_payload_len += strlen (nonce_str);
841 purpose = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
842 signature_payload_len);
843 purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + signature_payload_len);
844 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN);
845 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ticket_str,
846 strlen (ticket_str),
847 &purpose[1],
848 sizeof (struct GNUNET_RECLAIM_Ticket)))
849 {
850 GNUNET_free (purpose);
851 json_decref (code_json);
852 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
853 "Cannot parse ticket!\n");
854 return GNUNET_SYSERR;
855 }
856 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_str,
857 strlen (signature_str),
858 &signature,
859 sizeof (struct GNUNET_CRYPTO_EcdsaSignature)))
860 {
861 GNUNET_free (purpose);
862 json_decref (code_json);
863 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
864 "Cannot parse signature!\n");
865 return GNUNET_SYSERR;
866 }
867 *ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
868 memcpy (*ticket,
869 &purpose[1],
870 sizeof (struct GNUNET_RECLAIM_Ticket));
871 if (NULL != nonce_str)
872 memcpy (&purpose[1] + sizeof (struct GNUNET_RECLAIM_Ticket),
873 nonce_str,
874 strlen (nonce_str));
875 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN,
876 purpose,
877 &signature,
878 &(*ticket)->identity))
879 {
880 GNUNET_free (purpose);
881 GNUNET_free (*ticket);
882 json_decref (code_json);
883 *ticket = NULL;
884 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
885 "Signature of authZ code invalid!\n");
886 return GNUNET_SYSERR;
887 }
888 *nonce = GNUNET_strdup (nonce_str);
889 return GNUNET_OK;
890}
797 891
798static char* 892static char*
799build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, 893build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
800 const struct GNUNET_RECLAIM_Ticket *ticket, 894 const struct GNUNET_RECLAIM_Ticket *ticket,
801 const char* nonce) 895 const char* nonce)
802{ 896{
803 char *ticket_str; 897 char *ticket_str;
804 json_t *code_json; 898 json_t *code_json;
805 char *signature_payload; 899 char *signature_payload;
806 char *signature_str; 900 char *signature_str;
807 char *authz_code; 901 char *authz_code;
808 size_t signature_payload_len; 902 size_t signature_payload_len;
809 struct GNUNET_CRYPTO_EcdsaSignature signature; 903 struct GNUNET_CRYPTO_EcdsaSignature signature;
810 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 904 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
811 905
812 signature_payload_len = sizeof (struct GNUNET_RECLAIM_Ticket); 906 signature_payload_len = sizeof (struct GNUNET_RECLAIM_Ticket);
813 if (NULL != nonce) 907 if (NULL != nonce)
814 signature_payload_len += strlen (nonce); 908 signature_payload_len += strlen (nonce);
815 909
816 signature_payload = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + signature_payload_len); 910 signature_payload = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + signature_payload_len);
817 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *)signature_payload; 911 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *)signature_payload;
818 purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + signature_payload_len); 912 purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + signature_payload_len);
819 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); 913 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN);
820 memcpy (&purpose[1], 914 memcpy (&purpose[1],
821 ticket, 915 ticket,
822 sizeof (struct GNUNET_RECLAIM_Ticket)); 916 sizeof (struct GNUNET_RECLAIM_Ticket));
823 if (NULL != nonce) 917 if (NULL != nonce)
824 memcpy (&purpose[1] + sizeof (struct GNUNET_RECLAIM_Ticket), 918 memcpy (&purpose[1] + sizeof (struct GNUNET_RECLAIM_Ticket),
825 nonce, 919 nonce,
826 strlen (nonce)); 920 strlen (nonce));
827 if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_sign (issuer, 921 if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_sign (issuer,
828 purpose, 922 purpose,
829 &signature)) 923 &signature))
830 { 924 {
831 GNUNET_free (signature_payload); 925 GNUNET_free (signature_payload);
832 return NULL; 926 return NULL;
833 } 927 }
834 signature_str = GNUNET_STRINGS_data_to_string_alloc (&signature, 928 signature_str = GNUNET_STRINGS_data_to_string_alloc (&signature,
835 sizeof (signature)); 929 sizeof (signature));
836 ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket, 930 ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket,
837 sizeof (struct GNUNET_RECLAIM_Ticket)); 931 sizeof (struct GNUNET_RECLAIM_Ticket));
838 932
839 code_json = json_object (); 933 code_json = json_object ();
840 json_object_set_new (code_json, 934 json_object_set_new (code_json,
841 "ticket", 935 "ticket",
842 json_string (ticket_str)); 936 json_string (ticket_str));
843 if (NULL != nonce) 937 if (NULL != nonce)
844 json_object_set_new (code_json, 938 json_object_set_new (code_json,
845 "nonce", 939 "nonce",
846 json_string (nonce)); 940 json_string (nonce));
847 json_object_set_new (code_json, 941 json_object_set_new (code_json,
848 "signature", 942 "signature",
849 json_string (signature_str)); 943 json_string (signature_str));
850 authz_code = json_dumps (code_json, 944 authz_code = json_dumps (code_json,
851 JSON_INDENT(0) | JSON_COMPACT); 945 JSON_INDENT(0) | JSON_COMPACT);
852 GNUNET_free (signature_payload); 946 GNUNET_free (signature_payload);
853 GNUNET_free (signature_str); 947 GNUNET_free (signature_str);
854 GNUNET_free (ticket_str); 948 GNUNET_free (ticket_str);
855 json_decref (code_json); 949 json_decref (code_json);
856 return authz_code; 950 return authz_code;
857} 951}
858 952
859 953
@@ -882,10 +976,10 @@ get_client_name_result (void *cls,
882 &handle->ticket, 976 &handle->ticket,
883 handle->oidc->nonce); 977 handle->oidc->nonce);
884 /*GNUNET_asprintf (&code_json_string, "{\"ticket\":\"%s\"%s%s%s}", 978 /*GNUNET_asprintf (&code_json_string, "{\"ticket\":\"%s\"%s%s%s}",
885 ticket_str, 979 ticket_str,
886 (NULL != handle->oidc->nonce) ? ", \"nonce\":\"" : "", 980 (NULL != handle->oidc->nonce) ? ", \"nonce\":\"" : "",
887 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "", 981 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "",
888 (NULL != handle->oidc->nonce) ? "\"" : "");*/ 982 (NULL != handle->oidc->nonce) ? "\"" : "");*/
889 code_base64_final_string = base_64_encode(code_json_string); 983 code_base64_final_string = base_64_encode(code_json_string);
890 tmp = GNUNET_strdup (handle->oidc->redirect_uri); 984 tmp = GNUNET_strdup (handle->oidc->redirect_uri);
891 redirect_path = strtok (tmp, "/"); 985 redirect_path = strtok (tmp, "/");
@@ -1386,13 +1480,9 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1386 char *expected_psw; 1480 char *expected_psw;
1387 int client_exists = GNUNET_NO; 1481 int client_exists = GNUNET_NO;
1388 struct MHD_Response *resp; 1482 struct MHD_Response *resp;
1389 char* code_output;
1390 json_t *root;
1391 json_t *ticket_string;
1392 json_t *nonce;
1393 json_error_t error;
1394 char *json_response; 1483 char *json_response;
1395 char *jwt_secret; 1484 char *jwt_secret;
1485 char *nonce;
1396 1486
1397 /* 1487 /*
1398 * Check Authorization 1488 * Check Authorization
@@ -1579,13 +1669,10 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1579 } 1669 }
1580 1670
1581 //decode code 1671 //decode code
1582 GNUNET_STRINGS_base64_decode(code,strlen(code), (void**)&code_output); 1672 struct GNUNET_RECLAIM_Ticket *ticket;
1583 root = json_loads (code_output, 0, &error); 1673 if(GNUNET_OK != parse_authz_code (code,
1584 GNUNET_free(code_output); 1674 &ticket,
1585 ticket_string = json_object_get (root, "ticket"); 1675 &nonce))
1586 nonce = json_object_get (root, "nonce");
1587
1588 if(ticket_string == NULL && !json_is_string(ticket_string))
1589 { 1676 {
1590 GNUNET_free_non_null(user_psw); 1677 GNUNET_free_non_null(user_psw);
1591 handle->emsg = GNUNET_strdup("invalid_request"); 1678 handle->emsg = GNUNET_strdup("invalid_request");
@@ -1595,21 +1682,6 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1595 return; 1682 return;
1596 } 1683 }
1597 1684
1598 struct GNUNET_RECLAIM_Ticket *ticket = GNUNET_new(struct GNUNET_RECLAIM_Ticket);
1599 if ( GNUNET_OK
1600 != GNUNET_STRINGS_string_to_data (json_string_value(ticket_string),
1601 strlen (json_string_value(ticket_string)),
1602 ticket,
1603 sizeof(struct GNUNET_RECLAIM_Ticket)))
1604 {
1605 GNUNET_free_non_null(user_psw);
1606 handle->emsg = GNUNET_strdup("invalid_request");
1607 handle->edesc = GNUNET_strdup("invalid code");
1608 handle->response_code = MHD_HTTP_BAD_REQUEST;
1609 GNUNET_SCHEDULER_add_now (&do_error, handle);
1610 GNUNET_free(ticket);
1611 return;
1612 }
1613 // this is the current client (relying party) 1685 // this is the current client (relying party)
1614 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; 1686 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1615 GNUNET_IDENTITY_ego_get_public_key(handle->ego_entry->ego,&pub_key); 1687 GNUNET_IDENTITY_ego_get_public_key(handle->ego_entry->ego,&pub_key);
@@ -1678,7 +1750,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1678 &ticket->identity, 1750 &ticket->identity,
1679 cl, 1751 cl,
1680 &expiration_time, 1752 &expiration_time,
1681 (NULL != nonce && json_is_string(nonce)) ? json_string_value (nonce) : NULL, 1753 (NULL != nonce) ? nonce : NULL,
1682 jwt_secret); 1754 jwt_secret);
1683 1755
1684 //Create random access_token 1756 //Create random access_token
@@ -1702,10 +1774,13 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1702 id_token); 1774 id_token);
1703 GNUNET_CRYPTO_hash(access_token, strlen(access_token), &cache_key); 1775 GNUNET_CRYPTO_hash(access_token, strlen(access_token), &cache_key);
1704 char *id_ticket_combination; 1776 char *id_ticket_combination;
1777 char *ticket_string;
1778 ticket_string = GNUNET_STRINGS_data_to_string_alloc (ticket,
1779 sizeof (struct GNUNET_RECLAIM_Ticket));
1705 GNUNET_asprintf(&id_ticket_combination, 1780 GNUNET_asprintf(&id_ticket_combination,
1706 "%s;%s", 1781 "%s;%s",
1707 client_id, 1782 client_id,
1708 json_string_value(ticket_string)); 1783 ticket_string);
1709 GNUNET_CONTAINER_multihashmap_put(OIDC_interpret_access_token, 1784 GNUNET_CONTAINER_multihashmap_put(OIDC_interpret_access_token,
1710 &cache_key, 1785 &cache_key,
1711 id_ticket_combination, 1786 id_ticket_combination,
@@ -1724,7 +1799,6 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1724 GNUNET_free(json_response); 1799 GNUNET_free(json_response);
1725 GNUNET_free(ticket); 1800 GNUNET_free(ticket);
1726 GNUNET_free(id_token); 1801 GNUNET_free(id_token);
1727 json_decref (root);
1728 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle); 1802 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
1729} 1803}
1730 1804