HTTP | M. Thomson |
Internet-Draft | Mozilla |
Intended status: Standards Track | M. Bishop |
Expires: September 15, 2016 | Microsoft |
March 14, 2016 |
Reactive Certificate-Based Client Authentication in HTTP/2
draft-thomson-http2-client-certs-02
Some HTTP servers provide a subset of resources that require additional authentication to interact with. HTTP/1.1 servers rely on TLS renegotiation that is triggered by a request to a protected resource. HTTP/2 made this pattern impossible by forbidding the use of TLS renegotiation. While TLS 1.3 provides an alternate mechanism to obtain client certificates, this mechanism does not map well to usage in TLS 1.2.
This document describes a how client authentication might be requested by a server as a result of receiving a request to a protected resource.
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."
This Internet-Draft will expire on September 15, 2016.
Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
Many existing HTTP [RFC7230] servers have different authentication requirements for the different resources they serve. Of the bountiful authentication options available for authenticating HTTP requests, client certificates present a unique challenge for resource-specific authentication requirements because of the interaction with the underlying TLS RFC5246 [I-D.ietf-tls-tls13] layer.
For servers that wish to use client certificates to authenticate users, they might request client authentication during or immediately after the TLS handshake. However, if not all users or resources need certificate-based authentication, a request for a certificate has the unfortunate consequence of triggering the client to seek a certificate. Such a request can result in a poor experience, particularly when sent to a client that does not expect the request.
The TLS 1.3 CertificateRequest can be used by servers to give clients hints about which certificate to offer. Servers that rely on certificate-based authentication might request different certificates for different resources. Such a server cannot use contextual information about the resource to construct an appropriate TLS CertificateRequest message during the initial handshake.
Consequently, client certificates are requested at connection establishment time only in cases where all clients are expected or required to have a single certificate that is used for all resources. Many other uses for client certificates are reactive, that is, certificates are requested in response to the client making a request.
In Yokohama, there was extensive working group discussion regarding why certificate authentication could not easily be done at the HTTP semantic layer. However, in subsequent discussion, it became apparent that the HTTP framing layer did not suffer from the same limitation.
In this document, a mechanism for doing certificate-based client authentication via HTTP/2 frames is defined. This mechanism can be implemented at the HTTP layer without requiring new TLS stack behavior and without breaking the existing interface between HTTP and applications which employ client certificates.
In HTTP/1.1, a server that relies on client authentication for a subset of users or resources does not request a certificate when the connection is established. Instead, it only requests a client certificate when a request is made to a resource that requires a certificate. TLS 1.2 [RFC5246] accomodates this by permitting the server to request a new TLS handshake, in which the server will request the client’s certificate.
Figure 1 shows the server initiating a TLS-layer renegotiation in response to receiving an HTTP/1.1 request to a protected resource.
Client Server -- (HTTP) GET /protected -------------------> *1 <---------------------- (TLS) HelloRequest -- *2 -- (TLS) ClientHello -----------------------> <------------------ (TLS) ServerHello, ... -- <---------------- (TLS) CertificateRequest -- *3 -- (TLS) ..., Certificate ------------------> *4 -- (TLS) Finished --------------------------> <-------------------------- (TLS) Finished -- <--------------------------- (HTTP) 200 OK -- *5
Figure 1: HTTP/1.1 Reactive Certificate Authentication with TLS 1.2
In this example, the server receives a request for a protected resource (at *1 on Figure 1). Upon performing an authorization check, the server determines that the request requires authentication using a client certificate and that no such certificate has been provided.
The server initiates TLS renegotiation by sending a TLS HelloRequest (at *2). The client then initiates a TLS handshake. Note that some TLS messages are elided from the figure for the sake of brevity.
The critical messages for this example are the server requesting a certificate with a TLS CertificateRequest (*3); this request might use information about the request or resource. The client then provides a certificate and proof of possession of the private key in Certificate and CertificateVerify messages (*4).
When the handshake completes, the server performs any authorization checks a second time. With the client certificate available, it then authorizes the request and provides a response (*5).
TLS 1.3 [I-D.ietf-tls-tls13] introduces a new client authentication mechanism that allows for clients to authenticate after the handshake has been completed. For the purposes of authenticating an HTTP request, this is functionally equivalent to renegotiation. Figure 2 shows the simpler exchange this enables.
Client Server -- (HTTP) GET /protected -------------------> <---------------- (TLS) CertificateRequest -- -- (TLS) Certificate, CertificateVerify ----> <--------------------------- (HTTP) 200 OK --
Figure 2: HTTP/1.1 Reactive Certificate Authentication with TLS 1.3
TLS 1.3 does not support renegotiation, instead supporting direct client authentication. In contrast to the TLS 1.2 example, in TLS 1.3, a server can simply request a certificate.
An important part of the HTTP/1.1 exchange is that the client is able to easily identify the request that caused the TLS renegotiation. The client is able to assume that the next unanswered request on the connection is responsible. The HTTP stack in the client is then able to direct the certificate request to the application or component that initiated that request. This ensures that the application has the right contextual information for processing the request.
In HTTP/2, a client can have multiple outstanding requests. Without some sort of correlation information, a client is unable to identify which request caused the server to request a certificate.
Thus, the minimum necessary mechanism to support reactive certificate authentication in HTTP/2 is an identifier that can be use to correlate an HTTP request with a request for a certificate.
Such an identifier could be added to TLS 1.2 by means of an extension, but many TLS 1.2 implementations do not permit application data to continue during a renegotiation. This is problematic for a multiplexed protocol like HTTP/2. Instead, this draft proposes bringing the TLS 1.3 CertificateRequest, Certificate, and CertificateVerify messages into HTTP/2 frames, making client certificate authentication TLS-version-agnostic.
This could be done in a naive manner by replicating the messages as HTTP/2 frames on each stream. However, this would create needless redundancy between streams and require frequent expensive signing operations. Instead, this draft lifts the bulky portions of each message into frames on stream zero and permits the on-stream frames to incorporate them by reference as needed.
On each stream where certificate authentication is required, the server sends a CERTIFICATE_REQUIRED frame, which the client answers with a USE_CERTIFICATE frame either indicating the certificate to use, or indicating that no certificate should be used. These frames are simple, referencing information previously sent on stream zero to reduce redundancy.
CERTIFICATE_REQUIRED frames reference a CERTIFICATE_REQUEST on stream zero, analogous to the CertificateRequest message. USE_CERTIFICATE frames reference a sequence of CERTIFICATE and CERTIFICATE_PROOF frames on stream zero, analogous to the the Certificate and CertificateVerify messages.
The exchange then looks like this:
Client Server -- (streams 1,3) GET /protected ------------> <---------- (stream 0) CERTIFICATE_REQUEST -- <------ (streams 1,3) CERTIFICATE_REQUIRED -- -- (stream 0) CERTIFICATE ------------------> -- (stream 0) CERTIFICATE_PROOF ------------> -- (streams 1,3) USE_CERTIFICATE -----------> <-------------------- (streams 1,3) 200 OK --
Figure 3: HTTP/2 Reactive Certificate Authentication
To avoid the extra round-trip per stream required for a challenge and response, the AUTOMATIC_USE flag enables a certificate to be automatically used by the server on subsequent requests without sending a CERTIFICATE_REQUIRED exchange.
Section 2 describes how certificates can be requested and presented at the HTTP/2 framing layer using several new frame types which parallel the TLS 1.3 message exchange. Section 3 defines new error types which can be used to notify peers when the exchange has not been successful. Finally, Section 4 describes how an HTTP/2 client can announce support for this feature so that a server might use these capabilities.
RFC 2119 [RFC2119] defines the terms “MUST”, “MUST NOT”, “SHOULD” and “MAY”.
An HTTP/2 request from a client that has signaled support for reactive certificate authentication (see Section 4) might cause a server to request client authentication. In HTTP/2 a server does this by sending at least one CERTIFICATE_REQUEST frame (see Section 2.3) on stream zero and sending a CERTIFICATE_REQUIRED frame (see Section 2.1) on the affected stream(s). The CERTIFICATE_REQUEST and CERTIFICATE_REQUIRED frames are correlated by their Request-ID field. Subsequent CERTIFICATE_REQUIRED frames with the same Request-ID MAY be sent on other streams where the server is expecting client authentication with the same parameters.
A server MAY send multiple concurrent CERTIFICATE_REQUIRED frames on the same stream. If a server requires that a client provide multiple certificates before authorizing a single request, it MUST send a CERTIFICATE_REQUIRED frame with a different request identifier and a corresponding CERTIFICATE_REQUEST frame describing each required certificate.
Clients respond to requests by sending one or more CERTIFICATE frames (see Section 2.4), followed by a CERTIFICATE_PROOF frame (see Section 2.5), on stream zero containing the Request-ID to which they are responding. The USE_CERTIFICATE (see Section 2.2) frame is sent on-stream to notify the server the stream is ready to be processed.
To reduce round-trips, the client MAY set the AUTOMATIC_USE flag on a CERTIFICATE_PROOF frame, indicating that the server SHOULD automatically apply the supplied certificate to any future streams matching that request, rather than sending a CERTIFICATE_REQUIRED frame.
The CERTIFICATE_REQUIRED frame (0xFRAME-TBD2) is sent by servers to indicate that processing of an HTTP request is blocked pending certificate authentication. The frame includes a request identifier which can be used to correlate the stream with a previous CERTIFICATE_REQUEST frame received on stream zero. The CERTIFICATE_REQUEST describes the client certificate the server requires to process the request.
The CERTIFICATE_REQUIRED frame contains 1 octet, which is the authentication request identifier. A client that receives a CERTIFICATE_REQUIRED of any other length MUST treat this as a stream error of type PROTOCOL_ERROR. Frames with identical request identifiers refer to the same CERTIFICATE_REQUEST.
The CERTIFICATE_REQUIRED frame MUST NOT be sent by clients. A CERTIFICATE_REQUIRED frame received by a server SHOULD be rejected with a stream error of type PROTOCOL_ERROR.
The server MUST NOT send a CERTIFICATE_REQUIRED frame on stream zero, a server-initiated stream or a stream that does not have an outstanding request. In other words, a server can only send in the “open” or “half-closed (remote)” stream states.
A client that receives a CERTIFICATE_REQUIRED frame on a stream which is not in a valid state (“open” or “half-closed (local)” for clients) SHOULD treat this as a connection error of type PROTOCOL_ERROR.
The USE_CERTIFICATE frame (0xFRAME-TBD5) is sent by clients in response to a CERTIFICATE_REQUIRED frame to indicate that the requested certificate has been provided (or will not be).
A USE_CERTIFICATE frame with no payload expresses the client’s refusal to use the associated certificate (if any) with this stream. If the request was originally issued for a different stream, servers MAY create a new CERTIFICATE_REQUEST and permit the client to offer a different certificate. Alternatively, servers MAY process the request as unauthenticated, likely returning an authentication-related error at the HTTP level (e.g. 403).
Otherwise, the USE_CERTIFICATE frame contains the Request-ID of the now-completed certificate request. This MUST be an ID previously issued by the server, and for which a matching certificate has previously been presented along with a supporting certificate chain in one or more CERTIFICATE frames, and for which proof of possession has been presented in a CERTIFICATE_PROOF frame.
Use of the USE_CERTIFICATE frame by servers is not defined by this document. A USE_CERTIFICATE frame received by a client MUST be ignored.
The client MUST NOT send a USE_CERTIFICATE frame on stream zero, a server-initiated stream or a stream that does not have an outstanding request. In other words, a client can only send in the “open” or “half-closed (local)” stream states. The client MUST NOT send a USE_CERTIFICATE frame except in response to a CERTIFICATE_REQUIRED frame from the server.
A server that receives a USE_CERTIFICATE frame on a stream which is not in a valid state (“open” or “half-closed (remote)” for servers), on which it has not sent a CERTIFICATE_REQUIRED frame, or referencing a certificate it has not previously received SHOULD treat this as a connection error of type PROTOCOL_ERROR.
TLS 1.3 defines the CertificateRequest message, which prompts the client to provide a certificate which conforms to certain properties specified by the server. This draft defines the CERTIFICATE_REQUEST frame (0xFRAME-TBD1), which contains the same contents as a TLS 1.3 CertificateRequest message, but can be sent over any TLS version.
The CERTIFICATE_REQUEST frame MUST NOT be sent by clients. A CERTIFICATE_REQUEST frame received by a server SHOULD be rejected with a stream error of type PROTOCOL_ERROR.
The CERTIFICATE_REQUEST frame MUST be sent on stream zero. A CERTIFICATE_REQUEST frame received on any other stream MUST be rejected with a stream error of type PROTOCOL_ERROR.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-------------------------------+-------------------------------+ | Request-ID (8)| Algorithm-Count (16) | Algorithms ... +---------------------------------------------------------------+ | CA-Count (16) | Certificate-Authorities(?) ... +---------------------------------------------------------------+ | Cert-Extension-Count (16) | Cert-Extensions(?) ... +---------------------------------------------------------------+
Figure 4: CERTIFICATE_REQUEST frame payload
The frame contains the following fields:
Some certificate extension OIDs allow multiple values (e.g. Extended Key Usage). If the sender has included a non-empty certificate_extensions list, the certificate MUST contain all of the specified extension OIDs that the recipient recognizes. For each extension OID recognized by the recipient, all of the specified values MUST be present in the certificate (but the certificate MAY have other values as well). However, the recipient MUST ignore and skip any unrecognized certificate extension OIDs.
PKIX RFCs define a variety of certificate extension OIDs and their corresponding value types. Depending on the type, matching certificate extension values are not necessarily bitwise-equal. It is expected that implementations will rely on their PKI libraries to perform certificate selection using these certificate extension OIDs.
A certificate chain is transferred as a series of CERTIFICATE frames (0xFRAME-TBD3) with the same Request-ID, each containing a single certificate in the chain. The end certificate of the chain can be used as authentication for previous or subsequent requests.
The CERTIFICATE frame defines no flags.
While unlikely, it is possible that an exceptionally large certificate might be too large to fit in a single HTTP/2 frame (see [RFC7540] section 4.2). Senders unable to transfer a requested certificate due to the recipient’s SETTINGS_MAX_FRAME_SIZE value SHOULD terminate affected streams with CERTIFICATE_TOO_LARGE.
Use of the CERTIFICATE frame by servers is not defined by this document. A CERTIFICATE frame received by a client MUST be ignored.
The CERTIFICATE frame MUST be sent on stream zero. A CERTIFICATE frame received on any other stream MUST be rejected with a stream error of type PROTOCOL_ERROR.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-------------------------------+-------------------------------+ | Request-ID (8)| Certificate (*) ... +---------------------------------------------------------------+
Figure 5: CERTIFICATE frame payload
The fields defined by the CERTIFICATE frame are:
The first or only CERTIFICATE frame with a given Request-ID MUST contain the sender’s certificate. Each subsequent certificate SHOULD directly certify the certificate immediately preceding it. A certificate which specifies a trust anchor MAY be omitted, provided that the recipient is known to already possess the relevant certificate. (For example, because it was included in a CERTIFICATE_REQUEST’s Certificate-Authorities list.)
The Request-ID field MUST contain the same value as the corresponding CERTIFICATE_REQUEST frame, and the provided certificate chain MUST conform to the requirements expressed in the CERTIFICATE_REQUEST to the best of the client’s ability. Specifically:
If these requirements are not satisfied, the server MAY at its discretion either process the request without client authentication, or respond with a stream error [RFC7540] on any stream where the certificate is used. Section 3 defines certificate-related error codes which might be applicable.
A client cannot provide different certificates in response to the same CERTIFICATE_REQUEST for use on different streams. A client that has already sent and proven a certificate, but does not wish to use it on a particular stream SHOULD send an empty USE_CERTIFICATE frame, refusing to use that certificate on that stream.
The CERTIFICATE_PROOF frame proves possession of the private key corresponding to an end certificate previously shown in a CERTIFICATE frame.
The CERTIFICATE_PROOF frame defines one flag:
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-------------------------------+-------------------------------+ | Request-ID (8)| Algorithm (16) | Signature(*)... +---------------------------------------------------------------+
Figure 6: CERTIFICATE_PROOF frame payload
The CERTIFICATE_PROOF frame (0xFRAME-TBD4) contains an Algorithm field (a SignatureAndHashAlgorithm, from [I-D.ietf-tls-tls13] section 6.3.2.1), describing the hash/signature algorithm pair being used. The signature is performed as described in [I-D.ietf-tls-tls13], with the following values being used:
Because the exported value can be independently calculated by both sides of the TLS connection, the value to be signed is not sent on the wire at any time. The same signed value is used for all CERTIFICATE_PROOF frames in a single HTTP/2 connection.
A CERTIFICATE_PROOF frame MUST be sent only after all CERTIFICATE frames with the same Request-ID have been sent, and MUST correspond to the first certificate presented in the first CERTIFICATE frame with that Request-ID. Receipt of multiple CERTIFICATE_PROOF frames for the same Request-ID, receipt of a CERTIFICATE_PROOF frame without a corresponding CERTIFICATE frame, or receipt of a CERTIFICATE frame after a corresponding CERTIFICATE_PROOF MUST be treated as a session error of type PROTOCOL_ERROR.
If the AUTOMATIC_USE flag is set, the server MAY omit sending CERTIFICATE_REQUIRED frames on future streams associated with this request and use the referenced certificate for authentication without further notice to the client. This behavior is optional, and receipt of a CERTIFICATE_REQUIRED frame does not imply that previously-presented certificates were unacceptable to the server.
Use of the CERTIFICATE_PROOF frame by servers is not defined by this document. A CERTIFICATE_PROOF frame received by a client MUST be ignored.
Because this draft permits client certificates to be exchanged at the HTTP framing layer instead of the TLS layer, several certificate-related errors which are defined at the TLS layer might now occur at the HTTP framing layer. In this section, those errors are restated and added to the HTTP/2 error code registry.
As described in [RFC7540], implementations MAY choose to treat a stream error as a connection error at any time. Of particular note, a stream error cannot occur on stream 0, which means that implementations cannot send non-session errors in response to CERTIFICATE_REQUEST and CERTIFICATE frames. Implementations which do not wish to terminate the connection MAY either send relevant errors on any stream which references the failing certificate in question or process the requests as unauthenticated and provide error information at the HTTP semantic layer.
Clients that support HTTP-layer certificate authentication indicate this using the HTTP/2 SETTINGS_HTTP_CERT_AUTH (0xSETTING-TBD) setting.
The initial value for the SETTINGS_HTTP_CERT_AUTH setting is 0, indicating that the client does not support reactive certificate authentication. A client sets the SETTINGS_HTTP_CERT_AUTH setting to a value of 1 to indicate support for HTTP-layer certificate authentication as defined in this document. Any value other than 0 or 1 MUST be treated as a connection error (Section 5.4.1 of [RFC7540]) of type PROTOCOL_ERROR.
Failure to provide a certificate on a stream after receiving CERTIFICATE_REQUIRED blocks server processing, and SHOULD be subject to standard timeouts used to guard against unresponsive peers.
In order to protect the privacy of the connection against triple-handshake attacks, this feature of HTTP/2 MUST be used only over TLS 1.3 or greater, or over TLS 1.2 in combination with the Extended Master Secret extension defined in [RFC7627]. Because this feature is intended to operate with equivalent security to the TLS connection, hash and signature algorithms not permitted by the version of TLS in use MUST NOT be used. Additionally, the following algorithms MUST NOT be used, even if permitted by the underlying TLS version:
Client implementations need to carefully consider the impact of setting the AUTOMATIC_USE flag. This flag is a performance optimization, permitting the client to avoid a round-trip on each request where the server checks for certificate authentication. However, once this flag has been sent, the client has zero knowledge about whether the server will use the referenced cert for any future request, or even for an existing request which has not yet completed. Clients MUST NOT set this flag on any certificate which is not appropriate for currently-in-flight requests, and MUST NOT make any future requests on the same connection which they do not intend to have associated with the provided certificate.
Implementations need to be aware of the potential for confusion about the state of a connection. The presence or absence of a validated client certificate can change during the processing of a request, potentially multiple times, as USE_CERTIFICATE frames are received. A server that uses certificate authentication needs to be prepared to reevaluate the authorization state of a request as the set of certificates changes.
The HTTP/2 SETTINGS_HTTP_CERT_AUTH setting is registered in Section 6.1. Five frame types are registered in Section 6.2. Six error codes are registered in Section 6.3.
The SETTINGS_HTTP_CERT_AUTH setting is registered in the “HTTP/2 Settings” registry established in [RFC7540].
Four new frame types are registered in the “HTTP/2 Frame Types” registry established in [RFC7540].
Five new error codes are registered in the “HTTP/2 Error Code” registry established in [RFC7540].
Eric Rescorla pointed out several failings in an earlier revision. Andrei Popov contributed to the TLS considerations.