-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvements to tls API documentation, batch 1 #9800
Conversation
@nodejs/crypto @nodejs/documentation @silverwind @jasnell |
<!-- YAML | ||
added: v0.3.2 | ||
--> | ||
|
||
* `options` {Object} | ||
* `pfx` {string|Buffer} A string or `Buffer` containing the private key, | ||
certificate and CA certs of the server in PFX or PKCS12 format. (Mutually | ||
exclusive with the `key`, `cert`, and `ca` options.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My tests and reading of code show it not mutually exclusive with key/cert, btw, and it would be quite strange if it was mutually exclusive with ca. I am still extending test suite to confirm this.
dc2d08f
to
a05d3e8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few notes regarding docs.
[`tls.TLSSocket`]s. | ||
|
||
Consult | ||
<https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT> for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use a square bracket link here and move the actual link to the bottom?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, maybe In a follow on commit, because this style of link to openssl docs is pervasive here and in crypto.md, I can change them all in one go.
cb(); | ||
}); | ||
server.on('resumeSession', (id, cb) => { | ||
cb(null, tlsSessionStore[id.toString('hex')] || null); | ||
cb(null, tlsSessionStore[id.tostring('hex')] || null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A mistake?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. I was staring and staring at this, but I didn't see the case change. Now I do.
* `ca`{string|string[]|Buffer|Buffer[]} Optional CA certificates to trust. | ||
Default is the well-known CAs from Mozilla. When connecting to peers that | ||
use certificates issued privately, or self-signed, the private root CA or | ||
self-signed certificate must be provided to verify the peer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a word that it will replace default CAs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that how all default values work? The default is used when you don't specify the option. If you specify the option, the default isn't used.
I can spell it out if necessary, but the other Optional x. Default is y.
I think the old text used to be confusing, which is why some people thought it could possibly be additive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, meant to write: but the other Optional x. Default is y.
don't spell out that x replaces y if you specify it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, you have a point. It's probably okay your way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do feel there is a missing section describing the basic authentication model of TLS, which will make all the buttons and dials more clear. Also, the examples are terrible, but I ran out of time. Maybe on the plane next week I'll rewrite them.
* `honorCipherOrder` {boolean} Attempt to use the server's cipher suite | ||
preferences instead of the client's. When `true`, causes | ||
`SSL_OP_CIPHER_SERVER_PREFERENCE` to be set in `secureOptions`, see | ||
[OpenSSL Options][] for more information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defaults to true
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you read the Note below? It doesn't default to true if you do new tls.TLSSocket({isServer: true, ...})
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cf.
Line 917 in 1f45d7a
this.honorCipherOrder = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I follow. What influence does isServer
have over honorCipherOrder
? The linked code seems pretty clear that it is true
unless user-provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment two above. The linked code is in tls.createServer()
, that code isn't run when calling new tls.TLSSocket()
(server or client variant), and of course not when calling tls.connect()
, not that it would matter in that case, its a server only option.
Clearly you are finding this confusing, though, and the docs shouldn't be confusing. Any suggestions for making it clear that its true by default when using tls.createServer()
, but not when using new tls.TLSSocket({isServer: true, ...})
? In other words, the common way of making server sockets had a default value, but the other supported and documented way of making them does not set it?
I thought I said that pretty explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I see it now. I'd argue that it should be the default for all servers, at least that was the intention when I made that change. Should be a pretty low-impact change, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree its odd. In the process of documenting the existing behaviour, I found many odd and irregular aspects of the TLS API, but this PR documents TLS "as is". I definitely encourage you to PR a fix to move the setting of the default out of function Server()
and into _tls_common
where it can apply to all TLS sockets, and be based on the .isServer
property. If you don't, I will. I consider completing the docs to be step 1 to cleaning up the API. In the absence of docs, its hard for reviewers to understand why behaviour is inconsistent and needs to be fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have started a PR to make it default for all servers, FYI, @silverwind, but might not PR it until I'm back from node interactive. Btw, look for me if you are down here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 to that, I'm not too familiar around tls, so I welcome you doing that change. It was certainly an oversight when we flipped that option.
Oh, and I'm unfortunately not attending NI.
[Perfect Forward Secrecy][]. Use `openssl dhparam` to create the parameters. | ||
The key length must be greater than or equal to 1024 bits, otherwise an | ||
error will be thrown. It is strongly recommended to use 2048 bits or larger | ||
for stronger security. If omitted or invalid, the parameters are silently |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adequate security
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll fix the stuff you found. |
The number of commits seems a bit much, can't some of the common changes (e.g. 'describe' commits) be squashed together? |
@@ -1653,8 +1653,8 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. | |||
</tr> | |||
<tr> | |||
<td><code>SSL_OP_CIPHER_SERVER_PREFERENCE</code></td> | |||
<td>Uses the server's preferences instead of the clients when selecting a | |||
cipher. See | |||
<td>Attempt to use the server's preferences instead of the client's when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To use consistent verb conjugation with (most of) the other entries in this table, it would seem this should be Attempts
rather than Attempt
. (There's also an Allow
below that should be Allows
.)
* `secureOptions` {number} Optionally affect the OpenSSL protocol behaviour, | ||
which is not usually necessary. This should be used carefully if at all! | ||
Value is a numeric bitmask of the `SSL_OP_*` options from | ||
[OpenSSL Options][]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may replace #9340
7c21a24
to
3c1b2e5
Compare
@sam-github For review it's fine as-is, but I just wanted to make sure if/when this PR is landed, that the like-commits get squashed together and not landed as-is. |
var cert = fs.readFileSync(path.join(common.fixturesDir, 'pass-cert.pem')); | ||
|
||
assert(Buffer.isBuffer(passKey)); | ||
assert(Buffer.isBuffer(cert)); | ||
assert.equal(typeof passKey.toString(), 'string'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: assert.strictEqual()
instead of assert.equal()
here and anywhere else it shows up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it, though I don't understand why. The only difference is that now the test will fail if typeof doesn't return a string, or if a string literal is not a string, both of which would be crash the world bugs in V8.
var cert = fs.readFileSync(path.join(common.fixturesDir, 'pass-cert.pem')); | ||
|
||
assert(Buffer.isBuffer(passKey)); | ||
assert(Buffer.isBuffer(cert)); | ||
assert.equal(typeof passKey.toString(), 'string'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: assert.strictEqual()
instead of assert.equal()
here and anywhere else it shows up
rejectUnauthorized: false | ||
}, common.mustCall(function() {})); | ||
*/ | ||
})).unref(); | ||
|
||
assert.throws(function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: While you're in here anyway, can you add a second argument to this assert.throws()
, probably a RegExp that confirms that the error is the expected one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -11,11 +11,17 @@ var tls = require('tls'); | |||
var fs = require('fs'); | |||
var path = require('path'); | |||
|
|||
var key = fs.readFileSync(path.join(common.fixturesDir, 'pass-key.pem')); | |||
var passKey = fs.readFileSync(path.join(common.fixturesDir, 'pass-key.pem')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: While in here anyway, maybe take an opportunity to var->const some stuff? Up to you.
@@ -1,4 +1,5 @@ | |||
'use strict'; | |||
var assert = require('assert'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: var->const in this file too if you are so inclined (and not if you are not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM subject to squashing and nits as pointed out by Rich.
Either the options or the listener argument to tls.createServer() was optional, but not both. This makes no sense, so align the argument checking and documentation with net.createServer(), which accepts the same option sequence, and which tls.createServer() is modelled on.
Its confusing to have multiple names for the same thing, use secureOptions consistently.
- All the secure context options are valid options to a secureContext - isServer modifies the default value of requestCert
PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Either the options or the listener argument to tls.createServer() was optional, but not both. This makes no sense, so align the argument checking and documentation with net.createServer(), which accepts the same option sequence, and which tls.createServer() is modelled on. PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Its confusing to have multiple names for the same thing, use secureOptions consistently. PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Document all TLSSocket options: - All the secure context options are valid options to a secureContext - isServer modifies the default value of requestCert Describe all tls.connect() variants: - tls.connect(path) was undocumented - tls.connect(port) was underdocumented, and its relationship to tls.connect(options) was obscure Socket passed to tls.connect is user managed: - Replace #8996 Add documentation to: - describe and add tests for the pfx and key variants, and describe how and when passphrase is used. - describe tls cert and ca options - describe buffer forms of tls crl option - describe tls cipher option and defaults - fix link to Crypto Constants - describe that honorCipherOrder sets SSL_OP_CIPHER_SERVER_PREFERENCE. - describe tls ecdhCurve/dhparam options - describe tls secureProtocol option - describe tls secureOptions - describe tls sessionIdContext De-deduplicate secure context docs: The secure context options were documented 4 times, making it difficult to understand where the options come from, where they are supported, and under what conditions they are used. The multiple copies were inconsistent and contradictory in their descriptions of the options, and also inconsistent in whether the options would be documented at all. Cut through this gordian knot by linking all APIs that use the secureContext options to the single source of truth about the options. PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Either the options or the listener argument to tls.createServer() was optional, but not both. This makes no sense, so align the argument checking and documentation with net.createServer(), which accepts the same option sequence, and which tls.createServer() is modelled on. PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Its confusing to have multiple names for the same thing, use secureOptions consistently. PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Document all TLSSocket options: - All the secure context options are valid options to a secureContext - isServer modifies the default value of requestCert Describe all tls.connect() variants: - tls.connect(path) was undocumented - tls.connect(port) was underdocumented, and its relationship to tls.connect(options) was obscure Socket passed to tls.connect is user managed: - Replace #8996 Add documentation to: - describe and add tests for the pfx and key variants, and describe how and when passphrase is used. - describe tls cert and ca options - describe buffer forms of tls crl option - describe tls cipher option and defaults - fix link to Crypto Constants - describe that honorCipherOrder sets SSL_OP_CIPHER_SERVER_PREFERENCE. - describe tls ecdhCurve/dhparam options - describe tls secureProtocol option - describe tls secureOptions - describe tls sessionIdContext De-deduplicate secure context docs: The secure context options were documented 4 times, making it difficult to understand where the options come from, where they are supported, and under what conditions they are used. The multiple copies were inconsistent and contradictory in their descriptions of the options, and also inconsistent in whether the options would be documented at all. Cut through this gordian knot by linking all APIs that use the secureContext options to the single source of truth about the options. PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
PR-URL: #9800 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Checklist
make -j8 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
doc,tls
Description of change
Improvements to tls API documentation.