diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json
index a519cf09..53b8a2f0 100644
--- a/src/core/config/Categories.json
+++ b/src/core/config/Categories.json
@@ -179,6 +179,7 @@
"RSA Verify",
"RSA Encrypt",
"RSA Decrypt",
+ "Generate ECDSA Key Pair",
"Parse SSH Host Key",
"Parse CSR"
]
diff --git a/src/core/operations/GenerateECDSAKeyPair.mjs b/src/core/operations/GenerateECDSAKeyPair.mjs
new file mode 100644
index 00000000..c098fe01
--- /dev/null
+++ b/src/core/operations/GenerateECDSAKeyPair.mjs
@@ -0,0 +1,98 @@
+/**
+ * @author cplussharp
+ * @copyright Crown Copyright 2021
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation.mjs";
+import { cryptNotice } from "../lib/Crypt.mjs";
+import r from "jsrsasign";
+
+/**
+ * Generate ECDSA Key Pair operation
+ */
+class GenerateECDSAKeyPair extends Operation {
+
+ /**
+ * GenerateECDSAKeyPair constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Generate ECDSA Key Pair";
+ this.module = "Ciphers";
+ this.description = `Generate an ECDSA key pair with a given Curve.
${cryptNotice}`;
+ this.infoURL = "https://wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ name: "Elliptic Curve",
+ type: "option",
+ value: [
+ "P-256",
+ "P-384",
+ "P-521"
+ ]
+ },
+ {
+ name: "Output Format",
+ type: "option",
+ value: [
+ "PEM",
+ "DER",
+ "JWK"
+ ]
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async run(input, args) {
+ const [curveName, outputFormat] = args;
+
+ return new Promise((resolve, reject) => {
+ let internalCurveName;
+ switch (curveName) {
+ case "P-256":
+ internalCurveName = "secp256r1";
+ break;
+ case "P-384":
+ internalCurveName = "secp384r1";
+ break;
+ case "P-521":
+ internalCurveName = "secp521r1";
+ break;
+ }
+ const keyPair = r.KEYUTIL.generateKeypair("EC", internalCurveName);
+
+ let pubKey;
+ let privKey;
+ let result;
+ switch (outputFormat) {
+ case "PEM":
+ pubKey = r.KEYUTIL.getPEM(keyPair.pubKeyObj);
+ privKey = r.KEYUTIL.getPEM(keyPair.prvKeyObj, "PKCS8PRV");
+ result = pubKey + "\n" + privKey;
+ break;
+ case "DER":
+ result = keyPair.prvKeyObj.prvKeyHex;
+ break;
+ case "JWK":
+ pubKey = JSON.stringify(r.KEYUTIL.getJWKFromKey(keyPair.pubKeyObj));
+ privKey = JSON.stringify(r.KEYUTIL.getJWKFromKey(keyPair.prvKeyObj));
+ result = pubKey + "\n\n" + privKey;
+ break;
+ }
+
+ resolve(result);
+ });
+ }
+
+}
+
+export default GenerateECDSAKeyPair;