aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRanjitsinh Rathod <ranjitsinh.rathod@kpit.com>2022-08-12 09:42:53 +0200
committerArmin Kuster <akuster808@gmail.com>2022-09-11 13:49:52 -0400
commita1a40c95ebf3b9c593a5b6ab97f08db9901caf42 (patch)
treed0be67e7bd93c7218c25fe96d6c3927811c72ad5
parente5e63be86e247f1e243e4a8aa2be94e09df06c4c (diff)
downloadmeta-openembedded-contrib-a1a40c95ebf3b9c593a5b6ab97f08db9901caf42.tar.gz
nodejs: Upgrade to 12.22.12
As per the below release note, it should be a last release for 12.x stable LTS series. Link: https://github.com/nodejs/node/releases/tag/v12.22.12 Remove CVE-2021-44532 fix as it already available in this release v12.22.12 License-Update: src/gtest additional file in the LICENSE Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
-rw-r--r--meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch3090
-rw-r--r--meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb (renamed from meta-oe/recipes-devtools/nodejs/nodejs_12.22.2.bb)5
2 files changed, 2 insertions, 3093 deletions
diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch
deleted file mode 100644
index dff7fe23a2..0000000000
--- a/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2021-44532.patch
+++ /dev/null
@@ -1,3090 +0,0 @@
-From 19873abfb24dce75ffff042efe76dc5633052677 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <tniessen@tnie.de>
-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 <iit.akshay@gmail.com>
-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 <midawson@redhat.com>
-Reviewed-By: Rich Trott <rtrott@gmail.com>
-
-Upstream-Status: Backport [https://github.com/nodejs/node/commit/19873abfb24dce75ffff042efe76dc5633052677]
-
-CVE: CVE-2021-44532
-
-Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com>
-
----
- 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: 'foo@example.com' },
-+ { type: 'rfc822Name', value: 'foo@example.com, 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:foo@example.com',
-+ // ... but should be escaped if they contain commas.
-+ 'email:"foo@example.com\\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.22.2.bb b/meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb
index 2c7d3b3edd..8dbdd088e9 100644
--- a/meta-oe/recipes-devtools/nodejs/nodejs_12.22.2.bb
+++ b/meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb
@@ -1,7 +1,7 @@
DESCRIPTION = "nodeJS Evented I/O for V8 JavaScript"
HOMEPAGE = "http://nodejs.org"
LICENSE = "MIT & BSD & Artistic-2.0"
-LIC_FILES_CHKSUM = "file://LICENSE;md5=8c66ff8861d9f96076a7cb61e3d75f54"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=93997aa7a45ba0f25f9c61aaab153ab8"
DEPENDS = "openssl"
DEPENDS_append_class-target = " nodejs-native"
@@ -22,12 +22,11 @@ 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 \
"
-SRC_URI[sha256sum] = "7fd805571df106f086f4c45e131efed98bfd62628d9dec96bd62f8c11b0c48dc"
+SRC_URI[sha256sum] = "bc42b7f8495b9bfc7f7850dd180bb02a5bdf139cc232b8c6f02a6967e20714f2"
S = "${WORKDIR}/node-v${PV}"