diff --git a/src/core/operations/JWTSign.mjs b/src/core/operations/JWTSign.mjs index 7bf623086..d9eb75744 100644 --- a/src/core/operations/JWTSign.mjs +++ b/src/core/operations/JWTSign.mjs @@ -27,53 +27,23 @@ class JWTSign extends Operation { this.args = [ { name: "Private / Secret Key", - type: "shortString", + type: "text", value: "secret_cat" }, { name: "Signing Algorithm", - type: "populateOption", + type: "option", value: [ - { - name: "HS256", - value: "HS256" - }, - { - name: "HS384", - value: "HS384", - }, - { - name: "HS512", - value: "HS512", - }, - { - name: "RS256", - value: "RS256", - }, - { - name: "RS384", - value: "RS384", - }, - { - name: "RS512", - value: "RS512", - }, - { - name: "ES256", - value: "ES256", - }, - { - name: "ES384", - value: "ES384", - }, - { - name: "ES512", - value: "ES512", - }, - { - name: "None", - value: "none", - }, + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "None" ] } ]; diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index cd1df74d7..bbacdce14 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -27,7 +27,7 @@ class JWTVerify extends Operation { this.args = [ { name: "Private / Secret Key", - type: "shortString", + type: "text", value: "secret_cat" }, ]; @@ -42,7 +42,12 @@ class JWTVerify extends Operation { const [key] = args; try { - return jwt.verify(input, key); + return jwt.verify(input, key, { algorithms: [ + "HS256", + "HS384", + "HS512", + "none" + ]}); } catch (err) { return err; } diff --git a/test/index.mjs b/test/index.mjs index 8cf69732a..0812952b5 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -64,6 +64,9 @@ import "./tests/operations/SetUnion"; import "./tests/operations/SymmetricDifference"; import "./tests/operations/TranslateDateTimeFormat"; import "./tests/operations/Magic"; +import "./tests/operations/JWTSign"; +import "./tests/operations/JWTDecode"; +import "./tests/operations/JWTVerify"; let allTestsPassing = true; const testStatusCounts = { diff --git a/test/tests/operations/JWTDecode.mjs b/test/tests/operations/JWTDecode.mjs new file mode 100644 index 000000000..d355b8324 --- /dev/null +++ b/test/tests/operations/JWTDecode.mjs @@ -0,0 +1,51 @@ +/** + * JWT Decode tests + * + * @author gchq77703 [] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +const outputObject = JSON.stringify({ + String: "SomeString", + Number: 42, + iat: 1 +}); + +TestRegister.addTests([ + { + name: "JSON Decode: HS", + input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk", + expectedOutput: outputObject, + recipeConfig: [ + { + op: "JWT Decode", + args: [], + } + ], + }, + { + name: "JSON Decode: RS", + input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y", + expectedOutput: outputObject, + recipeConfig: [ + { + op: "JWT Decode", + args: [], + } + ], + }, + { + name: "JSON Decode: ES", + input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA", + expectedOutput: outputObject, + recipeConfig: [ + { + op: "JWT Decode", + args: [], + } + ], + } +]); diff --git a/test/tests/operations/JWTSign.mjs b/test/tests/operations/JWTSign.mjs new file mode 100644 index 000000000..f0432cbfe --- /dev/null +++ b/test/tests/operations/JWTSign.mjs @@ -0,0 +1,163 @@ +/** + * JWT Sign tests + * + * @author gchq77703 [] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +const inputObject = JSON.stringify({ + String: "SomeString", + Number: 42, + iat: 1 +}); + +const hsKey = "secret_cat"; +const rsKey = `-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw +33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW ++jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB +AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS +3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp +uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE +2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0 +GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K +Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY +6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5 +fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523 +Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP +FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw== +-----END RSA PRIVATE KEY-----`; +const esKey = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2 +OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r +1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G +-----END PRIVATE KEY-----`; + +TestRegister.addTests([ + { + name: "JSON Sign: HS256", + input: inputObject, + expectedOutput: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk", + recipeConfig: [ + { + op: "JWT Sign", + args: [hsKey, "HS256"], + } + ], + }, + { + name: "JSON Sign: HS384", + input: inputObject, + expectedOutput: "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ._bPK-Y3mIACConbJqkGFMQ_L3vbxgKXy9gSxtL9hA5XTganozTSXxD0vX0N1yT5s", + recipeConfig: [ + { + op: "JWT Sign", + args: [hsKey, "HS384"], + } + ], + }, + { + name: "JSON Sign: HS512", + input: inputObject, + expectedOutput: "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.vZIJU4XYMFt3FLE1V_RZOxEetmV4RvxtPZQGzJthK_d47pjwlEb6pQE23YxHFmOj8H5RLEdqqLPw4jNsOyHRzA", + recipeConfig: [ + { + op: "JWT Sign", + args: [hsKey, "HS512"], + } + ], + }, + { + name: "JSON Sign: ES256", + input: inputObject, + expectedOutput: inputObject, + recipeConfig: [ + { + op: "JWT Sign", + args: [esKey, "ES256"], + }, + { + op: "JWT Decode", + args: [] + } + ], + }, + { + name: "JSON Sign: ES384", + input: inputObject, + expectedOutput: inputObject, + recipeConfig: [ + { + op: "JWT Sign", + args: [esKey, "ES384"], + }, + { + op: "JWT Decode", + args: [] + } + ], + }, + { + name: "JSON Sign: ES512", + input: inputObject, + expectedOutput: inputObject, + recipeConfig: [ + { + op: "JWT Sign", + args: [esKey, "ES512"], + }, + { + op: "JWT Decode", + args: [] + } + ], + }, + { + name: "JSON Sign: RS256", + input: inputObject, + expectedOutput: inputObject, + recipeConfig: [ + { + op: "JWT Sign", + args: [rsKey, "RS256"], + }, + { + op: "JWT Decode", + args: [] + } + ], + }, + { + name: "JSON Sign: RS384", + input: inputObject, + expectedOutput: inputObject, + recipeConfig: [ + { + op: "JWT Sign", + args: [rsKey, "RS384"], + }, + { + op: "JWT Decode", + args: [] + } + ], + }, + { + name: "JSON Sign: RS512", + input: inputObject, + expectedOutput: inputObject, + recipeConfig: [ + { + op: "JWT Sign", + args: [esKey, "RS512"], + }, + { + op: "JWT Decode", + args: [] + } + ], + } +]); diff --git a/test/tests/operations/JWTVerify.mjs b/test/tests/operations/JWTVerify.mjs new file mode 100644 index 000000000..94e1074bf --- /dev/null +++ b/test/tests/operations/JWTVerify.mjs @@ -0,0 +1,78 @@ +/** + * JWT Verify tests + * + * @author gchq77703 [] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +const outputObject = JSON.stringify({ + String: "SomeString", + Number: 42, + iat: 1 +}); + +const invalidAlgorithm = JSON.stringify({ + name: "JsonWebTokenError", + message: "invalid algorithm" +}); + +const hsKey = "secret_cat"; +const rsKey = `-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw +33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW ++jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB +AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS +3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp +uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE +2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0 +GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K +Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY +6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5 +fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523 +Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP +FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw== +-----END RSA PRIVATE KEY-----`; +const esKey = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2 +OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r +1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G +-----END PRIVATE KEY-----`; + +TestRegister.addTests([ + { + name: "JSON Verify: HS", + input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk", + expectedOutput: outputObject, + recipeConfig: [ + { + op: "JWT Verify", + args: [hsKey], + } + ], + }, + { + name: "JSON Verify: RS", + input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y", + expectedOutput: invalidAlgorithm, + recipeConfig: [ + { + op: "JWT Verify", + args: [rsKey], + } + ], + }, + { + name: "JSON Verify: ES", + input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA", + expectedOutput: invalidAlgorithm, + recipeConfig: [ + { + op: "JWT Verify", + args: [esKey], + } + ], + } +]);