Skip to content

Name.fromString() incorrectly parses unquoted = characters within RDN values #139

Description

@oceddi

Description
The Name.fromString() method incorrectly treats = characters inside an attribute value as a type/value separator.

According to RFC 4514 (Section 2.4), the equals sign (=) is not among the characters that must be escaped when it appears in the middle of a value string. Currently, the parser fails to treat these as literal characters, which leads to incorrect RDN splitting.

Steps to Reproduce

import { Name } from "@peculiar/x509";

// An RDN where the value contains an internal "=" character
// According to RFC 4514, this is a valid string representation.
const dn = "CN=Test=Value, OU=Test Department";
const name = new Name(dn);

console.log("Count of RDNs:", name.length);
console.log("String output:", name.toString());

// For deep inspection:
// name.forEach(rdn => console.log(rdn.toJSON()));

Expected Behavior
The parser should identify the first = as the separator and the subsequent = as part of the value.

RDN 1: Type: CN, Value: Test=Value

RDN 2: Type: OU, Value: Test Department

toString() Output: CN=Test=Value, OU=Test Department

Actual Behavior
The parser treats the internal = as the start of a new attribute, even though no separator (, or +) is present.

RDN 1: Type: CN, Value: Test

RDN 2: Type: Value, Value: `` (Empty)

RDN 3: Type: OU, Value: Test Department

toString() Output: CN=Test, Value=, OU=Test Department

Root Cause
In the fromString implementation, the global regex used for tokenization is:
(\d.[\d.]\d|[A-Za-z]+)=((?:"")|(?:".?[^\\]")|(?:^,+"\)|(?:[^,+].*?(?:[^\\][,+]))|(?:))([,+])?/g

The logic attempts to match the entire DN in one pass. Because the "Type" capture group ([A-Za-z]+)= looks for any alpha-string followed by an =, it captures Value= as a new key, truncating the previous value.

The parser should ideally split by RDN separators (, and +) first (accounting for escapes), and only then split each part by the first = encountered.

Environment
Node.js version: v18.20.8
@peculiar/x509 version: 1.14.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions