diff --git a/src/core/operations/DeriveDUKPTKey.mjs b/src/core/operations/DeriveDUKPTKey.mjs index 35a66b10..20a54315 100644 --- a/src/core/operations/DeriveDUKPTKey.mjs +++ b/src/core/operations/DeriveDUKPTKey.mjs @@ -200,7 +200,7 @@ class DeriveDUKPTKey extends Operation { this.name = "DUKPT Derive TDES Key"; this.module = "Payment"; - this.description = "Paste the Base Derivation Key (BDK) into the input field as a 16-byte hex value.

Put the 10-byte Key Serial Number in the KSN argument field.

Input: BDK in hex.
Arguments: choose whether to derive the IPEK or the transaction key, provide the KSN, choose the variant, and optionally return JSON.

This operation derives TDES DUKPT keys (ANSI X9.24 Part 1) in software for test and interoperability work. It uses a 16-byte BDK and a 10-byte KSN. AES DUKPT (ANSI X9.24 Part 3), which uses a 12-byte KSN and AES keys, is not implemented here."; + this.description = "Paste the Base Derivation Key (BDK) into the input field as a 16-byte hex value.

Put the 10-byte Key Serial Number in the KSN argument field.

Input: BDK in hex.
Arguments: choose whether to derive the IPEK or the transaction key, provide the KSN, choose the variant, and optionally return JSON.

This operation derives TDES DUKPT keys (ANSI X9.24 Part 1) in software for test and interoperability work. It uses a 16-byte BDK and a 10-byte KSN. For AES DUKPT (ANSI X9.24 Part 3), which uses a 12-byte KSN and AES keys, use the DUKPT Derive AES Key operation."; this.inlineHelp = "Input: BDK hex.
Args: add the KSN, choose IPEK or transaction-key derivation, then optionally apply a variant."; this.testDataSamples = [ { diff --git a/src/core/operations/GenerateEMVMACForPINChange.mjs b/src/core/operations/GenerateEMVMACForPINChange.mjs index 21a7a042..714a3b86 100644 --- a/src/core/operations/GenerateEMVMACForPINChange.mjs +++ b/src/core/operations/GenerateEMVMACForPINChange.mjs @@ -18,8 +18,8 @@ class GenerateEMVMACForPINChange extends Operation { this.name = "EMV Generate MAC (PIN Change)"; this.module = "Payment"; - this.description = "Paste the issuer-script APDU command into the input field as hex and generate the MAC for an offline EMV PIN-change script.

Input: issuer-script message data as hex.
Arguments: provide the already-encrypted target PIN block in hex and the already-derived EMV session integrity key.

Validation: Emulation helper. The new PIN block must already be encrypted, and this op appends it to the supplied message before applying the same supplied-key EMV MAC profile used elsewhere in this fork.

Key context: In a full issuer implementation, a PIN-change script involves three distinct keys: a secure-messaging integrity key (for the MAC), a secure-messaging confidentiality key (for encrypting the script data), and a PIN encryption key (for the new PIN block). This operation accepts a single session integrity key and a pre-encrypted PIN block — it does not model the full three-key separation.

Security: Test-only issuer-script assembly with clear session keys in the recipe."; - this.inlineHelp = "Input: issuer-script APDU message as hex.
Args: provide the encrypted target PIN block and derived EMV integrity key.
Validation: emulation helper for PIN-change script MAC assembly."; + this.description = "Paste the issuer-script APDU command into the input field as hex and generate the MAC for an offline EMV PIN-change script.

Input: issuer-script message data as hex.
Arguments: provide the already-encrypted target PIN block in hex and the already-derived EMV session integrity key.

Validation: Test helper. The new PIN block must already be encrypted, and this op appends it to the supplied message before applying the same supplied-key EMV MAC profile used elsewhere in this fork.

Key context: In a full issuer implementation, a PIN-change script involves three distinct keys: a secure-messaging integrity key (for the MAC), a secure-messaging confidentiality key (for encrypting the script data), and a PIN encryption key (for the new PIN block). This operation accepts a single session integrity key and a pre-encrypted PIN block — it does not model the full three-key separation.

Security: Test-only issuer-script assembly with clear session keys in the recipe."; + this.inlineHelp = "Input: issuer-script APDU message as hex.
Args: provide the encrypted target PIN block and derived EMV integrity key.
Validation: test helper for PIN-change script MAC assembly."; this.testDataSamples = [ { name: "EMV PIN change MAC sample", @@ -32,7 +32,7 @@ class GenerateEMVMACForPINChange extends Operation { this.outputType = "string"; this.args = [ { name: "New encrypted PIN block (hex)", type: "string", value: "", comment: "Provide the already-encrypted new PIN block that will be appended to the issuer-script message." }, - { name: "Session integrity key (hex)", type: "string", value: "", comment: "Provide the already-derived EMV session integrity key in hex. This emulation does not derive EMV keys or encrypt the PIN block for you." }, + { name: "Session integrity key (hex)", type: "string", value: "", comment: "Provide the already-derived EMV session integrity key in hex. This operation does not derive EMV keys or encrypt the PIN block for you." }, { name: "Output bytes", type: "number", value: 8, min: 1, max: 8, comment: "Number of leftmost MAC bytes to return. EMV issuer scripts commonly use 8 bytes." }, { name: "Output as JSON", type: "boolean", value: false, comment: "When enabled, returns the composed issuer-script message and the computed MAC." }, ]; diff --git a/src/core/operations/VerifyEMVMAC.mjs b/src/core/operations/VerifyEMVMAC.mjs index dae7c4e9..70c1106e 100644 --- a/src/core/operations/VerifyEMVMAC.mjs +++ b/src/core/operations/VerifyEMVMAC.mjs @@ -19,7 +19,7 @@ class VerifyEMVMAC extends Operation { this.name = "EMV Verify MAC"; this.module = "Payment"; this.description = "Paste the issuer-script or EMV command payload into the input field as hex and verify an EMV MAC.

Input: message data as hex.
Arguments: provide the already-derived EMV session integrity key and the expected MAC as hex.

Validation: Partially verified. This checks the same supplied-key EMV MAC profile as the generate operation and does not claim full issuer-host or scheme-specific EMV verification semantics.

Key context: In a full issuer implementation, the session integrity key used here corresponds to the secure-messaging integrity key (distinct from the confidentiality key used to encrypt data and the PIN encryption key used for PIN blocks). This operation accepts any key you supply and does not enforce that separation.

Security: Clear session keys in the recipe are test-use only."; - this.inlineHelp = "Input: issuer-script message data as hex.
Args: provide the derived EMV session key and expected MAC.
Validation: same supplied-key EMV profile as generation."; + this.inlineHelp = "Input: issuer-script message data as hex.
Args: provide the derived EMV session integrity key and expected MAC.
Validation: same supplied-key EMV profile as generation."; this.testDataSamples = [ { name: "EMV MAC verification sample", diff --git a/src/core/operations/VerifyPaymentPINData.mjs b/src/core/operations/VerifyPaymentPINData.mjs index 132b6c84..6ea384fa 100644 --- a/src/core/operations/VerifyPaymentPINData.mjs +++ b/src/core/operations/VerifyPaymentPINData.mjs @@ -18,13 +18,13 @@ class VerifyPaymentPINData extends Operation { this.name = "PIN Data Verify"; this.module = "Payment"; - this.description = "Paste a clear PIN block into the input field as hex and verify it against an expected PIN.

Input: clear PIN block hex.
Arguments: choose the format, provide the PAN when required, and supply the expected clear PIN.

Validation: Partially verified. This wrapper currently covers clear ISO 9564 formats 0, 1, and 3 only.

Security: Clear PIN handling is test-use only."; - this.inlineHelp = "Input: clear PIN block hex.
Args: define the PIN-block format, PAN context, and expected PIN.
Validation: clear ISO formats 0, 1, and 3 only."; + this.description = "Paste a clear PIN block into the input field as hex and verify it against an expected PIN.

Input: clear PIN block hex.
Arguments: choose the format, provide the PAN when required, supply the expected clear PIN, and optionally return structured JSON.

Validation: Partially verified. This wrapper currently covers clear ISO 9564 formats 0, 1, and 3 only.

Security: Clear PIN handling is test-use only."; + this.inlineHelp = "Input: clear PIN block hex.
Args: define the PIN-block format, PAN context, expected PIN, and output format.
Validation: clear ISO formats 0, 1, and 3 only."; this.testDataSamples = [ { name: "Format 0 verification sample", input: "041215FEDCBA9876", - args: ["ISO Format 0", "5432101234567890", "1234"] + args: ["ISO Format 0", "5432101234567890", "1234", true] } ]; this.infoURL = "https://wikipedia.org/wiki/ISO_9564"; @@ -34,6 +34,7 @@ class VerifyPaymentPINData extends Operation { { name: "Format", type: "option", value: ["ISO Format 0", "ISO Format 1", "ISO Format 3"], comment: "How to decode the input PIN block." }, { name: "Primary account number", type: "string", value: "", comment: "Required for formats 0 and 3." }, { name: "Expected PIN", type: "string", value: "", comment: "Clear PIN digits to compare against." }, + { name: "Output as JSON", type: "boolean", value: true, comment: "When enabled, returns the parsed PIN block and validity result." }, ]; } @@ -43,14 +44,15 @@ class VerifyPaymentPINData extends Operation { * @returns {string} */ run(input, args) { - const [format, pan, expectedPin] = args; + const [format, pan, expectedPin, outputJson] = args; const parser = new ParsePINBlock(); const parsed = JSON.parse(parser.run(input, [format, pan])); - return JSON.stringify({ + const result = { ...parsed, expectedPin, valid: parsed.pin === String(expectedPin || "") - }, null, 4); + }; + return outputJson ? JSON.stringify(result, null, 4) : String(result.valid); } } diff --git a/tests/operations/tests/Payment.mjs b/tests/operations/tests/Payment.mjs index 5970b9dc..041174c5 100644 --- a/tests/operations/tests/Payment.mjs +++ b/tests/operations/tests/Payment.mjs @@ -817,7 +817,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "PIN Data Verify", - args: ["ISO Format 0", "5432101234567890", "1234"] + args: ["ISO Format 0", "5432101234567890", "1234", true] } ] },