mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-22 07:46:16 -04:00
ESM: Ported PublicKey operations
This commit is contained in:
parent
709630f39b
commit
049656ec6b
7 changed files with 518 additions and 0 deletions
40
src/core/operations/HexToObjectIdentifier.mjs
Normal file
40
src/core/operations/HexToObjectIdentifier.mjs
Normal file
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import r from "jsrsasign";
|
||||
import Operation from "../Operation";
|
||||
|
||||
/**
|
||||
* Hex to Object Identifier operation
|
||||
*/
|
||||
class HexToObjectIdentifier extends Operation {
|
||||
|
||||
/**
|
||||
* HexToObjectIdentifier constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Hex to Object Identifier";
|
||||
this.module = "PublicKey";
|
||||
this.description = "Converts a hexadecimal string into an object identifier (OID).";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
return r.KJUR.asn1.ASN1Util.oidHexToInt(input.replace(/\s/g, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default HexToObjectIdentifier;
|
46
src/core/operations/HexToPEM.mjs
Normal file
46
src/core/operations/HexToPEM.mjs
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import r from "jsrsasign";
|
||||
import Operation from "../Operation";
|
||||
|
||||
/**
|
||||
* Hex to PEM operation
|
||||
*/
|
||||
class HexToPEM extends Operation {
|
||||
|
||||
/**
|
||||
* HexToPEM constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Hex to PEM";
|
||||
this.module = "PublicKey";
|
||||
this.description = "Converts a hexadecimal DER (Distinguished Encoding Rules) string into PEM (Privacy Enhanced Mail) format.";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Header string",
|
||||
"type": "string",
|
||||
"value": "CERTIFICATE"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
return r.KJUR.asn1.ASN1Util.getPEMStringFromHex(input.replace(/\s/g, ""), args[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default HexToPEM;
|
40
src/core/operations/ObjectIdentifierToHex.mjs
Normal file
40
src/core/operations/ObjectIdentifierToHex.mjs
Normal file
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import r from "jsrsasign";
|
||||
import Operation from "../Operation";
|
||||
|
||||
/**
|
||||
* Object Identifier to Hex operation
|
||||
*/
|
||||
class ObjectIdentifierToHex extends Operation {
|
||||
|
||||
/**
|
||||
* ObjectIdentifierToHex constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Object Identifier to Hex";
|
||||
this.module = "PublicKey";
|
||||
this.description = "Converts an object identifier (OID) into a hexadecimal string.";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
return r.KJUR.asn1.ASN1Util.oidIntToHex(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ObjectIdentifierToHex;
|
50
src/core/operations/PEMToHex.mjs
Normal file
50
src/core/operations/PEMToHex.mjs
Normal file
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import r from "jsrsasign";
|
||||
import Operation from "../Operation";
|
||||
|
||||
/**
|
||||
* PEM to Hex operation
|
||||
*/
|
||||
class PEMToHex extends Operation {
|
||||
|
||||
/**
|
||||
* PEMToHex constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "PEM to Hex";
|
||||
this.module = "PublicKey";
|
||||
this.description = "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (input.indexOf("-----BEGIN") < 0) {
|
||||
// Add header so that the KEYUTIL function works
|
||||
input = "-----BEGIN CERTIFICATE-----" + input;
|
||||
}
|
||||
if (input.indexOf("-----END") < 0) {
|
||||
// Add footer so that the KEYUTIL function works
|
||||
input = input + "-----END CERTIFICATE-----";
|
||||
}
|
||||
const cert = new r.X509();
|
||||
cert.readCertPEM(input);
|
||||
return cert.hex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PEMToHex;
|
54
src/core/operations/ParseASN1HexString.mjs
Normal file
54
src/core/operations/ParseASN1HexString.mjs
Normal file
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import r from "jsrsasign";
|
||||
import Operation from "../Operation";
|
||||
|
||||
/**
|
||||
* Parse ASN.1 hex string operation
|
||||
*/
|
||||
class ParseASN1HexString extends Operation {
|
||||
|
||||
/**
|
||||
* ParseASN1HexString constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Parse ASN.1 hex string";
|
||||
this.module = "PublicKey";
|
||||
this.description = "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.<br><br>This operation parses arbitrary ASN.1 data and presents the resulting tree.";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Starting index",
|
||||
"type": "number",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"name": "Truncate octet strings longer than",
|
||||
"type": "number",
|
||||
"value": 32
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [index, truncateLen] = args;
|
||||
return r.ASN1HEX.dump(input.replace(/\s/g, ""), {
|
||||
"ommitLongOctet": truncateLen
|
||||
}, index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParseASN1HexString;
|
216
src/core/operations/ParseX509Certificate.mjs
Normal file
216
src/core/operations/ParseX509Certificate.mjs
Normal file
|
@ -0,0 +1,216 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import r from "jsrsasign";
|
||||
import { fromBase64 } from "../lib/Base64";
|
||||
import { toHex } from "../lib/Hex";
|
||||
import { formatByteStr, formatDnStr } from "../lib/PublicKey";
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
|
||||
/**
|
||||
* Parse X.509 certificate operation
|
||||
*/
|
||||
class ParseX509Certificate extends Operation {
|
||||
|
||||
/**
|
||||
* ParseX509Certificate constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Parse X.509 certificate";
|
||||
this.module = "PublicKey";
|
||||
this.description = "X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). It is commonly involved with SSL/TLS security.<br><br>This operation displays the contents of a certificate in a human readable format, similar to the openssl command line tool.<br><br>Tags: X509, server hello, handshake";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Input format",
|
||||
"type": "option",
|
||||
"value": ["PEM", "DER Hex", "Base64", "Raw"]
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
{
|
||||
"match": "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$",
|
||||
"flags": "i",
|
||||
"args": [
|
||||
"PEM"
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!input.length) {
|
||||
return "No input";
|
||||
}
|
||||
|
||||
const cert = new r.X509(),
|
||||
inputFormat = args[0];
|
||||
|
||||
switch (inputFormat) {
|
||||
case "DER Hex":
|
||||
input = input.replace(/\s/g, "");
|
||||
cert.readCertHex(input);
|
||||
break;
|
||||
case "PEM":
|
||||
cert.readCertPEM(input);
|
||||
break;
|
||||
case "Base64":
|
||||
cert.readCertHex(toHex(fromBase64(input, null, "byteArray"), ""));
|
||||
break;
|
||||
case "Raw":
|
||||
cert.readCertHex(toHex(Utils.strToByteArray(input), ""));
|
||||
break;
|
||||
default:
|
||||
throw "Undefined input format";
|
||||
}
|
||||
|
||||
const sn = cert.getSerialNumberHex(),
|
||||
issuer = cert.getIssuerString(),
|
||||
subject = cert.getSubjectString(),
|
||||
pk = cert.getPublicKey(),
|
||||
pkFields = [],
|
||||
sig = cert.getSignatureValueHex();
|
||||
|
||||
let pkStr = "",
|
||||
sigStr = "",
|
||||
extensions = "";
|
||||
|
||||
// Public Key fields
|
||||
pkFields.push({
|
||||
key: "Algorithm",
|
||||
value: pk.type
|
||||
});
|
||||
|
||||
if (pk.type === "EC") { // ECDSA
|
||||
pkFields.push({
|
||||
key: "Curve Name",
|
||||
value: pk.curveName
|
||||
});
|
||||
pkFields.push({
|
||||
key: "Length",
|
||||
value: (((new r.BigInteger(pk.pubKeyHex, 16)).bitLength()-3) /2) + " bits"
|
||||
});
|
||||
pkFields.push({
|
||||
key: "pub",
|
||||
value: formatByteStr(pk.pubKeyHex, 16, 18)
|
||||
});
|
||||
} else if (pk.type === "DSA") { // DSA
|
||||
pkFields.push({
|
||||
key: "pub",
|
||||
value: formatByteStr(pk.y.toString(16), 16, 18)
|
||||
});
|
||||
pkFields.push({
|
||||
key: "P",
|
||||
value: formatByteStr(pk.p.toString(16), 16, 18)
|
||||
});
|
||||
pkFields.push({
|
||||
key: "Q",
|
||||
value: formatByteStr(pk.q.toString(16), 16, 18)
|
||||
});
|
||||
pkFields.push({
|
||||
key: "G",
|
||||
value: formatByteStr(pk.g.toString(16), 16, 18)
|
||||
});
|
||||
} else if (pk.e) { // RSA
|
||||
pkFields.push({
|
||||
key: "Length",
|
||||
value: pk.n.bitLength() + " bits"
|
||||
});
|
||||
pkFields.push({
|
||||
key: "Modulus",
|
||||
value: formatByteStr(pk.n.toString(16), 16, 18)
|
||||
});
|
||||
pkFields.push({
|
||||
key: "Exponent",
|
||||
value: pk.e + " (0x" + pk.e.toString(16) + ")"
|
||||
});
|
||||
} else {
|
||||
pkFields.push({
|
||||
key: "Error",
|
||||
value: "Unknown Public Key type"
|
||||
});
|
||||
}
|
||||
|
||||
// Format Public Key fields
|
||||
for (let i = 0; i < pkFields.length; i++) {
|
||||
pkStr += ` ${pkFields[i].key}:${(pkFields[i].value + "\n").padStart(
|
||||
18 - (pkFields[i].key.length + 3) + pkFields[i].value.length + 1,
|
||||
" "
|
||||
)}`;
|
||||
}
|
||||
|
||||
// Signature fields
|
||||
let breakoutSig = false;
|
||||
try {
|
||||
breakoutSig = r.ASN1HEX.dump(sig).indexOf("SEQUENCE") === 0;
|
||||
} catch (err) {
|
||||
// Error processing signature, output without further breakout
|
||||
}
|
||||
|
||||
if (breakoutSig) { // DSA or ECDSA
|
||||
sigStr = ` r: ${formatByteStr(r.ASN1HEX.getV(sig, 4), 16, 18)}
|
||||
s: ${formatByteStr(r.ASN1HEX.getV(sig, 48), 16, 18)}`;
|
||||
} else { // RSA or unknown
|
||||
sigStr = ` Signature: ${formatByteStr(sig, 16, 18)}`;
|
||||
}
|
||||
|
||||
// Extensions
|
||||
try {
|
||||
extensions = cert.getInfo().split("X509v3 Extensions:\n")[1].split("signature")[0];
|
||||
} catch (err) {}
|
||||
|
||||
const issuerStr = formatDnStr(issuer, 2),
|
||||
nbDate = formatDate(cert.getNotBefore()),
|
||||
naDate = formatDate(cert.getNotAfter()),
|
||||
subjectStr = formatDnStr(subject, 2);
|
||||
|
||||
return `Version: ${cert.version} (0x${Utils.hex(cert.version - 1)})
|
||||
Serial number: ${new r.BigInteger(sn, 16).toString()} (0x${sn})
|
||||
Algorithm ID: ${cert.getSignatureAlgorithmField()}
|
||||
Validity
|
||||
Not Before: ${nbDate} (dd-mm-yy hh:mm:ss) (${cert.getNotBefore()})
|
||||
Not After: ${naDate} (dd-mm-yy hh:mm:ss) (${cert.getNotAfter()})
|
||||
Issuer
|
||||
${issuerStr}
|
||||
Subject
|
||||
${subjectStr}
|
||||
Public Key
|
||||
${pkStr.slice(0, -1)}
|
||||
Certificate Signature
|
||||
Algorithm: ${cert.getSignatureAlgorithmName()}
|
||||
${sigStr}
|
||||
|
||||
Extensions
|
||||
${extensions}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParseX509Certificate;
|
||||
|
||||
/**
|
||||
* Formats dates.
|
||||
*
|
||||
* @param {string} dateStr
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatDate (dateStr) {
|
||||
return dateStr[4] + dateStr[5] + "/" +
|
||||
dateStr[2] + dateStr[3] + "/" +
|
||||
dateStr[0] + dateStr[1] + " " +
|
||||
dateStr[6] + dateStr[7] + ":" +
|
||||
dateStr[8] + dateStr[9] + ":" +
|
||||
dateStr[10] + dateStr[11];
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue