diff --git a/openid-4-verifiable-credential-issuance-1_0.md b/openid-4-verifiable-credential-issuance-1_0.md index 0d196744..848216f8 100644 --- a/openid-4-verifiable-credential-issuance-1_0.md +++ b/openid-4-verifiable-credential-issuance-1_0.md @@ -920,161 +920,6 @@ The Client MAY request encrypted responses by providing its encryption parameter The Credential Issuer indicates support for encrypted responses by including the `credential_response_encryption` parameter in the Credential Issuer Metadata. -### Proof Types {#proof-types} - -This specification defines the following proof types: - -* `jwt`: A JWT [@!RFC7519] is used for proof of possession. When a `proof_type` parameter in a `proof` object is set to `jwt`, it MUST also contain a `jwt` parameter that includes a JWT as defined in (#jwt-proof-type). When a `proofs` object is using a `jwt` proof type, it MUST include a `jwt` parameter with its value being an array of JWTs, where each JWT is formed as defined in (#jwt-proof-type). -* `ldp_vp`: A W3C Verifiable Presentation object signed using the Data Integrity Proof [@VC_Data_Integrity] as defined in [@VC_DATA_2.0] or [@VC_DATA] is used for proof of possession. When a `proof_type` parameter in a `proof` object is set to `ldp_vp`, it MUST also contain an `ldp_vp` parameter that includes a [W3C Verifiable Presentation](https://www.w3.org/TR/vc-data-model-2.0/#presentations-0) defined in (#ldp-vp-proof-type). When a `proofs` object is using a `ldp_vp` proof type, it MUST include an `ldp_vp` parameter with its value being an array of [W3C Verifiable Presentations](https://www.w3.org/TR/vc-data-model-2.0/#presentations-0), where each of these W3C Verifiable Presentation is formed as defined in (#ldp-vp-proof-type). -* `attestation`: A JWT [@!RFC7519] representing a key attestation without using a proof of possession of the cryptographic key material that is being attested. When a `proof_type` parameter in a `proof` object is set to `attestation`, the object MUST also contain an `attestation` parameter that includes a JWT as defined in (#attestation-proof-type). - -There are two ways to convey key attestations (as defined in (#keyattestation)) of the cryptographic key material during Credential issuance: - -- The Wallet uses the `jwt` proof type in the Credential Request to create a proof of possession of the key and adds the key attestation in the JOSE header. -- The Wallet uses the `attestation` proof type in the Credential Request with the key attestation without a proof of possession of the key itself. - -Depending on the Wallet's implementation, the `attestation` may avoid unnecessary End-User interaction during Credential issuance, as the key itself does not necessarily need to perform signature operations. - -Additional proof types MAY be defined and used. - -#### `jwt` Proof Type {#jwt-proof-type} - -The JWT MUST contain the following elements: - -* in the JOSE header, - * `alg`: REQUIRED. A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry [@IANA.JOSE]. It MUST NOT be `none` or an identifier for a symmetric algorithm (MAC). - * `typ`: REQUIRED. MUST be `openid4vci-proof+jwt`, which explicitly types the key proof JWT as recommended in Section 3.11 of [@!RFC8725]. - * `kid`: OPTIONAL. JOSE Header containing the key ID. If the Credential shall be bound to a DID, the `kid` refers to a DID URL which identifies a particular key in the DID Document that the Credential shall be bound to. It MUST NOT be present if `jwk` is present. - * `jwk`: OPTIONAL. JOSE Header containing the key material the new Credential shall be bound to. It MUST NOT be present if `kid` is present. - * `x5c`: OPTIONAL. JOSE Header containing a certificate or certificate chain corresponding to the key used to sign the JWT. - * `key_attestation`: OPTIONAL. JOSE Header containing a key attestation as described in (#keyattestation). - * `trust_chain`: OPTIONAL. JOSE Header containing an [@!OpenID.Federation] Trust Chain. This element MAY be used to convey key attestation, metadata, metadata policies, federation Trust Marks and any other information related to a specific federation, if available in the chain. When used for signature verification, the header parameter `kid` MUST be present. - -* in the JWT body, - * `iss`: OPTIONAL (string). The value of this claim MUST be the `client_id` of the Client making the Credential request. This claim MUST be omitted if the access token authorizing the issuance call was obtained from a Pre-Authorized Code Flow through anonymous access to the token endpoint. - * `aud`: REQUIRED (string). The value of this claim MUST be the Credential Issuer Identifier. - * `iat`: REQUIRED (number). The value of this claim MUST be the time at which the key proof was issued using the syntax defined in [@!RFC7519]. - * `nonce`: OPTIONAL (string). The value type of this claim MUST be a string, where the value is a server-provided `c_nonce`. It MUST be present when the Wallet received a server-provided `c_nonce`. - -The Credential Issuer MUST validate that the JWT used as a proof is actually signed by a key identified in the JOSE Header. - -The Credential Issuer SHOULD issue a Credential for each cryptographic public key specified in the `attested_keys` claim within the `key_attestation` parameter. - -Cryptographic algorithm names used in the `proof_signing_alg_values_supported` Credential Issuer metadata parameter for this proof type SHOULD be one of those defined in [@IANA.JOSE]. - -Below is a non-normative example of a `proof` parameter (with line breaks within values for display purposes only): - -```json -{ - "proof_type": "jwt", - "jwt": - "eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrI - jp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiblVXQW9BdjNYWml0aDhFN2k - xOU9kYXhPTFlGT3dNLVoyRXVNMDJUaXJUNCIsInkiOiJIc2tIVThCalVpMVU5WHFpN - 1N3bWo4Z3dBS18weGtjRGpFV183MVNvc0VZIn19.eyJhdWQiOiJodHRwczovL2NyZW - RlbnRpYWwtaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNzAxOTYwNDQ0LCJub25j - ZSI6IkxhclJHU2JtVVBZdFJZTzZCUTR5bjgifQ.-a3EDsxClUB4O3LeDD5DVGEnNMT - 01FCQW4P6-2-BNBqc_Zxf0Qw4CWayLEpqkAomlkLb9zioZoipdP-jvh1WlA" -} -``` - -where the decoded JWT looks like this: - -```json -{ - "typ": "openid4vci-proof+jwt", - "alg": "ES256", - "jwk": { - "kty": "EC", - "crv": "P-256", - "x": "nUWAoAv3XZith8E7i19OdaxOLYFOwM-Z2EuM02TirT4", - "y": "HskHU8BjUi1U9Xqi7Swmj8gwAK_0xkcDjEW_71SosEY" - } -}.{ - "aud": "https://credential-issuer.example.com", - "iat": 1701960444, - "nonce": "LarRGSbmUPYtRYO6BQ4yn8" -} -``` - -Here is another example JWT not only proving possession of a private key but also providing key attestation data for that key: - -```json -{ - "typ": "openid4vci-proof+jwt", - "alg": "ES256", - "kid": "0", - "key_attestation": -}. -{ - "iss": "s6BhdRkqt3", - "aud": "https://server.example.com", - "iat": 1659145924, - "nonce": "tZignsnFbp" -} -``` - -#### `ldp_vp` Proof Type {#ldp-vp-proof-type} - -When a W3C Verifiable Presentation as defined by [@VC_DATA_2.0] or [@VC_DATA] signed using Data Integrity is used as key proof, it MUST contain the following elements: - -* `holder`: OPTIONAL. MUST be equivalent to the controller identifier (e.g., DID) for the `verificationMethod` value identified by the `proof.verificationMethod` property. -* `proof`: REQUIRED. The proof body of a W3C Verifiable Presentation. - * `domain`: REQUIRED (string). The value of this claim MUST be the Credential Issuer Identifier. - * `challenge`: REQUIRED when the Credential Issuer has provided a `c_nonce`. It MUST NOT be used otherwise. String, where the value is a server-provided `c_nonce`. It MUST be present when the Wallet received a server-provided `c_nonce`. - -The Credential Issuer MUST validate that the W3C Verifiable Presentation used as a proof is actually signed with a key in the possession of the Holder. - -Cryptographic algorithm names used in the `proof_signing_alg_values_supported` Credential Issuer metadata parameter for this proof type SHOULD be one of those defined in [@LD_Suite_Registry]. - -Below is a non-normative example of a `proof` parameter: - -```json -{ - "proof_type": "ldp_vp", - "ldp_vp": { - "@context": [ - "https://www.w3.org/ns/credentials/v2", - "https://www.w3.org/ns/credentials/examples/v2" - ], - "type": [ - "VerifiablePresentation" - ], - "holder": "did:key:z6MkvrFpBNCoYewiaeBLgjUDvLxUtnK5R6mqh5XPvLsrPsro", - "proof": [ - { - "type": "DataIntegrityProof", - "cryptosuite": "eddsa-2022", - "proofPurpose": "authentication", - "verificationMethod": "did:key:z6MkvrFpBNCoYewiaeBLgjUDvLxUtnK5R6mqh5XPvLsrPsro#z6MkvrFpBNCoYewiaeBLgjUDvLxUtnK5R6mqh5XPvLsrPsro", - "created": "2023-03-01T14:56:29.280619Z", - "challenge": "82d4cb36-11f6-4273-b9c6-df1ac0ff17e9", - "domain": "did:web:audience.company.com", - "proofValue": "z5hrbHzZiqXHNpLq6i7zePEUcUzEbZKmWfNQzXcUXUrqF7bykQ7ACiWFyZdT2HcptF1zd1t7NhfQSdqrbPEjZceg7" - } - ] - } -} - -``` - -#### `attestation` Proof Type {#attestation-proof-type} - -A key attestation in JWT format as defined in (#keyattestation-jwt). - -When a key attestation is used as a proof type, it MUST contain the `c_nonce` value provided by the Credential Issuer in its `nonce` parameter. - -Below is a non-normative example of a `proof` parameter (with line breaks within values for display purposes only): - -```json -{ - "proof_type": "attestation", - "attestation": "" -} -``` - -The Credential Issuer SHOULD issue a Credential for each cryptographic public key specified in the `attested_keys` claim within the `key_attestation` parameter. - ### Verifying Proof {#verifying-key-proof} To validate a key proof, the Credential Issuer MUST ensure that: @@ -2443,6 +2288,161 @@ claims: selected. - `["nationalities", 1]`: The second nationality is selected. +# Proof Types {#proof-types} + +This specification defines the following proof types: + +* `jwt`: A JWT [@!RFC7519] is used for proof of possession. When a `proof_type` parameter in a `proof` object is set to `jwt`, it MUST also contain a `jwt` parameter that includes a JWT as defined in (#jwt-proof-type). When a `proofs` object is using a `jwt` proof type, it MUST include a `jwt` parameter with its value being an array of JWTs, where each JWT is formed as defined in (#jwt-proof-type). +* `ldp_vp`: A W3C Verifiable Presentation object signed using the Data Integrity Proof [@VC_Data_Integrity] as defined in [@VC_DATA_2.0] or [@VC_DATA] is used for proof of possession. When a `proof_type` parameter in a `proof` object is set to `ldp_vp`, it MUST also contain an `ldp_vp` parameter that includes a [W3C Verifiable Presentation](https://www.w3.org/TR/vc-data-model-2.0/#presentations-0) defined in (#ldp-vp-proof-type). When a `proofs` object is using a `ldp_vp` proof type, it MUST include an `ldp_vp` parameter with its value being an array of [W3C Verifiable Presentations](https://www.w3.org/TR/vc-data-model-2.0/#presentations-0), where each of these W3C Verifiable Presentation is formed as defined in (#ldp-vp-proof-type). +* `attestation`: A JWT [@!RFC7519] representing a key attestation without using a proof of possession of the cryptographic key material that is being attested. When a `proof_type` parameter in a `proof` object is set to `attestation`, the object MUST also contain an `attestation` parameter that includes a JWT as defined in (#attestation-proof-type). + +There are two ways to convey key attestations (as defined in (#keyattestation)) of the cryptographic key material during Credential issuance: + +- The Wallet uses the `jwt` proof type in the Credential Request to create a proof of possession of the key and adds the key attestation in the JOSE header. +- The Wallet uses the `attestation` proof type in the Credential Request with the key attestation without a proof of possession of the key itself. + +Depending on the Wallet's implementation, the `attestation` may avoid unnecessary End-User interaction during Credential issuance, as the key itself does not necessarily need to perform signature operations. + +Additional proof types MAY be defined and used. + +## `jwt` Proof Type {#jwt-proof-type} + +The JWT MUST contain the following elements: + +* in the JOSE header, + * `alg`: REQUIRED. A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry [@IANA.JOSE]. It MUST NOT be `none` or an identifier for a symmetric algorithm (MAC). + * `typ`: REQUIRED. MUST be `openid4vci-proof+jwt`, which explicitly types the key proof JWT as recommended in Section 3.11 of [@!RFC8725]. + * `kid`: OPTIONAL. JOSE Header containing the key ID. If the Credential shall be bound to a DID, the `kid` refers to a DID URL which identifies a particular key in the DID Document that the Credential shall be bound to. It MUST NOT be present if `jwk` is present. + * `jwk`: OPTIONAL. JOSE Header containing the key material the new Credential shall be bound to. It MUST NOT be present if `kid` is present. + * `x5c`: OPTIONAL. JOSE Header containing a certificate or certificate chain corresponding to the key used to sign the JWT. + * `key_attestation`: OPTIONAL. JOSE Header containing a key attestation as described in (#keyattestation). + * `trust_chain`: OPTIONAL. JOSE Header containing an [@!OpenID.Federation] Trust Chain. This element MAY be used to convey key attestation, metadata, metadata policies, federation Trust Marks and any other information related to a specific federation, if available in the chain. When used for signature verification, the header parameter `kid` MUST be present. + +* in the JWT body, + * `iss`: OPTIONAL (string). The value of this claim MUST be the `client_id` of the Client making the Credential request. This claim MUST be omitted if the access token authorizing the issuance call was obtained from a Pre-Authorized Code Flow through anonymous access to the token endpoint. + * `aud`: REQUIRED (string). The value of this claim MUST be the Credential Issuer Identifier. + * `iat`: REQUIRED (number). The value of this claim MUST be the time at which the key proof was issued using the syntax defined in [@!RFC7519]. + * `nonce`: OPTIONAL (string). The value type of this claim MUST be a string, where the value is a server-provided `c_nonce`. It MUST be present when the Wallet received a server-provided `c_nonce`. + +The Credential Issuer MUST validate that the JWT used as a proof is actually signed by a key identified in the JOSE Header. + +The Credential Issuer SHOULD issue a Credential for each cryptographic public key specified in the `attested_keys` claim within the `key_attestation` parameter. + +Cryptographic algorithm names used in the `proof_signing_alg_values_supported` Credential Issuer metadata parameter for this proof type SHOULD be one of those defined in [@IANA.JOSE]. + +Below is a non-normative example of a `proof` parameter (with line breaks within values for display purposes only): + +```json +{ + "proof_type": "jwt", + "jwt": + "eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrI + jp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiblVXQW9BdjNYWml0aDhFN2k + xOU9kYXhPTFlGT3dNLVoyRXVNMDJUaXJUNCIsInkiOiJIc2tIVThCalVpMVU5WHFpN + 1N3bWo4Z3dBS18weGtjRGpFV183MVNvc0VZIn19.eyJhdWQiOiJodHRwczovL2NyZW + RlbnRpYWwtaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNzAxOTYwNDQ0LCJub25j + ZSI6IkxhclJHU2JtVVBZdFJZTzZCUTR5bjgifQ.-a3EDsxClUB4O3LeDD5DVGEnNMT + 01FCQW4P6-2-BNBqc_Zxf0Qw4CWayLEpqkAomlkLb9zioZoipdP-jvh1WlA" +} +``` + +where the decoded JWT looks like this: + +```json +{ + "typ": "openid4vci-proof+jwt", + "alg": "ES256", + "jwk": { + "kty": "EC", + "crv": "P-256", + "x": "nUWAoAv3XZith8E7i19OdaxOLYFOwM-Z2EuM02TirT4", + "y": "HskHU8BjUi1U9Xqi7Swmj8gwAK_0xkcDjEW_71SosEY" + } +}.{ + "aud": "https://credential-issuer.example.com", + "iat": 1701960444, + "nonce": "LarRGSbmUPYtRYO6BQ4yn8" +} +``` + +Here is another example JWT not only proving possession of a private key but also providing key attestation data for that key: + +```json +{ + "typ": "openid4vci-proof+jwt", + "alg": "ES256", + "kid": "0", + "key_attestation": +}. +{ + "iss": "s6BhdRkqt3", + "aud": "https://server.example.com", + "iat": 1659145924, + "nonce": "tZignsnFbp" +} +``` + +## `ldp_vp` Proof Type {#ldp-vp-proof-type} + +When a W3C Verifiable Presentation as defined by [@VC_DATA_2.0] or [@VC_DATA] signed using Data Integrity is used as key proof, it MUST contain the following elements: + +* `holder`: OPTIONAL. MUST be equivalent to the controller identifier (e.g., DID) for the `verificationMethod` value identified by the `proof.verificationMethod` property. +* `proof`: REQUIRED. The proof body of a W3C Verifiable Presentation. + * `domain`: REQUIRED (string). The value of this claim MUST be the Credential Issuer Identifier. + * `challenge`: REQUIRED when the Credential Issuer has provided a `c_nonce`. It MUST NOT be used otherwise. String, where the value is a server-provided `c_nonce`. It MUST be present when the Wallet received a server-provided `c_nonce`. + +The Credential Issuer MUST validate that the W3C Verifiable Presentation used as a proof is actually signed with a key in the possession of the Holder. + +Cryptographic algorithm names used in the `proof_signing_alg_values_supported` Credential Issuer metadata parameter for this proof type SHOULD be one of those defined in [@LD_Suite_Registry]. + +Below is a non-normative example of a `proof` parameter: + +```json +{ + "proof_type": "ldp_vp", + "ldp_vp": { + "@context": [ + "https://www.w3.org/ns/credentials/v2", + "https://www.w3.org/ns/credentials/examples/v2" + ], + "type": [ + "VerifiablePresentation" + ], + "holder": "did:key:z6MkvrFpBNCoYewiaeBLgjUDvLxUtnK5R6mqh5XPvLsrPsro", + "proof": [ + { + "type": "DataIntegrityProof", + "cryptosuite": "eddsa-2022", + "proofPurpose": "authentication", + "verificationMethod": "did:key:z6MkvrFpBNCoYewiaeBLgjUDvLxUtnK5R6mqh5XPvLsrPsro#z6MkvrFpBNCoYewiaeBLgjUDvLxUtnK5R6mqh5XPvLsrPsro", + "created": "2023-03-01T14:56:29.280619Z", + "challenge": "82d4cb36-11f6-4273-b9c6-df1ac0ff17e9", + "domain": "did:web:audience.company.com", + "proofValue": "z5hrbHzZiqXHNpLq6i7zePEUcUzEbZKmWfNQzXcUXUrqF7bykQ7ACiWFyZdT2HcptF1zd1t7NhfQSdqrbPEjZceg7" + } + ] + } +} + +``` + +## `attestation` Proof Type {#attestation-proof-type} + +A key attestation in JWT format as defined in (#keyattestation-jwt). + +When a key attestation is used as a proof type, it MUST contain the `c_nonce` value provided by the Credential Issuer in its `nonce` parameter. + +Below is a non-normative example of a `proof` parameter (with line breaks within values for display purposes only): + +```json +{ + "proof_type": "attestation", + "attestation": "" +} +``` + +The Credential Issuer SHOULD issue a Credential for each cryptographic public key specified in the `attested_keys` claim within the `key_attestation` parameter. + # Key Attestations {#keyattestation} A key attestation, as defined by this specification, is a verifiable statement that demonstrates the authenticity and security properties of a key and its storage component to the Credential Issuer. Keys can be stored in various key storage components, which vary in their ability to protect the private key from extraction and duplication, as well as in the methods used for User authentication to enable key operations. These key storage components can be software-based or hardware-based and may reside on the same device as the Wallet, on external security tokens, or on remote services that facilitate cryptographic key operations. Key attestations are issued either by the Wallet's key storage component itself or by the Wallet Provider. When the Wallet Provider creates the key attestation, it MUST verify the authenticity of its claims about the keys, possibly using platform-specific key attestations. @@ -2463,7 +2463,7 @@ The key attestation may use `x5c`, `kid` or `trust_chain` (as defined in (#jwt-p * in the JWT body, * `iat`: REQUIRED (number). Integer for the time at which the key attestation was issued using the syntax defined in [@!RFC7519]. - * `exp`: OPTIONAL (number). Integer for the time at which the key attestation and the key(s) it is attesting expire, using the syntax defined in [@!RFC7519]. MUST be present if the attestation is used with the JWT proof type. + * `exp`: OPTIONAL (number). Integer for the time at which the key attestation and the key(s) it is attesting expire, using the syntax defined in [@!RFC7519]. MUST be present if the attestation is used with the `jwt` proof type. * `attested_keys` : REQUIRED. Array of attested keys from the same key storage component using the syntax of JWK as defined in [@!RFC7517]. * `key_storage` : OPTIONAL. Array of case sensitive strings that assert the attack potential resistance of the key storage component and its keys attested in the `attested_keys` parameter. This specification defines initial values in (#keyattestation-apr). * `user_authentication` : OPTIONAL. Array of case sensitive strings that assert the attack potential resistance of the user authentication methods allowed to access the private keys from the `attested_keys` parameter. This specification defines initial values in (#keyattestation-apr). @@ -2756,7 +2756,8 @@ The technology described in this specification was made available from contribut -16 - * + * + * Move the Proof Types from the Credential Endpoint section to an appendix to increase readability -15