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: nodejs#36804
Refs: nodejs#41569
  • Loading branch information
tniessen committed Jan 19, 2022
1 parent eda54ba commit e6ba945
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
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/41569
description: The subject option can now be set to `'default'`.
Expand All @@ -2480,7 +2483,7 @@ changes:
* `email` {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 @@ -2490,14 +2493,14 @@ changes:

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 @@ -2506,6 +2509,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 @@ -2514,7 +2520,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 @@ -2530,15 +2536,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
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
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 e6ba945

Please sign in to comment.