On Thu, Apr 07, 2016 at 12:35:59PM +0100, Alex Bligh wrote: > * Call out TLS into a separate section > > * Add details of the TLS protocol itself > > * Emphasise that actual TLS session initiation (i.e. the TLS handshake) can > be initiated from either side (as required by the TLS standard I believe > and as actually works in practice) > > * Clarify what is a requirement on servers, and what is a requirement on > clients, separately, specifying their behaviour in a single place > in the document. > > * Document the four possible modes of operation of a server. > > Signed-off-by: Alex Bligh <a...@alex.org.uk> > --- > doc/proto.md | 267 > +++++++++++++++++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 234 insertions(+), 33 deletions(-) > > diff --git a/doc/proto.md b/doc/proto.md > index f117394..9437e9b 100644 > --- a/doc/proto.md > +++ b/doc/proto.md > @@ -286,6 +286,226 @@ S: (*length* bytes of data if the request is of type > `NBD_CMD_READ`) > This reply type MUST NOT be used except as documented by the > experimental `STRUCTURED_REPLY` extension; see below. > > +## TLS support > + > +The NBD protocol supports TLS via negotiation with the `NBD_OPT_STARTTLS` > +option. This is performed as an in-session upgrade. Below the term > +'negotiation' is used to refer to the sending and receiving of > +NBD commands, and the term 'initiation' of TLS is used to refer to > +the actual upgrade to TLS. > + > +### TLS versions Certificates, authentication and authorisation > + > +NBD implementations supporting TLS MUST support TLS version > +1.2, and MAY support other (earlier or later) versions of > +TLS/SSL. > + > +This standard does not specify what encryption, certification > +and signature algorithms are used. This standard does not > +specify authentication and authortisation (for instance > +whether client and/or server certificates are required and > +what they should contain); this is implementation dependent. > + > +### Server-side requirements > + > +There are four modes of operation for a server. The > +server MUST support one of these modes. > + > +* The server operates entirely without TLS ('NOTLS'); OR > + > +* The server makes TLS available (for all exports) and > + it is available at the option of the client ('OPTIONALTLS'); OR > + > +* The server insists upon TLS, and forces the client to > + upgrade by erroring any NBD options other than `NBD_OPT_STARTTLS` > + with `NBD_REP_ERR_TLS_REQD` ('FORCEDTLS'); this in practice means > + that all option negotiation (apart from the `NBD_OPT_STARTTLS` > + itself) is carried out with TLS; OR > + > +* The server provides TLS, and it is mandatory on zero or more > + exports, and is available at the client's option on all > + other exports ('SELECTIVETLS'). The server does not force > + the client to upgrade to TLS during option haggling (as > + if the client ultimately chose a non-TLS-only export, > + stopping TLS is not possible). Instead it permits the client > + to upgrade as and when it chooses, but unless an upgrade to > + TLS has already taken place, the server errors attempts > + to enter transmission mode on TLS-only exports, MAY > + refuse to provide information about TLS-only exports > + via `NBD_OPT_INFO`, and MAY refuse to provide information > + about non-existent exports via `NBD_OPT_INFO`. > + > +The server MAY determine the mode in which it operates > +dependent upon the connection (for instance it might be > +more liberal with connections made over the loopback > +interface) but it MUST be consistent in its mode > +of operation across the lifespan of a single TCP connection > +to the server. A client MUST NOT assume indications from > +a prior TCP session to a given server will be relevant > +to a subsequent session. > + > +These modes of operations are described in detail below. > + > +#### NOTLS mode > + > +If the server receives `NBD_OPT_STARTTLS` it MUST respond with > +`NBD_REP_ERR_UNSUPP`. The server MUST NOT respond to any
No. UNSUP (one P) is reserved for "this server doesn't support that" (i.e., backwards compatibility). Not configured for supporting TLS would be NBD_REP_ERR_POLICY. > +command with `NBD_REP_ERR_TLS_REQD`. > + > +#### OPTIONALTLS mode > + > +If the server receives `NBD_OPT_STARTTLS` it MUST reply with > +`NBD_REP_ACK`. After this reply has been sent, the server MUST > +be prepared for a TLS handshake, and all further data MUST > +be sent and received over TLS. There is no downgrade to a > +non-TLS connection. > + > +As per the TLS standard, the handshake MAY be initiated either > +by the server (having sent the `NBD_REP_ACK`) or by the client. > +If the handshake is unsuccessful (for instance the client's > +certificate does not match) the server MUST disconnect as > +by this stage it is too late to continue without TLS as the > +acknowledgement has been sent. > + > +The server MUST NOT respond to any command with `NBD_REP_ERR_TLS_REQD`, > +as TLS is optional. I think this mode is effectively the same as what you call selective, modulo that no exports have any TLS requirements, so I wouldn't specify it as a separate mode of operation (save perhaps that you may want to discourage it) > +#### FORCEDTLS mode > + > +If the server receives `NBD_OPT_STARTTLS` it MUST reply with > +`NBD_REP_ACK` and initiate TLS as set out under 'OPTIONALTLS' > +above. > + > +If the server receives any other option, including `NBD_OPT_INFO`, > +it SHOULD reply with `NBD_REP_ERR_TLS_REQD` if TLS has not > +been initiated; `NBD_OPT_INFO` is included as in this mode, > +all exports are TLS-only. If the server receives a request to enter > +transmission mode via `NBD_OPT_EXPORT_NAME` when TLS has not > +been initiated, then as this request cannot error, it MUST > +disconnect the connection. If the server receives a request to > +enter transmission mode via `NBD_OPT_GO` when TLS has not been > +initiated, it MUST error with `NBD_REP_ERR_TLS_REQD`. > + > +The server MUST NOT send `NBD_REP_ERR_TLS_REQD` in reply to > +any command if TLS has already been initiated. > + > +The FORCEDTLS mode of operation has an implementation problem in > +that the client MAY legally simply send a `NBD_OPT_EXPORT_NAME` > +to enter transmission mode without previously sending any options. > +Therefore, if a server uses FORCEDTLS, it SHOULD implement the > +INFO extension. Right. Clearly this can't be a must, because qemu already implements this and doesn't do INFO :-) [...] > +The server MUST NOT send `NBD_REP_ERR_TLS_REQD` in reply to > +any command if TLS has already been neogitated. The server negotiated [...] > +The client MAY send `NBD_OPT_STARTTLS` at any time to initiate > +a TLS session, except that the client MUST NOT send > +`NBD_OPT_STARTTLS` if TLS has alreay been initiated. If the > +cllient receives `NBD_REP_ACK` in response, it > +MUST immediately upgrade the connection to TLS. If it receives > +`NBD_ERR_REP_UNSUP` in response or any other error, it indicates > +that the server cannot or will not upgrade the connection to > +TLS and therefore MUST either continue the connection without > +TLS, or discconnect. That, or NBD_REP_ERR_POLICY. [...] > +appropriate credentials for this server). If the client > +receives `NBD_REP_ERR_TLS_REQD` in response to > +`NBD_OPT_INFO` or `NBD_OPT_GO` this indicates that the > +export referred to within the option is either non-existent > +or requires TLS; the server MAY therefore choose to issue client, not server > +a `NBD_OPT_STARTTLS`, MAY disconnect the session (if > +for instance it does not support TLS or does not have > +appropriate credentials for this server), or MAY continue > +in another manner without tls, for instance by querying > +or using other exports. > + > +The client MAY discover the server operates in NOTLS mode by > +sending `NBD_OPT_STARTTLS`. If `NBD_REP_ERR_UNSUPP` is > +replied, it is guaranteed the server is not in this mode. UNSUP or POLICY (actually, "any error". If STARTTLS errors, the server effectively does not support TLS) [...] > - `NBD_OPT_STARTTLS` (5) > > - The client wishes to initiate TLS. If the server replies with > - `NBD_REP_ACK`, then the client should immediately initiate a TLS > - handshake and continue the negotiation in the encrypted channel. If > - the server is unwilling to perform TLS, it should reply with > - `NBD_REP_ERR_POLICY`. For backwards compatibility, a client should > - also be prepared to handle `NBD_REP_ERR_UNSUP`. If the client sent > - along any data with the request, the server should send back > - `NBD_REP_ERR_INVALID`. The client MUST NOT send this option if > - it has already negotiated TLS; if the server receives > - `NBD_OPT_STARTTLS` when TLS has already been negotiated, the server > - MUST send back `NBD_REP_ERR_INVALID`. > - > - This functionality has not yet been implemented by the reference > - implementation, but was implemented by qemu so has been moved out of > - the "experimental" section. > + The client wishes to initiate TLS. > + > + The server MUST either reply with `NBD_REP_ACK` after which > + point the connection is upgraded to TLS, or reply with > + `NBD_REP_ERR_UNSUP`. (or POLICY) -- < ron> I mean, the main *practical* problem with C++, is there's like a dozen people in the world who think they really understand all of its rules, and pretty much all of them are just lying to themselves too. -- #debian-devel, OFTC, 2016-02-12