diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index 211def55..eae86374 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -11,7 +11,6 @@ import {fromBase64, toBase64} from "./lib/Base64.mjs"; import {fromHex} from "./lib/Hex.mjs"; import {fromDecimal} from "./lib/Decimal.mjs"; import {fromBinary} from "./lib/Binary.mjs"; -import OperationError from "./errors/OperationError.mjs"; /** * Utility functions for use in operations, the core framework and the stage. @@ -322,48 +321,6 @@ class Utils { } - /** - * Validates that a string contains only characters valid for the given format type. - * Recognised delimiters (spaces, commas, colons, 0x prefix, etc.) are always - * permitted in Hex and Binary formats. - * Throws an OperationError if genuinely invalid characters are found. - * - * @param {string} str - * @param {string} type - One of "Hex", "Base64", "Binary", "UTF8", "Latin1", etc. - * @throws {OperationError} - */ - static validateFormatInput(str, type) { - if (!str) return; - switch (type.toLowerCase()) { - case "hex": { - const stripped = str.replace(/0x|\\x|%|[\s,;:\n\r]/gi, ""); - const invalid = stripped.match(/[^0-9a-fA-F]/); - if (invalid) throw new OperationError( - `Invalid character '${invalid[0]}' in Hex input. ` + - `Hex accepts 0-9, a-f, A-F, and delimiters (space, comma, colon, 0x prefix).` - ); - break; - } - case "base64": { - const invalid = str.replace(/[\s]/g, "").match(/[^A-Za-z0-9+/=]/); - if (invalid) throw new OperationError( - `Invalid character '${invalid[0]}' in Base64 input. ` + - `Base64 accepts A-Z, a-z, 0-9, +, /, and = (padding).` - ); - break; - } - case "binary": { - const stripped = str.replace(/[\s,;:\n\r]/g, ""); - const invalid = stripped.match(/[^01]/); - if (invalid) throw new OperationError( - `Invalid character '${invalid[0]}' in Binary input. Binary accepts only 0 and 1.` - ); - break; - } - } - } - - /** * Coverts data of varying types to a byteArray. * Accepts hex, Base64, UTF8 and Latin1 strings. @@ -383,7 +340,6 @@ class Utils { * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64"); */ static convertToByteArray(str, type) { - Utils.validateFormatInput(str, type); switch (type.toLowerCase()) { case "binary": return fromBinary(str); @@ -421,7 +377,6 @@ class Utils { * Utils.convertToByteString("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64"); */ static convertToByteString(str, type) { - Utils.validateFormatInput(str, type); switch (type.toLowerCase()) { case "binary": return Utils.byteArrayToChars(fromBinary(str)); diff --git a/src/core/lib/Ciphers.mjs b/src/core/lib/Ciphers.mjs index 5305ab1d..b09fb58b 100644 --- a/src/core/lib/Ciphers.mjs +++ b/src/core/lib/Ciphers.mjs @@ -89,6 +89,48 @@ export const format = { }; +/** + * Validates that a passphrase/key string contains only characters valid for the + * given format. Recognised delimiters (spaces, commas, colons, 0x prefix, etc.) + * are always permitted in Hex and Binary formats. + * Throws an OperationError if genuinely invalid characters are found. + * + * @param {string} str + * @param {string} type - One of "Hex", "Base64", "Binary", "UTF8", "Latin1", etc. + * @throws {OperationError} + */ +function validateFormatInput(str, type) { + if (!str) return; + switch (type.toLowerCase()) { + case "hex": { + const stripped = str.replace(/0x|\\x|%|[\s,;:\n\r]/gi, ""); + const invalid = stripped.match(/[^0-9a-fA-F]/); + if (invalid) throw new OperationError( + `Invalid character '${invalid[0]}' in Hex input. ` + + `Hex accepts 0-9, a-f, A-F, and delimiters (space, comma, colon, 0x prefix).` + ); + break; + } + case "base64": { + const invalid = str.replace(/[\s]/g, "").match(/[^A-Za-z0-9+/=]/); + if (invalid) throw new OperationError( + `Invalid character '${invalid[0]}' in Base64 input. ` + + `Base64 accepts A-Z, a-z, 0-9, +, /, and = (padding).` + ); + break; + } + case "binary": { + const stripped = str.replace(/[\s,;:\n\r]/g, ""); + const invalid = stripped.match(/[^01]/); + if (invalid) throw new OperationError( + `Invalid character '${invalid[0]}' in Binary input. Binary accepts only 0 and 1.` + ); + break; + } + } +} + + /** * Parses a user-entered string in a given CryptoJS format, normalising common * hex delimiter conventions (commas, spaces, 0x prefix, etc.) before parsing. @@ -100,7 +142,7 @@ export const format = { * @returns {CryptoJS.lib.WordArray} */ export function parseFormatString(str, formatName) { - Utils.validateFormatInput(str, formatName); + validateFormatInput(str, formatName); if (formatName === "Hex") { return CryptoJS.enc.Hex.parse(toHexFast(fromHex(str))); } diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 2305e331..6cf85718 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -658,7 +658,7 @@ WWFkYSBZYWRh\r }), it("HMAC", () => { - assert.strictEqual(chef.HMAC("On Cloud Nine", {key: {string: "idea", option: "Latin1"}}).toString(), "b128b48ec0d6b0f1a27220c396d0f3e5"); + assert.strictEqual(chef.HMAC("On Cloud Nine", {key: "idea"}).toString(), "e15c268b4ee755c9e52db094ed50add7"); }), it("JPathExpression", () => { @@ -882,8 +882,8 @@ pCGTErs= it("Scrypt", () => { assert.strictEqual( - chef.scrypt("Playing For Keeps", {salt: {string: "salty", option: "UTF8"}}).toString(), - "2f1417e682a7bf008c60abf8e8b8dc33bde9eead9290f9f03d83a8acb49392cfd22ad1425db88f821c67f06a12bb203ccdd47ca5109b8364451d6ebf2215bbdf"); + chef.scrypt("Playing For Keeps", {salt: {string: "salty", option: "Hex"}}).toString(), + "5446b6d86d88515894a163201765bceed0bc39610b1506cdc4d939ffc638bc46e051bce756e2865165d89d955a43a7eb5504502567dea8bfc9e7d49aaa894c07"); }), it("SHA3", () => {