From: Virendra Thakur <[email protected]>

Add patch to fix CVE-2021-44532

Signed-off-by: Virendra Thakur <[email protected]>
Signed-off-by: virendra thakur <[email protected]>
---
 .../nodejs/nodejs/CVE-2021-44532.patch        | 3090 +++++++++++++++++
 .../recipes-devtools/nodejs/nodejs_12.21.0.bb |    1 +
 2 files changed, 3091 insertions(+)
 create mode 100644 meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch

diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch 
b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch
new file mode 100644
index 000000000..dff7fe23a
--- /dev/null
+++ b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch
@@ -0,0 +1,3090 @@
+From 19873abfb24dce75ffff042efe76dc5633052677 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <[email protected]>
+Date: Wed, 29 Dec 2021 19:30:57 -0500
+Subject: [PATCH] crypto,tls: implement safe x509 GeneralName format
+
+This change introduces JSON-compatible escaping rules for strings that
+include X.509 GeneralName components (see RFC 5280). This non-standard
+format avoids ambiguities and prevents injection attacks that could
+previously lead to X.509 certificates being accepted even though they
+were not valid for the target hostname.
+
+These changes affect the format of subject alternative names and the
+format of authority information access. The checkServerIdentity function
+has been modified to safely handle the new format, eliminating the
+possibility of injecting subject alternative names into the verification
+logic.
+
+Because each subject alternative name is only encoded as a JSON string
+literal if necessary for security purposes, this change will only be
+visible in rare cases.
+
+This addresses CVE-2021-44532.
+
+Co-authored-by: Akshay K <[email protected]>
+CVE-ID: CVE-2021-44532
+Backport-PR-URL: https://github.com/nodejs-private/node-private/pull/306
+PR-URL: https://github.com/nodejs-private/node-private/pull/300
+Reviewed-By: Michael Dawson <[email protected]>
+Reviewed-By: Rich Trott <[email protected]>
+
+Upstream-Status: Backport 
[https://github.com/nodejs/node/commit/19873abfb24dce75ffff042efe76dc5633052677]
+
+CVE: CVE-2021-44532
+
+Signed-off-by: Virendra Thakur <[email protected]>
+
+---
+ doc/api/errors.md                             |   8 +
+ lib/_tls_common.js                            |   9 +
+ lib/internal/errors.js                        |   2 +
+ lib/tls.js                                    |  52 +-
+ src/node_crypto_common.cc                     | 340 ++++++++++--
+ test/common/index.js                          |   7 +
+ test/fixtures/keys/Makefile                   |  14 +
+ .../incorrect_san_correct_subject-cert.pem    |  11 +
+ .../incorrect_san_correct_subject-key.pem     |   5 +
+ test/fixtures/x509-escaping/.gitignore        |   2 +
+ test/fixtures/x509-escaping/alt-0-cert.pem    |  29 +
+ test/fixtures/x509-escaping/alt-1-cert.pem    |  28 +
+ test/fixtures/x509-escaping/alt-10-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-11-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-12-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-13-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-14-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-15-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-16-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-17-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-18-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-19-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-2-cert.pem    |  28 +
+ test/fixtures/x509-escaping/alt-20-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-21-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-22-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-23-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-24-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-25-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-26-cert.pem   |  29 +
+ test/fixtures/x509-escaping/alt-27-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-28-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-29-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-3-cert.pem    |  28 +
+ test/fixtures/x509-escaping/alt-30-cert.pem   |  28 +
+ test/fixtures/x509-escaping/alt-4-cert.pem    |  28 +
+ test/fixtures/x509-escaping/alt-5-cert.pem    |  29 +
+ test/fixtures/x509-escaping/alt-6-cert.pem    |  28 +
+ test/fixtures/x509-escaping/alt-7-cert.pem    |  28 +
+ test/fixtures/x509-escaping/alt-8-cert.pem    |  28 +
+ test/fixtures/x509-escaping/alt-9-cert.pem    |  28 +
+ test/fixtures/x509-escaping/create-certs.js   | 502 ++++++++++++++++++
+ .../x509-escaping/google/intermediate.pem     |  11 +
+ test/fixtures/x509-escaping/google/key.pem    |   5 +
+ test/fixtures/x509-escaping/google/leaf0.pem  |  10 +
+ test/fixtures/x509-escaping/google/leaf1.pem  |  10 +
+ test/fixtures/x509-escaping/google/leaf2.pem  |  10 +
+ test/fixtures/x509-escaping/google/leaf3.pem  |  10 +
+ test/fixtures/x509-escaping/google/leaf4.pem  |  10 +
+ test/fixtures/x509-escaping/google/root.pem   |   9 +
+ test/fixtures/x509-escaping/info-0-cert.pem   |  30 ++
+ test/fixtures/x509-escaping/info-1-cert.pem   |  31 ++
+ test/fixtures/x509-escaping/info-2-cert.pem   |  29 +
+ test/fixtures/x509-escaping/info-3-cert.pem   |  30 ++
+ test/fixtures/x509-escaping/info-4-cert.pem   |  29 +
+ test/fixtures/x509-escaping/package.json      |  12 +
+ test/fixtures/x509-escaping/server-key.pem    |  52 ++
+ test/parallel/test-tls-0-dns-altname.js       |   2 +-
+ test/parallel/test-x509-escaping.js           | 349 ++++++++++++
+ 59 files changed, 2429 insertions(+), 42 deletions(-)
+ create mode 100644 test/fixtures/keys/incorrect_san_correct_subject-cert.pem
+ create mode 100644 test/fixtures/keys/incorrect_san_correct_subject-key.pem
+ create mode 100644 test/fixtures/x509-escaping/.gitignore
+ create mode 100644 test/fixtures/x509-escaping/alt-0-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-1-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-10-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-11-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-12-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-13-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-14-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-15-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-16-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-17-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-18-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-19-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-2-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-20-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-21-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-22-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-23-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-24-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-25-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-26-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-27-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-28-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-29-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-3-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-30-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-4-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-5-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-6-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-7-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-8-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/alt-9-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/create-certs.js
+ create mode 100644 test/fixtures/x509-escaping/google/intermediate.pem
+ create mode 100644 test/fixtures/x509-escaping/google/key.pem
+ create mode 100644 test/fixtures/x509-escaping/google/leaf0.pem
+ create mode 100644 test/fixtures/x509-escaping/google/leaf1.pem
+ create mode 100644 test/fixtures/x509-escaping/google/leaf2.pem
+ create mode 100644 test/fixtures/x509-escaping/google/leaf3.pem
+ create mode 100644 test/fixtures/x509-escaping/google/leaf4.pem
+ create mode 100644 test/fixtures/x509-escaping/google/root.pem
+ create mode 100644 test/fixtures/x509-escaping/info-0-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/info-1-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/info-2-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/info-3-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/info-4-cert.pem
+ create mode 100644 test/fixtures/x509-escaping/package.json
+ create mode 100644 test/fixtures/x509-escaping/server-key.pem
+ create mode 100644 test/parallel/test-x509-escaping.js
+
+diff --git a/doc/api/errors.md b/doc/api/errors.md
+index d5d8e1efa7..9d176d9048 100644
+--- a/doc/api/errors.md
++++ b/doc/api/errors.md
+@@ -1869,6 +1869,14 @@ An unspecified or non-specific system error has 
occurred within the Node.js
+ process. The error object will have an `err.info` object property with
+ additional details.
+ 
++<a id="ERR_TLS_CERT_ALTNAME_FORMAT"></a>
++### `ERR_TLS_CERT_ALTNAME_FORMAT`
++
++This error is thrown by `checkServerIdentity` if a user-supplied
++`subjectaltname` property violates encoding rules. Certificate objects 
produced
++by Node.js itself always comply with encoding rules and will never cause
++this error.
++
+ <a id="ERR_TLS_CERT_ALTNAME_INVALID"></a>
+ ### `ERR_TLS_CERT_ALTNAME_INVALID`
+ 
+diff --git a/lib/_tls_common.js b/lib/_tls_common.js
+index b7a3b70a24..a2a74813f1 100644
+--- a/lib/_tls_common.js
++++ b/lib/_tls_common.js
+@@ -23,6 +23,7 @@
+ 
+ const {
+   ArrayIsArray,
++  JSONParse,
+   ObjectCreate,
+ } = primordials;
+ 
+@@ -323,6 +324,14 @@ exports.translatePeerCertificate = function 
translatePeerCertificate(c) {
+ 
+     // XXX: More key validation?
+     info.replace(/([^\n:]*):([^\n]*)(?:\n|$)/g, (all, key, val) => {
++      if (val.charCodeAt(0) === 0x22) {
++        // The translatePeerCertificate function is only
++        // used on internally created legacy certificate
++        // objects, and any value that contains a quote
++        // will always be a valid JSON string literal,
++        // so this should never throw.
++        val = JSONParse(val);
++      }
+       if (key in c.infoAccess)
+         c.infoAccess[key].push(val);
+       else
+diff --git a/lib/internal/errors.js b/lib/internal/errors.js
+index 2cf7df436b..cd7153ad1a 100644
+--- a/lib/internal/errors.js
++++ b/lib/internal/errors.js
+@@ -1345,6 +1345,8 @@ E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is 
in objectMode', Error);
+ E('ERR_STREAM_WRITE_AFTER_END', 'write after end', Error);
+ E('ERR_SYNTHETIC', 'JavaScript Callstack', Error);
+ E('ERR_SYSTEM_ERROR', 'A system error occurred', SystemError);
++E('ERR_TLS_CERT_ALTNAME_FORMAT', 'Invalid subject alternative name string',
++  SyntaxError);
+ E('ERR_TLS_CERT_ALTNAME_INVALID', function(reason, host, cert) {
+   this.reason = reason;
+   this.host = host;
+diff --git a/lib/tls.js b/lib/tls.js
+index 2ccbe409c9..cefb47d10f 100644
+--- a/lib/tls.js
++++ b/lib/tls.js
+@@ -24,11 +24,19 @@
+ const {
+   Array,
+   ArrayIsArray,
++  ArrayPrototypePush,
++  JSONParse,
+   ObjectDefineProperty,
+   ObjectFreeze,
++  RegExpPrototypeExec,
++  StringPrototypeIncludes,
++  StringPrototypeIndexOf,
++  StringPrototypeSplit,
++  StringPrototypeSubstring,
+ } = primordials;
+ 
+ const {
++  ERR_TLS_CERT_ALTNAME_FORMAT,
+   ERR_TLS_CERT_ALTNAME_INVALID,
+   ERR_OUT_OF_RANGE
+ } = require('internal/errors').codes;
+@@ -207,6 +215,45 @@ function check(hostParts, pattern, wildcards) {
+   return true;
+ }
+ 
++// This pattern is used to determine the length of escaped sequences within
++// the subject alt names string. It allows any valid JSON string literal.
++// This MUST match the JSON specification (ECMA-404 / RFC8259) exactly.
++const jsonStringPattern =
++  // eslint-disable-next-line no-control-regex
++  /^"(?:[^"\\\u0000-\u001f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/;
++
++function splitEscapedAltNames(altNames) {
++  const result = [];
++  let currentToken = '';
++  let offset = 0;
++  while (offset !== altNames.length) {
++    const nextSep = StringPrototypeIndexOf(altNames, ', ', offset);
++    const nextQuote = StringPrototypeIndexOf(altNames, '"', offset);
++    if (nextQuote !== -1 && (nextSep === -1 || nextQuote < nextSep)) {
++      // There is a quote character and there is no separator before the 
quote.
++      currentToken += StringPrototypeSubstring(altNames, offset, nextQuote);
++      const match = RegExpPrototypeExec(
++        jsonStringPattern, StringPrototypeSubstring(altNames, nextQuote));
++      if (!match) {
++        throw new ERR_TLS_CERT_ALTNAME_FORMAT();
++      }
++      currentToken += JSONParse(match[0]);
++      offset = nextQuote + match[0].length;
++    } else if (nextSep !== -1) {
++      // There is a separator and no quote before it.
++      currentToken += StringPrototypeSubstring(altNames, offset, nextSep);
++      ArrayPrototypePush(result, currentToken);
++      currentToken = '';
++      offset = nextSep + 2;
++    } else {
++      currentToken += StringPrototypeSubstring(altNames, offset);
++      offset = altNames.length;
++    }
++  }
++  ArrayPrototypePush(result, currentToken);
++  return result;
++}
++
+ let urlWarningEmitted = false;
+ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
+   const subject = cert.subject;
+@@ -218,7 +265,10 @@ exports.checkServerIdentity = function 
checkServerIdentity(hostname, cert) {
+   hostname = '' + hostname;
+ 
+   if (altNames) {
+-    for (const name of altNames.split(', ')) {
++    const splitAltNames = StringPrototypeIncludes(altNames, '"') ?
++      splitEscapedAltNames(altNames) :
++      StringPrototypeSplit(altNames, ', ');
++    for (const name of splitAltNames) {
+       if (name.startsWith('DNS:')) {
+         dnsNames.push(name.slice(4));
+       } else if (name.startsWith('URI:')) {
+diff --git a/src/node_crypto_common.cc b/src/node_crypto_common.cc
+index 74bc0a9756..53fbc576ef 100644
+--- a/src/node_crypto_common.cc
++++ b/src/node_crypto_common.cc
+@@ -480,39 +480,320 @@ void AddFingerprintDigest(
+   }
+ }
+ 
+-bool SafeX509ExtPrint(const BIOPointer& out, X509_EXTENSION* ext) {
+-  const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
++static inline bool IsSafeAltName(const char* name, size_t length, bool utf8) {
++  for (size_t i = 0; i < length; i++) {
++    char c = name[i];
++    switch (c) {
++    case '"':
++    case '\\':
++      // These mess with encoding rules.
++      // Fall through.
++    case ',':
++      // Commas make it impossible to split the list of subject alternative
++      // names unambiguously, which is why we have to escape.
++      // Fall through.
++    case '\'':
++      // Single quotes are unlikely to appear in any legitimate values, but 
they
++      // could be used to make a value look like it was escaped (i.e., 
enclosed
++      // in single/double quotes).
++      return false;
++    default:
++      if (utf8) {
++        // In UTF8 strings, we require escaping for any ASCII control 
character,
++        // but NOT for non-ASCII characters. Note that all bytes of any code
++        // point that consists of more than a single byte have their MSB set.
++        if (static_cast<unsigned char>(c) < ' ' || c == '\x7f') {
++          return false;
++        }
++      } else {
++        // Check if the char is a control character or non-ASCII character. 
Note
++        // that char may or may not be a signed type. Regardless, non-ASCII
++        // values will always be outside of this range.
++        if (c < ' ' || c > '~') {
++          return false;
++        }
++      }
++    }
++  }
++  return true;
++}
+ 
+-  if (method != X509V3_EXT_get_nid(NID_subject_alt_name))
+-    return false;
++static inline void PrintAltName(const BIOPointer& out, const char* name,
++                                size_t length, bool utf8,
++                                const char* safe_prefix) {
++  if (IsSafeAltName(name, length, utf8)) {
++    // For backward-compatibility, append "safe" names without any
++    // modifications.
++    if (safe_prefix != nullptr) {
++      BIO_printf(out.get(), "%s:", safe_prefix);
++    }
++    BIO_write(out.get(), name, length);
++  } else {
++    // If a name is not "safe", we cannot embed it without special
++    // encoding. This does not usually happen, but we don't want to hide
++    // it from the user either. We use JSON compatible escaping here.
++    BIO_write(out.get(), "\"", 1);
++    if (safe_prefix != nullptr) {
++      BIO_printf(out.get(), "%s:", safe_prefix);
++    }
++    for (size_t j = 0; j < length; j++) {
++      char c = static_cast<char>(name[j]);
++      if (c == '\\') {
++        BIO_write(out.get(), "\\\\", 2);
++      } else if (c == '"') {
++        BIO_write(out.get(), "\\\"", 2);
++      } else if ((c >= ' ' && c != ',' && c <= '~') || (utf8 && (c & 0x80))) {
++        // Note that the above condition explicitly excludes commas, which 
means
++        // that those are encoded as Unicode escape sequences in the "else"
++        // block. That is not strictly necessary, and Node.js itself would 
parse
++        // it correctly either way. We only do this to account for third-party
++        // code that might be splitting the string at commas (as Node.js 
itself
++        // used to do).
++        BIO_write(out.get(), &c, 1);
++      } else {
++        // Control character or non-ASCII character. We treat everything as
++        // Latin-1, which corresponds to the first 255 Unicode code points.
++        const char hex[] = "0123456789abcdef";
++        char u[] = { '\\', 'u', '0', '0', hex[(c & 0xf0) >> 4], hex[c & 0x0f] 
};
++        BIO_write(out.get(), u, sizeof(u));
++      }
++    }
++    BIO_write(out.get(), "\"", 1);
++  }
++}
++
++static inline void PrintLatin1AltName(const BIOPointer& out,
++                                      const ASN1_IA5STRING* name,
++                                      const char* safe_prefix = nullptr) {
++  PrintAltName(out, reinterpret_cast<const char*>(name->data), name->length,
++               false, safe_prefix);
++}
++
++static inline void PrintUtf8AltName(const BIOPointer& out,
++                                    const ASN1_UTF8STRING* name,
++                                    const char* safe_prefix = nullptr) {
++  PrintAltName(out, reinterpret_cast<const char*>(name->data), name->length,
++               true, safe_prefix);
++}
++
++// This function currently emulates the behavior of i2v_GENERAL_NAME in a 
safer
++// and less ambiguous way.
++// TODO(tniessen): gradually improve the format in the next major version(s)
++static bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) {
++  if (gen->type == GEN_DNS) {
++    ASN1_IA5STRING* name = gen->d.dNSName;
++    BIO_write(out.get(), "DNS:", 4);
++    // Note that the preferred name syntax (see RFCs 5280 and 1034) with
++    // wildcards is a subset of what we consider "safe", so spec-compliant DNS
++    // names will never need to be escaped.
++    PrintLatin1AltName(out, name);
++  } else if (gen->type == GEN_EMAIL) {
++    ASN1_IA5STRING* name = gen->d.rfc822Name;
++    BIO_write(out.get(), "email:", 6);
++    PrintLatin1AltName(out, name);
++  } else if (gen->type == GEN_URI) {
++    ASN1_IA5STRING* name = gen->d.uniformResourceIdentifier;
++    BIO_write(out.get(), "URI:", 4);
++    // The set of "safe" names was designed to include just about any URI,
++    // with a few exceptions, most notably URIs that contains commas (see
++    // RFC 2396). In other words, most legitimate URIs will not require
++    // escaping.
++    PrintLatin1AltName(out, name);
++  } else if (gen->type == GEN_DIRNAME) {
++    // For backward compatibility, use X509_NAME_oneline to print the
++    // X509_NAME object. The format is non standard and should be avoided
++    // elsewhere, but conveniently, the function produces ASCII and the output
++    // is unlikely to contains commas or other characters that would require
++    // escaping. With that in mind, note that it SHOULD NOT produce ASCII
++    // output since an RFC5280 AttributeValue may be a UTF8String.
++    // TODO(tniessen): switch to RFC2253 rules in a major release
++    BIO_printf(out.get(), "DirName:");
++    char oline[256];
++    if (X509_NAME_oneline(gen->d.dirn, oline, sizeof(oline)) != nullptr) {
++      PrintAltName(out, oline, strlen(oline), false, nullptr);
++    } else {
++      return false;
++    }
++  } else if (gen->type == GEN_IPADD) {
++    BIO_printf(out.get(), "IP Address:");
++    const ASN1_OCTET_STRING* ip = gen->d.ip;
++    const unsigned char* b = ip->data;
++    if (ip->length == 4) {
++      BIO_printf(out.get(), "%d.%d.%d.%d", b[0], b[1], b[2], b[3]);
++    } else if (ip->length == 16) {
++      for (unsigned int j = 0; j < 8; j++) {
++        uint16_t pair = (b[2 * j] << 8) | b[2 * j + 1];
++        BIO_printf(out.get(), (j == 0) ? "%X" : ":%X", pair);
++      }
++    } else {
++#if OPENSSL_VERSION_MAJOR >= 3
++      BIO_printf(out.get(), "<invalid length=%d>", ip->length);
++#else
++      BIO_printf(out.get(), "<invalid>");
++#endif
++    }
++  } else if (gen->type == GEN_RID) {
++    // TODO(tniessen): unlike OpenSSL's default implementation, never print 
the
++    // OID as text and instead always print its numeric representation, which 
is
++    // backward compatible in practice and more future proof (see 
OBJ_obj2txt).
++    char oline[256];
++    i2t_ASN1_OBJECT(oline, sizeof(oline), gen->d.rid);
++    BIO_printf(out.get(), "Registered ID:%s", oline);
++  } else if (gen->type == GEN_OTHERNAME) {
++    // TODO(tniessen): the format that is used here is based on OpenSSL's
++    // implementation of i2v_GENERAL_NAME (as of OpenSSL 3.0.1), mostly for
++    // backward compatibility. It is somewhat awkward, especially when passed 
to
++    // translatePeerCertificate, and should be changed in the future, probably
++    // to the format used by GENERAL_NAME_print (in a major release).
++    bool unicode = true;
++    const char* prefix = nullptr;
++    // OpenSSL 1.1.1 does not support othername in i2v_GENERAL_NAME and may 
not
++    // define these NIDs.
++#if OPENSSL_VERSION_MAJOR >= 3
++    int nid = OBJ_obj2nid(gen->d.otherName->type_id);
++    switch (nid) {
++      case NID_id_on_SmtpUTF8Mailbox:
++        prefix = " SmtpUTF8Mailbox:";
++        break;
++      case NID_XmppAddr:
++        prefix = " XmppAddr:";
++        break;
++      case NID_SRVName:
++        prefix = " SRVName:";
++        unicode = false;
++        break;
++      case NID_ms_upn:
++        prefix = " UPN:";
++        break;
++      case NID_NAIRealm:
++        prefix = " NAIRealm:";
++        break;
++    }
++#endif  // OPENSSL_VERSION_MAJOR >= 3
++    int val_type = gen->d.otherName->value->type;
++    if (prefix == nullptr ||
++        (unicode && val_type != V_ASN1_UTF8STRING) ||
++        (!unicode && val_type != V_ASN1_IA5STRING)) {
++      BIO_printf(out.get(), "othername:<unsupported>");
++    } else {
++      BIO_printf(out.get(), "othername:");
++      if (unicode) {
++        PrintUtf8AltName(out, gen->d.otherName->value->value.utf8string,
++                         prefix);
++      } else {
++        PrintLatin1AltName(out, gen->d.otherName->value->value.ia5string,
++                           prefix);
++      }
++    }
++  } else if (gen->type == GEN_X400) {
++    // TODO(tniessen): this is what OpenSSL does, implement properly instead
++    BIO_printf(out.get(), "X400Name:<unsupported>");
++  } else if (gen->type == GEN_EDIPARTY) {
++    // TODO(tniessen): this is what OpenSSL does, implement properly instead
++    BIO_printf(out.get(), "EdiPartyName:<unsupported>");
++  } else {
++    // This is safe because X509V3_EXT_d2i would have returned nullptr in this
++    // case already.
++    UNREACHABLE();
++  }
++
++  return true;
++}
++
++bool SafeX509SubjectAltNamePrint(const BIOPointer& out, X509_EXTENSION* ext) {
++  const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
++  CHECK(method == X509V3_EXT_get_nid(NID_subject_alt_name));
+ 
+   GENERAL_NAMES* names = static_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(ext));
+   if (names == nullptr)
+     return false;
+ 
++  bool ok = true;
++
+   for (int i = 0; i < sk_GENERAL_NAME_num(names); i++) {
+     GENERAL_NAME* gen = sk_GENERAL_NAME_value(names, i);
+ 
+     if (i != 0)
+       BIO_write(out.get(), ", ", 2);
+ 
+-    if (gen->type == GEN_DNS) {
+-      ASN1_IA5STRING* name = gen->d.dNSName;
+-
+-      BIO_write(out.get(), "DNS:", 4);
+-      BIO_write(out.get(), name->data, name->length);
+-    } else {
+-      STACK_OF(CONF_VALUE)* nval = i2v_GENERAL_NAME(
+-          const_cast<X509V3_EXT_METHOD*>(method), gen, nullptr);
+-      if (nval == nullptr)
+-        return false;
+-      X509V3_EXT_val_prn(out.get(), nval, 0, 0);
+-      sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
++    if (!(ok = PrintGeneralName(out, gen))) {
++      break;
+     }
+   }
+   sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
+ 
+-  return true;
++  return ok;
++}
++
++bool SafeX509InfoAccessPrint(const BIOPointer& out, X509_EXTENSION* ext) {
++  const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext);
++  CHECK(method == X509V3_EXT_get_nid(NID_info_access));
++
++  AUTHORITY_INFO_ACCESS* descs =
++      static_cast<AUTHORITY_INFO_ACCESS*>(X509V3_EXT_d2i(ext));
++  if (descs == nullptr)
++    return false;
++
++  bool ok = true;
++
++  for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(descs); i++) {
++    ACCESS_DESCRIPTION* desc = sk_ACCESS_DESCRIPTION_value(descs, i);
++
++    if (i != 0)
++      BIO_write(out.get(), "\n", 1);
++
++    char objtmp[80];
++    i2t_ASN1_OBJECT(objtmp, sizeof(objtmp), desc->method);
++    BIO_printf(out.get(), "%s - ", objtmp);
++    if (!(ok = PrintGeneralName(out, desc->location))) {
++      break;
++    }
++  }
++  sk_ACCESS_DESCRIPTION_pop_free(descs, ACCESS_DESCRIPTION_free);
++
++#if OPENSSL_VERSION_MAJOR < 3
++  BIO_write(out.get(), "\n", 1);
++#endif
++
++  return ok;
++}
++
++v8::MaybeLocal<v8::Value> GetSubjectAltNameString(
++    Environment* env,
++    const BIOPointer& bio,
++    X509* cert) {
++  int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
++  if (index < 0)
++    return Undefined(env->isolate());
++
++  X509_EXTENSION* ext = X509_get_ext(cert, index);
++  CHECK_NOT_NULL(ext);
++
++  if (!SafeX509SubjectAltNamePrint(bio, ext)) {
++    USE(BIO_reset(bio.get()));
++    return v8::Null(env->isolate());
++  }
++
++  return ToV8Value(env, bio);
++}
++
++v8::MaybeLocal<v8::Value> GetInfoAccessString(
++    Environment* env,
++    const BIOPointer& bio,
++    X509* cert) {
++  int index = X509_get_ext_by_NID(cert, NID_info_access, -1);
++  if (index < 0)
++    return Undefined(env->isolate());
++
++  X509_EXTENSION* ext = X509_get_ext(cert, index);
++  CHECK_NOT_NULL(ext);
++
++  if (!SafeX509InfoAccessPrint(bio, ext)) {
++    USE(BIO_reset(bio.get()));
++    return v8::Null(env->isolate());
++  }
++
++  return ToV8Value(env, bio);
+ }
+ 
+ MaybeLocal<Value> GetFingerprintDigest(
+@@ -628,27 +909,6 @@ MaybeLocal<Value> GetModulusString(
+   return ToV8Value(env, bio);
+ }
+ 
+-template <int nid>
+-MaybeLocal<Value> GetInfoString(
+-    Environment* env,
+-    const BIOPointer& bio,
+-    X509* cert) {
+-  int index = X509_get_ext_by_NID(cert, nid, -1);
+-  if (index < 0)
+-    return Undefined(env->isolate());
+-
+-  X509_EXTENSION* ext = X509_get_ext(cert, index);
+-  CHECK_NOT_NULL(ext);
+-
+-  if (!SafeX509ExtPrint(bio, ext) &&
+-      X509V3_EXT_print(bio.get(), ext, 0, 0) != 1) {
+-    USE(BIO_reset(bio.get()));
+-    return Null(env->isolate());
+-  }
+-
+-  return ToV8Value(env, bio);
+-}
+-
+ MaybeLocal<Value> GetIssuerString(
+     Environment* env,
+     const BIOPointer& bio,
+@@ -917,11 +1177,11 @@ MaybeLocal<Object> X509ToObject(Environment* env, X509* 
cert) {
+       !Set<Value>(context,
+                   info,
+                   env->subjectaltname_string(),
+-                  GetInfoString<NID_subject_alt_name>(env, bio, cert)) ||
++                  GetSubjectAltNameString(env, bio, cert)) ||
+       !Set<Value>(context,
+                   info,
+                   env->infoaccess_string(),
+-                  GetInfoString<NID_info_access>(env, bio, cert))) {
++                  GetInfoAccessString(env, bio, cert))) {
+     return MaybeLocal<Object>();
+   }
+ 
+diff --git a/test/common/index.js b/test/common/index.js
+index 8cd9841527..98b586cafd 100644
+--- a/test/common/index.js
++++ b/test/common/index.js
+@@ -51,6 +51,11 @@ const noop = () => {};
+ const hasCrypto = Boolean(process.versions.openssl) &&
+                   !process.env.NODE_SKIP_CRYPTO;
+ 
++const hasOpenSSL3 = hasCrypto &&
++    require('crypto').constants.OPENSSL_VERSION_NUMBER >= 805306368;
++
++const hasQuic = hasCrypto && !!process.config.variables.openssl_quic;
++
+ // Check for flags. Skip this for workers (both, the `cluster` module and
+ // `worker_threads`) and child processes.
+ // If the binary was built without-ssl then the crypto flags are
+@@ -714,6 +719,8 @@ const common = {
+   getTTYfd,
+   hasIntl,
+   hasCrypto,
++  hasOpenSSL3,
++  hasQuic,
+   hasMultiLocalhost,
+   invalidArgTypeHelper,
+   isAIX,
+diff --git a/test/fixtures/keys/Makefile b/test/fixtures/keys/Makefile
+index 824704c724..49cc29ad1c 100644
+--- a/test/fixtures/keys/Makefile
++++ b/test/fixtures/keys/Makefile
+@@ -75,6 +75,8 @@ all: \
+   ed448_public.pem \
+   x448_private.pem \
+   x448_public.pem \
++  incorrect_san_correct_subject-cert.pem \
++  incorrect_san_correct_subject-key.pem \
+ 
+ #
+ # Create Certificate Authority: ca1
+@@ -733,6 +735,18 @@ x448_private.pem:
+ x448_public.pem: x448_private.pem
+       openssl pkey -in x448_private.pem -pubout -out x448_public.pem
+ 
++incorrect_san_correct_subject-cert.pem: incorrect_san_correct_subject-key.pem
++      openssl req -x509 \
++                  -key incorrect_san_correct_subject-key.pem \
++                  -out incorrect_san_correct_subject-cert.pem \
++                  -sha256 \
++                  -days 3650 \
++                  -subj "/CN=good.example.com" \
++                  -addext "subjectAltName = DNS:evil.example.com"
++
++incorrect_san_correct_subject-key.pem:
++      openssl ecparam -name prime256v1 -genkey -noout -out 
incorrect_san_correct_subject-key.pem
++
+ clean:
+       rm -f *.pfx *.pem *.srl ca2-database.txt ca2-serial 
fake-startcom-root-serial *.print *.old fake-startcom-root-issued-certs/*.pem
+       @> fake-startcom-root-database.txt
+diff --git a/test/fixtures/keys/incorrect_san_correct_subject-cert.pem 
b/test/fixtures/keys/incorrect_san_correct_subject-cert.pem
+new file mode 100644
+index 0000000000..787d9f1135
+--- /dev/null
++++ b/test/fixtures/keys/incorrect_san_correct_subject-cert.pem
+@@ -0,0 +1,11 @@
++-----BEGIN CERTIFICATE-----
++MIIBqDCCAU6gAwIBAgIUE3Kx4WUjkwuKy/fBOM+UJkb9aSAwCgYIKoZIzj0EAwIw
++GzEZMBcGA1UEAwwQZ29vZC5leGFtcGxlLmNvbTAeFw0yMTEyMTExNjUxNDVaFw0z
++MTEyMDkxNjUxNDVaMBsxGTAXBgNVBAMMEGdvb2QuZXhhbXBsZS5jb20wWTATBgcq
++hkjOPQIBBggqhkjOPQMBBwNCAASQ/CKa5uMZuLYssnNOm7DPdw3I5Doa0Qpyf3cS
++7aGatfK3tuY8qG7nJ5OGtl1WOL/gN0vRRN0/KA/iRJyjafzzo3AwbjAdBgNVHQ4E
++FgQUFkpgPzE1ePjK5UsPcR0gk5uLsTUwHwYDVR0jBBgwFoAUFkpgPzE1ePjK5UsP
++cR0gk5uLsTUwDwYDVR0TAQH/BAUwAwEB/zAbBgNVHREEFDASghBldmlsLmV4YW1w
++bGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIQCMZAinQXkOEhfp+moxVnLbcUPAAqsl
++1KCq3NRG91TGCgIgC4grmOhCRqJMF1RPNWobGogX/yNrYNjiGzNVyJzMR0s=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/keys/incorrect_san_correct_subject-key.pem 
b/test/fixtures/keys/incorrect_san_correct_subject-key.pem
+new file mode 100644
+index 0000000000..f7f51253a8
+--- /dev/null
++++ b/test/fixtures/keys/incorrect_san_correct_subject-key.pem
+@@ -0,0 +1,5 @@
++-----BEGIN EC PRIVATE KEY-----
++MHcCAQEEIOOVRgLS3H2T2fUhj4ASCFq60ySwO6yvSK6rvZHldAHuoAoGCCqGSM49
++AwEHoUQDQgAEkPwimubjGbi2LLJzTpuwz3cNyOQ6GtEKcn93Eu2hmrXyt7bmPKhu
++5yeThrZdVji/4DdL0UTdPygP4kSco2n88w==
++-----END EC PRIVATE KEY-----
+diff --git a/test/fixtures/x509-escaping/.gitignore 
b/test/fixtures/x509-escaping/.gitignore
+new file mode 100644
+index 0000000000..504afef81f
+--- /dev/null
++++ b/test/fixtures/x509-escaping/.gitignore
+@@ -0,0 +1,2 @@
++node_modules/
++package-lock.json
+diff --git a/test/fixtures/x509-escaping/alt-0-cert.pem 
b/test/fixtures/x509-escaping/alt-0-cert.pem
+new file mode 100644
+index 0000000000..30e6fa6c3f
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-0-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++NTAzMDEGA1UdEQQqMCiCJmdvb2QuZXhhbXBsZS5jb20sIEROUzpldmlsLmV4YW1w
++bGUuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAcsy+PIduM8NRrdqcTqufiajsAajQz
++eB5+5+lZLi9MliXqoS4HsdrDMDevMa2cC+wB+XZW9SJXjtqrwXAxTAHtEyhsCi25
++XV0sJPWmZM+OQkGTtp7Ain12htr/t/DJ13YJpT03W6kYogA1kKJ5OMYMTcGT+7UB
++zM4G2LUSrrSisxhfz9bF8Q9s1piG2gb5ACEQUiMLRrZXl8WLlaY59lloKyMa/9g6
++i3TgLxhp7XNS/bh/f2tDx+7ZgdtHUlkNhl1MycIVQRGK3BaZBEd+sDxS52kwym5I
++CWLXGLutU3OeaNgqyvZuMvy//2oER3PysizyjwNoFlUbIz3zMnXvBeEjeGtEHsCJ
++EBtX+xBWwMhUKE2QcMLxQaZNJCZFVFw8fDeEgFjTdEBcLsZ1PngT3jgXSHEWA+YL
++C3rQhFMjyjy2h8u1sjySFrTlbZPm8gC3q/+LaXxhf5i5xiZOOcVfeYiWFUa5gQal
++FaWj2SlQFaN2nidPaQO62vRIYn0Y/qbtUQAPkq4VVeycgxiuZaVVWCdct8UCYb9F
++b9QSMpK4r99MKy+s41RiJodDJy0XraOxy7hUDjyObL2fuuPUK6mQAFGwWtajv3qq
++vrRMvBEXdOPVmbETyzIosUHvOXT+v8WoCbC14mqMZTWVywRg7bD/NTHJDRIBrqvi
++O6Zqbod3EImVnQ==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-1-cert.pem 
b/test/fixtures/x509-escaping/alt-1-cert.pem
+new file mode 100644
+index 0000000000..63883c2bbf
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-1-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE0zCCArugAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++IjAgMB4GA1UdEQQXMBWGE2h0dHA6Ly9leGFtcGxlLmNvbS8wDQYJKoZIhvcNAQEL
++BQADggIBACFwNHWQ5w3UBbyq17emn7Z0BT0Zm5iFr8Qeik75WzbyzXd5QIeFWewB
++qmiuaoKGGZ674sGcuomnIwoZBCoqvzbBBqBHp+O3/6pq59THQxeE6vhjKAe8oaih
++emdigRmkX+Qi8UwUh76B51wHtkp6zAZnLDn8M67qmP7bjNrrMQeE81wRWYz9ssfd
++N63dzu2BdD3EGl4CepdszpfUYLkz6iiDwFkc1NaBcQbBDoGqn2ubNXTHAyGGeL5a
++ulDCND0FQtg+jhHHE3zXBqh1nPg/cXXRUG2zjxzUnaU2eMs5b4yqoLN/2n7fb7mV
++HRh0T6X1HZcYpf5BSsgmr3Ngd/9b3sYRvNXBkVmKAu8dH7zguksczsvbL9r/u2YX
++hgGjNT3xSphJbZTzqsACcoDo67EFkJ5p25f0N1i/rxk7O6uLMtrUqnzOXs6NXgEQ
++8lyfVEgLFrXzdKXuk2l/6bwym80Eqdpjv5yCckCl24cFVpc15MRP3MPwIHrtoOLw
++bdNZA5NUAnppLmG6zTdPPgBWEmf5+4ei9WjmpG1hq72/nJ1qM2dLIgV5nLggr1UH
++i+vih+ujceBLVumAu/naP440xO5HRvpPfDWI+eU/wuXjUyAqe6YlYS+Txu/5YnFh
++aMHO+PIgudWwGPhkABtrc/1jC+Yfy+GCtih10zBagoN9/DSugh0H
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-10-cert.pem 
b/test/fixtures/x509-escaping/alt-10-cert.pem
+new file mode 100644
+index 0000000000..14bec45d28
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-10-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIExTCCAq2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++FDASMBAGA1UdEQQJMAeHBQAICAQEMA0GCSqGSIb3DQEBCwUAA4ICAQA+jnyjJ/9X
++ENWXApq2g+GlWBM07KpsrxzwDXc6wsOnZCIiMoDqpcH96X8Q2Lahc4mZuz4yOZtv
++z8Q9YUDTnJY+RtKYNDbxlz7wI1ASxKdP0X1qdzkYtHH752tG/zwVU2FSvqJLw+nl
++rPJvQQ82/30BspejbW0JIfO7JnfN5BHPzzJp/V5tI1KQe+Wh0gEq6UvXjFrkCoeU
++gaedPaG2RYDi1LWawRque7pnYzrcJCtc+wb8wiL1dRv7fDDmI7fFm3Bj6Rnid4/6
++/CxK3WqLBQrXoGnPGwI4iR17Rx08hPCL2V8NvDuJlagJe/Vc6LzOEixofoHGx4rG
++Cm0AKubKbak/ML/rjyP2TiUmOhhm3Xdml3xexedErkgTLtlvmC0jesYuc4MeypNx
++Q0eKRnChRGZYT9kaNgXZG1Scq63vpxKhayVvwU4ahGQS+nmuZdbRMEMIH6YkGxo/
++i5qmNxQPLMLE6HclSdDtUxN4ywQAQ49CaTCxVYq7dLTzpII3ldQ+KuefenaXrYGE
++7TyqJBVdsTq0Bg2Ftf7GaoidJ/ZjjkB3Sj5uVQFMfU8uSATOolBOzh6fSiQJ60Zn
++CtAAkb9uOwTl67Qijo4qAe9JRNqR9H5d65D0Vx+gdhcZVEriqIVhXVcgsvYQ55Ju
++VGhc/foVd+vBuM3jXEdGR+DN/dEu+HZrhQ==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-11-cert.pem 
b/test/fixtures/x509-escaping/alt-11-cert.pem
+new file mode 100644
+index 0000000000..694cb7e9d8
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-11-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIExjCCAq6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++FTATMBEGA1UdEQQKMAiHBgABAgMEBTANBgkqhkiG9w0BAQsFAAOCAgEAp2nxfYla
++giNJ9S2owtp/5DxB3jIhQJzmdSxuUKVwWBffmzxrTkOoK/IcGkq3hu27GIy+ICFc
++YkSsAE3DfboSTStxhkVZKMVv+e5tXPQ0i+Z+CSgHZbrnaA7nH0UPEgFFddhqogGw
++LGE54iZ3D7ZYebTw/ELCIHNu9KeOStF7j04WXG7qRrqza5NmKqlxTC5tGoWAljzN
++cdC2BdK7H2+6de3c4dBsYqcL2IgwNhA1uKIsDjJwwkOPmCEPl+7DjleI3IAKpROh
++vX66DLaAsLEkoHsN7XTienHF8o/avIMGUfb0rtNLbwW8tzfjeAaJ7iTSm7ibhBLP
++fK+n7Osh9QH+lG0K7M2zez7Kd3u+eNgTEG63gVR+zDZQwkA2Hy1o4zmZ+a3iCtdi
++w6JGq3TT8nfPNO4kSoq7EYs6daPnGi3sqNRC20t4FZw0jOpvI4Uw7rPcTTqmAeAw
++9H37WU3URD2EP8BpkoZiOShMHzNGqlC9qbqr5dd83Lkdz9gN4w3ipdbiiGFGPXhT
++YubUecjwXoBUUI+be/edVbg7RtSSuplDv5l4bBSy+BG8JEUL6CKAUEtt2Tpt2SVD
++AIaj0B19/DSYq1e4x8IBVBsI2RnEEpP70bdLiSYLhVhMdzp0PRqDVDE+zt4mm0lx
++NRDSdNS1/rJEH1gLQEh4SGMs9iY5Vv+kx28=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-12-cert.pem 
b/test/fixtures/x509-escaping/alt-12-cert.pem
+new file mode 100644
+index 0000000000..7e48ebdf05
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-12-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE0DCCArigAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++HzAdMBsGA1UdEQQUMBKHEAoLDA0ODwAAAAAAAHp7fH0wDQYJKoZIhvcNAQELBQAD
++ggIBAEMU6XcjSdQ+EG22BsyAYin2d3g9Fd0gljsuyEyw2qwFE1zeNqz2sFX7GdmP
++hEmUVdzQ0EQsHtKiO2BIhU5fkLoGIkJQT0MY/Tkc3xCLjVBG9ryHNjhv4aYfcvZ2
++K8LwWu5na5YtpmEHppFTmhQFHK9Yf2Jeh5Ms1VH2jwKR8iFM9dk0wcB74Y1WqyX0
++bhNUzv0ISvz/DK6rN0CM0OiZ7D1toMFJIslEcZD/MCZ0icFwRgGLzooDbm1xtixo
++NjgdswdiL0cS/wgSdzu9eIugUQZU2KvUWYXGqYMDpn7iukiZSKQuFhZGcuK17zyR
++y6TkDFe9rTxVtw9SAxjlo94rEqWN9Cns0n7tqAI/Wg6ILHUjUFwqSdrZQTEgH4O3
++tfhRkV4HCgP1Tzfz/20uMBqjCLbdt7xcSfLIiHgaxgwM0LGhH2Uk3oYinL2WIUDi
++bZPI+1bzeyZ/tHw4sDxkGn3W3Nr44Td/5DAFz1lRMxAliVwHNzFTiY7IjCqmB0DL
++z91agdgPMdh/huFvGJZHS/v7EXMSXyNLyIw+5JO12iwf4+pu8NLnOtMoHDB4yY0w
++MEerc4e8SmygBQGF0MrcmirdT+7yiKRktZZFuyQoj4fBSKeBaBKUrnnk4UYw9H8f
++j/EQwM87PmYjTwYPrJ0Kz5r4dmAUvq4z2ReLgM08Ve4SPa79
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-13-cert.pem 
b/test/fixtures/x509-escaping/alt-13-cert.pem
+new file mode 100644
+index 0000000000..574ad1ca8f
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-13-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIEzzCCAregAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++HjAcMBoGA1UdEQQTMBGBD2Zvb0BleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOC
++AgEAkx9jG86PMjL+/UxlhX0B/gIKHyTVrEt8j+/fn74uMnd7CV7toK6f5DANIxYp
++3OJWAFYZ2lNS3MQMxpbjpd7D0BeNwhiJyBnRPhJ9KdsvdXnupF5ANNzr3oMioWwL
++3WxvmQDEz35sorae5nzuZu8EpuwgodR0NCEmoPdW9JOUiB7k3Ku5goZHqlrdzM8f
++YPbRDNOxSIpRqr5eqhEM9tEf+TF6qOM/NZJlXxtGDVdaDTbaULuCJGEW8TdVajnY
++FfWWtIHwF64G5qJTgENqJjR1kkJy5vg2lFoDXE8MG+LvTHfyY0rMilncD2YOBLcj
++gb3mBTxZGI2w2KZbchgEvA9+0heumAVJQPfdGs+pCUdvlhwWh8FCvu3aQb5X57OU
++3D97vwvEs8Mxm0KHf0o0ZnTvaBWN5htX2bbpvYxGGB0SsWM8r1LIXj8bwGNdViV8
++UWNrg37XyGCppL1jXJ1q+DDKOvi0JR384ocRmS8mWUf9qiAMOqveix38rHezWlEm
++4TCscq4tv135nM194D6uilzv4mUxLAMTX8Lvag1R3aKuOHio9lCGep4v776kALE6
++9/rekRGoMwNApoaC96x+V/dkbfnjWcxRXL5TvjDwVInl+RCcn6ijYZM0HYc+U1Dw
++MwqBCbP2Y9Ee7xcnAgPbqH2svWG7XadQHAcOEDc/DFsPRG8=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-14-cert.pem 
b/test/fixtures/x509-escaping/alt-14-cert.pem
+new file mode 100644
+index 0000000000..0265b5992c
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-14-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE5TCCAs2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++NDAyMDAGA1UdEQQpMCeBJWZvb0BleGFtcGxlLmNvbSwgRE5TOmdvb2QuZXhhbXBs
++ZS5jb20wDQYJKoZIhvcNAQELBQADggIBABf7bojDeoFEFyk/Xzo50sAL+5irJYzV
++n//5aEvUotYxQt5coi7UnkKUgdiUhIXD8WaxD9KP3nUH+C3cxAQ+I7iVjFhjqFQB
++X4c/ZjJA2QIX7VMWA3kpOFvR5N0HHest097Fi/HUEEXNkcUtCkRNtI2Msse9uz09
++DIv9P0IQ2TFgBRCTJwq2ZfVebHk/xoQ5fV9b0b39ts6ToiuMvGJVng2zz8fVNMah
++hycCn0WSb6dPi9k0ItSvRTYL6vp9X842+Q0Xkq0FxQPUcvzN7D1tSmHXDM7nYXp3
++FB6DKASp0+nn+J88RXVSpO0JedEyRDEluxHJcan+hqhWJ4DgamlVTEPN3q5yE4lt
++Jr/R5tnx0Lv0CxDTAfZLaFiKb2jz9nVhzbCh7t21mxyb2mOM+GAxRaIgxodeNJoY
++QA6Ezz4cbjjA72Rgi+tBxy2abXpbbJ/vX7FUhs0ICFKZJHvFoxazgtSGgHHYNxhc
++/+9o6Y9jhunwGn/MaoxWJsdSjZ8VX7HY0iOSU3z4d4PWvIz05n4sGoJET6s1JuKe
++dZAAeQy0V5/EzxIu4GPGrzVtk2SQhNHVJZKponZeCRruruGT5Z1T+gF5YSqVM6BA
++XA0ZVXwOEbZ5XRIzBBbaiX3Eeful50ILOiP/uxLlcZtTtOyT4wNBgijfJehRHbED
++ppJk42EFZKb2
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-15-cert.pem 
b/test/fixtures/x509-escaping/alt-15-cert.pem
+new file mode 100644
+index 0000000000..70a98fb90b
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-15-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE4jCCAsqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++MTAvMC0GA1UdEQQmMCSkIjAgMQswCQYDVQQGEwJERTERMA8GA1UEBwwISGFubm92
++ZXIwDQYJKoZIhvcNAQELBQADggIBABIv7Wlg5F1gh0+0v/+LnushmLeypcXQGqkg
++E2IxXC2VnZxq8xTFCHy/m1qTBLPJK5VIg5qmtstL9zIk9rOUshQvusvNLplC0j3o
++GuQdQJNKV7rrzYYpUZO1en11q27AgDsO6lwSNg4U+mqzJxxIHc8IMeJpfaGTkUz/
++ZXXNz04JJalUff+W2436vSvu8Y82fD72/qNu6EMiOl0EHJFQ/7eCAlz6hSNleLT/
++N2GztApNzujbPgH7+PHOeVpwppDuXY1rkmPJMxCqkY8yOwyM5dMov0bjIN1f+QXv
++7voxVGMTefUajKADaNGMShH5rhgjIWBgujvdCyLPr6W2R4S1QPzjx4X26eTX1G8V
++/eTsJ6mMc+3cd6CEmEahUnc6LdEdwm+1SMRG2nejea4o8c+crwYX5KQVrqx92FqB
++SdkdCtS6qlnxJVvSz+HW6lEM0EShvjKEz/udsnttALQjhxfB7AHNWA073o/OiH25
++Y9QpUudmWJjOoqRokN0SV4rDQnfNcLKIoVFPu+rG2CpBDjUsoxG3/aC8Owcd8Ceh
++w+O/DqQXudXFS3RsePbz4rPfID9YtBHrihCE10B70DUutWPsbe5lKie3wJpQbqvl
++zp5kkI5RffVU7OFD6os3+wPomdIG21Cf/fru56nV3FmkINCabLQddes7OarQcZ5y
++xsumEzq+
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-16-cert.pem 
b/test/fixtures/x509-escaping/alt-16-cert.pem
+new file mode 100644
+index 0000000000..64f852ceeb
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-16-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE4jCCAsqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++MTAvMC0GA1UdEQQmMCSkIjAgMQswCQYDVQQGEwJERTERMA8GA1UEBwwITcO8bmNo
++ZW4wDQYJKoZIhvcNAQELBQADggIBAEID22h5WK1YJrKUmmO0owley+tL519YwJbs
++FwbwPz7+SJKA+UQNqVXYOGLwDJ6A6OzsV1TnJuwGotTmvNwr7eOVyLf03qggIYEj
++5Twgk57gJmqE+Q8UXUq2ocALUcgReZhluhNoL1XYQMbDaHYwh9HSOP7udEszVQoE
++m1D74cSiW803XnqPJGj0i1s9mD6AEewPl2k0mQ0hTMM3rlE1jOCj4Jx81tWH5KNY
++LXn/LhFomeo/LAU4PCFTt65tAomKTNXq0GwuunU62fy8pwh9QUpD3Vfrkm4+08uz
++WXSk9PeaF8tOs5pRwVMRr0GIdnQHa9GKuBBSZEvkGTxLM+cxO7jp5qSs2IRVpI5s
++ztlJQcJpeTRNCEF7gM98nMqDqve/IySGle9s1RjpnBuSD9UKzbMGeBuZK8d0JfBt
++7XF3i6Tu74EbBL/mP/0xoHausW9Yo8HZhXjm5k9P7m9xxlq2JSSXeQCLbKFT/SN+
++Q3bS6rh0HaqLP8Gd3OyU+aOOy13Tr167LEFNK6DlfSadITuHwRMNvCk8UIDRDzAZ
++kXVXdT5UfUe4IJU6OPVsFfntTX6G8s2/K4WropnjD5NjBJ0ppvPgCBqEA03mCGVt
++IunRhQypiA0+SilM7BX6jD97IcmnbSyQ6fUkIdDBTMlX3MoYXkT00gDT3y8D/aKw
++KTd5SKbD
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-17-cert.pem 
b/test/fixtures/x509-escaping/alt-17-cert.pem
+new file mode 100644
+index 0000000000..f09f41b918
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-17-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE9jCCAt6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++RTBDMEEGA1UdEQQ6MDikNjA0MQswCQYDVQQGEwJERTElMCMGA1UEBwwcQmVybGlu
++LCBETlM6Z29vZC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAchR9+hds
++zMK0NKgiX32XxJJ79tlo2sRMCZqij8Lqfyz7JDlTMSvIVqcrmimlAMX5u8BxKRXG
++99KzXhbJb6Hnj2i6fQobxpD6nKnPSUcoiiWccmp8jmcKQW7M6TuqOfEdEnKpf0BF
++vNFBjXGxs0KqOArX/1d0DqYS1LTnxaC6NimgvjAqKVRm9mqj62pc9//ixCgHkqLJ
++stuoSerbo/mO0ieY1wq9r9TZT1epacVrQpJFWeJWhow94WutMNesJSWLcxX63mH4
++j0LHEEkHLa1UkMzM2RkHTVhKrthCiuyrtqrglLsdPInU7ZYVONyUrR2D1tMy52mB
++b1HzzP43pomBJtp3OeEZtBDwmmGgD8RBdVK/T9hcK02cvB1w1yr4LHUeYLMqrZaP
++SJHQ7kv9AV5Os64SYW9+7cqjt1q4VmaEqcuCqvB6mORHWHnsa6PQ19myA7OdqNpT
++WAK3D94tpbGPTzfhUCHk0w0fPzJ4A1+S6g4eHX4iQQxxDg9sXV4ZRvAEKnJhs2S7
++OhtXdfyu/1+lfaunN13SyxMwyyxHzylEU707Sisxse2usX1Zy2zxqD+LO/9iIu1S
++76/rquhiOFRWxSpjb7ewpH97OGFmtzfH70vBBukn0alT4xjkje10NlBfzcFwHWQH
++59nxPd5sUEqq+DxTjoAgwO91woU7UTs98lw=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-18-cert.pem 
b/test/fixtures/x509-escaping/alt-18-cert.pem
+new file mode 100644
+index 0000000000..341ac0b7ce
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-18-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIFBzCCAu+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++VjBUMFIGA1UdEQRLMEmkRzBFMQswCQYDVQQGEwJERTE2MDQGA1UEBwwtQmVybGlu
++LCBETlM6Z29vZC5leGFtcGxlLmNvbQBldmlsLmV4YW1wbGUuY29tMA0GCSqGSIb3
++DQEBCwUAA4ICAQBFUk2Z1E5Q4mW7S8dLz5h78AmfNbwx9eNtECc8iLQq2Q0MuIzQ
++noURyNSHhH2hkohU4afXjolCr54DkJNYogrBwHaNDt3Y3wqGQXc+BKRnqblfr1+A
++1EoIaqRFjv/Mu2gB0H4U3vBRYriZu7BhQFXiQHAr6hWLG91B1eN1i+my9zOSoSZF
++7BuemB/9F4wjvwmDJieSwOgGk3FhNV64Ce9M95RwDKNSJBTBqOTLoyvOw2jgs22m
++MntqW9oRywGeHdJ5EucPBrZQKDNysNFj3We8H7PedGNlnG/QknE6pzpRgqbRCAax
++hcvGQIaMcUJ3oWhJuPNscjsJ/nfaitz58nH5raj4O8JhlS1h49NpbJO/pAWMHh0d
++ZruXspxdEwW17aMJJ365q0XyVysRHiwQuIQYCo8L7oVUsH5FUJ9xxPH22b+PG05r
++EABdID+aDV7X/MNwBxgeBOFVOgE5bfrH8NBjkx/F7ID/hjcQDLVWWoFnpIjekebC
++EeqTRl5TcnoN9Dc7zkfwmuYGoaYJrGhj7WRvfFgcw1Cr1xujiJtoKbEbMoeD45+H
++SQ8MwBb37Gm3aBNakpVmJlp/QZSJY403hA8QrZdjnqoS4THrC0+gN2q71aZ9ZCZY
++3+OPNg659ZcYvo1onBSA0p1WGKEAWdHKqZCVRdsl5LnRg4H5gEVW4gmhjA==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-19-cert.pem 
b/test/fixtures/x509-escaping/alt-19-cert.pem
+new file mode 100644
+index 0000000000..f163184204
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-19-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIFCDCCAvCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++VzBVMFMGA1UdEQRMMEqkSDBGMQswCQYDVQQGEwJERTE3MDUGA1UEBwwuQmVybGlu
++LCBETlM6Z29vZC5leGFtcGxlLmNvbVwAZXZpbC5leGFtcGxlLmNvbTANBgkqhkiG
++9w0BAQsFAAOCAgEAWtSJOhwRpYdB/aq/AixRTIpwf5VR3MWaDNh7clpnpYhYoLDY
++7dJ8cv3AR5dOScFXLrCZ2UYVD+tTPyt18opnYDT4h6If/U9TTHVu5tRSX0wGIdPc
++j3zVVegty/HWMA5LfwygNTvZjgXhocckNND7hC42+BuXE2bqoqnkqMRer/R+9PmU
++FXpyLk0aDl2QmspDAz86FYpEuxpMfmDNmM1nWDz+n+uBbeuriTttsFqFWkfOGoNN
++/3tAmUjAt5IqkL+7rnDt6Lc9inY0z3uYGJEdqa0GJJFJ7U+8wcw8rUwvKETqAtW1
++mBOswkoCImPeNDpiqiotwl4cfrsb1+j9gNpYTP2oSurh/bF0mxGLoJa1iDeibwqg
+++f6oWcCdYQ94ItvS3d+lNXT0MWM6HU6sHXf3+5SqvsvsKjUBRyy1Nvnug1bha6Qv
++bdeErN0ZSGy12Vc90Y5fpl8kebmYiJc79OqvuTNDeRfgBm+U4ASAj/AEhtbN+wDd
++HrUHbk/9U9h0UFRZ5s7Pqoy5PEoLRoFeA/jQQa/fLC8nl7YTSwidVgj8cyAy36sV
++uaBNXrcgelqlR26SBynXM3APaFlv5IdSlF199swMCusQrGbiNajl21TUm+Iv+84g
++x7rnUPnQ1grkLpMOBtGaraKc93e2VfH5bAZvyaIq99qdA10ERCtE2grvjik=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-2-cert.pem 
b/test/fixtures/x509-escaping/alt-2-cert.pem
+new file mode 100644
+index 0000000000..6ae58f5636
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-2-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE2zCCAsOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++KjAoMCYGA1UdEQQfMB2GG2h0dHA6Ly9leGFtcGxlLmNvbS8/YT1iJmM9ZDANBgkq
++hkiG9w0BAQsFAAOCAgEANTZFCjNmspLkZaVYkcAXfT2poPPWAu7wS/wG4VEmKwPV
++A4dnFV2McXNW/iyABeoofeIjsjiYLpxTvz3teD2JJh+hidNED77PV7f4hj7vs4Dn
++DGB3HKJvTD63AVOiPJ4bbfUyiuvLO5TwdxAGm+q9lsf/fWFraTF2qlnFwyWf6Qul
+++NQo3bM8mErvntZMscq7wo0cOdAXA0bNqxKS+IDnc+HLxoEr2egbRJmEagMgV4/U
+++AGVQ1sY+HrEszOPUA6NZ/OzLuXUT3swm+4rqJZEQ3AVr2BdqSzoiGHqqzmfKO33
++sODcYXuED0sUkIhRZE1vW+wXR94WQsT5C4MtHabNjpPLSH7cVjGvEfTX8DJH/F7p
++OdMmXxvPey0wLGJwoZMMhG/XC8Nb1g+qCLLou9WuA7KHMibfiYdBnPcMDg3fwWwg
++pYzrvK/S6f5h6TS8y9zKxCJwTdfC7f4KT6EjxQFhgHCm8oFupOLSEZKF0UmLMeOA
++J504ZnGdhEG5p9AqQNBlyBsGGmSyQkSJg1BPB6U7wFBSwrXS+3b2ph4J5RivH68O
++CKjR7yWl7M75LOa1dt133GmhPUUGHLsjHTnuCDVB0eHcgboonKTjCSAmckNKm/uw
++tAUMkO3puty5JM38b8AwFRDXLnlWdSsNr9j243SHOfKyFWidjwglRpVGBhoECtA=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-20-cert.pem 
b/test/fixtures/x509-escaping/alt-20-cert.pem
+new file mode 100644
+index 0000000000..eca176f2df
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-20-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE4jCCAsqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++MTAvMC0GA1UdEQQmMCSkIjAgMQswCQYDVQQGEwJERTERMA8GA1UEBwwIQmVybGlu
++DQowDQYJKoZIhvcNAQELBQADggIBAKvkEHjR6lk0AlKiC7oltE+gp7SpVHdKs7I4
++zswnbZ1EcddA9D6hjemU+nIUriLkt8BxY+KxNtkwDm5mvXZn5E4XDXzRDsCdNZXE
++qx9og9LhkhfGbPJ1LPutQ0VmqPwY17mRUeaLhNIwOmD7g++oVHYmZWqA8tHVB9f+
++gP5Ni2x/PX772Vt/hIpI14VoYIsMFs4Ewjc0Gc02DvOdsDT9eUmAo6GNOAbxeRS/
++D2D0w6CQhwJ+cemcAo0lGw8KemCYfqzL+MQd8wUGPsiZgm5wQACOp+ImL4guy2gX
++h60W9Gtxu77jsjF7n0n4LlInylrZAgw09CkehUfF4+cP2kZDTcsuqOoCVYATAGxa
++49ZvuRHoo5Ine5PcfuARS09LmxgI0fdsjaRvRELYIRWHTvE+zCLlNkxkpwXULgZZ
++bpJ08L52P+jz+HJPeiHZnYKXgtXyGLpwG1danS600tqiMmDh0G9Ss+UzwhS+jhN5
++viIvpmns0zvI1Z1IWPw3y27pw7rmLVcFMbEZFK5mwHiT10iRrT4sxihWIT+sn6n5
++5baup/od4kSJABQy9LAuhhuZHyCfxC2yPYz70sP8qGVtY+rA3LNe0ns6pY1L77DR
++QIRD/Mm2hql91+U222mxikdT4WQEheh2cLwdg/T1uo/SQDruliNZncdNbTGDmnhc
++cg1mw5tk
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-21-cert.pem 
b/test/fixtures/x509-escaping/alt-21-cert.pem
+new file mode 100644
+index 0000000000..16d5e7265b
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-21-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE9DCCAtygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++QzBBMD8GA1UdEQQ4MDakNDAyMQswCQYDVQQGEwJERTEjMCEGA1UEBwwaQmVybGlu
++L0NOPWdvb2QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggIBAHdccJEkqezS
++GSNNVIWv9XffNTrZnejms90h66UDC4O9shHMy0aNWgmGuu7uFi1BK4sTciXT+ZR5
++3+1ni3WKMhJ5Iu1aNlNeXULOlmuHKVJKrAj8BR7lflSFqj/MHnw22HU+BTmddZPj
++F/OCl2W+O+eUNBTTmYI2+pZgmyyU9v8qEwLZn57qlpAJa4gpnSRYQS1xfSaUgAcM
++xtZM/AE4F9mDFOdO86/RxXsYRyT0+sOGmaoJrlTWoKduoI7fhzQAIGHnhn9yBT60
++0K6LmCR2dXRyLxxVTy0Laiz487IXpQTJ8jo6c0wT6SeiQBlE0W3FTH3IM8Shzd7b
++5tbix0bCR1pUT2Q46oaB4xkEweKNGKS46kIps6mpTav3TMhNDVyalUfF4fOu4FQu
++RLB6B/I1TI1KHiTeD9xfNInBAdO9ewjWQ9spFei3EExZmvnnWKZIA82mjG/9Wcdh
++HFK/uEylzo1Nsxujv2V6ueMYc0pF4XH2U1Azjxb0+pWUZhoy537Nlf8b+PO/GSG8
++del0yPwf6JP5AZdXfiV8vNqwEGCC/BEIPrbZ6Zz1q6lT+7GZAGkzbMYlfkzA1lXh
++JteRIracA38WfQOHf3FOPYvTBOPlVHWB+tJbwlalYQqCPupMaaxxizCLPIsNvqdy
++TAtC5Jbx6N1DdeyHpRuKRUe1M926oKTp
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-22-cert.pem 
b/test/fixtures/x509-escaping/alt-22-cert.pem
+new file mode 100644
+index 0000000000..5f89b00dfd
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-22-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIEyTCCArGgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++GDAWMBQGA1UdEQQNMAuICSqGSIb3DQEBCzANBgkqhkiG9w0BAQsFAAOCAgEAE8vG
++nLYo/G+3Cuzir4toX726vLOkCEqZrkRE18dc3px/CgmEI/6+4lWjp3u/9MxER+kT
++t5o5Xin+vmg5F+hocR16mMeX6pjD6tXJ+uzDacTxDgRBFdbqX4x8Fjiig0FXsr3H
++jFBY2c4UcKszFlCTqjH1/RfwLYJPU6Q1WZM+1iJotSKnhK7y4A/3jho7sL0PPuMG
++WEoxbTBmpAf+jPT+LRe2MY++VnVJHjlPba+S4Y9PHOzizQuIJs7YnhNIqA9So7Iv
++eA7Lp8GID+w/eY4DEq4z6CIuCplKZTrrWH0kQbG1sV4J5+W+JL0DOXDk91JwkOPH
++rWf6aOb3akFRk5Z/PrrcTAlqtApPQF4uGycQBo8KgcatZyP/3HZZHyyxhEjF9sw/
++STHm93GlCIwocJ+SkwjBmdupv6Yk8fRmA7LinjVvi7EnQQ7qcRE3oUCPPReDD96G
++TuDsGkQbv5WQSh+0mBAiTFze3C6FSNcldQBrlWReqOj6pVWtUN49lpYOJ2XfLCQe
++RjS7IUYNn7Ku3xXi2etgNzmJXcSnNXZkh+3henpFqkwEFJ5b5RgOHXULTwoqo9KS
++YMs3eKHp62J6l0pQD+wTGUyVU8cJghJ0hR1WnNR7o32Bos2dfBmIQgET4ZH/P2+H
++A2gtbJO5mRsTvuD+kZut1jxJvUzuO0yZoNpuUVQ=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-23-cert.pem 
b/test/fixtures/x509-escaping/alt-23-cert.pem
+new file mode 100644
+index 0000000000..5cd6795cde
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-23-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIExTCCAq2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++FDASMBAGA1UdEQQJMAeIBSvODwwiMA0GCSqGSIb3DQEBCwUAA4ICAQBps3VQshvW
++9HDR2oDXSldWNW2SWksa+9npI4IEMDusiDbLdR0VBphw2R3iUuJ4IAPDc1s/SMi0
++1t1o92lC5zVeTq9LvOOC1KxwbZXDubFDmdsuJ/DYPDkaRoDqoH7eFsJuIyD/TKqm
++HXPYmWmjUNv51SSLTTqPRz2TmLQVA1Iw7J7H3fz2LExsAtczx6gRZJPIZGdMx6do
++E67SUp/2RPYtkEmmCELOxCAh/Pzm6pBPncI86AMTNwppl+FpqaH0LPrqMre40tTt
++cQq/0XrMWRoWsS3VU8uor+aGTnNp5VT3ZLVmXZNyG7nISW7ERaGCeTZJRcqwjeH/
++yPxhQc7IpYCm5x+HN2sDuvVC7l/q1A7+CbO3jNR5Gb7aEEyGiKb5ZkElbsulfwom
++JOg1K8+SBDGrErEf0MDCenKY2g0lhpKGBwu6O+RVmKbhlHEjt2/31/NCSBMLopdU
++AmCNoBo3+KaRljo1lVf7tWbffNRCqsbPZPHtq9uXs0DliJTUroaJ584h92VrSLJB
++SdAUVLAwzmwu2Pa4bp0STv5tJy1hFNJdVFQ4rgAfaFudXy41K9zqrDCB7RbzX7Yi
++97TCDu/phzkoFpOZabqTrvcP13N0wfDeOx4Y9nx77aeqTAaQ0ooTG9IWrHmjuUKF
++wpEXQBfkuXug5+xq/hlCllkPj67cIaldDQ==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-24-cert.pem 
b/test/fixtures/x509-escaping/alt-24-cert.pem
+new file mode 100644
+index 0000000000..2a858dd39a
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-24-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE1DCCArygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++IzAhMB8GA1UdEQQYMBagFAYIKwYBBQUHCAWgCAwGYWJjMTIzMA0GCSqGSIb3DQEB
++CwUAA4ICAQCKRaPaQO4+oztra70h3g1qwmJurQ1vGBdcXh27nf9epFAwhU1zL5v7
++7wN7iclY15BX3w3WrZ+ag74AvQLG6WQkDY1JCmidEjjt2bmVTxIus0H9Bb2AlUEw
++BtVYMJrr+fiWbfSwRxhMQa9BQ6ZcUA7EluYQFApo2m7GIcMc4x51L/bwzmsXYj4t
++2tjnkU7clL+7GR/w/+ZB7nIe80j7wYvIbOfMS3Yxh+uu0aQCNdoh9Tsdtu1jtmJv
++4lJ5aZIDABE/XIFVkWRyHv2ou14J/LXUKE3HPEhSKWu7GShrdTeS+gZpOixM+uPG
++ieHah1GfJMS69P82Z72Cr7XWpQY0NKwMB+ePhTzz1LMBHQ5ySXQCViQRClRMc5K+
++cXZm8cs6oe4IEhMcf3kc/9xblgRWqxX7vsb6Gcrn1eXsfxco17S1yNBzTt75ybt9
++kvPmrWqpg+sQ0r4473DjEASoSCPwlzCpd7AHOw+XxSwsOUNXkEnXMa2v2VHBjx06
++QnrLenB/n7EQ5Vo9JLDMLM6ie4gfehHxfdyoBg21jN9eUPpKGnjARVvyfDWV+7rI
++ZHU7wc2iMnqroAqm9FZ0YBqZ/eI8M4ZAYSvDKnGZQlUWfhdNDhI4FsHBPymMFtjW
++ln5eFUNLMoitMGs12Ib+omr9WSTxRj97GvRkRTNK5Gxmo9Mi/Pkxng==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-25-cert.pem 
b/test/fixtures/x509-escaping/alt-25-cert.pem
+new file mode 100644
+index 0000000000..695b8ebba8
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-25-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE6jCCAtKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++OTA3MDUGA1UdEQQuMCygKgYIKwYBBQUHCAWgHgwcYWJjMTIzLCBETlM6Z29vZC5l
++eGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAIgp7IrYYdLCoUqg7E4igLD3u
++C68B896uoeenMmTKDfCzvB5svYKZlfIi3njJUZ2G6kgBNcSd/mwQ2ggex9AEUiGp
++uaT7Dpev3RpwtCz5zpOZxN+B0LJk4hPzzE4sjJFrmHRgJVzADL5RdcEF7+GV81nP
++X/cXviffkxSihAFALArAaOA6/hBoT6unvlDsY3cxgZWFl3ao76vTQFLs7ZNHYbHe
++WDkkNpheWmNlOrVTEz0vjNCQz5wYOM6HJ0O3cxzR/6+OnhPQagZRCWApPopYGuxc
++kXHAPbEkXpVzJTrNgHIvZ3l3JdJSHsh+DdGVz1NY4bogQNKCVa3xt+zLpUrr34XM
++61Z91MekMijfjOsy7LGLSBdCPCZ00enXPkflDEhv1kRlbo/ZdYGHynzl6Xzu1A5B
++nuwDbpsCzR6ij8fZDXGUS7F8Iemdfag4XTtrXnVXLgPpD/FMzJUx4kCIAjgh2MaP
++0nUvZDVYt+GKGohCNDrSt2ByFtbYGaX5GeMIp8zW+GT8KUW/K7pp9PjsmzG6vvQd
++kqxB45ddf87E8NoDWh/ptdj3pjfbDc5A1SeXKGXrt1TwgWHtUNW0zF8qOuG+PZ1P
++u10lUx4gayyF3unaSLZwYu8nYq5C7mC9DjjnbjLhsh0VOIEEh+Q8vJH8OvZFkyti
++l2ADXC+6evQTvqLwXi8=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-26-cert.pem 
b/test/fixtures/x509-escaping/alt-26-cert.pem
+new file mode 100644
+index 0000000000..1204d95a8a
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-26-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE5TCCAs2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++NDAyMDAGA1UdEQQpMCegJQYIKwYBBQUHCAWgGQwXZ29vZC5leGFtcGxlLmNvbQBh
++YmMxMjMwDQYJKoZIhvcNAQELBQADggIBAKmgEHc9b/bscpyO5mTKrITyoYtbhz/P
++0Uz2Uc4tKokUI9EBuuD/XX4EjtVzne9mssAAs9EhBSFmNhDjpAUYh9n2cFvAJQit
++4d9EbaNbB3SuzG5onu8ZBtfLsABr5L5tQspO3tinamSM2ZuRo4dvcQ2a38C38LAQ
++HBnvZ744Th3LckPMLTWNChe3E2jAt8Av0XA2yVJ/B+EeEaqSYDALKhI49CLeq96L
++m/Vq/mqADborW51pMNFn7CAF1jxizQNHy6K0E95ziq8q/OL7j4+j8Erh4x7bcjrQ
++X04Z+hrA9q5AjG++ieztKqGuGxHeSclqBhOdnU0UI528Vn0OXRxeMmbqMF+qhx17
++nHuxxs4z5CIdTwHA6LgMUpDxcOhdUctIj32gwZM3UHI8lmdRTWn13y/Ht6CpIXCL
++1ohSXne5y34z4AKeJQpdUfwQD552Ui8B+bhH1JBm5phjLn1fboXCYiCgnPQ+SJzx
++3hsIv7Fji7lfk1UPkr0s7Ze8b/seYS8nVB5rg4qXEwFDMo9zsjCEIyg0tKwj5Ani
++HlYzqjjsIK50TPjXYOA9J+NHcBDCDa3r8TBtRGtQqOXQGzvWTqAyT8Uwn7jimmh+
++EGDr4PJSTJxv43EYL+of0sRHkOhnfFfJYF9vQLT+wD6l+6T1xNPE/gjX8DyQS9a3
++zOgdOiTp0AKH
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-27-cert.pem 
b/test/fixtures/x509-escaping/alt-27-cert.pem
+new file mode 100644
+index 0000000000..268abdd300
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-27-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE0TCCArmgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++IDAeMBwGA1UdEQQVMBOgEQYFK84PDCKgCAwGYWJjMTIzMA0GCSqGSIb3DQEBCwUA
++A4ICAQBtXT+t0fuBRClJdY6y01k1jqcsXEkmKOr4czznuiloGVEjpbjmxzxsgvzw
++nz3od6Sx56SHG1xYbKDCapX9Ld2IDsPvpF2wdH2wpIS5DI7tQdBpLm7vr3vTYKwm
++Wns+WKO5VBHDLCyuYvHNo37MJCAfBlr1ni7BCLOg3eycPiANJHPD2T9BnXlJm49K
++166VMviuiLBEyO9tadhvQHGqCX3D4pW31zwsKHvS4wau15N4yt053Iac6eaysdTp
++mspw5jX85tlQ9XxKNTftUVJU9Uzk2ll4A0Gvnq2FEjiqf6m3tye2nsqDI3C81Dwb
++Y/+AeO7ZsVyLpIstfUBFmpLGPUoZ5MNmgrboGf8K8dPPgVbmbS0msrsI4LWSQb8P
++R2hzj0F7bFvgbZad7rFXJW9FQOqTwvJrZBkkDpZpeNbhah14avV2Ftrc5+PtVfP0
++jB1L3nhc5KGpGL4xqE19K+GVR/KBREgiFD7B7NYUOPt9NjFTrbbC3XA8L0MC7PNh
++ySDN/NCiIF9K9MtpC8BYuNBlRt5C82L37qPY4Tw3z9sCyXK5oOQ4xdbdDEWdwzc5
++F2S4zfQiB7y+C9RigOyGPChxBqDK/bCExrG1S2b95oP4QMuaL55iXnaG9ME8sCoa
++cUd62cMPk7piQW29oFiQPYsStfo09u9JXbalKhol9oPrDtQfrQ==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-28-cert.pem 
b/test/fixtures/x509-escaping/alt-28-cert.pem
+new file mode 100644
+index 0000000000..147fba3aff
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-28-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE1DCCArygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++IzAhMB8GA1UdEQQYMBagFAYIKwYBBQUHCAegCBYGYWJjMTIzMA0GCSqGSIb3DQEB
++CwUAA4ICAQA2KjgKCSLg/rDajrBTtVIu14rAP1pMwFZWrxcpTbN+fOs2dYQXZf7d
++/GaozSMSchjPAJ8lTFfEB20Mur/E284LlQPuQKqHHn3gIh92VkHHBHjj0ohnfigg
++eBHNMUisuGyNzKV7VI1+iwCoPBZC7ptbE4X08osVxxRESj+IT0TwtKDONTIIeogW
++6VhsKTQ1HM6AMbhVe0Led/ENxFFMquB25GG/hVB4ZzPmsJZzNdZYNNMa34kNcMN3
++5OFcxWV/4Hc77JYsqM9fE9gBaKC9pQE0XwIrOMQSaGYx+GO8Ty33YlM+oYBt6TMH
++/9oU8HVvEYW9GAyptNbXPOwyv/wikNBsJyDGfvuDoiTZ9iMFb/bEoWHSK/rYmAgk
++D272zxiPS3YgaZkvhlYZ+60w5CCgXoN5L0Zq9yAOTv92/VHFnMPrTP7zfD+4eUHY
++lg+A7pOCIUK4cIDUXQefn1dU5/8DHJ8aM+KQDBfkKOH3me3GzIKjtKQjhwYFiJ8L
++vD4V6+nq90GasShQDKUbMVbCxfyqlvrXOP0an+FxdknadnD5hRT3UsU9SRxAdkXi
++3er2sXpuULYqOst55Ahnj7D5uDN4KBoatZwFd1iw0CVPoox7ixZ2zOAkwVqzaEAq
++0yWyIlELm9/FdF78fu6LPrFKI1H4MH+0TQrF4MiyJWPvET7t8WKJsA==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-29-cert.pem 
b/test/fixtures/x509-escaping/alt-29-cert.pem
+new file mode 100644
+index 0000000000..434bda3e8e
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-29-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE1DCCArygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++IzAhMB8GA1UdEQQYMBagFAYIKwYBBQUHCAegCAwGYWJjMTIzMA0GCSqGSIb3DQEB
++CwUAA4ICAQCIFfHE09aftJrS629ZBBRKjRiVcxN0/FjeEHWbnb+3Re/LoU/Y64BT
++LmjMBB6wik3JxxUtLs2UYExQKfz3zmB+O99lR94of3V3RXPCe9Dz8C12iohYBvVO
++q+WzXyg8g4zoIndn9+ByR+JJsuk+WVTZd50wRaRvssUB5yhpLaFdZpnLUBdV5J2d
++shmefZxr0NgMb9p75wvWgZ2BiZQDeTR93+PWaZTMdSxZh6ynfG//5sxxw5fLm3pv
++eVo3oQQ8px9j8G83ouiDZJn7XZgNfXYNq7wo3yaqXX0zlCE00K6tXGI6FkKJnVdQ
++si+JYfGjzTM39JqFU9YYOOc3Gfw20iKIEQ0jnE0Z+z9Pv2GAel0UNdovluttxu9R
++CJcPJOLS+TMd/sAwCAELvhPpeWsDLhfd+lG7ofE/nM6hzec6apWYyCqqlYIdE8WK
++rtHXBIMGk/5Eo+2KDGQHgpMs/P8fNUL6FBx/i1pjm5nSHveDQryepEmOJq9NJCBW
++1AJhE4jCXMv+43Fnr1OSATNiOd+1KfQ7KC5PFkpZLY4GDFZcbLBKYj1TWx4WzRnm
++EW7cC/00Z3Cd76L5i+y1Xr44nbQcAMw6TlT6vvZjFCbCO+ZDUJSZBZMpWwBI/gAf
++MNzYPltOGm+GZUuxib2MSF9Qy8c9NegENmsK+zyPT3N9mUHCl9nknA==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-3-cert.pem 
b/test/fixtures/x509-escaping/alt-3-cert.pem
+new file mode 100644
+index 0000000000..59185b64a4
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-3-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE1jCCAr6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++JTAjMCEGA1UdEQQaMBiGFmh0dHA6Ly9leGFtcGxlLmNvbS9hLGIwDQYJKoZIhvcN
++AQELBQADggIBAEKwv45Zp5xJEGENPrOIwrGmuBDMtBPmXtSKydKSNUgrv08u4dHL
++n295L7jIwQ3SnRjS8PrZWD8RQ46hgFRY9pqk1uTys4jB7lki0eAUBC7oPn7q0GUv
++ojdSwOEjp5bfXyuRv7Z+3y2gD8pcCZsqcCjF5Svim6Q3pXMLRKQFhzhzL9k/gsNF
++lJ8KcLBECJSm5nUrZIRHPdIGYmWJG+t8CfS3E6OIyHILK1xCc1MasEpmYVoY9uzT
++2W2z+3pvwQqfdXO+lEOsT9dnjM/WbnkQMTWAn+++YFtkvA4kON4b/cp9imnXok02
++vq7MCbN+b5CJXIhKMC5eNA36ez5hou0MUmnsNo9ai1gVJXRoL67YgUh1yMfcAaSM
++Sfy3UBF++Az/yQo4AWtqWk4KPePdcsrYo9Fke1inUl+M12gkdIz+efbElHMqehbt
++lunbyFI/7CY6/Tno+T1cDkQlTouHK8Ddb1cPhkJbE4euRuLGdtn2AcFSemYGtib0
++ffuhnEBF8M8enPVyLjYA/3sELkmmaHMtgDTm0+XYQJtjIbvGcY7+bftPZgbXPVGv
++7+tiYjwarIexXN5yzMasgFI5+7qLSQJHcmwrzOm8K+Bzx34f20vwR4M2FJ6cqUeN
++qzdN1HSNp8aYNilaFa3+hfGRG9CZnVP8up8BwYx736EMu0G3yAp6UqqJ
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-30-cert.pem 
b/test/fixtures/x509-escaping/alt-30-cert.pem
+new file mode 100644
+index 0000000000..1b67d1f782
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-30-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE1TCCAr2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++JDAiMCAGA1UdEQQZMBegFQYIKwYBBQUHCAegCRYHYWJjAGRlZjANBgkqhkiG9w0B
++AQsFAAOCAgEAgG06c7GRpPohHa1X/YQVQGWa/J/f3qok3cu1nrD2H5Dkw1eAVPcQ
++lsng08lOxwSI0OgqJw0jl+ljLKuhHI3U68KbFmUO3Jw7uLDk1+UniRSNkfxVOrlc
++7YTlmsxiDgQdX6/TAHu6bERx147NqVzB4/I6qpX7ouLv4E7xdQgjKuvhWlJ+Fg/0
++pQ7EleQymRN6Y8qO6RwEWYao5pypg8/22cE3jgXleLM+5qWHqJs2ZewPQf7uo4Bf
++IwSUV5H0weftiSN+kOLYiNfUago108VHuk5sCIKr92q4WAJgA5C6ylcUWaJCKbCv
++HQYR/QG10Mrn4JCzzni90aBHrQoYQ8msEDH1QKyMJiNz6XXzwBP6bvgPlB2f7nPW
++ERpH45M2I4Z3dZYFw8bF7CcOIUuR0/Zu2WN22IhqhjVQSZPzdRWJt5Rr1mFUz+Nv
++Ymdi0w68KyRUiuOpKNLczDDnYpc9EqGBprnMOxALS4mQn1ySBXbZAXnTTdEzN5fM
++L4CXWUzIBVKv56Mn5YskhbCd+N8GV9Nj/A6dBwa004CQxbgAj+ndNWc7+h4iSNlz
++9VPHK2Kju6j4fVpe10jzSoEs0nnrsPy5Lxa6C4KhXBBJ3cPl6wWNe2mgbEqG9Pq2
++KrCizuFkIfZTAeSrR+prZXLw6cjmKPPEtNbK2JbteL2SEDT/3AjmmZE=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-4-cert.pem 
b/test/fixtures/x509-escaping/alt-4-cert.pem
+new file mode 100644
+index 0000000000..086af8e02e
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-4-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE2DCCAsCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++JzAlMCMGA1UdEQQcMBqGGGh0dHA6Ly9leGFtcGxlLmNvbS9hJTJDYjANBgkqhkiG
++9w0BAQsFAAOCAgEAPu7ubyZw1rOQJhFX6nBHyCYaBzaKxRZOHOFCjMrD/YQXPUNM
++Hs+8ChOeQ4M82jTyiP7XgF8EumDcckDIlIYvGXGrCB/6VcCVL1vPPtzjSaiF3PlG
++/dh0OlPvevr5Ajz7ZtFFwxeQ2EfsHiry8qnlDJSEjrh4Trcx9YzdkSZz8DaoODXz
++ctR/p1JEnQ6h/Axa6hdqTzbzTsINN7gD5Wi3ObfQbK6Ug/CuH6Zr8bdTsmeGcnD0
++fqHptuLVNcROykneYziXDzcqGwrZnYaOF54a4ibV/OfrBcgEKeDwsCrLs3nztSC4
++whV7DXZwaLl2KWl4/suBNI1cIKbxII1xTFLTog+UYz0zSZGPrtbt7zrlM4yG033t
++h9xIGUKebaNpQYkoxOc/+kKhbKCeL3klfxJoX+6Gf8DkTP7byX2HovfWV1rJbh57
++YZ04Bh69VmyxE4iyb1tAh5xh1bArCR9m96eXS/0KIZbykxltQGyHf1jpWw/4Wi3n
++oadkpMcyNX76M1xBJ5u03JL8+LWrXuzf/ScWdmPUWulAEhbo4fn4oRwP2C3l0vVQ
++iL482cIq1zF91lssRwQ17k38phulRdm+7W65/VI7hLoG6lXiSiHLH8e39hHO8Jey
++Z+BBvn8x+aFgIvpBK/MX35s0gSrl/UiIZPU9glnktSsX5D+aaQynbuvbOW8=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-5-cert.pem 
b/test/fixtures/x509-escaping/alt-5-cert.pem
+new file mode 100644
+index 0000000000..04a918008c
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-5-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE6jCCAtKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++OTA3MDUGA1UdEQQuMCyGKmh0dHA6Ly9leGFtcGxlLmNvbS9hLCBETlM6Z29vZC5l
++eGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEANAyZnL8f81Aax/0Rhw3CCdcQ
++SXF3dpAolObQB8rlirRZ7yOY1v3Poj411aV0x9zM6mjOJZwarUTL7kbO7odQxGhB
++x7O0DvUoG15VTvs0XLNHTPgnXtNjKOZ7XXVMzb46APfYSqdzMqhRWfy+Iaikp494
++urtqkVt05q2amzq7EXbXI8JQWhkJkhjBTowfZnpZUw4JeeqMNRZT9Ldv2XDZjaYS
++lkHOLzTmSmm2mf1oxhKGcRCgUCr/pzVUfDA3RBz25a6PWAQt4b2r8k5jydWyOeCZ
+++sjacoK5/E1PcdaOFJAjuAfbRMeK/gz2+yJwaB39Yh77t/9vQC0G6aiAmO0HxjJE
++L6Lb8BG/QNYBS7gGhzKFVXVVv5yXRioO9vMv0i8uxShqD2Lo/MbrNtRgi3eMFESd
++3NxUPXS1jMq2/SaXrENdKqNNi06LbnLaYpI3BLZ/Katq0V9ESlhcC2nT5uNBPiLr
++DNSekaIGobbTDkuV896L7jqsQpU+sgs4XqaISGgk2wAfnwbfpeiBCL8oH9yCYAO0
++1YlevrMGjBNvhysoABv7qaorqeL97ffRhjOZ72/fm2axD5l9MvWEFIf7L5uOah0f
++hF5vScQYgyWNuK8wjzT2tl0CuxvEyI7N4fkUEk+ZMkyI1Obx17p+d4SFyuq7wTXR
++05oWMsCMDyzxvFDv92w=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-6-cert.pem 
b/test/fixtures/x509-escaping/alt-6-cert.pem
+new file mode 100644
+index 0000000000..6643519957
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-6-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIEyzCCArOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++GjAYMBYGA1UdEQQPMA2CC2V45G1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQBB
++lBfIjUH7/PbpC00TWTOSR6sAzyBr681lSxYAgFLduDdfR/bTkI1p7txIAgennoUq
+++9slIIMaR799BUtQDfAQRYdbsWiG/+5Lj3JXs33LPPTdW1C97LOPlnnbRJh1sjbi
++UfGdxvdPA6iuyWhfwPZd+4IrcN+kefkvEnRkvDMGwmfmKQDjbu2mSIAIe+ECyLLu
++wdSI2sPBSUKQEKk+dABYq9TcdxlA+OSPjgs5ZF3NK3s/or7ay2r/i8be5TswY4Up
++IwByEk+7AST6ijwi3P8EN0HAyyuOfpBelWZCQgdEGt40Mpa58AwBGqdrCZ5wDAz5
++nBx6GscZUsqG9sVM71Tgq7Bc1b69FXUYAhmFucnXizHv1Ys0oGQVza1tkKbaLEFQ
++WvXWc7zW/0hTzvmtogKn/oM6GoNcQiW8KCwaCJq1TTv7Tip9znfB496tDruOr+2w
++HoqZTJ7ERklz0mlZ38ISTuaz+Qkn1KjBYh4tgP/wZIjIyppAaAr+JdqXzBejfb4M
++6x0S1AG9QgvyR1xDv3Vljjkh3m55kktTWSOfjS6aSzomaAyVAgi/vhHkxhsoBhgQ
++41+ffkhM9ps9wkmguwqOXsByQAZUQEJQigO39qYuGuJEDV8Bu8i/T5BuuJWP4BRF
++X+now5ObP73ufyFwYGsSgblivHUX4z/zAt4kp4AMXw==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-7-cert.pem 
b/test/fixtures/x509-escaping/alt-7-cert.pem
+new file mode 100644
+index 0000000000..6c0f287a1b
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-7-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIE0jCCArqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++ITAfMB0GA1UdEQQWMBSCEiJldmlsLmV4YW1wbGUuY29tIjANBgkqhkiG9w0BAQsF
++AAOCAgEAKmYr4QEnNq1Sy9lYePNRR60jufFXk44bczNT/wA6kvXKgv472V9wltVb
++yJVvYUWkTO8ahlELNLfqRcuih6myV64WJoewog8mwby0lBYr6bAz86DdeN/B9rFD
++OYnev1Ux4um45l42XP8acgJCoqn8+EE+H4AeMrz2xxHt+IDy4vUOowZna82f1Pcp
++O+vhod2uXlukfnhofVK4lMHl4++4kECkmUYl8U+L/zXwzOb4S3Yksffmadgo7ERk
++rJYLMLztvCk6TtP+p4NcvrE90dmss7R8hfw3asfjXsRbAMigdfSMKzGB2IHoHeV6
++fpmJy6kotfwulDrbr2QtrWOYdMrm1wT6ohT355KZQxcZr3VcK9gqEjcYafqIsXtA
++wYAaorKXaz7UkmFCDbk/24UuHgNgCl4KkGsFNwW6whTMpb9WnvPR7F798tiIbOL+
++FK6yA1q3Z2500lmloQWcUFBX48DViG3bsTJ9wmQ28aPqHVd5gTmTm/7W2iRGx36N
++PmbAk17J/bUzUSORgrPi2FLNNFg64x40pfdAyrF9ZBNcsVCFCUgOQHgMh4OjX/n7
++khmNbMYiOvJEoUbZ9flNr4AYY3ucpxQ2peTl4DNsVZZ8Xyh96h3URu63Ji9+xLrQ
++jSUtNHUCJaC3E9yTaIDc8jMli9s5/ElDZRkPxRP8o4VOt9KcLvU=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-8-cert.pem 
b/test/fixtures/x509-escaping/alt-8-cert.pem
+new file mode 100644
+index 0000000000..201b520f8b
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-8-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIExDCCAqygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++EzARMA8GA1UdEQQIMAaHBAgICAgwDQYJKoZIhvcNAQELBQADggIBAHfvavrzBLuS
++MMJwNkJGVt1W856zeZ6NZJ5vx2ZXziYxAkzw9N0pLHwgfzS8pXEPSZ6vMoeYMaH0
++zr/S5tHSMGEwOp/dIoxE4Hm1uMzugHFxNp34hvqsaDbwKMpQQzEPhN1QvAkD9IXL
++H2wOLqm+ZaTkT3OvOyJoml56wyUJ0nU746RuXgJHTFiWsUTPqT9bvofedC80MUyH
++MX2lA1oy8nzJa9h7JqsxOE4uccRhpCRf+PxeYvOdsUxyDWw8+rjwe4Ulr0yVjwnD
++x9ha/fTl96mYXyJGLtQvZmkllrctxcs0o82+wMZWBw4iPH/VnI7dj36b2uIHdrrf
++cVurEPcVE03zLwukjQPZh9otleTwmQI1wqg/Gm2OahXy/0f0fpBDQnPycczn8nFw
++nj6avmHubWVvzmEoKmOtavGEAbUn7ntQfsvM5JpiM+ck3MDMP9i9cMZvWKH8Eial
++ZnYcXkgAatWwp4Cbsv4H7LMNisKjrcY+r+MpaYYIpTRNp/s/P5bMCIVt07yosePg
++m9VWy03+hQJmD4/THeJsjuczPSBtsoJiKoTJ5TndmpFaG6J6lBVvpXJhoiW/QIgX
++u2QIb8Z6bRK/eQ8UVYm0/ZQLN+OOzYiQfm0AFbFpYhl46o6QNZ03P6GRLshv+N3E
++CX66ucPLd4QJitUy39LZjMlC0YxTZUry
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/alt-9-cert.pem 
b/test/fixtures/x509-escaping/alt-9-cert.pem
+new file mode 100644
+index 0000000000..660e65b8ed
+--- /dev/null
++++ b/test/fixtures/x509-escaping/alt-9-cert.pem
+@@ -0,0 +1,28 @@
++-----BEGIN CERTIFICATE-----
++MIIExDCCAqygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++EzARMA8GA1UdEQQIMAaHBAgIBAQwDQYJKoZIhvcNAQELBQADggIBAIefUJjnOtt8
++viFkr3lupabUMwSgtBXVCp+M9xhKqcSnYReSgg/LcqVDaXmU4s23n0Bc0M51HQMG
++puTpfr34ZUSQiLup9huELm5L+lcpYANJsKrBo+vz1w+fkPlcxXvXHpLzgb393XSJ
++/Prn7lNBrrh9b74azUEhz1KPmFbbMs7IwlhE1+stQ107VeSGvKlAOmaYdnVG1PXl
++AG7KJynpE5Ex8XF1ONQLneTdvo8gXZueb07SY+my5wrCQhSlh4/6Y2MnE9h+9ugx
++BfdU72okDaYRH1MAfFeAsUE7Y52cQqm26b7nBz0+IeP+uk7oqDLF+PGHfjeUGXGW
++aGFfaLk8Dl2gMg1DsRE8zcT215Dl4rqOtwbhW8kX7XzYE0sA7cnyZ0daLrrtxwe6
++MhrAOjYklRZpwUvy6E2IyipKwWSuKHLUk3mVxPrxVqvye2enZWW1PJeHNdL//Ogx
++5Mm++BOTNR+61pg/UrATlO3GMK6ggAfkP8H1r3jp24hc/TkXRkoUuWZqtjC5+qwB
++KVIPlr+/0zIhzDjNbN0TMgqv/Yz4/wCUjsmCPJu21C3+BP2O5ZD2e4hYe/X9kuhC
++YGWTf8dpq0LgYgVHqwXo0gCU/Ich9KtaJmCgZRUrzMl1aIYhqpuR2EW8H1bs3a0P
++/7wXhGudHCwm6j2H5/tbsREeYInl3mv4
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/create-certs.js 
b/test/fixtures/x509-escaping/create-certs.js
+new file mode 100644
+index 0000000000..b84547e1d0
+--- /dev/null
++++ b/test/fixtures/x509-escaping/create-certs.js
+@@ -0,0 +1,502 @@
++'use strict';
++
++const asn1 = require('asn1.js');
++const crypto = require('crypto');
++const { writeFileSync } = require('fs');
++const rfc5280 = require('asn1.js-rfc5280');
++const BN = asn1.bignum;
++
++const oid = {
++  commonName: [2, 5, 4, 3],
++  countryName: [2, 5, 4, 6],
++  localityName: [2, 5, 4, 7],
++  rsaEncryption: [1, 2, 840, 113549, 1, 1, 1],
++  sha256WithRSAEncryption: [1, 2, 840, 113549, 1, 1, 11],
++  xmppAddr: [1, 3, 6, 1, 5, 5, 7, 8, 5],
++  srvName: [1, 3, 6, 1, 5, 5, 7, 8, 7],
++  ocsp: [1, 3, 6, 1, 5, 5, 7, 48, 1],
++  caIssuers: [1, 3, 6, 1, 5, 5, 7, 48, 2],
++  privateUnrecognized: [1, 3, 9999, 12, 34]
++};
++
++const digest = 'SHA256';
++
++const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
++  modulusLength: 4096,
++  publicKeyEncoding: {
++    type: 'pkcs1',
++    format: 'der'
++  }
++});
++
++writeFileSync('server-key.pem', privateKey.export({
++  type: 'pkcs8',
++  format: 'pem'
++}));
++
++const now = Date.now();
++const days = 3650;
++
++function utilType(name, fn) {
++  return asn1.define(name, function() {
++    this[fn]();
++  });
++}
++
++const Null_ = utilType('Null_', 'null_');
++const null_ = Null_.encode('der');
++
++const IA5String = utilType('IA5String', 'ia5str');
++const PrintableString = utilType('PrintableString', 'printstr');
++const UTF8String = utilType('UTF8String', 'utf8str');
++
++const subjectCommonName = PrintableString.encode('evil.example.com', 'der');
++
++const sans = [
++  { type: 'dNSName', value: 'good.example.com, DNS:evil.example.com' },
++  { type: 'uniformResourceIdentifier', value: 'http://example.com/' },
++  { type: 'uniformResourceIdentifier', value: 'http://example.com/?a=b&c=d' },
++  { type: 'uniformResourceIdentifier', value: 'http://example.com/a,b' },
++  { type: 'uniformResourceIdentifier', value: 'http://example.com/a%2Cb' },
++  {
++    type: 'uniformResourceIdentifier',
++    value: 'http://example.com/a, DNS:good.example.com'
++  },
++  { type: 'dNSName', value: Buffer.from('exämple.com', 'latin1') },
++  { type: 'dNSName', value: '"evil.example.com"' },
++  { type: 'iPAddress', value: Buffer.from('08080808', 'hex') },
++  { type: 'iPAddress', value: Buffer.from('08080404', 'hex') },
++  { type: 'iPAddress', value: Buffer.from('0008080404', 'hex') },
++  { type: 'iPAddress', value: Buffer.from('000102030405', 'hex') },
++  {
++    type: 'iPAddress',
++    value: Buffer.from('0a0b0c0d0e0f0000000000007a7b7c7d', 'hex')
++  },
++  { type: 'rfc822Name', value: '[email protected]' },
++  { type: 'rfc822Name', value: '[email protected], DNS:good.example.com' },
++  {
++    type: 'directoryName',
++    value: {
++      type: 'rdnSequence',
++      value: [
++        [
++          {
++            type: oid.countryName,
++            value: PrintableString.encode('DE', 'der')
++          }
++        ],
++        [
++          {
++            type: oid.localityName,
++            value: UTF8String.encode('Hannover', 'der')
++          }
++        ]
++      ]
++    }
++  },
++  {
++    type: 'directoryName',
++    value: {
++      type: 'rdnSequence',
++      value: [
++        [
++          {
++            type: oid.countryName,
++            value: PrintableString.encode('DE', 'der')
++          }
++        ],
++        [
++          {
++            type: oid.localityName,
++            value: UTF8String.encode('München', 'der')
++          }
++        ]
++      ]
++    }
++  },
++  {
++    type: 'directoryName',
++    value: {
++      type: 'rdnSequence',
++      value: [
++        [
++          {
++            type: oid.countryName,
++            value: PrintableString.encode('DE', 'der')
++          }
++        ],
++        [
++          {
++            type: oid.localityName,
++            value: UTF8String.encode('Berlin, DNS:good.example.com', 'der')
++          }
++        ]
++      ]
++    }
++  },
++  {
++    type: 'directoryName',
++    value: {
++      type: 'rdnSequence',
++      value: [
++        [
++          {
++            type: oid.countryName,
++            value: PrintableString.encode('DE', 'der')
++          }
++        ],
++        [
++          {
++            type: oid.localityName,
++            value: UTF8String.encode('Berlin, 
DNS:good.example.com\0evil.example.com', 'der')
++          }
++        ]
++      ]
++    }
++  },
++  {
++    type: 'directoryName',
++    value: {
++      type: 'rdnSequence',
++      value: [
++        [
++          {
++            type: oid.countryName,
++            value: PrintableString.encode('DE', 'der')
++          }
++        ],
++        [
++          {
++            type: oid.localityName,
++            value: UTF8String.encode(
++              'Berlin, DNS:good.example.com\\\0evil.example.com', 'der')
++          }
++        ]
++      ]
++    }
++  },
++  {
++    type: 'directoryName',
++    value: {
++      type: 'rdnSequence',
++      value: [
++        [
++          {
++            type: oid.countryName,
++            value: PrintableString.encode('DE', 'der')
++          }
++        ],
++        [
++          {
++            type: oid.localityName,
++            value: UTF8String.encode('Berlin\r\n', 'der')
++          }
++        ]
++      ]
++    }
++  },
++  {
++    type: 'directoryName',
++    value: {
++      type: 'rdnSequence',
++      value: [
++        [
++          {
++            type: oid.countryName,
++            value: PrintableString.encode('DE', 'der')
++          }
++        ],
++        [
++          {
++            type: oid.localityName,
++            value: UTF8String.encode('Berlin/CN=good.example.com', 'der')
++          }
++        ]
++      ]
++    }
++  },
++  {
++    type: 'registeredID',
++    value: oid.sha256WithRSAEncryption
++  },
++  {
++    type: 'registeredID',
++    value: oid.privateUnrecognized
++  },
++  {
++    type: 'otherName',
++    value: {
++      'type-id': oid.xmppAddr,
++      value: UTF8String.encode('abc123', 'der')
++    }
++  },
++  {
++    type: 'otherName',
++    value: {
++      'type-id': oid.xmppAddr,
++      value: UTF8String.encode('abc123, DNS:good.example.com', 'der')
++    }
++  },
++  {
++    type: 'otherName',
++    value: {
++      'type-id': oid.xmppAddr,
++      value: UTF8String.encode('good.example.com\0abc123', 'der')
++    }
++  },
++  {
++    type: 'otherName',
++    value: {
++      'type-id': oid.privateUnrecognized,
++      value: UTF8String.encode('abc123', 'der')
++    }
++  },
++  {
++    type: 'otherName',
++    value: {
++      'type-id': oid.srvName,
++      value: IA5String.encode('abc123', 'der')
++    }
++  },
++  {
++    type: 'otherName',
++    value: {
++      'type-id': oid.srvName,
++      value: UTF8String.encode('abc123', 'der')
++    }
++  },
++  {
++    type: 'otherName',
++    value: {
++      'type-id': oid.srvName,
++      value: IA5String.encode('abc\0def', 'der')
++    }
++  }
++];
++
++for (let i = 0; i < sans.length; i++) {
++  const san = sans[i];
++
++  const tbs = {
++    version: 'v3',
++    serialNumber: new BN('01', 16),
++    signature: {
++      algorithm: oid.sha256WithRSAEncryption,
++      parameters: null_
++    },
++    issuer: {
++      type: 'rdnSequence',
++      value: [
++        [
++          { type: oid.commonName, value: subjectCommonName }
++        ]
++      ]
++    },
++    validity: {
++      notBefore: { type: 'utcTime', value: now },
++      notAfter: { type: 'utcTime', value: now + days * 86400000 }
++    },
++    subject: {
++      type: 'rdnSequence',
++      value: [
++        [
++          { type: oid.commonName, value: subjectCommonName }
++        ]
++      ]
++    },
++    subjectPublicKeyInfo: {
++      algorithm: {
++        algorithm: oid.rsaEncryption,
++        parameters: null_
++      },
++      subjectPublicKey: {
++        unused: 0,
++        data: publicKey
++      }
++    },
++    extensions: [
++      {
++        extnID: 'subjectAlternativeName',
++        critical: false,
++        extnValue: [san]
++      }
++    ]
++  };
++
++  // Self-sign the certificate.
++  const tbsDer = rfc5280.TBSCertificate.encode(tbs, 'der');
++  const signature = crypto.createSign(digest).update(tbsDer).sign(privateKey);
++
++  // Construct the signed certificate.
++  const cert = {
++    tbsCertificate: tbs,
++    signatureAlgorithm: {
++      algorithm: oid.sha256WithRSAEncryption,
++      parameters: null_
++    },
++    signature: {
++      unused: 0,
++      data: signature
++    }
++  };
++
++  // Store the signed certificate.
++  const pem = rfc5280.Certificate.encode(cert, 'pem', {
++    label: 'CERTIFICATE'
++  });
++  writeFileSync(`./alt-${i}-cert.pem`, `${pem}\n`);
++}
++
++const infoAccessExtensions = [
++  [
++    {
++      accessMethod: oid.ocsp,
++      accessLocation: {
++        type: 'uniformResourceIdentifier',
++        value: 'http://good.example.com/\nOCSP - 
URI:http://evil.example.com/',
++      },
++    },
++  ],
++  [
++    {
++      accessMethod: oid.caIssuers,
++      accessLocation: {
++        type: 'uniformResourceIdentifier',
++        value: 'http://ca.example.com/\nOCSP - URI:http://evil.example.com',
++      },
++    },
++    {
++      accessMethod: oid.ocsp,
++      accessLocation: {
++        type: 'dNSName',
++        value: 'good.example.com\nOCSP - URI:http://ca.nodejs.org/ca.cert',
++      },
++    },
++  ],
++  [
++    {
++      accessMethod: oid.privateUnrecognized,
++      accessLocation: {
++        type: 'uniformResourceIdentifier',
++        value: 'http://ca.example.com/',
++      },
++    },
++  ],
++  [
++    {
++      accessMethod: oid.ocsp,
++      accessLocation: {
++        type: 'otherName',
++        value: {
++          'type-id': oid.xmppAddr,
++          value: UTF8String.encode('good.example.com', 'der'),
++        },
++      },
++    },
++    {
++      accessMethod: oid.ocsp,
++      accessLocation: {
++        type: 'otherName',
++        value: {
++          'type-id': oid.privateUnrecognized,
++          value: UTF8String.encode('abc123', 'der')
++        },
++      },
++    },
++    {
++      accessMethod: oid.ocsp,
++      accessLocation: {
++        type: 'otherName',
++        value: {
++          'type-id': oid.srvName,
++          value: IA5String.encode('abc123', 'der')
++        }
++      }
++    },
++  ],
++  [
++    {
++      accessMethod: oid.ocsp,
++      accessLocation: {
++        type: 'otherName',
++        value: {
++          'type-id': oid.xmppAddr,
++          value: UTF8String.encode('good.example.com\0abc123', 'der'),
++        },
++      },
++    },
++  ],
++];
++
++for (let i = 0; i < infoAccessExtensions.length; i++) {
++  const infoAccess = infoAccessExtensions[i];
++
++  const tbs = {
++    version: 'v3',
++    serialNumber: new BN('01', 16),
++    signature: {
++      algorithm: oid.sha256WithRSAEncryption,
++      parameters: null_
++    },
++    issuer: {
++      type: 'rdnSequence',
++      value: [
++        [
++          { type: oid.commonName, value: subjectCommonName }
++        ]
++      ]
++    },
++    validity: {
++      notBefore: { type: 'utcTime', value: now },
++      notAfter: { type: 'utcTime', value: now + days * 86400000 }
++    },
++    subject: {
++      type: 'rdnSequence',
++      value: [
++        [
++          { type: oid.commonName, value: subjectCommonName }
++        ]
++      ]
++    },
++    subjectPublicKeyInfo: {
++      algorithm: {
++        algorithm: oid.rsaEncryption,
++        parameters: null_
++      },
++      subjectPublicKey: {
++        unused: 0,
++        data: publicKey
++      }
++    },
++    extensions: [
++      {
++        extnID: 'authorityInformationAccess',
++        critical: false,
++        extnValue: infoAccess
++      }
++    ]
++  };
++
++  // Self-sign the certificate.
++  const tbsDer = rfc5280.TBSCertificate.encode(tbs, 'der');
++  const signature = crypto.createSign(digest).update(tbsDer).sign(privateKey);
++
++  // Construct the signed certificate.
++  const cert = {
++    tbsCertificate: tbs,
++    signatureAlgorithm: {
++      algorithm: oid.sha256WithRSAEncryption,
++      parameters: null_
++    },
++    signature: {
++      unused: 0,
++      data: signature
++    }
++  };
++
++  // Store the signed certificate.
++  const pem = rfc5280.Certificate.encode(cert, 'pem', {
++    label: 'CERTIFICATE'
++  });
++  writeFileSync(`./info-${i}-cert.pem`, `${pem}\n`);
++}
+diff --git a/test/fixtures/x509-escaping/google/intermediate.pem 
b/test/fixtures/x509-escaping/google/intermediate.pem
+new file mode 100644
+index 0000000000..9d2aeb32c4
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/intermediate.pem
+@@ -0,0 +1,11 @@
++-----BEGIN CERTIFICATE-----
++MIIBjjCCATSgAwIBAgIBAjAKBggqhkjOPQQDAjAPMQ0wCwYDVQQDEwRSb290MCAX
++DTAwMDEwMTAwMDAwMFoYDzIwOTkwMTAxMDAwMDAwWjAXMRUwEwYDVQQDEwxJbnRl
++cm1lZGlhdGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR7DaOQvpvA47q2XxjM
++qxJVf/FvZm2ftiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkY
++tM/Bo3cwdTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQlGcYbYohaK3S+XGeq
++CTi4LLHeLTAfBgNVHSMEGDAWgBQlGcYbYohaK3S+XGeqCTi4LLHeLTAiBgNVHR4B
++Af8EGDAWoBQwEoIQYXR0YWNrZXIuZXhhbXBsZTAKBggqhkjOPQQDAgNIADBFAiEA
++uZhmF3buUdhzHjXLZQSOyT41DqUUX/VKBEraDu+gj+wCIG/R1arbHFRFnEuoVgZI
++bihwUpUZjIZ5YwJcBu6yuXlZ
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/google/key.pem 
b/test/fixtures/x509-escaping/google/key.pem
+new file mode 100644
+index 0000000000..102a9d8816
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/key.pem
+@@ -0,0 +1,5 @@
++-----BEGIN PRIVATE KEY-----
++MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgaNbpDxJET5xVHxd/
++ig5x2u2KUIe0jaCVWqarpIN/582hRANCAAR7DaOQvpvA47q2XxjMqxJVf/FvZm2f
++tiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkYtM/B
++-----END PRIVATE KEY-----
+diff --git a/test/fixtures/x509-escaping/google/leaf0.pem 
b/test/fixtures/x509-escaping/google/leaf0.pem
+new file mode 100644
+index 0000000000..ce19dc9699
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/leaf0.pem
+@@ -0,0 +1,10 @@
++-----BEGIN CERTIFICATE-----
++MIIBajCCARCgAwIBAgIBAzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxJbnRlcm1l
++ZGlhdGUwIBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMA8xDTALBgNV
++BAMTBExlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR7DaOQvpvA47q2XxjM
++qxJVf/FvZm2ftiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkY
++tM/Bo1MwUTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFCUZxhtiiFordL5cZ6oJ
++OLgssd4tMCAGA1UdEQQZMBeCFWJsYWguYXR0YWNrZXIuZXhhbXBsZTAKBggqhkjO
++PQQDAgNIADBFAiEA4NgHDxVrBjNW+So4MrRZMwDknvjRaBsB4j2IwVRKl4sCIDpg
++Bhm4ZdHwlUYrALkXa3dFBy8kXBkVumY7UJpbB2mO
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/google/leaf1.pem 
b/test/fixtures/x509-escaping/google/leaf1.pem
+new file mode 100644
+index 0000000000..0b45056656
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/leaf1.pem
+@@ -0,0 +1,10 @@
++-----BEGIN CERTIFICATE-----
++MIIBdTCCARygAwIBAgIBBDAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxJbnRlcm1l
++ZGlhdGUwIBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMA8xDTALBgNV
++BAMTBExlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR7DaOQvpvA47q2XxjM
++qxJVf/FvZm2ftiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkY
++tM/Bo18wXTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFCUZxhtiiFordL5cZ6oJ
++OLgssd4tMCwGA1UdEQQlMCOCCm5vZGVqcy5vcmeCFWJsYWguYXR0YWNrZXIuZXhh
++bXBsZTAKBggqhkjOPQQDAgNHADBEAiAOFFOCfA6c/iZWxbDn5QMjNdtZbtJPBcRv
++uEgSqWrGTAIgK5RK0xGK8UZb2aM2VjGNTYozlcwKaLgQukA+UnKrrJg=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/google/leaf2.pem 
b/test/fixtures/x509-escaping/google/leaf2.pem
+new file mode 100644
+index 0000000000..9cf03fae7d
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/leaf2.pem
+@@ -0,0 +1,10 @@
++-----BEGIN CERTIFICATE-----
++MIIBejCCASCgAwIBAgIBBTAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxJbnRlcm1l
++ZGlhdGUwIBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMA8xDTALBgNV
++BAMTBExlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR7DaOQvpvA47q2XxjM
++qxJVf/FvZm2ftiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkY
++tM/Bo2MwYTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFCUZxhtiiFordL5cZ6oJ
++OLgssd4tMDAGA1UdEQQpMCeCJW5vZGVqcy5vcmcsIEROUzpibGFoLmF0dGFja2Vy
++LmV4YW1wbGUwCgYIKoZIzj0EAwIDSAAwRQIgWfT1VXQA79PxgM0DsfeoiwZCc2Be
++v3/RCRYoRky9DgICIQDUTjndnBQ0KeIWhuMjtSz1C5uPUYofKe7pV2qb/57kvA==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/google/leaf3.pem 
b/test/fixtures/x509-escaping/google/leaf3.pem
+new file mode 100644
+index 0000000000..55a64fdc89
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/leaf3.pem
+@@ -0,0 +1,10 @@
++-----BEGIN CERTIFICATE-----
++MIIBZzCCAQ2gAwIBAgIBBjAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxJbnRlcm1l
++ZGlhdGUwIBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMA8xDTALBgNV
++BAMTBExlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR7DaOQvpvA47q2XxjM
++qxJVf/FvZm2ftiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkY
++tM/Bo1AwTjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFCUZxhtiiFordL5cZ6oJ
++OLgssd4tMB0GA1UdEQQWMBSGEmh0dHBzOi8vbm9kZWpzLm9yZzAKBggqhkjOPQQD
++AgNIADBFAiEArZgaxFBuPYFWCXeFTkXhV57MKxG/tIJ2Z3Wzts2Im7QCICoukuRf
++EsQN7g6h30fRuLOIdbfCCduc7YVpkkSlwe99
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/google/leaf4.pem 
b/test/fixtures/x509-escaping/google/leaf4.pem
+new file mode 100644
+index 0000000000..668a659f45
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/leaf4.pem
+@@ -0,0 +1,10 @@
++-----BEGIN CERTIFICATE-----
++MIIBdTCCARugAwIBAgIBBzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxJbnRlcm1l
++ZGlhdGUwIBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMDwxHzAdBgNV
++BAsMFm9yZyB1bml0CkNOPW5vZGVqcy5vcmcxGTAXBgNVBAMTEGF0dGFja2VyLmV4
++YW1wbGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR7DaOQvpvA47q2XxjMqxJV
++f/FvZm2ftiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkYtM/B
++ozEwLzAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFCUZxhtiiFordL5cZ6oJOLgs
++sd4tMAoGCCqGSM49BAMCA0gAMEUCIQCpchwik2NT0v8ifDT8aMqOLv5YwqB7oeOu
++LincYQYMagIgZc2U7DBrdEAWNfuAJx4I+ZkluIcswcdnOhbriOrTSHg=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/google/root.pem 
b/test/fixtures/x509-escaping/google/root.pem
+new file mode 100644
+index 0000000000..68eb00ae86
+--- /dev/null
++++ b/test/fixtures/x509-escaping/google/root.pem
+@@ -0,0 +1,9 @@
++-----BEGIN CERTIFICATE-----
++MIIBQTCB56ADAgECAgEBMAoGCCqGSM49BAMCMA8xDTALBgNVBAMTBFJvb3QwIBcN
++MDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMA8xDTALBgNVBAMTBFJvb3Qw
++WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR7DaOQvpvA47q2XxjMqxJVf/FvZm2f
++tiFRXNJMe/fhSlDh2CybdkFIw2mE5g4ShW5UBJe+sohqy5V9WRkYtM/BozIwMDAP
++BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQlGcYbYohaK3S+XGeqCTi4LLHeLTAK
++BggqhkjOPQQDAgNJADBGAiEA+Y5oEpcG6aRK5qQFLYRi2FrOSSLF1/dI4HtBh0mk
++GFoCIQD1DpNg6m5ZaogRW1mY1wmR5HFIr3gG8PYDRimQogXUxg==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/info-0-cert.pem 
b/test/fixtures/x509-escaping/info-0-cert.pem
+new file mode 100644
+index 0000000000..6872b9870a
+--- /dev/null
++++ b/test/fixtures/x509-escaping/info-0-cert.pem
+@@ -0,0 +1,30 @@
++-----BEGIN CERTIFICATE-----
++MIIFDTCCAvWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++XDBaMFgGCCsGAQUFBwEBBEwwSjBIBggrBgEFBQcwAYY8aHR0cDovL2dvb2QuZXhh
++bXBsZS5jb20vCk9DU1AgLSBVUkk6aHR0cDovL2V2aWwuZXhhbXBsZS5jb20vMA0G
++CSqGSIb3DQEBCwUAA4ICAQAAd/bIBmSIOJg+Rp96/BDpsZQYgYTyBNWrnBkuHQ0M
++bovgqEEI/5xiYGEzXhrzmWrUoG40PDeVrpCSsW5m+bsO4zDQeWW5mXejbr0Iwflf
++TYDxwGUUakAcZ1c5yJ/ABjKy0Tocb9bSzln+tc+HNStp86bbgrhb/wjddn6ca21V
++cuNFZbN+0SM0LxcWO8oGKXF0HFo0durGhamcH5B/D38FYkaVR5QXoOsWVqtPFjW2
++t67rmKS6XKaz2JhZDpWDZmDofCoFu/zlkPHXkq7yyrkJ/8qpJCznkZmLn+B1WA+y
++SrSOYMpQ6RnzMx7wK5UafX5J+lMv16+LTb/n1KAd4zElcqt5eRPLcEuknIEgC2X/
++AY1ooyN/Xb4QnqvtTmhzIDb7lzzMowi5QrG3rRYMldxG2Rdqwjc8qa5Tgh7EsiU8
++A/n5X/6cxA1zoyakSHFXzGtazIkPc+zFfOaV1+gpJtd2vD2T+FrmkL1fgazuHXNZ
++hAQq0RGZWPsCdxm7dG4w5bd3YgRKfD2ck+b9Imu0ta4pqMDHZYgncaeOuuHzHgXA
++MIvxIG5JfwYUJLUqBUz8hwDVcNMpnscyn2msdpiwXK0AahucBQjbyZ6sovoxmgk5
++xLdnq2GTtdghwdkF9DYK0ZekDlk1XWbP0tR5Cevo6WlMx+cbEBG+OSfNd8/dFrkd
++aw==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/info-1-cert.pem 
b/test/fixtures/x509-escaping/info-1-cert.pem
+new file mode 100644
+index 0000000000..05247873d8
+--- /dev/null
++++ b/test/fixtures/x509-escaping/info-1-cert.pem
+@@ -0,0 +1,31 @@
++-----BEGIN CERTIFICATE-----
++MIIFVTCCAz2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++gaMwgaAwgZ0GCCsGAQUFBwEBBIGQMIGNMEUGCCsGAQUFBzAChjlodHRwOi8vY2Eu
++ZXhhbXBsZS5jb20vCk9DU1AgLSBVUkk6aHR0cDovL2V2aWwuZXhhbXBsZS5jb20w
++RAYIKwYBBQUHMAGCOGdvb2QuZXhhbXBsZS5jb20KT0NTUCAtIFVSSTpodHRwOi8v
++Y2Eubm9kZWpzLm9yZy9jYS5jZXJ0MA0GCSqGSIb3DQEBCwUAA4ICAQCbwqw8YKIt
++Ht9qegR076xpnxuiH0THPGsgazvhCmEr5YHJ68sR1LexjneQDhpNXcnpYpfk6J4d
++Tu0ApMSbVypFyHcd88g0qVYI9JF+CTNnzut/Zn6xgnUjVjrSz6SZPhkMcBX9ahtY
++tzswzcyTzso5Do5pxvCWDI+bshgIhC3CYNyAjyOyyhnQrwcOcoatlhDmX1fCk+dC
++fhmzurBFNIz2gwDC7aRjcaUdTIlYnd6qHk5xLs3neBm44gNk17GazPIPo04LTKXs
++ZYzvDEUAdJ2FJMiYqSvvEv4k9ozx5HtwtncZpu46El2PQRANgj1UhemYVmHfbdU+
++7Q+rCv+Loq2v76fddhc1cM3gCQ+6SW2QmRo2rShRGxpuSuZiTngwgdQEGrkQq7Sv
++r695V7NlHWJgvv1r49wGmqWkviH5l6A0QdzL6TNYhwqCRsjxgsvCZUpOlZPASiME
++jhwBIOMy1YUSdEMnBrbuemawvbfocSuUlHaodwLZvwMgqHvNz/8ebMyRyyZrnmCx
++TYh8d0JIcA57VvfaZvvsPPV7TO7WLoJgbmuqM02JzzkJMh0fbt2oi1cqJL65V5Sn
++z0sXh/A/BzB4QawI93f9m0hX7RtuT1SolTNVyhg7dm1MwfO8khpfz5LLgflVwgN8
++6egKc6L755SlqZRMT03txH2UCBizLz1gjA==
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/info-2-cert.pem 
b/test/fixtures/x509-escaping/info-2-cert.pem
+new file mode 100644
+index 0000000000..06212d4e12
+--- /dev/null
++++ b/test/fixtures/x509-escaping/info-2-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE5DCCAsygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++MzAxMC8GCCsGAQUFBwEBBCMwITAfBgUrzg8MIoYWaHR0cDovL2NhLmV4YW1wbGUu
++Y29tLzANBgkqhkiG9w0BAQsFAAOCAgEABR5VyTZEQ0AQvdqlk+IDQT85qyf891eN
++BREiSg5KCei9Kmubv3ZJGoNVwZgybr5sCi5GqWOtG7S0GXvzS6c2Qy+cW0R4DDYs
++s6IIUn+ex1XygGrRHTDHu6tEUwSJMmOMKBh+iLjhtamD+YHjgOLG3MfadO5/9mvp
++r412MPhU1VvQ3FC3dZmBUW2gIKNEU4mzwISgPkLJXmBsnxu8F9YqHPgppqsfJ9AF
++KIc2nX7N3s8w9fCc03FrihdkE2C802jy71px5aPqa1xrIT/YBq/1fKTcYRAWF/pd
++iy2G1v0pz0kYu2/yPIC/xlFcUgeFqR/biwxAD9T9rp7rq+dpIJA5BUCpXVULqhY1
++SVZ22WKS0NR5rbu4BPDMShTOiwaDSwFQtI0OxM0g5zVFVjFOc6YbFu7ZyfLQ582S
++vgVU5/vaHANnEsCSUegXyLofqxTMPbM1rqibFmv2A4pm1Mp18ZFmqwh8cm6C0f7F
++qjdzBuSkcktTCq/dLX5yTm9aocyzye9cfNBjiGUregJEF7sD3nzsokEGj+S320w2
++5yUl95xgrHr+5bdDUEox+trTeBnddC4VxrieeH+Wv45try0Go48yK7b1Aqfu9G4B
++B/as+upQ+YjMG8mAe6JJ9JibpTvTmatYAsssEKT1vDZ5trqo4C5/utfbuyaf7qtx
++O+jFfYToPtE=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/info-3-cert.pem 
b/test/fixtures/x509-escaping/info-3-cert.pem
+new file mode 100644
+index 0000000000..1825949bd3
+--- /dev/null
++++ b/test/fixtures/x509-escaping/info-3-cert.pem
+@@ -0,0 +1,30 @@
++-----BEGIN CERTIFICATE-----
++MIIFMDCCAxigAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++fzB9MHsGCCsGAQUFBwEBBG8wbTAqBggrBgEFBQcwAaAeBggrBgEFBQcIBaASDBBn
++b29kLmV4YW1wbGUuY29tMB0GCCsGAQUFBzABoBEGBSvODwwioAgMBmFiYzEyMzAg
++BggrBgEFBQcwAaAUBggrBgEFBQcIB6AIFgZhYmMxMjMwDQYJKoZIhvcNAQELBQAD
++ggIBACR9nH4pRlcSIIF9DEExlJvLtkeFWHGIAYLBuauHmdzPdbq9Py9M5DOcc7yd
++OQYVYwW26hASb+3CYzhRQaWKOR+T/OwP+QMUl5Y6nc3HzLdYTSen2LLAYHySXK3G
++gTdOhmVQwdh+IzhpjLXC67/9gn/F1p73Ixv/0PBZzmC64DOp1ogso9RICu0xTAbo
++h8mdN4/Tbh9Ikd89lb91x1Xf86NyC7ZvSA9dUO07/3B6B0kkqCdP9Ytlsrt2wbt3
++2TVPp+ghjbPjdLrJUi3fbdC2CgjV2oLiYr1h7qn7SmYPNgOpDPKBI4Cei7UO+Wow
++yLCxBO0HgLZKcZorJFofekPjqtQYYj1sw3OEIcifMAmoHT7H57onfoQbRDpt57k2
++rHJKgzrRuT8Qbl3OHSkiWRE3u0S9kAg7QEq27e2fuvh23p+YHEiYIjAR9XLVh7/Q
++EG5QDfDq3MvtgD/khAd36il61T5h8F4u3MhONFMuwJ/TYtGR6QINrv4DqLBM1pRr
++LMApQYi0w/MCRj2wLeAro9NflE+PFDk+l44ojvnEUYAGUyIzWp80bjQrV7Up6sgQ
++HehcmxxTrOmiqrfw08c1aHhmGeplmPpQEET1wIjnyj49sfdSPYxg5Lh+f/l79fLb
++jFemE8otKfog84vNGbPFl/AHwxjKCeCA/MaNJz3y3RYVsZn6
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/info-4-cert.pem 
b/test/fixtures/x509-escaping/info-4-cert.pem
+new file mode 100644
+index 0000000000..8f1e69afec
+--- /dev/null
++++ b/test/fixtures/x509-escaping/info-4-cert.pem
+@@ -0,0 +1,29 @@
++-----BEGIN CERTIFICATE-----
++MIIE9jCCAt6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBldmls
++LmV4YW1wbGUuY29tMB4XDTIxMTIyMDE0NTczNVoXDTMxMTIxODE0NTczNVowGzEZ
++MBcGA1UEAxMQZXZpbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
++ADCCAgoCggIBALERZ3TS70T1P+SjpZwIqOFnu2Od9XKWcDszQQc7C92K+APjp4Bv
++WiayictqCJWtmsbsSli4yG3P6Ddi/V3Se8W+/yB71Qh2c3wQNMPMukncps2odRGt
++qJe4EOpret1jgkFqQJy5geXVuPU5N7DvGXUVZzWN7TisFNAZMUhF2YlljJz1sjD1
++aRjqayh3TDU8NwuFlLd6aH95hovjMBBatWFB9bN/itnMVoj9rmfSjvlpSRO6/EMN
++DnVXZ3paRJTcps6d/Ylb5Ald/Ow056JgD0Cd9jn16+vgYR4bxVl0a5Qbf24MIhaY
++BRPx6WFdepWr410GpzpVQ0sMluoKYzH8RynjwQc7pfm5ebTFWJkhU80jOqKJGFW3
++icV/A9BmtOBqrb60Pv/MPXIQPg7UWGUOXm3AfY3v6gbToewSW5B0s+uPsh52md4Z
++UoyzTvwN2i/uPqJxi/9FkdV60OWvMMMeMslbDHIBbN0Z2SG0wY93oH2LhO0X89Tc
++nedukufld8QEW7iMn7D7la+TlrrSAXURHL84sEz97yyujawQEimnW03XAlUFk61M
++iLhVUOHANFBSLBvZ3VF7sZDv6ZzPkP/TWrFbpL7DQgqunAlSNHealrQ5T3wp8pUm
++R7J4QEuQSEN2cZMOpn0T+JyQaiytbaAABgqDNeTvbl2nFN2ksSix8NunAgMBAAGj
++RTBDMEEGCCsGAQUFBwEBBDUwMzAxBggrBgEFBQcwAaAlBggrBgEFBQcIBaAZDBdn
++b29kLmV4YW1wbGUuY29tAGFiYzEyMzANBgkqhkiG9w0BAQsFAAOCAgEAQERLvjQB
++E2fmTVgHbr4MVXPfse9Xxk9TK8/IhxDNnql4bor3xat5oP+tDHVRi2StajfIcJlX
++C9blYOWg4w6QH3pmD6M7eQGOw7ntOUid4R2vhX3XiK3QB1h8lWSPFmSwBHA47mMJ
++IkrKNIo9+M9b7M05YwbAENi3TPgT8h2Ej9V4DUjLIEhDcu8fSh3FkNpZ2HohZ2I3
++QPe23FB052jX7uPfeZ9gcjL/iGxuTuPbKWxzZ/Gy2RmS8xfLkJESvvQ8a0H4f7Ij
++yjn7qYUkY6FoHxyg5BU34YNaJCmfgzRIE53Kv2FMPwj2JaXmIguR+mSDAbc0xjw3
++G3dRoCqhZugn8C6I5FhuXHdu6zSuuHtwOGEf07y5Im2sBsPVoq+Txh/mv3Zy9Ydy
++0yCDuq87jKSZd7FKorHOEoQY94UMs33PYjS4h/hYWiysYUeR0mlbjr4gyv1KH6K8
++JERGpI/OE+vzfOtgj/Z46/+wn7jF0LBCin7Jn5Zw1a1TNsiHKAjqW/P4vJxxUW++
++FtYwJhI7XJehwNNFra9rSC5M4TkpaqAZnbPvWZWxWVJIEYFgNjnt+b/VOpRpv5bJ
++7BOlVvP+56KF+vlmCnzVBmlHcr45sZUZ3mw3Sb6dcF0V0VaNQKw/F5EteQyafIIl
++dvCwwV4OwLwPliPAvwYfVEI41Dv3mF4fN7k=
++-----END CERTIFICATE-----
+diff --git a/test/fixtures/x509-escaping/package.json 
b/test/fixtures/x509-escaping/package.json
+new file mode 100644
+index 0000000000..37d9f2a938
+--- /dev/null
++++ b/test/fixtures/x509-escaping/package.json
+@@ -0,0 +1,12 @@
++{
++  "name": "x509-escaping",
++  "version": "1.0.0",
++  "description": "create certificates for x509-escaping test",
++  "main": "createCert.js",
++  "license": "SEE LICENSE IN ../../../LICENSE",
++  "private": true,
++  "dependencies": {
++    "asn1.js": "^5.4.1",
++    "asn1.js-rfc5280": "^3.0.0"
++  }
++}
+diff --git a/test/fixtures/x509-escaping/server-key.pem 
b/test/fixtures/x509-escaping/server-key.pem
+new file mode 100644
+index 0000000000..db1d2652d0
+--- /dev/null
++++ b/test/fixtures/x509-escaping/server-key.pem
+@@ -0,0 +1,52 @@
++-----BEGIN PRIVATE KEY-----
++MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCxEWd00u9E9T/k
++o6WcCKjhZ7tjnfVylnA7M0EHOwvdivgD46eAb1omsonLagiVrZrG7EpYuMhtz+g3
++Yv1d0nvFvv8ge9UIdnN8EDTDzLpJ3KbNqHURraiXuBDqa3rdY4JBakCcuYHl1bj1
++OTew7xl1FWc1je04rBTQGTFIRdmJZYyc9bIw9WkY6msod0w1PDcLhZS3emh/eYaL
++4zAQWrVhQfWzf4rZzFaI/a5n0o75aUkTuvxDDQ51V2d6WkSU3KbOnf2JW+QJXfzs
++NOeiYA9AnfY59evr4GEeG8VZdGuUG39uDCIWmAUT8elhXXqVq+NdBqc6VUNLDJbq
++CmMx/Ecp48EHO6X5uXm0xViZIVPNIzqiiRhVt4nFfwPQZrTgaq2+tD7/zD1yED4O
++1FhlDl5twH2N7+oG06HsEluQdLPrj7IedpneGVKMs078Ddov7j6icYv/RZHVetDl
++rzDDHjLJWwxyAWzdGdkhtMGPd6B9i4TtF/PU3J3nbpLn5XfEBFu4jJ+w+5Wvk5a6
++0gF1ERy/OLBM/e8sro2sEBIpp1tN1wJVBZOtTIi4VVDhwDRQUiwb2d1Re7GQ7+mc
++z5D/01qxW6S+w0IKrpwJUjR3mpa0OU98KfKVJkeyeEBLkEhDdnGTDqZ9E/ickGos
++rW2gAAYKgzXk725dpxTdpLEosfDbpwIDAQABAoICAAwUElkTPHQZQKsBiL38jzyU
++/WDduQ0AexZmuCRcoEIUBTgKsvXdYqpqGmEwUfaX2YuBOc8Uh8OJ357Ll1nrjjre
++fPvDxrPllJodZuQGVpzMOuqjd5zlmi8DRNAg1cg9TfjVXSPzuYsqiYvcw9JDdRqa
++A6jRDiIEBwVs+oIiFaU8MpvQXL/fNbSX5QhlHuMwwNZ93beoV3F+ojFvpWswLNg+
++DhsY86lIuYxttZRqdgtIZc49PpD6VoalmC7t8mivJofImi9g/8ytxx97umNGpzOy
++ssWgY1/7NdS+czdXbDE1sPsaQ8cDxrDmGxPjswV7rK4/Um/1ufnoGXFMlRinS1lQ
++nns4VAFefVUCk81LRyFb+X97NXPGC1p4zNlC1ZoihMgWKJBzH0uk5K/hURS/wDNZ
++epm9ssnEQrFGJhEI+635srfn9SVRZ8xNh+oCguo5NaZm/BezC6iBQeoaBmVL2lY8
++KLztN/JQd6MMZi3CWhTn0ZAtVNMxGjU9/yrdWIkX9EV8Sw68fqLGoKQXI67AOynQ
++5AnUyEjhVu7M39gYL71l7BVpuG7qaX8l4brzBcgzFldvuhuNCx0SW4gU2/Nx4OwY
++BLOX1LOrpD+5M9YwcbtSxcxz97nP8efb3hUK3QD2iuZ9Fa6zKWsoreMb7Jku38i7
++e41lupAIkxxuxGBe1YrZAoIBAQDVF7Kru6tsaWtvJw5cbZpKxcuUHHQ0X3XRgA+H
++uWfT8EbxmDpgcG8polqiYuXPFWcrElmtWeBCYXazGZocHRV8y+ri/9c2rMTH6Bni
++TcYfsc4E8WY6adxfUqajgQ2zShdZbxZtBvSP50HheZ0a+L2qn2MWDUN/mbwYEmom
++SonVx3MSJWm/Vrh5i4b/L/+9u7uumIjWYFK6pKdLerTfbXO7ZsNR9KDIOBLDnUcf
+++6K2vcclZN7aga1S7wTsrX+k9C/OQuj8ONMWQHCxryp5RAmgtArTBrJZq8el1lcG
++518Vo4QuOqsqTdAhqiImoPKe4NNCs1iTS9BdCqNYiF8sbmeJAoIBAQDUuL5ebQ68
++6vqTKYD47ZtCzeqziN3Y/0a1BsyZh0/snNmK5WIr4T0vX0Y/XG0EpkZdpW3odMBv
++CemKs6Zm+pfOUGu20PTJcdSOXRbFiVYSeQnfa0l3iXZvY9Ottz/IU/mWPuU3hc18
++hOZD9tKiwYDzZREg6L4XRizfT70UkD2eTz4lGBjR092TTj8WqSaI9GF6d9B6Aw9Y
++OCZdTqV7hPe0Rnvd1XiGsk68HN2Np47HHwwPsKMCYj8YNKmsUF8QSXmCkijlDeJW
++bC6TjAHlvnN6n1LjaLwULUs9Rb2fkNUOqsgR+T8YlqbclJbzC7gW53M/68c9eOQ1
++Y01JnzsB3S2vAoIBAQDT8DP2djtzIg6GiNPRvfj9cWifMQWqqV8nNTU9Cnxn4MzO
++sVcuX+VQBXgblj13D5SC1Ed5ELDplMJYM5iBabPbYX2GtGq6qG83XHOSD0SEdXWw
++mN/SLUPPUwcGC+8yaPh8LO6jFY3cKmft9+T31Hnf35LPdfWyTZc0YexNlUkt5Kdg
++XvGkKn5j9RAZcwXrEXMDnhZLEZZ2qBj0C2El71hyBS0ysBnRyWNwR1dcSgx1sJ8H
++ZCH6NYvLtoqxU4Zm6684eHf9lA7uTL1JHC0kWzUwLqGtbTWp1h5FpL790NVTUkS/
++Lf7bnnTpZqt8vAtTVc0IxBPOvFLKlzALd+cg69XxAoIBAQCv6Sbkh2NMrzUQRZ42
++PKfMkuSoG2L6dABQ65J+0/swPHVZ+1830kf6yNsawqAU3DwMbSV6ujH4oUXUQcQ2
++HL01DCRHRn1nqQ6RvEF8kZnwJNAZRmu2wqKCcxc17Ph9/ZPEv7ZmN+w6MN0LDy4Z
++EdRFcyq7AD1SmeG5ugMu4ilSpU1K96ZuvrnZezeI0dDgKNgDotlwTN9/oM95EfSf
++NNJy7ma4iDPnj8S0o1pELnBQEkizIOtsqTpsFgDKUpyKp3golh3jbZvixAuwUHOx
++PdHZca/mB1KhjONPhEDPl8HZIznYQzn+Z3cNqoM58lMF/di834ogN7zguYHMhDUT
++0YhZAoIBAHlYhuni+gyrn4tyZgep68VXW7wQxSvgSj8cpZAuT/w0UKAU53J5QTWZ
++aGHeICXvgvpalUL+2dGwASlOvPa52ekcOPd2+qKWyss0zA4ksI7mNE2vjFUcOr+S
++n9QSNvu3E8dYAjzSIsizcQbPTlk6A/TmytNJ4x67ZVGCmKXw1ZzzSrxSbAIdY254
++TxSGchrfcy0ofXIL2HXq16FRmesORTJFkkyQaldzn4y7S6HJ/vGppImTfeac1MwG
++jLYljIkIbt+nB1c8HeNvARmBa6M2pxB9f72oRMVqFdUUc5AxXuWP9v6xk227EuCq
++TBORAafu9WxKVwUsHa1rE1uGgNEfRJ8=
++-----END PRIVATE KEY-----
+diff --git a/test/parallel/test-tls-0-dns-altname.js 
b/test/parallel/test-tls-0-dns-altname.js
+index 4bc87e44cb..e5cb8e3d48 100644
+--- a/test/parallel/test-tls-0-dns-altname.js
++++ b/test/parallel/test-tls-0-dns-altname.js
+@@ -44,7 +44,7 @@ const server = tls.createServer({
+   }, common.mustCall(() => {
+     const cert = c.getPeerCertificate();
+     assert.strictEqual(cert.subjectaltname,
+-                       'DNS:good.example.org\0.evil.example.com, ' +
++                       'DNS:"good.example.org\\u0000.evil.example.com", ' +
+                            'DNS:just-another.example.com, ' +
+                            'IP Address:8.8.8.8, ' +
+                            'IP Address:8.8.4.4, ' +
+diff --git a/test/parallel/test-x509-escaping.js 
b/test/parallel/test-x509-escaping.js
+new file mode 100644
+index 0000000000..4e0f82767d
+--- /dev/null
++++ b/test/parallel/test-x509-escaping.js
+@@ -0,0 +1,349 @@
++'use strict';
++
++const common = require('../common');
++if (!common.hasCrypto)
++  common.skip('missing crypto');
++
++const assert = require('assert');
++const tls = require('tls');
++const fixtures = require('../common/fixtures');
++
++const { hasOpenSSL3 } = common;
++
++// Test that all certificate chains provided by the reporter are rejected.
++{
++  const rootPEM = fixtures.readSync('x509-escaping/google/root.pem');
++  const intermPEM = 
fixtures.readSync('x509-escaping/google/intermediate.pem');
++  const keyPEM = fixtures.readSync('x509-escaping/google/key.pem');
++
++  const numLeaves = 5;
++
++  for (let i = 0; i < numLeaves; i++) {
++    // TODO(tniessen): this test case requires proper handling of URI SANs,
++    // which node currently does not implement.
++    if (i === 3) continue;
++
++    const name = `x509-escaping/google/leaf${i}.pem`;
++    const leafPEM = fixtures.readSync(name, 'utf8');
++
++    const server = tls.createServer({
++      key: keyPEM,
++      cert: leafPEM + intermPEM,
++    }, common.mustNotCall()).listen(common.mustCall(() => {
++      const { port } = server.address();
++      const socket = tls.connect(port, {
++        ca: rootPEM,
++        servername: 'nodejs.org',
++      }, common.mustNotCall());
++      socket.on('error', common.mustCall());
++    })).unref();
++  }
++}
++
++// Test escaping rules for subject alternative names.
++{
++  const expectedSANs = [
++    'DNS:"good.example.com\\u002c DNS:evil.example.com"',
++    // URIs should not require escaping.
++    'URI:http://example.com/',
++    'URI:http://example.com/?a=b&c=d',
++    // Unless they contain commas.
++    'URI:"http://example.com/a\\u002cb";',
++    // Percent encoding should not require escaping.
++    'URI:http://example.com/a%2Cb',
++    // Malicious attempts should be escaped.
++    'URI:"http://example.com/a\\u002c DNS:good.example.com"',
++    // Non-ASCII characters in DNS names should be treated as Latin-1.
++    'DNS:"ex\\u00e4mple.com"',
++    // It should not be possible to cause unescaping without escaping.
++    'DNS:"\\"evil.example.com\\""',
++    // IPv4 addresses should be represented as usual.
++    'IP Address:8.8.8.8',
++    'IP Address:8.8.4.4',
++    // For backward-compatibility, include invalid IP address lengths.
++    hasOpenSSL3 ? 'IP Address:<invalid length=5>' : 'IP Address:<invalid>',
++    hasOpenSSL3 ? 'IP Address:<invalid length=6>' : 'IP Address:<invalid>',
++    // IPv6 addresses are represented as OpenSSL does.
++    'IP Address:A0B:C0D:E0F:0:0:0:7A7B:7C7D',
++    // Regular email addresses don't require escaping.
++    'email:[email protected]',
++    // ... but should be escaped if they contain commas.
++    'email:"[email protected]\\u002c DNS:good.example.com"',
++    'DirName:/C=DE/L=Hannover',
++    // TODO(tniessen): support UTF8 in DirName
++    'DirName:"/C=DE/L=M\\\\xC3\\\\xBCnchen"',
++    'DirName:"/C=DE/L=Berlin\\u002c DNS:good.example.com"',
++    'DirName:"/C=DE/L=Berlin\\u002c DNS:good.example.com\\\\x00' +
++      'evil.example.com"',
++    'DirName:"/C=DE/L=Berlin\\u002c DNS:good.example.com\\\\\\\\x00' +
++      'evil.example.com"',
++    // These next two tests might be surprising. OpenSSL applies its own rules
++    // first, which introduce backslashes, which activate node's escaping.
++    // Unfortunately, there are also differences between OpenSSL 1.1.1 and 
3.0.
++    'DirName:"/C=DE/L=Berlin\\\\x0D\\\\x0A"',
++    hasOpenSSL3 ?
++      'DirName:"/C=DE/L=Berlin\\\\/CN=good.example.com"' :
++      'DirName:/C=DE/L=Berlin/CN=good.example.com',
++    // TODO(tniessen): even OIDs that are well-known (such as the following,
++    // which is sha256WithRSAEncryption) should be represented numerically 
only.
++    'Registered ID:sha256WithRSAEncryption',
++    // This is an OID that will likely never be assigned to anything, thus
++    // OpenSSL should not know it.
++    'Registered ID:1.3.9999.12.34',
++    hasOpenSSL3 ?
++      'othername: XmppAddr::abc123' :
++      'othername:<unsupported>',
++    hasOpenSSL3 ?
++      'othername:" XmppAddr::abc123\\u002c DNS:good.example.com"' :
++      'othername:<unsupported>',
++    hasOpenSSL3 ?
++      'othername:" XmppAddr::good.example.com\\u0000abc123"' :
++      'othername:<unsupported>',
++    // This is unsupported because the OID is not recognized.
++    'othername:<unsupported>',
++    hasOpenSSL3 ? 'othername: SRVName::abc123' : 'othername:<unsupported>',
++    // This is unsupported because it is an SRVName with a UTF8String value,
++    // which is not allowed for SRVName.
++    'othername:<unsupported>',
++    hasOpenSSL3 ?
++      'othername:" SRVName::abc\\u0000def"' :
++      'othername:<unsupported>',
++  ];
++
++  const serverKey = fixtures.readSync('x509-escaping/server-key.pem', 'utf8');
++
++  for (let i = 0; i < expectedSANs.length; i++) {
++    const pem = fixtures.readSync(`x509-escaping/alt-${i}-cert.pem`, 'utf8');
++
++    // X509Certificate interface is not supported in v12.x & v14.x. Disable
++    // checks for subjectAltName with expectedSANs. The testcase is ported
++    // from v17.x
++    //
++    // Test the subjectAltName property of the X509Certificate API.
++    // const cert = new X509Certificate(pem);
++    // assert.strictEqual(cert.subjectAltName, expectedSANs[i]);
++
++    // Test that the certificate obtained by checkServerIdentity has the 
correct
++    // subjectaltname property.
++    const server = tls.createServer({
++      key: serverKey,
++      cert: pem,
++    }, common.mustCall((conn) => {
++      conn.destroy();
++      server.close();
++    })).listen(common.mustCall(() => {
++      const { port } = server.address();
++      tls.connect(port, {
++        ca: pem,
++        servername: 'example.com',
++        checkServerIdentity: (hostname, peerCert) => {
++          assert.strictEqual(hostname, 'example.com');
++          assert.strictEqual(peerCert.subjectaltname, expectedSANs[i]);
++        },
++      }, common.mustCall());
++    }));
++  }
++}
++
++// Test escaping rules for authority info access.
++{
++  const expectedInfoAccess = [
++    {
++      text: 'OCSP - URI:"http://good.example.com/\\u000a' +
++            'OCSP - URI:http://evil.example.com/";',
++      legacy: {
++        'OCSP - URI': [
++          'http://good.example.com/\nOCSP - URI:http://evil.example.com/',
++        ],
++      },
++    },
++    {
++      text: 'CA Issuers - URI:"http://ca.example.com/\\u000a' +
++            'OCSP - URI:http://evil.example.com"\n' +
++            'OCSP - DNS:"good.example.com\\u000a' +
++            'OCSP - URI:http://ca.nodejs.org/ca.cert";',
++      legacy: {
++        'CA Issuers - URI': [
++          'http://ca.example.com/\nOCSP - URI:http://evil.example.com',
++        ],
++        'OCSP - DNS': [
++          'good.example.com\nOCSP - URI:http://ca.nodejs.org/ca.cert',
++        ],
++      },
++    },
++    {
++      text: '1.3.9999.12.34 - URI:http://ca.example.com/',
++      legacy: {
++        '1.3.9999.12.34 - URI': [
++          'http://ca.example.com/',
++        ],
++      },
++    },
++    hasOpenSSL3 ? {
++      text: 'OCSP - othername: XmppAddr::good.example.com\n' +
++            'OCSP - othername:<unsupported>\n' +
++            'OCSP - othername: SRVName::abc123',
++      legacy: {
++        'OCSP - othername': [
++          ' XmppAddr::good.example.com',
++          '<unsupported>',
++          ' SRVName::abc123',
++        ],
++      },
++    } : {
++      text: 'OCSP - othername:<unsupported>\n' +
++            'OCSP - othername:<unsupported>\n' +
++            'OCSP - othername:<unsupported>',
++      legacy: {
++        'OCSP - othername': [
++          '<unsupported>',
++          '<unsupported>',
++          '<unsupported>',
++        ],
++      },
++    },
++    hasOpenSSL3 ? {
++      text: 'OCSP - othername:" XmppAddr::good.example.com\\u0000abc123"',
++      legacy: {
++        'OCSP - othername': [
++          ' XmppAddr::good.example.com\0abc123',
++        ],
++      },
++    } : {
++      text: 'OCSP - othername:<unsupported>',
++      legacy: {
++        'OCSP - othername': [
++          '<unsupported>',
++        ],
++      },
++    },
++  ];
++
++  const serverKey = fixtures.readSync('x509-escaping/server-key.pem', 'utf8');
++
++  for (let i = 0; i < expectedInfoAccess.length; i++) {
++    const pem = fixtures.readSync(`x509-escaping/info-${i}-cert.pem`, 'utf8');
++    const expected = expectedInfoAccess[i];
++
++    // X509Certificate interface is not supported in v12.x & v14.x. Disable
++    // checks for cert.infoAccess with expected text. The testcase is ported
++    // from v17.x
++    // Test the subjectAltName property of the X509Certificate API.
++    // const cert = new X509Certificate(pem);
++    // assert.strictEqual(cert.infoAccess,
++    //                   `${expected.text}${hasOpenSSL3 ? '' : '\n'}`);
++
++    // Test that the certificate obtained by checkServerIdentity has the 
correct
++    // subjectaltname property.
++    const server = tls.createServer({
++      key: serverKey,
++      cert: pem,
++    }, common.mustCall((conn) => {
++      conn.destroy();
++      server.close();
++    })).listen(common.mustCall(() => {
++      const { port } = server.address();
++      tls.connect(port, {
++        ca: pem,
++        servername: 'example.com',
++        checkServerIdentity: (hostname, peerCert) => {
++          assert.strictEqual(hostname, 'example.com');
++          assert.deepStrictEqual(peerCert.infoAccess,
++                                 Object.assign(Object.create(null),
++                                               expected.legacy));
++        },
++      }, common.mustCall());
++    }));
++  }
++}
++
++// The internal parsing logic must match the JSON specification exactly.
++{
++  // This list is partially based on V8's own JSON tests.
++  const invalidJSON = [
++    '"\\a invalid escape"',
++    '"\\v invalid escape"',
++    '"\\\' invalid escape"',
++    '"\\x42 invalid escape"',
++    '"\\u202 invalid escape"',
++    '"\\012 invalid escape"',
++    '"Unterminated string',
++    '"Unterminated string\\"',
++    '"Unterminated string\\\\\\"',
++    '"\u0000 control character"',
++    '"\u001e control character"',
++    '"\u001f control character"',
++  ];
++
++  for (const invalidStringLiteral of invalidJSON) {
++    // Usually, checkServerIdentity returns an error upon verification 
failure.
++    // In this case, however, it should throw an error since this is not a
++    // verification error. Node.js itself will never produce invalid JSON 
string
++    // literals, so this can only happen when users construct invalid subject
++    // alternative name strings (that do not follow escaping rules).
++    assert.throws(() => {
++      tls.checkServerIdentity('example.com', {
++        subjectaltname: `DNS:${invalidStringLiteral}`,
++      });
++    }, {
++      code: 'ERR_TLS_CERT_ALTNAME_FORMAT',
++      message: 'Invalid subject alternative name string'
++    });
++  }
++}
++
++// While node does not produce commas within SAN entries, it should parse them
++// correctly (i.e., not simply split at commas).
++{
++  // Regardless of the quotes, splitting this SAN string at commas would
++  // cause checkServerIdentity to see 'DNS:b.example.com' and thus to accept
++  // the certificate for b.example.com.
++  const san = 'DNS:"a.example.com, DNS:b.example.com, DNS:c.example.com"';
++
++  // This is what node used to do, and which is not correct!
++  const hostname = 'b.example.com';
++  assert.strictEqual(san.split(', ')[1], `DNS:${hostname}`);
++
++  // The new implementation should parse the string correctly.
++  const err = tls.checkServerIdentity(hostname, { subjectaltname: san });
++  assert(err);
++  assert.strictEqual(err.code, 'ERR_TLS_CERT_ALTNAME_INVALID');
++  assert.strictEqual(err.message, 'Hostname/IP does not match certificate\'s 
' +
++                                  'altnames: Host: b.example.com. is not in ' 
+
++                                  'the cert\'s altnames: DNS:"a.example.com, 
' +
++                                  'DNS:b.example.com, DNS:c.example.com"');
++}
++
++// The subject MUST be ignored if a dNSName subject alternative name exists.
++{
++  const key = fixtures.readKey('incorrect_san_correct_subject-key.pem');
++  const cert = fixtures.readKey('incorrect_san_correct_subject-cert.pem');
++
++  // The hostname is the CN, but not a SAN entry.
++  const servername = 'good.example.com';
++
++  // X509Certificate interface is not supported in v12.x & v14.x. Disable
++  // checks for certX509.subject and certX509.subjectAltName with expected
++  // value. The testcase is ported from v17.x
++  //
++  // const certX509 = new X509Certificate(cert);
++  // assert.strictEqual(certX509.subject, `CN=${servername}`);
++  // assert.strictEqual(certX509.subjectAltName, 'DNS:evil.example.com');
++
++  // Try connecting to a server that uses the self-signed certificate.
++  const server = tls.createServer({ key, cert }, common.mustNotCall());
++  server.listen(common.mustCall(() => {
++    const { port } = server.address();
++    const socket = tls.connect(port, {
++      ca: cert,
++      servername,
++    }, common.mustNotCall());
++    socket.on('error', common.mustCall((err) => {
++      assert.strictEqual(err.code, 'ERR_TLS_CERT_ALTNAME_INVALID');
++      assert.strictEqual(err.message, 'Hostname/IP does not match ' +
++                                      "certificate's altnames: Host: " +
++                                      "good.example.com. is not in the 
cert's" +
++                                      ' altnames: DNS:evil.example.com');
++    }));
++  })).unref();
++}
+-- 
+2.17.1
+
diff --git a/meta-oe/recipes-devtools/nodejs/nodejs_12.21.0.bb 
b/meta-oe/recipes-devtools/nodejs/nodejs_12.21.0.bb
index b9e382177..00de29d9a 100644
--- a/meta-oe/recipes-devtools/nodejs/nodejs_12.21.0.bb
+++ b/meta-oe/recipes-devtools/nodejs/nodejs_12.21.0.bb
@@ -22,6 +22,7 @@ SRC_URI = "http://nodejs.org/dist/v${PV}/node-v${PV}.tar.xz \
            file://big-endian.patch \
            file://mips-warnings.patch \
            
file://0001-Remove-use-of-register-r7-because-llvm-now-issues-an.patch \
+           file://CVE-2021-44532.patch \
            "
 SRC_URI_append_class-target = " \
            file://0002-Using-native-binaries.patch \
-- 
2.17.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#95233): 
https://lists.openembedded.org/g/openembedded-devel/message/95233
Mute This Topic: https://lists.openembedded.org/mt/88949292/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to