Skip to content

Commit

Permalink
Merge pull request #494 from ietf-wg-privacypass/caw/roman-protocol
Browse files Browse the repository at this point in the history
Address Roman's IESG review of the protocol document
  • Loading branch information
chris-wood authored Sep 25, 2023
2 parents e669a80 + 2a23d12 commit 63028a1
Showing 1 changed file with 63 additions and 32 deletions.
95 changes: 63 additions & 32 deletions draft-ietf-privacypass-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ that are publicly verifiable using the issuance public key.
The Privacy Pass protocol provides a privacy-preserving authorization
mechanism. In essence, the protocol allows clients to provide cryptographic
tokens that prove nothing other than that they have been created by a given
server in the past {{?ARCHITECTURE=I-D.ietf-privacypass-architecture}}.
server in the past {{!ARCHITECTURE=I-D.ietf-privacypass-architecture}}.

This document describes the issuance protocol for Privacy Pass built on
{{!HTTP=RFC9110}}. It specifies two variants: one that is privately verifiable
Expand All @@ -77,20 +77,15 @@ for protecting client privacy. This information is covered in {{ARCHITECTURE}}.

{::boilerplate bcp14}

The following terms are used throughout this document.
This document uses the terms Origin, Client, Issuer, and Token as defined in
{{Section 2 of ARCHITECTURE}}. Moreover, the following additional terms are
used throughout this document.

- Client: An entity that runs the Issuance protocol with an Issuer to produce
Tokens that can be later used for redemption (see
{{Section 2.2 of !AUTHSCHEME=I-D.ietf-privacypass-auth-scheme}}).
- Issuer: A service that provides Tokens to Clients.
- Issuer Public Key: The public key (from a private-public key pair) used by
the Issuer for issuing and verifying Tokens.
- Issuer Private Key: The private key (from a private-public key pair) used by
the Issuer for issuing and verifying Tokens.

This document additionally uses the terms "Origin" and "Token" as defined in
{{ARCHITECTURE}}.

Unless otherwise specified, this document encodes protocol messages in TLS
notation from {{Section 3 of !TLS13=RFC8446}}. Moreover, all constants are in
network byte order.
Expand Down Expand Up @@ -164,7 +159,7 @@ defined in {{tokenkeys-values}}.
| Field Name | Value |
|:-------------|:-------------------------------------------------------|
| token-type | Integer value of the Token Type, as defined in {{token-type}}, represented as a JSON number ({{RFC8259, Section 6}}) |
| token-key | The base64url encoding of the Public Key for use with the issuance protocol, including padding, represented as a JSON string ({{RFC8259, Section 7}}) |
| token-key | The base64url-encoded {{!RFC4648}} Public Key for use with the issuance protocol as determined by the token-type field, including padding, represented as a JSON string ({{RFC8259, Section 7}}) |
{: #tokenkeys-values title="Issuer 'token-keys' object description'"}

Each "token-keys" JSON object may also contain the optional field "not-before".
Expand All @@ -185,7 +180,8 @@ to use any key in the "token-keys" list to verify tokens, starting with the most
preferred key in the list. Trial verification like this can help deal with Client
clock skew.

Altogether, the Issuer's directory could look like:
Altogether, the Issuer's directory could look like the following (with the
"token-key" fields abbreviated):

~~~
{
Expand All @@ -208,6 +204,38 @@ Clients that use this directory resource before 1686913811 in UNIX time would us
second key in the "token-keys" list, whereas Clients that use this directory after
1686913811 in UNIX time would use the first key in the "token-keys" list.

A complete "token-key" value, encoded as it would be in the Issuer directory,
would look like the following (line breaks are inserted to fit within the per-line
character limits):

~~~
$ echo MIIBUjA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAqEaMBgGCSqGSIb3DQEBCDAL \
BglghkgBZQMEAgKiAwIBMAOCAQ8AMIIBCgKCAQEAmKHGAMyeoJt1pj3n7xTtqAPr_DhZAPhJM7 \
Pc8ENR2BzdZwPTTF7KFKms5wt-mL01at0SC-cdBuIj6WYK8Ovz0AyaBuvTvW6SKCh7ZPXEqCGR \
sq5I0nthREtrYkGo113oMVPVp3sy4VHPgzd8KdzTLGzOrjiUOsSFWbjf21iaVjXJ2VdwdS-8O- \
430wkucYjGeOJwi8rWx_ZkcHtav0S67Q_SlExJel6nyRzpuuID9OQm1nxfs1Z4PhWBzt93T2oz \
Tnda3OklF5n0pIXD6bttmTekIw_8Xx2LMis0jfJ1QL99aA-muXRFN4ZUwORrF7cAcCUD_-56_6 \
fh9s34FmqBGwIDAQAB \
| sed s/-/+/g | sed s/_/\\//g | openssl base64 -d \
| openssl asn1parse -dump -inform DER
0:d=0 hl=4 l= 338 cons: SEQUENCE
4:d=1 hl=2 l= 61 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsassaPss
17:d=2 hl=2 l= 48 cons: SEQUENCE
19:d=3 hl=2 l= 13 cons: cont [ 0 ]
21:d=4 hl=2 l= 11 cons: SEQUENCE
23:d=5 hl=2 l= 9 prim: OBJECT :sha384
34:d=3 hl=2 l= 26 cons: cont [ 1 ]
36:d=4 hl=2 l= 24 cons: SEQUENCE
38:d=5 hl=2 l= 9 prim: OBJECT :mgf1
49:d=5 hl=2 l= 11 cons: SEQUENCE
51:d=6 hl=2 l= 9 prim: OBJECT :sha384
62:d=3 hl=2 l= 3 cons: cont [ 2 ]
64:d=4 hl=2 l= 1 prim: INTEGER :30
67:d=1 hl=4 l= 271 prim: BIT STRING
... truncated public key bytes ...
~~~

Issuer directory resources have the media type
"application/private-token-issuer-directory" and are located at the well-known location
/.well-known/private-token-issuer-directory; see {{wkuri-reg}} for the registration
Expand Down Expand Up @@ -289,7 +317,7 @@ Here, "P384-SHA384" is the identifier corresponding to the
OPRF(P-384, SHA-384) ciphersuite in {{OPRF}}. SetupVOPRFClient
is defined in {{OPRF, Section 3.2}}.

The Client then creates an issuance request message for a random value `nonce`
The Client then creates an issuance request message for a random 32-byte value `nonce`
with the input challenge and Issuer key identifier as described below:

~~~
Expand Down Expand Up @@ -340,10 +368,10 @@ content. The media type for this request is

~~~
POST /request HTTP/1.1
Host = issuer.example.net
Accept = application/private-token-response
Content-Type = application/private-token-request
Content-Length = <Length of TokenRequest>
Host: issuer.example.net
Accept: application/private-token-response
Content-Type: application/private-token-request
Content-Length: <Length of TokenRequest>

<Bytes containing the TokenRequest>
~~~
Expand Down Expand Up @@ -400,8 +428,8 @@ consists of TokenResponse, with the content type set as

~~~
HTTP/1.1 200 OK
Content-Type = application/private-token-response
Content-Length = <Length of TokenResponse>
Content-Type: application/private-token-response
Content-Length: <Length of TokenResponse>

<Bytes containing the TokenResponse>
~~~
Expand Down Expand Up @@ -525,7 +553,7 @@ this protocol are described below. The constant `Nk` is defined by

## Client-to-Issuer Request {#public-request}

The Client first creates an issuance request message for a random value
The Client first creates an issuance request message for a random 32-byte value
`nonce` using the input challenge and Issuer key identifier as follows:

~~~
Expand Down Expand Up @@ -574,10 +602,10 @@ Request URL "https://issuer.example.net/request" is shown below.

~~~
POST /request HTTP/1.1
Host = issuer.example.net
Accept = application/private-token-response
Content-Type = application/private-token-request
Content-Length = <Length of TokenRequest>
Host: issuer.example.net
Accept: application/private-token-response
Content-Type: application/private-token-request
Content-Length: <Length of TokenRequest>

<Bytes containing the TokenRequest>
~~~
Expand Down Expand Up @@ -616,8 +644,8 @@ consists of TokenResponse, with the content type set as

~~~
HTTP/1.1 200 OK
Content-Type = application/private-token-response
Content-Length = <Length of TokenResponse>
Content-Type: application/private-token-response
Content-Length: <Length of TokenResponse>

<Bytes containing the TokenResponse>
~~~
Expand Down Expand Up @@ -677,14 +705,16 @@ These keys MUST NOT be reused in other protocols.

The key identifier for an Issuer Private and Public Key (skI, pkI), denoted `token_key_id`,
is computed as SHA256(encoded_key), where encoded_key is a DER-encoded
SubjectPublicKeyInfo (SPKI) object carrying pkI. The SPKI object MUST use the
RSASSA-PSS OID {{!RFC5756}}, which specifies the hash algorithm and salt size.
The salt size MUST match the output size of the hash function associated with
the public key and token type. The parameters field for the digest used in the
mask generation function and the digest being signed MUST be omitted.
SubjectPublicKeyInfo {{?RFC5280}} (SPKI) object carrying pkI as a DER-encoded
RSAPublicKey value in the the subjectPublicKey field. Additionally, the SPKI object
MUST use the id-RSASSA-PSS object identifier in the algorithm field within the
SPKI object, the parameters field MUST contain a RSASSA-PSS-params value,
and MUST include the hashAlgorithm, maskGenAlgorithm, and saltLength values.
The saltLength MUST match the output size of the hash function associated with
the public key and token type.

An example sequence of the SPKI object (in ASN.1 format) for a 2048-bit key is
below:
An example sequence of the SPKI object (in ASN.1 format, with the actual public key
bytes truncated) for a 2048-bit key is below:

~~~
$ cat spki.bin | xxd -r -p | openssl asn1parse -dump -inform DER
Expand All @@ -703,6 +733,7 @@ $ cat spki.bin | xxd -r -p | openssl asn1parse -dump -inform DER
62:d=3 hl=2 l= 3 cons: cont [ 2 ]
64:d=4 hl=2 l= 1 prim: INTEGER :30
67:d=1 hl=4 l= 271 prim: BIT STRING
... truncated public key bytes ...
~~~

Since Clients truncate `token_key_id` in each `TokenRequest`, Issuers SHOULD
Expand Down

0 comments on commit 63028a1

Please sign in to comment.