Skip to content

Commit

Permalink
Move to have base64url-encoding only done for
Browse files Browse the repository at this point in the history
serialization.

This corrects a few cases where base64url encoding
was done within an algorithm. For example, the
combined MAC representation uses the base64url-
encoded versions of the issuer protected header
and of the payloads, rather than their octet
string representations.

This is a compatibility break with the prior draft.

This also clarifies the appendix text to represent
examples are showing base64url-encoded data,
rather than the actual algorithmic data being
base64url-encoded.
  • Loading branch information
dwaite committed Jul 22, 2024
1 parent bceb7c7 commit 2e5e938
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 55 deletions.
61 changes: 32 additions & 29 deletions draft-ietf-jose-json-proof-algorithms.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,13 @@ JSON Web Signatures are used to create all of the signature values used by the S

Each individual JWS uses a fixed protected header containing only the minimum required `alg` value. Since this JWS protected header itself is the same for every JWS, it SHOULD be a static value in the form of `{"alg":"***"}` where `***` is the JWA asymmetric signing key algorithm identifier being used. This value is recreated by a verifier using the correct JWA algorithm value included in the SU algorithm identifier.

If an implementation uses an alternative JWS protected header than this fixed value, a base64url encoded serialized form of the alternate fixed header MUST be included using the `jws_header` claim in the issuer protected header.
If an implementation uses an alternative JWS protected header than this fixed value, the octet string representation of that header should be included, base64url-encoded into the `jws_header` parameter in the issuer protected header.

### Issuer Protected Header

The JWK of the issuer's Ephemeral Key MUST be included in the issuer protected header with the property name of `proof_jwk` and contain only the REQUIRED values to represent the public key.

The holder's Presentation Key JWK MUST be included in issuer protected header using the `presentation_jwk` claim.
The holder's Presentation Key JWK MUST be included in issuer protected header using the `presentation_jwk` parameter.

The final issuer protected header is then used directly as the body of a JWS and signed using the issuer's Stable Key. The resulting JWS signature value unencoded octet string is the first value in the JWP proof.

Expand All @@ -183,12 +183,12 @@ The proof value is an octet string array. The first entry is the unencoded signa

### Presentation Protected Header

To generate a new presentation, the holder first creates a presentation protected header that is specific to the verifier being presented to. This header MUST contain a claim that both the holder and verifier trust as being unique and non-replayable.
To generate a new presentation, the holder first creates a presentation protected header that is specific to the verifier being presented to. This header MUST contain a parameter that both the holder and verifier trust as being unique and non-replayable.
Use of the `nonce` header parameter is RECOMMENDED for this purpose.

This specification registers the `nonce` header parameter for the presentation protected header that contains a string value either generated by the verifier or derived from values provided by the verifier. When present, the verifier MUST ensure the nonce value matches during verification.

The presentation protected header MAY contain other header parameters that are either provided by the verifier or by the holder. These presentation claims SHOULD NOT contain values that are common across multiple presentations and SHOULD be unique to a single presentation and verifier.
The presentation protected header MAY contain other header parameters that are either provided by the verifier or by the holder. These presentation header parameters SHOULD NOT contain values that are common across multiple presentations and SHOULD be unique to a single presentation and verifier.

In various examples in this specification, the octet string serialized presentation header is referenced as `presentation_header`.

Expand All @@ -208,9 +208,9 @@ Since the individual signatures in the proof value are unique and remain unchang

### Verification

The verifier MUST verify the issuer protected header against the first matching JWS signature part in the proof using the issuer's Stable Key. It MUST also verify the presentation protected header against the second part in the proof value using the holder's Presentation Key as provided in the `presentation_jwk` claim in the issuer protected header.
The verifier MUST verify the issuer protected header against the first matching JWS signature part in the proof using the issuer's Stable Key. It MUST also verify the presentation protected header against the second part in the proof value using the holder's Presentation Key as provided in the `presentation_jwk` parameter in the issuer protected header.

With the headers verified, the issuer's Ephemeral Key as given in the issuer protected header `proof_jwk` claim can then be used to verify each of the disclosed payload signatures.
With the headers verified, the issuer's Ephemeral Key as given in the issuer protected header `proof_jwk` parameter can then be used to verify each of the disclosed payload signatures.

### JPA Registration {#SU-registration}

Expand All @@ -232,7 +232,7 @@ The `BBS-PROOF` `alg` parameter value in the presentation protected header corre

The key used for the `BBS` algorithm is an elliptic curve-based key pair, specifically against the G_2 subgroup of a pairing friendly curve. Additional details on key generation can be found in [@!I-D.irtf-cfrg-bbs-signatures, Section 3.4]

The JWK form of this key is an `OKP` type with a curve of `BLS12381G2`, with `x` being the BASE64URL-encoded form of the output of `point_to_octets_E2`. The use of this curve is described in [@!I-D.ietf-cose-bls-key-representations].
The JWK form of this key is an `OKP` type with a curve of `BLS12381G2`, with `x` being the base64url-encoded form of the output of `point_to_octets_E2`. The use of this curve is described in [@!I-D.ietf-cose-bls-key-representations].

There is no additional holder key necessary for presentation proofs.

Expand Down Expand Up @@ -282,7 +282,7 @@ Prior to the issuer creating a new JWP, it must have presentation binding inform

The presentation key used by the holder must be transferred to the issuer and verified, likely through a challenge and self-signing mechanism. If the holder requires unlinkability, it must also generate a new key that is verified and bound to each new JWP.

How these holder presentation keys are transferred and verified is out of scope of this specification. Protocols such as OpenID Connect can be used to accomplish this. What is required by this definition is that the holder's presentation key MUST be included in the issuer's protected header using the `pjwk` claim with a JWK as the value.
How these holder presentation keys are transferred and verified is out of scope of this specification. Protocols such as OpenID Connect can be used to accomplish this. What is required by this definition is that the holder's presentation key MUST be included in the issuer's protected header using the `pjwk` parameter with a JWK as the value.

### Issuer Setup

Expand All @@ -292,25 +292,25 @@ The Shared Secret is used by both the issuer and holder as the MAC method's key

### Issuer Protected Header {#issuer-protected-header}

The holder's presentation key JWK MUST be included in the issuer protected header using the `pjwk` claim. The issuer MUST validate that the holder has possession of this key through a trusted mechanism such as verifying the signature of a unique nonce value from the holder.
The holder's presentation key JWK MUST be included in the issuer protected header using the `pjwk` parameter. The issuer MUST validate that the holder has possession of this key through a trusted mechanism such as verifying the signature of a unique nonce value from the holder.

### Combined MAC Representation

The combined MAC representation is a single octet string representing the MAC values of the issuer protected header, along with each payload provided by the issuer. This representation is signed by the issuer, but not shared - parties will recreate this octet string and verify the signature to verify the integrity of supplied issuer protected header and the integrity of any disclosed payloads.

The issuer protected header is included in this value as a MAC created using the fixed key "issuer_header" in UTF-8 encoded octets. The value is the issuer header JSON in its base64url-encoded form, as a UTF-8 encoded octet string.
The issuer protected header is included in this value as a MAC created using the fixed key "issuer_header" in UTF-8 encoded octets. The value is the issuer header JSON as a UTF-8 encoded octet string.

A unique key is generated for each payload using a MAC, with the Shared Secret as the key and a value of "payload_X" as UTF-8 encoded octets, where "X" is replaced by the zero-based array index of the payload, for example "payload_0", "payload_1", etc.

Each payload then itself has a corresponding MAC, using the above per-payload key and the payload in its base64url-encoded form, sa a UTF-8 encoded octet string.
Each payload then itself has a corresponding MAC, using the above per-payload key and the payload octet string.

The combined MAC representation is the octet string formed by the the concatentation of the issuer protected header MAC output, along with each payload MAC output.

### Issuer Proof

The issuer proof consists of two octet strings.

The first octet string is the issuer signature over the combined mac representation. The issuer signs the JWS using its stable public key, and a fixed header containing the `alg` associated with signing algorithm in use.
The first octet string is the issuer signature over the combined MAC representation. The issuer signs the JWS using its stable public key, and a fixed header containing the `alg` associated with signing algorithm in use.

`jws_header = '{"alg":"ES256"}'`

Expand Down Expand Up @@ -623,12 +623,12 @@ The JWP Protected Header declares that the data structure is a JPT and the JWP P
<{{./fixtures/build/su-es256-issuer-protected-header.json.wrapped}}
Figure: Issuer Protected header (es256)

The JWP Protected Header is serialized (without the above whitespace added for readability) into UTF-8, then BASE64URL-encoded. This gives:
The JWP Protected Header JSON is serialized (without the above whitespace added for readability) and uses UTF-8 encoding to convert into an octet string. This gives:

<{{./fixtures/build/su-es256-issuer-protected-header.b64.wrapped}}
Figure: Encoded Issuer Protected Header (es256)
Figure: Encoded Issuer Protected Header (es256, base64url-encoded)

The Single Use algorithm utilizes multiple individual JWS Signatures. Each signature value is generated by creating a JWS with a single Protected Header with the associated `alg` value. In this example, the fixed header used for each JWS is the serialized JSON Object `{"alg":"ES256"}`. This protected header will be used to generate a signature over each corresponding payload in the JWP. The corresponding octet value in the proof is the binary (base64url-decoded) value of the signature.
The Single Use algorithm utilizes multiple individual JWS Signatures. Each signature value is generated by creating a JWS with a single Protected Header with the associated `alg` value. In this example, the fixed header used for each JWS is the serialized JSON Object `{"alg":"ES256"}`. This protected header will be used to generate a signature over each corresponding payload in the JWP. The corresponding octet value in the proof is the octet string (base64url-decoded) value of the signature.

The final proof value from the Issuer is an array with the octets of the header signature, followed by entries for each payload signature.

Expand All @@ -647,15 +647,15 @@ To present this JPT, we first use the following presentation header with a nonce
<{{./fixtures/build/su-es256-presentation-protected-header.json.wrapped}}
Figure: Presentation Header

When serialized without formatting and BASE64URL-encoded, this results in the string:
This header is serialized without whitespace and UTF-8 encoded into an octet string. This gives:

<{{./fixtures/build/su-es256-holder-protected-header.b64.wrapped}}
Figure: Presentation Header (BASE64URL-encoded)
Figure: Presentation Header (base64url-encoded)

When signed with the holder's presentation key, the resulting signature are:

<{{./fixtures/build/su-es256-holder-pop.b64.wrapped}}>
Figure: Holder Proof-of-Possession (BASE64URL-encoded)
Figure: Holder Proof-of-Possession (base64url-encoded)

Then by applying selective disclosure of only the given name and age claims (family name and email hidden), we get the following presented JPT:

Expand Down Expand Up @@ -735,25 +735,27 @@ Figure: Example issuer protected header
<{{./fixtures/template/jpt-issuer-payloads.json}}
Figure: Example issuer payloads (as members of a JSON array)

The first MAC is generated using the key `issuer_header` and the base64url-encoded issuer protected header, resulting in the following base64url-encoded octet array:
The first MAC is generated using the key `issuer_header` and a value of the issuer protected header as a UTF-8 encoded octet string. This results in the following MAC:

<{{./fixtures/build/mac-h256-issuer-protected-header-mac.txt}}
Figure: Issuer MAC of protected header
Figure: Issuer MAC of protected header (base64url-encoded)

The issuer generates an array of derived keys with one for each payload by using the shared secret as the key, and the index of the payload (as `payload_{n}` in UTF-8 encoded octets) as the input in a HMAC operation. This results in the following set of derived keys (as base64url-encoded members in a JSON array):
The issuer generates an array of derived keys with one for each payload by using the shared secret as the key, and the index of the payload (as `payload_{n}` in UTF-8 encoded octets) as the input in a HMAC operation. This results in the following set of derived keys:

<{{./fixtures/build/mac-h256-issuer-derived-payload-keys.json}}
Figure: Derived payload keys
Figure: Derived payload keys (base64url-encoded)

A MAC is generated for each payload using the corresponding derived payload key. This results in the following set of MAC values (as base64url-encoded members in a JSON array):
A MAC is generated for each payload using the corresponding derived payload key. This results in the following set of MAC values:

<{{./fixtures/build/mac-h256-payload-macs.json}}
Figure: Payload MAC values
Figure: Payload MAC values (base64url-encoded)

The proof is the issuer protected header MAC and the shared secret as octet strings. Representing this as an array of base64url-encoded values:
The issuer protected header MAC and the payload MAC octet strings are concatenated into a single value known as the combined MAC representation. This representation is signed with the issuer's private key.

The proof consists of two octet string values: the signature over the combined MAC representation, and the shared secret.

<{{./fixtures/build/mac-h256-issued-proof.json.wrapped}}
Figure: Issued Proof
Figure: Issued Proof (base64url-encoded)

The final issued JWP in JSON serialization is:

Expand All @@ -778,10 +780,10 @@ In this case, the holder has decided not to disclose the last three claims provi

For the disclosed payloads, the holder will provide the corresponding derived key. For the non-disclosed payloads, the holder will provide the corresponding MAC value.

The final presented proof value is generated by concatenating first the presentation header signature octet string, followed by the issuer signature octet string, then the value disclosed by the holder for each payload. This results in the following proof, represented as a JSON array of base64url-encoded values:
The final presented proof value is an array of octet strings. The contents are presentation header signature, followed by the issuer signature, then the value disclosed by the holder for each payload. This results in the following proof:

<{{./fixtures/build/mac-h256-presentation-proof.json.wrapped}}
Figure: Presentation proof
Figure: Presentation proof (base64url-encoded)

The final presented JWP in JSON serialization is:

Expand Down Expand Up @@ -814,7 +816,8 @@ The BBS examples were generated using the library at https://github.com/mattrglo
* Update BBS algorithm description and examples to clarify the proof is an array with a single octet string.
* Update MAC algorithm to use an array of octet values for the proof, rather than requiring splitting an octet buffer into parts.
* Add new section on the Combined MAC Representation to clarify operations are serving to recreate this octet string value.
* Correct reference to the latest BBS draft.
* Correct reference to the latest BBS draft
* Change algorithms to not use base64url-encoding internally. Algorithms are meant to operate on octets, while base64url-encoding is used to represent those octets in JSON and compact serializations.

-04

Expand Down
Loading

0 comments on commit 2e5e938

Please sign in to comment.