-
Notifications
You must be signed in to change notification settings - Fork 212
AlgorithmIdentifier parameters accepted for ecdsa-with-SHA256 in CMS SignerInfo #464
Description
Summary
PKIjs accepts CMS SignerInfo.signatureAlgorithm values where the AlgorithmIdentifier contains unexpected parameters for the algorithm ecdsa-with-SHA256 (1.2.840.10045.4.3.2).
According to common ASN.1 usage and interoperability expectations for ECDSA-with-SHA2 identifiers, the AlgorithmIdentifier.parameters field should be absent.
However, PKIjs successfully parses CMS structures where parameters are present and contain unexpected types such as:
-
NULL -
OCTET STRING
These structures are still considered valid during signature verification.
While major crypto stacks (e.g. OpenSSL and BouncyCastle) behave similarly and ignore the parameters, the acceptance of unexpected parameter encodings can create semantic ambiguity and policy mismatches across implementations.
Affected Component
CMS parsing and verification in PKIjs.
Relevant structure:
SignerInfo.signatureAlgorithm
ASN.1 structure:
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
Tested algorithm:
ecdsa-with-SHA256
OID: 1.2.840.10045.4.3.2
Security Implication
Although the signature still verifies cryptographically, accepting arbitrary parameter encodings may enable:
-
inconsistent algorithm interpretation across implementations
-
policy validation bypass when strict DER/semantic validation is expected
-
potential parser differential scenarios in heterogeneous verification pipelines
Example scenario:
Component A (strict validator)
→ rejects AlgorithmIdentifier parameters
Component B (PKIjs)
→ ignores parameters and verifies signature
This creates a verification policy mismatch.
Such mismatches have historically led to signature verification issues in cryptographic systems.
Proof of Concept
The following PoC generates CMS structures where:
AlgorithmIdentifier.algorithm = ecdsa-with-SHA256
AlgorithmIdentifier.parameters = NULL or OCTET STRING
and demonstrates that PKIjs still verifies the signature.
PoC Environment
Node.js
Node 24.x
PKIjs
asn1js
OpenSSL
PoC Script (PKIjs)
import fs from "fs";
import * as asn1js from "asn1js";
import * as pkijs from "pkijs";
const webcrypto = globalThis.crypto;
pkijs.setEngine(
"nodeEngine",
webcrypto,
new pkijs.CryptoEngine({
name: "nodeEngine",
crypto: webcrypto,
subtle: webcrypto.subtle
})
);
function readDER(path) {
const b = fs.readFileSync(path);
return b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength);
}
function inspectCMS(path) {
const der = readDER(path);
const asn1 = asn1js.fromBER(der);
const contentInfo = new pkijs.ContentInfo({
schema: asn1.result
});
const signedData = new pkijs.SignedData({
schema: contentInfo.content
});
console.log("signerInfos:", signedData.signerInfos.length);
signedData.signerInfos.forEach((si, i) => {
const alg = si.signatureAlgorithm;
console.log(
`SignerInfo[${i}]`,
"sigAlg OID=" + alg.algorithmId,
"params=" +
(alg.algorithmParams
? alg.algorithmParams.constructor.name
: "absent")
);
});
}
inspectCMS("bad_a1_pkijs.cms.der");
inspectCMS("bad_a2_pkijs.cms.der");
Example Outputs
Valid CMS
SignerInfo[0] sigAlg OID=1.2.840.10045.4.3.2 params=absent
Modified CMS
SignerInfo[0] sigAlg OID=1.2.840.10045.4.3.2 params=OCTET STRING
SignerInfo[0] sigAlg OID=1.2.840.10045.4.3.2 params=NULL
Despite the parameter manipulation, the CMS signature remains valid.
Verification Behavior
Observed behavior:
The parameters appear to be ignored during verification.
DER Example
Example DER encoding used in the PoC:
AlgorithmIdentifier
SEQUENCE
OBJECT IDENTIFIER 1.2.840.10045.4.3.2
OCTET STRING 00
Hex:
300d06082a8648ce3d040302040100
Recommendation
PKIjs could optionally enforce stricter validation rules for AlgorithmIdentifier parameters.
Suggested behavior:
If algorithm == ecdsa-with-SHA256
then parameters MUST be absent
Possible implementation:
if (algOID === "1.2.840.10045.4.3.2" && paramsPresent)
reject
Alternatively:
-
provide a strict validation mode
-
warn on unexpected parameter encodings
Disclosure Intent
This report is intended to highlight a semantic validation gap that may lead to interoperability issues or policy bypass in mixed cryptographic environments.
No direct exploit has been identified.