From 18c6b9bc09e07ea2dba33b98d556a7902b6bd4dd Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 6 Apr 2020 15:24:22 +0100 Subject: [PATCH] Add RSA Verify operation --- src/core/operations/RSAVerify.mjs | 77 +++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/core/operations/RSAVerify.mjs diff --git a/src/core/operations/RSAVerify.mjs b/src/core/operations/RSAVerify.mjs new file mode 100644 index 00000000..2041e341 --- /dev/null +++ b/src/core/operations/RSAVerify.mjs @@ -0,0 +1,77 @@ +/** + * @author Matt C [me@mitt.dev] + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import forge from "node-forge/dist/forge.min.js"; +import { MD_ALGORITHMS } from "../lib/RSA.mjs"; + +/** + * RSA Verify operation + */ +class RSAVerify extends Operation { + + /** + * RSAVerify constructor + */ + constructor() { + super(); + + this.name = "RSA Verify"; + this.module = "Ciphers"; + this.description = "Verify a message against a signature and a public PEM encoded RSA key."; + this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + name: "RSA Public Key (PEM)", + type: "text", + value: "-----BEGIN RSA PUBLIC KEY-----" + }, + { + name: "Message", + type: "text", + value: "" + }, + { + name: "Message Digest Algorithm", + type: "option", + value: Object.keys(MD_ALGORITHMS) + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [pemKey, message, mdAlgo] = args; + if (pemKey.replace("-----BEGIN RSA PUBLIC KEY-----", "").length === 0) { + throw new OperationError("Please enter a public key."); + } + try { + // Load public key + const pubKey = forge.pki.publicKeyFromPem(pemKey); + // Generate message digest + const md = MD_ALGORITHMS[mdAlgo].create(); + md.update(message, "utf8"); + // Compare signed message digest and generated message digest + const result = pubKey.verify(md.digest().bytes(), input); + return result ? "Verified OK" : "Verification Failure"; + } catch (err) { + if (err.message === "Encrypted message length is invalid.") { + throw new OperationError(`Signature length (${err.length}) does not match expected length based on key (${err.expected}).`); + } + throw new OperationError(err); + } + } + +} + +export default RSAVerify;