Removal of jsrsasign package and mentions.

This commit is contained in:
Leon Zandman 2026-05-17 19:31:38 +02:00
parent f61d26f189
commit 2c66e413bf
14 changed files with 41 additions and 50 deletions

View File

@ -13,6 +13,9 @@ All major and minor version changes will be documented in this file. Details of
## Details
## [Unreleased]
- Removed the unmaintained `jsrsasign` dependency. ASN.1/OID/PEM utilities, SM2, ECDSA, PEM/JWK key conversion, and X.509/CSR/CRL parsing now use `@noble/curves`, `@peculiar/x509`, and `asn1js`; related golden text fixtures were updated during the migration for accepted cosmetic output-format drift.
## [11.0.0] - 2026-04-28
- Revert sitemap to v8.0.X to fix build/deploy on master [@GCHQDeveloper581] | [#2348]
- Node version update from 22 to 24 [@lzandman] [@GCHQDeveloper581] | [#2347]
@ -1220,4 +1223,3 @@ Breaking changes:
[#2273]: https://github.com/gchq/CyberChef/pull/2273
[#2342]: https://github.com/gchq/CyberChef/pull/2342
[#1922]: https://github.com/gchq/CyberChef/pull/1922

7
package-lock.json generated
View File

@ -65,7 +65,6 @@
"jsonpath-plus": "^10.4.0",
"jsonwebtoken": "9.0.3",
"jsqr": "^1.4.0",
"jsrsasign": "^11.1.3",
"kbpgp": "^2.1.17",
"libbzip2-wasm": "0.0.4",
"libyara-wasm": "^1.2.1",
@ -12569,12 +12568,6 @@
"integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==",
"license": "Apache-2.0"
},
"node_modules/jsrsasign": {
"version": "11.1.3",
"resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-11.1.3.tgz",
"integrity": "sha512-nPnK5D/4lv0Dwr7TlzrKtAd8JlLZwFTqTUUB3NQCbtdobcRcohGFxjbPySDVh74iWUudcCsapYT6OxoyhJLhhA==",
"license": "MIT"
},
"node_modules/jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",

View File

@ -148,7 +148,6 @@
"jsonpath-plus": "^10.4.0",
"jsonwebtoken": "9.0.3",
"jsqr": "^1.4.0",
"jsrsasign": "^11.1.3",
"kbpgp": "^2.1.17",
"libbzip2-wasm": "0.0.4",
"libyara-wasm": "^1.2.1",

View File

@ -9,9 +9,10 @@
- [x] PR 3 — ECDSA primitives
- [x] PR 4 — PEM/JWK conversion + key extraction
- [x] PR 5 — X.509 / CSR / CRL parsing
- [ ] PR 6 — Removal
- [x] PR 6 — Removal
_Notes for next session:_
- **PR 6 complete:** dependency removed, source tree is free of runtime references, and the remaining migration references are documentation/changelog only.
- **PR 2 resolved:** SM2 is now built on `weierstrass(...)` + `ecdh(...)` from `@noble/curves/abstract/weierstrass.js` (curve params per GM/T 0003-2012). No `/sm2` subpath needed.
- **PR 3 resolved:** ECDSA primitives migrated; new [src/core/lib/Ecdsa.mjs](src/core/lib/Ecdsa.mjs) is the shared helper module. Existing ECDSA fixture set passes unchanged (sign↔verify round-trips and the canned P-256 signature fixtures both verify against `lowS: false`).
- **PR 4 resolved:** Key-conversion ops migrated; new [src/core/lib/KeyConvert.mjs](src/core/lib/KeyConvert.mjs) wraps RSA/EC/DSA PEM⇄JWK⇄SPKI/PKCS#8. DSA private-key parsing/building goes through `asn1js` directly (no peculiar `asn1-dsa` package and `node-forge` doesn't expose DSA), reusing the existing EC helpers from `Ecdsa.mjs`.
@ -241,6 +242,11 @@ After **PR 6:**
Record deviations from the original plan here, newest at the top. One bullet per change: what changed, why, and which PR.
### PR 6 — 2026-05-17
- Removed `jsrsasign` from [package.json](package.json) and [package-lock.json](package-lock.json). No runtime code changes were needed because PRs 1-5 had already moved operations to `@noble/curves`, `@peculiar/x509`, and `asn1js`.
- Removed stale dependency-name mentions from `src/` comments so `rg -n "jsrsasign" src/` is clean. Remaining mentions are intentionally limited to migration documentation and [CHANGELOG.md](CHANGELOG.md).
- Added a top-level [CHANGELOG.md](CHANGELOG.md) entry noting the removal and the accepted cosmetic output drift across the migrated ASN.1, ECDSA, key conversion, and X.509-family operations.
### PR 5 — 2026-05-17
- New [src/core/lib/X509.mjs](src/core/lib/X509.mjs) holds the shared X.509 helpers (`decodeX509Input`, `sigAlgOidToName`, `describeSpki`, `parseDerEcdsaSignature`, `isDerEcdsaSignature`, `formatJsonName`, `formatGeneralName`, `formatHexByteLines`/`formatHexColonWrapped`, `asnNameToJson`). [src/core/lib/PublicKey.mjs](src/core/lib/PublicKey.mjs)'s `formatDnObj` now accepts both the legacy jsrsasign shape and `@peculiar/x509`'s `JsonName` (array-of-records) shape. Migrated ops: [ParseX509Certificate.mjs](src/core/operations/ParseX509Certificate.mjs), [PubKeyFromCert.mjs](src/core/operations/PubKeyFromCert.mjs), [ParseCSR.mjs](src/core/operations/ParseCSR.mjs), [ParseX509CRL.mjs](src/core/operations/ParseX509CRL.mjs).
- **`X509Certificate` v1.14.3 doesn't expose `.version`.** Plan called for `cert.version`, but on the pinned v1 the property is missing. Worked around by parsing `cert.rawData` with the asn1-x509 `Certificate` schema and reading `tbsCertificate.version` + `signatureAlgorithm.algorithm` directly. The same approach is used in `ParseCSR` (with `CertificationRequest` from `@peculiar/asn1-csr`) and `ParseX509CRL` (with `CertificateList` from `@peculiar/asn1-x509`) — bypassing the WebCrypto algorithm mapping is necessary for DSA anyway (peculiar's algorithm provider doesn't know it).
@ -294,4 +300,3 @@ Record deviations from the original plan here, newest at the top. One bullet per
- Added `@noble/hashes` peer-dep bump (was on ^1.x, needed ^2 for the `legacy` subpath). No code impact.
- SM2 ciphertext fixture #3 was already wrong (decoded to the wrong plaintext under jsrsasign too) — confirmed via independent SM2 implementation, regenerated fixture.
-->

View File

@ -1,9 +1,8 @@
/**
* ASN.1 / OID / PEM helpers.
*
* Replacements for the small jsrsasign utilities used by the
* HexToObjectIdentifier, ObjectIdentifierToHex, HexToPEM and
* ParseASN1HexString operations.
* Helpers used by the HexToObjectIdentifier, ObjectIdentifierToHex,
* HexToPEM and ParseASN1HexString operations.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
@ -109,14 +108,13 @@ export function oidIntToHex(oid) {
/**
* Wrap a hex-encoded DER blob in a PEM envelope.
*
* Uses LF line endings only (the old jsrsasign output used CRLF).
* Uses LF line endings only.
*
* Input parsing is intentionally lenient to match the previous jsrsasign
* behaviour: whitespace is stripped, an odd-length string is left-padded
* with a zero, and characters that are not hex digits are treated as the
* nibble `0`. This keeps the operation usable as a generic byte-emitter
* inside larger recipes where the upstream stage may not produce strict
* hex.
* Input parsing is intentionally lenient: whitespace is stripped, an
* odd-length string is left-padded with a zero, and characters that are not
* hex digits are treated as the nibble `0`. This keeps the operation usable
* as a generic byte-emitter inside larger recipes where the upstream stage
* may not produce strict hex.
*
* @param {string} hex
* @param {string} label
@ -146,8 +144,7 @@ export function derToPem(hex, label) {
}
/**
* Walk an asn1js parse tree and produce an indented dump similar to the
* one jsrsasign's ASN1HEX.dump produced.
* Walk an asn1js parse tree and produce an indented dump.
*
* @param {string} hex
* @param {Object} [options]

View File

@ -2,7 +2,7 @@
* Shared ECDSA helpers built on @noble/curves and @peculiar/asn1-*.
*
* Used by the ECDSA Sign/Verify/Signature Conversion/Generate Key Pair
* operations. Migrated from jsrsasign.
* operations.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
@ -72,8 +72,7 @@ export function digestBytes(algo, bytes) {
/**
* Convert a JS string to bytes by Latin-1 truncation of each code unit (i.e.
* `charCodeAt(i) & 0xff`). This matches how jsrsasign / CryptoJS fed strings
* into MessageDigest.update keeping signatures interoperable for inputs
* `charCodeAt(i) & 0xff`). This keeps signatures interoperable for inputs
* coming out of upstream byte-producing ops, while preserving the
* (questionable) UTF-16-truncating behaviour for free-text inputs.
*
@ -162,7 +161,7 @@ export function verifyEcdsa(keyInfo, digest, asn1Hex) {
/**
* Quick test for whether a hex string parses as a single DER-encoded ASN.1
* value. Mirrors jsrsasign's ASN1HEX.isASN1HEX.
* value.
*
* @param {string} hex
* @returns {boolean}
@ -182,8 +181,8 @@ export function isAsn1Hex(hex) {
/**
* Parse an ASN.1 DER-encoded ECDSA signature and return the raw r/s INTEGER
* bytes as hex. Preserves the DER 2's-complement leading 0x00 when present
* (i.e. r/s may have a leading "00" pair) this matches the legacy
* jsrsasign ECDSA.parseSigHexInHexRS behaviour that existing tests assume.
* (i.e. r/s may have a leading "00" pair). Existing tests assume this
* compatibility behaviour.
*
* @param {string} asn1Hex
* @returns {{r: string, s: string}}

View File

@ -2,7 +2,7 @@
* Asymmetric key conversion helpers built on @peculiar/asn1-* and asn1js.
*
* Shared by the PEM to JWK / JWK to PEM / Public Key from Private Key
* operations. Replaces the jsrsasign key-format-conversion plumbing.
* operations.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
@ -370,8 +370,7 @@ function parsePkcs8(bytes) {
}
if (alg === ID_DSA) {
// DSA PKCS#8 carries only x (with p/q/g in the algorithm
// parameters). jsrsasign rejected this layout because no y was
// present and the existing tests assert that we do the same — we
// parameters). Without y, deriving the public key is unsupported;
// mark the info accordingly and let derivePublicKeyInfo throw.
return { kty: "DSA", isPrivate: true, y: null };
}

View File

@ -11,8 +11,8 @@ import { toHex, fromHex } from "./Hex.mjs";
/**
* Formats Distinguished Name (DN) objects to strings.
*
* Accepts either the legacy jsrsasign-style `{ array: [[{type, value}, ...], ...] }`
* shape OR `@peculiar/x509`'s `JsonName` shape an array of records keyed by
* Accepts either the legacy `{ array: [[{type, value}, ...], ...] }` shape
* OR `@peculiar/x509`'s `JsonName` shape an array of records keyed by
* RDN short-name (`[{ CN: ["foo"], OU: ["bar"] }, ...]`).
*
* @param {Object|Array} dnObj

View File

@ -58,8 +58,8 @@ function getCurve(name) {
Point,
n: params.n,
coordCharLen: params.coordCharLen,
// Uniform-ish random scalar in [1, n-1] — matches the bias profile of
// the previous jsrsasign-based getBigRandom.
// Uniform-ish random scalar in [1, n-1], matching the previous bias
// profile for compatibility with existing SM2 behaviour.
randomScalar: () => bytesToNumberBE(dh.utils.randomSecretKey()) % (params.n - 1n) + 1n,
};
curveCache[name] = cached;

View File

@ -2,7 +2,6 @@
* Shared X.509 / CSR / CRL helpers built on @peculiar/x509 + @peculiar/asn1-*.
*
* Used by ParseX509Certificate / PubKeyFromCert / ParseCSR / ParseX509CRL.
* Replaces the jsrsasign X.509 plumbing.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
@ -116,9 +115,9 @@ export function decodeX509Input(input, format) {
// ----- signature algorithm --------------------------------------------------
/**
* Map a signature-algorithm OID to the jsrsasign-style display name
* (e.g. "1.2.840.113549.1.1.11" -> "SHA256withRSA"). Falls back to the
* raw OID if unknown.
* Map a signature-algorithm OID to the compact display name used by these
* operations (e.g. "1.2.840.113549.1.1.11" -> "SHA256withRSA"). Falls back
* to the raw OID if unknown.
*
* @param {string} oid
* @returns {string}

View File

@ -166,7 +166,7 @@ ${extensionsText}`;
/**
* Format the algorithm label for the Public Key block. Mirrors the legacy
* jsrsasign labelling: "EC", "DSA", "RSA".
* labels: "EC", "DSA", "RSA".
*
* @param {object} spki
* @returns {string}
@ -233,8 +233,8 @@ function formatExtensions(cert) {
}
/**
* Format a JS Date as the jsrsasign UTCTime/GeneralizedTime string
* `yymmddHHMMSSZ` (or `yyyymmddHHMMSSZ` for dates past 2049).
* Format a JS Date as an ASN.1 UTCTime/GeneralizedTime string: `yymmddHHMMSSZ`
* or `yyyymmddHHMMSSZ` for dates past 2049.
*
* @param {Date} date
* @returns {string}

View File

@ -650,7 +650,7 @@ WWFkYSBZYWRh
it("Parse ASN.1 Hex string", () => {
// The bytes for "Mouth-watering" don't form a well-formed ASN.1 structure
// (tag 0x4d declares length 0x6f but only 12 bytes follow), so we report
// a parse error rather than the partial best-effort dump jsrsasign emitted.
// a parse error rather than a partial best-effort dump.
assert.strictEqual(
chef.parseASN1HexString(chef.toHex("Mouth-watering")).toString(),
"ASN.1 parse error: End of input reached before message was fully decoded (inconsistent offset and length values)"
@ -1146,4 +1146,3 @@ ExifImageHeight: 57`);
]);

View File

@ -1,8 +1,7 @@
/**
* ASN.1 / OID / PEM tests.
*
* Covers the four operations migrated from jsrsasign to the in-house
* Asn1.mjs helper:
* Covers the four operations migrated to the in-house Asn1.mjs helper:
* - Hex to Object Identifier
* - Object Identifier to Hex
* - Hex to PEM

View File

@ -1,8 +1,8 @@
/**
* Parse X.509 Certificate tests.
*
* Added as part of the jsrsasign @peculiar/x509 migration (PR 5) to give
* the operation regression coverage it previously lacked. The certificate
* Added as part of the @peculiar/x509 migration (PR 5) to give the
* operation regression coverage it previously lacked. The certificate
* fixtures are reused from PubKeyFromCert.mjs.
*
* @author n1474335 [n1474335@gmail.com]