idnits 2.17.1 draft-ietf-privacypass-http-api-00.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- == The page length should not exceed 58 lines per page, but there was 1 longer page, the longest (page 1) being 527 lines Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (5 January 2021) is 1199 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- No issues found here. Summary: 0 errors (**), 0 flaws (~~), 2 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group S. Valdez 3 Internet-Draft Google LLC 4 Intended status: Informational 5 January 2021 5 Expires: 9 July 2021 7 Privacy Pass HTTP API 8 draft-ietf-privacypass-http-api-00 10 Abstract 12 This document specifies an integration for Privacy Pass over an HTTP 13 API, along with recommendations on how key commitments are stored and 14 accessed by HTTP-based consumers. 16 Status of This Memo 18 This Internet-Draft is submitted in full conformance with the 19 provisions of BCP 78 and BCP 79. 21 Internet-Drafts are working documents of the Internet Engineering 22 Task Force (IETF). Note that other groups may also distribute 23 working documents as Internet-Drafts. The list of current Internet- 24 Drafts is at https://datatracker.ietf.org/drafts/current/. 26 Internet-Drafts are draft documents valid for a maximum of six months 27 and may be updated, replaced, or obsoleted by other documents at any 28 time. It is inappropriate to use Internet-Drafts as reference 29 material or to cite them other than as "work in progress." 31 This Internet-Draft will expire on 9 July 2021. 33 Copyright Notice 35 Copyright (c) 2021 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 40 license-info) in effect on the date of publication of this document. 41 Please review these documents carefully, as they describe your rights 42 and restrictions with respect to this document. Code Components 43 extracted from this document must include Simplified BSD License text 44 as described in Section 4.e of the Trust Legal Provisions and are 45 provided without warranty as described in the Simplified BSD License. 47 Table of Contents 49 1. Introduction 50 1.1. Terminology 51 1.2. Layout 52 1.3. Requirements 53 2. Privacy Pass HTTP API Wrapping 54 3. Server key registry 55 3.1. Key Registry 56 3.2. Server Configuration Retrieval 57 4. Key Commitment Retrieval 58 5. Privacy Pass Issuance 59 6. Privacy Pass Redemption 60 6.1. Generic Token Redemption 61 6.2. Direct Redemption 62 6.3. Delegated Redemption 63 7. Security Considerations 64 8. IANA Considerations 65 8.1. Well-Known URI 66 9. Normative References 67 Author's Address 69 1. Introduction 71 The Privacy Pass protocol as described in 72 [draft-davidson-pp-protocol] can be integrated with a number of 73 different settings, from server to server communication to browsing 74 the internet. 76 In this document, we will provide an API to use for integrating 77 Privacy Pass with an HTTP framework. Providing the format of HTTP 78 requests and responses needed to implement the Privacy Pass protocol. 80 1.1. Terminology 82 We use the same definition of server and client that is used in 83 [draft-davidson-pp-protocol] and [draft-davidson-pp-architecture]. 85 We assume that all protocol messages are encoded into raw byte format 86 before being sent. We use the TLS presentation language [RFC8446] to 87 describe the structure of protocol messages. 89 1.2. Layout 91 * Section 2: Describes the wrapping of messages within HTTP 92 requests/responses. 94 * Section 3: Describes how HTTP clients retrieve server 95 configurations and key commitments. 97 * Section 5: Describes how issuance requests are performed via a 98 HTTP API. 100 * Section 6: Describes how redemption requests are performed via a 101 HTTP API. 103 1.3. Requirements 105 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 106 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 107 document are to be interpreted as described in [RFC2119]. 109 2. Privacy Pass HTTP API Wrapping 111 Messages from HTTP-based clients to HTTP-based servers are performed 112 as GET and POST requests. The messages are sent via the "Sec- 113 Privacy-Pass" header. 115 "Sec-Privacy-Pass" is a Dictionary Structured Header 116 [draft-ietf-httpbis-header-structure-15]. The dictionary has two 117 keys: 119 * "type" whose value is a String conveying the function that is 120 being performed with this request. 122 * "body" whose value is a byte sequence containing a Privacy Pass 123 protocol message. 125 Note that the requests may contain addition Headers, request data and 126 URL parameters that are not specified here, these extra fields should 127 be ignored, though may be used by the server to determine whether to 128 fulfill the requested issuance/redemption. 130 3. Server key registry 132 A client SHOULD fetch a server's current public key information prior 133 to performing issuance and redemption. This configuration is 134 accessible via a "CONFIG_ENDPOINT", either provided by the server or 135 by a global registry that provides consistency and anonymization 136 guarantees. 138 3.1. Key Registry 140 To ensure that a server isn't providing different views of their 141 public key material to different users, servers are expected to write 142 their commitments to a verifiable data structure. 144 Using a verifiable log-backed map ([verifiable-data-structures]), the 145 server can publish their commitments to the log in a way that clients 146 can detect when the server is attempting to provide a split-view of 147 their key commitments to different clients. 149 The key to the map is the "server_origin", with the value being: 151 struct { 152 opaque public_key<1..2^16-1>; 153 uint64 expiry; 154 uint8 supported_methods; # 3:Issue/Redeem, 2:Redeem, 1:Issue 155 opaque signature<1..2^16-1>; 156 } KeyCommitment; 158 struct { 159 opaque server_id<1..2^16-1>; 160 uint16 ciphersuite; 161 opaque verification_key<1..2^16-1>; 162 KeyCommitment commitments<1..2^16-1>; 163 } 165 The addition to the log is made via a signed message to the log 166 operator, which verifies the authenticity against a public key 167 associated with that server origin (either via the Web PKI or a out- 168 of-band key). The signature should be computed under a long-term 169 signing key that is associated with the server identity. 171 The server SHOULD then store an inclusion proof of the current key 172 commitment so that it can present it when delivering the key 173 commitment directly to the client or when the key commitment is being 174 delivered by a delegated party (other registries/preloaded 175 configuration lists/etc). 177 The client can then perform a request for the key commitment against 178 either the global registry or the server as described in Section 4. 179 Note that the signature should be verified by the client to ensure 180 that the key material is owned by the server. This requires that the 181 client know the public verification key that is associated with the 182 server. 184 To avoid user segregation as a result of server configuration/ 185 commitment rotation, the log operator SHOULD enforce limits on how 186 many active commitments exist and how quickly the commitments are 187 being rotated. Clients SHOULD reject configurations/commitments that 188 violate their requirements for avoiding user segregation. These 189 considerations are discussed as part of 190 [draft-davidson-pp-architecture]. 192 3.2. Server Configuration Retrieval 194 Inputs: - "server_origin": The origin to retrieve a server 195 configuration for. 197 No outputs. 199 1. The client makes an anonymous GET request to 200 "CONFIG_ENDPOINT"/.well-known/privacy-pass with a message of type 201 "fetch-config" and a body of: 203 struct { 204 opaque server_origin<1..2^16-1>; 205 } 207 1. The server looks up the configuration associated with the origin 208 "server_origin" and responds with a message of type "config" and 209 a body of: 211 struct { 212 opaque server_id<1..2^16-1>; 213 uint16 ciphersuite; 214 opaque commitment_id<1..2^8-1>; 215 opaque verification_key<1..2^16-1>; 216 } 218 1. The client then stores the associated configuration state under 219 the corresponding "server_origin". 221 (TODO: This might be mergable with key commitment retrieval if 222 server_id = server_origin) 224 4. Key Commitment Retrieval 226 The client SHOULD retrieve server key commitments prior to both an 227 issuance and redemption to verify the consistency of the keys and to 228 monitor for key rotation between issuance and redemption events. 230 Inputs: - "server_origin": The origin to retrieve a key commitment 231 for. 233 No outputs. 235 1. The client fetches the configuration state "server_id", 236 "ciphersuite", "commitment_id" associated with "server_origin". 238 2. The client makes an anonymous GET request to 239 "CONFIG_ENDPOINT"/.well-known/privacy-pass with a message of type 240 "fetch-commitment" and a body of: 242 struct { 243 opaque server_id<1..2^16-1> = server_id; 244 opaque commitment_id<1..2^8-1> = commitment_id; 245 } 247 1. The server looks up the current configuration, and constructs a 248 list of commitments to return, noting whether a key commitment is 249 valid for issuance or redemption or both. 251 2. The server then responds with a message of type "commitment" and 252 a body of: 254 struct { 255 opaque public_key<1..2^16-1>; 256 uint64 expiry; 257 uint8 supported_methods; # 3:Issue/Redeem, 2:Redeem, 1:Issue 258 opaque signature<1..2^16-1>; 259 } KeyCommitment; 261 struct { 262 opaque server_id<1..2^16-1>; 263 uint16 ciphersuite; 264 opaque verification_key<1..2^16-1>; 265 KeyCommitment commitments<1..2^16-1>; 266 opaque inclusion_proofs<1..2^16-1>; 267 } 269 1. The client then verifies the signature for each key commitment 270 and stores the list of commitments to the current scope. The 271 client SHOULD NOT cache the commitments beyond the current scope, 272 as new commitments should be fetched for each independent 273 issuance and redemption request. The client SHOULD verify the 274 "inclusion_proofs" to confirm that the key commitment has been 275 submitted to a trusted registry. Once the client receives the 276 "ciphersuite" for the server, it should implement all Privacy 277 Pass API functions (as detailed in [draft-davidson-pp-protocol]) 278 using this ciphersuite. 280 5. Privacy Pass Issuance 282 Inputs: - "server_origin": The origin to request token issuance from. 283 - "count": The number of tokens to request issuance for. 285 Outputs: - "tokens": A list of tokens that have been signed via the 286 Privacy Pass protocol. 288 1. When a client wants to request tokens from a server, it should 289 first fetch a key commitment from the server via the process 290 described in Section 4 and keep the result as "commitment". 292 2. The client should then call the "Generate" function requesting 293 "count" tokens storing the resulting "input" data. 295 3. The client then makes a POST request to <"server_origin">/.well- 296 known/privacy-pass with a message of type "request-issuance" and 297 a body of: 299 enum { Normal(0) } IssuanceType; 301 struct { 302 IssuanceType type = 0; 303 opaque msg<0..2^16-1> = input.msg; 304 } 306 1. The server, upon receipt of the "request" should call the "Issue" 307 function with the "public_key", "secret_key" and the value of 308 "msg" with a result of "resp". 310 2. The server should then respond to the POST request with a message 311 of type "issue" and a body of: 313 struct { 314 IssuanceType type = request.type; 315 IssuanceResp resp = resp; 316 } 318 1. The client should then should call the "Process" function with 319 the "public_key", stored "inputs" and resulting "resp", to 320 extract a list of "redemption_tokens". 322 2. The client should store the "public_key" associated with these 323 tokens and the elements of "redemption_tokens" under storage 324 partitioned by the "server_origin", accessible only via the 325 Privacy Pass API. 327 6. Privacy Pass Redemption 329 There are two forms of Privacy Pass redemption that could function 330 under the HTTP API. Either passing along a token directly to the 331 target endpoint, which would perform its own redemption Section 6.1, 332 or the client redeeming the token and passing the result along to the 333 target endpoint. These two methods are described below. 335 6.1. Generic Token Redemption 337 Inputs: - "server_id": The server ID to redeem a token against. - 338 "ciphersuite": The ciphersuite for this token. - "public_key": The 339 public key associated with this token. - "redemption_token": A 340 Privacy Pass token. - "info": Additional data to bind to this token 341 redemption. 343 Outputs: - "result": The result of the redemption from the server. 345 1. The client should call the "Redeem" function with 346 "redemption_token" and additional data of "info" storing the 347 resulting "data" and "tag". 349 2. The client makes a POST request to <"server_origin">/.well-known/ 350 privacy-pass with a message of type "token-redemption" and a body 351 of: 353 struct { 354 opaque server_id<1..2^16-1> = server_id; 355 opaque data<1..2^16-1> = data; 356 opaque tag<1..2^16-1> = tag; 357 opaque info<1..2^16-1> = info; 358 } 360 1. The server, upon receipt of "request" should call the "Verify" 361 interface with "public_key", "secret_key" and the received 362 "data", "tag", "info" storing the resulting "resp". 364 2. The server should then respond to the POST request with a message 365 of type "redemption-result" and a signed body of: 367 struct { 368 opaque info<1..2^16-1> = info; 369 uint8 result = resp; 370 // signature of info and result using 371 // the server's verification key. 372 opaque signature<1..2^16-1>; 373 } 375 1. The client upon receipt of this message should verify the 376 "signature" using the "verification_key" from the configuration 377 and return the "result". 379 6.2. Direct Redemption 381 Inputs: - "server_origin": The server origin to redeem a token for. - 382 "target": The target endpoint to send the token to. - 383 "additional_data": Additional data to bind to this redemption 384 request. 386 1. When a client wants to redeem tokens for a server, it should 387 first fetch a key commitment from the server via the process 388 described in Section 4 and keep the result as "commitment". 390 2. The client should then look up the storage partition associated 391 with "server_origin" and fetch a "redemption_token" and 392 "public_key". 394 3. The client should verify that the "public_key" is in the current 395 "commitment". If not, it should discard the token and fail the 396 redemption attempt. 398 4. As part of the request to "target", the client will include the 399 token as part of the request in the "Sec-Privacy-Pass" header 400 along with whatever other parameters are being passed as part of 401 the request to "target". The header will contain a message of 402 type "token-redemption" with a body of: 404 struct { 405 opaque server_id<1..2^16-1> = server_id; 406 uint16 ciphersuite = ciphersuite; 407 opaque public_key<1..2^16-1> = public_key; 408 RedemptionToken token<1..2^16-1> = redemption_token; 409 opaque additional_data<1..2^16-1> = additional_data; 410 } 412 At this point, the "target" can perform a generic redemption as 413 described in Section 6.1 by forwarding the message included in the 414 request to "target". 416 6.3. Delegated Redemption 418 Inputs: - "server_origin": The server origin to redeem a token for. - 419 "target": The target endpoint to send the token to. - 420 "additional_data": Additional data to bind to this redemption 421 request. 423 1. When a client wants to redeem tokens for a server, it should 424 first fetch a key commitment from the server via the process 425 described in Section 4 and keep the result as "commitment". 427 2. The client should then look up the storage partition associated 428 with "server_origin" and fetch a "redemption_token" and 429 "public_key". 431 3. The client should verify that the "public_key" is in the current 432 "commitment". If not, it should discard the token and fail the 433 redemption attempt. 435 4. The client constructs a bytestring "info" made up of the 436 "target", the current "timestamp", and "additional_data": 438 struct { 439 opaque target<1..2^16-1>; 440 uint64 timestamp; 441 opaque additional_data<0..2^16-1>; 442 } 444 1. The client then performs a token redemption as described in 445 Section 6.1. Storing the resulting "redemption-result" message. 447 2. As part of the request to "target", the client will include the 448 redemption result as part of the request in the "Sec-Privacy- 449 Pass" header along with whatever other parameters are being 450 passed as part of the request to "target". The header will 451 contain a message of type "signed-redemption-result" with a body 452 of: 454 struct { 455 opaque server_origin<1..2^16-1>; 456 opaque target<1..2^16-1>; 457 uint64 timestamp; 458 opaque additional_data<1..2^16-1> = additional_data; 459 opaque signed_redemption<1..2^16-1>; 460 } 462 At this point, the "target" can verify the integrity of 463 "signed_redemption.info" based on the values of "target", 464 "timestamp", and "additional_data" and verify the signature of the 465 redemption result by querying the current configuration of the 466 Privacy Pass server. The inclusion of "target" and "timestamp" 467 proves that the server attested to the validity of the token in 468 relation to this particular request. 470 7. Security Considerations 472 Security considerations for Privacy Pass are discussed in 473 [draft-davidson-pp-architecture]. 475 8. IANA Considerations 477 8.1. Well-Known URI 479 This specification registers a new well-known URI. 481 URI suffix: "privacy-pass" 483 Change controller: IETF. 485 Specification document(s): this specification 487 9. Normative References 489 [draft-davidson-pp-architecture] 490 Davidson, A., "Privacy Pass: Architectural Framework", 491 n.d., . 494 [draft-davidson-pp-protocol] 495 Davidson, A., "Privacy Pass: The Protocol", n.d., 496 . 499 [draft-ietf-httpbis-header-structure-15] 500 Nottingham, M. and P-H. Kamp, "Structured Headers for 501 HTTP", n.d., . 504 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 505 Requirement Levels", BCP 14, RFC 2119, 506 DOI 10.17487/RFC2119, March 1997, 507 . 509 [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol 510 Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, 511 . 513 [verifiable-data-structures] 514 "Verifiable Data Structures", n.d., 515 . 518 Author's Address 520 Steven Valdez 521 Google LLC 523 Email: svaldez@chromium.org