Skip to content

Commit

Permalink
crypto: change default check(Host|Email) behavior
Browse files Browse the repository at this point in the history
This changes the default behavior of the X509Certificate functions
checkHost and checkEmail to match the default behavior of OpenSSL's
X509_check_host and X509_check_email functions, respectively, which
is also what RFC 2818 mandates for HTTPS.

Refs: #36804
Refs: #41569

PR-URL: #41600
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
  • Loading branch information
tniessen authored and panva committed Jan 22, 2022
1 parent 5aa4010 commit 18365d8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
28 changes: 17 additions & 11 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -2472,6 +2472,9 @@ added: v15.6.0
<!-- YAML
added: v15.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41600
description: The subject option now defaults to `'default'`.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41599
description: The `wildcards`, `partialWildcards`, `multiLabelWildcards`, and
Expand All @@ -2485,20 +2488,20 @@ changes:
* `email` {string}
* `options` {Object}
* `subject` {string} `'default'`, `'always'`, or `'never'`.
**Default:** `'always'`.
**Default:** `'default'`.
* Returns: {string|undefined} Returns `email` if the certificate matches,
`undefined` if it does not.

Checks whether the certificate matches the given email address.

If the `'subject'` option is undefined or set to `'default'`, the certificate
subject is only considered if the subject alternative name extension either does
not exist or does not contain any email addresses.

If the `'subject'` option is set to `'always'` and if the subject alternative
name extension either does not exist or does not contain a matching email
address, the certificate subject is considered.

If the `'subject'` option is set to `'default'`, the certificate subject is only
considered if the subject alternative name extension either does not exist or
does not contain any email addresses.

If the `'subject'` option is set to `'never'`, the certificate subject is never
considered, even if the certificate contains no subject alternative names.

Expand All @@ -2507,6 +2510,9 @@ considered, even if the certificate contains no subject alternative names.
<!-- YAML
added: v15.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41600
description: The subject option now defaults to `'default'`.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41569
description: The subject option can now be set to `'default'`.
Expand All @@ -2515,7 +2521,7 @@ changes:
* `name` {string}
* `options` {Object}
* `subject` {string} `'default'`, `'always'`, or `'never'`.
**Default:** `'always'`.
**Default:** `'default'`.
* `wildcards` {boolean} **Default:** `true`.
* `partialWildcards` {boolean} **Default:** `true`.
* `multiLabelWildcards` {boolean} **Default:** `false`.
Expand All @@ -2531,15 +2537,15 @@ or it might contain wildcards (e.g., `*.example.com`). Because host name
comparisons are case-insensitive, the returned subject name might also differ
from the given `name` in capitalization.

If the `'subject'` option is undefined or set to `'default'`, the certificate
subject is only considered if the subject alternative name extension either does
not exist or does not contain any DNS names. This behavior is consistent with
[RFC 2818][] ("HTTP Over TLS").

If the `'subject'` option is set to `'always'` and if the subject alternative
name extension either does not exist or does not contain a matching DNS name,
the certificate subject is considered.

If the `'subject'` option is set to `'default'`, the certificate subject is only
considered if the subject alternative name extension either does not exist or
does not contain any DNS names. This behavior is consistent with [RFC 2818][]
("HTTP Over TLS").

If the `'subject'` option is set to `'never'`, the certificate subject is never
considered, even if the certificate contains no subject alternative names.

Expand Down
3 changes: 1 addition & 2 deletions lib/internal/crypto/x509.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ function isX509Certificate(value) {
function getFlags(options = {}) {
validateObject(options, 'options');
const {
// TODO(tniessen): change the default to 'default'
subject = 'always', // Can be 'default', 'always', or 'never'
subject = 'default', // Can be 'default', 'always', or 'never'
wildcards = true,
partialWildcards = true,
multiLabelWildcards = false,
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-x509-escaping.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ const { hasOpenSSL3 } = common;
assert.strictEqual(certX509.subjectAltName, 'DNS:evil.example.com');

// The newer X509Certificate API allows customizing this behavior:
assert.strictEqual(certX509.checkHost(servername), servername);
assert.strictEqual(certX509.checkHost(servername), undefined);
assert.strictEqual(certX509.checkHost(servername, { subject: 'default' }),
undefined);
assert.strictEqual(certX509.checkHost(servername, { subject: 'always' }),
Expand Down

0 comments on commit 18365d8

Please sign in to comment.