diff --git a/tool/src/main/java/migt/At_Hash_update.java b/tool/src/main/java/migt/At_Hash_update.java index 2100c8e..c56b5a2 100644 --- a/tool/src/main/java/migt/At_Hash_update.java +++ b/tool/src/main/java/migt/At_Hash_update.java @@ -105,7 +105,8 @@ public void execute() { "$.at_hash", null, "", - at_hash_generated); + at_hash_generated, + ""); String new_id_token = ""; try { diff --git a/tool/src/main/java/migt/EditOperation.java b/tool/src/main/java/migt/EditOperation.java index b907081..40ff343 100644 --- a/tool/src/main/java/migt/EditOperation.java +++ b/tool/src/main/java/migt/EditOperation.java @@ -39,6 +39,7 @@ public class EditOperation extends Module { String jwt_private_key_pem; String what; + String key_add; // TXT TxtAction txt_action; @@ -189,6 +190,9 @@ public EditOperation(JSONObject eop_json) throws ParsingException { action = MessageOperation.MessageOperationActions.REMOVE_PARAMETER; what = eop_json.getString("remove"); break; + case "key": + key_add = eop_json.getString("key"); + break; default: throw new ParsingException("Invalid key \"" + key + "\" in Edit Operation"); } @@ -328,15 +332,15 @@ public void execute_decodeOperation_API(List vars) throws ParsingException switch (jwt_section) { case HEADER: tmp_imported_api.jwt.header = Tools.editJson( - jwt_action, tmp_imported_api.jwt.header, what, vars, save_as, value); + jwt_action, tmp_imported_api.jwt.header, what, vars, save_as, value, key_add); break; case PAYLOAD: tmp_imported_api.jwt.payload = Tools.editJson( - jwt_action, tmp_imported_api.jwt.payload, what, vars, save_as, value); + jwt_action, tmp_imported_api.jwt.payload, what, vars, save_as, value, key_add); break; case SIGNATURE: tmp_imported_api.jwt.signature = Tools.editJson( - jwt_action, tmp_imported_api.jwt.signature, what, vars, save_as, value); + jwt_action, tmp_imported_api.jwt.signature, what, vars, save_as, value, key_add); break; } } catch (PathNotFoundException e) { diff --git a/tool/src/main/java/migt/HTTPReqRes.java b/tool/src/main/java/migt/HTTPReqRes.java index 0733e16..f170777 100644 --- a/tool/src/main/java/migt/HTTPReqRes.java +++ b/tool/src/main/java/migt/HTTPReqRes.java @@ -55,6 +55,7 @@ public class HTTPReqRes implements Cloneable { * @param response the response in byte[] form */ public HTTPReqRes(byte[] request, byte[] response) { + //TODO: make method to work as with helpers this.isRequest = true; this.isResponse = true; this.setRequest(request); diff --git a/tool/src/main/java/migt/Module.java b/tool/src/main/java/migt/Module.java index 87bc884..6d87630 100644 --- a/tool/src/main/java/migt/Module.java +++ b/tool/src/main/java/migt/Module.java @@ -94,13 +94,21 @@ public boolean setResult(T module) { return module.result; } + public void setResult(boolean result) { + this.result = result; + } + + public void setApplicable(boolean applicable) { + this.applicable = applicable; + } + /** * Get the result of this module * * @return the result of the module */ public boolean getResult() { - return this.result; + return this.result & this.applicable; } /** @@ -109,6 +117,7 @@ public boolean getResult() { * @return the result of this module */ public void execute() { + throw new RuntimeException("Called execute method of root Module"); } /** diff --git a/tool/src/main/java/migt/Tools.java b/tool/src/main/java/migt/Tools.java index cc88db5..64a57da 100644 --- a/tool/src/main/java/migt/Tools.java +++ b/tool/src/main/java/migt/Tools.java @@ -740,7 +740,8 @@ public static String editJson(EditOperation.Jwt_action action, String j_path, List vars, String save_as, - String newValue) throws PathNotFoundException { + String newValue, + String newKey) throws PathNotFoundException { //TODO: remove in future versions Object document = Configuration.defaultConfiguration().jsonProvider().parse(content); JsonPath jsonPath = JsonPath.compile(j_path); @@ -750,8 +751,10 @@ public static String editJson(EditOperation.Jwt_action action, document = jsonPath.delete(document, Configuration.defaultConfiguration()); break; case EDIT: - case ADD: document = jsonPath.set(document, newValue, Configuration.defaultConfiguration()); + break; + case ADD: + document = jsonPath.put(document, newKey, newValue, Configuration.defaultConfiguration()); //TODO: check if set also adds in case it is not found break; case SAVE: diff --git a/tool/src/test/java/Checks_Test.java b/tool/src/test/java/Checks_Test.java index d9ef0b3..4a9076c 100644 --- a/tool/src/test/java/Checks_Test.java +++ b/tool/src/test/java/Checks_Test.java @@ -169,6 +169,7 @@ void test_check_json_set_result() throws ParsingException { c.execute(new ArrayList()); DecodeOperation dop = new DecodeOperation(); + dop.setApplicable(true); dop.setResult(c); assertTrue(dop.getResult()); diff --git a/tool/src/test/java/DecodeOperation_Test.java b/tool/src/test/java/DecodeOperation_Test.java index a3da903..2309366 100644 --- a/tool/src/test/java/DecodeOperation_Test.java +++ b/tool/src/test/java/DecodeOperation_Test.java @@ -1,5 +1,4 @@ -import migt.DecodeOperation; -import migt.ParsingException; +import migt.*; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -58,6 +57,33 @@ public class DecodeOperation_Test { " ]\n" + " }"; + public static HTTPReqRes get_test_message_with_jwt() { + String req = "GET /.well-known/openid-federation HTTP/1.1\n" + + "Host: trust-anchor.org:8000\n" + + "Accept: */*\n" + + "Accept-Encoding: gzip, deflate\n" + + "User-Agent: Python/3.10 aiohttp/3.9.3\n" + + "Connection: close\n" + + "\n"; + + String resp = "HTTP/1.1 200 OK\n" + + "Date: Wed, 13 Mar 2024 10:31:06 GMT\n" + + "Server: WSGIServer/0.2 CPython/3.10.13\n" + + "Content-Type: application/entity-statement+jwt\n" + + "X-Frame-Options: DENY\n" + + "Content-Length: 2464\n" + + "X-Content-Type-Options: nosniff\n" + + "Referrer-Policy: same-origin\n" + + "Cross-Origin-Opener-Policy: same-origin\n" + + "\n" + + "eyJ0eXAiOiJlbnRpdHktc3RhdGVtZW50K2p3dCIsImFsZyI6IlJTMjU2Iiwia2lkIjoiQlh2ZnJsbmhBTXVIUjA3YWpVbUFjQlJRY1N6bXcwY19SQWdKbnBTLTlXUSJ9.eyJleHAiOjE3MTAzMjc4NDYsImlhdCI6MTcxMDMyNTg2NiwiaXNzIjoiaHR0cDovL3RydXN0LWFuY2hvci5vcmc6ODAwMCIsInN1YiI6Imh0dHA6Ly90cnVzdC1hbmNob3Iub3JnOjgwMDAiLCJqd2tzIjp7ImtleXMiOlt7Imt0eSI6IlJTQSIsIm4iOiJvOElvbFJqWmxremN0LTQ4cmhyVmxUbllVMXBrTWJWSkQtRFUwNW9NUzlSVkdyc0Z5cGc5OG0tS3c0SDRxTlB5UVZ4Mk9RT1JpLXhTaGdrN0hVLWdLXzJwVmd1WWt2MDZGYWpMX2VkRUFxcXNxdF83NFFmMldMUkM1cGZKR196OU9Qelk4Skd5ay16M1NiZUhOX0JYS0k4R1k1RTRXVTJTc3RtUTlmeUw0Q3h0UmZqVWlhOGxpbVRDXzNNT3BUM3ppNW5yMDNqZmJqcG5qZ2E1MXFYdXJ4bmx6YzNhX3hqazVSQUFwS3hVdk53aEoyNzVNMENtQjk5RGpQd0Y2Qkx2VWdKcWd5Q3BVT24zNkxPaEk0RnF1VnFocWhpd0tsTW1pTWUzeXkweU5RN0ZYQld4anpoZXhicHljM1Z1N3pGSUhQQWNDNFV5SVFoYzN3YUVqMnZpWHciLCJlIjoiQVFBQiIsImtpZCI6IkJYdmZybG5oQU11SFIwN2FqVW1BY0JSUWNTem13MGNfUkFnSm5wUy05V1EifV19LCJtZXRhZGF0YSI6eyJmZWRlcmF0aW9uX2VudGl0eSI6eyJjb250YWN0cyI6WyJvcHNAbG9jYWxob3N0Il0sImZlZGVyYXRpb25fZmV0Y2hfZW5kcG9pbnQiOiJodHRwOi8vdHJ1c3QtYW5jaG9yLm9yZzo4MDAwL2ZldGNoIiwiZmVkZXJhdGlvbl9yZXNvbHZlX2VuZHBvaW50IjoiaHR0cDovL3RydXN0LWFuY2hvci5vcmc6ODAwMC9yZXNvbHZlIiwiZmVkZXJhdGlvbl90cnVzdF9tYXJrX3N0YXR1c19lbmRwb2ludCI6Imh0dHA6Ly90cnVzdC1hbmNob3Iub3JnOjgwMDAvdHJ1c3RfbWFya19zdGF0dXMiLCJob21lcGFnZV91cmkiOiJodHRwOi8vdHJ1c3QtYW5jaG9yLm9yZzo4MDAwIiwib3JnYW5pemF0aW9uX25hbWUiOiJleGFtcGxlIFRBIiwicG9saWN5X3VyaSI6Imh0dHA6Ly90cnVzdC1hbmNob3Iub3JnOjgwMDAvZW4vd2Vic2l0ZS9sZWdhbC1pbmZvcm1hdGlvbiIsImxvZ29fdXJpIjoiaHR0cDovL3RydXN0LWFuY2hvci5vcmc6ODAwMC9zdGF0aWMvc3ZnL3NwaWQtbG9nby1jLWxiLnN2ZyIsImZlZGVyYXRpb25fbGlzdF9lbmRwb2ludCI6Imh0dHA6Ly90cnVzdC1hbmNob3Iub3JnOjgwMDAvbGlzdCJ9fSwidHJ1c3RfbWFya19pc3N1ZXJzIjp7Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L2NlcnRpZmljYXRpb24vcnAvcHVibGljIjpbImh0dHBzOi8vcmVnaXN0cnkuc3BpZC5hZ2lkLmdvdi5pdCIsImh0dHBzOi8vcHVibGljLmludGVybWVkaWFyeS5zcGlkLml0Il0sImh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L2NlcnRpZmljYXRpb24vcnAvcHJpdmF0ZSI6WyJodHRwczovL3JlZ2lzdHJ5LnNwaWQuYWdpZC5nb3YuaXQiLCJodHRwczovL3ByaXZhdGUub3RoZXIuaW50ZXJtZWRpYXJ5Lml0Il0sImh0dHBzOi8vc2dkLmFhLml0L29uYm9hcmRpbmciOlsiaHR0cHM6Ly9zZ2QuYWEuaXQiXX0sImNvbnN0cmFpbnRzIjp7Im1heF9wYXRoX2xlbmd0aCI6MX19.XfNyESWn60pKcxd-g_fThaV0ig59GZgPkULIrKedEq1MBXpTchwrlSrpI490bSWIsgSARqtugXRMl6fqNhJfty82patlWGTPaYHvCd_6xOo-juRZC-WYn9zSIEw320SLA8FzDeGKIx_ny_vyv6Q2xVQt0BVE5ICngrFgxsLNQ1KOLo4l3EdorEJt8E18zGrB_bPwkMwIHg8smV5MAmWo9mc-4g4ZDRG2-BB2F2tVyavYa_eFPC-lhQSkmKMgtOh4m0QgslANfTKbT8Ce0dsDDrsjujUsiLCwXfwSVR_r9lbAm4tC-TQitpLregoGJYsD5SkEpbSTyWUGTGBvEcXBtg"; + + HTTPReqRes res = new HTTPReqRes(req.getBytes(), resp.getBytes()); + res.body_offset_resp = 283; + + return res; + } + @Test void test_parse() throws ParsingException { DecodeOperation dop = new DecodeOperation(new JSONObject(input)); @@ -99,4 +125,24 @@ void test_print_extended() throws ParsingException { DecodeOperation dop = new DecodeOperation(new JSONObject(input_w_edits_save)); System.out.println(dop.toStringExtended()); } + + @Test + void test_decode_jwt() throws ParsingException { + String in = "{\n" + + " \"from\": \"body\",\n" + + " \"type\": \"jwt\",\n" + + " \"decode regex\": \"[^\\\\n\\\\r]*\"\n" + + "}"; + DecodeOperation dop = new DecodeOperation(new JSONObject(in)); + + Operation_API op_api = new Operation_API(null); + op_api.message = get_test_message_with_jwt(); + + dop.loader(op_api); + dop.execute(null); + assertEquals(true, dop.getResult()); + DecodeOperation_API dop_api = dop.getAPI(); + assertEquals("{\"exp\":1710327846,\"iat\":1710325866,\"iss\":\"http://trust-anchor.org:8000\",\"sub\":\"http://trust-anchor.org:8000\",\"jwks\":{\"keys\":[{\"kty\":\"RSA\",\"n\":\"o8IolRjZlkzct-48rhrVlTnYU1pkMbVJD-DU05oMS9RVGrsFypg98m-Kw4H4qNPyQVx2OQORi-xShgk7HU-gK_2pVguYkv06FajL_edEAqqsqt_74Qf2WLRC5pfJG_z9OPzY8JGyk-z3SbeHN_BXKI8GY5E4WU2SstmQ9fyL4CxtRfjUia8limTC_3MOpT3zi5nr03jfbjpnjga51qXurxnlzc3a_xjk5RAApKxUvNwhJ275M0CmB99DjPwF6BLvUgJqgyCpUOn36LOhI4FquVqhqhiwKlMmiMe3yy0yNQ7FXBWxjzhexbpyc3Vu7zFIHPAcC4UyIQhc3waEj2viXw\",\"e\":\"AQAB\",\"kid\":\"BXvfrlnhAMuHR07ajUmAcBRQcSzmw0c_RAgJnpS-9WQ\"}]},\"metadata\":{\"federation_entity\":{\"contacts\":[\"ops@localhost\"],\"federation_fetch_endpoint\":\"http://trust-anchor.org:8000/fetch\",\"federation_resolve_endpoint\":\"http://trust-anchor.org:8000/resolve\",\"federation_trust_mark_status_endpoint\":\"http://trust-anchor.org:8000/trust_mark_status\",\"homepage_uri\":\"http://trust-anchor.org:8000\",\"organization_name\":\"example TA\",\"policy_uri\":\"http://trust-anchor.org:8000/en/website/legal-information\",\"logo_uri\":\"http://trust-anchor.org:8000/static/svg/spid-logo-c-lb.svg\",\"federation_list_endpoint\":\"http://trust-anchor.org:8000/list\"}},\"trust_mark_issuers\":{\"https://www.spid.gov.it/certification/rp/public\":[\"https://registry.spid.agid.gov.it\",\"https://public.intermediary.spid.it\"],\"https://www.spid.gov.it/certification/rp/private\":[\"https://registry.spid.agid.gov.it\",\"https://private.other.intermediary.it\"],\"https://sgd.aa.it/onboarding\":[\"https://sgd.aa.it\"]},\"constraints\":{\"max_path_length\":1}}", dop_api.jwt.payload); + assertEquals("{\"kid\":\"BXvfrlnhAMuHR07ajUmAcBRQcSzmw0c_RAgJnpS-9WQ\",\"typ\":\"entity-statement+jwt\",\"alg\":\"RS256\"}", dop_api.jwt.header); + } } diff --git a/tool/src/test/java/EditOperation_test.java b/tool/src/test/java/EditOperation_test.java index 203d020..7a172b5 100644 --- a/tool/src/test/java/EditOperation_test.java +++ b/tool/src/test/java/EditOperation_test.java @@ -1,7 +1,4 @@ -import migt.EditOperation; -import migt.HTTPReqRes; -import migt.Operation_API; -import migt.ParsingException; +import migt.*; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -155,4 +152,29 @@ public void test_add_body() throws ParsingException { assertEquals("bodycontent&appended", new String(res.message.getBody(true))); } + + @Test + public void test_add_json_jwt() throws ParsingException { + String input = "{\n" + + " \"from\": \"body\",\n" + + " \"type\": \"jwt\",\n" + + " \"decode regex\": \"[^\\\\n\\\\r]*\",\n" + + " \"edits\": [\n" + + " {\n" + + " \"jwt from\": \"payload\",\n" + + " \"jwt add\": \"$\",\n" + + " \"key\": \"new\",\n" + + " \"value\": \"valuenew\"\n" + + " }\n" + + " ]\n" + + "}"; + + DecodeOperation dop = new DecodeOperation(new JSONObject(input)); + dop.loader(new Operation_API(DecodeOperation_Test.get_test_message_with_jwt(), false)); + + dop.execute(null); + assertEquals(true, dop.editOperations.get(0).getResult()); + + assertEquals("{\"exp\":1710327846,\"iat\":1710325866,\"iss\":\"http://trust-anchor.org:8000\",\"sub\":\"http://trust-anchor.org:8000\",\"jwks\":{\"keys\":[{\"kty\":\"RSA\",\"n\":\"o8IolRjZlkzct-48rhrVlTnYU1pkMbVJD-DU05oMS9RVGrsFypg98m-Kw4H4qNPyQVx2OQORi-xShgk7HU-gK_2pVguYkv06FajL_edEAqqsqt_74Qf2WLRC5pfJG_z9OPzY8JGyk-z3SbeHN_BXKI8GY5E4WU2SstmQ9fyL4CxtRfjUia8limTC_3MOpT3zi5nr03jfbjpnjga51qXurxnlzc3a_xjk5RAApKxUvNwhJ275M0CmB99DjPwF6BLvUgJqgyCpUOn36LOhI4FquVqhqhiwKlMmiMe3yy0yNQ7FXBWxjzhexbpyc3Vu7zFIHPAcC4UyIQhc3waEj2viXw\",\"e\":\"AQAB\",\"kid\":\"BXvfrlnhAMuHR07ajUmAcBRQcSzmw0c_RAgJnpS-9WQ\"}]},\"metadata\":{\"federation_entity\":{\"contacts\":[\"ops@localhost\"],\"federation_fetch_endpoint\":\"http://trust-anchor.org:8000/fetch\",\"federation_resolve_endpoint\":\"http://trust-anchor.org:8000/resolve\",\"federation_trust_mark_status_endpoint\":\"http://trust-anchor.org:8000/trust_mark_status\",\"homepage_uri\":\"http://trust-anchor.org:8000\",\"organization_name\":\"example TA\",\"policy_uri\":\"http://trust-anchor.org:8000/en/website/legal-information\",\"logo_uri\":\"http://trust-anchor.org:8000/static/svg/spid-logo-c-lb.svg\",\"federation_list_endpoint\":\"http://trust-anchor.org:8000/list\"}},\"trust_mark_issuers\":{\"https://www.spid.gov.it/certification/rp/public\":[\"https://registry.spid.agid.gov.it\",\"https://public.intermediary.spid.it\"],\"https://www.spid.gov.it/certification/rp/private\":[\"https://registry.spid.agid.gov.it\",\"https://private.other.intermediary.it\"],\"https://sgd.aa.it/onboarding\":[\"https://sgd.aa.it\"]},\"constraints\":{\"max_path_length\":1},\"new\":\"valuenew\"}", dop.getAPI().jwt.payload); + } }