From patchwork Thu Apr 7 11:35:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Bligh X-Patchwork-Id: 8771231 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 8ECB5C0553 for ; Thu, 7 Apr 2016 11:36:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0DC2A20204 for ; Thu, 7 Apr 2016 11:35:59 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9EA8B201B9 for ; Thu, 7 Apr 2016 11:35:57 +0000 (UTC) Received: from localhost ([::1]:49092 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ao8E8-0000go-Uq for patchwork-qemu-devel@patchwork.kernel.org; Thu, 07 Apr 2016 07:35:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44457) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ao8Dv-0000de-V2 for qemu-devel@nongnu.org; Thu, 07 Apr 2016 07:35:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ao8Dt-00074c-Jx for qemu-devel@nongnu.org; Thu, 07 Apr 2016 07:35:43 -0400 Received: from mail.avalus.com ([2001:41c8:10:1dd::10]:40913) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ao8Dt-00073w-AJ for qemu-devel@nongnu.org; Thu, 07 Apr 2016 07:35:41 -0400 Received: by mail.avalus.com (Postfix) with ESMTPSA id B327832A6001; Thu, 7 Apr 2016 12:35:39 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=alex.org.uk; s=mail; t=1460028939; bh=VkaO0QsUqhKvQxuVBhczEJphsPYUOoW2yvTAJblyztQ=; h=From:To:Cc:Subject:Date; b=cP2B7NhsqwwPciG9gMo8I/Wtyjr+RPNPkQho6bP1hRfz+DkWVPAoU8F7QUygWPbTP 722bN21zDjyfy33poHEyIQaqcRj1Zu2RLu4D1f/Wf5F42CgzrDbCY3wIkYdRXmmNjX 5S9uG/E3+orTzR0SKMu8C88MhEvtrOlZIo7V3iIA= From: Alex Bligh To: Eric Blake , Wouter Verhelst Date: Thu, 7 Apr 2016 12:35:59 +0100 Message-Id: <1460028959-59091-1-git-send-email-alex@alex.org.uk> X-Mailer: git-send-email 1.9.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 2001:41c8:10:1dd::10 Cc: "nbd-general@lists.sourceforge.net" , "qemu-devel@nongnu.org" , Alex Bligh Subject: [Qemu-devel] [PATCH] Improve documentation for TLS X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP * 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 --- 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 +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. + +#### 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. + +#### SELECTIVETLS 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 except `NBD_OPT_INFO`, +it MUST NOT reply with `NBD_REP_ERR_TLS_REQD`. If the +server receives `NBD_OPT_INFO` and TLS has not been +initiated, it MAY reply with `NBD_REP_ERR_TLS_REQD` if that +export is non-existent, and MUST reply with `NBD_REP_ERR_TLS_REQD` +if that export is TLS-only. + +If the server receives a request to enter transmission mode +via `NBD_OPT_EXPORT_NAME` on a TLS-only export 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 neogitated. The server +MUST NOT send `NBD_REP_ERR_TLS_REQD` in response to any +option other than `NBD_OPT_INFO` or `NBD_OPT_GO`, and +only in those case in respect of a TLS-only non-existent export. + +There are two degenerate cases of SELECTIVETLS: where all +exports are TLS-only, and where no exports are TLS-only. +These are permitted to make programming of servers easier. +Where no exports are TLS-only, operation is very similar +to OPTIONALTLS. Where all exports are TLS-only, operation +is a little different from FORCEDTLS, as the client is not +forced to upgrade to TLS prior to any options being processed, +and the server MAY choose to give information on TLS-only +or non-existent exports via NBD_OPT_INFO exports prior to an +upgrade to TLS. + +The SELECTIVETLS mode of operation has an implementation problem +in that unless the INFO extension is supported, the client that +does not use TLS may have its access to exports denied without +it being able to ascertain the reason. For instance it may +go into transmission mode using `NBD_OPT_EXPORT_NAME` - which +does not return an error as no options will be denied with +`NBD_REP_ERR_TLS_REQD`. Futher there is no way to remotely +determine whether an export requires TLS, and therefore this +must be initiated between client and server out of band. +Therefore, if a server uses SELECTIVETLS, it SHOULD implement +the INFO extension. + +## Client side requirements + +If the client supports TLS at all, it MUST be prepared +to deal with servers operating in any of the above modes. +Notwithstanding, a client MAY always disconnect or +refuse to connect to a particular export if TLS is +not available and the user requires TLS. + +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. + +If the TLS handshake is unsuccessful (for instance the servers's +certificate does not validate) the client MUST disconnect as +by this stage it is too late to continue without TLS. + +If the client receives an `NBD_REP_ERR_TLS_REQD` in response +to any option, it implies that this option cannot be executed +unless a TLS upgrade is performed. If the option is any +option other than `NBD_OPT_INFO` or `NBD_OPT_GO`, this +indicates that no option will succeed unless a TLS upgrade +is performed; the client MAY therefore choose to issue +a `NBD_OPT_STARTTLS`, or MAY disconnect the session (if +for instance it does not support TLS or does not have +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 +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. +On all other modes, and upgrade to TLS will be performed. + +If a client supports TLS, it SHOULD also support the INFO +extension, and SHOULD use `NBD_OPT_GO` if available in place +of `NBD_OPT_EXPORT_NAME`. The reason for this is set out in +the final paragraphs of the sections under 'FORCEDTLS' +and 'SELECTIVETLS': this gives an opportunity for the +server to transmit that an error going into transmission +mode is due to the client's failure to initiate TLS, +and the fact that the client may obtain information about +which exports are TLS-only through `NBD_OPT_INFO`. + +### Status + +This functionality has not yet been implemented by the reference +implementation, but was implemented by qemu and subsequently +by other users, so has been moved out of the "experimental" section. + ## Values This section describes the value and meaning of constants (other than @@ -366,7 +586,7 @@ of the newstyle negotiation. Data: String, name of the export, as free-form text. The length of the name is determined from the option header. If the chosen export does not exist or requirements for the chosen export - are not met (e.g., the client did not negotiate TLS for an export + are not met (e.g., the client did not initiate TLS for an export where the server requires it), the server should close the connection. @@ -400,21 +620,13 @@ of the newstyle negotiation. - `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`. + + See the section on TLS above for futher details. - `NBD_OPT_INFO` (6) @@ -489,20 +701,9 @@ case that data is an error message string suitable for display to the user. * `NBD_REP_ERR_TLS_REQD` (2^31 + 5) The server is unwilling to continue negotiation unless TLS is - negotiated first. A server MUST NOT send this error if it has one or - more exports that do not require TLS; not even if the client indicated - interest (by way of `NBD_OPT_PEEK_EXPORT`) in an export which requires - TLS. - - If this reply is used, servers SHOULD send it in reply to each and every - unencrypted `NBD_OPT_*` message (apart from `NBD_OPT_STARTTLS`). - - 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 experimental `INFO` extension makes small but compatible - changes to the semantics of this error message; see below. + initiated first. In the case of `NBD_OPT_INFO` and `NBD_OPT_GO` + this unwillingness MAY be limited to the export in question. + See the section on TLS above for further details. * `NBD_REP_ERR_UNKNOWN` (2^31 + 6) @@ -735,13 +936,13 @@ Therefore these commands share common documentation. - `NBD_REP_ERR_UNKNOWN`: The chosen export does not exist on this server. - `NBD_REP_ERR_TLS_REQD`: The server does not wish to export this - block device unless the client negotiates TLS first. + block device unless the client initiates TLS first. - `NBD_REP_SERVER`: The server accepts the chosen export. - Additionally, if TLS has not been negotiated, the server MAY reply + Additionally, if TLS has not been initiated, the server MAY reply with `NBD_REP_ERR_TLS_REQD` (instead of `NBD_REP_ERR_UNKNOWN`) to requests for exports that are unknown. This is so that clients - that have not negotiated TLS cannot enumerate exports. + that have not initiated TLS cannot enumerate exports. In the case of `NBD_REP_SERVER`, the message's data takes on a different interpretation than the default (so as to provide additional