diff --git a/draft-hendrickson-privacypass-public-metadata.md b/draft-hendrickson-privacypass-public-metadata.md index ead5f00..635ed72 100644 --- a/draft-hendrickson-privacypass-public-metadata.md +++ b/draft-hendrickson-privacypass-public-metadata.md @@ -4,7 +4,7 @@ abbrev: "Public Metadata Issuance" category: info docname: draft-hendrickson-privacypass-public-metadata-latest -submissiontype: IETF # also: "independent", "IAB", or "IRTF" +submissiontype: IETF number: date: consensus: true @@ -29,58 +29,312 @@ author: normative: AUTHSCHEME: I-D.draft-ietf-privacypass-auth-scheme - PROTOCOL: I-D.draft-ietf-privacypass-protocol - PBLINDRSA: I-D.draft-amjad-cfrg-partially-blind-rsa + BASIC-PROTOCOL: I-D.draft-ietf-privacypass-protocol + POPRF: I-D.irtf-cfrg-voprf + PBRSA: I-D.amjad-cfrg-partially-blind-rsa + TOKEN-EXTENSION: + target: https://chris-wood.github.io/draft-wood-privacypass-extensible-token/draft-wood-privacypass-extensible-token.html + title: "The PrivateToken HTTP Authentication Scheme Extensions Parameter" --- abstract -This document specifies a Privacy Pass token type that encodes public metadata visible to the Client, Attester, Issuer, and Origin. +This document specifies Privacy Pass issuance protocols that encode public +information visible to the Client, Attester, Issuer, and Origin into each token. --- middle # Introduction -This document specifies a Privacy Pass token type that encodes public metadata visible to the Client, Attester, Issuer, and Origin. This allows deployments to encode a small amount of information visible to -all parties participating in the protocol. +The basic Privacy Pass issuance protocols as specified in {{BASIC-PROTOCOL}} and resulting +tokens convey only a single bit of information: whether or not the token is valid. However, +it is possible for tokens to be issued with additional information aggreed upon by Client, +Attester, and Issuer during issuance. This information, sometimes referred to as public +metadata, allows Privacy Pass applications to encode deployment-specific information that is +necessary for their use case. + +This document specifies two Privacy Pass issuance protocols that encode public information +visible to the Client, Attester, Issuer, and Origin. One is based on the partially-oblivious +PRF construction from {{POPRF}}, and the other is based on the partially-blind RSA signature +scheme from {{PBRSA}}. + +# Terminology + +{::boilerplate bcp14} + +# Notation + +The following terms are used throughout this document to describe the protocol operations in this document: + + - len(s): the length of a byte string, in bytes. + - concat(x0, ..., xN): Concatenation of byte strings. For example, concat(0x01, 0x0203, 0x040506) = 0x010203040506 + - int_to_bytes: Convert a non-negative integer to a byte string. int_to_bytes is + implemented as I2OSP as described in {{Section 4.1 of RFC8017}}. Note that these + functions operate on byte strings in big-endian byte order. # Motivation -Public metadata enables Privacy Pass deployments that share information between clients, attesters, issuers and origins. In a 0x01 (VOPRF) or 0x02 (Blind RSA) deployment, the only information available to all parties is the `issuer_name`. If one wants to differentiate bits of information at the origin, many TokenChallenges must be sent - one for each `issuer_name` that attests to the bit required. +Public metadata enables Privacy Pass deployments that share information between Clients, Attesters, +Issuers and Origins. In the basic Privacy Pass issuance protocols (types 0x0001 and 0x0002), the only +information available to all parties is the choice of Issuer, expressed through the TokenChallenge. +If one wants to differentiate bits of information at the origin, many TokenChallenges must be sent, +one for each Issuer that attests to the bit required. + +For example, if a deployment was built that attested to an app’s published state in an app store, +it requires 1 bit {`published`, `not_published`} and can be built with a single Issuer. An app version +attester would require one Issuer for each app version and one TokenChallenge per Issuer. + +Taken further, the limitation of one bit of information in each Privacy Pass token means that a distinct +Issuer and Issuer public key is needed for each unique value one wants to express with a token. +This many-key metadata deployment should provide metadata visible to all parties in the same way as +the {{!PBRSA}} proposal outlined in this document. However, it comes with practical reliability and +scalability tradeoffs. In particular, many simultaneous deployed keys could be difficult to scale. +Some HSM implementations have fixed per-key costs, slow key generation, and minimum key lifetimes. +Quick key rotation creates reliability risk to the system, as a pause or slowdown in key rotation +could cause the system to run out of active signing or verification keys. Issuance protocols that +support public metadata mitigate these tradeoffs by allowing deployments to change metadata values +without publishing new keys. + +# Issuance Protocol for Privately Verifiable Tokens {#private-flow} + +This section describes a variant of the issuance protocol in {{Section 5 of !BASIC-PROTOCOL}} +that supports public metadata based on the partially oblivious PRF (POPRF) from +{{POPRF}}. Issuers provide a Private and Public Key, denoted +`skI` and `pkI` respectively, used to produce tokens as input to the protocol. +See {{private-issuer-configuration}} for how this key pair is generated. -For example, if a deployment was built that attested to an app’s published state in an app store, it requires 1 bit {`published`, `not_published`} and can be built with a single issuer. To build an app version attester, we need one `issuer_name` for each app version, and one challenge per version the origin needs to differentiate on each origin load. For each new app version that requires attesting, a new `issuer_name` must be deployed. If we build this system with public metadata a single TokenChallenge for a single `issuer_name` can be used. Deployment specific logic could allow adding a new app version into the metadata once sufficient users are on the new version, ensuring users are private when providing attested metadata bits to the origins. +Clients provide the following as input to the issuance protocol: -## Alternatives +- Issuer Request URI: A URI to which token request messages are sent. This can + be a URL derived from the "issuer-request-uri" value in the Issuer's + directory resource, or it can be another Client-configured URL. The value + of this parameter depends on the Client configuration and deployment model. + For example, in the 'Split Origin, Attester, Issuer' deployment model, the + Issuer Request URI might correspond to the Client's configured Attester, + and the Attester is configured to relay requests to the Issuer. +- Issuer name: An identifier for the Issuer. This is typically a host name that + can be used to construct HTTP requests to the Issuer. +- Issuer Public Key: `pkI`, with a key identifier `token_key_id` computed as + described in {{public-issuer-configuration}}. +- Challenge value: `challenge`, an opaque byte string. For example, this might + be provided by the redemption protocol in {{AUTHSCHEME}}. +- Extensions: `extensions`, an Extensions structure as defined in {{TOKEN-EXTENSION}}. -To implement this scheme without new cryptographic primitives, one could deploy an issuer signing key per metadata value, and publish each key’s bit assignment in Issuer Configuration. This many-key metadata deployment should provide metadata visible to all parties in the same way as the {{!PBLINDRSA}} proposal outlined here, however it has reliability and scalability tradeoffs. Imagine a Privacy Pass deployment using a client cached redemption context where max-age cannot be used to expire signed tokens due to the cache, yet the deployment requires fast token expiration. Handling this requires either deploying one key per expiration period or rotating keys quickly. Many simultaneous deployed keys could be difficult to scale - for example some HSM implementations have fixed per-key costs, slow key generation, and minimum key lifetimes. Quick key rotation creates reliability risk to the system, as a pause or slowdown in key rotation could cause the system to run out of active signing or verification keys. {{!PBLINDRSA}} allows deployments to change metadata sets without publishing new keys, and challenge expiry can be encoded within metadata. It pushes all metadata design into the deployment domain, instead of defining them in issuer configuration. +Given this configuration and these inputs, the two messages exchanged in +this protocol are described below. This section uses notation described in +{{POPRF, Section 4}}, including SerializeElement and DeserializeElement, +SerializeScalar and DeserializeScalar, and DeriveKeyPair. +The constants `Ne` and `Ns` are as defined in {{POPRF, Section 4}} for +OPRF(P-384, SHA-384). The constant `Nk`, which is also equal to `Nh` as defined +in {{POPRF, Section 4}}, is defined in {{iana}}. -# Terminology +## Client-to-Issuer Request {#private-request} -{::boilerplate bcp14} +The Client first creates a context as follows: -The following terms are used throughout this document. +~~~ +client_context = SetupPOPRFClient("P384-SHA384", pkI) +~~~ -- Public Metadata: Information that can be viewed by the Client, Attester, Issuer, and Origin, and cryptographically bound to a token. +Here, "P384-SHA384" is the identifier corresponding to the +OPRF(P-384, SHA-384) ciphersuite in {{POPRF}}. SetupPOPRFClient +is defined in {{POPRF, Section 3.2}}. -# Notation +The Client then creates an issuance request message for a random value `nonce` +with the input challenge and Issuer key identifier as described below: -The following terms are used throughout this document to describe the protocol operations in this document: +~~~ +nonce = random(32) +challenge_digest = SHA256(challenge) +token_input = concat(0xDA7B, // Token type field is 2 bytes long + nonce, + challenge_digest, + token_key_id) +blind, blinded_element, tweaked_key = client_context.Blind(token_input, extensions, pkI) +~~~ - - len(s): the length of a byte string, in bytes. - - concat(x0, ..., xN): Concatenation of byte strings. For example, concat(0x01, 0x0203, 0x040506) = 0x010203040506 - - int_to_bytes: Convert a non-negative integer to a byte string. int_to_bytes is implemented as I2OSP as described in {{Section 4.1 of RFC8017}}. Note that these functions operate on byte strings in big-endian byte order. +The Blind function is defined in {{POPRF, Section 3.3.3}}. +If the Blind function fails, the Client aborts the protocol. +The Client stores the `nonce`, `challenge_digest`, and `tweaked_key` values locally +for use when finalizing the issuance protocol to produce a token +(as described in {{private-finalize}}). + +The Client then creates an ExtendedTokenRequest structured as follows: + +~~~ +struct { + TokenRequest request; + Extensions extensions; +} ExtendedTokenRequest; +~~~ + +The contents of ExtendedTokenRequest.request are as defined in {{Section 5 of BASIC-PROTOCOL}}. +The contents of ExtendedTokenRequest.extensions match the Client's configured `extensions` value. + +The Client then generates an HTTP POST request to send to the Issuer Request +URI, with the ExtendedTokenRequest as the content. The media type for this request +is "application/private-token-request". An example request is shown below: + +~~~ +:method = POST +:scheme = https +:authority = issuer.example.net +:path = /request +accept = application/private-token-response +cache-control = no-cache, no-store +content-type = application/private-token-request +content-length = + + +~~~ + +## Issuer-to-Client Response {#private-response} + +- The ExtendedTokenRequest.request contains a supported token_type. +- The ExtendedTokenRequest.request.truncated_token_key_id corresponds to the truncated key + ID of an Issuer Public Key. +- The ExtendedTokenRequest.request.blinded_msg is of the correct size. +- The ExtendedTokenRequest.extensions value is permitted by the Issuer's policy. + +If any of these conditions is not met, the Issuer MUST return an HTTP 400 error +to the Client, which will forward the error to the client. Otherwise, if the +Issuer is willing to produce a token token to the Client for the provided extensions, +the Issuer then tries to deseralize ExtendedTokenRequest.request.blinded_msg using +DeserializeElement from {{Section 2.1 of POPRF}}, yielding `blinded_element`. +If this fails, the Issuer MUST return an HTTP 400 error to the client. +Otherwise, the Issuer completes the issuance flow by computing a blinded response as follows: + +~~~ +server_context = SetupPOPRFServer("P384-SHA384", skI, pkI) +evaluate_element, proof = + server_context.BlindEvaluate(skI, blinded_element, ExtendedTokenRequest.extensions) +~~~ + +SetupPOPRFServer is defined in {{POPRF, Section 3.2}} and BlindEvaluate is defined in +{{POPRF, Section 3.3.3}}. The Issuer then creates a TokenResponse structured +as follows: + +~~~ +struct { + uint8_t evaluate_msg[Ne]; + uint8_t evaluate_proof[Ns+Ns]; +} TokenResponse; +~~~ +The structure fields are defined as follows: + +- "evaluate_msg" is the Ne-octet evaluated message, computed as + `SerializeElement(evaluate_element)`. + +- "evaluate_proof" is the (Ns+Ns)-octet serialized proof, which is a pair of + Scalar values, computed as + `concat(SerializeScalar(proof[0]), SerializeScalar(proof[1]))`. + +The Issuer generates an HTTP response with status code 200 whose content +consists of TokenResponse, with the content type set as +"application/private-token-response". + +~~~ +:status = 200 +content-type = application/private-token-response +content-length = + + +~~~ + +## Finalization {#private-finalize} + +Upon receipt, the Client handles the response and, if successful, deserializes +the content values TokenResponse.evaluate_msg and TokenResponse.evaluate_proof, +yielding `evaluated_element` and `proof`. If deserialization of either value +fails, the Client aborts the protocol. Otherwise, the Client processes the +response as follows: + +~~~ +authenticator = client_context.Finalize(token_input, blind, + evaluated_element, + blinded_element, + proof, extensions, tweaked_key) +~~~ + +The Finalize function is defined in {{POPRF, Section 3.3.3}}. If this +succeeds, the Client then constructs a Token as follows: + +~~~ +struct { + uint16_t token_type = 0xDA7B; /* Type POPRF(P-384, SHA-384) */ + uint8_t nonce[32]; + uint8_t challenge_digest[32]; + uint8_t token_key_id[32]; + uint8_t authenticator[Nk]; +} Token; +~~~ + +The Token.nonce value is that which was sampled in {{private-request}}. +If the Finalize function fails, the Client aborts the protocol. + +The Client will send this Token to Origins for redemption in the "token" HTTP +authentication parameter as specified in {{Section 2.2 of AUTHSCHEME}}. +The Client also supplies its extensions value as an additional authentication +parameter as specified in {{TOKEN-EXTENSION}}. + +## Token Verification + +Verifying a Token requires creating a POPRF context using the Issuer Private +Key and Public Key, evaluating the token contents with the corresponding extensions, +and comparing the result against the token authenticator value: + +~~~ +server_context = SetupPOPRFServer("P384-SHA384", skI) +token_authenticator_input = + concat(Token.token_type, + Token.nonce, + Token.challenge_digest, + Token.token_key_id) +token_authenticator = + server_context.Evaluate(skI, token_authenticator_input, extensions) +valid = (token_authenticator == Token.authenticator) +~~~ + +## Issuer Configuration {#private-issuer-configuration} + +Issuers are configured with Private and Public Key pairs, each denoted `skI` +and `pkI`, respectively, used to produce tokens. These keys MUST NOT be reused +in other protocols. A RECOMMENDED method for generating key pairs is as +follows: + +~~~ +seed = random(Ns) +(skI, pkI) = DeriveKeyPair(seed, "PrivacyPass-TypeDA7B") +~~~ + +The DeriveKeyPair function is defined in {{POPRF, Section 3.3.1}}. +The key identifier for a public key `pkI`, denoted `token_key_id`, is computed +as follows: + +~~~ +token_key_id = SHA256(SerializeElement(pkI)) +~~~ + +Since Clients truncate `token_key_id` in each `TokenRequest`, Issuers should +ensure that the truncated form of new key IDs do not collide with other +truncated key IDs in rotation. # Issuance Protocol for Publicly Verifiable Tokens {#public-flow} -This section describes a variant of the issuance protocol in {{Section 6 of !PROTOCOL}} -for producing publicly verifiable tokens including public metadata using cryptography specified in {{PBLINDRSA}}. +This section describes a variant of the issuance protocol in {{Section 6 of !BASIC-PROTOCOL}} +for producing publicly verifiable tokens including public metadata using cryptography specified in {{PBRSA}}. In particular, this variant of the issuance protocol works for the -`RSAPBSSA-SHA384-PSSZERO-Deterministic` or `RSAPBSSA-SHA384-PSS-Deterministic` variant of the blind RSA protocol variants described in {{Section 6 of !PBLINDRSA}}. +`RSAPBSSA-SHA384-PSSZERO-Deterministic` or `RSAPBSSA-SHA384-PSS-Deterministic` +variant of the blind RSA protocol variants described in {{Section 6 of !PBRSA}}. The public metadata issuance protocol differs from the protocol in -{{Section 6 of !PROTOCOL}} in that the issuance and redemption protocols carry metadata provided by the Client and visible to the Attester, Issuer, and Origin. This means Clients can set arbitrary metadata when requesting a token, but specific values of metadata may be rejected by any of Attester, Issuer, or Origin. Similar to a token nonce, metadata is cryptographically bound to a token and cannot be altered. +{{Section 6 of !BASIC-PROTOCOL}} in that the issuance and redemption protocols carry metadata +provided by the Client and visible to the Attester, Issuer, and Origin. This means Clients +can set arbitrary metadata when requesting a token, but specific values of metadata may be +rejected by any of Attester, Issuer, or Origin. Similar to a token nonce, metadata is +cryptographically bound to a token and cannot be altered. Clients provide the following as input to the issuance protocol: @@ -97,7 +351,7 @@ Clients provide the following as input to the issuance protocol: described in {{public-issuer-configuration}}. - Challenge value: `challenge`, an opaque byte string. For example, this might be provided by the redemption protocol in {{AUTHSCHEME}}. -- Public Metadata: `metadata`, an opaque byte string of length at most 216-1 bytes. +- Extensions: `extensions`, an Extensions structure as defined in {{TOKEN-EXTENSION}}. Given this configuration and these inputs, the two messages exchanged in this protocol are described below. The constant `Nk` is defined as 256 for token type 0xDA7A. @@ -111,45 +365,31 @@ The Client first creates an issuance request message for a random value nonce = random(32) challenge_digest = SHA256(challenge) token_input = concat(0xDA7A, // Token type field is 2 bytes long - int_to_bytes(len(metadata), 2), - metadata, nonce, challenge_digest, token_key_id) -blinded_msg, blind_inv = Blind(pkI, PrepareIdentity(token_input), metadata) +blinded_msg, blind_inv = Blind(pkI, PrepareIdentity(token_input), extensions) ~~~ -Where `PrepareIdentity` is defined in {{Section 6 of !PBLINDRSA}} and `Blind` is defined in {{Section 4.2 of !PBLINDRSA}} +Where `PrepareIdentity` is defined in {{Section 6 of !PBRSA}} and `Blind` is defined in {{Section 4.2 of !PBRSA}} -The Client stores the nonce, challenge_digest, and metadata values locally for use -when finalizing the issuance protocol to produce a token (as described -in {{public-finalize}}). +The Client stores the `nonce`, `challenge_digest`, and `extensions` values locally for use +when finalizing the issuance protocol to produce a token (as described in {{public-finalize}}). -The Client then creates a TokenRequest structured as follows: +The Client then creates an ExtendedTokenRequest structured as follows: ~~~ struct { - uint16_t token_type = 0xDA7A; /* Type Public Metadata Blind RSA (2048-bit) */ - uint8_t truncated_token_key_id; - opaque metadata<1..2^16-1>; - uint8_t blinded_msg[Nk]; -} MetadataTokenRequest; + TokenRequest request; + Extensions extensions; +} ExtendedTokenRequest; ~~~ -The structure fields are defined as follows: - -- "token_type" is a 2-octet integer, which matches the type in the challenge. - -- "truncated_token_key_id" is the least significant byte of the `token_key_id` - ({{public-issuer-configuration}}) in network byte order (in other words, the - last 8 bits of `token_key_id`). - -- "metadata" is the opaque metadata value input to the issuance protocol. - -- "blinded_msg" is the Nk-octet request defined above. +The contents of ExtendedTokenRequest.request are as defined in {{Section 6 of BASIC-PROTOCOL}}. +The contents of ExtendedTokenRequest.extensions match the Client's configured `extensions` value. The Client then generates an HTTP POST request to send to the Issuer Request -URI, with the TokenRequest as the content. The media type for this request +URI, with the ExtendedTokenRequest as the content. The media type for this request is "application/private-token-request". An example request is shown below: ~~~ @@ -160,39 +400,34 @@ is "application/private-token-request". An example request is shown below: accept = application/private-token-response cache-control = no-cache, no-store content-type = application/private-token-request -content-length = +content-length = - + ~~~ ## Issuer-to-Client Response {#public-response} Upon receipt of the request, the Issuer validates the following conditions: -- The TokenRequest contains a supported token_type. -- The TokenRequest.truncated_token_key_id corresponds to the truncated key +- The ExtendedTokenRequest.request contains a supported token_type. +- The ExtendedTokenRequest.request.truncated_token_key_id corresponds to the truncated key ID of an Issuer Public Key. -- The TokenRequest.blinded_msg is of the correct size. +- The ExtendedTokenRequest.request.blinded_msg is of the correct size. +- The ExtendedTokenRequest.extensions value is permitted by the Issuer's policy. If any of these conditions is not met, the Issuer MUST return an HTTP 400 error to the Client, which will forward the error to the client. Otherwise, if the -Issuer is willing to produce a token token to the Client for the provided metadata value, the Issuer -completes the issuance flow by computing a blinded response as follows: +Issuer is willing to produce a token token to the Client for the provided extensions, +the Issuer completes the issuance flow by computing a blinded response as follows: ~~~ -blind_sig = BlindSign(skI, TokenRequest.blinded_msg, metadata) +blind_sig = BlindSign(skI, ExtendedTokenRequest.request.blinded_msg, ExtendedTokenRequest.extensions) ~~~ -Where `BlindSign` is defined in {{Section 4.3 of !PBLINDRSA}}. - -The result is encoded and transmitted to the client in the following -TokenResponse structure: +Where `BlindSign` is defined in {{Section 4.3 of !PBRSA}}. -~~~ -struct { - uint8_t blind_sig[Nk]; -} MetadataTokenResponse; -~~~ +The result is encoded and transmitted to the client in a TokenResponse structure as +defined in {{Section 6 of BASIC-PROTOCOL}}. The Issuer generates an HTTP response with status code 200 whose content consists of TokenResponse, with the content type set as @@ -212,18 +447,17 @@ Upon receipt, the Client handles the response and, if successful, processes the content as follows: ~~~ -authenticator = Finalize(pkI, nonce, metadata, blind_sig, blind_inv) +authenticator = Finalize(pkI, nonce, extensions, blind_sig, blind_inv) ~~~ -Where `Finalize` function is defined in {{Section 4.4 of !PBLINDRSA}}. +Where `Finalize` function is defined in {{Section 4.4 of !PBRSA}}. -If this succeeds, the Client then constructs a Token as described in [AUTHSCHEME] as +If this succeeds, the Client then constructs a Token as described in {{AUTHSCHEME}} as follows: ~~~ struct { uint16_t token_type = 0xDA7A; /* Type Partially Blind RSA (2048-bit) */ - opaque metadata<1..2^16-1>; uint8_t nonce[32]; uint8_t challenge_digest[32]; uint8_t token_key_id[32]; @@ -231,45 +465,49 @@ struct { } Token; ~~~ -The Token.nonce value is that which was sampled in {{Section 5.1 of PROTOCOL}}. +The Token.nonce value is that which was sampled in {{Section 5.1 of !BASIC-PROTOCOL}}. If the Finalize function fails, the Client aborts the protocol. +The Client will send this Token to Origins for redemption in the "token" HTTP +authentication parameter as specified in {{Section 2.2 of AUTHSCHEME}}. +The Client also supplies its extensions value as an additional authentication +parameter as specified in {{TOKEN-EXTENSION}}. + ## Token Verification Verifying a Token requires checking that Token.authenticator is a valid -signature over the remainder of the token input using the Augmented Issuer Public Key. +signature over the remainder of the token input with respect to the corresponding +Extensions value `extensions` using the Augmented Issuer Public Key. ~~~ -pkM = AugmentPublicKey(pkI, Token.metadata) +pkM = AugmentPublicKey(pkI, extensions) token_input = concat(0xDA7A, // Token type field is 2 bytes long - int_to_bytes(len(Token.metadata), 2), - Token.metadata, Token.nonce, Token.challenge_digest, Token.token_key_id) token_authenticator_input = concat("msg", - int_to_bytes(len(Token.metadata), 2), - Token.metadata, + int_to_bytes(len(extensions), 2), + extensions, token_input) valid = RSASSA-PSS-VERIFY(pkM, token_authenticator_input, Token.authenticator) ~~~ -Where `AugmentPublicKey` is defined in {{Section 4.6 of !PBLINDRSA}}, -and message verification is redefined in {{Section 4.5 of !PBLINDRSA}}. +Where `AugmentPublicKey` is defined in {{Section 4.6 of !PBRSA}}, +and message verification is redefined in {{Section 4.5 of !PBRSA}}. The function `RSASSA-PSS-VERIFY` is defined in {{Section 8.1.2 of !RFC8017}}, using SHA-384 as the Hash function, MGF1 with SHA-384 as the PSS mask generation function (MGF), and a 48-byte salt length (sLen). - ## Issuer Configuration {#public-issuer-configuration} Issuers are configured with Private and Public Key pairs, each denoted skI and pkI, respectively, used to produce tokens. Each key pair SHALL be generated as -as specified in FIPS 186-4 {{?DSS=DOI.10.6028/NIST.FIPS.186-4}}, where n is 2048 bits in length. These key -pairs MUST NOT be reused in other protocols. Each key pair MUST comply with all requirements as specified in {{Section 5.2 of !PBLINDRSA}}. +as specified in FIPS 186-4 {{?DSS=DOI.10.6028/NIST.FIPS.186-4}}, where the RSA modulus +is 2048 bits in length. These key pairs MUST NOT be reused in other protocols. +Each key pair MUST comply with all requirements as specified in {{Section 5.2 of !PBRSA}}. The key identifier for a keypair (skI, pkI), denoted `token_key_id`, is computed as SHA256(encoded_key), where encoded_key is a DER-encoded @@ -288,13 +526,33 @@ truncated key IDs in rotation. TODO Security -# IANA Considerations +# IANA Considerations {#iana} + +This document extends the token type registry defined in {{Section 8.2.1 of !BASIC-PROTOCOL}} with two new +entries described in the following sub-sections. + +## Privately Verifiable Token Type -This extends the token type registry defined in {{Section 8.2.1 of !PROTOCOL}} with a new token type of value `0xDA7A`: +The contents of this token type registry entry are as follows: + +* Value: 0xDA7B +* Name: Partially Oblivious PRF, OPRF(P-384, SHA-384) +* Token Structure: As defined in {{private-finalize}} +* TokenChallenge Structure: As defined in {{Section 2.1 of AUTHSCHEME}} +* Publicly Verifiable: N +* Public Metadata: Y +* Private Metadata: N +* Nk: 48 +* Nid: 32 +* Notes: N/A + +## Publicly Verifiable Token Type + +The contents of this token type registry entry are as follows: * Value: 0xDA7A * Name: Partially Blind RSA (2048-bit) -* Token Structure: As defined in {{public-request}} +* Token Structure: As defined in {{public-finalize}} * TokenChallenge Structure: As defined in {{Section 2.1 of AUTHSCHEME}} * Publicly Verifiable: Y * Public Metadata: Y @@ -304,11 +562,9 @@ This extends the token type registry defined in {{Section 8.2.1 of !PROTOCOL}} w * Notes: The RSABSSA-SHA384-PSS-Deterministic and RSABSSA-SHA384-PSSZERO-Deterministic variants are supported - - --- back # Acknowledgments {:numbered="false"} -TODO acknowledge. +This work benefited from input from Ghous Amjad and Kevin Yeo.