RFC 9458
Oblivious HTTP
Oblivious HTTP ๐
Okay bestie, this RFC is literally about making your web requests invisible to the server you're talking to ๐โจ It's giving privacy main character energy, and I am obsessed. Let's get into it ๐
Quick title-block tea โ This doc is RFC 9458, written by M. Thomson (Mozilla) and C. A. Wood (Cloudflare), published in January 2024. It's on the Standards Track, which means it's an actual Internet standard, not just a suggestion ๐ It's tagged ISSN 2070-1721. It doesn't obsolete or update any other RFCs, so it's fresh and doesn't step on anyone's toes ๐ฆ
Abstract
Okay so the abstract is the elevator pitch ๐ It says Oblivious HTTP is a protocol for forwarding encrypted HTTP messages. The vibe? A client can send a bunch of requests to an origin server, and the server can't link them back to the client or realize they all came from the same person ๐ญ The client also doesn't have to trust the middle nodes that forward the messages very much. Iconic ๐ซถ
Status of This Memo
Literally just paperwork, but it's important paperwork ๐ This is an Internet Standards Track document from the IETF, and it has been reviewed publicly and approved by the IESG ๐ธ For more on Internet Standards, check out Section 2 of RFC 7841. The current status, errata, and feedback info all live at https://www.rfc-editor.org/info/rfc9458 ๐ง
Copyright Notice
Copyright (c) 2024 IETF Trust and the document authors, all rights reserved ๐ This doc is subject to BCP 78 and the IETF Trust's Legal Provisions, which spell out your rights and restrictions, so read them carefully ๐ Any Code Components pulled out of this document must include Revised BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty under that license ๐
Table of Contents
1. Introduction
2. Overview
2.1. Applicability
2.2. Conventions and Definitions
3. Key Configuration
3.1. Key Configuration Encoding
3.2. Key Configuration Media Type
4. HPKE Encapsulation
4.1. Request Format
4.2. Response Format
4.3. Encapsulation of Requests
4.4. Encapsulation of Responses
4.5. Request and Response Media Types
4.6. Repurposing the Encapsulation Format
5. HTTP Usage
5.1. Informational Responses
5.2. Errors
5.3. Signaling Key Configuration Problems
6. Security Considerations
6.1. Client Responsibilities
6.2. Relay Responsibilities
6.2.1. Differential Treatment
6.2.2. Denial of Service
6.2.3. Traffic Analysis
6.3. Server Responsibilities
6.4. Key Management
6.5. Replay Attacks
6.5.1. Use of Date for Anti-replay
6.5.2. Correcting Clock Differences
6.6. Forward Secrecy
6.7. Post-Compromise Security
6.8. Client Clock Exposure
6.9. Media Type Security
6.10. Separate Gateway and Target
7. Privacy Considerations
8. Operational and Deployment Considerations
8.1. Performance Overhead
8.2. Resource Mappings
8.3. Network Management
9. IANA Considerations
9.1. application/ohttp-keys Media Type
9.2. message/ohttp-req Media Type
9.3. message/ohttp-res Media Type
9.4. Registration of "date" Problem Type
9.5. Registration of "ohttp-key" Problem Type
10. References
10.1. Normative References
10.2. Informative References
Appendix A. Complete Example of a Request and Response
Acknowledgments
Authors' Addresses
1. Introduction ๐
Okay so, HTTP requests spill a lot of info about who you are to the server ๐ญ The content of your request is totally in your control, but other stuff is way harder to hide and can still be used to identify you ๐
Even if an IP address isn't tied to one specific person, all the requests coming from it can be lined up over time to build a profile of what you do ๐ Connection reuse makes things faster, but it also lets servers link together every request that shares a connection. Not ideal!
The source IP of the connection is a big giveaway, and you don't have much control over it. Proxies can help hide your IP, but they have a messy trade-off ๐ Without TLS, the proxy can read everything you send. With TLS, you need a brand-new connection for every single request so the origin server can't correlate them, and that's a huge performance hit ๐ฉ
So this document defines Oblivious HTTP ๐ฆ It's a protocol for encrypting HTTP messages and sending them from a client to a gateway. It uses a trusted relay so the metadata that could identify the client (like IP address and connection info) is mostly hidden, and it still keeps performance reasonable โจ Here's what the doc covers:
- An algorithm for encapsulating binary HTTP messages [BINARY] using Hybrid Public Key Encryption (HPKE) [HPKE] to protect their contents,
- A method for forwarding Encapsulated Requests between Clients and an Oblivious Gateway Resource through a trusted Oblivious Relay Resource using HTTP, and
- Requirements for how the Oblivious Gateway Resource handles Encapsulated Requests and produces Encapsulated Responses for the Client.
Put together, encapsulation plus relaying means the Oblivious Gateway Resource never sees the Client's IP address, and the Oblivious Relay Resource never sees plaintext HTTP content ๐ซถ Also, connections can be reused between the Client and the relay, and between the relay and the gateway, so this is faster than opening one connection per request ๐ฅ The relay is only trusted so much (see Section 6), but Clients still get the assurance that their requests aren't uniquely tied to them or linked to other requests ๐
2. Overview ๐
An Oblivious HTTP Client needs to know three things up front:
- The identity of an Oblivious Gateway Resource. This might include some info about which Target Resources the gateway supports.
- The details of an HPKE public key for the Oblivious Gateway Resource, including a key identifier and the HPKE algorithms used with that key.
- The identity of an Oblivious Relay Resource that accepts relay requests carrying an Encapsulated Request as content, and forwards that content to one particular Oblivious Gateway Resource. Oblivious HTTP uses a one-to-one mapping between Oblivious Relay and Gateway Resources; see Section 8.2 for more details.
With that info, the Client can send HTTP requests to the Oblivious Gateway Resource to be forwarded to a Target Resource ๐ The gateway never learns the Client's IP address or any other identifying info from the transport layer, and it also can't tell which of its requests came from the same Client ๐
.------------------------------.
+---------+ +----------+ | +----------+ +----------+ |
| Client | | Relay | | | Gateway | | Target | |
| | | Resource | | | Resource | | Resource | |
+----+----+ +----+-----+ | +-----+----+ +----+-----+ |
| | `-------|--------------|-------'
| Relay | | |
| Request | | |
| [+ Encapsulated | | |
| Request ] | | |
+---------------->| Gateway | |
| | Request | |
| | [+ Encapsulated | |
| | Request ] | |
| +------------------->| Request |
| | +------------->|
| | | |
| | | Response |
| | Gateway |<-------------+
| | Response | |
| | [+ Encapsulated | |
| | Response ] | |
| Relay |<-------------------+ |
| Response | | |
| [+ Encapsulated | | |
| Response ] | | |
|<----------------+ | |
| | | |
Figure 1: Overview of Oblivious HTTP
Here's how a request for a Target Resource gets sent to the Oblivious Gateway Resource, as shown in Figure 1 ๐ฆ
- The Client builds an HTTP request for a Target Resource.
- The Client encodes that HTTP request in a binary HTTP message, then encapsulates it using HPKE and the process from Section 4.3.
- The Client sends a POST request to the Oblivious Relay Resource, with the Encapsulated Request as the content of that message.
- The Oblivious Relay Resource forwards this request to the Oblivious Gateway Resource.
- The Oblivious Gateway Resource receives the request and removes the HPKE protection to get back an HTTP request.
The Oblivious Gateway Resource then handles that HTTP request ๐ This usually means making an HTTP request using the content of the Encapsulated Request. Once the gateway has an HTTP response, these steps send it back to the Client:
- The Oblivious Gateway Resource encapsulates the HTTP response following the process in Section 4.4, and sends it in response to the request from the Oblivious Relay Resource.
- The Oblivious Relay Resource forwards this response to the Client.
- The Client removes the encapsulation to get the response to the original request.
Okay, real talk โ ๏ธ This interaction gives authentication and confidentiality between the Client and the Oblivious Gateway, but not between the Client and the Target Resource. The Target Resource is a separate HTTP resource from the gateway, but they're both logically under the gateway's control, since the Oblivious Gateway Resource can make up whatever responses come back from the Target Resource to the Client ๐ญ That's the setup shown in Figure 1 ๐
Part 1 of 9 done! ๐ซถ More parts are coming, so stay tuned bestie ๐
2.1. Applicability
okay so Oblivious HTTP is NOT for everything ๐ it needs explicit support from a willing Oblivious Relay Resource AND an Oblivious Gateway Resource, so it's kinda picky about who it hangs out with. that really limits it for generic apps, see Section 6.3 for the deets ๐
a lot of HTTP stuff depends on remembering things between requests, like cookies [COOKIES], authentication (Section 11 of [HTTP]), or even alternative services [RFC7838]. Oblivious HTTP cuts the linkage at the transport layer, which only helps apps that DON'T carry state between requests. so if your app is keeping a memory of you, this isn't the drip for it ๐
it's mostly useful when the privacy risk of a server treating your requests statefully is big enough to justify deploying it. it's simpler and cheaper than heavier systems like Prio [PRIO] or Tor [DMS2004], which can give stronger guarantees but cost more to run ๐ฆ
and ngl, it's more expensive than just connecting straight to a server. some costs, like connection setup, can get amortized, but there are a few ways it's pricier than a direct request:
- Each request requires at least two regular HTTP requests, which could increase latency.
- Each request is expanded in size with additional HTTP fields, encryption-related metadata, and Authenticated Encryption with Associated Data (AEAD) expansion.
- Deriving cryptographic keys and applying them for request and response protection takes non-negligible computational resources.
so when is the extra cost worth it? when preventing requests from being linked is the whole point. some examples:
DNS queries: DNS queries made to a recursive resolver reveal information about the requester, especially if they get linked to other queries. big mood ๐
Telemetry submission: Applications that submit reports about their usage to their developers might use Oblivious HTTP for some types of moderately sensitive data. โจ
these are all requests where there's info that, if it got tied to your identity, could tell a server something about you even if your identity were only pseudonymous. other examples are submitting anonymous surveys, making search queries, or requesting location-specific content (like grabbing tiles for a map display) ๐บ๏ธ
โ ๏ธ on top of all this, Section 6 covers the operational constraints you NEED to follow to actually get the goals of the protocol. no skipping!
2.2. Conventions and Definitions
okay the BCP 14 key words. the words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" are only read as BCP 14 [RFC2119] [RFC8174] when they show up in ALL CAPS like that. lowercase ones are just regular words ๐ง
this doc uses terminology from [HTTP] and defines a few terms too:
Client: A Client originates Oblivious HTTP requests. A Client is also an HTTP client in two ways: for the Target Resource and for the Oblivious Relay Resource. but when we mean the HTTP definition of client (Section 3.3 of [HTTP]), we say "HTTP client" instead; see Section 5. ๐
Encapsulated Request: An HTTP request that is encapsulated in an HPKE-encrypted message; see Section 4.3. ๐
Encapsulated Response: An HTTP response that is encapsulated in an HPKE-encrypted message; see Section 4.4. ๐
Oblivious Relay Resource: An intermediary that forwards Encapsulated Requests and Responses between Clients and a single Oblivious Gateway Resource. in context, you can just call it a "relay" ๐ฆ
Oblivious Gateway Resource: A resource that can receive an Encapsulated Request, extract the contents of that request, forward it to a Target Resource, receive a response, encapsulate that response, and then return the resulting Encapsulated Response. in context, just say "gateway" ๐ธ
Target Resource: The resource that is the target of an Encapsulated Request. this resource logically handles only regular HTTP requests and responses, so it might be totally unaware that Oblivious HTTP is being used to reach it ๐ซถ
this document includes pseudocode that uses the functions and conventions defined in [HPKE].
encoding an integer into a sequence of bytes in network byte order is described with the function encode(n, v), where n is the number of bytes and v is the integer value. ASCII [ASCII] encoding of a string s is indicated with the function encode_str(s). ๐ฅ
formats are described using notation from Section 1.3 of [QUIC]. there's also an extension to that notation that expresses the number of bits in a field using a simple mathematical function. math girl era ๐งฎ
3. Key Configuration โจ
okay so a Client needs to get info about the key configuration of the Oblivious Gateway Resource before it can send Encapsulated Requests. and to make sure Clients don't encapsulate messages that other entities can intercept, the key configuration MUST be authenticated and have integrity protection. non-negotiable bestie ๐
this doc doesn't define HOW that acquisition happens. BUT to help with interop, it DOES specify a format for the keys. that way different Client implementations can be configured the same way, and key configurations can be advertised in a consistent format ๐ this format might be used, for example, with HTTPS, as part of a system for configuring or discovering key configurations. just note that such a system needs to think about the potential for key configuration to be used to compromise Client privacy; see Section 7. ๐
a Client might have multiple key configurations to pick from when encapsulating a request. Clients are responsible for picking a preferred key configuration from the ones they support. and they need to consider both the Key Encapsulation Method (KEM) and the combinations of the Key Derivation Function (KDF) and AEAD in that decision ๐ง
3.1. Key Configuration Encoding
a single key configuration has a key identifier, a public key, an identifier for the KEM that the public key uses, and a set of HPKE symmetric algorithms. each symmetric algorithm is an identifier for a KDF plus an identifier for an AEAD. โจ
here's Figure 2 showing a single key configuration:
HPKE Symmetric Algorithms {
HPKE KDF ID (16),
HPKE AEAD ID (16),
}
Key Config {
Key Identifier (8),
HPKE KEM ID (16),
HPKE Public Key (Npk * 8),
HPKE Symmetric Algorithms Length (16) = 4..65532,
HPKE Symmetric Algorithms (32) ...,
}
Figure 2: A Single Key Configuration
so a key configuration has these fields:
- Key Identifier: An 8-bit value that identifies the key used by the Oblivious Gateway Resource. ๐
- HPKE KEM ID: A 16-bit value that identifies the KEM used for the identified key as defined in Section 7.1 of [HPKE] or the "HPKE KEM Identifiers" registry
https://www.iana.org/assignments/hpke. - HPKE Public Key: The public key used by the gateway. The length of the public key is Npk, which is determined by the choice of HPKE KEM as defined in Section 4 of [HPKE]. ๐
- HPKE Symmetric Algorithms Length: A 16-bit integer in network byte order that encodes the length, in bytes, of the HPKE Symmetric Algorithms field that follows. ๐
- HPKE Symmetric Algorithms: One or more pairs of identifiers for the different combinations of HPKE KDF and AEAD that the Oblivious Gateway Resource supports:
- HPKE KDF ID: A 16-bit HPKE KDF identifier as defined in Section 7.2 of [HPKE] or the "HPKE KDF Identifiers" registry
https://www.iana.org/assignments/hpke. - HPKE AEAD ID: A 16-bit HPKE AEAD identifier as defined in Section 7.3 of [HPKE] or the "HPKE AEAD Identifiers" registry
https://www.iana.org/assignments/hpke. ๐
- HPKE KDF ID: A 16-bit HPKE KDF identifier as defined in Section 7.2 of [HPKE] or the "HPKE KDF Identifiers" registry
3.2. Key Configuration Media Type
the "application/ohttp-keys" format is a media type that identifies a serialized collection of key configurations. its content is one or more key configuration encodings (see Section 3.1). each encoded configuration gets prefixed with a 2-byte integer in network byte order that says how long the key configuration is, in bytes. the length-prefixed encodings are concatenated into a list. see Section 9.1 for the definition of the media type ๐
evolution of the key configuration format works by defining NEW formats, identified by NEW media types. very future-proof, very iconic ๐
now here's the part to really hear: a Client that receives an "application/ohttp-keys" object with encoding errors might still be able to recover one or more key configurations. BUT differences in how key configurations get recovered might be exploited to segregate Clients, so Clients MUST discard incorrectly encoded key configuration collections. no recovering, no cap ๐ซ
4. HPKE Encapsulation ๐ฆ
this doc defines how a binary-encoded HTTP message [BINARY] gets encapsulated using HPKE [HPKE]. there are separate media types to tell request and response messages apart:
- An Encapsulated Request format defined in Section 4.1 is identified by the "message/ohttp-req" media type (Section 9.2).
- An Encapsulated Response format defined in Section 4.2 is identified by the "message/ohttp-res" media type (Section 9.3).
alternative encapsulations or message formats are indicated using the media type; see Sections 4.5 and 4.6. ๐ธ
4.1. Request Format
a message in "message/ohttp-req" format protects a binary HTTP request message; see Figure 3. ๐
here's the plaintext Request structure, Figure 3:
Request {
Binary HTTP Message (..),
}
Figure 3: Plaintext Request Structure
this plaintext Request structure gets encapsulated into a "message/ohttp-req" message by generating an Encapsulated Request. an Encapsulated Request is made of a key identifier, HPKE parameters for the chosen KEM, KDF, and AEAD, the encapsulated KEM shared secret (or enc), and an HPKE-protected binary HTTP request message. โจ
Figure 4 shows an Encapsulated Request, and Section 4.3 walks through how to construct and process one:
Encapsulated Request {
Key Identifier (8),
HPKE KEM ID (16),
HPKE KDF ID (16),
HPKE AEAD ID (16),
Encapsulated KEM Shared Secret (8 * Nenc),
HPKE-Protected Request (..),
}
Figure 4: Encapsulated Request
so an Encapsulated Request has a Key Identifier, an HPKE KEM ID, an HPKE KDF ID, an HPKE AEAD ID, an Encapsulated KEM Shared Secret, and an HPKE-Protected Request. the Key Identifier, HPKE KEM ID, HPKE KDF ID, and HPKE AEAD ID fields are defined in Section 3.1. the Encapsulated KEM Shared Secret is the output of the Encap() function for the KEM, which is Nenc bytes long, as defined in Section 4 of [HPKE]. ๐ง๐
4.2. Response Format ๐
Okay so a message in message/ohttp-res format is what protects a binary HTTP response message ๐ (see Figure 5). The plaintext response is just a Binary HTTP Message wrapped up nice and neat:
Response {
Binary HTTP Message (..),
}
Figure 5: Plaintext Response Structure
Next, we take that plaintext Response structure and encapsulate it into a message/ohttp-res message by generating an Encapsulated Response ๐ฆ. An Encapsulated Response has two parts: a nonce and the AEAD-protected binary HTTP response message. It's giving layers, bestie ๐ง
Figure 6 shows what that looks like. Section 4.4 walks you through how to build and process an Encapsulated Response ๐ง
Encapsulated Response {
Nonce (8 * max(Nn, Nk)),
AEAD-Protected Response (..),
}
Figure 6: Encapsulated Response
So yeah, an Encapsulated Response contains a Nonce and an AEAD-Protected Response ๐ The Nonce field is either Nn or Nk bytes long, whichever one is bigger (main character energy for the bigger number ๐). Nn and Nk come from the parameters of the AEAD used in HPKE. You can find that in Section 7.3 of [HPKE] or in the "HPKE AEAD Identifiers" IANA registry at <https://www.iana.org/assignments/hpke>. And just so we're clear, Nn is the size of the AEAD nonce in bytes and Nk is the size of the AEAD key in bytes ๐
4.3. Encapsulation of Requests ๐
Clients encapsulate a request, which we call request, using values from a key configuration ๐ They grab:
- the key identifier from the configuration (key_id) along with the corresponding KEM identified by kem_id,
- the public key from the configuration (pkR), and
- a combo of KDF (identified by kdf_id) and AEAD (identified by aead_id) that the Client picks from the ones in the key configuration.
Then the Client builds an Encapsulated Request, enc_request, from a binary-encoded HTTP request [BINARY] (request), like this:
- Build a message header (hdr) by concatenating the values of key_id, kem_id, kdf_id, and aead_id. That's one 8-bit integer and three 16-bit integers, in that order, each in network byte order ๐งฉ
- Build a sequence of bytes (info) by concatenating the ASCII-encoded string "message/bhttp request", a zero byte, and the header. Heads up: Section 4.6 talks about how other message formats might use a different info value ๐ธ
- Create a sending HPKE context by invoking SetupBaseS() (Section 5.1.1 of [HPKE]) with the receiver's public key pkR and info. This gives you the context sctxt and an encapsulation key enc ๐
- Encrypt request by invoking the Seal() method on sctxt (Section 5.2 of [HPKE]) with empty associated data aad. That gives you the ciphertext ct โจ
- Concatenate hdr, enc, and ct. Ta-da, that's your Encapsulated Request (enc_request) ๐
Note that enc is a fixed length, so there's zero ambiguity when parsing this structure. No cap ๐ง
Here's the same procedure in pseudocode:
hdr = concat(encode(1, key_id),
encode(2, kem_id),
encode(2, kdf_id),
encode(2, aead_id))
info = concat(encode_str("message/bhttp request"),
encode(1, 0),
hdr)
enc, sctxt = SetupBaseS(pkR, info)
ct = sctxt.Seal("", request)
enc_request = concat(hdr, enc, ct)
Now, an Oblivious Gateway Resource undoes all of this to decrypt an Encapsulated Request ๐ To decapsulate an Encapsulated Request, enc_request, it does the following:
- Parse enc_request into key_id, kem_id, kdf_id, aead_id, enc, and ct (the pseudocode calls this function parse()). Then the Oblivious Gateway Resource can find the HPKE private key, skR, that matches key_id ๐ต๏ธโโ๏ธ
- a. If key_id doesn't identify a key that matches the type of kem_id, the Oblivious Gateway Resource returns an error. Rude ๐ โโ๏ธ
- b. If kdf_id and aead_id identify a combo of KDF and AEAD that the Oblivious Gateway Resource isn't willing to use with skR, the Oblivious Gateway Resource returns an error.
- Build a sequence of bytes (info) by concatenating the ASCII-encoded string "message/bhttp request", a zero byte, key_id as an 8-bit integer, plus kem_id, kdf_id, and aead_id as three 16-bit integers ๐ง
- Create a receiving HPKE context, rctxt, by invoking SetupBaseR() (Section 5.1.1 of [HPKE]) with skR, enc, and info ๐ท
- Decrypt ct by invoking the Open() method on rctxt (Section 5.2 of [HPKE]) with an empty associated data aad. That gives you request, or an error if decryption fails. If decryption fails, the Oblivious Gateway Resource returns an error ๐
And the pseudocode for that:
key_id, kem_id, kdf_id, aead_id, enc, ct = parse(enc_request)
info = concat(encode_str("message/bhttp request"),
encode(1, 0),
encode(1, key_id),
encode(2, kem_id),
encode(2, kdf_id),
encode(2, aead_id))
rctxt = SetupBaseR(enc, skR, info)
request, error = rctxt.Open("", ct)
One more thing: the Oblivious Gateway Resource keeps the HPKE context, rctxt, around so it can encapsulate a response later ๐ฆ
4.4. Encapsulation of Responses ๐
Oblivious Gateway Resources make an Encapsulated Response, enc_response, from a binary-encoded HTTP response [BINARY] (response). They use the HPKE receiver context (rctxt) as the HPKE context (context), and here's how:
- Export a secret (secret) from context, using the string "message/bhttp response" as the exporter_context parameter to context.Export. See Section 5.3 of [HPKE]. The length of this secret is max(Nn, Nk), where Nn and Nk are the lengths of the AEAD key and nonce tied to context. Note: Section 4.6 talks about how other message formats might use a different context value ๐ซถ
- Generate a random value of max(Nn, Nk) bytes, called response_nonce ๐ฒ
- Extract a pseudorandom key (prk) using the Extract function from the KDF algorithm associated with context. The ikm input is secret, and the salt input is enc (from enc_request) concatenated with response_nonce ๐ง
- Use the Expand function from that same KDF to create an AEAD key, key, of length Nk (the key length used by the AEAD associated with context). Making aead_key uses the label "key" ๐
- Use the same Expand function to create a nonce, nonce, of length Nn (the nonce length used by the AEAD). Making aead_nonce uses the label "nonce" ๐ช
- Encrypt response by passing aead_key, aead_nonce, an empty aad, and a pt input of response to the AEAD function Seal. That gives you ct ๐
- Concatenate response_nonce and ct to get the Encapsulated Response, enc_response. response_nonce is a fixed length too, so there's no ambiguity parsing either response_nonce or ct ๐
Pseudocode, because you know I love it ๐ค:
secret = context.Export("message/bhttp response", max(Nn, Nk))
response_nonce = random(max(Nn, Nk))
salt = concat(enc, response_nonce)
prk = Extract(salt, secret)
aead_key = Expand(prk, "key", Nk)
aead_nonce = Expand(prk, "nonce", Nn)
ct = Seal(aead_key, aead_nonce, "", response)
enc_response = concat(response_nonce, ct)
Clients decrypt an Encapsulated Response by running the process backwards ๐ They first parse enc_response into response_nonce and ct. Then they follow the same steps to derive aead_key and aead_nonce, using their sending HPKE context, sctxt, as the HPKE context, context.
The Client uses those values to decrypt ct with the AEAD function Open. Decrypting might fail, which looks like this:
response, error = Open(aead_key, aead_nonce, "", ct)
4.5. Request and Response Media Types ๐ฌ
Media types are how we identify Encapsulated Requests and Responses. Check out Sections 9.2 and 9.3 for the definitions of these media types ๐
Evolving the format of Encapsulated Requests and Responses is totally supported. You just define new formats and give them new media types ๐ฑ New media types might use a similar encapsulation with a different HTTP message format than the one in [BINARY]. For guidance on reusing this encapsulation method, see Section 4.6. Or, if you're feeling extra, you can define a brand new encapsulation method altogether โจ
4.6. Repurposing the Encapsulation Format ๐
The encrypted payload of an Oblivious HTTP request and response is a binary HTTP message [BINARY]. The Client and Oblivious Gateway Resource agree on this payload type by putting the media type "message/bhttp" in the HPKE info string for requests and in the HPKE export context string for responses ๐ค
Future specifications can repurpose the encapsulation mechanism described in this document ๐ฆ But they need to define a new media type to do it. The encapsulation process for that content type can follow the same steps, just using new constant strings for the HPKE info and exporter context inputs ๐ง
For example, a future spec might encapsulate DNS messages, which use the "application/dns-message" media type [RFC8484]. To make a new encrypted media type, a spec could use the string "application/dns-message request" (plus a zero byte and the header for the full value) for request encryption, and the string "application/dns-message response" for response encryption ๐
5. HTTP Usage โจ
Okay so a Client talks to the Oblivious Relay Resource by building an Encapsulated Request ๐ and putting it in the content of a POST request to that Oblivious Relay Resource. The request only needs the stuff that actually carries the Encapsulated Request: a method of POST, a target URI of the Oblivious Relay Resource, a header field with the content type (see Section 9.2), and the Encapsulated Request as the request content. Clients MAY add extra fields to that request to the Oblivious Relay Resource ๐. BUT those extra fields MUST be totally independent of the Encapsulated Request, and they MUST be fields the Oblivious Relay Resource will strip off before it forwards the Encapsulated Request on to the target, like the Connection or Proxy-Authorization header fields [HTTP]. No sneaking stuff in, periodt ๐ โโ๏ธ.
The Client role here acts as an HTTP client with respect to both the Oblivious Relay Resource and the Target Resource ๐ . The request the Client makes to the Target Resource is kinda different from the usual HTTP vibes about connections (see Section 3.3 of [HTTP]), because the request and response are encrypted instead of just sent over a connection ๐. The Oblivious Relay Resource and the Oblivious Gateway Resource also act as HTTP clients, toward the Oblivious Gateway Resource and the Target Resource respectively ๐ฆ.
To hit the privacy and security goals of the protocol, a Client also has to follow the guidance in Section 6.1 ๐ซถ.
The Oblivious Relay Resource talks to the Oblivious Gateway Resource as an HTTP client too. It builds a request with the same restrictions as the Client request, except the target URI is now the Oblivious Gateway Resource ๐ธ. The content gets copied straight over from the Client. An Oblivious Relay Resource MAY reject requests that are obviously invalid, like a request with no content ๐. It MUST NOT add information to the request unless the Client is aware of the type of information that might get added. See Section 6.2 for more on relay responsibilities ๐.
When a response comes back from the Oblivious Gateway Resource, the Oblivious Relay Resource forwards it following the rules of an HTTP proxy; see Section 7.6 of [HTTP] โจ. If there's a timeout or an error, the Oblivious Relay Resource can generate a response with an appropriate status code ๐.
To hit the privacy and security goals, the Oblivious Relay Resource also needs to follow the guidance in Section 6.2 ๐ฅ.
An Oblivious Gateway Resource acts as a gateway for requests to the Target Resource (see Section 7.6 of [HTTP]) ๐ง. The one exception is that anything it forwards in a response MUST be encapsulated, unless it's responding to errors that don't relate to processing the contents of the Encapsulated Request. See Section 5.2 for those ๐.
If an Oblivious Gateway Resource gets any response from the Target Resource, it sends back a single 200 response containing the Encapsulated Response ๐. Just like the Client's request, this response MUST only contain the fields needed to carry the Encapsulated Response: a 200 status code, a header field indicating the content type, and the Encapsulated Response as the response content ๐. Same as with requests, additional fields MAY be used to convey information that doesn't reveal anything about the Encapsulated Response ๐.
An Oblivious Gateway Resource that doesn't get a response can generate its own response with an appropriate error status code (like 504 (Gateway Timeout); see Section 15.6.5 of [HTTP]) ๐ญ. That response then gets encapsulated the same way as a successful one โจ.
To hit the privacy and security goals, the Oblivious Gateway Resource also needs to follow the guidance in Section 6.3 ๐ .
5.1. Informational Responses
Okay, real talk: this encapsulation does NOT allow progressive processing of responses ๐ โโ๏ธ. Even though the binary HTTP response format can include informational (1xx) status codes, the AEAD encapsulation can't be removed until the entire message has arrived ๐.
This means the Expect header field with 100-continue (see Section 10.1.1 of [HTTP]) can't be used ๐. Clients MUST NOT construct a request that includes a 100-continue expectation, and the Oblivious Gateway Resource MUST generate an error if it does receive a 100-continue expectation ๐ซ.
5.2. Errors
Here's the rule: a server that receives an invalid message for any reason MUST generate an HTTP response with a 4xx status code ๐ โโ๏ธ.
Errors detected by the Oblivious Relay Resource, and errors the Oblivious Gateway Resource detects before it removes protection (including when it can't remove the encapsulation for any reason), result in the status code being sent unprotected, as the response to the POST request made to that resource ๐ซฃ.
Errors the Oblivious Gateway Resource detects after it has successfully removed the encapsulation, and errors detected by the Target Resource, MUST be sent in an Encapsulated Response ๐. This might happen because the Encapsulated Request is malformed, or because the Target Resource doesn't produce a response ๐. Either way, the Oblivious Gateway Resource can generate a response with an appropriate error status code (like 400 (Bad Request) or 504 (Gateway Timeout); see Sections 15.5.1 and 15.6.5 of [HTTP], respectively) ๐. That response gets encapsulated the same way as a successful response ๐.
Errors in the encapsulation of requests mean responses can't be encapsulated ๐ฌ. This includes cases where the key configuration is incorrect or outdated ๐. The Oblivious Gateway Resource can generate and send a response with a 4xx status code to the Oblivious Relay Resource. That response MAY be forwarded to the Client, or the Oblivious Relay Resource can treat it as a failure ๐ธ. If a Client gets a response that is not an Encapsulated Response, it could mean the Client configuration used to build the request is incorrect or out of date โญ.
5.3. Signaling Key Configuration Problems
The problem type [PROBLEM] of https://iana.org/assignments/http-problem-types#ohttp-key is defined in this section ๐ง. An Oblivious Gateway Resource MAY use this problem type in a response to say that an Encapsulated Request used an outdated or incorrect key configuration ๐.
Figure 7 shows an example response in HTTP/1.1 format ๐:
HTTP/1.1 400 Bad Request
Date: Mon, 07 Feb 2022 00:28:05 GMT
Content-Type: application/problem+json
Content-Length: 106
{"type":"https://iana.org/assignments/http-problem-types#ohttp-key",
"title": "key identifier unknown"}
Figure 7: Example Rejection of Key Configuration
Heads up ๐จ: this response can't be encrypted, so it might not reach the Client. A Client can't rely on the Oblivious Gateway Resource using this problem type ๐ญ. A Client might also be configured to ignore responses that aren't encapsulated, since they might be watched or changed by an Oblivious Relay Resource ๐๏ธ. One way a Client might manage the risk of an outdated key configuration is a heuristic: it periodically refreshes its key configuration if it gets a response with an error status code that wasn't encapsulated ๐.
6. Security Considerations ๐
Alright, the vibe here: a Client wants to make a request to an Oblivious Gateway Resource that gets forwarded to a Target Resource ๐ฆ. The Client wants to do this without linking that request to either of the following:
- The identity at the network and transport layer of the Client (that is, the Client IP address and TCP or UDP port number the Client uses to create a connection) ๐.
- Any other request the Client might have made in the past or might make in the future ๐ฐ๏ธ.
To make sure of that, the Client picks a relay (the one serving the Oblivious Relay Resource) that it trusts to protect this information by forwarding the Encapsulated Request and Response without passing it to the server (the one serving the Oblivious Gateway Resource) ๐ก๏ธ.
In this section, we're looking at a deployment with three entities ๐ฏ:
- A Client makes requests and receives responses ๐.
- A relay operates the Oblivious Relay Resource ๐.
- A server operates both the Oblivious Gateway Resource and the Target Resource ๐ฅ๏ธ.
Section 6.10 talks about the security implications when different servers operate the Oblivious Gateway Resource and the Target Resource ๐.
Requests from the Client to the Oblivious Relay Resource, and from the Oblivious Relay Resource to the Oblivious Gateway Resource, MUST use HTTPS so that unlinkability holds even when a network observer is watching ๐.
To hit the stated privacy goals, the Oblivious Relay Resource can't be run by the same entity as the Oblivious Gateway Resource ๐ โโ๏ธ. That said, colocating the Oblivious Gateway Resource and the Target Resource makes the interactions between them simpler, and it doesn't affect Client privacy ๐.
Because of this setup, Oblivious HTTP prevents the linkability described above. Informally, that means ๐:
- Requests and responses are known only to Clients and Oblivious Gateway Resources. In particular, the Oblivious Relay Resource knows the origin and destination of an Encapsulated Request and Response, yet it doesn't know the decrypted contents ๐ค. Likewise, Oblivious Gateway Resources learn only the Oblivious Relay Resource and the decrypted request. No entity other than the Client can see the plaintext request and response and attribute them to the Client ๐ซข.
- Oblivious Gateway Resources, and therefore Target Resources, can't link requests from the same Client unless there are unique per-Client keys ๐.
Traffic analysis that could affect these properties is outside the scope of this document; see Section 6.2.3 ๐.
A formal analysis of Oblivious HTTP is in [OHTTP-ANALYSIS] ๐โจ.
6.1. Client Responsibilities โจ
okay so, Clients don't authenticate the Target Resource when they use Oblivious HTTP ๐ which means Clients MUST have some mechanism to authorize an Oblivious Gateway Resource for use with a Target Resource. One possible means of authorization is an allowlist. This makes sure Oblivious Gateway Resources are not misused to forward traffic to arbitrary Target Resources ๐ . Section 6.3 describes similar responsibilities that apply to Oblivious Gateway Resources too.
Clients MUST ensure that the key configuration they select for generating Encapsulated Requests is integrity protected and authenticated, so that it can be attributed to the Oblivious Gateway Resource ๐. See Section 3.
Since Clients connect directly to the Oblivious Relay Resource instead of the Target Resource, app configs where Clients make policy decisions about target connections (like certificate pinning) are incompatible with Oblivious HTTP ๐ญ. In those cases, alternative technologies such as HTTP CONNECT (Section 9.3.6 of [HTTP]) can be used. Applications could implement related policies on key configurations and relay connections, though these might not provide the same properties as policies enforced directly on target connections. Instead, when this difference matters, applications can connect directly to the target, at the cost of either privacy or performance.
Clients can't carry connection-level state between requests, since they only establish direct connections to the relay responsible for the Oblivious Relay Resource ๐ฆ. However, the content of requests might be used by a server to correlate requests. Cookies [COOKIES] are the most obvious feature that could be used to correlate requests, but any identity information and authentication credentials might have the same effect. Clients also need to treat information learned from responses with similar care when constructing subsequent requests, which includes the identity of resources.
Clients MUST generate a new HPKE context for every request, using a good source of entropy [RANDOM] for generating keys ๐. Key reuse not only risks requests being linked, but could also expose request and response contents to the relay. Not it, bestie ๐ โโ๏ธ.
The request the Client sends to the Oblivious Relay Resource only requires minimal information; see Section 5. The request that carries the Encapsulated Request and is sent to the Oblivious Relay Resource MUST NOT include identifying information, unless the Client can trust that this information is removed by the relay. A Client MAY include information only for the Oblivious Relay Resource in header fields identified by the Connection header field, if it trusts the relay to remove these, as required by Section 7.6.1 of [HTTP]. The Client needs to trust that the relay does not replicate the source addressing information in the request it forwards ๐.
Clients rely on the Oblivious Relay Resource to forward Encapsulated Requests and Responses. However, the relay can only refuse to forward messages. It can't inspect or modify the contents of Encapsulated Requests or Responses ๐.
6.2. Relay Responsibilities ๐ธ
The relay that serves the Oblivious Relay Resource has a very simple job. For each request it receives, it makes a request of the Oblivious Gateway Resource that includes the same content. When it receives a response, it sends a response to the Client that includes the content of the response from the Oblivious Gateway Resource.
When forwarding a request, the relay MUST follow the forwarding rules in Section 7.6 of [HTTP]. A generic HTTP intermediary implementation is suitable for serving an Oblivious Relay Resource, but extra care is needed to make sure Client privacy is maintained ๐ง.
Firstly, a generic implementation will forward unknown fields. For Oblivious HTTP, an Oblivious Relay Resource SHOULD NOT forward unknown fields. Though Clients aren't expected to include fields that might contain identifying information, removing unknown fields removes this privacy risk ๐ซถ.
Secondly, generic implementations are often configured to augment requests with information about the Client, such as the Via field or the Forwarded field [FORWARDED]. A relay MUST NOT add information when forwarding requests that might be used to identify Clients, except for information that a Client is aware of; see Section 6.2.1 ๐.
Finally, a relay can also generate responses. It's assumed not to be able to examine the content of a request (other than to observe the choice of key identifier, KDF, and AEAD), so it's also assumed that it cannot generate an Encapsulated Response ๐.
6.2.1. Differential Treatment ๐
A relay MAY add information to requests if the Client is aware of the nature of the information that could be added. Any addition MUST NOT include information that uniquely and permanently identifies the Client, including any pseudonymous identifier. Information added by the relay -- beyond what is already revealed through Encapsulated Requests from Clients -- can reduce the size of the anonymity set of Clients at a gateway.
A Client doesn't need to know the exact value added for each request, but it does need to know the range of possible values the relay might use. How a Client might learn about added information is not defined in this document.
Moreover, relays MAY apply differential treatment to Clients that engage in abusive behavior, e.g., by sending too many requests compared to other Clients, or in response to rate limits signaled from the gateway. Any such differential treatment can reveal information to the gateway that would not be revealed otherwise, and therefore reduce the size of the anonymity set of Clients using a gateway. For example, if a relay chooses to rate limit or block an abusive Client, that means any Client requests that aren't treated this way are known to be non-abusive by the gateway. Clients need to consider the likelihood of such differential treatment and the privacy risks when using a relay ๐จ.
Some patterns of abuse can't be detected without access to the request that is made to the target. This means only the gateway or the target is in a position to identify abuse. A gateway MAY send signals toward the relay to provide feedback about specific requests. For example, a gateway could respond differently to requests it cannot decapsulate, as mentioned in Section 5.2. A relay that acts on this feedback could -- either inadvertently or by design -- lead to Client deanonymization ๐ฑ.
6.2.2. Denial of Service ๐ก๏ธ
As there are privacy benefits from having a large rate of requests forwarded by the same relay (see Section 6.2.3), servers that operate the Oblivious Gateway Resource might need an arrangement with Oblivious Relay Resources. This arrangement might be necessary to prevent the large volume of requests from being classified as an attack by the server.
If a server accepts a larger volume of requests from a relay, it needs to trust that the relay does not allow abusive levels of request volumes from Clients. That is, if a server allows requests from the relay to be exempt from rate limits, the server might want to ensure that the relay applies a rate-limiting policy that is acceptable to the server ๐ .
Servers that enter into an agreement with a relay that enables a higher request rate might choose to authenticate the relay to enable the higher rate ๐.
6.2.3. Traffic Analysis ๐ต๏ธโโ๏ธ
Using HTTPS protects information about which resources are the subject of a request, and it prevents a network observer from being able to trivially correlate messages on either side of a relay. However, using HTTPS does not prevent traffic analysis by such network observers ๐๏ธ.
The time at which Encapsulated Request or Response messages are sent can reveal information to a network observer. Though messages exchanged between the Oblivious Relay Resource and the Oblivious Gateway Resource might be sent over a single connection, traffic analysis could still be used to match messages that are forwarded by the relay ๐ง.
A relay could, as part of its function, delay requests before forwarding them. Delays might increase the anonymity set into which each request is attributed. Any delay also increases the time a Client waits for a response, so delays SHOULD only be added with the consent -- or at least awareness -- of Clients โณ.
A relay that forwards large volumes of exchanges can provide better privacy by providing larger sets of messages that need to be matched ๐.
Traffic analysis isn't restricted to network observers. A malicious Oblivious Relay Resource could use traffic analysis to learn information about otherwise encrypted requests and responses relayed between Clients and gateways. An Oblivious Relay Resource terminates TLS connections from Clients, so it sees message boundaries. This privileged position allows for richer feature extraction from encrypted data, which might improve traffic analysis. Yikes ๐.
Clients and Oblivious Gateway Resources can use padding to reduce the effectiveness of traffic analysis. Padding is a capability provided by binary HTTP messages; see Section 3.8 of [BINARY]. If the encapsulation method described in this document is used to protect a different message type (see Section 4.6), that message format might need to include padding support. Oblivious Relay Resources can also use padding for the same reason, but they need to operate at the HTTP layer since they cannot manipulate binary HTTP messages; for example, see Section 10.7 of [HTTP/2] or Section 10.7 of [HTTP/3]).
6.3. Server Responsibilities ๐ฆข
The Oblivious Gateway Resource can be operated by a different entity than the Target Resource. However, this means the Client needs to trust the Oblivious Gateway Resource not to modify requests or responses. This analysis concerns a deployment scenario where a single server provides both the Oblivious Gateway Resource and the Target Resource ๐.
A server that operates both Oblivious Gateway and Target Resources is responsible for removing request encryption, generating a response to the Encapsulated Request, and encrypting the response ๐ฅ.
Servers should account for traffic analysis based on response size or generation time. Techniques such as padding or timing delays can help protect against such attacks; see Section 6.2.3 ๐.
If separate entities provide the Oblivious Gateway Resource and the Target Resource, these entities might need an arrangement similar to the one between server and relay for managing denial of service; see Section 6.2.2. Moreover, the Oblivious Gateway Resource SHOULD have some mechanism to ensure it is not misused as a relay for HTTP messages to an arbitrary Target Resource, such as an allowlist ๐ท.
Non-secure requests -- such as those with the "http" scheme as opposed to the "https" scheme -- SHOULD NOT be used if the Oblivious Gateway and Target Resources are not on the same origin. If messages are forwarded between these resources without the protections afforded by HTTPS, they could be inspected or modified by a network attacker ๐ซ. Note that a request could be forwarded without protection if the two resources share an origin.
6.4. Key Management โจ
okay so bestie, the Oblivious Gateway Resource has to have a plan for swapping out its keys ๐๐ . This might mean regularly replacing keys, and each new one can get its own new key identifier ๐ฆ. If an Oblivious Gateway Resource gets a request with a key identifier it doesn't understand, or one that matches a key that's already been replaced, the server can respond with an HTTP 422 (Unprocessable Content) status code ๐.
A server can also use a 422 status code if it does have a key matching the key identifier, but the Encapsulated Request just can't be decrypted with that key ๐.
A server MUST ensure that the HPKE keys it uses are not valid for any other protocol that uses HPKE with the "message/bhttp request" label. ๐จ Like, this is a big deal, no cap. Designers of protocols that reuse this encryption format, especially new versions of this protocol, can get key diversity by picking a different label when they use HPKE ๐. The "message/bhttp response" label was chosen just for symmetry ๐. It only gives key diversity inside the HPKE context made with the "message/bhttp request" label, see Section 4.6 ๐.
6.5. Replay Attacks ๐
A server is responsible for either rejecting replayed requests or making sure that replays don't adversely affect Clients or resources. Main character responsibility energy ๐.
Encapsulated Requests can be copied and replayed by the Oblivious Relay Resource ๐ญ. The threat model for Oblivious HTTP allows for the possibility that an Oblivious Relay Resource might replay requests. Furthermore, if a Client sends an Encapsulated Request in TLS early data (see Section 8 of [TLS] and [RFC8470]), a network-based adversary might be able to cause the request to be replayed ๐. In both cases, the effect of a replay attack and the mitigations that might be used are similar to TLS early data ๐ฆ.
It is the responsibility of the application that uses Oblivious HTTP to either reject replayed requests or make sure replayed requests have no adverse effect on its operation โจ. This section describes some approaches that are universally applicable, plus suggestions for more targeted techniques ๐ซถ.
A Client or Oblivious Relay Resource MUST NOT automatically attempt to retry a failed request unless it receives a positive signal indicating that the request was not processed or forwarded ๐. The HTTP/2 REFUSED_STREAM error code (Section 8.1.4 of [HTTP/2]), the HTTP/3 H3_REQUEST_REJECTED error code (Section 8.1 of [HTTP/3]), or a GOAWAY frame with a low enough identifier (in either protocol version) are all sufficient signals that no processing occurred ๐ธ. HTTP/1.1 [HTTP/1.1] provides no equivalent signal, sadly ๐ฅบ. Connection failures or interruptions are NOT sufficient signals that no processing occurred, so don't be fooled ๐ .
The anti-replay mechanisms described in Section 8 of [TLS] are generally applicable to Oblivious HTTP requests ๐ง. The encapsulated keying material (or enc) can be used in place of a nonce to uniquely identify a request ๐. This value is high-entropy and freshly generated for every request, so two valid requests will have different values with overwhelming probability ๐.
The mechanism TLS uses for managing differences in Client and server clocks cannot be used, because it depends on being able to observe previous interactions ๐. Oblivious HTTP explicitly prevents that kind of linkability, so it's not an option here ๐ซ.
The considerations in [RFC8470] as they relate to managing the risk of replay also apply, though there is no option to delay the processing of a request โญ.
Limiting requests to those with safe methods might not be satisfactory for some applications, especially ones that submit data to a server ๐. Idempotent methods might help a bit with managing replay risk, but it's important to recognize that different idempotent requests can be combined to become not idempotent ๐.
Even without replay prevention, the server-chosen response_nonce field makes sure responses have unique AEAD keys and nonces even when requests get replayed ๐๐.
6.5.1. Use of Date for Anti-replay ๐
Clients SHOULD include a Date header field in Encapsulated Requests, unless the Client has prior knowledge indicating that the Oblivious Gateway Resource does not use Date for anti-replay purposes โฐ.
Even though HTTP requests often don't include a Date header field, a server can use that value to limit how many requests it needs to track if it's trying to prevent replay attacks ๐ง .
An Oblivious Gateway Resource can keep state for requests over a small window of time in which it wants to accept requests ๐ช. It can store all requests it processes within this window. Storing just the enc field of a request, which should be unique to each request, is enough ๐. The Oblivious Gateway Resource can reject any request that matches one previously answered within that window, or if the Date header field from the decrypted request is outside the current time window ๐ซ.
Oblivious Gateway Resources might need to allow for the time it takes requests to arrive from the Client, so the window has to be big enough to cover clock differences ๐ฐ๏ธ. Not allowing enough tolerance for time differences could get valid requests unnecessarily rejected ๐ค. Beyond allowing for multiple round-trip times (to account for retransmission), network delays are unlikely to decide the size of the window, unless all potential Clients are known to have excellent timekeeping โฑ๏ธ. A specific window size might need to be figured out experimentally ๐งช.
Oblivious Gateway Resources MUST NOT treat the time window as secret information ๐ซฃ. An attacker can actively probe with different values for the Date field to find out the time window over which the server will accept responses ๐.
6.5.2. Correcting Clock Differences โณ
An Oblivious Gateway Resource can reject requests that contain a Date value outside its active window with a 400 series status code ๐ . The problem type [PROBLEM] of "https://iana.org/assignments/http-problem-types#date" exists so the server can signal that the Date value in the request was unacceptable ๐ฉ.
Figure 8 shows an example response in HTTP/1.1 format ๐.
HTTP/1.1 400 Bad Request
Date: Mon, 07 Feb 2022 00:28:05 GMT
Content-Type: application/problem+json
Content-Length: 128
{"type":"https://iana.org/assignments/http-problem-types#date",
"title": "date field in request outside of acceptable range"}
Figure 8: Example Rejection of Request Date Field
Clock disagreements are unlikely if both Client and Oblivious Gateway Resource have a good source of time; see [NTP] ๐. However, clock differences are known to be super commonplace, see Section 7.1 of [CLOCKSKEW] ๐.
Including a Date header field in the response lets the Client fix clock errors by retrying the same request using the Date value the Oblivious Gateway Resource provided ๐ง. The value of the Date field can be copied if the response is fresh, or adjusted based on the Age field otherwise; see Section 4.2 of [HTTP-CACHING] ๐งฎ. When retrying a request, the Client MUST create a fresh encryption of the modified request, using a new HPKE context ๐.
+---------+ +-------------------+ +----------+
| Client | | Relay and Gateway | | Target |
| | | Resources | | Resource |
+----+----+ +----+-----------+--+ +----+-----+
| | | |
| | | |
| Request | | |
+============================>+------------->|
| | | |
| | | 400 Response |
| | | + Date |
|<============================+<-------------+
| | | |
| Request | | |
| + Updated Date | | |
+============================>+------------->|
| | | |
Figure 9: Retrying with an Updated Date Field
Retrying immediately lets the Oblivious Gateway Resource measure the round-trip time to the Client โฒ๏ธ. That observed delay might reveal something about where the Client is ๐. Clients could delay retries to add some uncertainty to any observed delay ๐.
Intermediaries can sometimes rewrite the Date field when forwarding responses ๐. This might cause problems if the Oblivious Gateway Resource and intermediary clocks differ enough to get the retry rejected ๐ฌ. So, Clients MUST NOT retry a request with an adjusted date more than once ๐.
Oblivious Gateway Resources that condition their responses on the Date header field SHOULD either make sure intermediaries don't cache responses (by including a Cache-Control directive of no-store), or designate the response as conditional on the value of the Date request header field (by including the token "date" in a Vary header field) ๐๏ธ.
Clients MUST NOT use the date provided by the Oblivious Gateway Resource for any other purpose, including future requests to any resource ๐ โโ๏ธ. Any request that uses information provided by the Oblivious Gateway Resource might be correlated using that information ๐ต๏ธ.
6.6. Forward Secrecy ๐๏ธ
This document does not provide forward secrecy for either requests or responses during the lifetime of the key configuration ๐ข. A measure of forward secrecy can be provided by generating a new key configuration and then deleting the old keys after a suitable period ๐.
6.7. Post-Compromise Security ๐ก๏ธ
This design does not provide post-compromise security for responses ๐ฅ.
A Client only needs to retain keying material that might be used to compromise the confidentiality and integrity of a response until that response is consumed, so there's negligible risk associated with a Client compromise ๐.
A server keeps a secret key that might be used to remove protection from messages over much longer periods โณ. A server compromise that gave access to the Oblivious Gateway Resource secret key could let an attacker recover the plaintext of all requests sent toward affected keys, and all of the responses that were generated ๐ฑ.
Even if server keys are compromised, an adversary cannot access messages exchanged by the Client with the Oblivious Relay Resource, because those messages are protected by TLS ๐. Using a compromised key also requires that the Oblivious Relay Resource cooperate with the attacker, or that the attacker can compromise these TLS connections ๐ธ๏ธ.
The total number of messages affected by server key compromise can be limited by regularly rotating server keys ๐.
6.8. Client Clock Exposure ๐ฐ๏ธ๐
Including a Date field in requests reveals some information about the Client's clock โฐ. This might be used to fingerprint Clients [UWT] or to identify Clients that are vulnerable to attacks that depend on incorrect clocks ๐ฏ.
Clients can randomize the value they provide for Date to hide the true value of their clock and reduce the chance of linking requests over time ๐ฒ. However, this increases the risk that their request is rejected as outside the acceptable window ๐ตโ๐ซ.
6.9. Media Type Security
The key configuration media type defined in Section 3.2 represents keying material. The content of this media type is not active (see Section 4.6 of [RFC6838]), but it governs how a Client might interact with an Oblivious Gateway Resource. The security implications of processing it are described in Section 6.1; privacy implications are described in Section 7.
The security implications of handling the message media types defined in Section 4.5 is covered in other parts of this section in more detail. However, these message media types are also encrypted encapsulations of HTTP requests and responses.
HTTP messages contain content, which can use any media type. In particular, requests are processed by an Oblivious Target Resource, which -- as an HTTP resource -- defines how content is processed; see Section 3.1 of [HTTP]. HTTP clients can also use resource identity and response content to determine how content is processed. Consequently, the security considerations of Section 17 of [HTTP] also apply to the handling of the content of these media types.
6.10. Separate Gateway and Target
This document generally assumes that the same entity operates the Oblivious Gateway Resource and the Target Resource. However, as the Oblivious Gateway Resource performs generic HTTP processing, the use of forwarding cannot be completely precluded.
The scheme specified in the Encapsulated Request determines the security requirements for any protocol that is used between the Oblivious Gateway and Target Resources. Using HTTPS is RECOMMENDED; see Section 6.3.
A Target Resource that is operated on a different server from the Oblivious Gateway Resource is an ordinary HTTP resource. A Target Resource can privilege requests that are forwarded by a given Oblivious Gateway Resource if it trusts the operator of the Oblivious Gateway Resource to only forward requests that meet the expectations of the Target Resource. Otherwise, the Target Resource treats requests from an Oblivious Gateway Resource no differently than any other HTTP client.
For instance, an Oblivious Gateway Resource might -- possibly with the help of Oblivious Relay Resources -- be trusted not to forward an excessive volume of requests. This might allow the Target Resource to accept a greater volume of requests from that Oblivious Gateway Resource relative to other HTTP clients.
An Oblivious Gateway Resource could implement policies that improve the ability of the Target Resource to implement policy exemptions, such as only forwarding requests toward specific Target Resources according to an allowlist; see Section 6.3.
7. Privacy Considerations โจ
One goal of this design is that independent Client requests are only linkable by their content. ๐ฆ However, the choice of Client configuration might be used to correlate requests. A Client configuration includes the Oblivious Relay Resource URI, the Oblivious Gateway key configuration, and the Oblivious Gateway Resource URI. A configuration is active if Clients can successfully use it for interacting with a target.
Oblivious Relay and Gateway Resources can identify when requests use the same configuration by matching the key identifier from the key configuration or the Oblivious Gateway Resource URI. The Oblivious Gateway Resource might use the source address of requests to correlate requests that use an Oblivious Relay Resource run by the same operator. If the Oblivious Gateway Resource is willing to use trial decryption, requests can be further separated into smaller groupings based on active configurations that clients use. ๐ต๏ธโโ๏ธ
Each active Client configuration partitions the Client anonymity set. In practice, it is infeasible to reduce the number of active configurations to one. Enabling diversity in choice of Oblivious Relay Resource naturally increases the number of active configurations. More than one configuration might need to be active to allow for key rotation and server maintenance. ๐
Client privacy depends on having each configuration used by many other Clients. It is critical to prevent the use of unique Client configurations, which might be used to track individual Clients, but it is also important to avoid creating small groupings of Clients that might weaken privacy protections. ๐
A specific method for a Client to acquire configurations is not included in this specification. Applications using this design MUST provide accommodations to mitigate tracking using Client configurations. [CONSISTENCY] provides options for ensuring that Client configurations are consistent between Clients.
The content of requests or responses, if used in forming new requests, can be used to correlate requests. This includes obvious methods of linking requests, like cookies [COOKIES], but it also includes any information in either message that might affect how subsequent requests are formulated. For example, [FIELDING] describes how interactions that are individually stateless can be used to build a stateful system when a Client acts on the content of a response. ๐
8. Operational and Deployment Considerations ๐
This section discusses various operational and deployment considerations.
8.1. Performance Overhead โฑ๏ธ
Using Oblivious HTTP adds both cryptographic overhead and latency to requests relative to a simple HTTP request-response exchange. Deploying relay services that are on path between Clients and servers avoids adding significant additional delay due to network topology. A study of a similar system [ODOH-PETS] found that deploying proxies close to servers was most effective in minimizing additional latency. ๐
8.2. Resource Mappings ๐บ๏ธ
This protocol assumes a fixed, one-to-one mapping between the Oblivious Relay Resource and the Oblivious Gateway Resource. This means that any Encapsulated Request sent to the Oblivious Relay Resource will always be forwarded to the Oblivious Gateway Resource. This constraint was imposed to simplify relay configuration and mitigate against the Oblivious Relay Resource being used as a generic relay for unknown Oblivious Gateway Resources. The relay will only forward for Oblivious Gateway Resources that it has explicitly configured and allowed.
It is possible for a server to be configured with multiple Oblivious Relay Resources, each for a different Oblivious Gateway Resource as needed. If the goal is to support a large number of Oblivious Gateway Resources, Clients might be provided with a URI template [TEMPLATE], from which multiple Oblivious Relay Resources could be constructed.
8.3. Network Management ๐
Oblivious HTTP might be incompatible with network interception regimes, such as those that rely on configuring Clients with trust anchors and intercepting TLS connections. While TLS might be intercepted successfully, interception middlebox devices might not receive updates that would allow Oblivious HTTP to be correctly identified using the media types defined in Sections 9.2 and 9.3.
Oblivious HTTP has a simple key management design that is not trivially altered to enable interception by intermediaries. Clients that are configured to enable interception might choose to disable Oblivious HTTP in order to ensure that content is accessible to middleboxes. ๐
9. IANA Considerations ๐
IANA has registered the following media types in the "Media Types" registry at https://iana.org/assignments/media-types, following the procedures of [RFC6838]: "application/ohttp-keys" (Section 9.1), "message/ohttp-req" (Section 9.2), and "message/ohttp-res" (Section 9.3).
IANA has added the following types to the "HTTP Problem Types" registry at https://iana.org/assignments/http-problem-types: "date" (Section 9.4) and "ohttp-key" (Section 9.5).
9.1. application/ohttp-keys Media Type ๐
The "application/ohttp-keys" media type identifies a key configuration used by Oblivious HTTP.
Type name: application
Subtype name: ohttp-keys
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: "binary"
Security considerations: See Section 6.9
Interoperability considerations: N/A
Published specification: RFC 9458
Applications that use this media type: This type identifies a key
configuration as used by Oblivious HTTP and applications that use
Oblivious HTTP.
Fragment identifier considerations: N/A
Additional information:
Magic number(s): N/A
Deprecated alias names for this type: N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person and email address to contact for further information:
See Authors' Addresses section
Intended usage: COMMON
Restrictions on usage: N/A
Author: See Authors' Addresses section
Change controller: IETF
9.2. message/ohttp-req Media Type ๐
The "message/ohttp-req" identifies an encrypted binary HTTP request. This is a binary format that is defined in Section 4.3.
Type name: message
Subtype name: ohttp-req
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: "binary"
Security considerations: See Section 6.9
Interoperability considerations: N/A
Published specification: RFC 9458
Applications that use this media type: Oblivious HTTP and
applications that use Oblivious HTTP use this media type to
identify encapsulated binary HTTP requests.
Fragment identifier considerations: N/A
Additional information:
Magic number(s): N/A
Deprecated alias names for this type: N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person and email address to contact for further information:
See Authors' Addresses section
Intended usage: COMMON
Restrictions on usage: N/A
Author: See Authors' Addresses section
Change controller: IETF
9.3. message/ohttp-res Media Type ๐
The "message/ohttp-res" identifies an encrypted binary HTTP response. This is a binary format that is defined in Section 4.4.
Type name: message
Subtype name: ohttp-res
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: "binary"
Security considerations: See Section 6.9
Interoperability considerations: N/A
Published specification: RFC 9458
Applications that use this media type: Oblivious HTTP and
applications that use Oblivious HTTP use this media type to
identify encapsulated binary HTTP responses.
Fragment identifier considerations: N/A
Additional information:
Magic number(s): N/A
Deprecated alias names for this type: N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person and email address to contact for further information:
See Authors' Addresses section
Intended usage: COMMON
Restrictions on usage: N/A
Author: See Authors' Addresses section
Change controller: IETF
9.4. Registration of "date" Problem Type ๐
IANA has added a new entry in the "HTTP Problem Types" registry established by [PROBLEM].
Type URI: https://iana.org/assignments/http-problem-types#date
Title: Date Not Acceptable
Recommended HTTP Status Code: 400
Reference: Section 6.5.2 of RFC 9458
9.5. Registration of "ohttp-key" Problem Type ๐
IANA has added a new entry in the "HTTP Problem Types" registry established by [PROBLEM].
Type URI: https://iana.org/assignments/http-problem-types#ohttp-key
Title: Oblivious HTTP key configuration not acceptable
Recommended HTTP Status Code: 400
Reference: Section 5.3 of RFC 9458
10. References ๐
10.1. Normative References ๐
These are the must-reads, the foundations this whole spec stands on ๐งฑโจ
[ASCII] Cerf, V., "ASCII format for network interchange", STD 80, RFC 20, DOI 10.17487/RFC0020, October 1969, https://www.rfc-editor.org/info/rfc20.
[BINARY] Thomson, M. and C. A. Wood, "Binary Representation of HTTP Messages", RFC 9292, DOI 10.17487/RFC9292, August 2022, https://www.rfc-editor.org/info/rfc9292.
[HPKE] Barnes, R., Bhargavan, K., Lipp, B., and C. Wood, "Hybrid Public Key Encryption", RFC 9180, DOI 10.17487/RFC9180, February 2022, https://www.rfc-editor.org/info/rfc9180.
[HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022, https://www.rfc-editor.org/info/rfc9110.
[HTTP-CACHING] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Caching", STD 98, RFC 9111, DOI 10.17487/RFC9111, June 2022, https://www.rfc-editor.org/info/rfc9111.
[PROBLEM] Nottingham, M., Wilde, E., and S. Dalal, "Problem Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023, https://www.rfc-editor.org/info/rfc9457.
[QUIC] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, May 2021, https://www.rfc-editor.org/info/rfc9000.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, https://www.rfc-editor.org/info/rfc2119.
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, https://www.rfc-editor.org/info/rfc6838.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, https://www.rfc-editor.org/info/rfc8174.
[RFC8470] Thomson, M., Nottingham, M., and W. Tarreau, "Using Early Data in HTTP", RFC 8470, DOI 10.17487/RFC8470, September 2018, https://www.rfc-editor.org/info/rfc8470.
[TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, https://www.rfc-editor.org/info/rfc8446.
10.2. Informative References ๐ง
These ones are the extra reading for the curious ๐ค๐ They're not strictly required, but they're seriously worth a peek if you want the whole story ๐
[CLOCKSKEW] Acer, M., Stark, E., Felt, A., Fahl, S., Bhargava, R., Dev, B., Braithwaite, M., Sleevi, R., and P. Tabriz, "Where the Wild Warnings Are: Root Causes of Chrome HTTPS Certificate Errors", Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security, DOI 10.1145/3133956.3134007, October 2017, https://doi.org/10.1145/3133956.3134007.
[CONSISTENCY] Davidson, A., Finkel, M., Thomson, M., and C. A. Wood, "Key Consistency and Discovery", Work in Progress, Internet-Draft, draft-ietf-privacypass-key-consistency-01, 10 July 2023, https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01.
[COOKIES] Barth, A., "HTTP State Management Mechanism", RFC 6265, DOI 10.17487/RFC6265, April 2011, https://www.rfc-editor.org/info/rfc6265.
[DMS2004] Dingledine, R., Mathewson, N., and P. Syverson, "Tor: The Second-Generation Onion Router", May 2004, https://svn.torproject.org/svn/projects/design-paper/tor-design.html.
[FIELDING] Fielding, R. T., "Architectural Styles and the Design of Network-based Software Architectures", January 2000, https://www.ics.uci.edu/~fielding/pubs/dissertation/fielding_dissertation.pdf.
[FORWARDED] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", RFC 7239, DOI 10.17487/RFC7239, June 2014, https://www.rfc-editor.org/info/rfc7239.
[HTTP/1.1] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, June 2022, https://www.rfc-editor.org/info/rfc9112.
[HTTP/2] Thomson, M., Ed. and C. Benfield, Ed., "HTTP/2", RFC 9113, DOI 10.17487/RFC9113, June 2022, https://www.rfc-editor.org/info/rfc9113.
[HTTP/3] Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114, June 2022, https://www.rfc-editor.org/info/rfc9114.
[NTP] Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch, "Network Time Protocol Version 4: Protocol and Algorithms Specification", RFC 5905, DOI 10.17487/RFC5905, June 2010, https://www.rfc-editor.org/info/rfc5905.
[ODOH] Kinnear, E., McManus, P., Pauly, T., Verma, T., and C.A. Wood, "Oblivious DNS over HTTPS", RFC 9230, DOI 10.17487/RFC9230, June 2022, https://www.rfc-editor.org/info/rfc9230.
[ODOH-PETS] Singanamalla, S., Chunhapanya, S., Hoyland, J., Vavruลกa, M., Verma, T., Wu, P., Fayed, M., Heimerl, K., Sullivan, N., and C. A. Wood, "Oblivious DNS over HTTPS (ODoH): A Practical Privacy Enhancement to DNS", PoPETS Proceedings Volume 2021, Issue 4, pp. 575-592, DOI 10.2478/popets-2021-0085, January 2021, https://www.petsymposium.org/2021/files/papers/issue4/popets-2021-0085.pdf.
[OHTTP-ANALYSIS] Hoyland, J., "Tamarin Model of Oblivious HTTP", commit 6824eee, October 2022, https://github.com/cloudflare/ohttp-analysis.
[PRIO] Corrigan-Gibbs, H. and D. Boneh, "Prio: Private, Robust, and Scalable Computation of Aggregate Statistics", March 2017, https://crypto.stanford.edu/prio/paper.pdf.
[RANDOM] Eastlake 3rd, D., Schiller, J., and S. Crocker, "Randomness Requirements for Security", BCP 106, RFC 4086, DOI 10.17487/RFC4086, June 2005, https://www.rfc-editor.org/info/rfc4086.
[RFC7838] Nottingham, M., McManus, P., and J. Reschke, "HTTP Alternative Services", RFC 7838, DOI 10.17487/RFC7838, April 2016, https://www.rfc-editor.org/info/rfc7838.
[RFC8484] Hoffman, P. and P. McManus, "DNS Queries over HTTPS (DoH)", RFC 8484, DOI 10.17487/RFC8484, October 2018, https://www.rfc-editor.org/info/rfc8484.
[TEMPLATE] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., and D. Orchard, "URI Template", RFC 6570, DOI 10.17487/RFC6570, March 2012, https://www.rfc-editor.org/info/rfc6570.
[UWT] Nottingham, M., "Unsanctioned Web Tracking", W3C TAG Finding, July 2015, https://www.w3.org/2001/tag/doc/unsanctioned-tracking/.
[X25519] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves for Security", RFC 7748, DOI 10.17487/RFC7748, January 2016, https://www.rfc-editor.org/info/rfc7748.
Appendix A. Complete Example of a Request and Response ๐
okay so this is the fun part, bestie ๐ we get one full request and response exchange, start to finish, in hex. the request and response are super minimal on purpose, because the whole point is to show you the crypto steps happening ๐โจ binary stuff (key config, secret keys, message contents, and the in-between values) is shown in hexadecimal.
the setup: the Client is configured with the Oblivious Relay Resource URI https://proxy.example.org/request.example.net/proxy, and the proxy is set up to map requests to that URI over to the Oblivious Gateway Resource URI https://example.com/oblivious/request. the Target Resource URI (the thing the Client actually wants to query) is https://example.com ๐ฆ
first up, the Oblivious Gateway Resource generates a key pair. the server picks DHKEM(X25519, HKDF-SHA256) and makes an X25519 key pair [X25519] ๐ธ the X25519 secret key is:
3c168975674b2fa8e465970b79c8dcf09f1c741626480bd4c6162fc5b6a98e1a
then the Oblivious Gateway Resource builds a key configuration with the matching public key in it:
01002031e1f05a740102115220e9af918f738674aec95f54db6e04eb705aae8e
79815500080001000100010003
the Client somehow gets this key configuration (the spec doesn't say how, it's just "somehow" lol ๐). then, when the Client wants to send an HTTP GET to https://example.com, it builds this binary HTTP message:
00034745540568747470730b6578616d706c652e636f6d012f
next, the Client reads the key configuration and picks a KDF and AEAD that both sides support. here it goes with HKDF-SHA256 and AES-128-GCM ๐ it makes an HPKE sending context using the server's public key, built from this ephemeral secret key:
bc51d5e930bda26589890ac7032f70ad12e4ecb37abb1b65b1256c9c48999c73
the matching public key is:
4b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad19dec96c208b472
the context gets created with this info parameter:
6d6573736167652f626874747020726571756573740001002000010001
now the Client runs the Seal operation from that HPKE context to get an encrypted message, and that lets it build this Encapsulated Request ๐ฅ
010020000100014b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad1
9dec96c208b4726374e469135906992e1268c594d2a10c695d858c40a026e796
5e7d86b83dd440b2c0185204b4d63525
the Client sends that to the Oblivious Relay Resource in a POST, and it might look something like this:
POST /request.example.net/proxy HTTP/1.1
Host: proxy.example.org
Content-Type: message/ohttp-req
Content-Length: 78
<content is the Encapsulated Request above>
the Oblivious Relay Resource gets that and forwards it to the Oblivious Gateway Resource, which might look like:
POST /oblivious/request HTTP/1.1
Host: example.com
Content-Type: message/ohttp-req
Content-Length: 78
<content is the Encapsulated Request above>
the Oblivious Gateway Resource receives it, grabs the key it made earlier using the key identifier from the message, and decrypts it ๐ง since this request is headed to the same server, the Oblivious Gateway Resource doesn't have to start its own HTTP request to the Target Resource. the Target Resource can serve the request directly, and it makes a tiny response (just a 200 status code) like this:
0140c8
the response gets built by exporting a secret from the HPKE context. ngl this is the part where the crypto gets really spicy ๐ถ๏ธ
the exported secret is:
62d87a6ba569ee81014c2641f52bea36
the key derivation for the Encapsulated Response uses both the encapsulated KEM key from the request and a randomly picked nonce ๐ฒ that makes a salt of:
4b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad19dec96c208b472
c789e7151fcba46158ca84b04464910d
then the salt and secret both go into the Extract function of the chosen KDF (HKDF-SHA256), which gives a pseudorandom key of:
979aaeae066cf211ab407b31ae49767f344e1501e475c84e8aff547cc5a683db
the pseudorandom key goes with the Expand function of the KDF and an info field of "key", which makes a 16-byte key for the chosen AEAD (AES-128-GCM):
5d0172a080e428b16d298c4ea0db620d
using that same KDF and pseudorandom key, but with an info field of "nonce", it makes a 12-byte nonce:
f6bf1aeb88d6df87007fa263
now the AEAD Seal() function encrypts the response, and the result gets added to the randomized nonce value to make the Encapsulated Response ๐
c789e7151fcba46158ca84b04464910d86f9013e404feea014e7be4a441f234f
857fbd
the Oblivious Gateway Resource builds a response with this same content:
HTTP/1.1 200 OK
Date: Wed, 27 Jan 2021 04:45:07 GMT
Cache-Control: private, no-store
Content-Type: message/ohttp-res
Content-Length: 38
<content is the Encapsulated Response>
the same response might then come out of the Oblivious Relay Resource too, and the only thing that might change is the Date header โจ the Client can then use the HPKE context it made, plus the nonce from the Encapsulated Response, to build the AEAD key and nonce and decrypt the response. and that's the whole loop, periodt ๐๐
Acknowledgments
this design is based on a design for Oblivious DNS (queries) over HTTPS (DoH), described in [ODOH] ๐ David Benjamin, Mark Nottingham, and Eric Rescorla made technical contributions. the authors also thank Ralph Giles, Lucas Pardue, and Tommy Pauly for invaluable assistance ๐ซถ
Authors' Addresses
Martin Thomson Mozilla Email: mt@lowentropy.net
Christopher A. Wood Cloudflare Email: caw@heapingbits.net
๐ฆ where this page comes from
- ietf: rfc9458 2024-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms