diff --git a/refs/pull/443/merge/en/.buildinfo b/refs/pull/443/merge/en/.buildinfo new file mode 100644 index 000000000..a9bc11296 --- /dev/null +++ b/refs/pull/443/merge/en/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: ed59d2c7d28e0bffbeacd4ace4e0bbab +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/refs/pull/443/merge/en/.doctrees/algorithms.doctree b/refs/pull/443/merge/en/.doctrees/algorithms.doctree new file mode 100644 index 000000000..4629d4393 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/algorithms.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/authentic-sources.doctree b/refs/pull/443/merge/en/.doctrees/authentic-sources.doctree new file mode 100644 index 000000000..1b7157abe Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/authentic-sources.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/backup-restore.doctree b/refs/pull/443/merge/en/.doctrees/backup-restore.doctree new file mode 100644 index 000000000..cfb309841 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/backup-restore.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/contribute.doctree b/refs/pull/443/merge/en/.doctrees/contribute.doctree new file mode 100644 index 000000000..f3711d438 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/contribute.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/defined-terms.doctree b/refs/pull/443/merge/en/.doctrees/defined-terms.doctree new file mode 100644 index 000000000..6db507216 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/defined-terms.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/environment.pickle b/refs/pull/443/merge/en/.doctrees/environment.pickle new file mode 100644 index 000000000..97d6ebf7d Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/environment.pickle differ diff --git a/refs/pull/443/merge/en/.doctrees/index.doctree b/refs/pull/443/merge/en/.doctrees/index.doctree new file mode 100644 index 000000000..032b4840a Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/index.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/pid-eaa-data-model.doctree b/refs/pull/443/merge/en/.doctrees/pid-eaa-data-model.doctree new file mode 100644 index 000000000..6708b78ff Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/pid-eaa-data-model.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/pid-eaa-entity-configuration.doctree b/refs/pull/443/merge/en/.doctrees/pid-eaa-entity-configuration.doctree new file mode 100644 index 000000000..3465223bc Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/pid-eaa-entity-configuration.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/pid-eaa-issuance.doctree b/refs/pull/443/merge/en/.doctrees/pid-eaa-issuance.doctree new file mode 100644 index 000000000..2cc21ac07 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/pid-eaa-issuance.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/proximity-flow.doctree b/refs/pull/443/merge/en/.doctrees/proximity-flow.doctree new file mode 100644 index 000000000..1c5dde15c Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/proximity-flow.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/pseudonyms.doctree b/refs/pull/443/merge/en/.doctrees/pseudonyms.doctree new file mode 100644 index 000000000..21ada8456 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/pseudonyms.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/relying-party-entity-configuration.doctree b/refs/pull/443/merge/en/.doctrees/relying-party-entity-configuration.doctree new file mode 100644 index 000000000..238f2874f Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/relying-party-entity-configuration.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/relying-party-solution.doctree b/refs/pull/443/merge/en/.doctrees/relying-party-solution.doctree new file mode 100644 index 000000000..7461ea4a9 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/relying-party-solution.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/remote-flow.doctree b/refs/pull/443/merge/en/.doctrees/remote-flow.doctree new file mode 100644 index 000000000..5feb50825 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/remote-flow.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/revocation-lists.doctree b/refs/pull/443/merge/en/.doctrees/revocation-lists.doctree new file mode 100644 index 000000000..a4898ff7e Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/revocation-lists.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/ssi-introduction.doctree b/refs/pull/443/merge/en/.doctrees/ssi-introduction.doctree new file mode 100644 index 000000000..4cafde30b Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/ssi-introduction.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/standards.doctree b/refs/pull/443/merge/en/.doctrees/standards.doctree new file mode 100644 index 000000000..7c0ea5f0a Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/standards.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/trust.doctree b/refs/pull/443/merge/en/.doctrees/trust.doctree new file mode 100644 index 000000000..c4eb20e3c Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/trust.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/wallet-attestation.doctree b/refs/pull/443/merge/en/.doctrees/wallet-attestation.doctree new file mode 100644 index 000000000..e044e4796 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/wallet-attestation.doctree differ diff --git a/refs/pull/443/merge/en/.doctrees/wallet-solution.doctree b/refs/pull/443/merge/en/.doctrees/wallet-solution.doctree new file mode 100644 index 000000000..f8406bd20 Binary files /dev/null and b/refs/pull/443/merge/en/.doctrees/wallet-solution.doctree differ diff --git a/refs/pull/443/merge/en/_images/Eo_circle_green_checkmark.svg b/refs/pull/443/merge/en/_images/Eo_circle_green_checkmark.svg new file mode 100644 index 000000000..19e0bd7f0 --- /dev/null +++ b/refs/pull/443/merge/en/_images/Eo_circle_green_checkmark.svg @@ -0,0 +1,2 @@ + diff --git a/refs/pull/443/merge/en/_images/Eo_circle_red_letter-x.svg b/refs/pull/443/merge/en/_images/Eo_circle_red_letter-x.svg new file mode 100644 index 000000000..4c3c8e785 --- /dev/null +++ b/refs/pull/443/merge/en/_images/Eo_circle_red_letter-x.svg @@ -0,0 +1 @@ + diff --git a/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-PID-Issuance.svg b/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-PID-Issuance.svg new file mode 100644 index 000000000..112223018 --- /dev/null +++ b/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-PID-Issuance.svg @@ -0,0 +1,3 @@ + + +
PID Provider
PID Provider
Wallet Solution
Wallet Solution
Wallet Instance
Wallet Instance
VCI Component (OIDC4VCI)
VCI Component (OIDC4VCI...
Issues PID
Issues PID
National eID Component
 (e.g. OIDC, SAML)
National eID Component...
Wallet Provider
Wallet Provider
Attestation Service
Attestation Service
Issues
Wallet Verifiable Attestation
Issues...
Authenticates the User
Authenticates the User
Requests PID
Requests PID
Develop and Maintains
Develop and Maintains
Federation API Services
Federation API Services
Federation API Services
Federation API Serv...
National IdP
National IdP
0
0
3
3
4
4
5
5
Trust Anchor - Accreditation Body
Trust Anchor - Accreditation Body
Federation API Services
Federation API Services
Requests for PID Provider identifier
Requests for PID Provider identifier
1
1
2
2
Requests for PID Provider Metadata
Requests for PID Provider Metadata
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-Presentation-ISO.svg b/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-Presentation-ISO.svg new file mode 100644 index 000000000..6bcf4030f --- /dev/null +++ b/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-Presentation-ISO.svg @@ -0,0 +1 @@ +User's SmartphoneVerifier's SmartphoneUserUserWallet InstanceWallet InstanceVerifier AppVerifier App1Open the Wallet Instance to present an mDoc CredentialDevice Engagement subphase -over QR-2Generate new ephemeral key pair3Show the QR Code for Device Engagement4Scan the QR Code5Generate newephemeral key pair6Compute session keySession establishment and Communication subphase -over BLE secure channel-7mDoc Request + public key of the Verifier App(Session establishment)8Compute session key9Prompt for consent to share the requested information10Grant consent11Retrieve mDoc from local storage12mDoc Response13Verify Response signatureand check mDoc validity \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-QEAA-Issuance.svg b/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-QEAA-Issuance.svg new file mode 100644 index 000000000..7a55b4792 --- /dev/null +++ b/refs/pull/443/merge/en/_images/High-Level-Flow-ITWallet-QEAA-Issuance.svg @@ -0,0 +1,3 @@ + + +
(Q)EAA Provider
(Q)EAA Provider
Wallet Solution
Wallet Solution
Wallet Instance
Wallet Instance
VCI Component (OpenID4VCI)
VCI Component (OpenID4V...
Issues (Q)EAA
Issues (Q)EAA
Requests (Q)EAA
Requests (Q)EAA
Federation API Services
Federation API Services
Trust Anchor - Accreditation Body
Trust Anchor - Accreditation Body
Federation API Services
Federation API Services
Requests for Issuer identifier
Requests for Issuer identifier
1
1
2
2
Register
Register
User Authentication with PID
User Authentication with PID
Requests for Issuer Metadata
Requests for Issuer Metadata
RP Component (OpenID4VP)
RP Component (OpenID4VP...
5
5
3
3
4
4
Text is not SVG - cannot display
\ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/High-Level-Flow-Status-Attestation.svg b/refs/pull/443/merge/en/_images/High-Level-Flow-Status-Attestation.svg new file mode 100644 index 000000000..fe109258f --- /dev/null +++ b/refs/pull/443/merge/en/_images/High-Level-Flow-Status-Attestation.svg @@ -0,0 +1,4 @@ + + + +
Credential Issuer
Wallet Instance
Verifier
1
Request a Status Attestation for a Digital Credential
Provide a Status Attestation for a Digital Credential
Request a Digital Credential with a corresponding Status Attestation
Present a Digital Credential with a corresponding Status Attestation
2
3
4
At time t0, a Status Attestation is obtained by the Wallet Instance, for each stored Digital Credential
At time t1, greater that t0 and less that the expiration time of the Status Attestation, the Wallet Instance presents a Digital Credential and the corresponding Status Attestation if requested.

This page contains the following errors:

error on line 3 at column 6: XML declaration allowed only at the start of the document

Below is a rendering of the page up to the first error.

\ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/Low-Level-Flow-ITWallet-PID-QEAA-Issuance.svg b/refs/pull/443/merge/en/_images/Low-Level-Flow-ITWallet-PID-QEAA-Issuance.svg new file mode 100644 index 000000000..90dd9849b --- /dev/null +++ b/refs/pull/443/merge/en/_images/Low-Level-Flow-ITWallet-PID-QEAA-Issuance.svg @@ -0,0 +1 @@ +User's smartphoneUserUserBrowserBrowserWallet InstanceWallet InstancePID/(Q)EAA ProviderPID/(Q)EAA Provider1obtain your Digital Credential2yesObtain the list of the Trusted PID/(Q)EAA Providers3confirm the selection of PID/(Q)EAA Provider4okCheck PID/(Q)EAA Provider is part of the Federation and obtain its metadata5create PKCE code verifier and WIA-PoP6PAR Request (response_type,client_id,code_challenge,code_challenge_method,request)with OAuth-Client-Attestation and OAuth-Client-Attestation-PoP in the HeaderCheck Wallet Provider is part of the FederationCheck signature of the Wallet Attestation and its validity7PAR Response (request_uri, expires_in)8Authorization Request (client_id, request_uri)9Authorization Request (client_id, request_uri)alt[Credential == PID]user authentication with national eIDAS notified Schemes and consent[Credential == (Q)EAA)]user authentication with PID and consent10Authorization Response (code, state, iss)11Authorization Response (code, state, iss)12generate DPoP key13generate DPoP proof and WIA-PoP for PID/(Q)EAA Provider token endpoint14Token Request with DPoP proof (client_id,grant_type,code,code_verifier,redirect_uri)with OAuth-Client-Attestation and OAuth-Client-Attestation-PoP in the Header15Token Response (access_token, token_type, expires_in, c_nonce, c_nonce_expires_in)16create proof of possession (c_nonce)17create DPoP proof for PID/(Q)EAA Provider credential endpoint18Credential Request with DPoP access_token and DPoP proof (credential_definition, format, proof)alt[Credential is available]19Credential Response (format, credential, c_nonce, c_nonce_expires_in, notification_id)20PID/(Q)EAA validity and status check21store credential22Notification Request HTTP POST /notification (notification_id, event)with DPoP Access TokenRegister all the credential-relatedinformation for verification/revocation23Notification Response HTTP 204 No Content[Credential is NOT available]24Credential Response (lead_time, c_nonce, c_nonce_expires_in)The Wallet Instance, after an amount of time specified by lead_time and when triggered by the User, starts the flow again \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/Low-Level-Flow-Revocation-Attestation.svg b/refs/pull/443/merge/en/_images/Low-Level-Flow-Revocation-Attestation.svg new file mode 100644 index 000000000..e77ec7936 --- /dev/null +++ b/refs/pull/443/merge/en/_images/Low-Level-Flow-Revocation-Attestation.svg @@ -0,0 +1 @@ +Wallet InstanceWallet InstanceIssuerIssuerAuthentic SourceAuthentic Source1POST /status request(credential_pop=$CredentialPoPJWT)2Validate Credential PoP JWTThe Issuer obtains from the Authentic Sourcethe updated attributes and the validity statusof them through an out-of-band mechanism,(e.g. though the PDND APIs system)3Check for attributesupdate and validity4Create StatusAttestation JWT5Response with Status Attestation JWT \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/Low-Level-Flow-Revocation.svg b/refs/pull/443/merge/en/_images/Low-Level-Flow-Revocation.svg new file mode 100644 index 000000000..ef2f16fce --- /dev/null +++ b/refs/pull/443/merge/en/_images/Low-Level-Flow-Revocation.svg @@ -0,0 +1 @@ +Wallet InstanceWallet InstanceIssuerIssuer1POST /revoke request(credential_pop=$CredentialPoPJWT)2Validate the CredentialProof of Possession3Revoke the Credential4Response Ok \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/cross_device_auth_seq_diagram.svg b/refs/pull/443/merge/en/_images/cross_device_auth_seq_diagram.svg new file mode 100644 index 000000000..6a5b3ca6f --- /dev/null +++ b/refs/pull/443/merge/en/_images/cross_device_auth_seq_diagram.svg @@ -0,0 +1 @@ +User's DevicesUserUserWallet InstanceWallet Instanceuser-agentuser-agentRelying PartyRelying Party1Web Service navigation2Request Protected ResourcePresentation Phase3Create astatevaluebound to user-agent cookie4Create request_uri resource5QRCode OR HTTP Redirect (302) withclient_id, request_uri, state, [request_uri_method] [client_id_scheme]Cross Device only6Show the QRCode page7Open the Wallet Instance app, local authentication8Scan QR Code9Extract the parameters from the QR Code10evaluates trust with the client_id [client_id_scheme]alt[if request_uri_method is set with POST]11provides Wallet metadata to the request_uri endpoint12evaluates the Wallet tecnical capabilities[if request_uri_method is set with GET or not present]13requests the signed request object from the request_uri endpoint14signed request object15evaluates Relying Party Metadata and policies16Verify signature of the signed Request Object17Validate requested VP(s)18Request for consent19Confirmed20POST Authorization Responsewith vp_token, state, presentation_submission21Evaluate the Verifiable Presentation token22Validate the Wallet Attestation.Attest the Wallet Provideris part of the Federationand the Wallet Instance is not revoked.23Attest Credential Issuer Trustand Validate JWT Signature24Process the credentialProcess the credential:Check Holder Key Binding and Proof of Possession:- using the public key bound in the Credential to verify the VP token. Then extract the disclosed attributes: check if all the required data are available25Update the User session (cookie updated)Same Device only26HTTP/1.1 200 OK{"redirect_uri": https url with response_code }27Use the redirect_uriCross Device only28HTTP/1.1 200 OK29QRCode JS: Check authentication state (HTTP request with cookie)30Authentication state given with HTTP codes, untill expired or successful \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/static_view_wallet_instance_attestation.svg b/refs/pull/443/merge/en/_images/static_view_wallet_instance_attestation.svg new file mode 100644 index 000000000..2f18451e1 --- /dev/null +++ b/refs/pull/443/merge/en/_images/static_view_wallet_instance_attestation.svg @@ -0,0 +1 @@ +UserWallet ProviderDevice OEMWallet SolutionWallet InstanceWallet BackendDevice Integrity ServiceUseUseIs part ofProvides Wallet Attestationcontrol / activateIs an instance ofProvideProvide \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/trust-roles.svg b/refs/pull/443/merge/en/_images/trust-roles.svg new file mode 100644 index 000000000..a1e8dd823 --- /dev/null +++ b/refs/pull/443/merge/en/_images/trust-roles.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/refs/pull/443/merge/en/_images/verifier_qr_code.svg b/refs/pull/443/merge/en/_images/verifier_qr_code.svg new file mode 100644 index 000000000..437ad39ca --- /dev/null +++ b/refs/pull/443/merge/en/_images/verifier_qr_code.svg @@ -0,0 +1,2 @@ + + diff --git a/refs/pull/443/merge/en/_images/wallet_instance_acquisition.svg b/refs/pull/443/merge/en/_images/wallet_instance_acquisition.svg new file mode 100644 index 000000000..040a35eb4 --- /dev/null +++ b/refs/pull/443/merge/en/_images/wallet_instance_acquisition.svg @@ -0,0 +1 @@ +UserWallet InstanceDevice Integrity ServiceWallet Provider backend1Request a new operation thatrequires aWallet Attestation2Check ifCryptographic Hardware Keysis available3Generates an ephemeral key pairJWKCheck Wallet Provider is part of the Federation and obtain its metadata4Getchallenge5Generate one time usechallenge6challenge7Generateclient_data_hashas SHA256(challenge, public_jwk)8GenerateCryptographic Hardware KeyPoPhardware_signature= sign(client_data_hash, wallet_hardware_key_tag)9generateIntegrityAssertion(client_data_hash)10integrity_assertion11Generate Wallet Attestation Request withintegrity_assertion,hardware_signature,challenge,Cryptographic Hardware Key Tag,public_jwksigned with ephemeralJWK12Send Wallet Attestation RequestCheck if Wallet Instance is initialized and validusing Cryptographic Hardware Key Tag andhardware_signature13Validatechallenge14Validateintegrity_assertion15Validatehardware_signature16ValidateJWKPoP17CreateWallet Attestation18Wallet Attestation \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/wallet_instance_initialization.svg b/refs/pull/443/merge/en/_images/wallet_instance_initialization.svg new file mode 100644 index 000000000..9cd561232 --- /dev/null +++ b/refs/pull/443/merge/en/_images/wallet_instance_initialization.svg @@ -0,0 +1 @@ +UserWallet InstanceDevice Integrity ServiceWallet Provider backendonly upon first installation of the app1starts the app (first use)2Check if the device meets the minimum security requirementsand ifDevice Integrity Serviceis availableCheck Wallet Provider is part of the Federation and obtain its metadata3Getchallenge4Generate one time usechallenge5challenge6GenerateCryptographic Hardware Keyspair and storeCryptographic Hardware Key Tag7attestKey(challenge, Cryptographic Hardware Key Tag)8Key Attestationsigned by OEM9Sendchallenge,Key AttestationandCryptographic Hardware Key Tag10Validatechallenge11ValidateKey Attestation12StoreCryptographic Hardware Keys13OK14Wallet Instance Initialized \ No newline at end of file diff --git a/refs/pull/443/merge/en/_images/wallet_instance_lifecycle.svg b/refs/pull/443/merge/en/_images/wallet_instance_lifecycle.svg new file mode 100644 index 000000000..386473b45 --- /dev/null +++ b/refs/pull/443/merge/en/_images/wallet_instance_lifecycle.svg @@ -0,0 +1 @@ +InstalledOperationalValidDeactivatedinstallverifyvalidateinvalidaterevokerevokeuninstalluninstalluninstalluninstall \ No newline at end of file diff --git a/refs/pull/443/merge/en/_sources/algorithms.rst.txt b/refs/pull/443/merge/en/_sources/algorithms.rst.txt new file mode 100644 index 000000000..1c9b101a6 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/algorithms.rst.txt @@ -0,0 +1,130 @@ +.. include:: ../common/common_definitions.rst + +.. _supported_algs: + +Cryptographic Algorithms +++++++++++++++++++++++++ + +The following algorithms MUST be supported: + +.. list-table:: + :widths: 20 20 20 20 + :header-rows: 1 + + * - **Algorithm `alg` parameter value** + - **Description** + - **Operations** + - **References** + * - **ES256** + - Elliptic Curve Digital Signature Algorithm (ECDSA) using one of the enabled curves listed in the section below and SHA256. + - Signature + - :rfc:`7518`, `[SOG-IS] `_, `[ETSI] `_ . + * - **ES384** + - Elliptic Curve Digital Signature Algorithm (ECDSA) using one of the enabled curves listed in the section below and SHA384. + - Signature + - :rfc:`7518`, `[SOG-IS] `_, `[ETSI] `_ . + * - **ES512** + - Elliptic Curve Digital Signature Algorithm (ECDSA) using one of the enabled curves listed in the section below and SHA521. + - Signature + - :rfc:`7518`, `[SOG-IS] `_, `[ETSI] `_ . + * - **RSA-OAEP-256** + - RSA Encryption Scheme with Optimal Asymmetric Encryption Padding (OAEP) using SHA256 hash function and the MGF1 with SHA-256 mask generation function. + - Key Encryption + - :rfc:`7516`, :rfc:`7518`. + * - **A128CBC-HS256** + - AES encryption in Cipher Block Chaining mode with 128-bit Initial Vector value, plus HMAC authentication using SHA-256 and truncating HMAC to 128 bits. + - Content Encryption + - :rfc:`7516`, :rfc:`7518`. + * - **A256CBC-HS512** + - AES encryption in Cipher Block Chaining mode with 256-bit Initial Vector value, plus HMAC authentication using SHA-512 and truncating HMAC to 256 bits. + - Content Encryption + - :rfc:`7516`, :rfc:`7518`. + +The following Elliptic Curves MUST be supported for the Elliptic Curve Digital Signature Algorithm: + +.. list-table:: + :widths: 20 20 20 + :header-rows: 1 + + * - **Curve Family** + - **Short Curve Name** + - **References** + * - **Brainpool** + - brainpoolP256r1, brainpoolP384r1, brainpoolP512r1. + - :rfc:`5639`, `[ETSI] `_ . + * - **NIST** + - P-256, P-384, P-521 + - `[ETSI] `_, `[FIPS-186-4] `_, `[ISO/IEC 14888-3] `_. + +The following algorithms are RECOMMENDED to be supported: + +.. list-table:: + :widths: 20 20 20 20 + :header-rows: 1 + + * - **Algorithm `alg` parameter value** + - **Description** + - **Operations** + - **References** + * - **PS256** + - RSASSA (RSA with Signature Scheme Appendix) with PSS ( Probabilistic Signature Scheme) padding using SHA256 hash function and MGF1 mask generation function with SHA-256. + - Signature + - :rfc:`7518`, `[SOG-IS] `_. + * - **PS384** + - RSASSA (RSA with Signature Scheme Appendix) with PSS ( Probabilistic Signature Scheme) padding using SHA384 hash function and MGF1 mask generation function with SHA-384. + - Signature + - :rfc:`7518`, `[SOG-IS] `_. + * - **PS512** + - RSASSA (RSA with Signature Scheme Appendix) with PSS ( Probabilistic Signature Scheme) padding using SHA512 hash function and MGF1 mask generation function with SHA-512. + - Signature + - :rfc:`7518`, `[SOG-IS] `_. + * - **ECDH-ES** + - Elliptic Curve Diffie-Hellman (ECDH) Ephemeral Static key agreement using Concat Key Derivation Function (KDF). + - Key Encryption + - :rfc:`7518`. + * - **ECDH-ES+A128KW** + - ECDH-ES using Concat KDF and content encryption key (CEK) wrapped using AES with a key length of 128 (A128KW). + - Key Encryption + - :rfc:`7518`. + * - **ECDH-ES+A256KW** + - ECDH-ES using Concat KDF and content encryption key (CEK) wrapped using AES with a key length of 256 (A256KW). + - Key Encryption + - :rfc:`7518`. + +The following algorithms MUST NOT be supported: + +.. list-table:: + :widths: 20 20 20 20 + :header-rows: 1 + + * - **Algorithm `alg` parameter value** + - **Description** + - **Operations** + - **References** + * - **none** + - - + - Signature + - :rfc:`7518`. + * - **RSA_1_5** + - RSAES with PKCS1-v1_5 padding scheme. Use of this algorithm is generally not recommended. + - Key Encryption + - :rfc:`7516`, `[Security Vulnerability] `_, `[SOG-IS] `_. + * - **RSA-OAEP** + - RSA Encryption Scheme with Optimal Asymmetric Encryption Padding (OAEP) using default parameters. + - Key Encryption + - :rfc:`7518`, `[SOG-IS] `_. + * - **HS256** + - HMAC using SHA256. + - Signature + - :rfc:`7518`. + * - **HS384** + - HMAC using SHA384. + - Signature + - :rfc:`7518`. + * - **HS512** + - HMAC using SHA512 + - Signature + - :rfc:`7518`. + + + diff --git a/refs/pull/443/merge/en/_sources/authentic-sources.rst.txt b/refs/pull/443/merge/en/_sources/authentic-sources.rst.txt new file mode 100644 index 000000000..398fde02b --- /dev/null +++ b/refs/pull/443/merge/en/_sources/authentic-sources.rst.txt @@ -0,0 +1,40 @@ +.. include:: ../common/common_definitions.rst + + +Authentic Sources ++++++++++++++++++++ + +Authentic Sources are responsible for the authenticity of the User's attributes provided as Digital Credentials by the PID/(Q)EAA Provider. During the Issuance Flow, PID/(Q)EAA Providers, after authenticating the User, request from Authentic Sources the attributes required to provide the requested Credential. If PID/(Q)EAA Providers and Authentic Sources are both allowed to use PDND, the communication between them is accomplished in compliance with [`MODI`_] and [`PDND`_] and according to the rules defined within this specification. In particular, + + - The Authentic Source MUST provide an e-service registered within the PDND catalogue which the PID/(Q)EAA Provider, as the recipient, MUST use to request the User's attributes. + - In case of unavailability of the User's attributes, the Authentic Source MUST provide a response to the PID/(Q)EAA Provider with an estimation time when a new request can be sent. + - The PID/(Q)EAA Provider MUST provide to the Authentic Source an evidence that: + + - the request for Users attributes is related to data about themselves; + - the request for User attributes comes from a valid Wallet Instance. + + - The PID/(Q)EAA Provider MUST make available to the Authentic Source an e-service for notifications on attributes availability and validity status (revocation or updates). The Authentic Source MUST use this e-service to notify to the PID/(Q)EAA Provider the notifications on the availability of the User's attributes as well as those relating to the attributes updates. + - The protocol flow MUST ensure integrity, authenticity, and non-repudiation of the exchanged data between the Authentic Source and the PID/(Q)EAA Provider. + - The e-services MUST be implemented in REST. SOAP protocol MUST NOT be used. + + + +Security Patterns +---------------------- + +The following security patterns and profiles are applicable: + + - **[REST_JWS_2021_POP]** JWS POP Voucher Issuing Profile (*Annex 3 - Standards and technical details used for Voucher Authorization* [`PDND`_]): REQUIRED. It adds a proof of possession on the Voucher. The client using the Voucher to access an e-service MUST demonstrate the proof of possession of the private key whose public is attested on the Voucher. + + - **[ID_AUTH_REST_02]** Client Authentication with X.509 certificate with uniqueness of the token/message (*Annex 2 - Security Pattern* [`MODI`_]): REQUIRED. It guarantees trust between the Authentic Source and the PID/(Q)EAA Provider and provides a mitigation against replay attacks. + + - **[INTEGRITY_REST_01]** REST message payload integrity (*Annex 2 - Security Pattern* [`MODI`_]): REQUIRED. It adds message payload integrity of the HTTP POST request. + + - **[AUDIT_REST_02]** submission of audit data within the request (*Annex 2 - Security Pattern* [`MODI`_]): OPTIONAL. The Authentic Source MAY request an evidence about the User Authentication related to the User's attributes requested by the PID/(Q)EAA Provider and/or a proof that the Wallet Instance is valid. In this case this pattern MUST be used. + + - **[PROFILE_NON_REPUDIATION_01]** Profile for non-repudiation of transmission (*Annex 3 - Interoperability Profile* [`MODI`_]): REQUIRED. This profile uses the following security patterns: + + - **ID_AUTH_CHANNEL_01** or **ID_AUTH_CHANNEL_02** + - **ID_AUTH_REST_02** + - **INTEGRITY_REST_01** + diff --git a/refs/pull/443/merge/en/_sources/backup-restore.rst.txt b/refs/pull/443/merge/en/_sources/backup-restore.rst.txt new file mode 100644 index 000000000..186042348 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/backup-restore.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _backup-restore.rst: + +backup-restore.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/en/_sources/contribute.rst.txt b/refs/pull/443/merge/en/_sources/contribute.rst.txt new file mode 100644 index 000000000..c4bea2975 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/contribute.rst.txt @@ -0,0 +1,67 @@ +.. include:: ../common/common_definitions.rst + +.. _contribute.rst: + +How to contribute ++++++++++++++++++++++++++++ + +The IT-Wallet project, including this document, follows an **open development process**. This approach ensures the development process is accessible to all, inviting all interested parties to participate. + +Consequently, stakeholders, national and international community members are not only encouraged but also heartily welcomed to contribute to the refinement of these technical rules. + +Below are several methods available for contributing to this project: + +- **GitHub issues**. By opening an issue, you can seek clarification, propose enhancements, or report editorial typos. If you are working on an issue, we encourage you to open a draft pull request and link it. +- **Pull requests**. Pull requests represent active contributions to the project, typically, but not always following issue-based discussions. Once a pull request is initiated, it facilitates discussion and review of the proposed changes before they are merged into the main branch (`versione-corrente`). +- **Developers Italia Slack channel**. Slack is a messaging application designed for businesses, connecting people to the information they need. *Developers Italia* is an open community based on contributions and participation from public administrations, developers, technicians, students, and citizens. *Developers Italia* has initiated a Slack channel that [everyone can join for free](https://slack.developers.italia.it/), where you can learn about all their activities and partake in discussions. + + +Acknowledgements +---------------- + +We would like to thank the following individuals for their comments, +concerns, ideas, contributions, some of which substantial, to this +implementation profile and to the initial set of implementations. + +- Alen Horvat +- Amir Sharif +- Andrea Moro +- Andrea Prosseda +- Elisa Nicolussi Paolaz +- Emanuele De Cupis +- Emiliano Vernini +- Francesco Grauso +- Francesco Marino +- Francesco Ventola +- Gabriella Cefalù +- Giada Sciarretta +- Giuseppe De Marco +- Klaas Wierenga +- Kristina Yasuda +- Leif Johansson +- Lorenzo Cerini +- Mart Aarma +- Marta Sciunnach +- Michele Silletti +- Nicola Saitto +- Niels van Dijk +- Oliver Terbu +- Paul Bastien +- Pasquale De Rose +- Peter Altmann +- Riccardo Iaconelli +- Roland Hedberg +- Salvatore Laiso +- Salvatore Manfredi +- Stefano Alifuoco +- Takahiko Kawasaki +- Thomas Chiozzi +- Torsten Lodderstedt +- Vladimir Duzhinov + + +If anyone has been forgotten, please accept our apologies with the +request to propose the modification of this page via a [Pull Request](https://github.com/italia/eudi-wallet-it-docs) +with a brief description of the contribution offered, during which +event or channel, and during which period. We will then have the opportunity +to apologize again and make amends as soon as possible, including you in the list. diff --git a/refs/pull/443/merge/en/_sources/defined-terms.rst.txt b/refs/pull/443/merge/en/_sources/defined-terms.rst.txt new file mode 100644 index 000000000..dc086506f --- /dev/null +++ b/refs/pull/443/merge/en/_sources/defined-terms.rst.txt @@ -0,0 +1,207 @@ +.. include:: ../common/common_definitions.rst + +.. _defined-terms.rst: + + +Normative Language and Conventions +++++++++++++++++++++++++++++++++++ + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. + + +Defined Terms ++++++++++++++ + +The terms *User*, *Trust Service*, *Trust Model*, *Trusted List*, *Trust Framework*, *Attribute*, *Electronic Attestations of Attributes Provider* or *Trust Service Provider (TSP)*, *Person Identification Data (PID)*, *Revocation List*, *Qualified Electronic Attestations of Attributes Provider* or *Qualified Trust Service Provider (QTSP)*, *Electronic Attestation of Attributes (EAA)*, are defined in the `EIDAS-ARF`_. + +Below are the description of acronyms and definitions which are useful for further insights into topics that complement the it-wallet and the interacting components. + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + - Notes + * - User + - A natural or legal person, or a natural person representing another natural person or a legal person, that uses a trust services or electronic identification means provided in accordance with EUDI Wallet Architecture Reference Framework. [ARF v1.4] + - + * - User Attribute + - A characteristic, quality, right or permission of a natural or legal person or of an object. [ARF v1.4] + - Other alternative terms: User Claim + * - Digital Identity Provider + - Entity responsible for identifying citizens for the issuance of a digital identity. + - + * - Digital Credential + - A signed set of Attributes encapsulated in a specific data format, such as mdoc format specified in [ISO 18013-5] or the SD-JWT VC format specified in [SD-JWT-VC]. This may be a Personal Identification Data (PID), (Qualified) Electronic Attestation of Attribute ((Q)EAA). [Revised from ARF v1.4] + - Differences with ARF: The definition from ARF restricts the data format to mdoc and SD-JWT VC. For the scope of the Trust Model, a Digital Credential definition should be neutral on the format. ARF alternative terms: Electronic Attestation, Attestation. Other alternative terms: Verifiable Credential, Digital Attestation. + * - Organizational Entity + - A legal person (only considering organizations and public entities, not natural/physical persons) recognized by the Member State through a unique identifier to operate a certain role within the EUDI Wallet ecosystem. + - In this category the following entity roles are included: Wallet Provider, Credential Issuer, Relying Party, QTSP In general, any kind of Entity that must be registered through a national or European registration mechanism. ARF alternative terms: legal person (only considering organizations and public entities, not natural/physical persons) + * - Wallet Solution + - A Wallet Solution is the entire eIDAS-compliant product and service provided by a Wallet Provider to all Users and certified as EUDI-compliant by a Conformity Assessment Body (CAB). [Revised from ARF v1.4] + - Differences with ARF: editorial ARF alternative terms: EUDI Wallet Solution + * - Wallet Provider + - An Organizational Entity, responsible for the management and release operation of a Wallet Solution. The Wallet Provider issues the Wallet Attestations to its Wallet Instances through an Attestation Service. The Wallet Attestation certifies the genuinity and authenticity of the Wallet Instance and its compliance with the security and privacy requirements. [Revised from ARF v1.4] + - Differences with ARF: editorial ARF alternative terms: EUDI Wallet Provider + * - Wallet Instance + - Instance of a Wallet Solution installed on a User’s device belonging to and which is controlled by a User. It enables the storage and management of Digital Credentials.The Wallet Instance provides graphical interfaces for User interaction with Relying Parties, PID, (Q)EAA Providers and the Wallet Provider. [Revised from ARF v1.4] + - Differences with ARF: editorial ARF alternative terms: EUDI Wallet Instance + * - Wallet Provider Backend + - Is the technical infrastructure and server-side components, including a set of endpoints, managed by a Wallet Provider. + - + * - Credential Issuer + - An Organizational Entity providing Digital Credentials to Users. It may be PID Provider or (Q)EAA Providers. [Revised from ARF v1.4] + - Differences with ARF: (i) merged the PID Providers and (Q)EEA Providers definitions using the general term Digital Credential, (ii) renamed “Member Stare or other legal entity” in “Organizational Entity” ARF alternative terms: PID Providers,(Q)EEA Providers, Attestation Provider Other alternative terms: Verifiable Credential Issuer + * - Relying Party + - An Organizational Entity that relies upon an electronic identification or a Trust Service originating from a Wallet Instance. [Revised from ARF v1.4] + - Differences with ARF: renamed “natural or legal person” in “Organizational Entity”. + * - Relying Party Instance + - A Relying Party Instance in the context of a mobile application or a standalone embedded device refers to a specific deployment of the application or device. These instances depend on an User Authentication through a Wallet Instance to confirm User identities before granting access to their functionalities. Each version or environment where the application or device is running, be it a particular release of a mobile app installed on a User's smartphone or a specific embedded device in use, constitutes a separate instance. In case of proximity supervised scenarios, it belongs to and is controlled by a Verifier. [Revised from ARF v1.4] + - Differences with ARF: added a sentence on proximity supervised scenarios. Other alternative terms: Verifier App + * - Verifier + - A natural person or legal person using an RP Instance. [New] + - + * - Trust + - Trust is the confidence in the security, reliability, and integrity of entities (such as systems, organizations, or individuals) and their actions, ensuring that they will operate as expected in a secure and predictable manner. It is often established through empirical proof, such as past performance, security certifications, or transparent operational practices, which demonstrate a track record of adherence to security standards and ethical conduct. [Revised from ARF v1.4] + - + * - Trust Framework + - A legally enforceable set of operational and technical rules and agreements that govern a multi-party system designed for conducting specific types of transactions among a community of participants and bound by a common set of requirements. [ARF v1.4] + - + * - Trust Model + - Collection of rules that ensure the legitimacy of the components and the entities involved in the EUDI Wallet ecosystem. [ARF v1.4] + - + * - Trusted List + - Repository of information about authoritative entities in a particular legal or contractual context which provides information about their current and historical status. It serves as the bedrock of trust, acting as federative sources that publish the crucial information about root entities within the ecosystem. [Revised from ARF v1.4] + - Differences with ARF: added the last sentence + * - Registration Authority + - A party responsible for registering all the Organizational Entities by issuing a Trust Assertion. + - ARF: Registrar + * - Conformity Assessment Body (CAB) + - A conformity assessment body as defined in Article 2, point 13, of Regulation (EC) No 765/2008, which is accredited in accordance with that Regulation as competent to carry out conformity assessment of a qualified trust service provider and the qualified trust services it provides, or as competent to carry out certification of European Digital Identity Wallets or electronic identification means. [ARF v1.4] + - + * - National Accreditation Bodies (NAB) + - A body that performs accreditation with authority derived from a Member State under Regulation (EC) No 765/2008. [ARF v1.4] + - Other alternative terms: Accreditation Authority + * - Trust Evaluation + - The process of verifying the trustworthiness of registered Organizational Entities, in accordance with pre-established rules. For example, involving the retrieval and validation of entity configurations and trust chains. + - Other alternative terms: Trust Discovery, Trust Establishment + * - Trust Assertion + - Cryptographically verifiable artifact that proves the compliance of an Organizational Entity with known rules and requirements defined within the Trust Model. + - Other alternative terms: Verifiable Attestation, Access Certificate + * - Trust Relationship + - Positive outcome of Trust Evaluation, which produces a reliable relationship between Organizational Entities, where one Organizational Entity trusts the other to securely handle data, execute transactions, or perform actions on its behalf. + - + * - Metadata + - Digital artifact that contains all the required information about an Organizational Entity, e.g., protocol related endpoints and the Organizational Entity’s cryptographic public keys (for the complete list check requirement “Metadata Content”). + - + * - Policy Language + - A formal language used to define security, privacy, and identity management policies that govern interactions and transactions within a Trust Framework. This language allows for the clear and unambiguous expression of rules and conditions, facilitating the automation of processes and interoperability among different systems and organizations. + - + * - Registration Process + - Process performed by a Registration Authority verifying necessary information to ensure Organizational Entity eligibility and compliance with the relevant rules and standards. The main goal of the Registration Process is for the Organizational Entity to receive one or more Trust Assertions to be used for the Trust Evaluation processes. + - + * - Accreditation Process + - Process performed by the National Accreditation Body to accreditate CABs. As a result of the Accreditation Process, a NAB issues an accreditation certificate to a CAB. + - Currently, out of scope of the Trust Model requirements + * - Certification Process + - Process performed by Conformity Assessment Bodies to certify the Wallet Solution. The Certification Process aims to periodically assess technical Wallet Solutions (e.g. performing vulnerability assessment and risk analysis). As a result of the Certification Process a certification is provided to the Wallet Solution. [New] + - Currently, out of scope of the Trust Model requirements + * - Notification Process + - Process defining how information is transferred to the European Commission and the inclusion of an entity in the Trusted List. + - + * - Supervision Process + - Process performed by a Supervisory Body to review and ensure proper functioning of the Wallet Provider and other relevant actors. + - Currently, out of scope of the Trust Model requirements + * - Federation Authority + - A public governance entity that issues guidelines and technical rules, and administers - directly or through its intermediary - Trusted Lists, services, and accreditation processes, the status of participants, and their eligibility evaluation. It also performs oversight functions. + - + * - Wallet Attestation + - Verifiable Attestation, issued by the Wallet Provider, that proves the security compliace of the Wallet Instance. + - + * - Wallet Secure Cryptographic Device (WSCD) + - Hardware-backed secure environment for creating, storing, and/or managing cryptographic keys and data. A WSCD MAY implement an association proof in different ways. This largely depends on the implementation of the WSCD for example: remote HSM, external smart card, internal UICC, internal native cryptographic hardware, such as the iOS Secure Enclave or the Android Hardware Backed Keystore or StrongBox + - + * - Credential Status Attestation + - Verifiable Attestation proving that a related Digital Credential is not revoked. + - + * - Device Integrity Service + - A service provided by device manufacturers that verifies the integrity and authenticity of the app instance (Wallet Instance), as well as certifying the secure storage of private keys generated by the device within its dedicated hardware. It's important to note that the terminology used to describe this service varies among manufacturers. + - + * - Cryptographic Hardware Keys + - During the app initialization, the Wallet Instance generates a pair of keys, one public and one private, which remain valid for the entire duration of the Wallet Instance's life. Functioning as a Master Key for the personal device, these Cryptographic Hardware Keys are confined to the OS domain and are not designed for signing arbitrary payloads. Their primary role is to provide a unique identification for each Wallet Instance. + - + * - Cryptographic Hardware Key Tag + - A unique identifier created by the operating system for the Cryptographic Hardware Keys, utilized to gain access to the private key stored in the hardware. + - + * - Key Attestation + - An attestation from the device's OEM that enhances your confidence in the keys used in your Wallet Instance being securely stored within the device's hardware-backed keystore. Its content is therefore defined by the operating system manufacturer. For Google Android, the term Key Attestation refers to the Strongbox Key Attestation feature. For Apple iOS, the reference is to the `Device Check`_ service, specifically the `attestKey`_ feature. + - + * - Qualified Electronic Attestation of Attributes (QEAA) + - A digitally verifiable attestation in electronic form, issued by a QTSP, that substantiates a person's possession of attributes. + - + * - Qualified Electronic Signature Provider + - The Electronic Trust Service Provider responsible for the issuing of Qualified Electronic Signature certificates to the User. + - + * - Qualified Electronic Attestation of Attributes Provider + - Organizational Entity which serves as Credential issuer providing Qualified Electronic Attestations of Attributes (QEAAs). + - + * - PID Provider + - Organizational Entity which serves as Credential issuer providing Person Identification Data to Users. + - Differences with ARF: renamed “Member Stare or other legal entity” in “Organizational Entity” + * - National Identity Provider + - It represents preexisting identity systems based on SAML2 or OpenID Connect Core 1.0, already in production in each Member State (eg: the Italian SPID and CIE id schemes notified eIDAS with *LoA* **High**, see `SPID/CIE-OpenID-Connect-Specifications`_). + - + * - Relying Party + - A natural or legal person that implements an authentication system requiring electronic attribute attestation submissions as an authentication mechanism. + - + * - Verifier + - See Relying Party + - + * - Trust Attestation + - Electronic attestation of an entity's compliance with the national regulatory framework, which is cryptographically verifiable and cannot be repudiated over time by the entity that issued it. A Trust Attestation is always related to a particular Trust Framework. + - + * - Trust Layer + - Architectural component that enables IT-Wallet system participants to establish trust, in terms of reliability and compliance of all participants with the regulatory framework governing the digital identity system. + - + * - Trust Model + - System defining how the participants of the ecosystem establish and maintain trust in their interactions. The Trust Model outlines the rules and the procedures for the entities (like users, systems, or applications) should validate each other's identities, authenticate, and establish the level of trust before exchanging information. + - + * - Level of Assurance + - The degree of confidence in the vetting process used to establish the identity of the User and the degree of confidence that the User who presents the credential is the same User to whom the Digital Credential was issued. + - + * - Holder Key Binding + - Ability of the Holder to prove legitimate possession of the private part, related to the public part attested by a Trusted Third Party. + - + * - Holder + - Natural or Legal person that receives Verifiable Credentials from the Credential Issuers, manages the Verifiable Credentials within the Wallet, and presents them to Verifiers. The Holder is the User in control of the Wallet. + - + * - Pseudonym + - Pseudonyms are alternative identifier used to represent an entity (such as a person or organization) without revealing their true identity. It provides a layer of privacy and anonymity while still allowing for consistent authentication and authorization within a system. + - + + +Acronyms +-------- + +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - **Acronym** + - **Description** + * - **OID4VP** + - OpenID for Verifiable Presentation + * - **PID** + - Person Identification Data + * - **VC** + - Verifiable Credential + * - **VP** + - Verifiable Presentation + * - **API** + - Application Programming Interface + * - **LoA** + - Level of Assurance + * - **AAL** + - Authenticator Assurance Level as defined in ``_ + * - **WSCD** + - Wallet Secure Cryptographic Device diff --git a/refs/pull/443/merge/en/_sources/index.rst.txt b/refs/pull/443/merge/en/_sources/index.rst.txt new file mode 100644 index 000000000..36c62995e --- /dev/null +++ b/refs/pull/443/merge/en/_sources/index.rst.txt @@ -0,0 +1,54 @@ +.. include:: ../common/common_definitions.rst + +============================================== +The Italian EUDI Wallet implementation profile +============================================== + +Introduction +------------ + +The European Parliament `has adopted `_ the revision of the eIDAS Regulation concerning electronic identification and trust services, introducing a significant innovation: the `European Digital Identity Wallet `_. This update marks a pivotal advancement in the EU's digital strategy, aiming to enhance the security, interoperability, and usability of digital identities across Member States. For further details, resources, and notes on this legislative development, please refer to the official EU Commission and Parliament websites. + +Italy has launched the National digital identity Wallet solution, known as IT-Wallet, established by the Legislative Decree of March 2, 2024, No. 19 (commonly referred to as the PNRR Decree)., in direct response to the European community's directives. This initiative ensures full interoperability with the digital identity solutions provided by other European Member States, aligning with European regulations. + +The purpose of the following technical rules is to define the technical architecture and reference framework to be used as a guideline by all the parties involved in the development of the IT-Wallet project. + +This documentation defines the national implementation profile of IT-Wallet, containing the technical details about components of the Wallet ecosystem, as listed below: + + - Entities of the ecosystem according to `EIDAS-ARF`_. + - Infrastructure of trust attesting realiability and eligibility of the participants. + - PID and EAAs data schemes and attribute sets. + - PID/EAA in MDL CBOR format. + - PID/EAA in `SD-JWT`_ format. + - Wallet Solution general architecture. + - Wallet Attestation. + - Issuance of PID/EAA according to `OpenID4VCI`_. + - Presentation of PID/EAA according to `OpenID4VP`_. + - Presentation of pseudonyms according to `SIOPv2`_. + - PID/EAA backup and restore mechanisms. + - PID/EAA revocation lists. + +Index of content +---------------- + +.. toctree:: + :maxdepth: 3 + + ssi-introduction.rst + defined-terms.rst + trust.rst + wallet-solution.rst + wallet-attestation.rst + pid-eaa-data-model.rst + pid-eaa-issuance.rst + pid-eaa-entity-configuration.rst + authentic-sources.rst + relying-party-solution.rst + relying-party-entity-configuration.rst + revocation-lists.rst + pseudonyms.rst + backup-restore.rst + algorithms.rst + contribute.rst + standards.rst + diff --git a/refs/pull/443/merge/en/_sources/pid-eaa-data-model.rst.txt b/refs/pull/443/merge/en/_sources/pid-eaa-data-model.rst.txt new file mode 100644 index 000000000..2111da269 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/pid-eaa-data-model.rst.txt @@ -0,0 +1,731 @@ + +.. include:: ../common/common_definitions.rst + +.. _pid_eaa_data_model.rst: + +PID/(Q)EAA Data Model ++++++++++++++++++++++ + +The Person Identification Data (PID) is issued by the PID Provider according to national laws. The main scope of the PID is allowing natural persons to be authenticated for the access to a service or to a protected resource. +The User attributes provided within the Italian PID are the ones listed below: + + - Current Family Name + - Current First Name + - Date of Birth + - Unique Identifier + - Taxpayer identification number + +The (Q)EAAs are issued by (Q)EAA Issuers to a Wallet Instance and MUST be provided in SD-JWT-VC or MDOC-CBOR data format. + +The PID/(Q)EAA data format and the mechanism through which a digital credential is issued to the Wallet Instance and presented to a Relying Party are described in the following sections. + +SD-JWT-VC Credential Format +=========================== + +The PID/(Q)EAA is issued in the form of a Digital Credential. The Digital Credential format is `SD-JWT`_ as specified in `SD-JWT-VC`_. + +SD-JWT MUST be signed using the Issuer's private key. SD-JWT MUST be provided along with a Type Metadata related to the issued Digital Credential according to Sections 6 and 6.3 of [`SD-JWT-VC`_]. The payload MUST contain the **_sd_alg** claim described in the Section 5.1.1 `SD-JWT`_ and other claims specified in this section. + +The claim **_sd_alg** indicates the hash algorithm used by the Issuer to generate the digests as described in Section 5.1.1 of `SD-JWT`_. **_sd_alg** MUST be set to one of the specified algorithms in Section :ref:`Cryptographic Algorithms `. + +Claims that are not selectively disclosable MUST be included in the SD-JWT as they are. The digests of the disclosures, along with any decoy if present, MUST be contained in the **_sd** array, as specified in Section 5.2.4.1 of `SD-JWT`_. + +Each digest value, calculated using a hash function over the disclosures, verifies the integrity and corresponds to a specific Disclosure. Each disclosure includes: + + - a random salt, + - the claim name (only when the claim is an object element), + - the claim value. + +In case of nested object in a SD-JWT payload each claim, on each level of the JSON, should be individually selectively disclosable or not. Therefore **_sd** claim containing digests MAY appear multiple times at different level in the SD-JWT. + +For each claim that is an array element the digests of the respective disclosures and decoy digests are added to the array in the same position of the original claim values as specified in Section 5.2.4.2 of `SD-JWT`_. + +In case of array elements, digest values are calculated using a hash function over the disclosures, containing: + + - a random salt, + - the array element + +In case of multiple array elements, the Issuer may wish to conceal presence of any statement while also allowing the Holder to reveal each of those elements individually (Section 5.2.6 `SD-JWT`_). Both the entire array and the individuals entries can be selective disclosure. + +The Disclosures are provided to the Holder together with the SD-JWT in the *Combined Format for Issuance* that is an ordered series of base64url-encoded values, each separated from the next by a single tilde ('~') character as follows: + +.. code-block:: + + ~~~...~ + +See `SD-JWT-VC`_ and `SD-JWT`_ for additional details. + + +PID/(Q)EAA SD-JWT parameters +---------------------------- + +The JOSE header contains the following mandatory parameters: + +.. _pid_jose_header: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **typ** + - REQUIRED. It MUST be set to ``vc+sd-jwt`` as defined in `SD-JWT-VC`_. + - :rfc:`7515` Section 4.1.9. + * - **alg** + - REQUIRED. Signature Algorithm. + - :rfc:`7515` Section 4.1.1. + * - **kid** + - REQUIRED. Unique identifier of the public key. + - :rfc:`7515` Section 4.1.8. + * - **trust_chain** + - OPTIONAL. JSON array containing the trust chain that proves the reliability of the issuer of the JWT. + - [`OID-FED`_] Section 3.2.1. + * - **x5c** + - OPTIONAL. Contains the X.509 public key certificate or certificate chain [:rfc:`5280`] corresponding to the key used to digitally sign the JWS. + - :rfc:`7515` Section 4.1.8 and [`SD-JWT-VC`_] Section 3.5. + * - **vctm** + - OPTIONAL. JSON array of base64url-encoded Type Metadata JSON documents. In case of extended type metadata, this claim contains the entire chain of JSON documents. + - [`SD-JWT-VC`_] Section 6.3.5. + +The following claims MUST be in the JWT payload. Some of these claims can be disclosed, these are listed in the following tables that specify whether a claim is selectively disclosable [SD] or not [NSD]. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **iss** + - [NSD].URL string representing the PID/(Q)EAA Issuer unique identifier. + - `[RFC7519, Section 4.1.1] `_. + * - **sub** + - [NSD]. The identifier of the subject of the Digital Credential, the User, MUST be opaque and MUST NOT correspond to any anagraphic data or be derived from the User's anagraphic data via pseudonymization. Additionally, it is required that two different Credentials issued MUST NOT use the same ``sub`` value. + - `[RFC7519, Section 4.1.2] `_. + * - **iat** + - [SD].UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in :rfc:`7519`. + - `[RFC7519, Section 4.1.6] `_. + * - **exp** + - [NSD].UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated in :rfc:`7519`. + - `[RFC7519, Section 4.1.4] `_. + * - **status** + - [NSD]. It MUST be a valid JSON object containing the information on how to read the status of the Verifiable Credential. It MUST contain the JSON member *status_assertion* set to a JSON Object containing the *credential_hash_alg* claim indicating the Algorithm used for hashing the Digital Credential to which the Status Assertion is bound. It is RECOMMENDED to use *sha-256*. + - Section 3.2.2.2 `SD-JWT-VC`_ and Section 11 `OAUTH-STATUS-ASSERTION`_. + * - **cnf** + - [NSD].JSON object containing the proof-of-possession key materials. By including a **cnf** (confirmation) claim in a JWT, the issuer of the JWT declares that the Holder is in control of the private key related to the public one defined in the **cnf** parameter. The recipient MUST cryptographically verify that the Holder is in control of that key. + - `[RFC7800, Section 3.1] `_ and Section 3.2.2.2 `SD-JWT-VC`_. + * - **vct** + - [NSD]. Credential type value MUST be an HTTPS URL String and it MUST be set using one of the values obtained from the PID/(Q)EAA Issuer metadata. It is the identifier of the SD-JWT VC type and it MUST be set with a collision-resistant value as defined in Section 2 of :rfc:`7515`. It MUST contain also the number of version of the Credential type (for instance: ``https://issuer.example.org/v1.0/personidentificationdata``). + - Section 3.2.2.2 `SD-JWT-VC`_. + * - **vct#integrity** + - [NSD].The value MUST be an "integrity metadata" string as defined in Section 3 of [`W3C-SRI`_]. *SHA-256*, *SHA-384* and *SHA-512* MUST be supported as cryptographic hash functions. *MD5* and *SHA-1* MUST NOT be used. This claim MUST be verified according to Section 3.3.5 of [`W3C-SRI`_]. + - Section 6.1 `SD-JWT-VC`_, [`W3C-SRI`_] + * - **verification** + - [NSD].Object containing user authentication information. It MUST contain the following sub-value: + + * ``trust_framework``: String identifying the trust framework used for user digital authetication. + * ``assurance_level``: String identifying the level of identity assurance guarateed during the authentication process. + * ``evidence``: It MUST contain ``method`` claim identifying the digital identity system used for the authentication. + - `OIDC-IDA`_. + +.. note:: + + Credential Type Metadata JSON Document MAY be retrieved directly from the URL contained in the claim **vct**, using the HTTP GET method or using the vctm header parameter if provided. Unlike specified in Section 6.3.1 of `SD-JWT-VC`_ the **.well-known** endpoint is not included in the current implementation profile. Implementers may decide to use it for interoperability with other systems. + + +Digital Credential Metadata Type +-------------------------------- + +The Metadata type document MUST be a JSON object and contains the following parameters. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **name** + - REQUIRED. Human-readable name of the Digital Credential type. In case of multiple language, the language tags are added to member name, delimited by a # character as defined in :rfc:`5646` (e.g. *name#it-IT*). + - [`SD-JWT-VC`_] Section 6.2 and [`OIDC`_] Section 5.2. + * - **description** + - REQUIRED. A human-readable description of the Digital Credential type. In case of multiple language, the language tags are added to member name, delimited by a # character as defined in :rfc:`5646`. + - [`SD-JWT-VC`_] Section 6.2 and [`OIDC`_] Section 5.2. + * - **extends** + - OPTIONAL. String Identitifier of an exteded metadata type document. + - [`SD-JWT-VC`_] Section 6.2. + * - **extends#integrity** + - CONDITIONAL. REQUIRED if **extends** is present. + - [`SD-JWT-VC`_] Section 6.2. + * - **schema** + - CONDITIONAL. REQUIRED if **schema_uri** is not present. + - [`SD-JWT-VC`_] Section 6.2. + * - **schema_uri** + - CONDITIONAL. REQUIRED if **schema** is not present. + - [`SD-JWT-VC`_] Section 6.2. + * - **schema#integrity** + - CONDITIONAL. REQUIRED if **schema_uri** is not present. + - [`SD-JWT-VC`_] Section 6.2. + * - **data_source** + - REQUIRED. Object containing information about the data origin. It MUST contain the object ``verification`` with this following sub-value: + + * ``trust_framework``: MUST cointain trust framework used for digital authentication towards authentic source system. + * ``authentic_source``: MUST contain ``organization_name`` and ``organization_code`` cliam related to name and code identifier of the authentic source. + - This specification + * - **vc_claims** + - REQUIRED. Object containing useful information about the Digital credential graphical rappresentation. It MUST contain the for each credential claim the following objects: + + * ``display``: MUST cointain name human-readable display name. + * ``graphics``: MUST contain position, font character, color, size. + - This specification + + +A non-normative Digital Credential metadata type is provided below. + +.. literalinclude:: ../../examples/vc-metadata-type.json + :language: JSON + +.. _sec-pid-user-claims: + +PID Claims +---------- + +Depending on the Digital Credential type **vct**, additional claims data MAY be added. The PID MUST support the following data: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **given_name** + - [SD]. Current First Name. + - `[OpenID Connect Core 1.0, Section 5.1] `_ + * - **family_name** + - [SD]. Current Family Name. + - `[OpenID Connect Core 1.0, Section 5.1] `_ + * - **birth_date** + - [SD]. Date of Birth. + - + * - **unique_id** + - [SD]. Unique citizen identifier (ID ANPR) given by the National Register of the Resident Population (ANPR). It MUST be set according to `ANPR rules `_ + - + * - **tax_id_code** + - [SD]. National tax identification code of natural person as a String format. It MUST be set according to ETSI EN 319 412-1. For example ``TINIT-`` + - + +The PID attribute schema, which encompasses all potential User data, is defined in `ARF v1.4 `_, and furthermore detailed in the `PID Rulebook `_. + + +PID Non-Normative Examples +-------------------------- + +In the following, the non-normative example of the payload of a PID represented in JSON format. + +.. literalinclude:: ../../examples/pid-json-example-payload.json + :language: JSON + +The corresponding SD-JWT version for PID is given by + +.. literalinclude:: ../../examples/pid-sd-jwt-example-header.json + :language: JSON + +.. literalinclude:: ../../examples/pid-sd-jwt-example-payload.json + :language: JSON + +In the following the disclosure list is given + +**Claim** ``iat``: + +- SHA-256 Hash: ``Yrc-s-WSr4exEYtqDEsmRl7spoVfmBxixP12e4syqNE`` +- Disclosure: + ``WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImlhdCIsIDE2ODMwMDAwMDBd`` +- Contents: ``["2GLC42sKQveCfGfryNRN9w", "iat", 1683000000]`` + +**Claim** ``unique_id``: + +- SHA-256 Hash: ``BoMGktW1rbikntw8Fzx_BeL4YbAndr6AHsdgpatFCig`` +- Disclosure: + ``WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgInVuaXF1ZV9pZCIsICJ4eHh4`` + ``eHh4eC14eHh4LXh4eHgteHh4eC14eHh4eHh4eHh4eHgiXQ`` +- Contents: ``["eluV5Og3gSNII8EYnsxA_A", "unique_id",`` + ``"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]`` + +**Claim** ``given_name``: + +- SHA-256 Hash: ``zVdghcmClMVWlUgGsGpSkCPkEHZ4u9oWj1SlIBlCc1o`` +- Disclosure: + ``WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImdpdmVuX25hbWUiLCAiTWFy`` + ``aW8iXQ`` +- Contents: ``["6Ij7tM-a5iVPGboS5tmvVA", "given_name", "Mario"]`` + +**Claim** ``family_name``: + +- SHA-256 Hash: ``VQI-S1mT1Kxfq2o8J9io7xMMX2MIxaG9M9PeJVqrMcA`` +- Disclosure: + ``WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgImZhbWlseV9uYW1lIiwgIlJv`` + ``c3NpIl0`` +- Contents: ``["eI8ZWm9QnKPpNPeNenHdhQ", "family_name", "Rossi"]`` + +**Claim** ``birth_date``: + +- SHA-256 Hash: ``s1XK5f2pM3-aFTauXhmvd9pyQTJ6FMUhc-JXfHrxhLk`` +- Disclosure: + ``WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImJpcnRoX2RhdGUiLCAiMTk4`` + ``MC0wMS0xMCJd`` +- Contents: ``["Qg_O64zqAxe412a108iroA", "birth_date", "1980-01-10"]`` + +**Claim** ``tax_id_code``: + +- SHA-256 Hash: ``ENNo31jfzFp8Y2DW0R-fIMeWwe7ELGvGoHMwMBpu14E`` +- Disclosure: + ``WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgInRheF9pZF9jb2RlIiwgIlRJ`` + ``TklULVhYWFhYWFhYWFhYWFhYWFgiXQ`` +- Contents: ``["AJx-095VPrpTtN4QMOqROA", "tax_id_code",`` + ``"TINIT-XXXXXXXXXXXXXXXX"]`` + + + +The combined format for the PID issuance is given by + +.. code-block:: + + eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBb + IkJvTUdrdFcxcmJpa250dzhGenhfQmVMNFliQW5kcjZBSHNkZ3BhdEZDaWciLCAiRU5O + bzMxamZ6RnA4WTJEVzBSLWZJTWVXd2U3RUxHdkdvSE13TUJwdTE0RSIsICJWUUktUzFt + VDFLeGZxMm84Sjlpbzd4TU1YMk1JeGFHOU05UGVKVnFyTWNBIiwgIllyYy1zLVdTcjRl + eEVZdHFERXNtUmw3c3BvVmZtQnhpeFAxMmU0c3lxTkUiLCAiczFYSzVmMnBNMy1hRlRh + dVhobXZkOXB5UVRKNkZNVWhjLUpYZkhyeGhMayIsICJ6VmRnaGNtQ2xNVldsVWdHc0dw + U2tDUGtFSFo0dTlvV2oxU2xJQmxDYzFvIl0sICJpc3MiOiAiaHR0cHM6Ly9waWRwcm92 + aWRlci5leGFtcGxlLm9yZyIsICJpYXQiOiAxNjgzMDAwMDAwLCAiZXhwIjogMTg4MzAw + MDAwMCwgInN1YiI6ICJOemJMc1hoOHVEQ2NkN25vV1hGWkFmSGt4WnNSR0M5WHMiLCAi + c3RhdHVzIjogeyJzdGF0dXNfYXNzZXJ0aW9uIjogeyJjcmVkZW50aWFsX2hhc2hfYWxn + IjogInNoYS0yNTYifX0sICJ2Y3QiOiAiaHR0cHM6Ly9waWRwcm92aWRlci5leGFtcGxl + Lm9yZy92MS4wL3BlcnNvbmlkZW50aWZpY2F0aW9uZGF0YSIsICJ2Y3QjaW50ZWdyaXR5 + IjogImM1ZjczZTI1MGZlODY5ZjI0ZDE1MTE4YWNjZTI4NmM5YmI1NmI2M2E0NDNkYzg1 + YWY2NTNjZDczZjYwNzhiMWYiLCAidmVyaWZpY2F0aW9uIjogeyJ0cnVzdF9mcmFtZXdv + cmsiOiAiZWlkYXMiLCAiYXNzdXJhbmNlX2xldmVsIjogImhpZ2giLCAiZXZpZGVuY2Ui + OiB7Im1ldGhvZCI6ICJjaWUifX0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjog + eyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5 + WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdX + YlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.NE_Q2unPGzoh + rIyVI0kAZ8nz3DLhUXBBd-jji8302PyIU0xqLnGtcWrdM9NPE_-BfUe3H-XFahYOMI54 + PUvdZw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImlhdCIsIDE2ODMwMDAwMDBd~ + WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgInVuaXF1ZV9pZCIsICJ4eHh4eHh4eC14 + eHh4LXh4eHgteHh4eC14eHh4eHh4eHh4eHgiXQ~WyI2SWo3dE0tYTVpVlBHYm9TNXRtd + lZBIiwgImdpdmVuX25hbWUiLCAiTWFyaW8iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZG + hRIiwgImZhbWlseV9uYW1lIiwgIlJvc3NpIl0~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm + 9BIiwgImJpcnRoX2RhdGUiLCAiMTk4MC0wMS0xMCJd~WyJBSngtMDk1VlBycFR0TjRRT + U9xUk9BIiwgInRheF9pZF9jb2RlIiwgIlRJTklULVhYWFhYWFhYWFhYWFhYWFgiXQ~ + +(Q)EAA non-normative examples +----------------------------- + +In the following, we provide a non-normative example of (Q)EAA in JSON. + +.. literalinclude:: ../../examples/qeaa-json-example-payload.json + :language: JSON + +The corresponding SD-JWT for the previous data is represented as follow, as decoded JSON for both header and payload. + +.. literalinclude:: ../../examples/qeaa-sd-jwt-example-header.json + :language: JSON + +.. literalinclude:: ../../examples/qeaa-sd-jwt-example-payload.json + :language: JSON + +In the following the disclosure list is given: + +**Claim** ``iat``: + +- SHA-256 Hash: ``Yrc-s-WSr4exEYtqDEsmRl7spoVfmBxixP12e4syqNE`` +- Disclosure: + ``WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImlhdCIsIDE2ODMwMDAwMDBd`` +- Contents: ``["2GLC42sKQveCfGfryNRN9w", "iat", 1683000000]`` + +**Claim** ``document_number``: + +- SHA-256 Hash: ``Dx-6hjvrcxNzF0slU6ukNmzHoL-YvBN-tFa0T8X-bY0`` +- Disclosure: + ``WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImRvY3VtZW50X251bWJlciIs`` + ``ICJYWFhYWFhYWFhYIl0`` +- Contents: + ``["eluV5Og3gSNII8EYnsxA_A", "document_number", "XXXXXXXXXX"]`` + +**Claim** ``given_name``: + +- SHA-256 Hash: ``zVdghcmClMVWlUgGsGpSkCPkEHZ4u9oWj1SlIBlCc1o`` +- Disclosure: + ``WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImdpdmVuX25hbWUiLCAiTWFy`` + ``aW8iXQ`` +- Contents: ``["6Ij7tM-a5iVPGboS5tmvVA", "given_name", "Mario"]`` + +**Claim** ``family_name``: + +- SHA-256 Hash: ``VQI-S1mT1Kxfq2o8J9io7xMMX2MIxaG9M9PeJVqrMcA`` +- Disclosure: + ``WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgImZhbWlseV9uYW1lIiwgIlJv`` + ``c3NpIl0`` +- Contents: ``["eI8ZWm9QnKPpNPeNenHdhQ", "family_name", "Rossi"]`` + +**Claim** ``birth_date``: + +- SHA-256 Hash: ``s1XK5f2pM3-aFTauXhmvd9pyQTJ6FMUhc-JXfHrxhLk`` +- Disclosure: + ``WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImJpcnRoX2RhdGUiLCAiMTk4`` + ``MC0wMS0xMCJd`` +- Contents: ``["Qg_O64zqAxe412a108iroA", "birth_date", "1980-01-10"]`` + +**Claim** ``expiry_date``: + +- SHA-256 Hash: ``aBVdfcnxT0Z5RrwdxZSUhuUxz3gM2vcEZLeYIj61Kas`` +- Disclosure: + ``WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImV4cGlyeV9kYXRlIiwgIjIw`` + ``MjQtMDEtMDEiXQ`` +- Contents: ``["AJx-095VPrpTtN4QMOqROA", "expiry_date", "2024-01-01"]`` + +**Claim** ``tax_id_code``: + +- SHA-256 Hash: ``8JjozBfovMNvQ3HflmPWy4O19Gpxs61FWHjZebU589E`` +- Disclosure: + ``WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgInRheF9pZF9jb2RlIiwgIlRJ`` + ``TklULVhYWFhYWFhYWFhYWFhYWFgiXQ`` +- Contents: ``["Pc33JM2LchcU_lHggv_ufQ", "tax_id_code",`` + ``"TINIT-XXXXXXXXXXXXXXXX"]`` + +**Claim** ``constant_attendance_allowance``: + +- SHA-256 Hash: ``GE3Sjy_zAT34f8wa5DUkVB0FslaSJRAAc8I3lN11Ffc`` +- Disclosure: + ``WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgImNvbnN0YW50X2F0dGVuZGFu`` + ``Y2VfYWxsb3dhbmNlIiwgdHJ1ZV0`` +- Contents: + ``["G02NSrQfjFXQ7Io09syajA", "constant_attendance_allowance",`` + ``true]`` + + +The combined format for the (Q)EAA issuance is represented below: + +.. code-block:: + + eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBb + IjhKam96QmZvdk1OdlEzSGZsbVBXeTRPMTlHcHhzNjFGV0hqWmViVTU4OUUiLCAiRHgt + NmhqdnJjeE56RjBzbFU2dWtObXpIb0wtWXZCTi10RmEwVDhYLWJZMCIsICJHRTNTanlf + ekFUMzRmOHdhNURVa1ZCMEZzbGFTSlJBQWM4STNsTjExRmZjIiwgIlZRSS1TMW1UMUt4 + ZnEybzhKOWlvN3hNTVgyTUl4YUc5TTlQZUpWcXJNY0EiLCAiWXJjLXMtV1NyNGV4RVl0 + cURFc21SbDdzcG9WZm1CeGl4UDEyZTRzeXFORSIsICJhQlZkZmNueFQwWjVScndkeFpT + VWh1VXh6M2dNMnZjRVpMZVlJajYxS2FzIiwgInMxWEs1ZjJwTTMtYUZUYXVYaG12ZDlw + eVFUSjZGTVVoYy1KWGZIcnhoTGsiLCAielZkZ2hjbUNsTVZXbFVnR3NHcFNrQ1BrRUha + NHU5b1dqMVNsSUJsQ2MxbyJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUu + b3JnIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjog + Ik56YkxzWGg4dURDY2Q3bm9XWEZaQWZIa3hac1JHQzlYcyIsICJzdGF0dXMiOiB7InN0 + YXR1c19hc3NlcnRpb24iOiB7ImNyZWRlbnRpYWxfaGFzaF9hbGciOiAic2hhLTI1NiJ9 + fSwgInZjdCI6ICJodHRwczovL2lzc3Vlci5leGFtcGxlLm9yZy92MS4wL2Rpc2FiaWxp + dHljYXJkIiwgInZjdCNpbnRlZ3JpdHkiOiAiMmU0MGJjZDY3OTkwMDgwODVmZmIxYTFm + MzUxN2VmZWUzMzUyOThmZDk3NmIzZTY1NWJmYjNmNGVhYTExZDE3MSIsICJ2ZXJpZmlj + YXRpb24iOiB7InRydXN0X2ZyYW1ld29yayI6ICJlaWRhcyIsICJhc3N1cmFuY2VfbGV2 + ZWwiOiAiaGlnaCIsICJldmlkZW5jZSI6IHsibWV0aG9kIjogImNpZSJ9fSwgIl9zZF9h + bGciOiAic2hhLTI1NiIsICJjbmYiOiB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6 + ICJQLTI1NiIsICJ4IjogIlRDQUVSMTladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxz + N3ZDZUdlbWMiLCAieSI6ICJaeGppV1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0 + NGpUOUYySFpRIn19fQ.FAIV8Cncch43N07yBcWleJg4ZO9o_XdefgIejdShK1cCj8yT9 + S022cvSpdxuV44x-c_XmTn3Db9t0jJJPtqebA~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STj + l3IiwgImlhdCIsIDE2ODMwMDAwMDBd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgI + mRvY3VtZW50X251bWJlciIsICJYWFhYWFhYWFhYIl0~WyI2SWo3dE0tYTVpVlBHYm9TN + XRtdlZBIiwgImdpdmVuX25hbWUiLCAiTWFyaW8iXQ~WyJlSThaV205UW5LUHBOUGVOZW + 5IZGhRIiwgImZhbWlseV9uYW1lIiwgIlJvc3NpIl0~WyJRZ19PNjR6cUF4ZTQxMmExMD + hpcm9BIiwgImJpcnRoX2RhdGUiLCAiMTk4MC0wMS0xMCJd~WyJBSngtMDk1VlBycFR0T + jRRTU9xUk9BIiwgImV4cGlyeV9kYXRlIiwgIjIwMjQtMDEtMDEiXQ~WyJQYzMzSk0yTG + NoY1VfbEhnZ3ZfdWZRIiwgInRheF9pZF9jb2RlIiwgIlRJTklULVhYWFhYWFhYWFhYWF + hYWFgiXQ~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgImNvbnN0YW50X2F0dGVuZGF + uY2VfYWxsb3dhbmNlIiwgdHJ1ZV0~ + +MDOC-CBOR +========= + +The PID/(Q)EAA MDOC-CBOR data model is defined in ISO/IEC 18013-5, the standard born for the the mobile driving license (mDL) use case. + +The MDOC data elements MUST be encoded as defined in `RFC 8949 - Concise Binary Object Representation (CBOR) `_. + +The PID encoded in MDOC-CBOR format uses the document type set to `eu.europa.ec.eudiw.pid.1`, according to the reverse domain approach defined in the +`EIDAS-ARF`_ and ISO/IEC 18013-5. + +The document's data elements utilize a consistent namespace for the mandatory Mobile Driving License attributes, while the national PID attributes use the domestic namespace `eu.europa.ec.eudiw.pid.it.1`, as outlined in this implementation profile. + +In compliance with ISO/IEC 18013-5, the MDOC data model in the domestic namespace `eu.europa.ec.eudiw.pid.it.1`, requires the following attributes: + +.. _table-mdoc-attributes: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Attribute name** + - **Description** + - **Reference** + * - **version** + - *tstr (text string)*. Version of the data structure being used. It's a way to track changes and updates to the standard or to a specific implementation profile. This allows for backward compatibility and understanding of the data if the standard or implementation evolves over time. + - [ISO 18013-5#8.3.2.1.2] + * - **status** + - *uint (unsigned int)*. Status code. For example ``"status":0`` means OK (normal processing). + - [ISO 18013-5#8.3.2.1.2.3] + * - **documents** + - *bstr (byte string)*. The collection of digital documents. Each document in this collection represents a specific type of data or information related to the Digital Credential. + - [ISO 18013-5#8.3.2.1.2] + +Each document within the **documents** collection MUST have the following structure: + +.. _table-mdoc-documents-attributes: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Attribute name** + - **Description** + - **Reference** + * - **docType** + - *tstr (text string)*. Document type. For the PID, the value MUST be set to ``eu.europa.ec.eudiw.pid.1.`` For an mDL, the value MUST be ``org.iso.18013-5.1.mDL``. + - [ISO 18013-5#8.3.2.1.2] + * - **issuerSigned** + - *bstr (byte string)*. It MUST contain the Mobile Security Object for Issuer data authentication and the data elements protected by Issuer data authentication. + - [ISO 18013-5#8.3.2.1.2] + +The **issuerSigned** object MUST have the following structure: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Attribute name** + - **Description** + - **Reference** + * - **nameSpaces** + - *bstr (byte string)* with *tag* 24 and *major type* 6. Returned data elements for the namespaces. It MAY be possible to have one or more namespaces. The `nameSpaces` MUST use the same value for the document type. However, it MAY have a domestic namespace to include attributes defined in this implementation profile. The value MUST be set to ``eu.europa.ec.eudiw.pid.it.1``. + - [ISO 18013-5#8.3.2.1.2] + * - **issuerAuth** + - *bstr (byte string)*. Contains *Mobile Security Object* (MSO), a COSE Sign1 Document, issued by the Credential Issuer. + - [ISO 18013-5#9.1.2.4] + +During the presentation of the MDOC-CBOR credential, in addition to the objects in the table above, a **deviceSigned** object MUST also be added. **deviceSigned** MUST NOT be included in the issued credential provided by the PID/(Q)EAA Issuer. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Attribute name** + - **Description** + - **Reference** + * - **deviceSigned** + - *bstr (byte string)*. Data elements signed by the Wallet Instance during the presentation phase. + - [ISO 18013-5#8.3.2.1.2] + +Where the **deviceSigned** MUST have the following structure: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Attribute name** + - **Description** + - **Reference** + * - **nameSpaces** + - *tstr (text string)*. Returned data elements for the namespaces. It MAY be possible to have one or more namespaces. It MAY be used for self-attested claims. + - [ISO 18013-5#8.3.2.1.2] + * - **deviceAuth** + - *bstr (byte string)*. It MUST contain either the *DeviceSignature* or the *DeviceMac* element. + - [ISO 18013-5#8.3.2.1.2] + + +.. note:: + + A **deviceSigned** object given during the presentation phase has two purposes: + + 1. It provides optional self-attested attributes in the ``nameSpaces`` object. If no self-attested attributes are provided by the Wallet Instance, the ``nameSpaces`` object MUST be included with an empty structure. + 2. Provide a cryptographic proof attesting that the Holder is the legitimate owner of the Credential, by means of a ``deviceAuth`` object. + + +.. note:: + + The ``issuerSigned`` and the ``deviceSigned`` objects contain the ``nameSpaces`` object and the *Mobile Security Object*. The latter is the only signed object, while the ``nameSpaces`` object is not signed. + + + +nameSpaces +---------- + +The **nameSpaces** object contains one or more *IssuerSignedItemBytes* that are encoded using CBOR bitsring 24 tag (#6.24(bstr .cbor), marked with the CBOR Tag 24(<<... >>) and represented in the example using the diagnostic format). It represents the disclosure information for each digest within the `Mobile Security Object` and MUST contain the following attributes: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Name** + - **Encoding** + - **Description** + * - **digestID** + - *integer* + - Reference value to one of the ``ValueDigests`` provided in the *Mobile Security Object* (`issuerAuth`). + * - **random** + - *bstr (byte string)* + - Random byte value used as salt for the hash function. This value SHALL be different for each *IssuerSignedItem* and it SHALL have a minimum length of 16 bytes. + * - **elementIdentifier** + - *tstr (text string)* + - Data element identifier. + * - **elementValue** + - depends by the value, see the next table. + - Data element value. + +The **elementIdentifier** data that MUST be included in a PID/(Q)EAA are: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Namespace** + - **Element identifier** + - **Description** + * - **eu.europa.ec.eudiw.pid.1** + - **issue_date** + - *full-date (CBORTag 1004)*. Date when the PID/(Q)EAA was issued. + * - **eu.europa.ec.eudiw.pid.1** + - **expiry_date** + - *full-date (CBORTag 1004)*. Date when the PID/(Q)EAA will expire. + * - **eu.europa.ec.eudiw.pid.1** + - **issuing_authority** + - *tstr (text string)*. Name of administrative authority that has issued the PID/(Q)EAA. + * - **eu.europa.ec.eudiw.pid.1** + - **issuing_country** + - *tstr (text string)*. Alpha-2 country code as defined in [ISO 3166]. + + +Depending on the Digital Credential type, additional **elementIdentifier** data MAY be added. The PID MUST support the following data: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Namespace** + - **Element identifier** + - **Description** + * - **eu.europa.ec.eudiw.pid.1** + - **given_name** + - *tstr (text string)*. See :ref:`PID Claims fields Section `. + * - **eu.europa.ec.eudiw.pid.1** + - **family_name** + - *tstr (text string)*. See :ref:`PID Claims fields Section `. + * - **eu.europa.ec.eudiw.pid.1** + - **birth_date** + - *full-date (CBORTag 1004)*. See :ref:`PID Claims fields Section `. + * - **eu.europa.ec.eudiw.pid.1** + - **unique_id** + - *tstr (text string)*. See :ref:`PID Claims fields Section `. + * - **eu.europa.ec.eudiw.pid.it.1** + - **tax_id_code** + - *tstr (text string)*. See :ref:`PID Claims fields Section `. + + +Mobile Security Object +---------------------- + +The **issuerAuth** represents the `Mobile Security Object` which is a `COSE Sign1 Document` defined in `RFC 9052 - CBOR Object Signing and Encryption (COSE): Structures and Process `_. It has the following data structure: + +* protected header +* unprotected header +* payload +* signature. + +The **protected header** MUST contain the following parameter encoded in CBOR format: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Element** + - **Description** + - **Reference** + * - **Signature algorithm** + - `-7` means ES256, SHA-256. + - RFC8152 + +.. note:: + + Only the Signature Algorithm MUST be present in the protected headers, other elements SHOULD not be present in the protected header. + + +The **unprotected header** MUST contain the following parameter: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Element** + - **Description** + - **Reference** + * - **x5chain** + - Identified with the label 33 + - `RFC 9360 CBOR Object Signing and Encryption (COSE) - Header Parameters for Carrying and Referencing X.509 Certificates `_. + +.. note:: + The `x5chain` is included in the unprotected header with the aim to make the Holder able to update the X.509 certificate chain, related to the `Mobile Security Object` issuer, without invalidating the signature. + +The **payload** MUST contain the *MobileSecurityObject*, without the `content-type` COSE Sign header parameter and encoded as a *byte string* (bstr) using the *CBOR Tag* 24. + +The `MobileSecurityObjectBytes` MUST have the following attributes: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Element** + - **Description** + - **Reference** + * - **docType** + - See :ref:`Table `. + - [ISO 18013-5#9.1.2.4] + * - **version** + - See :ref:`Table `. + - [ISO 18013-5#9.1.2.4] + * - **validityInfo** + - Object containing issuance and expiration datetimes. It MUST contain the following sub-value: + + * *signed* + * *validFrom* + * *validUntil* + - [ISO 18013-5#9.1.2.4] + * - **digestAlgorithm** + - According to the algorithm defined in the protected header. + - [ISO 18013-5#9.1.2.4] + * - **valueDigests** + - Mapped digest by unique id, grouped by namespace. + - [ISO 18013-5#9.1.2.4] + * - **deviceKeyInfo** + - It MUST contain the Wallet Instance's public key containing the following sub-values. + + * *deviceKey* (REQUIRED). + * *keyAuthorizations* (OPTIONAL). + * *keyInfo* (OPTIONAL). + - [ISO 18013-5#9.1.2.4] + +.. note:: + The private key related to the public key stored in the `deviceKey` object is used to sign the `DeviceSignedItems` object and proof the possession of the PID during the presentation phase (see the presentation phase with MDOC-CBOR). + + +MDOC-CBOR Examples +------------------ + +A non-normative example of a PID in MDOC-CBOR format is represented below using the AF Binary encoding: + +.. code-block:: text + + a366737461747573006776657273696f6e63312e3069646f63756d656e747381a267646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316c6973737565725369676e6564a26a697373756572417574688443a10126a1182159021930820215308201bca003020102021404ad06a30c1a6dc6e93be0e2e8f78dcafa7907c2300a06082a8648ce3d040302305b310b3009060355040613025a45312e302c060355040a0c25465053204d6f62696c69747920616e64205472616e73706f7274206f66205a65746f706961311c301a06035504030c1349414341205a65746573436f6e666964656e73301e170d3231303932393033333034355a170d3232313130333033333034345a3050311a301806035504030c114453205a65746573436f6e666964656e7331253023060355040a0c1c5a65746f70696120436974792044657074206f662054726166666963310b3009060355040613025a453059301306072a8648ce3d020106082a8648ce3d030107034200047c5545e9a0b15f4ff3ce5015121e8ad3257c28d541c1cd0d604fc9d1e352ccc38adef5f7902d44b7a6fc1f99f06eedf7b0018fd9da716aec2f1ffac173356c7da3693067301f0603551d23041830168014bba2a53201700d3c97542ef42889556d15b7ac4630150603551d250101ff040b3009060728818c5d050102301d0603551d0e04160414ce5fd758a8e88563e625cf056bfe9f692f4296fd300e0603551d0f0101ff040403020780300a06082a8648ce3d0403020347003044022012b06a3813ffec5679f3b8cddb51eaa4b95b0cbb1786b09405e2000e9c46618c02202c1f778ad252285ed05d9b55469f1cb78d773671f30fe7ab815371942328317c59032ad818590325a667646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316776657273696f6e63312e306c76616c6964697479496e666fa3667369676e6564c074323032332d30322d32325430363a32333a35365a6976616c696446726f6dc074323032332d30322d32325430363a32333a35365a6a76616c6964556e74696cc074323032342d30322d32325430303a30303a30305a6c76616c756544696765737473a2781865752e6575726f70612e65632e65756469772e7069642e31ac015820a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a025820cd372fb85148700fa88095e3492d3f9f5beb43e555e5ff26d95f5a6adc36f8e6035820e67e72111b363d80c8124d28193926000980e1211c7986cacbd26aacc5528d48045820f7d062d662826ed95869851db06bb539b402047baee53a00e0aa35bfbe98265d0658202a132dbfe4784627b86aa3807cd19cfeff487aab3dd7a60d0ab119a72e736936075820bdca9e8dbca354e824e67bfe1533fa4a238b9ea832f23fb4271ebeb3a5a8f7200858202c0eaec2f05b6c7fe7982683e3773b5d8d7a01e33d04dfcb162add8bd99bee9a095820bfe220d85657ccec3c67e7db1df747e9148a152334bb6d4b65b273279bcc36ec0a582018e38144f5044301d6a0b4ec9d5f98d4cd950e6ea2c29b849cbd457da29b6ad30b58203c71d2f0efa09d9e3fbbdffd29204f6b292c9f79570aef72dd86c91f7a3aa5c50c582065743d58d89d45e52044758f546034fd13a4f994bc270cdfa7844f74eb3f4b6e0d5820b4a8eb5d523bffa17b41bda12ddc7da32ae1e5f7ff3dcc394a35401f16919bbf781b65752e6575726f70612e65632e65756469772e7069642e69742e31a10e58209d6c11644651126c94acdaf0803e86d4c71d15d3b2712a14295416734efd514d6d6465766963654b6579496e666fa1696465766963654b6579a401022001215820ba01aea44eee1e338eb2f04e279dbd51b34655783ee185150838c9a7a7c4db7122582025ba0044439a3871a7b975a0994a85e79b705a9ac263b3fe899b0a93412ee8c96f646967657374416c676f726974686d675348412d32353658400813c28fd62f2602cbc14724e5865733c44a0fca589b55c085ec9d5c725d6cce25ba0044439a3871a7b975a0994a85e79b705a9ac263b3fe899b0a93412ee8c96a6e616d65537061636573a2781865752e6575726f70612e65632e65756469772e7069642e3188d818586da4686469676573744944016672616e646f6d5820156df9227ad341eaa61aabd301106fd21bdc18820e01dfc16bcf5fecc447111b71656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d30322d3232d818586fa4686469676573744944026672616e646f6d5820a3a1f13f05544d03a5b50b5fdb78465808393bcf3b7953a345fe28f820c7be0d71656c656d656e744964656e7469666965726d69737375616e63655f646174656c656c656d656e7456616c7565d903ec6a323032332d30322d3232d8185866a4686469676573744944036672616e646f6d5820852591f90f2c9ded57a03632e2c1322ab52a082a431e71a4149a6830c8f1ad0c71656c656d656e744964656e7469666965726f69737375696e675f636f756e7472796c656c656d656e7456616c7565624954d818587ca4686469676573744944046672616e646f6d5820d1d587b3512acce15c4f6b20944ceb002a464e4a158389788563408873c3fce571656c656d656e744964656e7469666965727169737375696e675f617574686f726974796c656c656d656e7456616c7565764d696e69737465726f2064656c6c27496e7465726e6fd8185864a4686469676573744944056672616e646f6d582094fdd7609c0e73dc8589b5cab11e1d9058cf8bff8a336da5f81fcba055396a0f71656c656d656e744964656e7469666965726a676976656e5f6e616d656c656c656d656e7456616c7565654d6172696fd8185865a4686469676573744944066672616e646f6d5820660c0a7bf79e0e0261ca1547a4294fb808aa70738f424b13ab1b9440b566ae1371656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756565526f737369d818586ba4686469676573744944076672616e646f6d5820315c53491286488fa07f5c2ce67135ef5c9959c3469c99a14e9b6dc924f9eba571656c656d656e744964656e746966696572696269727468646174656c656c656d656e7456616c7565d903ec6a313935362d30312d3132d818587da4686469676573744944086672616e646f6d5820764ef39c9d01f3aa6a87f441603cfe853fba3cee3bc2c168bcc9e96271d6e06371656c656d656e744964656e74696669657269756e697175655f69646c656c656d656e7456616c7565781e78787878787878782d7878782d787878782d787878787878787878787878781b65752e6575726f70612e65632e65756469772e7069642e69742e3181d8185877a46864696765737449440d6672616e646f6d5820717df3f583b1484366c33a1f869f2b5d201d466a8b589c79ab1a2d85e595432571656c656d656e744964656e7469666965726d7461785f69645f6e756d6265726c656c656d656e7456616c75657554494e49542d585858585858585858585858585858 + +The `Diagnostic Notation` of the above MDOC-CBOR is given below: + +.. literalinclude:: ../../examples/pid-mdoc-cbor-example.txt + :language: text + + diff --git a/refs/pull/443/merge/en/_sources/pid-eaa-entity-configuration.rst.txt b/refs/pull/443/merge/en/_sources/pid-eaa-entity-configuration.rst.txt new file mode 100644 index 000000000..f15444cee --- /dev/null +++ b/refs/pull/443/merge/en/_sources/pid-eaa-entity-configuration.rst.txt @@ -0,0 +1,145 @@ +.. include:: ../common/common_definitions.rst +.. _Entity_Configuration_Credential_Issuer: + +Entity Configuration of PID/(Q)EAA Providers +-------------------------------------------- + +The PID/(Q)EAA Providers, as Federation Entity, are required to adhere to the guidelines outlined in Section :ref:`Configuration of the Federation`. Specifically, they MUST provide a well-known endpoint that hosts their Entity Configuration. +The Entity Configuration of PID/(Q)EAA Providers MUST contain the parameters defined in the Sections :ref:`Entity Configuration Leaves and Intermediates` and :ref:`Entity Configurations Common Parameters`. + +The PID/(Q)EAA Providers MUST provide the following metadata types: + + - `federation_entity` + - `oauth_authorization_server` + - `openid_credential_issuer` + +In cases where the (Q)EAA Providers authenticate Users using their Wallet Instance, then the metadata for *wallet_relying_party* MUST be provided in addition to the metadata above. In case a national eID scheme is used by the PID/(Q)EAA Providers for the User authentication, they MAY include a metadata for *openid_relying_party* within their Entity Configuration. The *openid_relying_party* metadata MUST be compliant with the current version of `SPID/CIE id OIDC Technical Specification `_. + + +Metadata for federation_entity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The *federation_entity* metadata MUST contain the parameters as defined in Section :ref:`Metadata of federation_entity Leaves`. + + +Metadata for oauth_authorization_server +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The *oauth_authorization_server* metadata MUST contain the following parameters. + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - **issuer** + - It MUST contain an HTTPS URL that uniquely identifies the PID/(Q)EAA Provider. + * - **pushed_authorization_request_endpoint** + - The URL of the pushed authorization request endpoint is where a Wallet Instance MUST submit an authorization request to obtain a *request_uri* value, which can then be used at the authorization endpoint. See :rfc:`9126#as_metadata`. + * - **authorization_endpoint** + - URL of the authorization server's authorization endpoint. See :rfc:`8414#section-2`. + * - **token_endpoint** + - URL of the authorization server's token endpoint. See :rfc:`8414#section-2`. + * - **client_registration_types_supported** + - Array specifying the registration types supported. The authorization server MUST support *automatic*. See `OID-FED`_ Section 5.1.3. + * - **code_challenge_methods_supported** + - JSON array containing a list of Proof Key for Code Exchange (PKCE) :rfc:`7636` code challenge methods supported by the authorization server. The authorization server MUST support *S256*. + * - **acr_values_supported** + - See `OpenID Connect Discovery 1.0 Section 3 `_. The supported values are: + + - `https://www.spid.gov.it/SpidL1` + - `https://www.spid.gov.it/SpidL2` + - `https://www.spid.gov.it/SpidL3` + * - **scopes_supported** + - JSON array containing a list of the supported *scope* values. See :rfc:`8414#section-2`. + * - **response_modes_supported** + - JSON array containing a list of the supported "response_mode" values, as specified in `OAuth 2.0 Multiple Response Type Encoding Practices `_. The supported values MAY be *query* and *form_post.jwt* (see `[oauth-v2-jarm-03] `__). + * - **authorization_signing_alg_values_supported** + - JSON array containing a list of the JWS :rfc:`7515` supported signing algorithms (*alg* values). The values MUST be set according to Section :ref:`Cryptographic algorithms`. See Section 4 of `[oauth-v2-jarm-03] `__. + * - **grant_types_supported** + - JSON array containing a list of the supported grant type values. The authorization server MUST support *authorization_code*. + * - **token_endpoint_auth_methods_supported** + - JSON array containing a list of supported client authentication methods. The Token Endpoint MUST support *attest_jwt_client_auth* as defined in `OAUTH-ATTESTATION-CLIENT-AUTH`_. + * - **token_endpoint_auth_signing_alg_values_supported** + - JSON array containing a list of the JWS signing algorithms ("*alg*" values) supported by the token endpoint for the signature on the JWT used to authenticate the client at the Token Endpoint. See :rfc:`8414#section-2`. + * - **request_object_signing_alg_values_supported** + - JSON array containing a list of the JWS signing algorithms ("*alg*" values) supported for Request Objects. See `[openid-connect-discovery-1_0] `_. + * - **jwks** + - JSON Web Key Set containing the cryptographic keys for the authorization server. See `OID-FED`_ Section 5.2.1 and `JWK`_. + +Metadata for openid_credential_issuer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The *openid_credential_issuer* metadata MUST contain the following claims. + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - **credential_issuer** + - The PID/(Q)EAA Provider identifier. It MUST be a case sensitive URL using HTTPS scheme as defined in `OpenID4VCI`_ Sections 11.2.1 and 11.2.3. + * - **credential_endpoint** + - URL of the credential endpoint. See `OpenID4VCI`_ Section 11.2.3. + * - **revocation_endpoint** + - URL of the revocation endpoint. See :rfc:`8414#section-2`. + * - **status_attestation_endpoint** + - It MUST be an HTTPs URL indicating the endpoint where the Wallet Instances can request Status Attestations. See Section :ref:`Credential Lifecycle` for more details. + * - **notification_endpoint** + - It MUST be an HTTPs URL indicating the notification endpoint. See Section 11.2.3 of [`OpenID4VCI`_]. + * - **authorization_servers** + - OPTIONAL. Array of strings, where each string is an identifier of the OAuth 2.0 Authorization Server (as defined in [:rfc:`8414`]) the PID/(Q)EAA Provider relies on for authorization. If this parameter is omitted, the entity providing the PID/(Q)EAA Provider is also acting as the Authorization Server. + * - **display** + - See `OpenID4VCI`_ Section 11.2.3. Array of objects containing display language properties. The parameters that MUST be included are: + + - **name**: String value of a display name for the PID/(Q)EAA Provider. + - **locale**: String value that identifies the language of this object represented as a language tag taken from values defined in *BCP47* :rfc:`5646`. There MUST be only one object for each language identifier. + + * - **credential_configurations_supported** + - JSON object that outlines the details of the Credential supported by the PID/(Q)EAA Provider. It includes a list of name/value pairs, where each name uniquely identifies a specific supported Credential. This identifier is utilized to inform the Wallet Instance which Credential can be provided by the PID/(Q)EAA Provider. The associated value within the object MUST contain metadata specific to that Credential, as defined following. See `OpenID4VCI`_ Sections 11.2.3 and A.3.2. + + - **format**: String identifying the format of this Credential. The PID/(Q)EAA MUST support the value string "*vc+sd-jwt*". See `OpenID4VCI`_ Section A.3.1. + - **scope**: JSON String identifying the supported *scope* value. The Wallet Instance MUST use this value in the Pushed Authorization Request. Scope values MUST be the entire set or a subset of the *scope* values in the *scopes_supported* parameter of the Authorization Server. [See `OpenID4VCI`_ Section 11.2.3]. + - **cryptographic_binding_methods_supported**: JSON Array of case sensitive strings that identify the representation of the cryptographic key material that the issued Credential is bound to. The PID/(Q)EAA Provider MUST support the value "*jwk*". + - **credential_signing_alg_values_supported**: JSON Array of case sensitive strings that identify the algorithms that the PID/(Q)EAA Provider MUST support to sign the issued Credential. See Section :ref:`Cryptographic algorithms` for more details. + - **proof_types_supported**: JSON object which provide detailed information about the key proof(s) supported by the PID/(Q)EAA Provider. It consists of a list of name/value pairs, where each name uniquely identifies a supported proof type. The PID/(Q)EAA Provider MUST support at least "*jwt*" as defined in `OpenID4VCI`_ Section 7.2. The value associated with each name/value pair is a JSON object containing metadata related to the key proof. The PID/(Q)EAA Provider MUST support at least the parameter **proof_signing_alg_values_supported** which MUST be a JSON Array of case sensitive strings that identify the supported algorithms (see Section :ref:`Cryptographic algorithms` for more details about the supported algorithms). + - **display**: Array of objects containing display language properties. The parameters that MUST be included are: + + - **name**: String value of a display name for the Credential. + - **locale**: String value that identifies the language of this object represented as a language tag taken from values defined in *BCP47* :rfc:`5646`. There MUST be only one object for each language identifier. + + - **vct**: As defined in [:ref:`SD-JWT-VC Credential Format`]. + - **claims**: JSON object comprising a collection of name/value pairs, where each name represents a claim related to the subject described in the Credential. The value associated with each name MAY be either another nested object or an array of objects. To provide detailed information about the claim, the innermost value MUST contain at least the following parameters. See `OpenID4VCI`_ Section A.3.2. + + - **value_type**: String value determining the type of value of the claim. The values that MUST be supported by the PID/(Q)EAA Provider are *String* and *Boolean*. + - **display**: Array of objects containing display language properties. The parameters that MUST be included are: + + - **name**: String value of a display name for the claim. + - **locale**: String value that identifies the language of this object represented as a language tag taken from values defined in *BCP47* :rfc:`5646`. There MUST be only one object for each language identifier. + + * - **jwks** + - JSON Web Key Set document, passed by value, containing the protocol specific keys for the Credential Issuer. See `OID-FED`_ Section 5.2.1 and `JWK`_. + + + +Metadata for wallet_relying_party +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The *wallet_relying_party* metadata MUST contain the parameters as defined in Section :ref:`Metadata for wallet_relying_party`. + + +Example of a (Q)EAA Provider Entity Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Below is a non-normative example of an Entity Configuration of a (Q)EAA Provider containing a metadata for + + - `federation_entity` + - `oauth_authorization_server` + - `openid_credential_issuer` + - `wallet_relying_party` + +.. literalinclude:: ../../examples/ec-eaa.json + :language: JSON + diff --git a/refs/pull/443/merge/en/_sources/pid-eaa-issuance.rst.txt b/refs/pull/443/merge/en/_sources/pid-eaa-issuance.rst.txt new file mode 100644 index 000000000..77d62256f --- /dev/null +++ b/refs/pull/443/merge/en/_sources/pid-eaa-issuance.rst.txt @@ -0,0 +1,1045 @@ +.. include:: ../common/common_definitions.rst + +.. _pid_eaa_issuance.rst: + +PID/(Q)EAA Issuance ++++++++++++++++++++ + +This section describes the PID and (Q)EAAs issuance flow with an high level of security. +The relevant entities and interfaces involved in the issuance flow are: + + - *Wallet Provider*, + - *Wallet Solution*, + - *Wallet Instance*, + - *PID Provider*, + - *National Identity Provider*, + - *(Q)EAA Provider*. + + +PID/(Q)EAA Providers are composed of: + + - Credential Issuer Component: based on the "OpenID for Verifiable Credential Issuance" specification [`OpenID4VCI`_] to release the PID/(Q)EAA. + - Relying Party Component: The component to authenticate the User. PID Providers authenticate users with the national Digital Identity Providers, based on OpenID Connect Core 1.0 or SAML2 while (Q)EAA Providers authenticate users with the PID. + +The (Q)EAA Provider acts as a Verifier by sending a presentation request to the Wallet Instance, according to [`OpenID4VP`_]. The Wallet Instance MUST have a valid PID, obtained in a previous time, to get authenticated with the (Q)EAA Provider. + + +High-Level PID flow +------------------- + +The :numref:`fig_High-Level-Flow-ITWallet-PID-Issuance` shows a general architecture and highlights the main operations involved in the issuance of a PID. + +.. _fig_High-Level-Flow-ITWallet-PID-Issuance: +.. figure:: ../../images/High-Level-Flow-ITWallet-PID-Issuance.svg + :figwidth: 100% + :align: center + + PID Issuance - General architecture and high level flow. + +Below the description of the steps represented in the previous picture: + + 0. **Wallet Instance Setup**: the first time the Wallet Instance is started a preliminary setup phase is carried out. It consists of the release of the Wallet Attestation issued by Wallet Attestation Service asserting the genuineness and the compliance of the Wallet Instance with the shared trust framework. The Wallet Attestation binds the public key provided by the Wallet Instance, related to one of the private keys generated by the Wallet Instance. + 1. **PID/(Q)EAA Provider Discovery**: the Wallet Instance discovers the trusted Digital Credential Issuers using the Federation API (e.g.: using the Subordinate Listing Endpoint of the Trust Anchor and its Intermediates), inspecting the Credential Issuer metadata and Trust Marks for filtering the PID Provider. + 2. **PID Provider Metadata**: the Wallet Instance establishes the trust to the PID Provider according to the Trust Model and obtains the Metadata that discloses the formats of the PID, the algorithms supported, and any other parameter required for interoperability needs. + 3. **PID Request**: using the Authorization Code Flow defined in [`OpenID4VCI`_] the Wallet Instance requests the PID to the PID Provider. + 4. **User Authentication**: the PID Provider authenticates the User with LoA High, acting as an Identity and Access Management Proxy to the National eID system. + 5. **PID Issuance**: the User is authenticated with LoA High and the PID Provider releases a PID bound to the key material held by the requesting Wallet Instance. + +In the following sections the steps from 1 to 5 are further expanded into more technical details. + +High-Level (Q)EAA flow +---------------------- + +The :numref:`fig_High-Level-Flow-ITWallet-QEAA-Issuance` shows a general architecture and highlights the main operations involved in the issuance of a (Q)EAA, following the assumptions listed below: + + - the User has a valid PID stored in their own Wallet Instance; + - the (Q)EAA requires a high security implementation profile. + +.. _fig_High-Level-Flow-ITWallet-QEAA-Issuance: +.. figure:: ../../images/High-Level-Flow-ITWallet-QEAA-Issuance.svg + :figwidth: 70% + :align: center + + (Q)EAA Issuance - General architecture and high level flow + +Below the description of the most relevant operations involved in the (Q)EAA issuance: + + 1. **Discovery of the trusted (Q)EAA Provider**: the Wallet Instance obtains the list of the trusted (Q)EAA Provider using the Federation API (e.g.: using the Subordinate Listing Endpoint of the Trust Anchor and its Intermediates), then inspects the metadata and Trust Mark looking for the Digital Credential capabilities of each (Q)EAA Provider. + 2. **(Q)EAA Provider Metadata**: the Wallet Instance establishes the trust to the (Q)EAA Provider according to the Trust Model, obtaining the Metadata that discloses the formats of the (Q)EAA, the algorithms supported, and any other parameter required for interoperability needs. + 3. **(Q)EAA Request**: using the Authorization Code Flow , defined in [`OpenID4VCI`_], the Wallet Instance requests a (Q)EAA to the (Q)EAA Provider. + 4. **User Authentication**: the (Q)EAA Provider, acting as a Verifier (Relying Party), authenticates the User evaluating the presentation of the PID. + 5. **(Q)EAA Issuance**: the User is authenticated with a valid PID and the (Q)EAA Provider releases a (Q)EAA bound to the key material held by the requesting Wallet Instance. + + +Low-Level Issuance Flow +----------------------- + +The PID/(Q)EAA Issuance flow is based on [`OpenID4VCI`_] and the following main reference standards/specifications MUST be supported on top of `OpenID4VCI`_: + + * **The OAuth 2.0 Authorization Framework** [:rfc:`6749`], as recommended in Section 3 of [`OpenID4VCI`_]. + * **Pushed Authorization Requests** (PAR) [:rfc:`9126`], as recommended in Section 5 of [`OpenID4VCI`_]. + * **Proof Key for Code Exchange** (PKCE) [:rfc:`7636`], as recommended in Section 5 of [`OpenID4VCI`_]. + * **JWT Authorization Requests** (JAR) [:rfc:`9101`]. + * **JWT Authorization Response Modes** (JARM) [`OAUTH-V2-JARM-04`_]. + * **Rich Authorization Requests** (RAR) [:rfc:`9396`]. + * **OAuth 2.0 Attestation-Based Client Authentication** [`OAUTH-ATTESTATION-CLIENT-AUTH`_]. + * **OpenID Federation 1.0** [`OID-FED`_]. + +The PID/(Q)EAA Provider MUST use *OAuth 2.0 Authorization Server* based on :rfc:`6749` to authorize the User to obtain a Credential. PID/(Q)EAA Providers MUST support + + * **Authorization Code Flow**: The PID/(Q)EAA Provider requires User authentication and consent at the Authorization Endpoint before collecting User information to create and provide a Credential. + * **Wallet Initiated Flow**: The request from the Wallet Instance is sent to the PID/(Q)EAA Provider without any input from the latter. + * **Same-device Issuance flow**: The User receives the Credential on the same device that initiated the flow. + * **Immediate Issuance flow**: The PID/(Q)EAA Provider issues the Credential directly in response to the Credential Request. + * **Deferred Issuance flow**: The PID/(Q)EAA Provider may require time to issue the requested Digital Credential, due to the Authentic Sources data provisioning rules, and allows the Wallet to retrieve the requested Credential in the future. + + +.. _fig_Low-Level-Flow-ITWallet-PID-QEAA-Issuance: + +.. figure:: ../../images/Low-Level-Flow-ITWallet-PID-QEAA-Issuance.svg + :figwidth: 100% + :align: center + :target: https://www.plantuml.com/plantuml/svg/hPRVJoCt4CVV_LUCk8S6QIEggaz8Txe0wH7r12dan4kbbTcTP4TixAqzJYxzwsklazW9eLUa8WGRUtvy_PaPRpvRbeRTiXNIiLPk-On6YCwlKKMTL0ndtooQCv0Md13F-djS-Cc2NNghhj4Ap-33LreqVDKwFFIzCdgzTvU7Uq-oRP5Xehm4LM5linQeQl1PZZHC9pSNWp_EnwCHJ8rUKRsDISB_h67u2Tmbw6UMf62ZdO4RMX3B5guDrgYOP2iS3BtT-X8sQ8KmIZE2Ng61DNnukftCnk8-1k06eINBeEVzyymuorZ32H4swEr3UHd3Jrv4fTMSpB9tjDXYnQILZtJAMmZd9Nb5-kLGK46UwEJBxUpBmtXy9wuRh5vE1G2ou3djbVw6Vb7s6QMgTq28BIoHPIrPvdeXu00lsQ1aXEdlrsCllqRm6cXEQFeWJvFHSAgdMtlozjFH0ppWNmujm-1F1M3GTbfPB7dJOH5MgfPGSKbr_EI3bbKJwgqMU6AfzF8Q7OrDZ7mE_iEQk87xaUDcUDr778wO_MOwubkRGJ9iQtcBqcF90P_26zlnlw3TEbXQACdEuCva6-5OOi2_aYtLn1l8-0kA3Rad6Y72O4kWT8OAmEyT6RGbgVFOwg7NvIM4Ssj3V_TvKZaIUCZ2d0idUqzwjwEGBMTJ11y_XaOyW5cutG0v6vh69mZ6LPyXrb3rpzuT9pUZH_3EeS5gUAmQNABjELNXz8eJ8Mmj7gME_N_-tlHUyHifLBshWoTq32UL9BHh0Q6g_XzPkmUwVfTJcha5gj1E23UXKLzmy-PUPxIUvvC8SsrENWQiNr01ghhJf5Xa4plpEwdM0KaUU_1wOXT6Aix6MTVPsEwkXx1Yi2Q3LMoM_tra1KKcyGGvMrbLQ6tP7xc89uzoiu4fe2gLLXNk7yfycbvTW966_-sqjJvw43pOUlRcH_O9uPibgLBtfhhiov9w-qHjiXD6Rdd5KjoonZaf2W2B86CfkOXMhsUNBCYLf5O-jmWYqSrj4k9Ti9JhNu4MSQgtS-SRAIUSsAIhC9mfbDvPgCA5cfbRrWQpn1cpkop9djhjR3Q5wVtZ32vKlZyuabG0hb35TqiYFUf9nnOJfruJLr-_ZSK3BiYoNvLj2zpayeO6MybOWo0LgCNa_Wbyb7t-2uChlHMMtWDP5VAZfJhqP_lbvr_zDbnhnQXOfAinLVRkVfQg-uFIjYZhacc9FnYHZ8KhICmQXADlRGN8UGz5WLngf-BxqaS6ss4LB_dd3UmJzbLVDwY03IqMQE9-u1c-LlRNfM7RBynRlGQvaAGEB-pF_ezRjly0 + + PID/(Q)EAA Issuance - Detailed flow + + +**Steps 1-4 (Discovery):** The User, using the Wallet Instance, selects the PID/(Q)EAA Provider from those listed in the list of trustworthy entities. The Wallet Instance then processes the Metadata for the selected PID/(Q)EAA Provider as defined in the `Trust Model section `_ of this specification. + +.. note:: + + **Federation Check:** The Wallet Instance must verify whether the PID/(Q)EAA Provider is a member of the Federation, obtaining its protocol specific Metadata. A non-normative example of a response from the endpoint **.well-known/openid-federation** with the **Entity Configuration** and the **Metadata** of the PID/(Q)EAA Provider is represented within the section :ref:`Entity Configuration of PID/(Q)EAA Providers`. + +**Steps 5-6 (PAR Request)**: The Wallet Instance: + + * creates a fresh PKCE code verifier, Wallet Attestation Proof of Possession, and ``state`` parameter for the *Pushed Authorization Request*. + * provides to the PID/(Q)EAA Provider PAR endpoint the parameters previously listed above, using the ``request`` parameter (hereafter Request Object) according to :rfc:`9126` Section 3 to prevent Request URI swapping attack. + * MUST create the ``code_verifier`` with enough entropy random string using the unreserved characters with a minimum length of 43 characters and a maximum length of 128 characters, making it impractical for an attacker to guess its value. The value MUST be generated following the recommendation in Section 4.1 of :rfc:`7636`. + * signs this request using the private key that is created during the setup phase to obtain the Wallet Attestation. The related public key that is attested by the Wallet Provider is provided within the Wallet Attestation ``cnf`` claim. + * MUST use the ``OAuth-Client-Attestation`` and ``OAuth-Client-Attestation-PoP`` parameters according to OAuth 2.0 Attestation-based Client Authentication [`OAUTH-ATTESTATION-CLIENT-AUTH`_], since in this flow the Pushed Authorization Endpoint is a protected endpoint. + * specifies the types of the requested credentials using the ``authorization_details`` [RAR :rfc:`9396`] parameter and or scope parameter. + +The PID/(Q)EAA Provider performs the following checks upon the receipt of the PAR request: + + 1. It MUST validate the signature of the Request Object using the algorithm specified in the ``alg`` header parameter (:rfc:`9126`, :rfc:`9101`) and the public key retrieved from the Wallet Attestation (``cnf.jwk``) referenced in the Request Object, using the ``kid`` JWS header parameter. + 2. It MUST check that the used algorithm for signing the request in the ``alg`` header is one of the listed within the Section `Cryptographic Algorithms `_. + 3. It MUST check that the ``client_id`` in the request body of the PAR request matches the ``client_id`` claim included in the Request Object. + 4. It MUST check that the ``iss`` claim in the Request Object matches the ``client_id`` claim in the Request Object (:rfc:`9126`, :rfc:`9101`). + 5. It MUST check that the ``aud`` claim in the Request Object is equal to the identifier of the PID/(Q)EAA Provider (:rfc:`9126`, :rfc:`9101`). + 6. It MUST reject the PAR request, if it contains the ``request_uri`` parameter (:rfc:`9126`). + 7. It MUST check that the Request Object contains all the mandatory parameters which values are validated according to :ref:`Table of the HTTP parameters ` [derived from :rfc:`9126`]. + 8. It MUST check that the Request Object is not expired, checking the ``exp`` claim. + 9. It MUST check that the Request Object was issued in a previous time than the value exposed in the ``iat`` claim. It SHOULD reject the request if the ``iat`` claim is far from the current time (:rfc:`9126`) of more than `5` minutes. + 10. It MUST check that the ``jti`` claim in the Request Object has not been used before by the Wallet Instance identified by the ``client_id``. This allows the PID/(Q)EAA Provider to mitigate replay attacks (:rfc:`7519`). + 11. It MUST validate the ``OAuth-Client-Attestation-PoP`` parameter based on Section 4 of [`OAUTH-ATTESTATION-CLIENT-AUTH`_]. + +Below a non-normative example of the PAR. + +.. code-block:: + + POST /as/par HTTP/1.1 + Host: eaa-provider.example.org + Content-Type: application/x-www-form-urlencoded + OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IkVVRzBFdlRWaUk1RU5aQXdVQ0lVTWdQQVk4X1VISW5fMkhIWlMxN3RfQzAifQ.eyJpc3MiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCAiYXVkIjogImh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCAibmJmIjogMTMwMDgxNTc4MCwgImV4cCI6IDEzMDA4MTkzODB9._v3bjJelKI0TNpbc4ysS7yJupwSZzMPQ0ZQ9N5zj8XGQ_T3NN9bghUyVzegR60xokqBnqmMS4iYgPOL7ekEspw + OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiIgaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImp0aSI6IjVlZmY5YzFiLWVkMGQtNDdlOC1hNTUzLWY3NGRmMWJiZWVkZCIsImlhdCI6MTcyMjI0OTQ0NywiZXhwIjoxNzIyMjQ5NzQ3fQ.aZpx7u7R-W8q7fJh9BEaRf8LM7RQRxAVc-okalAVqxHWqUMh3ehYukMLaCsiDQ33pyS41Y5PEsZ3HXwAXQ3nMg + + &client_id=$thumprint-of-the-jwk-in-the-cnf-wallet-attestation$ + &request=$SIGNED-JWT + +Below an non-normative example of the Wallet Attestation Proof of Possession (WIA-PoP) header and body: + +.. literalinclude:: ../../examples/wa-pop-header.json + :language: JSON + +.. literalinclude:: ../../examples/wa-pop-payload.json + :language: JSON + + +Below an non-normative example of the signed Request Object without encoding and signature applied: + +.. literalinclude:: ../../examples/request-object-header.json + :language: JSON + +.. literalinclude:: ../../examples/request-object-payload.json + :language: JSON + + +.. note:: + + **Federation Check**: The PID/(Q)EAA Provider MUST check that the Wallet Provider is part of the federation. + + +.. note:: + The PID/(Q)EAA Provider MUST validate the signature of the the Wallet Attestation and that it is not expired. + + +**Step 7 (PAR Response)**: The PID/(Q)EAA Provider provides a one-time use ``request_uri`` value. The issued ``request_uri`` value must be bound to the client identifier (``client_id``) that was provided in the Request Object. + + +.. note:: + The entropy of the ``request_uri`` MUST be sufficiently large. The adequate shortness of the validity and the entropy of the ``request_uri`` depends on the risk calculation based on the value of the resource being protected. The validity time SHOULD be less than a minute, and the ``request_uri`` MUST include a cryptographic random value of 128 bits or more (:rfc:`9101`). The entire ``request_uri`` SHOULD NOT exceed 512 ASCII characters due to the following two main reasons (:rfc:`9101`): + + 1. Many phones on the market still do not accept large payloads. The restriction is typically either 512 or 1024 ASCII characters. + 2. On a slow connection such as a 2G mobile connection, a large URL would cause a slow response; therefore, the use of such is not advisable from the user-experience point of view. + +The PID/(Q)EAA Provider returns the issued ``request_uri`` to the Wallet Instance. A non-normative example of the response is shown below. + +.. code-block:: http + + HTTP/1.1 201 Created + Cache-Control: no-cache, no-store + Content-Type: application/json + +.. literalinclude:: ../../examples/par-response.json + :language: JSON + + +**Steps 8-9 (Authorization Request)**: The Wallet Instance sends an authorization request to the PID/(Q)EAA Provider Authorization Endpoint. Since parts of this Authorization Request content, e.g., the ``code_challenge`` parameter value, are unique to a particular Authorization Request, the Wallet Instance MUST only use a ``request_uri`` value once (:rfc:`9126`); The PID/(Q)EAA Provider performs the following checks upon the receipt of the Authorization Request: + + 1. It MUST treat ``request_uri`` values as one-time use and MUST reject an expired request. However, it MAY allow for duplicate requests due to a user reloading/refreshing their user-agent (derived from :rfc:`9126`). + 2. It MUST identify the request as a result of the submitted PAR (derived from :rfc:`9126`). + 3. It MUST reject all the Authorization Requests that do not contain the ``request_uri`` parameter as the PAR is the only way to pass the Authorization Request from the Wallet Instance (derived from :rfc:`9126`). + + +.. code-block:: http + + GET /authorize?client_id=$thumprint-of-the-jwk-in-the-cnf-wallet-attestation$&request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3Abwc4JK-ESC0w8acc191e-Y1LTC2 HTTP/1.1 + Host: eaa-provider.example.org + + +.. note:: + + **User Authentication and Consent**: The PID Provider performs the User authentication based on the requirements of eIDAS LoA High by means of national notified eIDAS scheme and requires the User consent for the PID issuance. + The (Q)EAA Provider performs the User authentication requesting a valid PID to the Wallet Instance. The (Q)EAA Provider MUST use [`OpenID4VP`_] to dynamically request the presentation of the PID. From a protocol perspective, the (Q)EAA Provider acts as a Relying Party, providing the presentation request to the Wallet Instance. The Wallet Instance MUST have a valid PID obtained prior to start the transaction with the (Q)EAA Provider. + + +**Steps 10-11 (Authorization Response)**: The PID/(Q)EAA Provider sends an authorization ``code`` together with ``state`` and ``iss`` parameters to the Wallet Instance. The Wallet Instance performs the following checks on the Authorization Response: + + 1. It MUST check the Authorization Response contains all the defined parameters according to :ref:`Table of the HTTP Response parameters `. + 2. It MUST check the returned value by the PID/(Q)EAA Provider for ``state`` parameter is equal to the value sent by Wallet Instance in the Request Object (:rfc:`6749`). + 3. It MUST check that the URL of PID/(Q)EAA Provider in ``iss`` parameter is equal to the URL identifier of intended PID/(Q)EAA Provider that the Wallet Instance start the communication with (:rfc:`9027`). + +.. note:: + + The Wallet Instance redirect URI is a universal or app link registered with the local operating system, so this latter will resolve it and pass the response to the Wallet Instance. + +.. code-block:: http + + HTTP/1.1 302 Found + Location: https://start.wallet.example.org?code=SplxlOBeZQQYbYS6WxSbIA&state=fyZiOL9Lf2CeKuNT2JzxiLRDink0uPcd&iss=https%3A%2F%2Feaa-provider.example.org + +**Steps 12-13 (DPoP Proof for Token Endpoint)**: The Wallet Instance MUST create a new key pair for the DPoP and a fresh DPoP Proof JWT following the instruction provided in the Section 4 of (:rfc:`9449`) for the token request to the PID/(Q)EAA Provider. The DPoP Proof JWT is signed using the private key for DPoP created by Wallet Instance for this scope. DPoP binds the Access Token to a certain Wallet Instance (:rfc:`9449`) and mitigates the misuse of leaked or stolen Access Tokens at the Credential Endpoint. + +**Step 14 (Token Request):** The Wallet Instance sends a token request to the PID/(Q)EAA Provider Token Endpoint with a *DPoP Proof JWT* and the parameters: ``code``, ``code_verifier``, and OAuth 2.0 Attestation based Client Authentication (``OAuth-Client-Attestation`` and ``OAuth-Client-Attestation-PoP``). +The ``OAuth-Client-Attestation`` is signed using the private key that is created during the setup phase to obtain the Wallet Attestation. The related public key that is attested by the Wallet Provider is provided within the Wallet Attestation (``cnf`` claim). The PID/(Q)EAA Provider performs the following checks on the Token Request: + + 1. It MUST ensure that the Authorization ``code`` is issued to the authenticated Wallet Instance (:rfc:`6749`) and was not replied. + 2. It MUST ensure the Authorization ``code`` is valid and has not been previously used (:rfc:`6749`). + 3. It MUST ensure the ``redirect_uri`` matches the value included in the previous Request Object (see Section 3.1.3.1. of [`OIDC`_]). + 4. It MUST validate the DPoP Proof JWT, according to (:rfc:`9449`) Section 4.3. + +.. code-block:: http + + POST /token HTTP/1.1 + Host: eaa-provider.example.org + Content-Type: application/x-www-form-urlencoded + DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik + OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IkVVRzBFdlRWaUk1RU5aQXdVQ0lVTWdQQVk4X1VISW5fMkhIWlMxN3RfQzAifQ.eyJpc3MiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCAiYXVkIjogImh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCAibmJmIjogMTMwMDgxNTc4MCwgImV4cCI6IDEzMDA4MTkzODB9._v3bjJelKI0TNpbc4ysS7yJupwSZzMPQ0ZQ9N5zj8XGQ_T3NN9bghUyVzegR60xokqBnqmMS4iYgPOL7ekEspw + OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiIgaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImp0aSI6IjVlZmY5YzFiLWVkMGQtNDdlOC1hNTUzLWY3NGRmMWJiZWVkZCIsImlhdCI6MTcyMjI0OTQ0NywiZXhwIjoxNzIyMjQ5NzQ3fQ.aZpx7u7R-W8q7fJh9BEaRf8LM7RQRxAVc-okalAVqxHWqUMh3ehYukMLaCsiDQ33pyS41Y5PEsZ3HXwAXQ3nMg + + grant_type=authorization_code + &code=SplxlOBeZQQYbYS6WxSbIA + &code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk + &redirect_uri=https://start.wallet.example.org/cb + +**Step 15 (Token Response)**: The PID/(Q)EAA Provider validates the request, if successful an *Access Token* (bound to the DPoP key) and a fresh `c_nonce` are provided by the Issuer to the Wallet Instance. The parameter `c_nonce` is a string value, which MUST be unpredictable and is used later by the Wallet Instance in Step 18 to create the proof of possession of the key (*proof* claim) and it is the primary countermeasure against key proof replay attack. Note that, the received `c_nonce` value can be used to create the proof as long as the Issuer provides the Wallet Instance with a new `c_nonce` value. + +.. code-block:: http + + HTTP/1.1 200 OK + Content-Type: application/json + Cache-Control: no-store + +.. literalinclude:: ../../examples/token-response.json + :language: JSON + +The non-normative example of the DPoP Access Token is given below. + +.. literalinclude:: ../../examples/at-dpop-header.json + :language: JSON + +.. literalinclude:: ../../examples/at-dpop-payload.json + :language: JSON + + +**Steps 16-17 (DPoP Proof for Credential Endpoint)**: The Wallet Instance for requesting the Digital Credential creates a proof of possession with ``c_nonce`` obtained in **Step 15** and using the private key used for the DPoP, signing a DPoP Proof JWT according to (:rfc:`9449`) Section 4. The ``jwk`` value in the ``proof`` parameter MUST be equal to the public key referenced in the DPoP. + +**Step 18 (Credential Request)**: The Wallet Instance sends a request for the Digital Credential to the PID/(Q)EAA Credential endpoint. This request MUST include the Access Token, DPoP Proof JWT, credential type, proof (which demonstrates possession of the key), and format parameters. The proof parameter MUST be an object that contains evidence of possession of the cryptographic key material to which the issued PID/(Q)EAA Digital Credential will be bound. To verify the proof, the PID/(Q)EAA Provider conducts the following checks at the Credential endpoint: + + 1. the JWT proof MUST include all required claims as specified in the table of Section :ref:`Token Request `; + 2. The key proof MUST be explicitly typed using header parameters as defined for the respective proof type; + 3. The header parameter alg MUST indicate a registered asymmetric digital signature algorithm, and MUST NOT be set to `none`; + 4. The signature on the key proof MUST be verified using the public key specified in the header parameter. + 5. The header parameter MUST NOT contain a private key. + 6. If a `c_nonce` value was previously provided by the server, the nonce claim in the JWT MUST match this `c_nonce` value. Furthermore, the creation time of the JWT, as indicated by the `iat` claim or a server-managed timestamp via the nonce claim, MUST be within an acceptable window of time as determined by the server. + + +.. note:: + + **PID/(Q)EAA Credential Schema and Status registration**: The PID/(Q)EAA Provider MUST register all the issued Credentials for their later revocation, if needed. + + +.. note:: + + It is RECOMMENDED that the public key contained in the ``jwt_proof`` be specifically generated for the requested Credential (fresh cryptographic key) to ensure that different issued Credentials do not share the same public key, thereby remaining unlinkable to each other. + + +A non-normative example of the Credential Request is provided below. + + +.. code-block:: http + + POST /credential HTTP/1.1 + Host: eaa-provider.example.org + Content-Type: application/json + Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU + DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik + VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR + nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R + 1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj + oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z + WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF + c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E + OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA + +.. literalinclude:: ../../examples/credential-request.json + :language: JSON + + + +Where a non-normative example of the decoded content of the ``jwt`` parameter is represented below, +without encoding and signature. The JWS header: + +.. literalinclude:: ../../examples/credential-jwt-proof-header.json + :language: JSON + +.. literalinclude:: ../../examples/credential-jwt-proof-payload.json + :language: JSON + +**Steps 19-21 (Credential Response)**: The PID/(Q)EAA Provider MUST validate the *DPoP JWT Proof* based on the steps defined in Section 4.3 of (:rfc:`9449`) and whether the *Access Token* is valid and suitable for the requested PID/(Q)EAA. It also MUST validate the proof of possession for the key material the new credential SHALL be bound to, according to `OpenID4VCI`_ Section 7.2.2. If all checks succeed, the PID/(Q)EAA Provider creates a new Credential bound to the key material and provide it to the Wallet Instance. The Wallet Instance MUST perform the following checks before proceeding with the secure storage of the PID/(Q)EAA: + + 1. It MUST check that the PID Credential Response contains all the mandatory parameters and values are validated according to :ref:`Table of the credential response parameters `. + 2. It MUST check the PID integrity by verifying the signature using the algorithm specified in the ``alg`` header parameter of SD-JWT (:ref:`PID/(Q)EAA Data Model `) and the public key that is identified using using the ``kid`` header of the SD-JWT. + 3. It MUST check that the received PID (in credential claim) matches the schema defined in :ref:`PID/(Q)EAA Data Model `. + 4. It MUST process and verify the PID in SD-JWT VC format (according to `SD-JWT`_ Section 6.) or MDOC CBOR format. + 5. It MUST verify the Trust Chain in the header of SD-JWT VC to verify that the PID Provider is trusted. + +If the checks defined above are successful the Wallet Instance proceeds with the secure storage of the PID/(Q)EAA. + +.. code-block:: http + + HTTP/1.1 200 OK + Content-Type: application/json + Cache-Control: no-store + Pragma: no-cache + +.. literalinclude:: ../../examples/credential-response.json + :language: JSON + +.. note:: + + If the issuance of the requested Credential cannot be issued immediately and it requires more time to be issued, then the PID/(Q)EAA Provider MAY support the *Deferred Flow* (step 24) as specified in Section :ref:`Deferred Flow`. + +**Steps 22 (Notification Request)**: According to Section 10.1 of [`OpenID4VCI`_], the Wallet sends an HTTP POST request to the Notification Endpoint using the *application/json* media type as in the following non-normative example. + +.. code-block:: http + + POST /notification HTTP/1.1 + Host: eaa-provider.example.org + Content-Type: application/json + Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU + DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik + VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR + nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R + 1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj + oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z + WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF + c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E + OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA +.. literalinclude:: ../../examples/notification-request.json + :language: JSON + + +**Steps 23 (Notification Response)**: When the Credential Issuer has successfully received the Notification Request from the Wallet, it MUST respond with an HTTP status code *204* as recommended in Section 10.2 of [`OpenID4VCI`_]. Below is a non-normative example of response to a successful Notification Request: + +.. code-block:: http + + HTTP/1.1 204 No Content + + + +Deferred Flow +------------- + +The PID/(Q)EAA Providers MAY support a *Deferred Flow* which has the aim of handling the cases where an immediate issuance is not possible for some reasons due to errors during the communication between the PID/(Q)EAA Provider and the Authentic Source (for example the Authentic Source is temporarily unavailable, etc.) or due to administrative or technical processes that do not allow the Credential to be provided immediately. + + +General Requirements +^^^^^^^^^^^^^^^^^^^^ + + 1. The Deferred Credential request MAY also happen several days after the initial Credential request. + 2. The User MUST be informed that the Credential is available and ready to be issued. + 3. The Wallet Provider MUST NOT be informed about which Credential is available to be issued or which Credential Provider the User needs to contact. + 4. The Wallet Instance MUST be informed about the amount of time to wait before making a new Credential request. + 5. As, in general, an unavailability may be an unexpected event, the PID/(Q)EAA Provider MUST be able to switch on the fly between a *immediate* and an *deferred* flow. This decision MUST be taken after the authorization step. + +Technical Flow +^^^^^^^^^^^^^^ + +If PID/(Q)EAA Providers, supporting this flow, are not able to immediately issue a requested Credential, they MUST provide the Wallet Instance with an HTTP Credential Response cointaining the amount of time to wait before making a new Credential request. The HTTP status code MUST be *202* (see Section 15.3.3 of [:rfc:`9110`]). Below a non-normative example is given. + +.. code-block:: http + + HTTP/1.1 202 Accepted + Content-Type: application/json + Cache-Control: no-store + +.. literalinclude:: ../../examples/credential-response-deferred.json + :language: JSON + +The Wallet Instance MUST use the value given in the *lead_time* parameter to inform the User when the Credential becomes available (e.g. using a local notification triggered by the *lead_time* time value). PID/(Q)EAA Providers MAY send a notification to the User through a communication channel (e.g. email address), if available from the PID/(Q)EAA Provider. + +Upon receipt of the notification (by the Wallet Instance and/or by the PID/(Q)EAA Provider), the User opens the Wallet Instance and start the Issuance Flow again from the beginning as defined in the previous section. + +If the *lead_time* parameter is less than the expiration time of the Access Token, the Wallet Instance MAY use it along with the *c_nonce* provided in the Credential Response to perform a new Credential Request without requiring the User to submit a new authentication request. + +In the case where the Authentic Source and the PID/(Q)EAA Provider are both enabled to use *PDND*, what is described in Section :ref:`Authentic Sources` MUST apply. + +Pushed Authorization Request Endpoint +------------------------------------- + +Pushed Authorization Request (PAR) Request +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The request to the PID/(Q)EAA authorization endpoint MUST use HTTP Headers parameters and HTTP POST parameters. + +The HTTP POST method MUST use the parameters in the message body encoded in ``application/x-www-form-urlencoded`` format. + +.. _table_http_request_claim: +.. list-table:: PAR http request parameters + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **client_id** + - MUST be set to the thumbprint of the ``jwk`` value in the ``cnf`` parameter inside the Wallet Attestation. + - :rfc:`6749` + * - **request** + - It MUST be a signed JWT. The private key corresponding to the public one in the ``cnf`` parameter inside the Wallet Attestation MUST be used for signing the Request Object. + - `OpenID Connect Core. Section 6 `_ + +The Pushed Authorization Endpoint is protected with OAuth 2.0 Attestation-based Client Authentication [`OAUTH-ATTESTATION-CLIENT-AUTH`_], therefore +the request to the PID/(Q)EAA authorization endpoint MUST use the following HTTP Headers parameters: + + +.. _table_http_request_headers_claim: +.. list-table:: http request header parameters + :widths: 20 60 20 + :header-rows: 1 + + * - **OAuth-Client-Attestation** + - It MUST be set to a value containing the Wallet Attestation JWT. + - `OAUTH-ATTESTATION-CLIENT-AUTH`_. + * - **OAuth-Client-Attestation-PoP** + - It MUST be set to a value containing the Wallet Attestation JWT Proof of Possession. + - `OAUTH-ATTESTATION-CLIENT-AUTH`_. + + +The JWT *Request Object* has the following JOSE header parameters: + +.. _table_request_object_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **JOSE header** + - **Description** + - **Reference** + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section `Cryptographic Algorithms `_ and MUST NOT be set to ``none`` or any symmetric algorithm (MAC) identifier. + - :rfc:`7516#section-4.1.1`. + * - **kid** + - Unique identifier of the ``jwk`` inside the ``cnf`` claim of Wallet Attestation as base64url-encoded JWK Thumbprint value. + - :rfc:`7638#section_3`. + +.. note:: + The parameter **typ**, if omitted, assumes the implicit value **JWT**. + + +The ``request`` JWT payload contained in the HTTP POST message is given with the following parameters: + +.. _table_jwt_request: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **iss** + - It MUST be set to the ``client_id``. + - :rfc:`9126` and :rfc:`7519`. + * - **aud** + - It MUST be set to the identifier of the PID/(Q)EAA Provider. + - :rfc:`9126` and :rfc:`7519`. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT. The claim value MUST be not greater than 300 seconds from the issuance time. + - :rfc:`9126` and :rfc:`7519`. + * - **iat** + - UNIX Timestamp with the time of JWT issuance. + - :rfc:`9126` and :rfc:`7519`. + * - **response_type** + - MUST be set to ``code``. + - :rfc:`6749` + * - **response_mode** + - It MUST be a string indicating the "*response_mode*", as specified in [`OAUTH-MULT-RESP-TYPE`_]. It MUST be one of the supported values (*response_modes_supported*) provided in the metadata of the PID/(Q)EAA Provider. It informs the PID/(Q)EAA Provider of the mechanism to be used for returning parameters from the Authorization Endpoint. In case of *HTTP 302 Redirect Response* the value MUST be *query*. In this mode, Authorization Response parameters are encoded in the query string added to the ``redirect_uri`` when redirecting back to the Wallet Instance. In case of *HTTP POST Response* the value MUST be *form_post.jwt* according to [`OAUTH-V2-JARM-04`_]. In this mode, Authorization Response parameters are specified into a JWT encoded as HTML form value that is auto-submitted in the user-agent, and thus is transmitted via the HTTP POST method to the Wallet Instance, with the result parameters being encoded in the body using the *application/x-www-form-urlencoded* format. The action attribute of the form MUST be the Redirection URI of the Wallet Instance. The method of the form attribute MUST be POST. + - See [`OAUTH-MULT-RESP-TYPE`_] and [`OAUTH-V2-JARM-04`_]. + * - **client_id** + - It MUST be set as in the :ref:`Table of the HTTP parameters `. + - See :ref:`Table of the HTTP parameters `. + * - **state** + - Unique session identifier at the client side. This value will be returned to the client in the response, at the end of the authentication. It MUST be a random string composed by alphanumeric characters and with a minimum length of 32 digits. Special characters MUST be considered non-alphanumeric characters as defined in `[NIST] `__. + - See [`OIDC`_] Section 3.1.2.1. + * - **code_challenge** + - A challenge derived from the **code verifier** that is sent in the authorization request. + - :rfc:`7636#section-4.2`. + * - **code_challenge_method** + - A method that was used to derive **code challenge**. It MUST be set to ``S256``. + - :rfc:`7636#section-4.3`. + * - **scope** + - JSON String. String specifying a unique identifier of the Credential being described in the `credential_configurations_supported` map in the Credential Issuer Metadata. For example, in the case of the PID, it MUST be set to ``PersonIdentificationData``. It MAY be multivalued, each value MUST be separated by a space. + - :rfc:`6749` + * - **authorization_details** + - Array of JSON Objects. Each JSON Object MUST include the following claims: + + - **type**: it MUST be set to ``openid_credential``, + - **credential_configuration_id**: JSON String. String specifying a unique identifier of the Credential being described in the `credential_configurations_supported` map in the Credential Issuer Metadata. For example, in the case of the PID, it MUST be set to ``PersonIdentificationData``. + - See [RAR :rfc:`9396`] and [`OpenID4VCI`_]. + * - **redirect_uri** + - Redirection URI to which the response is intended to be sent. It MUST be an universal or app link registered with the local operating system, so this latter will provide the response to the Wallet Instance. + - See [`OIDC`_] Section 3.1.2.1. + * - **jti** + - Unique identifier of the JWT that, together with the value contained in the ``iss`` claim, prevents the reuse of the JWT (replay attack). Since the `jti` value alone is not collision resistant, it MUST be identified uniquely together with its issuer. + - [:rfc:`7519`]. + +.. note:: + + If the request cointains scope value and the *authorization_details* parameter the Credential Issuer MUST interpret these individually. However, if both request the same Credential type, then the Credential Issuer MUST follow the request as given by the authorization details object. + +The JOSE header of the Wallet Attestation proof of possession, contained in the HTTP Request headers, MUST contain: + +.. _table_jwt_pop: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **JOSE header** + - **Description** + - **Reference** + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section `Cryptographic Algorithms `_ and MUST NOT be set to ``none`` or any symmetric algorithm (MAC) identifier. + - :rfc:`7516#section-4.1.1`. + +The body of the Wallet Attestation proof of possession JWT, contained in the HTTP Request headers, MUST contain: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **iss** + - Thumbprint of the JWK in the ``cnf`` parameter. + - :rfc:`9126` and :rfc:`7519`. + * - **aud** + - It MUST be set to the identifier of the PID/(Q)EAA Provider. + - :rfc:`9126` and :rfc:`7519`. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT. + - :rfc:`9126` and :rfc:`7519`. + * - **iat** + - UNIX Timestamp with the time of JWT issuance. + - :rfc:`9126` and :rfc:`7519`. + * - **jti** + - Unique identifier for the DPoP proof JWT. The value SHOULD be set using a *UUID v4* value according to [:rfc:`4122`]. + - [:rfc:`7519`. Section 4.1.7]. + +.. _sec_par: + +Pushed Authorization Request (PAR) Response +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If the verification is successful, the PID/(Q)EAA Issuer MUST provide the response with a *201 HTTP status code*. The following parameters are included as top-level members in the HTTP response message body, using the ``application/json`` media type as defined in [:rfc:`8259`]. + +.. _table_http_response_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **request_uri** + - The request URI corresponding to the authorization request posted. This URI MUST be a single-use reference to the respective authorization request. It MUST contain some part generated using a cryptographically strong pseudorandom algorithm. The value format MUST be ``urn:ietf:params:oauth:request_uri:`` with ```` as the random part of the URI that references the respective authorization request data. + - [:rfc:`9126`]. + * - **expires_in** + - A JSON number that represents the lifetime of the request URI in seconds as a positive integer. + - [:rfc:`9126`]. + +If any errors occur during the PAR Request, the Authorization Server MUST return an error response as defined in :rfc:`9126#section-2.3`. The response MUST use *application/json* as the content type and MUST include the following parameters: + + - *error*. The error code. + - *error_description*. Text in human-readable form providing further details to clarify the nature of the error encountered. + +Below is a non-normative example of an error response. + +.. code:: http + + HTTP/1.1 400 Bad Request + Content-Type: application/json + +.. literalinclude:: ../../examples/par-error.json + :language: JSON + + + +Authorization endpoint +---------------------- + +The authorization endpoint is used to interact with the PID/(Q)EAA Issuer and obtain an authorization grant. +The authorization server MUST first verify the identity of the User that own the credential. + + +Authorization Request +^^^^^^^^^^^^^^^^^^^^^^^ + +The Authorization request is issued by the Web Browser in use by the Wallet Instance, the HTTP methods **POST** or **GET** are used. When the method **POST** is used, the parameters MUST be sent using the *Form Serialization*. When the method **GET** is used, the parameters MUST be sent using the *Query String Serialization*. For more details see Section 13 of [`OIDC`_]. + +The mandatory parameters in the HTTP authentication request are specified in the following table. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **client_id** + - It MUST be set as in the :ref:`Table of the HTTP parameters `. + - See :ref:`Table of the HTTP parameters `. + * - **request_uri** + - It MUST be set to the same value as obtained by PAR Response. See :ref:`Table of the HTTP PAR Response parameters `. + - [:rfc:`9126`]. + + +.. note:: + + In the case of PID issuance, the Wallet Instance MAY include the **idphinting** parameter as a URL encoded string. This parameter specifies the Identity Provider where the User wishes to authenticate.. See `AARC-G061 - A specification for IdP hinting. `_ for more details. + +Authorization Response +^^^^^^^^^^^^^^^^^^^^^^^ + +The authentication response is returned by the PID/(Q)EAA authorization endpoint at the end of the authentication flow. + +If the authentication is successful the PID/(Q)EAA Issuer redirects the User by adding the following query parameters as required to the *redirect_uri*. The redirect URI MUST be an universal or app link registered with the local operating system, so this latter is able to provide the response to the Wallet Instance. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **code** + - Unique *Authorization Code* that the Wallet Instance submits to the Token Endpoint. + - [:rfc:`6749#section-4.1.2`], [:rfc:`7521`]. + * - **state** + - The Wallet Instance MUST check the correspondence with the ``state`` parameter value in the Request Object. It is defined as in the :ref:`Table of the JWT Request parameters `. + - [:rfc:`6749#section-4.1.2`]. + * - **iss** + - Unique identifier of the PID/(Q)EAA Issuer who created the Authentication Response. The Wallet Instance MUST validate this parameter. + - [:rfc:`9207`], [:rfc:`7519`, Section 4.1.1.]. + +If any errors occur during the Authorization Request, the Authorization Server MUST return an error response as defined in :rfc:`6749#section-4.1.2.1`. The response MUST use *application/json* as the content type and MUST include the following parameters: + + - *error*. The error code. + - *error_description*. Text in human-readable form providing further details to clarify the nature of the error encountered. + +Token endpoint +-------------- + +The token endpoint is used by the Wallet Instance to obtain an Access Token by presenting an authorization grant, as +defined in :rfc:`6749`. The Token Endpoint is a protected endpoint with a client authentication based on the model defined in OAuth 2.0 Attestation-based Client Authentication [`OAUTH-ATTESTATION-CLIENT-AUTH`_ ]. + +.. _sec_token_request: + +Token Request +^^^^^^^^^^^^^^^ + +The request to the PID/(Q)EAA Token endpoint MUST be an HTTP request with method POST, with the body message encoded in ``application/x-www-form-urlencoded`` format. The Wallet Instance sends the Token endpoint request with ``OAuth-Client-Attestation`` and ``OAuth-Client-Attestation-PoP`` as header parameters according to `OAUTH-ATTESTATION-CLIENT-AUTH`_. + +The Token endpoint is protected with OAuth 2.0 Attestation-based Client Authentication [`OAUTH-ATTESTATION-CLIENT-AUTH`_], therefore +the request to the PID/(Q)EAA authorization endpoint MUST use the following HTTP Headers parameters **OAuth-Client-Attestation** as **OAuth-Client-Attestation-PoP** +as defined in the "Pushed Authorization Request (PAR) Endpoint". + +The Token endpoint issues DPoP tokens, therefore it is REQUIRED that the request incluides in its HTTP header the DPoP proof parameter. +The Token endpoint MUST validate the DPoP proof according to Section 4.3 of the DPoP specifications (:rfc:`9449`). This mitigates the misuse of leaked or stolen Access Tokens at the credential endpoint. If the DPoP proof is invalid, the Token endpoint returns an error response, according to Section 5.2 of [:rfc:`6749`] with ``invalid_dpop_proof`` as the value of the error parameter. + +All the parameters listed below are REQUIRED: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **grant_type** + - It MUST be set to ``authorization_code``. + - [:rfc:`7521`]. + * - **code** + - Authorization code returned in the Authentication Response. + - [:rfc:`7521`]. + * - **redirect_uri** + - It MUST be set as in the Request Object :ref:`Table of the JWT Request parameters `. + - [:rfc:`7521`]. + * - **code_verifier** + - Verification code of the **code_challenge**. + - `Proof Key for Code Exchange by OAuth Public Clients `_. + + +A **DPoP Proof JWT** is included in the HTTP request using the ``DPoP`` header parameter containing a DPoP JWS. + +The JOSE header of a **DPoP JWT** MUST contain at least the following parameters: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **JOSE header** + - **Description** + - **Reference** + * - **typ** + - It MUST be equal to ``dpop+jwt``. + - [:rfc:`7515`] and [:rfc:`8725`. Section 3.11]. + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section :ref:`Cryptographic Algorithms ` and MUST NOT be set to ``none`` or with a symmetric algorithm (MAC) identifier. + - [:rfc:`7515`]. + * - **jwk** + - It represents the public key chosen by the Wallet Instance, in JSON Web Key (JWK) [:rfc:`7517`] format that the Access Token MUST be bound to, as defined in [:rfc:`7515`] Section 4.1.3. It MUST NOT contain a private key. + - [:rfc:`7517`] and [:rfc:`7515`]. + + +The payload of a **DPoP JWT Proof** MUST contain the following claims: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **jti** + - Unique identifier for the DPoP proof JWT. The value SHOULD be set using a *UUID v4* value according to [:rfc:`4122`]. + - [:rfc:`7519`. Section 4.1.7]. + * - **htm** + - The value of the HTTP method of the request to which the JWT is attached. + - [:rfc:`9110`. Section 9.1]. + * - **htu** + - The HTTP target URI, without query and fragment parts, of the request to which the JWT is attached. + - [:rfc:`9110`. Section 7.1]. + * - **iat** + - UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in :rfc:`7519`. + - [:rfc:`7519`. Section 4.1.6]. + + +Token Response +^^^^^^^^^^^^^^^ + +If the Token Request is successfully validated, the Authorization Server provides an HTTP Token Response with a *200 (OK)* status code. The Token Response MUST contain the following mandatory claims. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **access_token** + - The *DPoP-bound Access Token*, in signed JWT format, allows accessing the PID/(Q)EAA Credential Endpoint for obtaining the credential. + - :rfc:`6749`. + * - **token_type** + - Type of *Access Token* returned. It MUST be equal to ``DPoP``. + - :rfc:`6749`. + * - **expires_in** + - Expiry time of the *Access Token* in seconds. + - :rfc:`6749`. + * - **c_nonce** + - JSON string containing a ``nonce`` value to be used to create a *proof of possession* of key material when requesting a Credential. + - [`OpenID4VCI`_]. + * - **c_nonce_expires_in** + - JSON integer, it represents the lifetime in seconds of the **c_nonce**. + - [`OpenID4VCI`_]. + * - **authorization_details** + - Array of JSON Objects, used to identify Credentials with the same metadata but different claimset/claim values and/or simplify the Credential request even when only one Credential is being issued. + - [`OpenID4VCI`_]. + +If any errors occur during the validation of the Token Request, the Authorization Server MUST return an error response as defined in :rfc:`6749#section-5.2`. + +.. code:: http + + HTTP/1.1 400 Bad Request + Content-Type: application/json;charset=UTF-8 + Cache-Control: no-store + Pragma: no-cache + +.. literalinclude:: ../../examples/token-error.json + :language: JSON + + +Access Token +^^^^^^^^^^^^ + +A DPoP-bound Access Token is provided by the PID/(Q)EAA Token endpoint as a result of a successful token request. The Access Token is encoded in JWT format, according to [:rfc:`7519`]. The Access Token MUST have at least the following mandatory claims and it MUST be bound to the public key that is provided by the DPoP proof. This binding can be accomplished based on the methodology defined in Section 6 of (:rfc:`9449`). + +The JOSE header of a **DPoP JWT** MUST contain the following claims. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **JOSE header** + - **Description** + - **Reference** + * - **typ** + - It MUST be equal to ``at+jwt``. + - [:rfc:`7515`]. + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section :ref:`Cryptographic Algorithms ` and MUST NOT be set to ``none`` or with a symmetric algorithm (MAC) identifier. + - [:rfc:`7515`]. + * - **kid** + - Unique identifier of the ``jwk`` used by the PID/(Q)EAA Provider to sign the Access Token. + - :rfc:`7638#section_3`. + + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **iss** + - It MUST be an HTTPS URL that uniquely identifies the PID/(Q)EAA Issuer. The Wallet Instance MUST verify that this value matches the PID/(Q)EAA Issuer where it has requested the credential. + - [:rfc:`9068`], [:rfc:`7519`]. + * - **sub** + - It identifies the subject of the JWT. It MUST be set to the value of the ``sub`` field in the PID/(Q)EAA SD-JWT-VC. + - [:rfc:`9068`], [:rfc:`7519`] and Section 8 of [`OIDC`_]. + * - **client_id** + - The identifier for the Wallet Instance that requested the Access Token; it MUST be equal to the to kid of the public key of the Wallet Instance specified into the Wallet Attestation (``cnf.jwk``). + - [:rfc:`9068`], [:rfc:`7519`] and Section 8 of [`OIDC`_]. + * - **aud** + - It MUST be set to the identifier of the PID/(Q)EAA Provider. + - [:rfc:`9068`]. + * - **iat** + - UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in :rfc:`7519`. + - [:rfc:`9068`], [:rfc:`7519`. Section 4.1.6]. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated in :rfc:`7519`. + - [:rfc:`9068`], [:rfc:`7519`]. + * - **jti** + - It MUST be a String in *uuid4* format. Unique Token ID identifier that the RP SHOULD use to prevent reuse by rejecting the Token ID if already processed. + - [:rfc:`9068`], [:rfc:`7519`]. + * - **cnf** + - It MUST contain a **jkt** claim being JWK SHA-256 Thumbprint Confirmation Method. The value of the *jkt* member MUST be the base64url encoding (as defined in [:rfc:`7515`]) of the JWK SHA-256 Thumbprint of the DPoP public key (in JWK format) to which the Access Token is bound. + - [:rfc:`9449`. Section 6.1] and [:rfc:`7638`]. + + +Credential endpoint +------------------- + +The Credential Endpoint issues a Credential upon the presentation of a valid Access Token, as defined in `OpenID4VCI`_. + + +Credential Request +^^^^^^^^^^^^^^^^^^^ + +The Wallet Instance when requests the PID/(Q)EAA to the PID/(Q)EAA Credential endpoint, MUST use the following parameters in the message body of the HTTP POST request, using the `application/json` media type. + +The Credential endpoint MUST accept and validate the *DPoP proof* sent in the DPoP HTTP Header parameter, according to the steps defined in (:rfc:`9449`) Section 4.3. The *DPoP proof* in addition to the values that are defined in the Token Endpoint section MUST contain the following claim: + + - **ath**: hash value of the Access Token encoded in ASCII. The value MUST use the base64url encoding (as defined in Section 2 of :rfc:`7515`) with the SHA-256 algorithm. + +If the *DPoP proof* is invalid, the Credential endpoint returns an error response per Section 5.2 of [:rfc:`6749`] with `invalid_dpop_proof` as the value of the error parameter. + +.. warning:: + The Wallet Instance MUST create a **new DPoP proof** for the Credential request and MUST NOT use the previously created proof for the Token Endpoint. + + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **format** + - Format of the Credential to be issued. This MUST be ``vc+sd-jwt`` or ``mso_mdoc``. + - [`OpenID4VCI`_]. + * - **vct** + - CONDITIONAL. REQUIRED only if the *format* identifier is ``vc+sd-jwt``. + - See Annex A3.4. of [`OpenID4VCI`_] + * - **doctype** + - CONDITIONAL. REQUIRED only if the *format* identifier is ``mso_mdoc``. + - See Annex A2.4. of [`OpenID4VCI`_] + * - **proof** + - JSON object containing proof of possession of the key material the issued credential shall be bound to. The proof object MUST contain the following mandatory claims: + + - **proof_type**: JSON string denoting the proof type. It MUST be `jwt`. + - **jwt**: the JWT used as proof of possession. + - [`OpenID4VCI`_]. + + +The JWT proof type MUST contain the following parameters for the JOSE header and the JWT body: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **JOSE Header** + - **Description** + - **Reference** + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section :ref:`Cryptographic Algorithms ` and MUST NOT be set to ``none`` or to a symmetric algorithm (MAC) identifier. + - [`OpenID4VCI`_], [:rfc:`7515`], [:rfc:`7517`]. + * - **typ** + - It MUST be set to `openid4vci-proof+jwt`. + - [`OpenID4VCI`_], [:rfc:`7515`], [:rfc:`7517`]. + * - **jwk** + - Representing the public key chosen by the Wallet Instance, in JSON Web Key (JWK) [:rfc:`7517`] format that the PID/(Q)EAA shall be bound to, as defined in Section 4.1.3 of [:rfc:`7515`]. + - [`OpenID4VCI`_], [:rfc:`7515`], [:rfc:`7517`]. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **iss** + - The value of this claim MUST be the **client_id** of the Wallet Instance. + - [`OpenID4VCI`_], [:rfc:`7519`, Section 4.1.1]. + * - **aud** + - It MUST be set to the identifier of the PID/(Q)EAA Provider. + - [`OpenID4VCI`_]. + * - **iat** + - UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in :rfc:`7519`. + - [`OpenID4VCI`_], [:rfc:`7519`. Section 4.1.6]. + * - **nonce** + - The value type of this claim MUST be a string, where the value is a **c_nonce** provided by the PID/(Q)EAA Issuer in the Token response. + - [`OpenID4VCI`_]. + + +Credential Response +^^^^^^^^^^^^^^^^^^^^ + +Credential Response to the Wallet Instance MUST be sent using `application/json` media type. If the Credential Request is successfully validated, and the Credential is immediately available, the PID/(Q)EAA Provider MUST return HTTP response with a *200 (OK)* status code. If the Credential is not available and the deferred flow is supported by the PID/(Q)EAA Provider, an HTTP status code *202* MUST be returned. + +The Credential Response contains the following parameters: + +.. _table_credential_response_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **credential** + - CONDITIONAL. REQUIRED if ``lead_time`` is not present. String Containing the issued PID/(Q)EAA. If the requested format identifier is ``vc+sd-jwt`` then the ``credential`` parameter MUST NOT be re-encoded. If the requested format identifier is ``mso_mdoc`` then the ``credential`` parameter MUST be a base64url-encoded representation of the issued Credential. + - Section 7.3, Annex A2.5 and Annex A3.5 of [`OpenID4VCI`_]. + * - **lead_time** + - CONDITIONAL. REQUIRED if ``credential`` is not present. The amount of time (in seconds) required before making a new Credential Request. + - This Specification + * - **c_nonce** + - REQUIRED. JSON string containing a ``nonce`` value to be used to create a *proof of possession* of the key material when requesting a further Credential or for the renewal of a Credential. + - Section 7.3 of [`OpenID4VCI`_]. + * - **c_nonce_expires_in** + - REQUIRED. JSON integer corresponding to the ``c_nonce`` lifetime in seconds. + - Section 7.3 of [`OpenID4VCI`_]. + * - **notification_id** + - OPTIONAL. String identifying an issued Credential that the Wallet includes in the Notification Request as defined in Section :ref:`Notification Request`. It MUST NOT be present if the ``credential`` parameter is not present + - Section 7.3 of [`OpenID4VCI`_]. + + +If the Credential Request is invalid, the PID/(Q)EAA Provider MUST return an error response as defined in Section 7.3.1 of [`OpenID4VCI`_]. The response MUST use the content type *application/json* and MUST include the following parameters: + + - *error*. The error code. + - *error_description*. Text in human-readable form providing further details to clarify the nature of the error encountered. + +.. code:: http + + HTTP/1.1 400 Bad Request + Content-Type: application/json + Cache-Control: no-store + +.. literalinclude:: ../../examples/credential-error.json + :language: JSON + +Notification endpoint +--------------------- + +The Notification Endpoint is used by the Wallet to notify the PID/(Q)EAA Provider of certain events for issued Credentials, such as if the Credential was successfully stored in the Wallet Instance or in case of unsuccessful Credential issuance caused by a User action. + +This endpoint MUST be protected using a DPoP Access Token. TLS for the confidentiality of the HTTP transport is REQUIRED according to Section 10 of [`OpenID4VCI`_]. + + +Notification Request +^^^^^^^^^^^^^^^^^^^^ + +The Notification Request MUST be an HTTP POST using the *application/json* media type with the following parameters. + +.. list-table:: + :widths: 20 60 25 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **notification_id** + - REQUIRED. It MUST be equal to the ``notification_id`` value returned in the Credential Response by the PID/(Q)EAA Provider. + - Section 10.1 of [`OpenID4VCI`_]. + * - **event** + - REQUIRED. Type of the notification event. It MUST be a case sensitive string and it MUST support the following values: + + - *credential_accepted*: when the Credential was successfully stored in the Wallet Instance. + - *credential_deleted*: when the unsuccessful Credential issuance was caused by a user action. + - *credential_failure*: in all other unsuccessful cases. + + - Section 10.1 of [`OpenID4VCI`_]. + * - **event_description** + - OPTIONAL. Human-readable ASCII [USASCII] text providing additional information, used to inform about the event that occurred. Values for the event_description parameter MUST NOT include characters outside the set *%x20-21 / %x23-5B / %x5D-7E*. + - Section 10.1 of [`OpenID4VCI`_]. + + + +Notification Response +^^^^^^^^^^^^^^^^^^^^^ + +The Notification Response MUST be use an HTTP status code *204 (No Content)*, as recommended in Section 10.2 of [`OpenID4VCI`_]. + +In case of errors, what is described in Section 10.3 of [`OpenID4VCI`_] MUST apply. + diff --git a/refs/pull/443/merge/en/_sources/proximity-flow.rst.txt b/refs/pull/443/merge/en/_sources/proximity-flow.rst.txt new file mode 100644 index 000000000..4b2246754 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/proximity-flow.rst.txt @@ -0,0 +1,412 @@ + + +.. _proximity_flow_sec: + +Proximity Flow +============== + +This section describes how a Verifier requests the presentation of an *mDoc-CBOR* Credential to a Wallet Instance according to the *ISO 18013-5 Specification*. Only *Supervised Device Retrieval flow* is supported in this technical implementation profile. + +The presentation phase is divided into three sub-phases: + + 1. **Device Engagement**: This subphase begins when the User is prompted to disclose certain attributes from the mDoc(s). The objective of this subphase is to establish a secure communication channel between the Wallet Instance and the Verifier App, so that the mDoc requests and responses can be exchanged during the communication subphase. + The messages exchanged in this subphase are transmitted through short-range technologies to limit the possibility of interception and eavesdropping. + This technical implementation profile exclusively supports QR code for Device Engagement. + + 2. **Session establishment**: During the session establishment phase, the Verifier App sets up a secure connection. All data transmitted over this connection is encrypted using a session key, which is known to both the Wallet Instance and the Verifier at this stage. + The established session MAY be terminated based on the conditions as detailed in [ISO18013-5#9.1.1.4]. + + 3. **Communication - Device Retrieval**: The Verifier App encrypts the mDoc request with the appropriate session key and sends it to the Wallet Instance together with its public key in a session establishment message. The mDoc uses the data from the session establishment message to derive the session key and decrypt the mDoc request. + During the communication subphase, the Verifier App has the option to request information from the Wallet using mDoc requests and responses. The primary mode of communication is the secure channel established during the session setup. The Wallet Instance encrypts the mDoc response using the session key and transmits it to the Verifier App via a session data message. This technical implementation profile only supports Bluetooth Low Energy (BLE) for the communication sub-phase. + + +The following figure illustrates the flow diagram compliant with ISO 18013-5 for proximity flow. + +.. _fig_High-Level-Flow-ITWallet-Presentation-ISO: +.. figure:: ../../images/High-Level-Flow-ITWallet-Presentation-ISO.svg + :figwidth: 100% + :align: center + :target: https://www.plantuml.com/plantuml/svg/bL9BZnCn3BxFhx3A0H3q3_ImMlOXXBJYqGguzE9ct2RQn0bvJDb_ZoSP3QFI2xab_Xx-xDocZ34NPpiisNDn1ufT1t9GPH_XUw88cA3KjuF_3QlnwNM2dHDYq9vf1Q-Up4ddErkeme9KZ381ESFg9rfB6JwnEB4IiAYTAuou7nN_Al-WQ8xcVzHd2dm8eKeFI-cMfApNDpVd3Nm9n90rmKLBa3s4I8b441dSWrTm7wcNkq7RD3xxJE07CIhlXmqyq624-CWdF94RYQaSWiP4iAweRzjr1vLvRkOVYIcYY32TWO8c9rSBp_GYWKoSe88LzPtsvx5HKO5xtnCSVVpNibA6ATjE8IyfKr7aBgptVDry0WlPXIBOH2aPpoEcbgzDOJTXIEPui2PfrqROZogki56OfNuvcxkdHv5N9H8eZSnaPLRJwUPU95JTn9P-5J60Tn2AcAZQjJ_MiCljxndUN6texN8Dr-ErSjd0roZrNEUjFDSVaJqaZP6gOMpDK0-61UHglkcJjJL75Cx4NHflAKT30xLGH_41wnLQIDb7FD6C7URSAOZCSfCjxyjSWcHEZBb4slCuTQL9FJVsWDRq9akuxfQuByx-0G00 + + High-Level Proximity Flow + +**Step 1-3**: The Verifier requests the User to reveal certain attributes from their mDoc(s) stored in the Wallet Instance. The User initiates the Wallet Instance. The Wallet Instance MUST create a new temporary key pair (EDeviceKey.Priv, EDeviceKey.Pub), and incorporate the cipher suite identifier, the identifier of the elliptic curve for key agreement, and the EDeviceKey public point into the device engagement structure (refer to [ISO18013-5#9.1.1.4]). This key pair is temporary and MUST be invalidated immediately after the secure channel is established. Finally, the Wallet Instance displays the QR Code for Device Engagement. + +Below an example of a device engagement structure that utilizes QR for device engagement and Bluetooth Low Energy (BLE) for data retrieval. + +CBOR data: + +.. code-block:: + + a30063312e30018201d818584ba4010220012158205a88d182bce5f42efa59943f33359d2e8a968ff289d93e5fa444b624343167fe225820b16e8cf858ddc7690407ba61d4c338237a8cfcf3de6aa672fc60a557aa32fc670281830201a300f401f50b5045efef742b2c4837a9a3b0e1d05a6917 + +In diagnostic notation: + +.. code-block:: + + { + 0: "1.0", % Version + + 1: % Security + [ + 1, % defines the cipher suite 1 which contains only EC curves + 24(<< % embedded CBOR data item + { + 1: 2, % kty:EC2 (Elliptic curves with x and y coordinate pairs) + -1: 1, % crv:p256 + -2:h'5A88D182BCE5F42EFA59943F33359D2E8A968FF289D93E5FA444B624343 167FE',% x-coordinate + -3:h'B16E8CF858DDC7690407BA61D4C338237A8CFCF3DE6AA672FC60A557AA32FC67' % y-coordinate + } + >>) + ], + + 2: %DeviceRetrievalMethods(Device engagement using QR code) + [ + [ + 2, %BLE + 1, % Version + { %BLE options + 0: false, % no support for mdoc peripheral server mode + 1: true, % support mdoc central client mode + 11: h'45EFEF742B2C4837A9A3B0E1D05A6917' % UUID of mdoc client central mode + } + ] + ] + } + + + +**Step 4-6**: The Verifier App scans the QR Code and generates its own ephemeral key pair (EReaderKey.Priv, EReaderKey.Pub). It then calculates the session key, using the public key received in the Engagement Structure and its newly-generated private key, as outlined in [ISO18013-5#9.1.1.5]. Finally, it generates its session key, which must be independently derived by both the Wallet Instance and the Verifier App. + +**Step 7**: The Verifier App creates an mDoc request that MUST be encrypted using the relevant session key, and transmits it to the Wallet Instance along with EReaderKey.Pub within a session establishment message. The mDoc request MUST be encoded in CBOR, as demonstrated in the following non-normative example. + +CBOR data: +.. code-block:: + + a26776657273696f6e63312e306b646f63526571756573747381a26c6974656d7352657175657374d818590152a267646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e4954a375766572696669636174696f6e2e65766964656e6365f4781c766572696669636174696f6e2e6173737572616e63655f6c6576656cf4781c766572696669636174696f6e2e74727573745f6672616d65776f726bf4716f72672e69736f2e31383031332e352e31ab76756e5f64697374696e6775697368696e675f7369676ef47264726976696e675f70726976696c65676573f46f646f63756d656e745f6e756d626572f46a69737375655f64617465f46f69737375696e675f636f756e747279f47169737375696e675f617574686f72697479f46a62697274685f64617465f46b6578706972795f64617465f46a676976656e5f6e616d65f468706f727472616974f46b66616d696c795f6e616d65f46a726561646572417574688443a10126a11821590129308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97bf6584058a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9 + +The above CBOR data is represented in diagnostic notation as follows: +.. code-block:: + + { + "version": "1.0", + "docRequests": [ + { + "itemsRequest": 24(<< { + "docType": "org.iso.18013.5.1.mDL", + "nameSpaces": { + "org.iso.18013.5.1.IT": { + "verification.evidence": false, + "verification.assurance_level": false, + "verification.trust_framework": false + }, + "org.iso.18013.5.1": { + "un_distinguishing_sign": false, + "driving_privileges": false, + "document_number": false, + "issue_date": false, + "issuing_country": false, + "issuing_authority": false, + "birth_date": false, + "expiry_date": false, + "given_name": false, + "portrait": false, + "family_name": false + } + } + } >>), + "readerAuth": [ + h'a10126', + { + 33: h'308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97b' + }, + null, + h'58a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9' + ] + } + ] + } + +**Step 8**: The Wallet Instance uses the session establishment message to derive the session keys and decrypt the mDoc request. It computes the session key using the public key received from the Verifier App and its private key. + +**Step 9-10**: When the Wallet Instance receives the mDoc request, it locates the documents that contain the requested attributes and asks the User for permission to provide this information to the Verifier. If the User agrees, the Wallet generates an mDoc response and transmits it to the Verifier App through the secure channel. + +**Step 11-12**: If the User gives consent, the Wallet Instance creates an mDoc response and transmits it to the Verifier App via the secure channel. The mDoc response MUST be encoded in CBOR, with its structure outlined in [ISO18013-5#8.3.2.1.2.2]. Below is a non-normative example of an mDoc response. + +CBOR Data: +.. code-block:: + + a36776657273696f6e63312e3069646f63756d656e747381a367646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6c6973737565725369676e6564a26a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e495483d81858f7a46864696765737449440b6672616e646f6d506d44f21ee875f2c1d502b43198e5a15271656c656d656e744964656e74696669657275766572696669636174696f6e2e65766964656e63656c656c656d656e7456616c756581a2647479706571656c656374726f6e69635f7265636f7264667265636f7264bf6474797065781f68747470733a2f2f657564692e77616c6c65742e70646e642e676f762e697466736f75726365bf716f7267616e697a6174696f6e5f6e616d65754d6f746f72697a7a617a696f6e6520436976696c656f6f7267616e697a6174696f6e5f6964656d5f696e666c636f756e7472795f636f6465626974ffffd8185866a4686469676573744944046672616e646f6d50185d84dfb71ce9b173010ddd62174fbe71656c656d656e744964656e746966696572781c766572696669636174696f6e2e74727573745f6672616d65776f726b6c656c656d656e7456616c7565656569646173d8185865a4686469676573744944006672616e646f6d50137f903174253c4585358267aae2ea4e71656c656d656e744964656e746966696572781c766572696669636174696f6e2e6173737572616e63655f6c6576656c6c656c656d656e7456616c75656468696768716f72672e69736f2e31383031332e352e318bd8185852a46864696765737449440c6672616e646f6d5053e29d0ddbbc7d2306a32bdbe2e56e5171656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756563446f65d8185855a4686469676573744944036672616e646f6d50990cba2069fa1b33b8d6ae910b6549dc71656c656d656e744964656e7469666965726a676976656e5f6e616d656c656c656d656e7456616c756567416e746f6e696fd818585ba46864696765737449440a6672616e646f6d504086c1379975f805f1b1f4975e6a126571656c656d656e744964656e7469666965726a69737375655f646174656c656c656d656e7456616c7565d903ec6a323031392d31302d3230d818585ca4686469676573744944016672616e646f6d50ab4ca30c918dd2fd0bf35242c15fa2d871656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d31302d3230d8185855a4686469676573744944076672616e646f6d508d9066f6c8da16619867cd4e2fab0c8871656c656d656e744964656e7469666965726f69737375696e675f636f756e7472796c656c656d656e7456616c7565624954d818587ea4686469676573744944056672616e646f6d5059fe68db795dee4c20976380ea24770571656c656d656e744964656e7469666965727169737375696e675f617574686f726974796c656c656d656e7456616c75657828497374697475746f20506f6c696772616669636f2065205a656363612064656c6c6f20537461746fd818585ba4686469676573744944026672616e646f6d5008b3f1ca5517019767be3dee3bb0614571656c656d656e744964656e7469666965726a62697274685f646174656c656c656d656e7456616c7565d903ec6a313935362d30312d3230d818585ca4686469676573744944096672616e646f6d50a2395ec214350c26066306e23279b3ae71656c656d656e744964656e7469666965726f646f63756d656e745f6e756d6265726c656c656d656e7456616c756569393837363534333231d8185850a4686469676573744944066672616e646f6d50a25e1a5b915d2d6eafee9674e023293971656c656d656e744964656e74696669657268706f7274726169746c656c656d656e7456616c75654420212223d81858eea46864696765737449440d6672616e646f6d50eeed6a3b856563627589a360939d12f771656c656d656e744964656e7469666965727264726976696e675f70726976696c656765736c656c656d656e7456616c756582a37576656869636c655f63617465676f72795f636f646561416a69737375655f64617465d903ec6a323031382d30382d30396b6578706972795f64617465d903ec6a323032342d31302d3230a37576656869636c655f63617465676f72795f636f646561426a69737375655f64617465d903ec6a323031372d30322d32336b6578706972795f64617465d903ec6a323032342d31302d3230d818585ba4686469676573744944086672616e646f6d50c0ef486b2a194ed3cbf7f354fd40092171656c656d656e744964656e74696669657276756e5f64697374696e6775697368696e675f7369676e6c656c656d656e7456616c756561496a697373756572417574688443a10126a118215901423082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb + +In diagnostic notation: +.. code-block:: + + { + "version": "1.0", + "documents": [ + { + "docType": "org.iso.18013.5.1.mDL", + "issuerSigned": { + "nameSpaces": { + "org.iso.18013.5.1.IT": [ + 24(<< { + "digestID": 11, + "random": h'6d44f21ee875f2c1d502b43198e5a152', + "elementIdentifier": "verification.evidence", + "elementValue": [ + { + "type": "electronic_record", + "record": { + "type": "https://eudi.wallet.pdnd.gov.it", + "source": { + "organization_name": "Motorizzazione Civile", + "organization_id": "m_inf", + "country_code": "it" + } + } + } + ] + } >>), + 24(<< { + "digestID": 4, + "random": h'185d84dfb71ce9b173010ddd62174fbe', + "elementIdentifier": "verification.trust_framework", + "elementValue": "eidas" + } >>), + 24(<< { + "digestID": 0, + "random": h'137f903174253c4585358267aae2ea4e', + "elementIdentifier": "verification.assurance_level", + "elementValue": "high" + } >>) + ], + "org.iso.18013.5.1": [ + 24(<< { + "digestID": 12, + "random": h'53e29d0ddbbc7d2306a32bdbe2e56e51', + "elementIdentifier": "family_name", + "elementValue": "Doe" + } >>), + 24(<< { + "digestID": 3, + "random": h'990cba2069fa1b33b8d6ae910b6549dc', + "elementIdentifier": "given_name", + "elementValue": "Antonio" + } >>), + 24(<< { + "digestID": 10, + "random": h'4086c1379975f805f1b1f4975e6a1265', + "elementIdentifier": "issue_date", + "elementValue": 1004("2019-10-20") + } >>), + 24(<< { + "digestID": 1, + "random": h'ab4ca30c918dd2fd0bf35242c15fa2d8', + "elementIdentifier": "expiry_date", + "elementValue": 1004("2024-10-20") + } >>), + 24(<< { + "digestID": 7, + "random": h'8d9066f6c8da16619867cd4e2fab0c88', + "elementIdentifier": "issuing_country", + "elementValue": "IT" + } >>), + 24(<< { + "digestID": 5, + "random": h'59fe68db795dee4c20976380ea247705', + "elementIdentifier": "issuing_authority", + "elementValue": "Istituto Poligrafico e Zecca dello Stato" + } >>), + 24(<< { + "digestID": 2, + "random": h'08b3f1ca5517019767be3dee3bb06145', + "elementIdentifier": "birth_date", + "elementValue": 1004("1956-01-20") + } >>), + 24(<< { + "digestID": 9, + "random": h'a2395ec214350c26066306e23279b3ae', + "elementIdentifier": "document_number", + "elementValue": "987654321" + } >>), + 24(<< { + "digestID": 6, + "random": h'a25e1a5b915d2d6eafee9674e0232939', + "elementIdentifier": "portrait", + "elementValue": h'20212223' + } >>), + 24(<< { + "digestID": 13, + "random": h'eeed6a3b856563627589a360939d12f7', + "elementIdentifier": "driving_privileges", + "elementValue": [ + { + "vehicle_category_code": "A", + "issue_date": 1004("2018-08-09"), + "expiry_date": 1004("2024-10-20") + }, + { + "vehicle_category_code": "B", + "issue_date": 1004("2017-02-23"), + "expiry_date": 1004("2024-10-20") + } + ] + } >>), + 24(<< { + "digestID": 8, + "random": h'c0ef486b2a194ed3cbf7f354fd400921', + "elementIdentifier": "un_distinguishing_sign", + "elementValue": "I" + } >>) + ] + }, + "issuerAuth": [ + h'a10126', + { + 33: h'3082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb7d518bd9a519583e082d67effff06565804fc09abf0e4a08e699c9dba3796285a15f68e40ac7f9fc7700a15153a4065300a06082a8648ce3d040302034800304502210099b7d62e6bf7b1823db3713df889bf73e70bb4d9c58c21e92c58d2f1beffe932022058d039747a00d70e6d66be4797e6142b3608a014ee09b7b79af2cae2aaf27788' + }, + 24(<< { + "version": "1.0", + "digestAlgorithm": "SHA-256", + "docType": "org.iso.18013.5.1.mDL", + "valueDigests": { + "org.iso.18013.5.1": { + 1: h'0E5F0B6B33418E508740771E82F893372EAF5B2445BC4C84DCF08B005E9493FC', + 2: h'DE21BB62FF2897D8B986D2CDA9F9BC5865C02807F7B4D9DD1FA4A79DF4C0D37F', + 3: h'BC5568239E35CE9FF8798C27FFDCD757B134B679F0FE05729AA3491381912E65', + 5: h'E6048BDC7FD6454296F1E3F54536107C9C5B24C4064DE46A98121E3630EECCA2', + 6: h'73690D92DCAA61B0203870F67C6AA9FDFEA889B6F0C720DE757B4B0A8516A206', + 7: h'E353EA0B0FD92B6BE90C64CC3B2EE1284153A8F0F5066B99AAC599200E6EEEB2', + 8: h'29227872CEB49923D267B5F4BADE6D387B42AC2DC4B2AE26C9013067FEE7018A', + 9: h'A6A119F7CACAC0B8C6AACAC747FD3FE7E50B6D9BB8A507FDA79F0DF6646F285D', + 10: h'6D8025D2F02A5E7E1406FB6AAEB67F9EDE9B07191A53F3E23B77C528223A94E2', + 12: h'B0D43E4E2EA534E4D5304E64BCF7A0F13E2C8EE8304B9CD23ABA4909652A4647', + 13: h'FBF4DE318982F2DBAD43C601CAEB22628B301AC18AA8264C5831B2AAAC89C486' + }, + "org.iso.18013.5.1.IT": { + 0: h'CF57377B675F64F37314739592C1E8A911A7DDAF341CE2902FE877C5A835E4C1', + 4: h'4A4B4CC64EC9299C1A2501EA449F577005E9F7A60408057C07A7C67FB151E5F5', + 11: h'78824FBD6FBBA88A2AAB44DF8B6F5E9759126D87D1F4415995E658FD9239E1FE' + } + }, + "deviceKeyInfo": { + "deviceKey": { + 1: 2, + -1: 1, + -2: h'AFD09E720B918CEDC2B8A881950BAB6A1051E18AE16A814D51E609938663D5E1', + -3: h'61FBC6C8AD24EC86A78BB4E9AC377DD2B7C711D9F2EB9AFD4AA0963662847AED'}}, + "validityInfo": { + "signed": 0("2023-11-24T14:54:05Z"), + "validFrom": 0("2023-11-24T14:54:05Z"), + "validUntil": 0("2024-11-24T14:54:05Z")} + } >>), + h'f2461e4fab69e9f7bcffe552395424514524d1679440036213173101448d1b1ab4a293859b389ffa8b47aeed10e9b0c1545412ac37c51a76482cd9bbbe110152' + ] + }, + "deviceSigned": { + "nameSpaces": 24(<< {} >>), + "deviceAuth": { + "deviceSignature": [ + h'a10126', + {}, + null, + h'1fed7190d2975ab79c072e6f1d9d52436059d1fc959d55baf74f057d89b10fcc0dc77a50d433d4c76ddf26223c5560c4ab123b5cb5eb805a90036aa147493076' + ] + } + } + } + ], + "status": 0 + } + +**Step 13**: The Verifier App is required to validate the signatures in the mDoc's issuerSigned field using the public key of the Credential Issuer specified within the mDoc. Subsequently, the Verifier MUST validate the signature in the deviceSigned field. If these signature checks pass, the Verifier can confidently consider the received information as valid. + +Device Engagement +----------------- + +The Device Engagement structure MUST be have at least the following components: + + - **Version**: *tstr*. Version of the data structure being used. + - **Security**: an array that contains two mandatory values + + - the cipher identifier: see Table 22 of [ISO18013-5] + - the mDL public ephemeral key generated by the Wallet Instance and required by the Verifier App to derive the Session Key. The mDL public ephemeral key MUST be of a type allowed by the indicated cipher suite. + - **transferMethod**: an array that contains one or more transferMethod arrays when performing device engagement using the QR code. This array is for offline data retrieval methods. A transferMethod array holds two mandatory values (type and version). Only the BLE option is supported by this technical implementation profile, then the type value MUST be set to ``2``. + - **BleOptions**: this elements MUST provide options for the BLE connection (support for Peripheral Server or Central Client Mode, and the device UUID). + + +mDoc Request +------------ + +The messages in the mDoc Request MUST be encoded using CBOR. The resulting CBOR byte string for the mDoc Request MUST be encrypted with the Session Key obtained after the Device Engagement phase and MUST be transmitted using the BLE protocol. +The details on the structure of mDoc Request, including identifier and format of the data elements, are provided below. + + - **version**: (tstr). Version of the data structure. + - **docRequests**: Requested DocType, NameSpace and data elements. + + - **itemsRequest**: #6.24(bstr .cbor ItemsRequest). + + - **docType**: (tstr). The DocType element contains the type of document requested. See :ref:`Data Model Section `. + - **nameSpaces**: (tstr). See :ref:`Data Model Section ` for more details. + + - **dataElements**: (tstr). Requested data elements with *Intent to Retain* value for each requested element. + + - **IntentToRetain**: (bool). It indicates that the Verifier App intends to retain the received data element. + - **readerAuth**: *COSE_Sign1*. It is required for the Verifier App authentication. + +.. note:: + + The domestic data elements MUST not be returned unless specifically requested by the Verifier App. + +mDoc Response +------------- + +The messages in the mDoc Response MUST be encoded using CBOR and MUST be encrypted with the Session Key obtained after the Device Engagement phase. +The details on the structure of mDoc Response are provided below. + + - **version**: (tstr). Version of the data structure. + - **documents**: Returned *DocType*, and *ResponseData*. + + - **docType**: (tstr). The DocType element contains the type of document returned. See :ref:`Data Model Section `. + - **ResponseData**: + + - **IssuerSigned**: Responded data elements signed by the issuer. + + - **nameSpaces**: (tstr). See :ref:`Data Model Section ` for more details. + + - **IssuerSignedItemBytes**: #6.24(bstr .cbor). + + - **digestID**: (uint). Reference value to one of the **ValueDigests** provided in the *Mobile Security Object* (`issuerAuth`). + - **random**: (bstr). Random byte value used as salt for the hash function. This value SHALL be different for each *IssuerSignedItem* and it SHALL have a minimum length of 16 bytes. + - **elementIdentifier**: (tstr). Identifier of User attribute name contained in the Credential. + - **elementValue**: (any). User attribute value + - **DeviceSigned**: Responded data elements signed by the Wallet Instance. + + - **NameSpaces**: #6.24(bstr .cbor DeviceNameSpaces). The DeviceNameSpaces structure MAY be an empty structure. DeviceNameSpaces contains the data element identifiers and values. It is returned as part of the corresponding namespace in DeviceNameSpace. + + - **DataItemName**: (tstr). The identifier of the element. + - **DataItemValue**: (any). The value of the element. + - **DeviceAuth**: The DeviceAuth structure MUST contain the DeviceSignature elements. + + - **DeviceSignature**: It MUST contain the device signature for the Wallet Instance authentication. + - **status**: It contains a status code. For detailed description and action required refer to to Table 8 (ResponseStatus) of the [ISO18013-5] + + +Session Termination +------------------- + +The session MUST be terminated if at least one of the following conditions occur. + + - After a time-out of no activity of receiving or sending session establishment or session data messages occurs. The time-out for no activity implemented by the Wallet Instance and the Verifier App SHOULD be no less than 300 seconds. + - When the Wallet Instance doesn't accept any more requests. + - When the Verifier App does not send any further requests. + +If the Wallet Instance and the Verifier App does not send or receive any further requests, the session termination MUST be initiated as follows. + + - Send the status code for session termination, or + - dispatch the "End" command as outlined in [ISO18013-5#8.3.3.1.1.5]. + +When a session is terminated, the Wallet Instance and the Verifier App MUST perform at least the following actions: + + - destruction of session keys and related ephemeral key material; + - closure of the communication channel used for data retrieval. diff --git a/refs/pull/443/merge/en/_sources/pseudonyms.rst.txt b/refs/pull/443/merge/en/_sources/pseudonyms.rst.txt new file mode 100644 index 000000000..e53c8bbc4 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/pseudonyms.rst.txt @@ -0,0 +1,45 @@ +.. include:: ../common/common_definitions.rst + +.. _pseudonyms.rst: + + +Pseudonyms +++++++++++ + + +What it is useful for +--------------------- +Pseudonyms are useful for: +- Protecting user privacy in online platforms +- Allowing anonymous participation in discussions or transactions +- Maintaining consistent identities across multiple services without revealing personal information +- Compliance with data protection regulations that require data minimization + +Example +------- +In a social media platform, a user might choose the pseudonym "SunflowerDreamer" +instead of using their real name "Jane Smith". This allows Jane +to participate in discussions while maintaining her privacy. + +General Properties +------------------ +- Uniqueness within a given context. +- Consistency (the same entity always uses the same pseudonym in a given context). +- Reversibility (optional, depending on the system's requirements). +- Non-linkability to the real identity (without additional information). + +Requirements +------------ +- IT-Wallet MUST be able to generate or assign unique pseudonyms. +- The pseudonym SHOULD NOT contain information that directly reveals the entity's real identity. +- The system SHOULD maintain a secure mapping between pseudonyms and real identities (if reversibility is required). +- The pseudonym generation process SHOULD be resistant to guessing attacks. + + +Implementation Considerations +----------------------------- +- IT-Wallet MUST use a pseudonym format that balances uniqueness, readability, and security. +- IT-Wallet MUST implement a secure method for generating and storing pseudonyms. +- IT-Wallet SHOULD use different pseudonyms for the same entity across different contexts to prevent cross-context linking. +- IT-Wallet SHOULD implement access controls to protect the mapping between pseudonyms and real identities. +- IT-Wallet SHOULD implements policies for pseudonym rotation or expiration. diff --git a/refs/pull/443/merge/en/_sources/relying-party-entity-configuration.rst.txt b/refs/pull/443/merge/en/_sources/relying-party-entity-configuration.rst.txt new file mode 100644 index 000000000..9f0f69e85 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/relying-party-entity-configuration.rst.txt @@ -0,0 +1,68 @@ +.. include:: ../common/common_definitions.rst + +Entity Configuration of Relying Parties +-------------------------------------------- + +According to Section :ref:`Configuration of the Federation`, as a Federation Entity, the Relying Party is required to maintain a well-known endpoint that hosts its Entity Configuration. +The Entity Configuration of Relying Parties MUST contain the parameters defined in the Sections :ref:`Entity Configuration Leaves and Intermediates` and :ref:`Entity Configurations Common Parameters`. + +The Relying Parties MUST provide the following metadata types: + + - `federation_entity` + - `wallet_relying_party` + + +Metadata for federation_entity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The *federation_entity* metadata MUST contain the claims as defined in Section :ref:`Metadata of federation_entity Leaves`. + +Metadata for wallet_relying_party +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The *wallet_relying_party* metadata MUST contain the following parameters. + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - **client_id** + - It MUST contain an HTTPS URL that uniquely identifies the RP. See :rfc:`7591#section-3.2.1` and `OpenID Connect Dynamic Client Registration 1.0 `_ Section 3.2. + * - **client_name** + - Human-readable string name of the RP. See :rfc:`7591#section-2`. + * - **application_type** + - String indicating the type of application. It MUST be set to "*web*" value. See `OpenID Connect Dynamic Client Registration 1.0 `_ Section 2. + * - **request_uris** + - JSON Array of *request_uri* values that are pre-registered by the RP. These URLs MUST use the *https* scheme. See `OpenID Connect Dynamic Client Registration 1.0 `_ Section 2. + * - **response_uris_supported** + - JSON Array of response URI strings to which the Wallet Instance MUST send the Authorization Response using an HTTP POST request as defined by the Response Mode ``direct_post`` and ``direct_post.jwt`` (see `OpenID4VP`_ Draft 20 Sections 6.2 and 6.3). + * - **authorization_signed_response_alg** + - String representing the JWS [:rfc:`7515`] *alg* algorithm that MUST be used for signing authorization responses. The algorithm *none* MUST NOT be used. See `[oauth-v2-jarm-03] `_ Section 3. + * - **vp_formats** + - JSON object defining the formats and proof types of Verifiable Presentations and Verifiable Credentials the RP supports. It consists of a list of name/value pairs, where each name uniquely identifies a supported type. The RP MUST support at least "*vc+sd-jwt*" according to `OPENID4VC-HAIP`_ Draft 00 Section 7.2.7. The value associated with each name/value pair MUST be a JSON object "**sd-jwt_alg_values**" that MUST contain a JSON array containing identifiers of cryptographic algorithms the RP supports for protection of a SD-JWT. The *alg* JOSE header (as defined in :rfc:`7515`) of the presented SD-JWT MUST match one of the array values. See also `OpenID4VP`_ Draft 20 Section 9.1. + * - **presentation_definitions_supported** + - JSON Array of supported *presentation_definition* objects that MUST be compliant to the syntax defined in Section 5 of `[DIF.PresentationExchange] `_ and Section 7.2.8 of `OPENID4VC-HAIP`_ Draft 00. For *presentation_definition* objects see also `OpenID4VP`_ Section 5.1. + * - **jwks** + - JSON Web Key Set document, passed by value, containing the protocol specific keys for the Relying Party. See `[oauth-v2-jarm-03] `_ Section 3, `OID-FED`_ Draft 36 Section 5.2.1 and `JWK`_. + +.. note:: + The claims **response_uris_supported** and **presentation_definitions_supported** are introduced in this Specification. + +Example of a Relying Party Entity Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Below a non-normative example of the request made by the Wallet Instance to the *openid-federation* well-known endpoint to obtain the Relying Party Entity Configuration: + +.. code-block:: http + + GET /.well-known/openid-federation HTTP/1.1 + HOST: relying-party.example.org + + +Below is a non-normative response example: + +.. literalinclude:: ../../examples/ec-rp.json + :language: JSON + diff --git a/refs/pull/443/merge/en/_sources/relying-party-solution.rst.txt b/refs/pull/443/merge/en/_sources/relying-party-solution.rst.txt new file mode 100644 index 000000000..eabd1c452 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/relying-party-solution.rst.txt @@ -0,0 +1,20 @@ + + + + +.. _relying-party-solution: + +Relying Party Solution ++++++++++++++++++++++++ + +This section describes how a remote Relying Party or a Verifier App requests to a Wallet Instance the presentation of the PID/EAAs. + +In this section the following flows are described: + +- :ref:`Remote Flow`, where the User presents a Credential to a remote Relying Party according to `OpenID4VP`_ Draft 20. In this scenario the user-agent and the Wallet Instance can be used in the same device (**Same Device Flow**), or in different devices (**Cross Device Flow**). +- :ref:`Proximity Flow`, where the User presents a Credential to a Verifier App according to ISO 18013-5. The User interacts with a Verifier using proximity connection technologies such as QR Code and Bluetooth Low Energy (BLE). + +.. include:: remote-flow.rst + +.. include:: proximity-flow.rst + diff --git a/refs/pull/443/merge/en/_sources/remote-flow.rst.txt b/refs/pull/443/merge/en/_sources/remote-flow.rst.txt new file mode 100644 index 000000000..07c28afde --- /dev/null +++ b/refs/pull/443/merge/en/_sources/remote-flow.rst.txt @@ -0,0 +1,577 @@ +.. include:: ../common/common_definitions.rst +.. _Wallet Attestation: wallet-attestation.html +.. _Trust Model: trust.html + + +Remote Flow +=========== + +In this flow the Relying Party MUST provide the URL where the signed presentation Request Object is available for download. + +Depending on whether the User is using a mobile device or a workstation, the Relying Party MUST support the following remote flows: + +* **Same Device**, the Relying Party MUST provide a HTTP redirect (302) location to the Wallet Instance; +* **Cross Device**, the Relying Party MUST provide a QR Code which the User frames with the Wallet Instance. + +Once the Wallet Instance establishes the trust with the Relying Party and evaluates the request, the User gives the consent for the disclosure of the Digital Credentials, in the form of a Verifiable Presentation. + +A High-Level description of the remote flow, from the User's perspective, is given below: + + 1. the Wallet Instance obtains an URL in the Same Device flow or a QR Code containing the URL in Cross Device flow; + 2. the Wallet Instance extracts from the payload the following parameters: ``client_id``, ``request_uri``, ``state``, ``request_uri_method`` and ``client_id_scheme``; + 3. If the ``client_id_scheme`` is provided and set with the value ``entity_id``, the Wallet Instance MUST collect and validate the OpenID Federation Trust Chain related to the Relying Party. If the ``client_id_scheme`` is either not provided or is assigned a value different from ``entity_id``, the Wallet Instance MUST establish the trust by utilizing the ``client_id`` or an alternative ``client_id_scheme`` value. This alternative value MUST enable the Wallet Instance to establish trust with the Relying Party, ensuring compliance with the assurance levels mandated by the trust framework; + 4. If ``request_uri_method`` is provided and set with the value ``post``, the Wallet Instance SHOULD transmit its metadata to the Relying Party's ``request_uri`` endpoint using the HTTP POST method and obtain the signed Request Object. If ``request_uri_method`` is set with the value ``get`` or not present, the Wallet Instance MUST fetch the signed Request Object using an HTTP request with method GET to the endpoint provided in the ``request_uri`` parameter; + 5. the Wallet Instance verifies the signature of the signed Request Object, using the public key identifier within the Request Object JWT header parameter to select the correct public key obtained within Trust Chain related to the RP; + 6. the Wallet Instance verifies that the ``client_id`` contained in the Request Object issuer (RP) matches with the one obtained at the step number 2 and with the ``sub`` parameter contained in the RP's Entity Configuration within the Trust Chain; + 7. the Wallet Instance evaluates the requested Digital Credentials and checks the elegibility of the Relying Party in asking these by applying the policies related to that specific Relying Party, obtained with the trust chain; + 8. the Wallet Instance asks User disclosure and consent; + 9. the Wallet Instance presents the requested information to the Relying Party along with the Wallet Attestation. The Relying Party validates the presented Credentials checking the trust with their Issuers, and validates the Wallet Attestation by also checking that the Wallet Provider is trusted; + 10. the Wallet Instance informs the User about the successfull authentication with the Relying Party, the User continues the navigation. + +Below a sequence diagram that summarizes the interactions between all the involved parties. + +.. figure:: ../../images/cross_device_auth_seq_diagram.svg + :figwidth: 100% + :align: center + :target: https://www.plantuml.com/plantuml/svg/ZLPDRnit4BtpLmpKGst3Tftq9i157DUrdRIrQYdn8Gu4YZkIM5FabX-hk4N_UuQabk36EaG80fYQz-RDcnbIRvpdreUDOZnueyDcWPOnTY6yiJ3wuD2EW3i8Z2tCbtpmeuDViPC2tGX--5skrlwj2iXQuf52jbnx63rmfT33hIPwBJ1nR8SXWQXE-0grpnauGzq0PHc6tQDwbde54pfyJf4TCiQ5bnttIC82dFn2w34yu0AcQACoqBoJA-wbqLKePmtMG1wH7OxX7ly9w3nChF4eF3PquaomWZATdzCnEfAPw62ovWxX_BpmHZqTzbIN5kCPXwCZHmWyEeAEapsFUc42rUSDbC8z26EUv1wupOBcmKgmlPGE-qh_khyq3SBTFTpCPXCIsqXBkk7WvxFNXx2LVlseXPAKOIwRuvhj69AgO_XK7SutwDUc-GoV2cZkn1et-9aSg-kCdvKreIMXnlLp04QhvvsTOGpJjTc2NsCliwLQ1yxpRzf7iEqOxbhK2VRDx01lssDGHd05F520zbBarjQaXPFcR0kPSYgu9XKGPPJ3go_UKcnAHPF6gNYq3fRMRE9PYKVTi0B2s4GYT-1jS3vvdAABO_lCOrnva4juwJL81mvtF9ExwOm1VRRz6BJMTB91rtj18Dvmpy4RoZgS3zBP6gbzOgYR1VGfarLLK7diKMWPZHMyvGkff9Ve62g7to7x-ce6ne8s7jgy8QogeKVdV4wkD3Rz6PZ5toXyyNnlFRa17VRpiPVYnNo-RDZW0e4_UYUvRg0rIWg9hg0-efNBvvIA-s0HpBAIN-w9kvoxeBYIJRMs5FbnSk0ESq0O5zpIM116Hwlshi2bqKjfDzWC9xjO6WS5BW9rmif_qmeGjMiZ8ppgt9MkdNlpXBfiUblTNdCN5XlfN5oU_VVNrSwtM7QsG_A5mk4Tc18KK6L0DLeNtgFByQSaBlzP1qpoZ5iIBbtSHD-x_HlISKBITzIdlRU2T6doB7OafZcjrEnINLgYqLvo1RVE1RGmYwkxeooItptCODhtks8XUGAToqjUg1Ypb1N1T6WfZDw_s-kRsVNzrTMVR3zYpE1oZU89Reng2FGUd-6jr0sDP192A2gR_asCSvXQGv0J28uYyYKL5ZIcy4J0_8P87S_h0hs1BerkRjiaT-YKCPYjKGDMLruZdL36OGFSUoiNmQCRWqWIvHB8vRAHqb9KNXQBm3ikLPo5k9Z91LRPzQ4j0n1_8y2k53Z8Jno4z7rp26ouilrxCkKRh9-JQl7Z6_VJgzDNyFhi3ExUKmF_6zdyvAKROpI6jVUjWs1LtW6xMugvC0t2_xizvAJIPOarlDQp7VnQe3e7pzttwIk_Ayex_Muwtit0yFtA6me7aQ3SQwc0RDhXYntTbN6nZsObEzGPdWXZxUuO0iKfHIFGfdOQ2ow8EAVBe8Qlyh0ngVetz5_OgAy0 + + + Remote Protocol Flow + + +The details of each step shown in the previous picture are described in the table below. + +.. list-table:: + :widths: 10 50 + :header-rows: 1 + + * - **Id** + - **Description** + * - **1**, **2** + - The User requests to access to a protected resource of the Relying Party. + * - **3**, **4**, + - The Relying Party provides the Wallet Instance with a URL where the information about the Relying Party are provided, along with the information about where the signed request is available for download. + * - **5**, **6**, **7**, **8**, **9** + - In the **Cross Device Flow**, the Request URI is presented as a QR Code displayed to the User. The User scans the QR Code using the Wallet Instance, which retrieves a URL with the parameters ``client_id``, ``request_uri``, ``state``, ``client_id_scheme``, and ``request_uri_method``. Conversely, in the Same Device Flow, the Relying Party supplies identical information as in the Cross-Device flow, but directly through a URL. + * - **10**, + - The Wallet Instance evaluates the trust with the Relying Party. + * - **11**, **12** + - The Wallet Instance checks if the Relying Party has provided the ``request_uri_method`` within its signed Request Object. If provided and it is equal to ``post``, the Wallet Instance provides its metadata to the Relying Party. The Relying Party returns a signed Request Object compliant to the Wallet technical capabilities. + * - **13** + - When the Wallet Instance capabilities discovery is not supported by RP, the Wallet Instance request the signed Request Object using the HTTP method GET. + * - **14** + - The RP issues the Request Object signin it using one of its cryptographic private keys, where their public parts have been published within its Entity Configuration (`metadata.wallet_relying_party.jwks`). The Wallet Instance obtains the signed Request Object. + * - **15**, **16**, **17** + - The Request Object JWS is verified by the Wallet Instance. The Wallet Instance processes the Relying Party metadata and applies the policies related to the Relying Party, attesting whose Digital Credentials and User data the Relying Party is granted to request. + * - **18**, **19** + - The Wallet Instance requests the User's consent for the release of the Credentials. The User authorizes and consents the presentation of the Credentials by selecting/deselecting the personal data to release. + * - **20** + - The Wallet Instance provides the Authorization Response to the Relying Party using an HTTP request with the method POST (response mode "direct_post.jwt"). + * - **21**, **22**, **23**, **24**, **25** + - The Relying Party verifies the Authorization Response, extracts the Wallet Attestation to establish the trust with the Wallet Solution. The Relying Party extracts the Digital Credentials and attests the trust to the Credentials Issuer and the proof of possession of the Wallet Instance about the presented Digital Credentials. Finally, the Relying Party verifies the revocation status of the presented Digital Credentials. + * - **26** (Same Device Flow only) + - The Relying Party provides to the Wallet Instance a redirect URI with a response code to be used by the Wallet Instance to finalize the authentication. + * - **27**, **28** and **29** + - The User is informed by the Wallet Instance that the Autentication succeded, then the protected resource is made available to the User. + + +Request URI with HTTP POST +-------------------------- + +The Relying Party SHOULD provide the POST method with its ``request_uri`` endpoint +allowing the Wallet Instance to inform the Relying Party about its technical capabilities. + +This feature can be useful when, for example, the Wallet Instance supports +a restricted set of features, supported algorithms or a specific url for +its ``authorization_endpoint``, and any other information that it deems necessary to +provide to the Relying Party for better interoperability. + +.. warning:: + The Wallet Instance, when providing its technical capabilities to the + Relying Party, MUST NOT include any User information or other explicit + information regarding the hardware used or usage preferences of its User. + +If both the Relying Party and the Wallet Instance +support the ``request_uri_method`` with HTTP POST, +the Wallet Instance capabilities (metadata) MUST +be provided using an HTTP request to the `request_uri` endpoint of the Relying Party, +with the method POST and content type set to `application/json`. + +A non-normative example of the HTTP request is represented below: + +.. code:: http + + POST /request-uri HTTP/1.1 + HOST: relying-party.example.org + Content-Type: application/json + + { + "authorization_endpoint": "https://wallet-solution.digital-strategy.europa.eu/authorization", + "response_types_supported": [ + "vp_token" + ], + "response_modes_supported": [ + "form_post.jwt" + ], + "vp_formats_supported": { + "vc+sd-jwt": { + "sd-jwt_alg_values": [ + "ES256", + "ES384" + ] + } + }, + "request_object_signing_alg_values_supported": [ + "ES256" + ], + "presentation_definition_uri_supported": false + } + +The response of the Relying Party is defined in the section below. + + +Authorization Request Details +----------------------------- + +The Relying Party MUST create a Request Object in the form of a signed JWT and +MUST provide it to the Wallet Instance through an HTTP URL (request URI). +The HTTP URL points to the web resource where the signed Request Object is +available for download. The URL parameters contained in the Relying Party +response, containing the request URI, are described in the Table below. + +.. list-table:: + :widths: 25 50 + :header-rows: 1 + + * - **Name** + - **Description** + * - **client_id** + - REQUIRED. Unique identifier of the Relying Party. + * - **request_uri** + - REQUIRED. The HTTPs URL where the Relying Party provides the signed Request Object to the Wallet Instance. + * - **client_id_scheme** + - OPTIONAL. The scheme used by the Relying Party for the client_id, detailing the format and structure and the trust evaluation method. It SHOULD be set with ``entity_id``. + * - **state** + - OPTIONAL. A unique identifier for the current transaction generated by the Relying Party. The value SHOULD be opaque to the Wallet Instance. + * - **request_uri_method** + - OPTIONAL. The HTTP method MUST be set with ``get`` or ``post``. The Wallet Instance should use this method to obtain the signed Request Object from the request_uri. If not provided or equal to ``get``, the Wallet Instance SHOULD use the HTTP method ``get``. Otherwise, the Wallet Instance SHOULD provide its metadata within the HTTP POST body encoded in ``application/json``. + +Below a non-normative example of the response containing the required parameters previously described. + +.. code-block:: javascript + + https://wallet-solution.digital-strategy.europa.eu/authorization?client_id=...&request_uri=...&client_id_scheme=entity_id&request_uri_method=post + +The value corresponding to the `request_uri` endpoint SHOULD be randomized, according to `RFC 9101, The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR) `_ Section 5.2.1. + + +In the **Same Device Flow** the Relying Party uses an HTTP response redirect (with status code set to 302) as represented in the following non-normative example: + +.. code:: text + + HTTP/1.1 /authorization Found + Location: https://wallet-solution.digital-strategy.europa.eu? + client_id=https%3A%2F%2Frelying-party.example.org%2Fcb + &request_uri=https%3A%2F%2Frelying-party.example.org%2Frequest_uri + &client_id_scheme=entity_id + &request_uri_method=post + + +In the **Cross Device Flow**, a QR Code is shown by the Relying Party to the User in order to provide the Authorization Request. The User frames the QR Code using their Wallet Instance. + +Below is represented a non-normative example of a QR Code issued by the Relying Party. + +.. figure:: ../../images/verifier_qr_code.svg + :figwidth: 50% + :align: center + + +Below is represented a non-normative example of the QR Code raw payload: + +.. code-block:: text + + https://wallet-solution.digital-strategy.europa.eu/authorization?client_id=https%3A%2F%2Frelying-party.example.org&request_uri=https%3A%2F%2Frelying-party.example.org&client_id_scheme=entity_id&request_uri_method=post + +.. note:: + The *error correction level* chosen for the QR Code MUST be Q (Quartily - up to 25%), since it offers a good balance between error correction capability and data density/space. This level of quality and error correction allows the QR Code to remain readable even if it is damaged or partially obscured. + + +Cross Device Flow Status Checks and Security +-------------------------------------------- + +When the flow is Cross Device, the user-agent needs to check the session status to the endpoint made available by Relying Party (status endpoint). This check MAY be implemented in the form of JavaScript code, within the page that shows the QRCode, then the user-agent checks the status with a polling strategy in seconds or a push strategy (eg: web socket). + +Since the QRcode page and the status endpoint are implemented by the Relying Party, it is under the Relying Party responsability the implementation details of this solution, since it is related to the Relying Party's internal API. However, the text below describes an implementation example. + +The Relying Party binds the request of the user-agent, with a session cookie marked as ``Secure`` and ``HttpOnly``, with the issued request. The request url SHOULD include a parameter with a random value. The HTTP response returned by this specialized endpoint MAY contain the HTTP status codes listed below: + +* **201 Created**. The signed Request Object was issued by the Relying Party that waits to be downloaded by the Wallet Instance at the **request_uri** endpoint. +* **202 Accepted**. This response is given when the signed Request Object was obtained by the Wallet Instance. +* **200 OK**. The Wallet Instance has provided the presentation to the Relying Party's **response_uri** endpoint and the User authentication is successful. The Relying Party updates the session cookie allowing the user-agent to access to the protected resource. An URL is provided carrying the location where the user-agent is intended to navigate. +* **401 Unauthorized**. The Wallet Instance or its User have rejected the request, or the request is expired. The QRCode page SHOULD be updated with an error message. + +Below a non-normative example of the HTTP Request to this specialized endpoint, where the parameter ``id`` contains an opaque and random value: + +.. code:: + + GET /session-state?id=3be39b69-6ac1-41aa-921b-3e6c07ddcb03 + HTTP/1.1 + HOST: relying-party.example.org + + +Request Object Details +---------------------- + +Below a non-normative example of HTTP request made by the Wallet Instance to the Relying Party. + +.. code-block:: javascript + + GET /request_uri HTTP/1.1 + HOST: relying-party.example.org + + +Request URI Response +-------------------- + +The Relying Party issues the signed Request Object using the content type set to ``application/oauth-authz-req+jwt``, +where a non-normative example in the form of decoded header and payload is shown below: + +.. code-block:: text + + { + "alg": "ES256", + "typ": "JWT", + "kid": "9tjiCaivhWLVUJ3AxwGGz_9", + "trust_chain": [ + "MIICajCCAdOgAwIBAgIC...awz", + "MIICajCCAdOgAwIBAgIC...2w3", + "MIICajCCAdOgAwIBAgIC...sf2" + ] + } + . + { + "scope": "PersonIdentificationData WalletAttestation", + "client_id_scheme": "entity_id", + "client_id": "https://relying-party.example.org", + "response_mode": "direct_post.jwt", + "response_type": "vp_token", + "response_uri": "https://relying-party.example.org/response_uri", + "nonce": "2c128e4d-fc91-4cd3-86b8-18bdea0988cb", + "state": "3be39b69-6ac1-41aa-921b-3e6c07ddcb03", + "iss": "https://relying-party.example.org", + "iat": 1672418465, + "exp": 1672422065, + "request_uri_method": "post" + } + +The JWS header parameters are described below: + +.. list-table:: + :widths: 25 50 + :header-rows: 1 + + * - **Name** + - **Description** + * - **alg** + - Algorithm used to sign the JWT, according to [:rfc:`7516#section-4.1.1`]. It MUST be one of the supported algorithms in Section *Cryptographic Algorithms* and MUST NOT be set to ``none`` or to a symmetric algorithm (MAC) identifier. + * - **typ** + - Media Type of the JWT, as defined in [:rfc:`7519`]. + * - **kid** + - Key ID of the public key needed to verify the JWS signature, as defined in [:rfc:`7517`]. REQUIRED when ``trust_chain`` is used. + * - **trust_chain** + - Sequence of Entity Statements that composes the Trust Chain related to the Relying Party, as defined in `OID-FED`_ Section *3.2.1. Trust Chain Header Parameter*. + + +The JWS payload parameters are described herein: + +.. list-table:: + :widths: 25 50 + :header-rows: 1 + + * - **Name** + - **Description** + * - **scope** + - Aliases for well-defined Presentation Definitions IDs. It is used to identify which required Credentials and User attributes are requested by the Relying Party, according to the Section "Using scope Parameter to Request Verifiable Credential(s)" of [OID4VP]. + * - **client_id_scheme** + - String identifying the scheme of the value in the ``client_id``. It MUST be set to the value ``entity_id``. + * - **client_id** + - Unique Identifier of the Relying Party. + * - **response_mode** + - It MUST be set to ``direct_post.jwt``. + * - **response_type** + - It MUST be set to ``vp_token``. + * - **response_uri** + - The Response URI to which the Wallet Instance MUST send the Authorization Response using an HTTP request using the method POST. + * - **nonce** + - Fresh cryptographically random number with sufficient entropy, which length MUST be at least 32 digits. + * - **state** + - Unique identifier of the Authorization Request. + * - **iss** + - The entity that has issued the JWT. It will be populated with the Relying Party client id. + * - **iat** + - Unix Timestamp, representing the time at which the JWT was issued. + * - **exp** + - Unix Timestamp, representing the expiration time on or after which the JWT MUST NOT be valid anymore. + * - **request_uri_method** + - String determining the HTTP method to be used with the `request_uri` endpoint to provide the Wallet Instance metadata to the Relying Party. The value is case-insensitive and can be set to: `get` or `post`. The GET method, as defined in [@RFC9101], involves the Wallet Instance sending a GET request to retrieve a Request Object. The POST method involves the Wallet Instance requesting the creation of a new Request Object by sending an HTTP POST request, with its metadata, to the request URI of the Relying Party. + +.. warning:: + + Using the parameter ``scope`` requires that the Relying Party Metadata MUST contain the ``presentation_definition``, where a non-normative example of it is given below: + +.. literalinclude:: ../../examples/presentation-definition.json + :language: JSON + +.. note:: + + The following parameters, even if defined in [OID4VP], are not mentioned in the previous non-normative example, since their usage is conditional and may change in future release of this documentation. + + - ``presentation_definition``: JSON object according to `Presentation Exchange `_. This parameter MUST not be present when ``presentation_definition_uri`` or ``scope`` are present. + - ``presentation_definition_uri``: Not supported. String containing an HTTPS URL pointing to a resource where a Presentation Definition JSON object can be retrieved. This parameter MUST be present when ``presentation_definition`` parameter or a ``scope`` value representing a Presentation Definition is not present. + - ``client_metadata``: A JSON object containing the Relying Party metadata values. If the ``client_metadata`` parameter is present when ``client_id_scheme`` is ``entity_id``, the Wallet Instance MUST consider the client metadata obtained through the OpenID Federation Trust Chain. + + +Request URI Endpoint Errors +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the Relying Party encounters errors while issuing the Request Object from the ``request_uri`` endpoint, the following error responses are applicable: + +- **invalid_request**: The ``request_uri`` URL is missing in some part within its webpath or urlparams, therefore it does not point to a valid Request Object and then it cannot be retrieved. This error is returned when the Request Object is not well referenced in the ``request_uri``. + +- **server_error**: The server encountered an unexpected condition that prevented it from fulfilling the request. This error is returned when the Relying Party's server is unable to process the Request Object due to a server-side issue, such as a malfunction or maintenance. The Wallet Instance should advise the User to try again later. + +The following is an example of an error response from ``request_uri`` endpoint: + +.. code-block:: + + HTTP/1.1 400 Bad Request + Content-Type: application/json + + { + "error": "invalid_request", + "error_description": "The request_uri is malformed or does not point to a valid Request Object." + } + + +Another example: + +.. code-block:: + + HTTP/1.1 500 Internal Server Error + Content-Type: application/json + + { + "error": "server_error", + "error_description": "The request_uri cannot be retrieved due to an internal server error." + } + +There are cases where the Wallet Instance cannot validate the Request Object or the Request Object results invalid. This error occurs if the Request Object is successfully fetched from the ``request_uri`` but fails validation checks by the Wallet Instance. This could be due to incorrect signatures, malformed claims, or other validation failures, such as the revocation of its issuer (Relying Party). + +Upon receiving an error response, the Wallet Instance SHOULD inform the User of the error condition in an appropriate manner. Additionally, the Wallet Instance SHOULD log the error and MAY attempt to recover from certain errors if feasible. For example, if the error is ``server_error``, the Wallet Instance MAY prompt the User to re-enter or scan a new QR code, if applicable. + +It is crucial for Wallet Instances to implement robust error handling to maintain a secure and user-friendly experience. Adhering to the specified error responses ensures interoperability and helps in diagnosing issues during the interaction with the Relying Party's endpoints. + +.. warning:: + + The current OpenID4VP specification outlines various error responses that a Wallet Instance may return to the Relying Party (Verifier) in case of faulty requests (OpenID4VP, Section 6.4. Error Response). For privacy enhancement, Wallet Instances SHOULD NOT notify the Relying Party of faulty requests in certain scenarios. This is to prevent any potential misuse of error responses that could lead to gather informations that could be exploited. + + +Authorization Response Details +------------------------------ + +After getting the User authorization and consent for the presentation of the Credentials, the Wallet Instance sends the Authorization Response to the Relying Party ``response_uri`` endpoint, the content SHOULD be encrypted according `OpenID4VP`_ Section 6.3, using the Relying Party public key. + +.. note:: + **Why the response is encrypted?** + + The response sent from the Wallet Instance to the Relying Party is encrypted to prevent a malicious agent from gaining access to the plaintext information transmitted within the Relying Party's network. This is only possible if the network environment of the Relying Party employs `TLS termination `_. Such technique employs a termination proxy that acts as an intermediary between the client and the webserver and handles all TLS-related operations. In this manner, the proxy deciphers the transmission's content and either forwards it in plaintext or by negotiates an internal TLS session with the actual webserver's intended target. In the first scenario, any malicious actor within the network segment could intercept the transmitted data and obtain sensitive information, such as an unencrypted response, by sniffing the transmitted data. + +Below a non-normative example of the request: + +.. code-block:: http + + POST /response_uri HTTP/1.1 + HOST: relying-party.example.org + Content-Type: application/x-www-form-urlencoded + + response=eyJhbGciOiJFUzI1NiIs...9t2LQ + + +Below is a non-normative example of the decrypted payload of the JWT contained in the ``response``, before base64url encoding: + +.. code-block:: + + { + "state": "3be39b69-6ac1-41aa-921b-3e6c07ddcb03", + "vp_token": [ + "eyJhbGciOiJFUzI1NiIs...PT0iXX0", + $WalletAttestation-JWT + ], + "presentation_submission": { + "definition_id": "32f54163-7166-48f1-93d8-ff217bdb0653", + "id": "04a98be3-7fb0-4cf5-af9a-31579c8b0e7d", + "descriptor_map": [ + { + "id": "PersonIdentificationData", + "path": "$.vp_token[0]", + "format": "vc+sd-jwt" + }, + { + "id": "WalletAttestation", + "path": "$.vp_token[1]", + "format": "wallet-attestation+jwt" + } + ] + } + } + +Where the following parameters are used: + +.. list-table:: + :widths: 25 50 + :header-rows: 1 + + * - **Name** + - **Description** + * - **vp_token** + - JSON Array containing the Verifiable Presentation(s). There MUST be at least two signed presentations in this Array: + + - The requested Digital Credential (one or more, in format of SD-JWT VC) + - The Wallet Attestation + * - **presentation_submission** + - JSON Object containing the mappings between the requested Verifiable Credentials and where to find them within the returned Verifiable Presentation Token, according to the `Presentation Exchange `_. This is expressed via elements in the ``descriptor_map`` array (Input Descriptor Mapping Objects) that contain a field called ``path``, which MUST have the value $ (top level root path) when only one Verifiable Presentation is contained in the VP Token, and MUST have the value $[n] (indexed path from root) when there are multiple Verifiable Presentations, where ``n`` is the index to select. The Relying Party receiving the `presentation_submission` descriptor therefore is able to use the correct method to decode each credential data format provided within the ``vp_token``. + * - **state** + - Unique identifier provided by the Relying Party within the Authorization Request. + + +The items contained in the ``vp_token`` array are Verifiable Presentations of Credentials. + + +SD-JWT Presentation +------------------- + +SD-JWT defines how an Holder can present a Credential to a Verifier proving the legitimate possession +of the Credential. For doing this the Holder MUST include the ``KB-JWT`` in the SD-JWT, +by appending the ``KB-JWT`` at the end of the of the SD-JWT, as represented in the example below: + +.. code-block:: + + ~~~...~~ + +To validate the signature on the Key Binding JWT, the Verifier MUST use the key material included in the Issuer-Signed-JWT. +The Key Binding JWT (KB-JWT) signature validation MUST use the public key included in the SD-JWT, +using the ``cnf`` parameter contained in the Issuer-Signed-JWT. + +When an SD-JWT is presented, its KB-JWT MUST contain the following parameters in the JWS header: + +.. list-table:: + :widths: 25 50 + :header-rows: 1 + + * - **Claim** + - **Description** + * - **typ** + - REQUIRED. MUST be ``kb+jwt``, which explicitly types the Key Binding JWT as recommended in Section 3.11 of [RFC8725]. + * - **alg** + - REQUIRED. Signature Algorithm using one of the specified in the section Cryptographic Algorithms. + + +When an SD-JWT is presented, its KB-JWT MUST contain the following parameters in the JWS payload: + +.. list-table:: + :widths: 25 50 + :header-rows: 1 + + * - **Claim** + - **Description** + * - **iat** + - REQUIRED. The value of this claim MUST be the time at which the Key Binding JWT was issued, using the syntax defined in [RFC7519]. + * - **aud** + - REQUIRED. The intended receiver of the Key Binding JWT. The value of this parameter MUST match the Relying Party unique entity identifier. + * - **nonce** + - REQUIRED. Ensures the freshness of the signature. The value type of this claim MUST be a string. The value MUST match with the one provided in the request object. + * - **sd_hash** + - REQUIRED. The base64url-encoded hash digest over the Issuer-signed JWT and the selected disclosures. + + +Revocation Checks +~~~~~~~~~~~~~~~~~ + +The revocation mechanisms that the Relying Parties MUST implement are defined in the section (:ref:`Revocations `). + +In the context of Digital Credential evaluation, any Relying Parties (RPs) establishes internal policies that define the meaning and value of presented Credentials. This is particularly important in scenarios where a Credential may be suspended but still holds value for certain purposes. For example, a suspended mobile driving license might still be valid for verifying the age of the holder. + +The process begins with the RP requesting specific Credentials from the Holder. This request should align with the Relying Party's requirements and the context in which the Credentials will be used. The Holder then responds by releasing the requested Credentials. + +Upon receiving the Credentials, the Relying Party evaluates their validity and value based on its internal policies. This evaluation considers the current status of the Credential (e.g., active, suspended, revoked) and the specific use case for which the Credential is being presented. + +Relying Parties should develop comprehensive internal policies that outline how different types of Credentials are to be evaluated. These policies should address scenarios where a Credential may be partially valid or have limited applicability. Flexibility in evaluation processes is important to accommodate various use cases. For instance, a Credential that is suspended for driving purposes might still be acceptable for age verification. + + +Authorization Response Errors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the Wallet sends a response using ``direct_post.jwt`` to the Relying Party, several errors may occur, including: + + - **Invalid Credential**: This error occurs when one or more Credentials or VPs, included in the ``vp_token``, fail validation because they are malformed. The correct HTTP status code for this error is 400 (Bad Request). The error should be set to ``invalid_request``, and the ``error_description`` SHOULD identify the malformed Credentials. + - **Issuer Credential Trust Failure**: This error arises when the Relying Party cannot establish trust with the issuer of a presented Credential, included in the ``vp_token``. The appropriate HTTP status code for this error is 403 (Forbidden). The ``error`` should be labeled as ``invalid_request``, and the ``error_description`` SHOULD specify the issuer for which trust could not be established. + - **Invalid Nonce**: This error happens when the nonce provided in the request is incorrect. The HTTP status code for this error should be 403 (Forbidden). The error SHOULD be labeled as ``invalid_request``, with an ``error_description`` indicating that the nonce is incorrect. + - **Invalid Wallet Attestation**: This error occours when it's not possible to establish trust with the Wallet Attestation's issuer (Wallet Provider), or if the Wallet Attestation is invalid or does not meet the Relying Party's minimum security criteria. The correct HTTP status code for this error is 403 (Forbidden). The ``error`` SHOULD be marked as ``invalid_request``, and the ``error_description`` should clarify that the issue stems from the Wallet Attestation's failure to establish trust with its issuer or its non-compliance with required security standards. + - **Invalid Presentation Submission**: This error occurs when the presentation submission is not valid. The appropriate HTTP status code for this error is 400 Bad Request. The ``error`` should be labeled as ``invalid_request``, and the ``error_description`` should specify the invalid aspects of the presentation submission. + + To enhance clarity and ensure proper error handling, it's crucial to provide detailed error responses. Below are two examples of HTTP responses using ``application/json`` that include both the ``error`` and ``error_description`` members: + +.. code-block:: text + + HTTP/1.1 403 Forbidden + Content-Type: application/json + + { + "error": "invalid_request", + "error_description": "Trust cannot be established with the issuer: https://issuer.example.com" + } + + +.. code-block:: text + + HTTP/1.1 400 Bad Request + Content-Type: application/json + + { + "error": "invalid_request", + "error_description": "The following Credentials/VP are malformed: [CredentialX, vp_token[2]]" + } + +Redirect URI +------------ + +When the Relying Party provides the redirect URI, the Wallet Instance MUST send the user-agent to this redirect URI. The redirect URI allows the Relying Party to continue the interaction with the End-User on the device where the Wallet Instance resides after the Wallet Instance has sent the Authorization Response to the response URI. + +The Relying Party MUST include a response code within the redirect URI. The response code is a fresh, cryptographically random number used to ensure only the receiver of the redirect can fetch and process the Authorization Response. The number could be added as a path component, as a parameter or as a fragment to the URL. It is RECOMMENDED to use a cryptographic random value of 128 bits or more at the time of the writing of this specification. + +The following is a non-normative example of the response from the Relying Party to the Wallet Instance upon receiving the Authorization Response at the Response Endpoint. + + +.. code-block:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "redirect_uri": "https://relying-party.example.org/cb?response_code=091535f699ea575c7937fa5f0f454aee" + } + +The ``redirect_uri`` value MUST be used with an HTTP method GET by either the Wallet Instance or the user-agent to redirect the User to the Relying Party in order to complete the process. The value can be added as a path component, as a fragment or as a parameter to the URL according to Section 6.2 of `OpenID4VP`_. The specific entity that performs this action depends on whether the flow is Same device or Cross device. + +Redirect URI Errors +------------------- + +When the Wallet Instance sends the user-agent to the Redirect URI provided by the Relying Party, several errors may occur that prevent the successful completion of the process. These errors are critical as they directly impact the User experience by hindering the seamless flow of information between the Wallet Instance and the Relying Party. Below are potential errors related to the Redirect URI and their implications: + +- **Mismatched Redirect URI**: This error occurs when the Redirect URI provided by the Relying Party does not match any of the URIs linked with the User session. This mismatch can lead to a HTTP status error code set to 403 (Forbidden), indicating that the request cannot be processed due session/URI mismatch. + +- **Redirect URI Security Issues**: If the Relying Party incurs in security issues when evaluating the User session with the provided URI, the Relying Party MUST raise an error. In such cases, an HTTP status code set to 403 (Forbidden) MUST be returned, indicating that the request is valid but the server is refusing action due to security precautions. + +Handling these errors requires clear communication to the User within the returned navigation web page. It is crucial for the Relying Party to implement robust error handling and validation mechanisms for Redirect URIs to ensure a secure implementation. + + diff --git a/refs/pull/443/merge/en/_sources/revocation-lists.rst.txt b/refs/pull/443/merge/en/_sources/revocation-lists.rst.txt new file mode 100644 index 000000000..e8f40a0b1 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/revocation-lists.rst.txt @@ -0,0 +1,747 @@ +.. include:: ../common/common_definitions.rst + +.. _sec_revocation_intro: + +Credential Lifecycle +++++++++++++++++++++ + +The value of a Digital Credential is conditional on its validity. A Credential that has been revoked, due to legal requirements, inaccuracy or compromise, is valueless and potentially harmful. +For these reasons a robust mechanism for managing the life-cycle and the revocation of a Digital Credential is required. + +This section outlines the key technical requirements and processes related to the revocation of Digital Credentials. +Furthermore, it provides the technical details that the Verifiers MUST implement to verify, in a secure and reliable manner, the validity of a Digital Credential during the presentation phase. + +The verification of the validity of a Digital Credential is based on the `OAUTH-STATUS-ASSERTION`_. + +A Status Assertion is a signed document serving as proof of a Digital Credential's current validity status. The Credential Issuer provides these assertions to Holders who can present them to Verifiers together with the corresponding Digital Credentials. + +The Status Assertions have the following features: + +- automated issuance, as the User authentication is not required for the provisioning of the Status Assertion; +- verification of the Digital Credential validity status in both online and offline scenarios; +- privacy-preserving, according to the following evidences: + + 1. the Verifier can check the validity of the Credential during the presentation phase. It is not able to check the validity of a given Digital Credential related to the User over time and out of the scope of the User authentication; + 2. the Credential Issuers is not able to know to which Verifier the Digital Credential or the Status Assertion will be presented; + 3. it doesn't reveal any information about the Users or the content of their Digital Credentials. + +.. _sec_revocation_assumption: + +Operational Requirements +------------------------ + +- **Internet Connection for Status Assertions**: Status Assertions can be obtained only when the Wallet Instance is connected to the internet and actively operated by the User. +- **Role of a Credential Issuer**: A Credential Issuer is responsible for creating and issuing Credentials, as well as managing their lifecycle and validity status. +- **Involvement of Authentic Sources**: When one or more Authentic Sources are involved in the issuance of a Digital Credential, the information exchanged between the Authentic Source and the Credential Issuer is crucial for the Digital Credential's issuance. Furthermore, in cases where the Authentic Source initiates a revocation or data changes, revoking the Digital Credential becomes necessary. + + +.. _sec_revocation_requirements: + +Functional Requirements +----------------------- + +In addition to the requirements in Section 5 of `OAUTH-STATUS-ASSERTION`_, **The Status Assertion:** + +- MUST have a validity period not greater than 24 hours; +- MUST NOT reveal any information about the Relying Party, the User's device or the User's data contained in the Digital Credential the assertion is related to; +- MUST be non-repudiable even beyond its expiration time and even in the case of cryptographic keys rotation. + + +**The Credential Issuer MUST:** + +- ensure that the data contained in a Digital Credential is kept up to date, including the status of validity of the data from the Authentic Source; +- revoke a Digital Credential when the following circumstances occur: + + - the Digital Credential requires to be updated, whenever one or more attributes are changed; in this case the User will request a new issuance for that Digital Credential; + - the Holder needs to address the loss or compromise of cryptographic key material associated with the issued Digital Credential. In such case, the End-User should request the revocation of the Digital Credential through a service provided by the Credential Issuer and using an authentication method that offers the same Level of Assurance obtained during the Credential Issuance; + - the User deletes the Digital Credential from the Wallet Instance. The Wallet Instance therefore should request the revocation of such Digital Credential to the Credential Issuer; + +- provide a web service for allowing a Wallet Instance, with a proof of possession of a specific Digital Credential, to + + - request a revocation of that Digital Credential; + - obtain a related Status Assertion; + +- provide out-of-band mechanisms through which the User can request the revocation of their Digital Credentials, using a robust procedure for identity proofing and User authentication, in particular when the User is unable to use the personal Wallet Instance. + + +**The Wallet Instance MUST:** + +- check periodically the validity status of the Digital Credential that is stored in it, requesting a Status Assertion for each Digital Credential; +- be able to present a Status Assertion if required by a Verifier, along with the corresponding Digital Credential; +- request a revocation of a Digital Credential when the Users delete it from the storage. + + +**The Authentic Sources MUST:** + +- provide web services for the providing of updated User data and the validity status; +- store in local databases only the minimum information required to provide the Credential Issuer with the User data or a change in the validity status. + + +Revocation Use Cases +-------------------- + +The revocation of a Digital Credential MAY be triggered by: + +- Users using their personal Wallet Instance or by some out-of-band touchpoints. +- Revocation of the Wallet Instance. +- Authentic Sources (e.g., for attribute updates) following administrative purposes. +- Law-Enforcing Bodies for the fulfillment of their functions and any other judicial reasons (e.g., Police). + +Credential Revocation Flows can start under different scenarios, such as: + + - The User reports the loss or theft of their own physical document to the Law-Enforcement Authorities: this implies that the Credentials, if any, shall be revoked. + - The User notifies an Authentic Source that one or more attributes are changed (e.g. the current resident address): in this case the Credentials MUST be revoked, as they are no longer valid due to the change in attributes. + - Users who lose access to their Wallet Instance (e.g., due to theft or loss of the device) can request the Credential Issuer to revoke their Credentials or ask the Wallet Provider to revoke the Wallet Instance. If the Wallet Provider is authorized by the User and is aware of the types of Credentials and their issuers stored in the Wallet, it can then initiate the revocation of all Digital Credentials contained within the Wallet Instance on behalf of the User. + - The Law-Enforcing Authorities, for the fulfillment of their functions and any other judicial reasons, may request the Authentic Source to revoke entitlements, licenses, certificates, identification documents, etc., which in turn leads to the revocation of any linked Credentials. + - The Authentic Sources that for any update of one or more User attributes, SHOULD inform the Credential Issuer that has previously requested those data for the issuance of a Credential about that User. + - The Credential Issuers, for technical security reasons (e.g. in the case of compromised cryptographic keys), SHOULD decide to revoke the Credentials. + + +The revocation scenarios involve two main flows: + + - The **Revocation flows**: these flows describe how an Entity requests for a Digital Credential revocation. + - The **Status Assertion flows**: these flows define the technical protocols for requesting and obtaining a Status Assertion and how the Wallet Instance SHOULD provide it to a Verifier as a proof of validity of a corresponding Digital Credential. + + +.. _sec_revocation_high_level_flow: + +Revocation Flows +---------------- + +Depending on the different scenarios that may involve the revocation of a Digital Credential, different processes and technical flows may be implemented, according to national laws or Regulations of specific domains. +The subsequent sections define the protocol interface between the Wallet Instances and the Credential Issuers during the revocation request. The communication between the Credential Issuers and other Entities is out-of-scope of this technical implementation profile. + + +.. _sec_revocation_wi_initiated_flow: + +Revocation Request by Wallet Instance +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A Wallet Instance MUST request the revocation of a Digital Credential as defined below. + +.. _fig_Low-Level-Flow-Revocation: +.. figure:: ../../images/Low-Level-Flow-Revocation.svg + :figwidth: 100% + :align: center + :target: https://www.plantuml.com/plantuml/svg/LOz1IyKm383l_HNXuK4FubrG7dXwNbxHuIw2n2rYM9VK9dL_tpBHCUYb-RwFaACv5gzp2bXTfSxlL49k8nuuepWSUao974xIJ1de06YmyDuvcLKgA-8G5eRhU-1RYEVd3cuAVUj4KEYhaldbK6WaSSRqbZNVNJpy_wF6nxwx2k6lVy748pg1Vn9itgl4ele1xKKr8pDMsQgdtttxPiMDBwjWMSK8pbCuaepj-Xy0 + + Wallet Instance Initiated Revocation Flow + +**Step 1 (Credential Revocation Request)**: The Wallet Instance initiates the process by creating a Credential Revocation Request. This request MUST be sent to the Credential Issuer who has previously issued that Credential. The Credential Revocation Request MUST contain a JSON object with the member `revocation_requests`. + +The `revocation_requests` MUST be set with an array of strings, where each string within the array represents a Credential Revocation Request object, enabling the Wallet Instance to request multiple Credential Revocation Requests to a single Credential Issuer. + +The request MUST be signed with the private key related to the public key contained within the Credential (such as the Credential Issuer Signed JWT in the case of SD-JWT, or the MSO in the case of Mdoc CBOR). Then, the Wallet Instance sends the request to the Credential Issuer as in the following non-normative example representing a Revocation Assertion Request array. + +.. _credential_revocation_request_ex: +.. code-block:: + + POST /revoke HTTP/1.1 + Host: pid-provider.example.org + Content-Type: application/json + + revocation_requests : ["${base64url(json({typ: revocation-assertion+jwt, ...}))}.payload.signature", ... ] + + +Below, is given a non-normative example of a single Revocation Assertion Request object with decoded JWT headers and payload and without signature for better readability: + +.. _credential_pop_jwt_ex: +.. code-block:: + + { + "alg": "ES256", + "typ": "credential-revocation-request+jwt", + "kid": $CREDENTIAL-CNF-JWKID + } + . + { + "iss": "0b434530-e151-4c40-98b7-74c75a5ef760", + "aud": "https://pid-provider.example.org", + "iat": 1698744039, + "exp": 1698744139, + "jti": "6f204f7e-e453-4dfd-814e-9d155319408c", + "credential_hash": $Issuer-Signed-JWT-Hash, + "credential_hash_alg": "sha-256" + } + +**Step 2 (Revocation Assertion Request verification)**: The Credential Issuer verifies the proof of possession of the Credential requested to be revoked, using the the confirmation method that was attested in the Credential. If the verification is successful the revocation request is allowed. + +**Step 3 (Credential Revocation)**: The Credential Issuer revokes the Credential provided in the Revocation Request object. After the revocation, the Credential Issuer MAY also send a notification to the User (e.g. using a User's email address, telephone number, or any other verified and secure communication channel), with all needed information related to the Credential revocation status update. This communication is out of scope of the current technical implementation profile. + +**Step 4 (Credential Revocation Response)**: The Credential Issuer sends a response back to the Wallet Instance with the result of the revocation request. + +.. code:: + + .. code-block:: http + HTTP/1.1 200 Ok + Content-Type: application/json + + { + "revocation_assertion_responses": ["${base64url(json({typ: revocation_assertion+jwt, ...}))}.payload.signature", ... ] + } + +Credential Revocation HTTP Request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The requests to the *Credential Issuer Revocation endpoint* MUST be HTTP with method POST, using the mandatory parameters listed below within the HTTP request message body. These MUST be encoded in ``application/json`` format. + +.. _table_revocation_request_params: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **revocation_requests** + - It MUST be an array of strings, where each represents a Revocation Assertion Request object. Each element MUST contain a signed JWT as a cryptographic proof of possession to which the Digital Credential to be revoked shall be bound. See Section :ref:`Credential Proof of Possession ` for more details. + - `OAUTH-STATUS-ASSERTION`_ . + +The Revocation Endpoint MUST be provided by the Credential Issuer within its Metadata. + + +Credential Revocation HTTP Response +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In case of succesfully Revocation Request validation, the *Credential Issuer* MUST return an HTTP response with the status code set to 200. If the *Credential Issuer* is able to provide a valid Status Assertion for a requested Credential, the response MUST contains a revocation Assertion object within a JSON Array. Otherwise, a Revocation Assertion Errors related to that Credential MUST be included in the Response JSON Array as an entry. + +If the Revocation Request fails (e.g. invalid request, server unavailability, etc.), an HTTP Error Status Code MUST be provided within the Revocation Response. + +In the following table are listed HTTP Status Codes that MUST be supported: + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - **Status Code** + - **Body** + - **Description** + * - *200 Created* + - Revocation Assertion Response + - The Revocation Assertion Response has been successfully created. + * - *400 Bad Request* + - Error code and description + - The Credential Issuer cannot fulfill the request because of invalid parameters. + * - *500 Internal Server Error* + - + - The Credential Issuer encountered an internal problem. (:rfc:`6749#section-5.2`). + * - *503 Service Unavailable* + - + - The Credential Issuer is temporary unavailable. (:rfc:`6749#section-5.2`). + +The response MUST: + +- include a JSON object with a member named `revocation_assertion_responses`; + +- be encoded in ``application/json`` format. + + +The ``revocation_assertion_responses`` object MUST contain the following mandatory claims. + +.. _table_http_response_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **revocation_assertion_responses** + - the Revocation Assertions and or the Revocation Assertion Errors related to the request made by the Wallet Instance. + - `OAUTH-STATUS-ASSERTION`_. + +The Revocation Assertion object MUST contain the parameter ``credential_status_validity`` with the value set to ``false``. +Below a non-normative example of a Revocation Assertion object in JWT format, with the headers and payload represented in JSON and without applying the signature. + +.. code:: + + { + "alg": "ES256", + "typ": "revocation-assertion+jwt", + "kid": "Issuer-JWK-KID" + } + . + { + "iss": "https://issuer.example.org", + "jti": "6f204f7e-e453-4dfd-814e-9d155319408c" + "credential_hash": $CREDENTIAL-HASH, + "credential_hash_alg": "sha-256", + "credential_status_validity": false, + "cnf": { + "jwk": { + "kty": "EC", + "crv": "P-256", + "x": "_2ySUmWFjwmraNlo15r6dIBXerVdy_NpJuwAKJMFdoc", + "y": "MV3C88MhhEMba6oyMBWuGeB3dKHP4YADJmGyJwwILsk" + } + } + } + +The Revocation Assertion Error object MUST contain the following parameters: + + - *error*. The error code, as registerd in the table below; + - *error_description*. Text in human-readable form providing further details to clarify the nature of the error encountered. + +Errors are meant to provide additional information about the failure so that the User can be informed and take the appropriate action. +The `error` parameter for the Revocation Assertion Error object MUST be set with one of the values defined in the table below, in addition to the values specified in :rfc:`6749#section-5.2`: + + +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - **Error Code** + - **Description** + * - ``invalid_request`` + - The request is not valid due to the lack or incorrectness of one or more parameters. (:rfc:`6749#section-5.2`). + * - ``credential_already_revoked`` + - The Digital Credential is already revoked. + * - ``credential_updated`` + - One or more information contained in the Digital Credential are changed. The `error_description` field SHOULD contain a human-readable text describing the general parameters updated without specifying each one. + * - ``credential_invalid`` + - The Digital Credential is invalid. The `error_description` field SHOULD contain the reason of invalidation. + * - ``invalid_request_signature`` + - The Revocation Assertion Request signature validation has failed. This error type is used when the proof of possession of the Digital Credential is found not valid within the Revocation Assertion Request. + * - ``credential_not_found`` + - The `credential_hash` value provided in the Revocation Assertion Request doesn't match with any active Digital Credential. + * - ``unsupported_hash_alg`` + - The hash algorithm set in `credential_hash_alg` is not supported. + +Below a non-normative example of a Revocation Assertion Error object in JWT format, with the headers and payload represented in JSON and without applying the signature. + +.. code:: + + { + "alg": "ES256", + "typ": "revocation-assertion-error+jwt", + "kid": "Issuer-JWK-KID" + } + . + { + "iss": "https://issuer.example.org", + "jti": "6f204f7e-e453-4dfd-814e-9d155319408c" + "credential_hash": $CREDENTIAL-HASH, + "credential_hash_alg": "sha-256", + "error": "unsupported_hash_alg", + "error_description": "The hash algorithm is not supported" + } + + +Status Assertion Flows +------------------------ + +The Status Assertion process is divided into the following phases: + + 1. The Status Assertion Request by a Wallet Instance: it involves the Wallet Instance and the Credential Issuer. + 2. The Status Assertion Presentation to a Verifier: it involves the Wallet Instance and the Verifier. + + +.. figure:: ../../images/High-Level-Flow-Status-Attestation.svg + :figwidth: 100% + :align: center + + High-Level Status Assertion Flows + + +.. _sec_revocation_status_assertion_request: + +Status Assertion Request by Wallet Instance +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The presentation of a Credential to a Verifier may occur long after it has been issued by the Credential Issuer. During this time interval, the Credential can be invalidated for any reason and therefore the Verifier also needs to verify its revocation or suspension status. To address this scenario, the Credential Issuer provides the Wallet Instance with a *Status Assertion*. This Assertion is bound to a Credential so that the Wallet Instance can present it to a Verifier, along with the Credential itself, as proof of non-revocation status of the Credential. + +The following diagram shows how the Wallet Instance requests a Status Assertion to the Credential Issuer. + +.. _fig_Low-Level-Flow-Status-Assertion: +.. figure:: ../../images/Low-Level-Flow-Revocation-Attestation.svg + :figwidth: 100% + :align: center + :target: https://www.plantuml.com/plantuml/svg/NP31Rk9038RlynGMsWD8mDwHTWM22tlOHWML2r8rIHmoQZ9EnnuGRryFeK0vsl_tErzcpcA3nBOnDWhvsEOOJAShLxZEUe71pZOD2gozahx00LY6a_l9h9aZXalqb2oYrEXrXWt5SArRDkRaOF8Nt0oobyqMVkjnYGm1FoEo38k0PQhPvhsZxi-lvMtEAFktsuwC-Uw_sSQLLX3k32W4IXdZIGCwOW0tjZo3ROtGomBbOfrdg0Are9Bmh0fxdzQnIzTBi2B1vL5G_NrvQHpJfvsSeRVN0bKfIFS2nKEj952K2LMJF9LQB6hh7RTZPOSuFKoLJE3bNBRwlu95jcRWCmks8xZ_vRB6uWCg2WyUUz-x9P-RoqCbO0etoKtPXGWcJqU-Vnlb53mf-OhSaMVKGUfh0PxvEVeojiqN + + Status Assertion Request Flow + +**Step 1 (Status Assertion Request)**: The Wallet Instance sends the Status Assertion Request to the Credential Issuer, where: + +- The request MUST contain the base64url encoded hash value of the Digital Credential, for which the Status Assertion is requested, and enveloped in a signed Status Assertion Request object. + +- The Status Assertion Request object MUST be signed with the private key corresponding to the confirmation claim assigned by the Issuer and contained within the Digital Credential. + +Below a non-normative example representing a Status Assertion Request array with a single Status Assertion Request object in JWT format. + +.. code:: + + POST /status HTTP/1.1 + Host: issuer.example.org + Content-Type: application/json + + { + "status_assertion_requests" : ["${base64url(json({typ: status-assertion+jwt, ...}))}.payload.signature", ... ] + } + +The Status Assertion HTTP request can be sent to a single Credential Issuer regarding multiple Digital Credentials, and MUST contain a JSON object with the member `status_assertion_requests`. +The `status_assertion_requests` MUST be set with an array of strings, where each string within the array represents a Digital Credential Status Assertion Request object. + +A non-normative example of Credential Proof of Possession is provided :ref:`in the previous section `. + +**Step 2 (Status Assertion Request verification)**: The Credential Issuer that receives the Status Assertion Request object MUST validate that the Wallet Instance making the request is authorized to request Status Assertions. Therefore the following requirements MUST be satisfied: + +- The Credential Issuer MUST verify the compliance of all elements in the `status_assertion_requests` object using the confirmation method contained within the Digital Credential where the Status Assertion Request object is referred to; + +- The Credential Issuer MUST verify that it is the legitimate Issuer of the Digital Credential to which each Status Assertion Request object refers. + +**Step 3 (Check for validity)**: The Credential Issuer checks that the User's attributes are not updated by the Authentic Source or that the latter has not revoked them. The technical mechanisms for obtaining this information are out-of-scope of this technical implementation profile. + +**Step 4 (Status Assertion Creation)**: The Credential Issuer creates the corresponding Status Assertion. When a Status Assertion is requested to a Credential Issuer, the Credential Issuer checks the status of the Digital Credential and creates a Status Assertion bound to it. If the Digital Credential is valid, the Credential Issuer creates a new Status Assertion, which a non-normative example is given below where the format is JWT. + +.. code:: + + { + "alg": "ES256", + "typ": "status-assertion+jwt", + "kid": $ISSUER-JWKID + } + . + { + "iss": "https://issuer.example.org", + "iat": 1504699136, + "exp": 1504785536, + "credential_hash": $CREDENTIAL-HASH, + "credential_hash_alg": "sha-256", + "credential_status_validity": true, + "cnf": { + "jwk": {...} + } + } + +**Step 4 (Status Assertion Response)**: The response MUST include a JSON object with a member named `status_assertion_responses`, which contains the Status Assertions and or the Status Assertion Errors related to the request made by the Wallet Instance, as in the following non-normative example. + +.. code:: + + HTTP/1.1 200 Created + Content-Type: application/json + + { + "status_assertion_responses": ["${base64url(json({typ: status-assertion+jwt, ...}))}.payload.signature", ... ] + } + +The member `status_assertion_responses` MUST be an array of strings, where each of them represent a Status Assertion Response object as defined in `OAUTH-STATUS-ASSERTION`_. + + +Status Assertion HTTP Request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The requests to the *Credential status endpoint* of the Credential Issuers MUST be HTTP with method POST, using the same mandatory parameters as in the :ref:`Table of Credential Request parameters `. These MUST be encoded in ``application/json`` format. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **status_assertion_requests** + - It MUST be an array of strings, where each of them represent a Status Assertion Request object. Each element MUST contain a signed JWT as a cryptographic proof of possession of the Digital Credential. See Section :ref:`Credential Proof of Possession ` for more details. + - `OAUTH-STATUS-ASSERTION`_ . + +The *typ* value in the *credential_pop* JWT MUST be set to **status-assertion+jwt** + +The *Credential status endpoint* MUST be provided by the Credential Issuers within their Metadata. The Credential Issuers MUST include in the issued Digital Credentials the object *status_assertion_requests* with the JSON member *status_assertion* set to a JSON Object containing the *credential_hash_alg* claim. It MUST contain the algorithm used for hashing the Digital Credential. Among the hash algorithms, the value ``sha-256`` is RECOMMENDED . + + +Status Assertion HTTP Response +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In case of succesfully Status Assertion Request validation, the *Credential Issuer* MUST return an HTTP response with the status code set to 200. If the *Credential Issuer* is able to provide a valid Status Assertion for a requested Credential, the response MUST contains a Status Assertion object within a JSON Array. Otherwise, a Status Assertion Errors related to that Credential MUST be included in the Response JSON Array as an entry. + +If the Status Request fails (e.g. invalid request, server unavailability, etc.), an HTTP Error Status Code MUST be provided within the Status Assertion Response. + +In the following table are listed HTTP Status Codes that MUST be supported: + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - **Status Code** + - **Body** + - **Description** + * - *200 Created* + - Status Assertion Response + - The Status Assertion Response has been successfully created and it has been returned. + * - *400 Bad Request* + - Error code and description + - The Credential Issuer cannot fulfill the request because of invalid parameters. + * - *500 Internal Server Error* + - + - The Credential Issuer encountered an internal problem. (:rfc:`6749#section-5.2`). + * - *503 Service Unavailable* + - + - The Credential Issuer is temporary unavailable. (:rfc:`6749#section-5.2`). + +The response MUST: + +- include a JSON object with a member named `status_assertion_responses`; + +- be encoded in ``application/json`` format. + +The status_assertion_responses object MUST contain the following mandatory claims. + +.. _table_http_status_assertion_response_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **status_assertion_responses** + - the Status Assertions and or the Status Assertion Errors related to the request made by the Wallet Instance. + - `OAUTH-STATUS-ASSERTION`_. + +The Status Assertion Error object MUST contain the following parameters: + + - *error*. The error code, as registerd in the table below; + - *error_description*. Text in human-readable form providing further details to clarify the nature of the error encountered. + +Errors are meant to provide additional information about the failure so that the User can be informed and take the appropriate action. +The `error` parameter for the Status Assertion Error object MUST be set with one of the values defined in the table below, in addition to the values specified in :rfc:`6749#section-5.2`: + +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - **Error Code** + - **Description** + * - ``invalid_request`` + - The request is not valid due to the lack or incorrectness of one or more parameters. (:rfc:`6749#section-5.2`). + * - ``credential_revoked`` + - The Digital Credential is revoked. The reason of revocation MUST be provided in the *error_description* field. + * - ``credential_updated`` + - One or more information contained in the Digital Credential are changed. The `error_description` field SHOULD contain a human-readable text describing the general parameters updated without specifying each one. + * - ``credential_invalid`` + - The Digital Credential is invalid. The `error_description` field SHOULD contain the reason of invalidation. + * - ``invalid_request_signature`` + - The Status Assertion Request signature validation has failed. This error type is used when the proof of possession of the Digital Credential is found not valid within the Status Assertion Request. + * - ``credential_not_found`` + - The `credential_hash` value provided in the Status Assertion Request doesn't match with any active Digital Credential. + * - ``unsupported_hash_alg`` + - The hash algorithm set in `credential_hash_alg` is not supported. + +Below a non-normative example of a Status Assertion Error object in JWT format, with the headers and payload represented in JSON and without applying the signature. + +.. code:: + + { + "alg": "ES256", + "typ": "status-assertion-error+jwt", + "kid": "Issuer-JWK-KID" + } + . + { + "iss": "https://issuer.example.org", + "jti": "6f204f7e-e453-4dfd-814e-9d155319408c" + "credential_hash": $CREDENTIAL-HASH, + "credential_hash_alg": "sha-256", + "error": "credential_revoked", + "error_description": "Credential is revoked." + } + + +.. _sec_revocation_nra_presentation: + +Status Assertion Presentation to the Verifiers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +During the presentation phase, a Verifier MAY request the Wallet Instance to provide a Non-Revocation Assertion along with the requested Credential. If a Verifier requests a Status Assertion for a requested Digital Credential, the Wallet Instance MUST provide the Status Assertions in the *vp_token* JSON array. If the Status Assertion is requested by the Verifier and the Wallet Instance is not able to provide it or it is expired or it is issued far back in time, the Verifier MAY decide to accept or reject the Credential according to its security policy. + +Law-Enforcement Authorities or Third Parties authorized by national law, MAY require deferred non-revocation status verification but the definition of these protocols is currently out-of-scope for this technical implementation profile. + + + +.. _sec_revocation_credential_pop: + +Credential Proof of Possession +------------------------------ + +The Credential Proof of Possession (**credential_pop**) MUST be a JWT that MUST contain the parameters (Header and Payload) in the following table. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Header** + - **Description** + - **Reference** + * - **typ** + - In case of revocation request it MUST be set to ``revocation-request+jwt``. In case of Status Assertion request it MUST be set to ``status-assertion-request+jwt``, according to `OAUTH-STATUS-ASSERTION`_ . + - :rfc:`7516#section-4.1.1`. + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section `Cryptographic Algorithms `_ and MUST NOT be set to ``none`` or any symmetric algorithm (MAC) identifier. + - :rfc:`7516#section-4.1.1`. + * - **kid** + - Unique identifier of the ``jwk`` or ``COSE_Key`` inside the ``cnf`` claim of the Credential to be revoked, as base64url-encoded JWK Thumbprint value, according to `OAUTH-STATUS-ASSERTION`_. + - :rfc:`7638#section_3`. + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Payload** + - **Description** + - **Reference** + * - **iss** + - Thumbprint of the JWK in the ``cnf`` parameter of the Wallet Assertion. + - :rfc:`9126` and :rfc:`7519`. + * - **aud** + - It MUST be set to the identifier of the Issuer. + - :rfc:`9126` and :rfc:`7519`. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT. It MUST be greater than the value set for `iat`. + - :rfc:`9126` and :rfc:`7519`. + * - **iat** + - UNIX Timestamp with the time of JWT issuance. + - :rfc:`9126` and :rfc:`7519`. + * - **jti** + - Unique identifier for the proof of possession JWT. The value SHOULD be set using a *UUID v4* value according to [:rfc:`4122`]. + - :rfc:`7519#section-4.1.7`. + * - **credential_hash** + - It MUST contain the hash value of a Digital Credential, derived by computing the base64url encoded hash of the Digital Credential. + - `OAUTH-STATUS-ASSERTION`_. + * - **credential_hash_alg** + - It MUST contain the Algorithm used for hashing the Digital Credential. The value SHOULD be set to `S256`. + - `OAUTH-STATUS-ASSERTION`_. + +Revocation Assertion +-------------------- + +When the JWT format is used, the Revocation Assertion MUST contain the following claims. + +.. _table_revocation_assertion_header: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Header** + - **Description** + - **Reference** + * - **alg** + - Algorithm used to verify the cryptographic signature of the Revocation Assertion. Revocation Assertion that do not need to be signed SHOULD set the `alg` value to `none` in according with `OAUTH-STATUS-ASSERTION`_. + - `[OIDC4VCI. Draft 13] `_, [:rfc:`7515`], [:rfc:`7517`]. + * - **typ** + - It MUST be set to `revocation-assertion-response+jwt` when JWT format is used. + - [:rfc:`7515`], [:rfc:`7517`], `OAUTH-STATUS-ASSERTION`_. + + +.. _table_revocation_assertion_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Payload** + - **Description** + - **Reference** + * - **iss** + - It MUST be set to the identifier of the Credential Issuer. + - :rfc:`9126` and :rfc:`7519`. + * - **jti** + - Unique identifier for the JWT. + - :rfc:`7519#section-4.1.7`. + * - **credential_status_validity** + - Boolean value indicating the absolute validity of the Credential linked to the Status Assertion. It MUST be set with the value `false`. + - `OAUTH-STATUS-ASSERTION`_. + + +Status Assertion +------------------ + +When the JWT format is used, the Status Assertion MUST contain the following claims. + +.. _table_non_revocation_assertion_header: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Header** + - **Description** + - **Reference** + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section :ref:`Cryptographic Algorithms ` and MUST NOT be set to ``none`` or to a symmetric algorithm (MAC) identifier. + - `[OIDC4VCI. Draft 13] `_, [:rfc:`7515`], [:rfc:`7517`]. + * - **typ** + - It MUST be set to `status-assertion-request+jwt` when JWT format is used. + - [:rfc:`7515`], [:rfc:`7517`], `[OAuth Status Attestation draft 01] `_.. + * - **kid** + - Unique identifier of the Credential Issuer ``jwk`` as base64url-encoded JWK Thumbprint value. + - :rfc:`7638#section_3`. + +.. _table_non_revocation_assertion_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Payload** + - **Description** + - **Reference** + * - **iss** + - It MUST be set to the identifier of the Credential Issuer. + - :rfc:`9126` and :rfc:`7519`. + * - **iat** + - UNIX Timestamp with the time of JWT issuance. + - :rfc:`9126` and :rfc:`7519`. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT. It MUST be greater than the value set for `iat`. + - :rfc:`9126` and :rfc:`7519`. + * - **credential_hash** + - Hash value of the Credential the Status Assertion is bound to. + - `OAUTH-STATUS-ASSERTION`_. + * - **credential_hash_alg** + - The Algorithm used for hashing the Credential to which the Status Assertion is bound. The value SHOULD be set to ``S256``. + - `OAUTH-STATUS-ASSERTION`_. + * - **credential_status_validity** + - Boolean value indicating the absolute validity of the Credential linked to the Status Assertion. It is REQUIRED and it MUST be set with the value "false" or "true". + - `OAUTH-STATUS-ASSERTION`_. + * - **cnf** + - JSON object containing confirmation methods. The sub-member contained within `cnf` member, such as `jwk` for JWT, MUST match with the one provided within the related Digital Credential. Other confirmation methods can be utilized when the referenced Digital Credential supports them, in accordance with the relevant standards. + - `[RFC7800, Section 3.1] `_ and `[RFC8747, Section 3.1] `_. + + +Error Assertion +------------------ + +When the JWT format is used, the Revocation or Status Assertion Error MUST contain the following claims. + +.. _table_non_revocation_assertion_error_header: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Header** + - **Description** + - **Reference** + * - **alg** + - Algorithm used to verify the cryptographic signature of the Assertion Error. Assertion Error that do not need to be signed SHOULD set the `alg` value to `none` in according with `OAUTH-STATUS-ASSERTION`_. + - `[OIDC4VCI. Draft 13] `_, [:rfc:`7515`], [:rfc:`7517`]. + * - **typ** + - It MUST be set to `status-assertion-response+jwt` or `revocation-assertion-response+jwt` when JWT format is used. + - [:rfc:`7515`], [:rfc:`7517`], `OAUTH-STATUS-ASSERTION`_ . + + +.. _table_non_revocation_assertion_error_claim: +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Payload** + - **Description** + - **Reference** + * - **iss** + - It MUST be set to the identifier of the Credential Issuer. + - :rfc:`9126` and :rfc:`7519`. + * - **jti** + - Unique identifier for the JWT. + - :rfc:`7519#section-4.1.7`. + * - **error** + - Status code returned from the Credential Issuer after revocation. The value SHOULD be assigned with one of the error types defined in {{RFC6749}}[Section 5.2] or defined in `OAUTH-STATUS-ASSERTION`_. + - `[RFC6749, Section 5.2] `_, `OAUTH-STATUS-ASSERTION`_ + * - **error_description** + - Text that clarifies the nature of the error, such as attribute changes, revocation reasons, in relation to the `error` value. + - `OAUTH-STATUS-ASSERTION`_. diff --git a/refs/pull/443/merge/en/_sources/ssi-introduction.rst.txt b/refs/pull/443/merge/en/_sources/ssi-introduction.rst.txt new file mode 100644 index 000000000..bceaff260 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/ssi-introduction.rst.txt @@ -0,0 +1,30 @@ +.. include:: ../common/common_definitions.rst + +.. _ssi-introduction.rst: + +The Digital Identity Wallet Paradigm +++++++++++++++++++++++++++++++++++++ + +The Digital Identity Wallet paradigm refers to a new architecture in Identity and Access Management (IAM) that improves the privacy and grants complete control and ownership over the personal data by their owner, the users. +Users possess their digital documents and determine to which actors they present these documents, with the ability to revoke the use of said documents, all while maintaining a history of their activities. + +The main difference between this new approach and the traditional IAM infrastructure is that during the presentation phase there are no intermediaries between the Wallet and the Relying Party, while in the SAML2 or OIDC based infrastructure an Identity Provider is always involved, knowing which services a citizen is accessing to. + +Self-Sovereign Identity (SSI) is also significant in the field of data exchange and data governance. This is relevant at both national and European levels, including the new eIDAS Regulation. In fact, it envisions a login option designed for European Users - be they citizens, public administrations, or companies - who want to access another Member State's services using their national authentication systems. + +The main roles in a Wallet ecosystem are are listed as follow: + + - Issuers: parties who can issue digital credentials about a person; + - Verifiers: parties who request Holders' digital credentials for authentication and authorization purposes; + - Holders: individuals who own a Wallet and have control over the digital credentials they can request, acquire, store, and present to verifiers; + - Verifiable Data Registries: Authorities that publish certificates, attestations, metadata, and schemes needed for allowing the trust establishment between the parties. + +In this model, the credential issuer (e.g., an educational institution) provides digital credentials to the user, who can store them in their digital Wallet. +The Wallet typically comes in the form of an application on the User's mobile phone. + +Other key elements that characterize an SSI system include: + + - **Privacy and control**: Wallets enable individuals to maintain control over their personal data. They can choose what information to release, to whom, and for what purpose; + - **Security**: Wallets leverage cryptographic mechanism to ensure the integrity and security of identity information. It avoids the risk of identity theft, fraud, and unauthorized access since the data remains under the individual's control; + - **Interoperability**: Wallets promote interoperability by enabling different systems and organizations to recognize and verify identities without relying on a central authority. This allows for seamless and trusted interactions between individuals, organizations, and even across borders; + - **Efficiency and cost reduction**: individuals can manage their own identities, eliminating the need for multiple identity credentials and repetitive identity verification processes. This can streamline administrative procedures, reduce costs, and enhance the user experience. diff --git a/refs/pull/443/merge/en/_sources/standards.rst.txt b/refs/pull/443/merge/en/_sources/standards.rst.txt new file mode 100644 index 000000000..2a2c017f8 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/standards.rst.txt @@ -0,0 +1 @@ +.. include:: ../common/standards.rst diff --git a/refs/pull/443/merge/en/_sources/trust.rst.txt b/refs/pull/443/merge/en/_sources/trust.rst.txt new file mode 100644 index 000000000..8fbb56354 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/trust.rst.txt @@ -0,0 +1,723 @@ +.. include:: ../common/common_definitions.rst + +.. _trust.rst: + +The Infrastructure of Trust ++++++++++++++++++++++++++++ + +The EUDI Wallet Architecture Reference Framework (`EIDAS-ARF`_) describes the Trust Model as a *"collection of rules that ensure the legitimacy of the components and the entities involved in the EUDI Wallet ecosystem"*. + +This section outlines the implementation of the Trust Model in an infrastructure that complies with OpenID Federation 1.0 `OID-FED`_. This infrastructure involves a RESTful API for distributing metadata, metadata policies, trust marks, public keys, X.509 certificates, and the revocation status of the participants, also called Federation Entities. + +The Infrastructure of trust facilitates the application of a trust assessment mechanism among the parties defined in the `EIDAS-ARF`_. + +.. figure:: ../../images/trust-roles.svg + :alt: federation portrait + :width: 100% + + The roles within the Federation, where the Trust Anchor oversees its subordinates, + which include one or more Intermediates and Leaves. In this + representation, both the Trust Anchor and the Intermediates assume the role of Registration Authority. + +Federation Roles +------------------ + +All the participants are Federation Entities that MUST be registered by an Registration Body, +except for Wallet Instances which are End-User's personal devices certified by their Wallet Provider. + +.. note:: + The Wallet Instance, as a personal device, is certified as reliable through a verifiable attestation issued and signed by a trusted third party. + + This is called *Wallet Attestation* and is documented in `the dedicated section `_. + + +Below the table with the summary of the Federation Entity roles, mapped on the corresponding EUDI Wallet roles, as defined in the `EIDAS-ARF`_. + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - EUDI Role + - Federation Role + - Notes + * - Public Key Infrastructure (PKI) + - Trust Anchor + - The Federation has PKI capabilities. The Entity that configures the entire infrastructure is the Trust Anchor. + * - Qualified Trust Service Provider (QTSP) + - Leaf + - + * - Person Identification Data Provider + - Leaf + - + * - Qualified Electronic Attestations of Attributes Provider + - Leaf + - + * - Electronic Attestations of Attributes Provider + - Leaf + - + * - Relying Party + - Leaf + - + * - Trust Service Provider (TSP) + - Leaf + - + * - Trusted List + - Trust Anchor + - The listing endpoint, the trust mark status endpoint, and the fetch endpoint must be exposed by both Trust Anchors and Intermediates, making the Trusted List distributed over multiple Federation Entities, where each of these is responsible for their registered subordinates. + * - Wallet Provider + - Leaf + - + + +General Properties +------------------ + +The architecture of the trust infrastructure based on OpenID Federation is built upon several core principles: + +.. list-table:: + :header-rows: 1 + + * - Identifier + - Property + - Description + * - P1 + - **Security** + - Incorporates mechanisms to ensure the integrity, confidentiality, and authenticity of the trust relationships and interactions within the federation. + * - P2 + - **Privacy** + - Designed to respect and protect the privacy of the entities and individuals involved, minimal disclosure is part of this. + * - P3 + - **Interoperability** + - Supports seamless interaction and trust establishment between diverse systems and entities within the federation. + * - P4 + - **Transitive Trust** + - Trust established indirectly through a chain of trusted relationships, enabling entities to trust each other based on common authorities and trusted intermediaries. + * - P5 + - **Delegation** + - Technical ability/feature to delegate authority or responsibilities to other entities, allowing for a distributed trust mechanism. + * - P6 + - **Scalability** + - Designed to efficiently manage an increasing number of entities or interactions without a significant increase in trust management complexity. + * - P7 + - **Flexibility** + - Adaptable to various operational and organizational needs, allowing entities to define and adjust their trust relationships and policies. + * - P8 + - **Autonomy** + - While part of a federated ecosystem, each entity retains control over its own definitions and configurations. + * - P9 + - **Decentralization** + - Unlike traditional centralized systems, the OpenID Federation model promotes a decentralized approach. This ensures that no single entity has control over the entire system, enhancing privacy and security for all participants. + +Trust Infrastructure Functional Requirements +---------------------------------------------- + +This section includes the requirements necessary for the successful implementation and operation of the infrastructure of trust. + +.. list-table:: Functional Requirements + :header-rows: 1 + + * - ID + - Description + * - FR1 + - **Federation Trust Establishment**: the system must be able to establish trust between different entities (Credential Issuers, Relying Parties, etc.) within a federation, using cryptographic signatures for secure information exchange about the participants in the ecosystem. + * - FR2 + - **Entity Authentication**: the system must implement mechanisms for authenticating entities within the federation, ensuring compliance with the shared rules. + * - FR3 + - **Signature Validation**: the system must support the creation, verification, and validation of electronic signatures and provide standard and secure mechanisms to obtain the public keys required for the signature validation. + * - FR4 + - **Time Stamping**: the signed artifacts must contain time stamps to ensure the integrity and non-repudiation of transactions over time, thanks to the interfaces, services, storage model and approaches defined within the federation. + * - FR5 + - **Certificate Validation**: the system requires confidential transmission, secured via TLS over HTTP, and validation of certificates for website authentication, ensuring they meet eIDAS criteria. + * - FR6 + - **Interoperability and Standards Compliance**: ensure interoperability between federation members by adhering to technical standards, facilitating cross-border electronic transactions. + * - FR7 + - **Data Protection and Privacy**: implement data protection measures in compliance with GDPR and eIDAS regulations, ensuring the privacy and security of personal data processed within the federation. + * - FR8 + - **User Consent and Control**: design mechanisms for obtaining and managing user consent, empowering users with control over their personal information. + * - FR9 + - **Audit and Logging**: the system must minimize data, anonymize if possible, define retention periods, secure access, and storage encryption. This protects privacy while enabling security and accountability. + * - FR10 + - **Dispute Resolution and Liability**: establish clear procedures for dispute resolution and define liability among federation members, in accordance with eIDAS provisions. + * - FR11 + - **Accessibility**: ensure that the system is accessible to all users, including those with disabilities, aligning with eIDAS and local accessibility standards. + * - FR12 + - **Emergency and Revocation Services**: implement mechanisms for the immediate revocation of electronic identification means and participants in case of security breaches or other emergencies. + * - FR13 + - **Scalable Trust Infrastructure**: the system must support scalable trust establishment mechanisms, leveraging approaches and technical solutions that complement delegation transitive approaches to efficiently manage trust relationships as the federation grows, removing central registries that might technically or administratively fail. + * - FR14 + - **Efficient Storage Scalability**: implement a storage solution that scales horizontally to accommodate increasing data volumes while minimizing central storage and administrative costs. The system should enable members to independently store and present historical trust attestations and signed artifacts during dispute resolutions, with the federation infrastructure maintaining only a registry of historical keys to validate the historical data, stored and provided by the participants. + * - FR15 + - **Verifiable Attestation (Trust Mark)**: incorporate a mechanism for issuing and verifying verifiable attestations that serve as proof of compliance with specific profiles or standards. This allows entities within the federation to demonstrate adherence to agreed-upon security, privacy, and operational standards. + * - FR16 + - **Dynamic Policy Language**: develop and implement a dynamic, extensible policy language that allows for the creation and modification of federation policies in response to evolving requirements, technological advancements, and regulatory changes. This policy language should support the specification of rules governing entity behavior, metadata handling, and trust validation within the federation. + * - FR17 + - **Automated Policy Enforcement**: the system must automatically enforce federation policies as defined by policy language and verifiable attestations, ensuring that all operations and transactions comply with current rules and standards. + * - FR18 + - **Decentralized Dispute Resolution Mechanism**: design a decentralized mechanism for dispute resolution that allows federation members to independently verify historical trust establishment and signed artifacts, reducing reliance on central authorities and streamlining the resolution process. + * - FR19 + - **Adaptive Load Management**: implement adaptive load management strategies to ensure the system remains responsive and efficient under varying loads, particularly during peak usage times or when processing complex tasks. + * - FR20 + - **Cross-Federation Interoperability**: ensure the system is capable of interoperating with other federations or trust frameworks, facilitating cross-federation transactions and trust establishment without compromising security or compliance. + * - FR21 + - **Future-Proof Cryptography**: the system should employ a flexible cryptographic framework that can be updated in response to new threats or advancements in cryptographic research, ensuring long-term security and integrity of federation operations. + * - FR22 + - **Autonomous Registration Bodies**: the system must facilitate the integration of autonomous registration bodies that operate in compliance with federation rules. These bodies are tasked with evaluating and registering entities within the federation, according to the pre-established rules and their compliance that must be periodically asserted. + * - FR23 + - **Compliance Evaluation for Federation Entity Candidates**: registration bodies must evaluate the compliance of candidate entities against federation standards before their registration in the federation. + * - FR24 + - **Periodic Auditing of Registration Bodies and Entities**: implement mechanisms for the periodic auditing and monitoring of the compliance status of both registration bodies and their registered entities. This ensures ongoing adherence to federation standards and policies. + * - FR25 + - **Certification of Compliance for Personal Devices**: trusted bodies, in the form of federation entities, should issue certifications of compliance and provide signed proof of such compliance for the hardware of personal devices used within the federation. These certifications should be attested and periodically renewed to ensure the devices meet current security standards. + * - FR26 + - **Certification of Compliance for Cryptographic Devices**: similar to personal devices, personal cryptographic devices used within the federation must also receive certifications of compliance and signed proof thereof from trusted bodies. These certifications should be subject to periodic renewal to reflect the latest security and compliance standards. + * - FR27 + - **Transparent Compliance Reporting**: develop a system for transparent reporting and publication of compliance statuses, audit results, and certification renewals for all federation entities. This transparency fosters trust within the federation and with external stakeholders. + * - FR28 + - **Automated Compliance Monitoring**: the system should include automated tools for monitoring the compliance of entities with federation standards. This automation aids in the early detection of potential compliance issues. + * - FR29 + - **Secure Protocol Capabilities Binding**: the secure protocol must enable the exchange of protocol-specific capabilities data as cryptographically-bound metadata attached to a specific identity. This metadata should define the technical capabilities associated with the identity, ensuring verifiable proof and tamper-proof association for robust trust establishment and access control. + + +Federation API endpoints +------------------------ + +OpenID Federation 1.0 uses RESTful Web Services secured over +HTTPs. OpenID Federation 1.0 defines which are the web endpoints that the participants MUST make +publicly available. The table below summarises the endpoints and their scopes. + +All the endpoints listed below are defined in the `OID-FED`_ specs. + +.. list-table:: + :widths: 20 20 20 20 + :header-rows: 1 + + * - endpoint name + - http request + - scope + - required for + * - federation metadata + - **GET** .well-known/openid-federation + - Metadata that an Entity publishes about itself, verifiable with a trusted third party (Superior Entity). It's called Entity Configuration. + - Trust Anchor, Intermediate, Wallet Provider, Relying Party, Credential Issuer + * - subordinate list endpoint + - **GET** /list + - Lists the Subordinates. + - Trust Anchor, Intermediate + * - fetch endpoint + - **GET** /fetch?sub=https://rp.example.org + - Returns a signed document (JWS) about a specific subject, its Subordinate. It's called Entity Statement. + - Trust Anchor, Intermediate + * - trust mark status + - **POST** /status?sub=...&trust_mark_id=... + - Returns the status of the issuance (validity) of a Trust Mark related to a specific subject. + - Trust Anchor, Intermediate + * - historical keys + - **GET** /historical-jwks + - Lists the expired and revoked keys, with the motivation of the revocation. + - Trust Anchor, Intermediate + + +All the responses of the federation endpoints are in the form of JWS, with the exception of the **Subordinate Listing endpoint** and the **Trust Mark Status endpoint** that are served as plain JSON by default. + + +Configuration of the Federation +------------------------------- + +The configuration of the federation is published by the Trust Anchor within its Entity Configuration, it is available at the well-known web path corresponding to **.well-known/openid-federation**. + +All the participants in the federation MUST obtain the federation configuration before entering the operational phase, and they +MUST keep it up-to-date. The federation configuration is the Trust Anchor's Entity Configuration, it contains the +public keys for signature operations and the maximum number of Intermediates allowed between a Leaf and the Trust Anchor (**max_path_length**). + +Below is a non-normative example of a Trust Anchor Entity Configuration, where each parameter is documented in the `OpenID Federation `_ specification: + +.. code-block:: text + + { + "alg": "ES256", + "kid": "FifYx03bnosD8m6gYQIfNHNP9cM_Sam9Tc5nLloIIrc", + "typ": "entity-statement+jwt" + } + . + { + "exp": 1649375259, + "iat": 1649373279, + "iss": "https://registry.eidas.trust-anchor.example.eu", + "sub": "https://registry.eidas.trust-anchor.example.eu", + "jwks": { + "keys": [ + { + + "kty": "EC", + "kid": "X2ZOMHNGSDc4ZlBrcXhMT3MzRmRZOG9Jd3o2QjZDam51cUhhUFRuOWd0WQ", + "crv": "P-256", + "x": "1kNR9Ar3MzMokYTY8BRvRIue85NIXrYX4XD3K4JW7vI", + "y": "slT14644zbYXYF-xmw7aPdlbMuw3T1URwI4nafMtKrY" + } + ] + }, + "metadata": { + "federation_entity": { + "organization_name": "example TA", + "contacts":[ + "tech@eidas.trust-anchor.example.eu" + ], + "homepage_uri": "https://registry.eidas.trust-anchor.example.eu", + "logo_uri":"https://registry.eidas.trust-anchor.example.eu/static/svg/logo.svg", + "federation_fetch_endpoint": "https://registry.eidas.trust-anchor.example.eu/fetch", + "federation_resolve_endpoint": "https://registry.eidas.trust-anchor.example.eu/resolve", + "federation_list_endpoint": "https://registry.eidas.trust-anchor.example.eu/list", + "federation_trust_mark_status_endpoint": "https://registry.eidas.trust-anchor.example.eu/trust_mark_status" + } + }, + "trust_mark_issuers": { + "https://registry.eidas.trust-anchor.example.eu/openid_relying_party/public": [ + "https://registry.spid.eidas.trust-anchor.example.eu", + "https://public.intermediary.spid.org" + ], + "https://registry.eidas.trust-anchor.example.eu/openid_relying_party/private": [ + "https://registry.spid.eidas.trust-anchor.example.eu", + "https://private.other.intermediary.org" + ] + } + } + + +Entity Configuration +-------------------- + +The Entity Configuration is the verifiable document that each Federation Entity MUST publish on its own behalf, in the **.well-known/openid-federation** endpoint. + +The Entity Configuration HTTP Response MUST set the media type to `application/entity-statement+jwt`. + +The Entity Configuration MUST be cryptographically signed. The public part of this key MUST be provided in the +Entity Configuration and within the Entity Statement issued by a immediate superior and related to its subordinate Federation Entity. + +The Entity Configuration MAY also contain one or more Trust Marks. + +.. note:: + **Entity Configuration Signature** + + All the signature-check operations regarding the Entity Configurations, Entity Statements and Trust Marks, are carried out with the Federation public keys. For the supported algorithms refer to Section `Cryptografic Algorithm`. + +Entity Configurations Common Parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Entity Configurations of all the participants in the federation MUST have in common the parameters listed below. + + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - **iss** + - String. Identifier of the issuing Entity. + * - **sub** + - String. Identifier of the Entity to which it is referred. It MUST be equal to ``iss``. + * - **iat** + - UNIX Timestamp with the time of generation of the JWT, coded as NumericDate as indicated at :rfc:`7519`. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated at :rfc:`7519`. + * - **jwks** + - A JSON Web Key Set (JWKS) :rfc:`7517` that represents the public part of the signing keys of the Entity at issue. Each JWK in the JWK set MUST have a key ID (claim kid) and MAY have a `x5c` parameter, as defined in :rfc:`7517`. It contains the Federation Entity Keys required for the operations of trust evaluation. + * - **metadata** + - JSON Object. Each key of the JSON Object represents a metadata type identifier + containing JSON Object representing the metadata, according to the metadata + schema of that type. An Entity Configuration MAY contain more metadata statements, but only one for each type of + metadata (<**entity_type**>). the metadata types are defined in the section `Metadata Types `_. + + +Entity Configuration Trust Anchor +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Trust Anchor Entity Configuration, in addition of the common parameters listed above, MAY contain the following parameters: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Required** + * - **constraints** + - JSON Object that describes the trust evaluation mechanisms bounds. It MUST contain the attribute **max_path_length** that + defines the maximum number of Intermediates between a Leaf and the Trust Anchor. + - |check-icon| + * - **trust_mark_issuers** + - JSON Array that defines which Federation authorities are considered trustworthy + for issuing specific Trust Marks, assigned with their unique identifiers. + - |uncheck-icon| + * - **trust_mark_owners** + - JSON Array that lists which entities are considered to be the owners of + specific Trust Marks. + - |uncheck-icon| + + +Entity Configuration Leaves and Intermediates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In addition to the previously defined claims, the Entity Configuration of the Leaf and of the Intermediate Entities, MAY contain the parameters listed below: + + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Required** + * - **authority_hints** + - Array of URLs (String). It contains a list of URLs of the immediate superior entities, such as the Trust Anchor or + an Intermediate, that issues an Entity Statement related to this subject. + - |check-icon| + * - **trust_marks** + - A JSON Array containing the Trust Marks. + - |uncheck-icon| + +Metadata Types +^^^^^^^^^^^^^^^^ + +In this section are defined the main metadata types mapped to the roles of the ecosystem, +giving the references of the metadata protocol for each of these. + + +.. note:: + + The entries that don't have any reference to a known draft or standard are intended to be defined in this technical reference. + +.. list-table:: + :widths: 20 20 20 60 + :header-rows: 1 + + * - OpenID Entity + - EUDI Entity + - Metadata Type + - References + * - Trust Anchor + - Trust Anchor + - ``federation_entity`` + - `OID-FED`_ + * - Intermediate + - Intermediate + - ``federation_entity`` + - `OID-FED`_ + * - Wallet Provider + - Wallet Provider + - ``federation_entity``, ``wallet_provider`` + - -- + * - Authorization Server + - + - ``federation_entity``, ``oauth_authorization_server`` + - `OPENID4VCI`_ + * - Credential Issuer + - PID Provider, (Q)EAA Provider + - ``federation_entity``, ``openid_credential_issuer``, [``oauth_authorization_server``] + - `OPENID4VCI`_ + * - Relying Party + - Relying Party + - ``federation_entity``, ``wallet_relying_party`` + - `OID-FED`_, `OpenID4VP`_ + + +.. note:: + Wallet Provider metadata is defined in the section below. + + `Wallet Solution section `_. + + +.. note:: + In instances where a PID/EAA Provider implements both the Credential Issuer and the Authorization Server, + it MUST incorporate both + ``oauth_authorization_server`` and ``openid_credential_issuer`` within its metadata types. + Other implementations may divide the Credential Issuer from the Authorization Server, when this happens the Credential Issuer metadata MUST contain the `authorization_servers` parameters, including the Authorization Server unique identifier. + Furthermore, should there be a necessity for User Authentication by the Credential Issuer, + it could be necessary to include the relevant metadata type, either ``openid_relying_party`` + or ``wallet_relying_party``. + + +Metadata of federation_entity Leaves +------------------------------------- + +The *federation_entity* metadata for Leaves MUST contain the following claims. + + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - **organization_name** + - See `OID-FED`_ Draft 36 Section 5.2.2 + * - **homepage_uri** + - See `OID-FED`_ Draft 36 Section 5.2.2 + * - **policy_uri** + - See `OID-FED`_ Draft 36 Section 5.2.2 + * - **logo_uri** + - URL of the entity's logo; it MUST be in SVG format. See `OID-FED`_ Draft 36 Section 5.2.2 + * - **contacts** + - Institutional certified email address (PEC) of the entity. See `OID-FED`_ Draft 36 Section 5.2.2 + * - **federation_resolve_endpoint** + - See `OID-FED`_ Draft 36 Section 5.1.1 + +Entity Statements +----------------- + +Trust Anchors and Intermediates publish Entity Statements related to their immediate Subordinates. +The Entity Statement MAY contain a metadata policy and the Trust Marks related to a Subordinate. + +The metadata policy, when applied, makes one or more changes to the final metadata of the Leaf. The final metadata of a Leaf is derived from the Trust Chain that contains all the statements, starting from the Entity Configuration up to the Entity Statement issued by the Trust Anchor. + +Trust Anchors and Intermediates MUST expose the Federation Fetch endpoint, where the Entity Statements are requested to validate the Leaf's Entity Configuration signature. + +.. note:: + The Federation Fetch endpoint MAY also publish X.509 certificates for each of the public keys of the Subordinate. Making the distribution of the issued X.509 certificates via a RESTful service. + +Below there is a non-normative example of an Entity Statement issued by an Registration Body (such as the Trust Anchor or its Intermediate) in relation to one of its Subordinates. + +.. code-block:: text + + { + "alg": "ES256", + "kid": "em3cmnZgHIYFsQ090N6B3Op7LAAqj8rghMhxGmJstqg", + "typ": "entity-statement+jwt" + } + . + { + "exp": 1649623546, + "iat": 1649450746, + "iss": "https://intermediate.eidas.example.org", + "sub": "https://rp.example.it", + "jwks": { + "keys": [ + { + "kty": "EC", + "kid": "2HnoFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMEEs", + "crv": "P-256", + "x": "1kNR9Ar3MzMokYTY8BRvRIue85NIXrYX4XD3K4JW7vI", + "y": "slT14644zbYXYF-xmw7aPdlbMuw3T1URwI4nafMtKrY", + "x5c": [ ] + } + ] + }, + "metadata_policy": { + "wallet_relying_party": { + "scope": { + "subset_of": [ + "eu.europa.ec.eudiw.pid.1", + "given_name", + "family_name", + "email" + ] + }, + "vp_formats": { + "vc+sd-jwt": { + "sd-jwt_alg_values": [ + "ES256", + "ES384" + ], + "kb-jwt_alg_values": [ + "ES256", + "ES384" + ] + } + } + } + } + } + + +.. note:: + + **Entity Statement Signature** + + The same considerations and requirements made for the Entity Configuration + and in relation to the signature mechanisms MUST be applied for the Entity Statements. + + +Entity Statement +^^^^^^^^^^^^^^^^^^ + +The Entity Statement issued by Trust Anchors and Intermediates contains the following attributes: + + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Required** + * - **iss** + - See `OID-FED`_ Section 3.1 for further details. + - |check-icon| + * - **sub** + - See `OID-FED`_ Section 3.1 for further details. + - |check-icon| + * - **iat** + - See `OID-FED`_ Section 3.1 for further details. + - |check-icon| + * - **exp** + - See `OID-FED`_ Section 3.1 for further details. + - |check-icon| + * - **jwks** + - Federation JWKS of the *sub* entity. See `OID-FED`_ Section 3.1 for further details. + - |check-icon| + * - **metadata_policy** + - JSON Object that describes the Metadata policy. Each key of the JSON Object represents an identifier of the metadata type and each value MUST be a JSON Object that represents the metadata policy according to that metadata type. Please refer to the `OID-FED`_ specifications, Section-5.1, for the implementation details. + - |uncheck-icon| + * - **trust_marks** + - JSON Array containing the Trust Marks issued by itself for the subordinate subject. + - |uncheck-icon| + * - **constraints** + - It MAY contain the **allowed_leaf_entity_types**, that restricts what types of metadata the subject is allowed to publish. + - |check-icon| + + +Trust Evaluation Mechanism +-------------------------- + +Trust Anchors MUST distribute their Federation Public Keys through secure out-of-band mechanisms, such as publishing them on a verified web page or storing them in a remote repository as part of a trust list. The rationale behind this requirement is that relying solely on the data provided within the Trust Anchor's Entity Configuration does not adequately mitigate risks associated with DNS and TLS manipulation attacks. To ensure security, all participants MUST obtain the Trust Anchor's public keys using these out-of-band methods. They should then compare these keys with those obtained from the Trust Anchor's Entity Configuration, discarding any keys that do not match. This process helps to ensure the integrity and authenticity of the Trust Anchor's public keys and the overall security of the federation. + +The Trust Anchor publishes the list of its Subordinates (Federation Subordinate Listing endpoint) and the attestations of their metadata and public keys (Entity Statements). + +Each participant, including Trust Anchor, Intermediate, Credential Issuer, Wallet Provider, and Relying Party, publishes its own metadata and public keys (Entity Configuration endpoint) in the well-known web resource **.well-known/openid-federation**. + +Each of these can be verified using the Entity Statement issued by a superior, such as the Trust Anchor or an Intermediate. + +Each Entity Statement is verifiable over time and MUST have an expiration date. The revocation of each statement is verifiable in real time and online (only for remote flows) through the federation endpoints. + +.. note:: + The revocation of an Entity is made with the unavailability of the Entity Statement related to it. If the Trust Anchor or its Intermediate doesn't publish a valid Entity Statement, or if it publishes an expired/invalid Entity Statement, the subject of the Entity Statement MUST be intended as not valid or revoked. + +The concatenation of the statements, through the combination of these signing mechanisms and the binding of claims and public keys, forms the Trust Chain. + +The Trust Chains can also be verified offline, using one of the Trust Anchor's public keys. + +.. note:: + Since the Wallet Instance is not a Federation Entity, the Trust Evaluation Mechanism related to it **requires the presentation of the Wallet Attestation during the credential issuance and presentation phases**. + + The Wallet Attestation conveys all the required information pertaining to the instance, such as its public key and any other technical or administrative information, without any User's personal data. + + +Relying Party Trust Evaluation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Relying Party is registered by a Trust Anchor or its Intermediate and obtains a Trust Mark to be included in its Entity Configuration. In its Entity Configuration the Relying Party publishes its specific metadata, including the supported signature and encryption algorithms and any other necessary information for the interoperability requirements. + +Any requests for User attributes, such as PID or (Q)EAA, from the Relying Party to Wallet Instances are signed and SHOULD contain the verifiable Trust Chain regarding the Relying Party. + +The Wallet Instance verifies that the Trust Chain related to the Relying Party is still active, proving that the Relying Party is still part of the Federation and not revoked. + +The Trust Chain SHOULD be contained within the signed request in the form of a JWS header parameter. + +In offline flows, Trust Chain verification enables the assessment of the reliability of Trust Marks and Attestations contained within. + + +Wallet Attestation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Wallet Provider issues the Wallet Attestation, certifying the operational status of its Wallet Instances and including one of their public keys. + +The Wallet Attestation contains the Trust Chain that attests the reliability for its issuer (Wallet Provider) at the time of issuance. + +The Wallet Instance provides its Wallet Attestation within the signed request during the PID issuance phase, containing the Trust Chain related to the Wallet Provider. + + +Trust Chain +^^^^^^^^^^^^^^^ + +The Trust Chain is a sequence of verified statements that validates a participant's compliance with the Federation. It has an expiration date time, beyond which it MUST be renewed to obtain the fresh and updated metadata. The expiration date of the Trust Chain is determined by the earliest expiration timestamp among all the expiration timestamp contained in the statements. No Entity can force the expiration date of the Trust Chain to be higher than the one configured by the Trust Anchor. + +Below is an abstract representation of a Trust Chain. + +.. code-block:: python + + [ + "EntityConfiguration-as-SignedJWT-selfissued-byLeaf", + "EntityStatement-as-SignedJWT-issued-byTrustAnchor" + ] + +Below is a non-normative example of a Trust Chain in its original format (JSON Array containing JWS as strings) with an Intermediate involved. + +.. code-block:: python + + [ + "eyJhbGciOiJFUzI1NiIsImtpZCI6Ik5GTTFXVVZpVWxZelVXcExhbWxmY0VwUFJWWTJWWFpJUmpCblFYWm1SSGhLWVVWWVVsZFRRbkEyTkEiLCJ0eXAiOiJhcHBsaWNhdGlvbi9lbnRpdHktc3RhdGVtZW50K2p3dCJ9.eyJleHAiOjE2NDk1OTA2MDIsImlhdCI6MTY0OTQxNzg2MiwiaXNzIjoiaHR0cHM6Ly9ycC5leGFtcGxlLm9yZyIsInN1YiI6Imh0dHBzOi8vcnAuZXhhbXBsZS5vcmciLCJqd2tzIjp7ImtleXMiOlt7Imt0eSI6IkVDIiwia2lkIjoiTkZNMVdVVmlVbFl6VVdwTGFtbGZjRXBQUlZZMlZYWklSakJuUVhabVJIaEtZVVZZVWxkVFFuQTJOQSIsImNydiI6IlAtMjU2IiwieCI6InVzbEMzd2QtcFgzd3o0YlJZbnd5M2x6cGJHWkZoTjk2aEwyQUhBM01RNlkiLCJ5IjoiVkxDQlhGV2xkTlNOSXo4a0gyOXZMUjROMThCa3dHT1gyNnpRb3J1UTFNNCJ9XX0sIm1ldGFkYXRhIjp7Im9wZW5pZF9yZWx5aW5nX3BhcnR5Ijp7ImFwcGxpY2F0aW9uX3R5cGUiOiJ3ZWIiLCJjbGllbnRfaWQiOiJodHRwczovL3JwLmV4YW1wbGUub3JnLyIsImNsaWVudF9yZWdpc3RyYXRpb25fdHlwZXMiOlsiYXV0b21hdGljIl0sImp3a3MiOnsia2V5cyI6W3sia3R5IjoiRUMiLCJraWQiOiJORk0xV1VWaVVsWXpVV3BMYW1sZmNFcFBSVlkyVlhaSVJqQm5RWFptUkhoS1lVVllVbGRUUW5BMk5BIiwiY3J2IjoiUC0yNTYiLCJ4IjoidXNsQzN3ZC1wWDN3ejRiUllud3kzbHpwYkdaRmhOOTZoTDJBSEEzTVE2WSIsInkiOiJWTENCWEZXbGROU05JejhrSDI5dkxSNE4xOEJrd0dPWDI2elFvcnVRMU00In1dfSwiY2xpZW50X25hbWUiOiJOYW1lIG9mIGFuIGV4YW1wbGUgb3JnYW5pemF0aW9uIiwiY29udGFjdHMiOlsib3BzQHJwLmV4YW1wbGUuaXQiXSwiZ3JhbnRfdHlwZXMiOlsicmVmcmVzaF90b2tlbiIsImF1dGhvcml6YXRpb25fY29kZSJdLCJyZWRpcmVjdF91cmlzIjpbImh0dHBzOi8vcnAuZXhhbXBsZS5vcmcvb2lkYy9ycC9jYWxsYmFjay8iXSwicmVzcG9uc2VfdHlwZXMiOlsiY29kZSJdLCJzY29wZSI6ImV1LmV1cm9wYS5lYy5ldWRpdy5waWQuMSBldS5ldXJvcGEuZWMuZXVkaXcucGlkLml0LjEgZW1haWwiLCJzdWJqZWN0X3R5cGUiOiJwYWlyd2lzZSJ9LCJmZWRlcmF0aW9uX2VudGl0eSI6eyJmZWRlcmF0aW9uX3Jlc29sdmVfZW5kcG9pbnQiOiJodHRwczovL3JwLmV4YW1wbGUub3JnL3Jlc29sdmUvIiwib3JnYW5pemF0aW9uX25hbWUiOiJFeGFtcGxlIFJQIiwiaG9tZXBhZ2VfdXJpIjoiaHR0cHM6Ly9ycC5leGFtcGxlLml0IiwicG9saWN5X3VyaSI6Imh0dHBzOi8vcnAuZXhhbXBsZS5pdC9wb2xpY3kiLCJsb2dvX3VyaSI6Imh0dHBzOi8vcnAuZXhhbXBsZS5pdC9zdGF0aWMvbG9nby5zdmciLCJjb250YWN0cyI6WyJ0ZWNoQGV4YW1wbGUuaXQiXX19LCJ0cnVzdF9tYXJrcyI6W3siaWQiOiJodHRwczovL3JlZ2lzdHJ5LmVpZGFzLnRydXN0LWFuY2hvci5leGFtcGxlLmV1L29wZW5pZF9yZWx5aW5nX3BhcnR5L3B1YmxpYy8iLCJ0cnVzdF9tYXJrIjoiZXlKaCBcdTIwMjYifV0sImF1dGhvcml0eV9oaW50cyI6WyJodHRwczovL2ludGVybWVkaWF0ZS5laWRhcy5leGFtcGxlLm9yZyJdfQ.Un315HdckvhYA-iRregZAmL7pnfjQH2APz82blQO5S0sl1JR0TEFp5E1T913g8GnuwgGtMQUqHPZwV6BvTLA8g", + "eyJhbGciOiJFUzI1NiIsImtpZCI6IlNURkRXV2hKY0dWWFgzQjNSVmRaYWtsQ0xUTnVNa000WTNGNlFUTk9kRXRyZFhGWVlYWjJjWGN0UVEiLCJ0eXAiOiJhcHBsaWNhdGlvbi9lbnRpdHktc3RhdGVtZW50K2p3dCJ9.eyJleHAiOjE2NDk2MjM1NDYsImlhdCI6MTY0OTQ1MDc0NiwiaXNzIjoiaHR0cHM6Ly9pbnRlcm1lZGlhdGUuZWlkYXMuZXhhbXBsZS5vcmciLCJzdWIiOiJodHRwczovL3JwLmV4YW1wbGUub3JnIiwiandrcyI6eyJrZXlzIjpbeyJrdHkiOiJFQyIsImtpZCI6Ik5GTTFXVVZpVWxZelVXcExhbWxmY0VwUFJWWTJWWFpJUmpCblFYWm1SSGhLWVVWWVVsZFRRbkEyTkEiLCJjcnYiOiJQLTI1NiIsIngiOiJ1c2xDM3dkLXBYM3d6NGJSWW53eTNsenBiR1pGaE45NmhMMkFIQTNNUTZZIiwieSI6IlZMQ0JYRldsZE5TTkl6OGtIMjl2TFI0TjE4Qmt3R09YMjZ6UW9ydVExTTQifV19LCJtZXRhZGF0YV9wb2xpY3kiOnsib3BlbmlkX3JlbHlpbmdfcGFydHkiOnsic2NvcGUiOnsic3Vic2V0X29mIjpbImV1LmV1cm9wYS5lYy5ldWRpdy5waWQuMSwgIGV1LmV1cm9wYS5lYy5ldWRpdy5waWQuaXQuMSJdfSwicmVxdWVzdF9hdXRoZW50aWNhdGlvbl9tZXRob2RzX3N1cHBvcnRlZCI6eyJvbmVfb2YiOlsicmVxdWVzdF9vYmplY3QiXX0sInJlcXVlc3RfYXV0aGVudGljYXRpb25fc2lnbmluZ19hbGdfdmFsdWVzX3N1cHBvcnRlZCI6eyJzdWJzZXRfb2YiOlsiUlMyNTYiLCJSUzUxMiIsIkVTMjU2IiwiRVM1MTIiLCJQUzI1NiIsIlBTNTEyIl19fX0sInRydXN0X21hcmtzIjpbeyJpZCI6Imh0dHBzOi8vdHJ1c3QtYW5jaG9yLmV4YW1wbGUuZXUvb3BlbmlkX3JlbHlpbmdfcGFydHkvcHVibGljLyIsInRydXN0X21hcmsiOiJleUpoYiBcdTIwMjYifV19._qt5-T6DahP3TuWa_27klE8I9Z_sPK2FtQlKY6pGMPchbSI2aHXY3aAXDUrObPo4CHtqgg3J2XcrghDFUCFGEQ", + "eyJhbGciOiJFUzI1NiIsImtpZCI6ImVXa3pUbWt0WW5kblZHMWxhMjU1ZDJkQ2RVZERSazQwUWt0WVlVMWFhRFZYT1RobFpHdFdXSGQ1WnciLCJ0eXAiOiJhcHBsaWNhdGlvbi9lbnRpdHktc3RhdGVtZW50K2p3dCJ9.eyJleHAiOjE2NDk2MjM1NDYsImlhdCI6MTY0OTQ1MDc0NiwiaXNzIjoiaHR0cHM6Ly90cnVzdC1hbmNob3IuZXhhbXBsZS5ldSIsInN1YiI6Imh0dHBzOi8vaW50ZXJtZWRpYXRlLmVpZGFzLmV4YW1wbGUub3JnIiwiandrcyI6eyJrZXlzIjpbeyJrdHkiOiJFQyIsImtpZCI6IlNURkRXV2hKY0dWWFgzQjNSVmRaYWtsQ0xUTnVNa000WTNGNlFUTk9kRXRyZFhGWVlYWjJjWGN0UVEiLCJjcnYiOiJQLTI1NiIsIngiOiJyQl9BOGdCUnh5NjhVTkxZRkZLR0ZMR2VmWU5XYmgtSzh1OS1GYlQyZkZJIiwieSI6IlNuWVk2Y3NjZnkxcjBISFhLTGJuVFZsamFndzhOZzNRUEs2WFVoc2UzdkUifV19LCJ0cnVzdF9tYXJrcyI6W3siaWQiOiJodHRwczovL3RydXN0LWFuY2hvci5leGFtcGxlLmV1L2ZlZGVyYXRpb25fZW50aXR5L3RoYXQtcHJvZmlsZSIsInRydXN0X21hcmsiOiJleUpoYiBcdTIwMjYifV19.r3uoi-U0tx0gDFlnDdITbcwZNUpy7M2tnh08jlD-Ej9vMzWMCXOCCuwIn0ZT0jS4M_sHneiG6tLxRqj-htI70g" + ] + + +.. note:: + + The entire Trust Chain is verifiable by only possessing the Trust Anchor's public keys. + + +Offline Trust Attestation Mechanisms +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The offline flows do not allow for real-time evaluation of an Entity's status, such as its revocation. At the same time, using short-lived Trust Chains enables the attainment of trust attestations compatible with the required revocation administrative protocols (e.g., a revocation must be propagated in less than 24 hours, thus the Trust Chain must not be valid for more than that period). + + +Offline Wallet Trust Attestation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Given that the Wallet Instance cannot publish its metadata online at the *.well-known/openid-federation* endpoint, +it MUST obtain a Wallet Attestation issued by its Wallet Provider. The Wallet Attestation MUST contain all the relevant information regarding the security capabilities of the Wallet Instance and its protocol related configuration. It SHOULD contain the Trust Chain related to its issuer (Wallet Provider). + + +Offline Relying Party Metadata +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since the Federation Entity Discovery is only applicable in online scenarios, it is possible to include the Trust Chain in the presentation requests that the Relying Party may issue for a Wallet Instance. + +The Relying Party MUST sign the presentation request, the request SHOULD include the `trust_chain` claim in its JWS header parameters, containing the Federation Trust Chain related to itself. + +The Wallet Instance that verifies the request issued by the Relying Party MUST use the Trust Anchor's public keys to validate the entire Trust Chain related to the Relying Party before attesting its reliability. + +Furthermore, the Wallet Instance applies the metadata policy, if any. + +Trust Chain Fast Renewal +------------------------ + +The Trust Chain fast renewal method offers a streamlined way to maintain the validity of a trust chain without undergoing the full discovery +process again. It's particularly useful for quickly updating trust relationships when minor changes occur or when the +Trust Chain is close to expiration but the overall structure of the federation hasn't changed significantly. + +The Trust Chain fast renewal process is initiated by fetching the leaf's Entity Configuration anew. However, unlike the federation discovery process that may involve fetching Entity Configurations starting from the authority hints, the fast renewal focuses on directly obtaining the Subordinate Statements. These statements are requested using the `source_endpoint` provided within them, which points to the location where the statements can be fetched. + + +Non-repudiability of the Long Lived Attestations +-------------------------------------------------- + +The Trust Anchor and its Intermediate MUST expose the Federation Historical Keys endpoint, where are published all the public part of the Federation Entity Keys that are no longer used, whether expired or revoked. + +The details of this endpoint are defined in the `OID-FED`_ Section 7.6. + +Each JWS containing a Trust Chain in the form of a JWS header parameter can be verified over time, since the entire Trust Chain is verifiable using the Trust Anchor's public key. + +Even if the Trust Anchor has changed its cryptographic keys for digital signature, the Federation Historical Keys endpoint always makes the keys no longer used available for historical signature verifications. + + +Privacy Remarks +--------------- + +- Wallet Instances MUST NOT publish their metadata through an online service. +- The trust infrastructure MUST be public, with all endpoints publicly accessible without any client credentials that may disclose who is requesting access. +- When a Wallet Instance requests the Entity Statements to build the Trust Chain for a specific Relying Party or validates a Trust Mark online, issued for a specific Relying Party, the Trust Anchor or its Intermediate do not know that a particular Wallet Instance is inquiring about a specific Relying Party; instead, they only serve the statements related to that Relying Party as a public resource. +- The Wallet Instance metadata MUST not contain information that may disclose technical information about the hardware used. +- Leaf entity, Intermediate, and Trust Anchor metadata may include the necessary amount of data as part of administrative, technical, and security contact information. It is generally not recommended to use personal contact details in such cases. From a legal perspective, the publication of such information is needed for operational support concerning technical and security matters and the GDPR regulation. + + +Considerations about Decentralization +------------------------------------- + +- There may be more than a single Trust Anchor. +- In some cases, a trust verifier may trust an Intermediate, especially when the Intermediate acts as a Trust Anchor within a specific perimeter, such as cases where the Leafs are both in the same perimeter like a Member State jurisdiction (eg: an Italian Relying Party with an Italian Wallet Instance may consider the Italian Intermediate as a Trust Anchor for the scopes of their interactions). +- Trust attestations (Trust Chain) should be included in the JWS issued by Credential Issuers, and the Presentation Requests of RPs should contain the Trust Chain related to them (issuers of the presentation requests). +- Since the credential presentation must be signed, storing the signed presentation requests and responses, which include the Trust Chain, the Wallet Instance may have the snapshot of the federation configuration (Trust Anchor Entity Configuration in the Trust Chain) and the verifiable reliability of the Relying Party it has interacted with. +- Each signed attestation is long-lived since it can be cryptographically validated even when the federation configuration changes or the keys of its issuers are renewed. +- Each participant should be able to update its Entity Configuration without notifying the changes to any third party. The metadata policy contained within a Trust Chain must be applied to overload any information related to protocol specific metadata. diff --git a/refs/pull/443/merge/en/_sources/wallet-attestation.rst.txt b/refs/pull/443/merge/en/_sources/wallet-attestation.rst.txt new file mode 100644 index 000000000..5c2b9e164 --- /dev/null +++ b/refs/pull/443/merge/en/_sources/wallet-attestation.rst.txt @@ -0,0 +1,642 @@ +.. include:: ../common/common_definitions.rst + +.. _wallet-attestation.rst: + +Wallet Attestation +++++++++++++++++++ + +Wallet Attestation contains information regarding the security level of the device hosting the Wallet Instance. +It primarily certifies the **authenticity**, **integrity**, **security**, **privacy**, and **trustworthiness** of a particular Wallet Instance. + + +Requirements +------------ + +The requirements for the Wallet Attestation are defined below: + +- The Wallet Attestation MUST contain a Wallet Instance public key. +- The Wallet Attestation MUST use the signed JSON Web Token (JWT) format; +- The Wallet Attestation MUST provide all the relevant information to attest to the **integrity** and **security** of the device where the Wallet Instance is installed. +- The Wallet Attestation MUST be signed by the Wallet Provider that has authority over and is the owner of the Wallet Solution, as specified by the overseeing registration authority. This ensures that the Wallet Attestation uniquely links the Wallet Provider to this particular Wallet Instance. +- The Wallet Provider MUST ensure the integrity, authenticity, and genuineness of the Wallet Instance, preventing any attempts at manipulation or falsification by unauthorized third parties. The Wallet Provider MUST also verify the Wallet Instance using the App Store vendor's API, such as the *Play Integrity API* for Android and *DeviceCheck* for iOS. These services are defined in this specification as **Device Integrity Service (DIS)**. +- The Wallet Attestation MUST have a mechanism in place for revoking the Wallet Instance, allowing the Wallet Provider to terminate service for a specific instance at any time. +- The Wallet Attestation MUST be securely bound to the Wallet Instance's ephemeral public key. +- The Wallet Attestation MAY be used multiple times during its validity period, allowing for repeated authentication and authorization without the need to request new attestations with each interaction. +- The Wallet Attestation MUST be short-lived and MUST have an expiration date/time, after which it SHOULD no longer be considered valid. +- The Wallet Attestation MUST NOT be issued by the Wallet Provider if the authenticity, integrity, and genuineness are not guaranteed. In this case, the Wallet Instance MUST be revoked. +- Each Wallet Instance SHOULD be able to request multiple attestations with different ephemeral public keys associated with them. This requirement provides a privacy-preserving measure, as the public key MAY be used as a tracking tool during the presentation phase (see also the point listed below). +- The Wallet Attestation MUST NOT contain any information that can be used to directly identify the User. +- The Wallet Instance MUST secure a Wallet Attestation as a prerequisite for transitioning to the Operational state, as defined by `ARF`_. +- Private keys MUST be generated and stored in the WSCD using at least one of the approaches listed below: + + - **Local Internal WSCD**: The WSCD relies entirely on the device's native cryptographic hardware, such as the Secure Enclave on iOS devices or the Hardware-Backed Keystore or Strongbox on Android devices. + - **Local External WSCD**: The WSCD is hardware external to the User's device, such as a smart card compliant with *GlobalPlatform* and supporting *JavaCard*. + - **Remote WSCD**: The WSCD utilizes a remote Hardware Security Module (HSM). + - **Local Hybrid WSCD**: The WSCD involves a pluggable internal hardware component within the User's device, such as an *eUICC* that adheres to *GlobalPlatform* standards and supports *JavaCard*. + - **Remote Hybrid WSCD**: The WSCD involves a local component mixed with a remote service. + +- The Wallet Provider MUST offer a set of services, exclusively available to its Wallet Solution instances, for the issuance of Wallet Attestations. + +.. warning:: + At the current stage, the implementation profile defined in this document supports only the **Local Internal WSCD**. Future versions of this specification MAY include other approaches depending on the required `AAL`. + +Static Component View +--------------------- + +.. figure:: ../../images/static_view_wallet_instance_attestation.svg + :name: Wallet Solution Schema + :alt: The image illustrates the containment of Wallet Provider and Wallet Instances within the Wallet Solution, managed by the Wallet Provider. + :target: https://www.plantuml.com/plantuml/uml/VP8nJyCm48Lt_ugdTexOCw22OCY0GAeGOsMSerWuliY-fEg_9mrEPTAqw-VtNLxEtaJHGRh6AMs40rRlaS8AEgAB533H3-qS2Tu2zxPEWSF8TcrYv-mJzTOGNfzVnXXJ0wKCDorxydAUjMNNYMMVpug9OTrR7i22LlaesXlADPiOraToZWyBsgCsF-JhtFhyGyZJgNlbXVR1oX5R2YSoUdQYEzrQO1seLcfUeGXs_ot5_VzqYM6lQlRXMz6hsTccIbGHhGu2_hhfP1tBwHuZqdOUH6WuEmrKIeqtNonvXhq4ThY3Dc9xBNJv_rSwQeyfawhcZsTPIpKLKuFYSa_JyOPytJNk5m00 + +Dynamic Component View +---------------------- + +The Wallet Attestation acquisition flow can be divided into two main phases. The first phase involves device initialization and registration, which occurs only during the initial launch of the Wallet Instance (after installation). The second phase pertains to the actual acquisition of the Wallet Attestation. + +Wallet Instance Initialization and Registration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. figure:: ../../images/wallet_instance_initialization.svg + :name: Sequence Diagram for Wallet Instance Initialization + :alt: The figure illustrates the sequence diagram for initializing a Wallet Instance, with the steps explained below. + :target: https://www.plantuml.com/plantuml/uml/ZLJ1RjD04BtlLupQ0sqKVY07L5H2MXKe8WKkNCRsn1d5tZMpiu7mzSpQROYZK3WuMis-z-QzjrAkeg9eQXk7IODFRK7YrbmHh4BG8lnqBpe3SCaTUdKEImq2PvyZoHbWX1GDVu20iw_ODAHmwqtPbzIZiEjWZ7f3Mox9K4griEvWIP8d0nmrmddiX7rT2v4_kU6ZXAqP5IYmt92lUcfHRfoh9QGEWczsaBhWOSKI5TWS6HELRHHMe6lAnboEyFALdMRGbn6VRk1Y81hWCWVdBUf0iU-HSRscSWCyg5L3g9ReKQHbpsrg8LAP-fH2tnCBjUGrVlFegqoTJFxMncG2706to0qM3JadFYX1s99a7rDB2-VlRXSt3ujFy_a7DxWvxiSaSdzFcT-I3OSMie5GAB87rcZ65IjKTDPclycv8QhjcS62rAoMwwpkQ_EsxwHltRuzq9FaSV04oYtb1e-e6JrKU7HHqKXrt_HUrV3Nikiqr8BTcakuGQb-e13SqIvQOnsozCcY1daU3WzOsyvX2MgS0QfILBkws9kQmlC2bovJ_wJ9uzUzJ5-oEOfSUwgWsC7z_Fr1eqlhUHn_Uf9lOVuhnkdd-88DLpOURpeDEDezWYt_MMSSF-pztOdNjCiKIMPmz3zX1rOs9x-eEgGPnLbDxif-Kjly1W00 + +**Step 1**: The User starts the Wallet Instance mobile app for the first time. + +**Step 2**: The Wallet Instance: + + * Checks whether the device meets the minimum security requirements. + * Checks if the Device Integrity Service is available. + +.. note:: + + **Federation Check**: The Wallet Instance needs to check if the Wallet Provider is part of the Federation, obtaining its protocol-specific Metadata. A non-normative example of a response from the endpoint **.well-known/openid-federation** with the **Entity Configuration** and the **Metadata** of the Wallet Provider is represented within the section `Wallet Provider metadata`_. + +**Steps 3-5**: The Wallet Instance sends a request to the Wallet Provider Backend and receives a one-time ``challenge``. This "challenge" is a ``nonce``, which must be unpredictable to serve as the main defense against replay attacks. The backend must generate the ``nonce`` value in a manner that ensures it is single-use and valid only within a specific time frame. This endpoint is compliant with the specification `OAuth 2.0 Nonce Endpoint`_. + +.. code-block:: http + + GET /nonce HTTP/1.1 + Host: walletprovider.example.com + +.. code-block:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "nonce": "d2JhY2NhbG91cmVqdWFuZGFt" + } + +**Step 6**: The Wallet Instance, through the operating system, creates a pair of Cryptographic Hardware Keys and stores the corresponding Cryptographic Hardware Key Tag in local storage once the following requirements are met: + + 1. It MUST ensure that Cryptographic Hardware Keys do not already exist. If they do exist and the Wallet is in the initialization phase, they MUST be deleted. + 2. It MUST generate a pair of asymmetric Elliptic Curve keys (Cryptographic Hardware Keys) via a local WSCD. + 3. It SHOULD obtain a unique identifier (Cryptographic Hardware Key Tag) for the generated Cryptographic Hardware Keys from the operating system. If the operating system permits specifying a tag during the creation of keys, then a random string for the Cryptographic Hardware Key Tag MUST be selected. This random value MUST be collision-resistant and unpredictable to ensure security. To achieve this, consider using a cryptographic hash function or a secure random number generator provided by the operating system or a reputable cryptographic library. + 4. If the previous points are satisfied, it MUST store the Cryptographic Hardware Key Tag in local storage. + +.. note:: + + **WSCD**: The Wallet Instance MAY use a local WSCD for key generation on devices that support this feature. On Android devices, Strongbox is RECOMMENDED; Trusted Execution Environment (TEE) MAY be used only when Strongbox is unavailable. For iOS devices, Secure Elements (SE) MUST be used. Given that each OEM offers a distinct SDK for accessing the local WSCD, the discussion hereafter will address this topic in a general context. + +**Step 7**: The Wallet Instance uses the Device Integrity Service, providing the "challenge" and the Cryptographic Hardware Key Tag to acquire the Key Attestation. + +.. note:: + + **Device Integrity Service**: In this section, the Device Integrity Service is considered as it is provided by device manufacturers. This service allows the verification of a key being securely stored within the device's hardware through a signed object. Additionally, it offers verifiable proof that a specific Wallet Instance is authentic, unaltered, and in its original state using a specialized signed document made for this purpose. + + The service also incorporates details in the signed object, such as the device type, model, app version, operating system version, bootloader status, and other relevant information to assess whether the device has been compromised. For Android, the DIS is represented by *Key Attestation*, a feature supported by *StrongBox Keymaster*, which is a physical HSM installed directly on the motherboard, and the *TEE* (Trusted Execution Environment), a secure area of the main processor. *Key Attestation* aims to provide a way to strongly determine if a key pair is hardware-backed, what the properties of the key are, and what constraints are applied to its usage. Developers can leverage its functionality through the *Play Integrity API*. For Apple devices, the DIS is represented by *DeviceCheck*, which provides a framework and server interface to manage device-specific data securely. *DeviceCheck* is used in combination with the *Secure Enclave*, a dedicated HSM integrated into Apple's SoCs. *DeviceCheck* can be used to attest to the integrity of the device, apps, and/or encryption keys generated on the device, ensuring they were created in a secure environment like *Secure Enclave*. Developers can leverage *DeviceCheck* functionality by using the framework itself. + These services, specifically developed by the manufacturer, are integrated within the Android or iOS SDKs, eliminating the need for a predefined endpoint to access them. Additionally, as they are specifically developed for mobile architecture, they do not need to be registered as Federation Entities through national registration systems. + *Secure Enclave* has been available on Apple devices since the iPhone 5s (2013). + For Android devices, the inclusion of **Strongbox Keymaster** may vary by manufacturer, who decides whether to include it or not. + +**Step 8**: The Device Integrity Service performs the following actions: + +* Creates a Key Attestation that is linked with the provided "challenge" and the public key of the Wallet Hardware. +* Incorporates information pertaining to the device's security. +* Uses an OEM private key to sign the Key Attestation, therefore verifieable with the related OEM certificate, confirming that the Cryptographic Hardware Keys are securely managed by the operating system. + +**Step 9**: The Wallet Instance sends the ``challenge`` with Key Attestation and Cryptographic Hardware Key Tag to the Wallet Provider Backend in order to register the Wallet Instance identified with the Cryptographic Hardware Key public key. + +In order to register the Wallet Instance, the request to the Wallet Provider MUST use the HTTP POST method. The parameters MUST be encoded using the `application/json` format and included in the message body. The following parameters MUST be provided: + +.. _table_http_request_claim: +.. list-table:: Wallet Instance registration http request parameters + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **challenge** + - MUST be set to the challenge obtained from the Wallet Provider throught the ``nonce`` endpoint. + - `OAuth 2.0 Nonce Endpoint`_ + * - **key_attestation** + - It MUST be a ``base64url`` encoded Key Attestation obtained from the **Device Integrity Service**. + - + * - **hardware_key_tag** + - It MUST be set with the unique identifier of the **Cryptographic Hardware Keys** and encoded in ``base64url``. + - + +Below is a non-normative example of the request. + +.. code-block:: http + + POST /wallet-instance HTTP/1.1 + Host: walletprovider.example.com + Content-Type: application/json + + { + "challenge": "0fe3cbe0-646d-44b5-8808-917dd5391bd9", + "key_attestation": "o2NmbXRvYXBwbGUtYXBw... redacted", + "hardware_key_tag": "WQhyDymFKsP95iFqpzdEDWW4l7aVna2Fn4JCeWHYtbU=" + } + +.. note:: + It is not necessary to send the Wallet Hardware public key because it is already included in the ``key_attestation``. + As seen in the previous steps, the Device Integrity Service (DIS) creates a Key Attestation linked to the provided "challenge" and the public key of the Wallet Hardware. This process eliminates the need to send the Wallet Hardware public key directly, as it is already included in the key attestation. The ``hardware_key_tag`` serves as a reference or identifier for the corresponding Cryptographic Hardware key stored by the Wallet Provider. Therefore, the Wallet Provider can associate the received ``hardware_key_tag`` with the appropriate Cryptographic Hardware key in its storage. + +.. warning:: + During the registration phase of the Wallet Instance with the Wallet Provider it is also necessary to associate it with a specific user + uniquely identifiable by the Wallet Provider. This association is at the discretion of the Wallet PRovider and will not be addressed + within these guidelines as each Wallet Provider may or may not have a user identification system already implemented. + + +**Steps 10-12**: The Wallet Provider validates the ``challenge`` and ``key_attestation`` signature, therefore: + + 1. It MUST verify that the ``challenge`` was generated by Wallet Provider and has not already been used. + 2. It MUST validate the ``key_attestation`` as defined by the device manufacturers' guidelines. + 3. It MUST verify that the device in use has no security flaws and reflects the minimum security requirements defined by the Wallet Provider. + 4. If these checks are passed, it MUST register the Wallet Instance, keeping the Cryptographic Hardware Key Tag and all useful information related to the device. + 5. It SHOULD associate the Wallet Instance with a specific User uniquely identified within the Wallet Provider's systems. This will be useful for the lifecycle of the Wallet Instance and for a future revocation. + +Upon successful registration of the Wallet Instance, the Wallet Provider MUST respond with a status code set to 204 (No Content). +Below is a non-normative example of the response. + +.. code-block:: http + + HTTP/1.1 204 No content + +If any errors occur during the Wallet Instance registration, the Wallet Provider MUST return an error response. The response MUST use the content type set to *application/json* and MUST include the following parameters: + + - *error*. The error code. + - *error_description*. Text in human-readable form providing further details to clarify the nature of the error encountered. + +**Steps 13-14**: The Wallet Instance has been initialized and becomes operational. + +.. note:: **Threat Model**: while the registration endpoint does not necessitate any client authentication, it is safeguarded through the use of `key_attestation`. Proper validation of this attestation permits the registration of authentic and unaltered app instances. Any other claims submitted will not undergo validation, leading the endpoint to respond with an error. Additionally, the inclusion of a challenge helps prevent replay attacks. The authenticity of both the challenge and the ``hardware_key_tag`` is ensured by the signature found within the ``key_attestation``. + + +Wallet Attestation Issuance +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section describes the Wallet Attestation format and how the Wallet Provider issues it. + +.. figure:: ../../images/wallet_instance_acquisition.svg + :name: Sequence Diagram for Wallet Attestation acquisition + :alt: The figure illustrates the sequence diagram for issuing a Wallet Attestation, with the steps explained below. + :target: https://www.plantuml.com/plantuml/uml/VLJ1Jjj04BtlLupWK8ZIIwNsWDGAH2bGgWe1BHSaQsmFzZJEhhixTff-VMTD4YV6pS4IoxvvyzxRcPm6GI_Dl3BOYBFDF2LlIiu9dfsJrFqnRse5SCOrMZ46Ct4U3du4yWU00PgW-2q473nYLP70jLLccr67mhg6NTHdQZaZHGaLdcK9z-HRNiDH0Xo6shCj2azaHplSUjUgK0yfPZEoULUQPZDZJ5JrzfDsFO4x-jrG442mj01NaqTXPq5Ab2VhzPOzQKkOJ5QyPo9QqA4casYOMnIA7en-Azhpah8PyBEMdVjbBQxmM9USmHNwV86Uu8QMOJ81LkuMkSAq8hD5S4asIecjBL1TqboF5Sne2JMoLzwlZpVQttZhXC2rvAE4gHg4ms_NbrSFbtSN5z_DYv1X9DerHWRkMOqIVA5yxHjj3YuLP0ii0UOacAEWqG2xJcObKlj4aQ92iZAosuAsuuX1wzS1UpVWB87mdE9W34eZUcL-zoAd7LOp5bCigPYi955jKc8eDLmCS7zrzkxzXwCDtnJg9gquItujPiVZJ7jUJ3bltUsJFdov-cyIkB0eZIUz-mZnT3HKCeL5bt-oAT9dJ0IBZG2KS0B5Ii5cwCz282_iNZCUcrZInyNhaWJNDIfdrDxhATxim8Ab_1_P5COzJtSVQ_faz-K73rYyrFIle48Z7-LT_txMDoFUpzizsNoFWTtfwnSZ7iSN8sxeu0SfxWPR5iQA_rBUBKIhV-Uc2MmBs6DEiEZWuqdrAzJlnSz8Z39OXH70-BECGyVRZoDZmjrCzzVga5ukNoSzMDDnn61VjyzQPaurXsPU_GC0 + +**Step 1**: The User initiates a new operation that necessitates the acquisition of a Wallet Attestation. + +**Steps 2-3**: The Wallet Instance checks if a Cryptographic Hardware Key exists and generates an ephemeral asymmetric key pair. The Wallet Instance also: + + 1. MUST ensure that Cryptographic Hardware Keys exist. If they do not exist, it is necessary to reinitialize the Wallet. + 2. MUST generates an ephemeral asymmetric key pair whose public key will be linked with the Wallet Attestation. + 3. MUST check if Wallet Provider is part of the federation and obtain its metadata. + + +**Steps 4-6**: The Wallet Instance solicits a one-time "challenge" from the Wallet Provider Backend. This "challenge" takes the form of a "nonce," which is required to be unpredictable and serves as the main defense against replay attacks. The backend MUST produce the "nonce" in a manner that ensures its single-use within a predetermined time frame. + +.. code-block:: http + + GET /nonce HTTP/1.1 + Host: walletprovider.example.com + +.. code-block:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "nonce": "d2JhY2NhbG91cmVqdWFuZGFt" + } + +**Step 7**: The Wallet Instance performs the following actions: + + * Creates a ``client_data``, a JSON structure that includes the challenge and the thumbprint of ephemeral public ``jwk``. + * Computes a ``client_data_hash`` by applying the ``SHA256`` algorithm to the ``client_data``. + +Below a non-normative example of the ``client_data``. + +.. code-block:: json + + { + "challenge": "0fe3cbe0-646d-44b5-8808-917dd5391bd9", + "jwk_thumbprint": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c" + } + +**Steps 8-10**: The Wallet Instance takes the following steps: + + * It produces an hardware_signature by signing the ``client_data_hash`` with the Wallet Hardware's private key, serving as a proof of possession for the Cryptographic Hardware Keys. + * It requests the Device Integrity Service to create an ``integrity_assertion`` linked to the ``client_data_hash``. + * It receives a signed ``integrity_assertion`` from the Device Integrity Service, authenticated by the OEM. + +.. note:: ``integrity_assertion`` is a custom payload generated by Device Integrity Service, signed by device OEM and encoded in base64 to have uniformity between different devices. + +**Steps 11-12**: The Wallet Instance: + + * Constructs the Wallet Attestation Request in the form of a JWT. This JWT includes the ``integrity_assertion``, ``hardware_signature``, ``challenge``, ``hardware_key_tag``, ``cnf`` and other configuration related parameters (see :ref:`Table of the Wallet Attestation Request Body ` below) and is signed using the private key of the initially generated ephemeral key pair. + * Submits the Wallet Attestation Request to the token endpoint of the Wallet Provider Backend. + +Below an non-normative example of the Wallet Attestation Request JWT without encoding and signature applied: + +.. code-block:: + + { + "alg": "ES256", + "kid": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c", + "typ": "war+jwt" + } + . + { + "iss": "https://wallet-provider.example.org/instance/vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c", + "sub": "https://wallet-provider.example.org/", + "challenge": "6ec69324-60a8-4e5b-a697-a766d85790ea", + "hardware_signature": "KoZIhvcNAQcCoIAwgAIB...redacted", + "integrity_assertion": "o2NmbXRvYXBwbGUtYXBwYX...redacted", + "hardware_key_tag": "WQhyDymFKsP95iFqpzdEDWW4l7aVna2Fn4JCeWHYtbU=", + "cnf": { + "jwk": { + "crv": "P-256", + "kty": "EC", + "x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44", + "y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg" + } + }, + "vp_formats_supported": { + "jwt_vc_json": { + "alg_values_supported": ["ES256K", "ES384"] + }, + "jwt_vp_json": { + "alg_values_supported": ["ES256K", "EdDSA"] + }, + }, + }, + authorization_endpoint": "https://wallet-solution.digital-strategy.europa.eu/authorization", + "response_types_supported": [ + "vp_token" + ], + "response_modes_supported": [ + "form_post.jwt" + ], + "request_object_signing_alg_values_supported": [ + "ES256" + ], + "presentation_definition_uri_supported": false, + "iat": 1686645115, + "exp": 1686652315 + } + +The Wallet Instance MUST do an HTTP request to the Wallet Provider's `token endpoint`_, +using the method `POST `__. + +The **token** endpoint (as defined in `RFC 7523 section 4`_) requires the following parameters +encoded in ``application/x-www-form-urlencoded`` format: + +* ``grant_type`` set to ``urn:ietf:params:oauth:grant-type:jwt-bearer``; +* ``assertion`` containing the signed JWT of the Wallet Attestation Request. + +.. code-block:: http + + POST /token HTTP/1.1 + Host: wallet-provider.example.org + Content-Type: application/x-www-form-urlencoded + + grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer + &assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6ImtoakZWTE9nRjNHeG... + +**Steps 13-17**: The Wallet Provider Backend assesses the Wallet Attestation Request and issues a Wallet Attestation, if the requirements described below are satisfied: + + 1. It MUST check the Wallet Attestation Request contains all the defined HTTP Request header parameters according to :ref:`Table of the Wallet Attestation Request Header `. + 2. It MUST verify that the signature of the received Wallet Attestation Request is valid and associated with public ``jwk``. + 3. It MUST verify that the ``challenge`` was generated by Wallet Provider and has not already been used. + 4. It MUST check that there is a Wallet Instance registered with that ``hardware_key_tag`` and that it is still valid. + 5. It MUST reconstruct the ``client_data`` via the ``challenge`` and the ``jwk`` public key, to validate ``hardware_signature`` via the Cryptographic Hardware Key public key registered and associated with the Wallet Instance. + 6. It MUST validate the ``integrity_assertion`` as defined by the device manufacturers' guidelines. The list of checks that the Wallet Provider MUST perform are defined by the operating system manufacturers documentation. + 7. It MUST verify that the device in use has no security flaws and reflects the minimum security requirements defined by the Wallet Provider. + 8. It MUST check that the URL in ``iss`` parameter is equal to the URL identifier of Wallet Provider. + +If all checks are passed, Wallet Provider issues a Wallet Attestation with an expiration limited to 24 hours. + +Below an non-normative example of the Wallet Attestation without encoding and signature applied: + +.. code-block:: + + { + "alg": "ES256", + "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY", + "trust_chain": [ + "eyJhbGciOiJFUz...6S0A", + "eyJhbGciOiJFUz...jJLA", + "eyJhbGciOiJFUz...H9gw", + ], + "typ": "wallet-attestation+jwt", + } + . + { + "iss": "https://wallet-provider.example.org", + "sub": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c", + "aal": "https://trust-list.eu/aal/high", + "cnf": + { + "jwk": + { + "crv": "P-256", + "kty": "EC", + "x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44", + "y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg" + } + }, + "authorization_endpoint": "eudiw:", + "response_types_supported": [ + "vp_token" + ], + "response_modes_supported": [ + "form_post.jwt" + ], + "vp_formats_supported": { + "vc+sd-jwt": { + "sd-jwt_alg_values": [ + "ES256", + "ES384" + ] + } + }, + "request_object_signing_alg_values_supported": [ + "ES256" + ], + "presentation_definition_uri_supported": false, + "iat": 1687281195, + "exp": 1687288395 + } + +**Step 18**: The response is returned by the Wallet Provider. If successful, the HTTP response code MUST be set with the value ``200 OK`` and contain the Wallet Attestation signed by the Wallet Provider. The Wallet Instance therefore performs security, integrity and trust verification about the Wallet Attestation and its issuer. + + +Below is a non-normative example of the response. + +.. code-block:: http + + HTTP/1.1 200 OK + Content-Type: application/jwt + + eyJhbGciOiJFUzI1NiIsInR5cCI6IndhbGx ... + + +.. _table_wallet_attestation_request_claim: + +Wallet Attestation Request +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The JOSE header of the Wallet Attestation Request JWT MUST contain: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **JOSE header** + - **Description** + - **Reference** + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section `Cryptographic Algorithms `_ and MUST NOT be set to ``none`` or any symmetric algorithm (MAC) identifier. + - :rfc:`7516#section-4.1.1`. + * - **kid** + - Unique identifier of the ``jwk`` used by the Wallet Provider to sign the Wallet Attestation, essential for matching the Wallet Provider's cryptographic public key needed for signature verification. + - :rfc:`7638#section_3`. + * - **typ** + - It MUST be set to ``var+jwt`` + - + +The body of the Wallet Attestation Request JWT MUST contain: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **iss** + - Identifier of the Wallet Provider concatenated with thumbprint of the JWK in the ``cnf`` parameter. + - :rfc:`9126` and :rfc:`7519`. + * - **aud** + - It MUST be set to the identifier of the Wallet Provider. + - :rfc:`9126` and :rfc:`7519`. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT. + - :rfc:`9126` and :rfc:`7519`. + * - **iat** + - REQUIRED. UNIX Timestamp with the time of JWT issuance. + - :rfc:`9126` and :rfc:`7519`. + * - **challenge** + - Challenge data obtained from ``nonce`` endpoint + - + * - **hardware_signature** + - The signature of ``client_data`` obtained using Cryptographic Hardware Key base64 encoded. + - + * - **integrity_assertion** + - The integrity assertion obtained from the **Device Integrity Service** with the holder binding of ``client_data``. + - + * - **hardware_key_tag** + - Unique identifier of the **Cryptographic Hardware Keys** + - + * - **cnf** + - JSON object, containing the public part of an asymmetric key pair owned by the Wallet Instance. + - :rfc:`7800` + * - **vp_formats_supported** + - JSON object with name/value pairs, identifying a Credential format supported by the Wallet. + - + * - **authorization_endpoint** + - URL of the Wallet Authorization Endpoint (custom url schema or universal link of the Wallet Instance). + - + * - **response_types_supported** + - JSON array containing a list of the OAuth 2.0 ``response_type`` values. + - + * - **response_modes_supported** + - JSON array containing a list of the OAuth 2.0 "response_mode" values that this authorization server supports. + - :rfc:`8414` + * - **request_object_signing_alg_values_supported** + - JSON array containing a list of the JWS signing algorithms (alg values) supported. + - + * - **presentation_definition_uri_supported** + - Boolean value specifying whether the Wallet Instance supports the transfer of presentation_definition by reference. MUST be set to false. + - + +.. _table_wallet_attestation_claim: + +Wallet Attestation +~~~~~~~~~~~~~~~~~~ + +The JOSE header of the Wallet Attestation JWT MUST contain: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **JOSE header** + - **Description** + - **Reference** + * - **alg** + - A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section `Cryptographic Algorithms `_ and MUST NOT be set to ``none`` or any symmetric algorithm (MAC) identifier. + - :rfc:`7516#section-4.1.1`. + * - **kid** + - Unique identifier of the ``jwk`` inside the ``cnf`` claim of Wallet Instance as base64url-encoded JWK Thumbprint value. + - :rfc:`7638#section_3`. + * - **typ** + - It MUST be set to ``wallet-attestation+jwt`` + - `OPENID4VC-HAIP`_ + * - **trust_chain** + - Sequence of Entity Statements that composes the Trust Chain related to the Relying Party. + - `OID-FED`_ Section *3.2.1. Trust Chain Header Parameter*. + +The body of the Wallet Attestation JWT MUST contain: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - **Claim** + - **Description** + - **Reference** + * - **iss** + - Identifier of the Wallet Provider + - :rfc:`9126` and :rfc:`7519`. + * - **sub** + - Identifier of the Wallet Instance which is the thumbprint of the Wallet Instance JWK contained in the ``cnf`` claim. + - :rfc:`9126` and :rfc:`7519`. + * - **exp** + - UNIX Timestamp with the expiry time of the JWT. + - :rfc:`9126` and :rfc:`7519`. + * - **iat** + - UNIX Timestamp with the time of JWT issuance. + - :rfc:`9126` and :rfc:`7519`. + * - **cnf** + - JSON object, containing the public part of an asymmetric key pair owned by the Wallet Instance. + - :rfc:`7800` + * - **aal** + - JSON String asserting the authentication level of the Wallet and the key as asserted in the cnf claim. + - + * - **authorization_endpoint** + - URL of the Wallet Authorization Endpoint (Universal Link). + - + * - **response_types_supported** + - JSON array containing a list of the OAuth 2.0 ``response_type`` values. + - + * - **response_modes_supported** + - JSON array containing a list of the OAuth 2.0 "response_mode" values that this authorization server supports. + - :rfc:`8414` + * - **vp_formats_supported** + - JSON object with name/value pairs, identifying a Credential format supported by the Wallet. + - + * - **request_object_signing_alg_values_supported** + - JSON array containing a list of the JWS signing algorithms (alg values) supported. + - + * - **presentation_definition_uri_supported** + - Boolean value specifying whether the Wallet Instance supports the transfer of presentation_definition by reference. MUST be set to false. + - + + +Wallet Instance Lifecycle +----------------------------- + +The ability of the Wallet Instance to obtain a Wallet Attestation is bound to its current state. +The Wallet Instance assesses its current state based on the Credentials stored locally and the Wallet Attestation issued by the Wallet Provider. + +The lifecycle of a Wallet Instance encompasses all the potential states it can configure, along with the transitions from one state to another. This lifecycle is depicted in the diagram below: + +.. figure:: ../../images/wallet_instance_lifecycle.svg + :name: Wallet Instance Lifecycle + :alt: Illustration representing the Wallet Instance lifecycle, with the states explained below. + :target: https://www.plantuml.com/plantuml/uml/SoWkIImgAStDuOhMYbNGrRLJyCm32kNafAPOAMH2c5mAG00N1YloBqWjIYp9pCzBpB5IA4ijoaoh1Ab25WUh2qlCoKm1gW1HYIMf83KGCKnJClDmg799JKmkoIm3IW1DAaejoyzEHRSBfpfCbmEzQQLGceVaDOH6x4emxS9KWd0mfgH3QbuAC801 + + +A Wallet Instance SHOULD obtain a Wallet Attestation if it's in either `Installed`, `Operational` or `Valid` state; that implies that a `Deactivated` Wallet Instance cannot obtain a Wallet Attestation hence it cannot interact with other entities of the ecosystem, such as PID/(Q)EAA Providers and Relying Parties. + +States +~~~~~~~~~~~~~~~~~~ +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **State** + - **Description** + * - `Installed` + - The User has installed the Wallet Solution on the device. + * - `Operational` + - The Wallet Instance has been verified and the Wallet Hardware Key has been registered; no valid PID is present in the storage. + * - `Valid` + - A valid PID is present in the storage. + * - `Deactivated` + - The Wallet Instance has been revoked and its Wallet Hardware Key has been marked as not usable. + +Transitions +~~~~~~~~~~~~~~~~~~ +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Transition** + - **Description** + * - `install` + - The User performs a fresh installation or restores the initial state of the Wallet Instance on the device. + * - `verify` + - The Wallet Instance has been verified by the Wallet Provider and its Wallet Hardware Key has been registered. + * - `validate` + - The Wallet Instance obtains a valid PID. + * - `invalidate` + - The PID expires or gets revoked. + * - `revoke` + - The Wallet Provider marks the Wallet Instance as not usable. + * - `uninstall` + - The User removes the Wallet Instance from the device. + +Revocations +~~~~~~~~~~~~~~~~~~ +As mentioned in the *Wallet Instance initialization and registration* section above, a Wallet Instance is bound to a Wallet Hardware Key and it's uniquely identified by it. +The Wallet Instance SHOULD send its public Wallet Hardware Key with the Wallet Provider, thus the Wallet Provider MUST identify a Wallet Instance by its Wallet Hardware Key. + +When a Wallet Instance is not usable anymore, the Wallet Provider MUST revoke it. The revocation process is a unilateral action taken by the Wallet Provider, and it MUST be performed when the Wallet Instance is in the `Operational` or `Valid` state. +A Wallet Instance becomes unusable for several reasons, such as: the User requests the revocation, the Wallet Provider detects a security issue, or the Wallet Instance is no longer compliant with the Wallet Provider's security requirements. + +The details of the revocation mechanism used by the Wallet Provider as well as the data model for maintaining the Wallet Instance references is delegated to the Wallet Provider's implementation. + +According to ARF, `Section 6.5.4 `_ and more specifically in `Topic 38 `_ the Wallet Instance can be revoked by the following entities: + + 1. Its owner, the User + 2. Wallet Provider + 3. PID Provider + +During the *Wallet Instance initialization and registration* phase the Wallet Provider MAY associate the Wallet Instance with a specific User, subject to obtaining the User's consent. The Wallet Provider MUST evaluate the operating system and general technical capabilities of the device to check compliance with the technical and security requirements and to produce the Wallet Instance metadata. +When the User consents to being linked with the Wallet Instance, they gain the ability to directly request Wallet revocation from the Wallet Provider, and it also allows the Wallet Provider to revoke the Wallet Instance associated with that User. + +Regarding the reasons for revoking a Wallet Instance, the following scenarios may occur: + +- The smartphone is lost; +- The smartphone has been compromised (e.g., a malicious actor gains control of the smartphone); +- The smartphone has been reset to factory settings; +- Any other scenarios where the User loses the control of the Wallet Instance. + +If any of the previous scenarios occur, the Wallet Instance **MUST** be revoked. +To allow the User to revoke the Wallet Instance, the Wallet Provider (WP) **MUST** offer a remote service, such as a web page, where the User can authenticate and request the revocation of a previously activated Wallet Instance. + +.. _token endpoint: wallet-solution.html#wallet-attestation +.. _Wallet Attestation Request: wallet-attestation.html#format-of-the-wallet-attestation-request +.. _Wallet Attestation: wallet-attestation.html#format-of-the-wallet-attestation +.. _RFC 7523 section 4: https://www.rfc-editor.org/rfc/rfc7523.html#section-4 +.. _RFC 8414 section 2: https://www.rfc-editor.org/rfc/rfc8414.html#section-2 +.. _Wallet Provider metadata: wallet-solution.html#wallet-provider-metadata +.. _Play Integrity API: https://developer.android.com/google/play/integrity?hl=it +.. _DeviceCheck: https://developer.apple.com/documentation/devicecheck +.. _OAuth 2.0 Nonce Endpoint: https://datatracker.ietf.org/doc/draft-demarco-oauth-nonce-endpoint/ +.. _ARF: https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework diff --git a/refs/pull/443/merge/en/_sources/wallet-solution.rst.txt b/refs/pull/443/merge/en/_sources/wallet-solution.rst.txt new file mode 100644 index 000000000..ae2dcc15c --- /dev/null +++ b/refs/pull/443/merge/en/_sources/wallet-solution.rst.txt @@ -0,0 +1,277 @@ +.. include:: ../common/common_definitions.rst + +.. _wallet-solution.rst: + +Wallet Solution +------------------- + +The Wallet Solution is issued by the Wallet Provider in the form of a mobile app and services, such as web interfaces. + +The mobile app serves as the primary interface for Users, +allowing them to hold their Digital Credentials and interact with other participants of the ecosystem, +such as Credential Issuers and Relying Parties. + +These Credentials are a set of data that can uniquely identify a natural or legal person, +along with other Qualified and non-qualified Electronic Attestations of Attributes, +also known as QEAAs and EAAs respectively, or (Q)EAAs for short[1]. + +Once a User installs the mobile app on their device, such an installation is referred to as a Wallet Instance for the User. + +By supporting the mobile app, the Wallet Provider enusers the security and reliability of the entire Wallet Solution, +as it is responsible for issuing the Wallet Attestation, +which is a cryptographic proof about the authenticity and integrity of the Wallet Instance. + +Requirements +^^^^^^^^^^^^ + +This section lists the requirements that are be met by Wallet Providers and Wallet Solutions. + + - The Wallet Provider MUST offer a RESTful set of services for issuing the Wallet Attestations. + - The Wallet Instance MUST periodically reestablish trust with its Wallet Provider. + - The Wallet Instance MUST establish trust with other participants of the Wallet ecosystem, such as Credential Issers and Relying Parties. + - The Wallet Solutions MUST adhere to the specifications set by this document for obtaining Personal Identification (PID) and (Q)EAAs. + - The Wallet Instance MUST be compatible and functional on both Android and iOS operating systems and available on the Play Store and App Store, respectively. + - The Wallet Instance MUST provide a mechanism to verify the User's actual possession and full control of their personal device. + +Wallet Instance +^^^^^^^^^^^^^^^ +The Wallet Instance serves as a unique and secure device for authenticating the User within the Wallet ecosystem. +It establishes a strong and reliable mechanism for the User to engage in various digital transactions in a secure and privacy-preserving manner. + +The Wallet Instance allows other entities within the ecosystem to establish trust with it, by consistently +presenting a Wallet Attestation during interactions with PID Providers, +(Q)EAA Providers, and Relying Parties. These verifiable attestations, provided by the Wallet Provider, +serve to authenticate the Wallet Instance itself, ensuring its reliability when engaging with other ecosystem actors. + +To guarantee the utmost security, these cryptographic keys MUST be securely stored within the WSCD, which MAY be internal (device's Trusted Execution Environment (TEE)[3]), external, or hybrid. This ensures that only the User can access them, thus preventing unauthorized usage or tampering. For more detailed information, please refer to the `Wallet Attestation section`_ and the `Trust Model section`_ of this document. + +Wallet Instance Lifecycle +^^^^^^^^^^^^^^^^^^^^^^^^^ +The Wallet Instance has three distinct states: Operational, Valid, and Deactivated. +Each state represents a specific functional status and determines the actions that can be performed[2]. + +Initialization Process +~~~~~~~~~~~~~~~~~~~~~~ +To activate the Wallet Instance, Users MUST install the mobile Wallet application on their device and open it. Furthermore, Users will be asked to set their preferred method of unlocking their device; this can be accomplished by entering a personal identification number (PIN) or by utilizing biometric authentication, such as fingerprint or facial recognition, according to their personal preferences and device's capabilities. + +After completing these steps, the Wallet Instance enters the Operational state. + +Transition to Valid state +~~~~~~~~~~~~~~~~~~~~~~~~~ +To transition from the Operational state to the Valid state, the Wallet Instance MUST obtain a valid Personal Identification (PID). Once a valid PID is acquired, the Wallet Instance becomes Valid. + +The Wallet Instance MUST demonstrate to the Credential Issuer adequate security compliance to maintain the Credential at the same LoA at which it was issued. + +Once the Wallet Instance is in the Valid state, Users can: + + - Obtain, view, and manage (Q)EAAs from trusted (Q)EAA Providers[1]; + - Authenticate to Relying Parties[1]; + - Authorize the presentation of their digital Credentials to Relying Parties. + +Please refer to the relevant sections for further information about PID and (Q)EAAs issuance and presentation. + +Return to Operational state +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A Valid Wallet Instance may revert to the Operational state under specific circumstances. These circumstances include the expiration or revocation of the associated PID by its PID Provider. + +Deactivation +~~~~~~~~~~~~ +Users have the ability to deactivate the Wallet Instance voluntarily. This action removes the operational capabilities of the Wallet Instance and sets it to the Deactivated state. Deactivation provides Users with control over access and usage according to their preferences. + +Wallet Provider Endpoints +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Wallet Provider that issues the Wallet Attestations MUST make its APIs available in the form of RESTful services, as listed below. + +Wallet Provider Metadata +~~~~~~~~~~~~~~~~~~~~~~~~ +An HTTP GET request to the **/.well-known/openid-federation** endpoint allows the retrieval of the Wallet Provider Entity Configuration. + +The Wallet Provider Entity Configuration is a JWS containing the public keys and supported algorithms of the Wallet Provider metadata definition. It is structured in accordance with the `OpenID Connect Federation `_ and the Trust Model section outlined in this specification. + +The returning Entity Configuration of the Wallet Provider MUST contain the attributes listed below: + +Header +^^^^^^ +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - **Key** + - **Value** + * - alg + - Algorithm used to verify the token signature. It MUST be one of the possible values indicated in this `table `_ (e.g., ES256). + * - kid + - Thumbprint of the public key used for signing, according to :rfc:`7638`. + * - typ + - Media type, set to ``entity-statement+jwt``. + +Payload +^^^^^^^ +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - **Key** + - **Value** + * - iss + - Public URL of the Wallet Provider. + * - sub + - Public URL of the Wallet Provider. + * - iat + - Issuance datetime in Unix Timestamp format. + * - exp + - Expiration datetime in Unix Timestamp format. + * - authority_hints + - Array of URLs (String) containing the list of URLs of the immediate superior Entities, such as the Trust Anchor or an Intermediate, that MAY issue an Entity Statement related to this subject. + * - jwks + - A JSON Web Key Set (JWKS) `RFC 7517 `_ that represents the public part of the signing keys of the Entity at issue. Each JWK in the JWK set MUST have a key ID (claim kid). + * - metadata + - Contains the ``wallet_provider`` and ``federation_entity`` metadata. + +wallet_provider metadata +~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++---------------------------------------------+---------------------------------------------------------------------+ +| **Key** | **Value** | ++---------------------------------------------+---------------------------------------------------------------------+ +| jwks | A JSON Web Key Set (JWKS) | +| | that represents the Wallet | +| | Provider's public keys. | ++---------------------------------------------+---------------------------------------------------------------------+ +| token_endpoint | Endpoint for obtaining the Wallet | +| | Instance Attestation. | ++---------------------------------------------+---------------------------------------------------------------------+ +| nonce_endpoint | HTTPs URL indicating the endpoint | +| | where the client can request the nonce. | ++---------------------------------------------+---------------------------------------------------------------------+ +| aal_values_supported | List of supported values for the | +| | certifiable security context. These | +| | values specify the security level | +| | of the app, according to the levels: low, medium, or high. | +| | Authenticator Assurance Level values supported. | ++---------------------------------------------+---------------------------------------------------------------------+ +| grant_types_supported | The types of grants supported by | +| | the token endpoint. It MUST be set to | +| | ``urn:ietf:params:oauth:client-assertion-type: | +| | jwt-client-attestation``. | ++---------------------------------------------+---------------------------------------------------------------------+ +| token_endpoint_auth_methods_suppor | Supported authentication methods for | +| ted | the token endpoint. | ++---------------------------------------------+---------------------------------------------------------------------+ +| token_endpoint_auth_signing_alg_va | Supported signature | +| lues_supported | algorithms for the token endpoint. | ++---------------------------------------------+---------------------------------------------------------------------+ + + +.. note:: + The `aal_values_supported` parameter is experimental and under review. + +Payload `federation_entity` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++-------------------+----------------------------------------------+ +| **Key** | **Value** | ++-------------------+----------------------------------------------+ +| organization_name | Organization name. | ++-------------------+----------------------------------------------+ +| homepage_uri | Organization's website URL. | ++-------------------+----------------------------------------------+ +| tos_uri | URL to the terms of service. | ++-------------------+----------------------------------------------+ +| policy_uri | URL to the privacy policy. | ++-------------------+----------------------------------------------+ +| logo_uri | URL of the organization's logo in SVG format.| ++-------------------+----------------------------------------------+ + +Below a non-normative example of the Entity Configuration. + +.. code-block:: javascript + + { + "alg": "ES256", + "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY", + "typ": "entity-statement+jwt" + } + . + { + "iss": "https://wallet-provider.example.org", + "sub": "https://wallet-provider.example.org", + "jwks": { + "keys": [ + { + "crv": "P-256", + "kty": "EC", + "x": "qrJrj3Af_B57sbOIRrcBM7br7wOc8ynj7lHFPTeffUk", + "y": "1H0cWDyGgvU8w-kPKU_xycOCUNT2o0bwslIQtnPU6iM", + "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY" + } + ] + }, + "metadata": { + "wallet_provider": { + "jwks": { + "keys": [ + { + "crv": "P-256", + "kty": "EC", + "x": "qrJrj3Af_B57sbOIRrcBM7br7wOc8ynj7lHFPTeffUk", + "y": "1H0cWDyGgvU8w-kPKU_xycOCUNT2o0bwslIQtnPU6iM", + "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY" + } + ] + }, + "token_endpoint": "https://wallet-provider.example.org/token", + "nonce_endpoint": "https://wallet-provider.example.org/nonce", + "aal_values_supported": [ + "https://wallet-provider.example.org/LoA/basic", + "https://wallet-provider.example.org/LoA/medium", + "https://wallet-provider.example.org/LoA/high" + ], + "grant_types_supported": [ + "urn:ietf:params:oauth:client-assertion-type:jwt-client-attestation" + ], + "token_endpoint_auth_methods_supported": [ + "private_key_jwt" + ], + "token_endpoint_auth_signing_alg_values_supported": [ + "ES256", + "ES384", + "ES512" + ] + }, + "federation_entity": { + "organization_name": "IT-Wallet Provider", + "homepage_uri": "https://wallet-provider.example.org", + "policy_uri": "https://wallet-provider.example.org/privacy_policy", + "tos_uri": "https://wallet-provider.example.org/info_policy", + "logo_uri": "https://wallet-provider.example.org/logo.svg" + } + }, + "authority_hints": [ + "https://registry.eudi-wallet.example.it" + ] + "iat": 1687171759, + "exp": 1709290159 + } + + +Wallet Attestation +~~~~~~~~~~~~~~~~~~ + +Please refer to the `Wallet Attestation section`_. + + +External references +^^^^^^^^^^^^^^^^^^^^ +.. [1] Definitions are inherited from the EUDI Wallet Architecture and Reference Framework, version 1.1.0 at the time of writing. Please refer to `this page `_ for extended definitions and details. + +.. [2] Wallet Instance states adhere to the EUDI Wallet Architecture and Reference Framework, as defined `here `_. + +.. [3] Depending on the device operating system, TEE is defined by `Trusty`_ or `Secure Enclave`_ for Android and iOS devices, respectively. + +.. _Trust Model section: trust.html +.. _Wallet Attestation section: wallet-attestation.html +.. _Trusty: https://source.android.com/docs/security/features/trusty +.. _Secure Enclave: https://support.apple.com/en-gb/guide/security/sec59b0b31ff/web + diff --git a/refs/pull/443/merge/en/_static/basic.css b/refs/pull/443/merge/en/_static/basic.css new file mode 100644 index 000000000..f316efcb4 --- /dev/null +++ b/refs/pull/443/merge/en/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/refs/pull/443/merge/en/_static/basic_mod.css b/refs/pull/443/merge/en/_static/basic_mod.css new file mode 100644 index 000000000..0df77588f --- /dev/null +++ b/refs/pull/443/merge/en/_static/basic_mod.css @@ -0,0 +1,1194 @@ +@font-face { + font-family: Roboto; + font-style: normal; + font-weight: 400; + src: local("Roboto"), local("Roboto-Regular"), url(fonts/roboto/roboto.woff2) format("woff2"); +} +@font-face { + font-family: Roboto; + font-style: italic; + font-weight: 400; + src: local("Roboto Italic"), local("Roboto-Italic"), url(fonts/roboto/roboto-italic.woff2) format("woff2"); +} +@font-face { + font-family: Roboto; + font-style: normal; + font-weight: 700; + src: local("Roboto Bold"), local("Roboto-Bold"), url(fonts/roboto/roboto-bold.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: normal; + font-weight: 400; + src: local("Roboto Mono Regular"), local("RobotoMono-Regular"), url(fonts/roboto-mono/roboto-mono.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: italic; + font-weight: 400; + src: local("Roboto Mono Italic"), local("RobotoMono-Italic"), url(fonts/roboto-mono/roboto-mono-italic.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: normal; + font-weight: 700; + src: local("Roboto Mono Bold"), local("RobotoMono-Bold"), url(fonts/roboto-mono/roboto-mono-bold.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: italic; + font-weight: 700; + src: local("Roboto Mono Bold Italic"), local("RobotoMono-BoldItalic"), url(fonts/roboto-mono/roboto-mono-bold-italic.woff2) format("woff2"); +} +/*****************************************************************************/ +/* Typography */ +:root { + --codeBackgroundColor: #f8f8f8; + --inlineCodeBackgroundColor: #f8f8f8; + --codeBlue: #0000ff; + --codeGreen: #008000; + --dividerColor: rgba(0, 0, 0, 0.08); + --faintFontColor: rgba(0, 0, 0, 0.6); + --fontColor: #252630; + --linkColor: #2980b9; + --mainBackgroundColor: white; + --mainNavColor: #3889ce; + --notificationBannerColor: #176bb0; + --searchHighlightColor: #fff150; + --sidebarColor: white; + --navbarHeight: 4rem; +} +:root[data-mode=darkest] { + --mainBackgroundColor: black; + --sidebarColor: black; + --codeBackgroundColor: rgba(255, 255, 255, 0.1); + --inlineCodeBackgroundColor: rgba(255, 255, 255, 0.1); +} +:root[data-mode=dark] { + --mainBackgroundColor: #242429; + --sidebarColor: #242429; + --codeBackgroundColor: rgba(0, 0, 0, 0.1); + --inlineCodeBackgroundColor: rgba(255, 255, 255, 0.06); +} +:root[data-mode=dark], :root[data-mode=darkest] { + --codeBlue: #77baff; + --codeGreen: #38c038; + --dividerColor: rgba(255, 255, 255, 0.1); + --faintFontColor: rgba(255, 255, 255, 0.6); + --fontColor: white; + --linkColor: #319be0; + --searchHighlightColor: #fe8e04; +} + +body { + font-family: Roboto, "OpenSans", sans-serif; + background-color: var(--mainBackgroundColor); + color: var(--fontColor); +} + +h1 { + font-size: 2rem; +} + +h2 { + font-size: 1.5rem; +} + +h3 { + font-size: 1.17rem; +} + +a { + color: var(--linkColor); + text-decoration: none; +} + +/*****************************************************************************/ +html { + height: 100%; + scroll-padding-top: var(--navbarHeight); +} + +html, +body { + padding: 0; + margin: 0; + min-height: 100%; +} + +body { + display: flex; + flex-direction: column; +} + +/*****************************************************************************/ +/* Top nav */ +#searchbox h3#searchlabel { + display: none; +} +#searchbox form.search { + display: flex; + flex-direction: row; +} +#searchbox form.search input { + display: block; + box-sizing: border-box; + padding: 0.3rem; + color: rgba(0, 0, 0, 0.7); + border-radius: 0.2rem; +} +#searchbox form.search input[type=text] { + border: none; + background-color: rgba(255, 255, 255, 0.6); + flex-grow: 1; + margin-right: 0.2rem; +} +#searchbox form.search input[type=text]::placeholder { + color: rgba(0, 0, 0, 0.6); +} +#searchbox form.search input[type=submit] { + cursor: pointer; + color: var(--mainNavColor); + flex-grow: 0; + border: none; + background-color: white; +} + +div#top_nav { + position: fixed; + top: 0; + left: 0; + right: 0; + color: white; + z-index: 100; +} +div#top_nav div#notification_banner { + background-color: var(--notificationBannerColor); + box-sizing: border-box; + padding: 0.1rem 1rem; + display: flex; + flex-direction: row; + align-items: center; + justify-content: right; +} +div#top_nav div#notification_banner a.close { + flex-grow: 0; + flex-shrink: 0; + color: rgba(255, 255, 255, 0.85); + text-align: right; + font-size: 0.6rem; + text-transform: uppercase; + display: block; + text-decoration: none; + margin-left: 0.5rem; +} +div#top_nav div#notification_banner a.close:hover { + color: white; +} +div#top_nav div#notification_banner p { + flex-grow: 1; + margin: 0; + text-align: center; + font-size: 0.9rem; + line-height: 1.2; + padding: 0.4rem 0; +} +div#top_nav div#notification_banner p a { + color: white; + text-decoration: underline; +} +div#top_nav nav { + background-color: var(--mainNavColor); + box-sizing: border-box; + padding: 1rem; + display: flex; + flex-direction: row; + align-items: center; +} +div#top_nav nav h1 { + flex-grow: 1; + font-size: 1.2rem; + margin: 0; + padding: 0 0 0 0.8rem; + line-height: 1; +} +div#top_nav nav h1 a { + color: white; +} +div#top_nav nav h1 img { + height: 1.3rem; + width: auto; +} +div#top_nav nav p#toggle_sidebar { + transform: rotate(90deg); + letter-spacing: 0.1rem; + flex-grow: 0; + margin: 0; + padding: 0; +} +div#top_nav nav p#toggle_sidebar a { + color: white; + font-weight: bold; +} +div#top_nav nav a#mode_toggle, div#top_nav nav a#source_link { + margin-right: 1rem; + display: block; + flex-grow: 0; +} +div#top_nav nav a#mode_toggle svg, div#top_nav nav a#source_link svg { + height: 1.3rem; + width: 1.3rem; + vertical-align: middle; +} +div#top_nav nav p.mobile_search_link { + margin: 0; +} +@media (min-width: 50rem) { + div#top_nav nav p.mobile_search_link { + display: none; + } +} +div#top_nav nav p.mobile_search_link a { + color: white; +} +div#top_nav nav p.mobile_search_link a svg { + height: 1rem; + vertical-align: middle; +} +@media (max-width: 50rem) { + div#top_nav nav div.searchbox_wrapper { + display: none; + } +} +div#top_nav nav div.searchbox_wrapper #searchbox { + align-items: center; + display: flex !important; + flex-direction: row-reverse; +} +div#top_nav nav div.searchbox_wrapper #searchbox p.highlight-link { + margin: 0 0.5rem 0 0; +} +div#top_nav nav div.searchbox_wrapper #searchbox p.highlight-link a { + color: rgba(255, 255, 255, 0.8); + font-size: 0.8em; + padding-right: 0.5rem; + text-decoration: underline; +} +div#top_nav nav div.searchbox_wrapper #searchbox p.highlight-link a:hover { + color: white; +} + +/*****************************************************************************/ +/* Main content */ +div.document { + flex-grow: 1; + margin-top: 2rem; + margin-bottom: 5rem; + margin-left: 15rem; + margin-right: 15rem; + padding-top: var(--navbarHeight); + /***************************************************************************/ + /***************************************************************************/ +} +@media (max-width: 50rem) { + div.document { + margin-left: 0px; + margin-right: 0px; + } +} +div.document section, +div.document div.section { + margin: 4rem 0; +} +div.document section:first-child, +div.document div.section:first-child { + margin-top: 0; +} +div.document section > section, +div.document div.section > div.section { + margin: 4rem 0; +} +div.document section > section > section, +div.document div.section > div.section > div.section { + margin: 2rem 0 0 0; +} +div.document section > section > section > section, +div.document div.section > div.section > div.section > div.section { + margin: 1.5rem 0 0 0; +} +div.document h1 + section, +div.document h1 + div.section { + margin-top: 2.5rem !important; +} +div.document h2 + section, +div.document h2 + div.section { + margin-top: 1.5rem !important; +} +div.document img { + max-width: 100%; +} +div.document code { + padding: 2px 4px; + background-color: var(--inlineCodeBackgroundColor); + border-radius: 0.2rem; + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; + font-size: 0.9em; +} +div.document div.documentwrapper { + max-width: 45rem; + margin: 0 auto; + flex-grow: 1; + box-sizing: border-box; + padding: 1rem; +} +div.document div.highlight { + color: #252630; + box-sizing: border-box; + padding: 0.2rem 1rem; + margin: 0.5rem 0; + border-radius: 0.2rem; + font-size: 0.9rem; +} +div.document div.highlight pre { + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; +} +div.document div[class*=highlight] { + overflow-x: auto; +} +div.document a.headerlink { + font-size: 0.6em; + display: none; + padding-left: 0.5rem; + vertical-align: middle; +} +div.document h1, +div.document h2, +div.document h3, +div.document h4, +div.document h5, +div.document h6, +div.document str, +div.document b { + font-weight: 700; +} +div.document h1 { + margin: 0.8rem 0 0.5rem 0; +} +div.document h2 { + margin: 0.8rem 0 0.5rem 0; +} +div.document h3, div.document h4 { + margin: 1rem 0 0.5rem 0; +} +div.document h1:hover a.headerlink, +div.document h2:hover a.headerlink, +div.document h3:hover a.headerlink, +div.document h4:hover a.headerlink { + display: inline-block; +} +div.document p, +div.document li { + font-size: 1rem; + line-height: 1.5; +} +div.document li p { + margin: 0 0 0.5rem 0; +} +div.document ul, div.document ol { + padding-left: 2rem; +} +div.document ol.loweralpha { + list-style: lower-alpha; +} +div.document ol.arabic { + list-style: decimal; +} +div.document ol.lowerroman { + list-style: lower-roman; +} +div.document ol.upperalpha { + list-style: upper-alpha; +} +div.document ol.upperroman { + list-style: upper-roman; +} +div.document dd { + margin-left: 1.5rem; +} +div.document hr { + border: none; + height: 1px; + background-color: var(--dividerColor); + margin: 2rem 0; +} +div.document table.docutils { + border-collapse: collapse; +} +div.document table.docutils th, div.document table.docutils td { + border: 1px solid var(--dividerColor); + box-sizing: border-box; + padding: 0.5rem 1rem; +} +div.document table.docutils th p, div.document table.docutils th ul, div.document table.docutils td p, div.document table.docutils td ul { + margin: 0.3rem 0; +} +div.document table.docutils th ul, div.document table.docutils td ul { + padding-left: 1rem; +} +div.document form input { + padding: 0.5rem; +} +div.document form input[type=submit], div.document form button { + border: none; + background-color: var(--mainNavColor); + color: white; + padding: 0.5rem 1rem; + border-radius: 0.2rem; +} +div.document span.highlighted { + background-color: var(--searchHighlightColor); + padding: 0 0.1em; +} +div.document div#search-results { + padding-top: 2rem; +} +div.document div#search-results p.search-summary { + font-size: 0.8em; +} +div.document div#search-results ul.search { + list-style: none; + padding-left: 0; +} +div.document div#search-results ul.search li { + border-bottom: 1px solid var(--dividerColor); + margin: 0; + padding: 2rem 0; +} +div.document div#search-results ul.search li > a:first-child { + font-size: 1.2rem; +} +div.document dd ul, div.document dd ol { + padding-left: 1rem; +} +div.document dl.py { + margin-bottom: 2rem; +} +div.document dl.py dt.sig { + background-color: var(--codeBackgroundColor); + color: var(--fontColor); + box-sizing: border-box; + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; + font-size: 0.9rem; + padding: 1rem; + border-left: 5px solid rgba(0, 0, 0, 0.1); + border-radius: 0.2rem; +} +div.document dl.py em.property { + color: var(--sidebarColor); + font-weight: bold; +} +div.document dl.py span.sig-name { + color: var(--codeBlue); + font-weight: bold; +} +div.document dl.py em.property { + color: var(--codeGreen); +} +div.document dl.py em.sig-param { + margin-left: 2rem; +} +div.document dl.py em.sig-param span.default_value { + color: var(--codeGreen); +} +div.document dl.py span.sig-return span.sig-return-typehint { + color: var(--fontColor); +} +div.document dl.py span.sig-return span.sig-return-typehint pre { + color: var(--fontColor); +} +div.document dl.py em.sig-param > span:first-child { + font-weight: bold; +} +div.document dl.cpp, div.document dl.c { + margin-bottom: 1rem; +} +div.document dl.cpp dt.sig, div.document dl.c dt.sig { + background-color: var(--codeBackgroundColor); + color: var(--fontColor); + box-sizing: border-box; + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; + font-size: 0.9rem; + padding: 1rem; + border-left: 5px solid rgba(0, 0, 0, 0.1); + border-radius: 0.2rem; + line-height: 1.4; +} +div.document dl.cpp span.sig-name, div.document dl.c span.sig-name { + color: var(--codeBlue); + font-weight: bold; +} +div.document dl.cpp span.sig-indent, div.document dl.c span.sig-indent { + margin-left: 2rem; +} +div.document dl.cpp span.target + span, div.document dl.c span.target + span { + color: var(--codeGreen); +} +div.document dl.cpp span.sig-param > span:first-child, div.document dl.c span.sig-param > span:first-child { + font-weight: bold; +} +div.document div.admonition { + box-shadow: 0px 0px 0px 1px var(--dividerColor); + border-radius: 0.2rem; + margin: 1rem 0; + overflow: hidden; +} +div.document div.admonition p { + box-sizing: border-box; + font-size: 0.9rem; + padding: 0.5rem; + margin: 0; +} +div.document div.admonition p:first-child { + padding-bottom: 0; + margin-bottom: 0; +} +div.document div.admonition p + p { + padding-top: 0.2rem; +} +div.document div.admonition p.admonition-title { + font-weight: bolder; + letter-spacing: 0.01rem; +} +div.document div.admonition.hint, div.document div.admonition.important, div.document div.admonition.tip { + border-left: 5px solid #56b79c; +} +div.document div.admonition.hint p.admonition-title, div.document div.admonition.important p.admonition-title, div.document div.admonition.tip p.admonition-title { + color: #56b79c; +} +div.document div.admonition.note { + border-left: 5px solid #587f9f; +} +div.document div.admonition.note p.admonition-title { + color: #587f9f; +} +div.document div.admonition.danger, div.document div.admonition.error { + border-left: 5px solid #e6a39a; +} +div.document div.admonition.danger p.admonition-title, div.document div.admonition.error p.admonition-title { + color: #e6a39a; +} +div.document div.admonition.attention, div.document div.admonition.caution, div.document div.admonition.warning { + border-left: 5px solid #e7b486; +} +div.document div.admonition.attention p.admonition-title, div.document div.admonition.caution p.admonition-title, div.document div.admonition.warning p.admonition-title { + color: #e7b486; +} + +/*****************************************************************************/ +/* Sidebar */ +div.sphinxsidebar { + background-color: var(--sidebarColor); + border-right: 1px solid var(--dividerColor); + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: 15rem; + box-sizing: border-box; + padding: var(--navbarHeight) 1rem 1rem; + z-index: 50; +} +@media (max-width: 50rem) { + div.sphinxsidebar { + display: none; + } +} +div.sphinxsidebar div.sphinxsidebarwrapper { + height: 100%; + overflow-y: auto; +} +div.sphinxsidebar ul { + padding-left: 0rem; + list-style: none; +} +div.sphinxsidebar ul li { + font-size: 0.9rem; + line-height: 1.2; +} +div.sphinxsidebar ul li a { + display: block; + box-sizing: border-box; + padding: 0 0.2rem 0.6rem; + color: var(--fontColor); + text-decoration: none; +} +div.sphinxsidebar ul li a.current { + color: var(--linkColor); +} +div.sphinxsidebar ul li a:hover { + color: var(--linkColor); +} +div.sphinxsidebar ul li > ul { + padding-left: 1rem; +} +div.sphinxsidebar p { + color: var(--faintFontColor); +} + +/*****************************************************************************/ +/* The right sidebar, showing the table of contents for the current page. */ +div#show_right_sidebar { + position: fixed; + right: 0; + top: 0; + z-index: 20; + background-color: var(--sidebarColor); + border-left: 1px solid var(--dividerColor); + border-bottom: 1px solid var(--dividerColor); + padding: var(--navbarHeight) 1rem 0rem; +} +div#show_right_sidebar p { + font-size: 0.9em; +} +div#show_right_sidebar p span { + color: var(--faintFontColor); + vertical-align: middle; +} +div#show_right_sidebar p span.icon { + color: var(--linkColor); + font-size: 0.9em; + padding-right: 0.2rem; +} + +div#right_sidebar { + position: fixed; + right: 0; + top: 0; + z-index: 50; + background-color: var(--sidebarColor); + width: 15rem; + border-left: 1px solid var(--dividerColor); + box-sizing: border-box; + padding: var(--navbarHeight) 1rem 1rem; + height: 100%; + overflow-y: auto; +} +div#right_sidebar p span { + color: var(--faintFontColor); + vertical-align: middle; +} +div#right_sidebar p span.icon { + color: var(--linkColor); + font-size: 0.9em; + padding-right: 0.2rem; +} +div#right_sidebar ul { + padding-left: 0rem; + list-style: none; +} +div#right_sidebar ul li { + font-size: 0.9rem; + line-height: 1.2; +} +div#right_sidebar ul li a { + display: block; + box-sizing: border-box; + padding: 0 0.2rem 0.6rem; + color: var(--fontColor); + text-decoration: none; +} +div#right_sidebar ul li a.current { + color: var(--linkColor); +} +div#right_sidebar ul li a:hover { + color: var(--linkColor); +} +div#right_sidebar ul li > ul { + padding-left: 1rem; +} +div#right_sidebar p { + color: var(--faintFontColor); +} +@media (max-width: 50rem) { + div#right_sidebar { + display: none; + } +} + +/*****************************************************************************/ +/* Footer */ +div.footer { + box-sizing: border-box; + padding-top: 2rem; + font-size: 0.7rem; + text-align: center; + text-transform: uppercase; + color: var(--faintFontColor); +} + +p#theme_credit { + font-size: 0.6rem; + text-transform: uppercase; + text-align: center; + color: var(--faintFontColor); +} + +/*****************************************************************************/ +/* Buttons */ +div.button_nav_wrapper { + margin-left: 15rem; + margin-right: 15rem; +} +@media (max-width: 50rem) { + div.button_nav_wrapper { + margin-left: 0px; + margin-right: 0px; + } +} +div.button_nav_wrapper div.button_nav { + max-width: 45rem; + margin: 0 auto; + display: flex; + flex-direction: row; + width: 100%; +} +div.button_nav_wrapper div.button_nav div { + box-sizing: border-box; + padding: 1rem; + flex: 50%; +} +div.button_nav_wrapper div.button_nav div a { + display: block; +} +div.button_nav_wrapper div.button_nav div a span { + vertical-align: middle; +} +div.button_nav_wrapper div.button_nav div a span.icon { + font-weight: bold; + font-size: 0.8em; +} +div.button_nav_wrapper div.button_nav div.left a { + text-align: left; +} +div.button_nav_wrapper div.button_nav div.left a span.icon { + padding-right: 0.4rem; +} +div.button_nav_wrapper div.button_nav div.right a { + text-align: right; +} +div.button_nav_wrapper div.button_nav div.right a span.icon { + padding-left: 0.4rem; +} + +/*****************************************************************************/ +/* Pygments overrides in dark mode */ +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight { + --black: #000000; + --red: #ff9393; + --darkBlue: #6b83fe; + --grey: #a8a8a8; + --pink: #ff99d8; + --torquoise: #68e9e9; + --brown: #d48a00; + --purple: #ce04e9; + --paleYellow: #454534; + background: var(--codeBackgroundColor); + color: var(--fontColor); + /* Comment */ + /* Error */ + /* Keyword */ + /* Operator */ + /* Comment.Hashbang */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.PreprocFile */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Deleted */ + /* Generic.Emph */ + /* Generic.Error */ + /* Generic.Heading */ + /* Generic.Inserted */ + /* Generic.Output */ + /* Generic.Prompt */ + /* Generic.Strong */ + /* Generic.Subheading */ + /* Generic.Traceback */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Namespace */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Number */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Decorator */ + /* Name.Entity */ + /* Name.Exception */ + /* Name.Function */ + /* Name.Label */ + /* Name.Namespace */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Bin */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Affix */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Delimiter */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Function.Magic */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Name.Variable.Magic */ + /* Literal.Number.Integer.Long */ +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight pre, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight pre { + line-height: 125%; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight td.linenos .normal, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight td.linenos .normal { + color: inherit; + background-color: transparent; + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight span.linenos, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight span.linenos { + color: inherit; + background-color: transparent; + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight td.linenos .special, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight td.linenos .special { + color: var(--black); + background-color: var(--paleYellow); + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight span.linenos.special, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight span.linenos.special { + color: var(--black); + background-color: var(--paleYellow); + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .hll, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .hll { + background-color: var(--paleYellow); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .c, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .c { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .err, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .err { + border: 1px solid var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .k, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .k { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .o, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .o { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ch, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ch { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cm, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cm { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cp { + color: var(--brown); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cpf, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cpf { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .c1, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .c1 { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cs, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cs { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gd { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ge, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ge { + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gr, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gr { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gh, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gh { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gi, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gi { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .go, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .go { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gp { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gs, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gs { + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gu, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gu { + color: var(--purple); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gt, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gt { + color: var(--codeBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kc { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kd { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kn, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kn { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kp { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kr, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kr { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kt, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kt { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .m, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .m { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .s, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .s { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .na, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .na { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nb, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nb { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nc { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .no, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .no { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nd { + color: var(--purple); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ni, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ni { + color: var(--grey); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ne, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ne { + color: var(--red); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nf, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nf { + color: var(--codeBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nl, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nl { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nn, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nn { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nt, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nt { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nv, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nv { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ow, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ow { + color: var(--pink); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .w, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .w { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mb, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mb { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mf, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mf { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mh, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mh { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mi, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mi { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mo, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mo { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sa, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sa { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sb, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sb { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sc { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .dl, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .dl { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sd { + color: var(--red); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .s2, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .s2 { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .se, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .se { + color: var(--brown); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sh, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sh { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .si, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .si { + color: var(--pink); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sx, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sx { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sr, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sr { + color: var(--pink); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .s1, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .s1 { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ss, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ss { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .bp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .bp { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .fm, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .fm { + color: var(--codeBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vc { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vg, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vg { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vi, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vi { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vm, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vm { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .il, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .il { + color: var(--grey); +} + +/*# sourceMappingURL=basic_mod.css.map */ diff --git a/refs/pull/443/merge/en/_static/basic_mod.css.map b/refs/pull/443/merge/en/_static/basic_mod.css.map new file mode 100644 index 000000000..332d772fb --- /dev/null +++ b/refs/pull/443/merge/en/_static/basic_mod.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../../src/sass/basic_mod.scss"],"names":[],"mappings":"AAGA;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAID;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAaD;AACA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;AAEA;EACE;EAEA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AACA;AAKE;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA,eAhHS;;AAmHX;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE,OA9Na;EA+Nb;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;;AAEA;EACE;EACA;;AAOJ;EADF;IAEI;;;AAKF;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AASd;AACA;AAEA;EACE;EACA;EACA;EACA,aAnSa;EAoSb,cApSa;EAqSb;AAOA;AAqDA;;AA1DA;EARF;IASI;IACA;;;AAgBF;AAAA;EAEE;;AAGA;AAAA;EACE;;AAOJ;AAAA;EAEE;;AAIF;AAAA;EAEE;;AAIF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAKF;EACE;;AAGF;EACE;EACA;EACA,eA7WW;EA8WX,aAhXO;EAiXP;;AAGF;EACE,WAlXW;EAmXX;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA,eA/XW;EAgYX;;AAEA;EACE,aArYK;;AA0YT;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAOA;AAAA;AAAA;AAAA;EACE;;AAIJ;AAAA;EAEE;EACA;;AAQA;EACE;;AAIJ;EACE;;AAOA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AACA;EACE;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;AAMJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAOJ;EACE;EACA;;AAGF;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AASN;EACE;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA,aAzjBK;EA0jBL;EACA;EACA;EACA,eA3jBS;;AA+jBX;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKF;EACE;;AAEA;EACE;;AAMN;EACE;;AAMJ;EACE;;AAEA;EACE;EACA;EACA;EACA,aAlnBK;EAmnBL;EACA;EACA;EACA,eApnBS;EAqnBT;;AAIF;EACE;EACA;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;AAMJ;EACE;EACA,eAlpBW;EAmpBX;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EAIE;;AAEA;EACE,OAJM;;AAQV;EAEE;;AAEA;EACE,OAJM;;AAQV;EAGE;;AAEA;EACE,OAJM;;AAQV;EAIE;;AAEA;EACE,OAJM;;;AAUd;AACA;AAwCA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OAnwBa;EAowBb;EACA;EACA;;AAEA;EAZF;IAaI;;;AAGF;EACE;EACA;;AAvDF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAKN;EACE;;AAMJ;EACE;;;AA6BJ;AACA;AAiBA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAxBF;EACE;EACA;;AAEA;EACE;EACA;EACA;;;AAuBN;EACE;EACA;EACA;EACA;EACA;EACA,OA9zBa;EA+zBb;EACA;EACA;EACA;EACA;;AAzCA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AA1EJ;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAKN;EACE;;AAMJ;EACE;;AAoFF;EApBF;IAqBI;;;;AAIJ;AACA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;AACA;AAEA;EACE,aAx2Ba;EAy2Bb,cAz2Ba;;AA22Bb;EAJF;IAKI;IACA;;;AAGF;EACE,WAn3BW;EAo3BX;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAKF;EACE;;AAEA;EACE;;AAMJ;EACE;;AAEA;EACE;;;AAQZ;AACA;AAOE;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;AAoCE;AAGA;AAIA;AAGA;AAIA;AAIA;AAGA;AAIA;AAIA;AAIA;AAGA;AAGA;AAGA;AAIA;AAGA;AAGA;AAIA;AAGA;AAIA;AAGA;AAIA;AAIA;AAIA;AAGA;AAIA;AAGA;AAGA;AAGA;AAGA;AAGA;AAIA;AAGA;AAGA;AAIA;AAIA;AAGA;AAGA;AAIA;AAIA;AAGA;AAIA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAIA;AAGA;AAIA;AAGA;AAIA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;;AA9PF;AAAA;EACE;;AAGF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE","file":"basic_mod.css"} \ No newline at end of file diff --git a/refs/pull/443/merge/en/_static/doctools.js b/refs/pull/443/merge/en/_static/doctools.js new file mode 100644 index 000000000..4d67807d1 --- /dev/null +++ b/refs/pull/443/merge/en/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/refs/pull/443/merge/en/_static/documentation_options.js b/refs/pull/443/merge/en/_static/documentation_options.js new file mode 100644 index 000000000..9feebd4c3 --- /dev/null +++ b/refs/pull/443/merge/en/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: 'version: latest', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/refs/pull/443/merge/en/_static/file.png b/refs/pull/443/merge/en/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/refs/pull/443/merge/en/_static/file.png differ diff --git a/refs/pull/443/merge/en/_static/fonts/roboto-mono/LICENSE.txt b/refs/pull/443/merge/en/_static/fonts/roboto-mono/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/refs/pull/443/merge/en/_static/fonts/roboto-mono/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-bold-italic.woff2 b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-bold-italic.woff2 new file mode 100644 index 000000000..595f902d6 Binary files /dev/null and b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-bold-italic.woff2 differ diff --git a/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-bold.woff2 b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-bold.woff2 new file mode 100644 index 000000000..eb7eb9d48 Binary files /dev/null and b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-bold.woff2 differ diff --git a/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-italic.woff2 b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-italic.woff2 new file mode 100644 index 000000000..8f5146aa0 Binary files /dev/null and b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono-italic.woff2 differ diff --git a/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono.woff2 b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono.woff2 new file mode 100644 index 000000000..9e69f6d1a Binary files /dev/null and b/refs/pull/443/merge/en/_static/fonts/roboto-mono/roboto-mono.woff2 differ diff --git a/refs/pull/443/merge/en/_static/fonts/roboto/LICENSE.txt b/refs/pull/443/merge/en/_static/fonts/roboto/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/refs/pull/443/merge/en/_static/fonts/roboto/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/refs/pull/443/merge/en/_static/fonts/roboto/roboto-bold.woff2 b/refs/pull/443/merge/en/_static/fonts/roboto/roboto-bold.woff2 new file mode 100644 index 000000000..ed8b5520c Binary files /dev/null and b/refs/pull/443/merge/en/_static/fonts/roboto/roboto-bold.woff2 differ diff --git a/refs/pull/443/merge/en/_static/fonts/roboto/roboto-italic.woff2 b/refs/pull/443/merge/en/_static/fonts/roboto/roboto-italic.woff2 new file mode 100644 index 000000000..719979294 Binary files /dev/null and b/refs/pull/443/merge/en/_static/fonts/roboto/roboto-italic.woff2 differ diff --git a/refs/pull/443/merge/en/_static/fonts/roboto/roboto.woff2 b/refs/pull/443/merge/en/_static/fonts/roboto/roboto.woff2 new file mode 100644 index 000000000..39cd5a6f0 Binary files /dev/null and b/refs/pull/443/merge/en/_static/fonts/roboto/roboto.woff2 differ diff --git a/refs/pull/443/merge/en/_static/js/petite-vue.js b/refs/pull/443/merge/en/_static/js/petite-vue.js new file mode 100644 index 000000000..b2acae462 --- /dev/null +++ b/refs/pull/443/merge/en/_static/js/petite-vue.js @@ -0,0 +1 @@ +var pn=Object.defineProperty,hn=(e,t,n)=>t in e?pn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,C=(e,t,n)=>(hn(e,"symbol"!=typeof t?t+"":t,n),n),PetiteVue=function(e){"use strict";function t(e){if(a(e)){const n={};for(let s=0;s{if(e){const n=e.split(s);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}function i(e){let t="";if(d(e))t=e;else if(a(e))for(let n=0;no(e,t)))}const l=Object.assign,f=Object.prototype.hasOwnProperty,u=(e,t)=>f.call(e,t),a=Array.isArray,p=e=>"[object Map]"===y(e),h=e=>e instanceof Date,d=e=>"string"==typeof e,m=e=>"symbol"==typeof e,g=e=>null!==e&&"object"==typeof e,v=Object.prototype.toString,y=e=>v.call(e),b=e=>d(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,x=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},_=/-(\w)/g,w=x((e=>e.replace(_,((e,t)=>t?t.toUpperCase():"")))),$=/\B([A-Z])/g,k=x((e=>e.replace($,"-$1").toLowerCase())),O=e=>{const t=parseFloat(e);return isNaN(t)?e:t};function S(e,t){(t=t||undefined)&&t.active&&t.effects.push(e)}const E=e=>{const t=new Set(e);return t.w=0,t.n=0,t},j=e=>(e.w&N)>0,A=e=>(e.n&N)>0,P=new WeakMap;let R=0,N=1;const T=[];let M;const B=Symbol(""),L=Symbol("");class W{constructor(e,t=null,n){this.fn=e,this.scheduler=t,this.active=!0,this.deps=[],S(this,n)}run(){if(!this.active)return this.fn();if(!T.includes(this))try{return T.push(M=this),F.push(V),V=!0,N=1<<++R,R<=30?(({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let s=0;s0?T[e-1]:void 0}}stop(){this.active&&(I(this),this.onStop&&this.onStop(),this.active=!1)}}function I(e){const{deps:t}=e;if(t.length){for(let n=0;n{("length"===t||t>=s)&&c.push(e)}));else switch(void 0!==n&&c.push(o.get(n)),t){case"add":a(e)?b(n)&&c.push(o.get("length")):(c.push(o.get(B)),p(e)&&c.push(o.get(L)));break;case"delete":a(e)||(c.push(o.get(B)),p(e)&&c.push(o.get(L)));break;case"set":p(e)&&c.push(o.get(B))}if(1===c.length)c[0]&&Z(c[0]);else{const e=[];for(const t of c)t&&e.push(...t);Z(E(e))}}function Z(e,t){for(const n of a(e)?e:[...e])(n!==M||n.allowRecurse)&&(n.scheduler?n.scheduler():n.run())}const q=function(e,t){const n=Object.create(null),s=e.split(",");for(let r=0;r!!n[e.toLowerCase()]:e=>!!n[e]}("__proto__,__v_isRef,__isVue"),D=new Set(Object.getOwnPropertyNames(Symbol).map((e=>Symbol[e])).filter(m)),G=X(),U=X(!0),Q=function(){const e={};return["includes","indexOf","lastIndexOf"].forEach((t=>{e[t]=function(...e){const n=le(this);for(let t=0,r=this.length;t{e[t]=function(...e){F.push(V),V=!1;const n=le(this)[t].apply(this,e);return z(),n}})),e}();function X(e=!1,t=!1){return function(n,s,r){if("__v_isReactive"===s)return!e;if("__v_isReadonly"===s)return e;if("__v_raw"===s&&r===(e?t?re:se:t?ne:te).get(n))return n;const i=a(n);if(!e&&i&&u(Q,s))return Reflect.get(Q,s,r);const o=Reflect.get(n,s,r);return(m(s)?D.has(s):q(s))||(e||H(n,0,s),t)?o:fe(o)?i&&b(s)?o:o.value:g(o)?e?function(e){return ce(e,!0,ee,null,se)}(o):oe(o):o}}const Y={get:G,set:function(e=!1){return function(t,n,s,r){let i=t[n];if(!e&&!function(e){return!(!e||!e.__v_isReadonly)}(s)&&(s=le(s),i=le(i),!a(t)&&fe(i)&&!fe(s)))return i.value=s,!0;const o=a(t)&&b(n)?Number(n)!Object.is(e,t))(s,i)&&J(t,"set",n,s):J(t,"add",n,s)),c}}(),deleteProperty:function(e,t){const n=u(e,t);e[t];const s=Reflect.deleteProperty(e,t);return s&&n&&J(e,"delete",t,void 0),s},has:function(e,t){const n=Reflect.has(e,t);return(!m(t)||!D.has(t))&&H(e,0,t),n},ownKeys:function(e){return H(e,0,a(e)?"length":B),Reflect.ownKeys(e)}},ee={get:U,set:(e,t)=>!0,deleteProperty:(e,t)=>!0},te=new WeakMap,ne=new WeakMap,se=new WeakMap,re=new WeakMap;function ie(e){return e.__v_skip||!Object.isExtensible(e)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}((e=>y(e).slice(8,-1))(e))}function oe(e){return e&&e.__v_isReadonly?e:ce(e,!1,Y,null,te)}function ce(e,t,n,s,r){if(!g(e)||e.__v_raw&&(!t||!e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const o=ie(e);if(0===o)return e;const c=new Proxy(e,2===o?s:n);return r.set(e,c),c}function le(e){const t=e&&e.__v_raw;return t?le(t):e}function fe(e){return Boolean(e&&!0===e.__v_isRef)}Promise.resolve();let ue=!1;const ae=[],pe=Promise.resolve(),he=e=>pe.then(e),de=e=>{ae.includes(e)||ae.push(e),ue||(ue=!0,he(me))},me=()=>{for(const e of ae)e();ae.length=0,ue=!1},ge=/^(spellcheck|draggable|form|list|type)$/,ve=({el:e,get:t,effect:n,arg:s,modifiers:r})=>{let i;"class"===s&&(e._class=e.className),n((()=>{let n=t();if(s)(null==r?void 0:r.camel)&&(s=w(s)),ye(e,s,n,i);else{for(const t in n)ye(e,t,n[t],i&&i[t]);for(const t in i)(!n||!(t in n))&&ye(e,t,null)}i=n}))},ye=(e,n,s,r)=>{if("class"===n)e.setAttribute("class",i(e._class?[e._class,s]:s)||"");else if("style"===n){s=t(s);const{style:n}=e;if(s)if(d(s))s!==r&&(n.cssText=s);else{for(const e in s)xe(n,e,s[e]);if(r&&!d(r))for(const e in r)null==s[e]&&xe(n,e,"")}else e.removeAttribute("style")}else e instanceof SVGElement||!(n in e)||ge.test(n)?"true-value"===n?e._trueValue=s:"false-value"===n?e._falseValue=s:null!=s?e.setAttribute(n,s):e.removeAttribute(n):(e[n]=s,"value"===n&&(e._value=s))},be=/\s*!important$/,xe=(e,t,n)=>{a(n)?n.forEach((n=>xe(e,t,n))):t.startsWith("--")?e.setProperty(t,n):be.test(n)?e.setProperty(k(t),n.replace(be,""),"important"):e[t]=n},_e=(e,t)=>{const n=e.getAttribute(t);return null!=n&&e.removeAttribute(t),n},we=(e,t,n,s)=>{e.addEventListener(t,n,s)},$e=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,ke=["ctrl","shift","alt","meta"],Oe={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&0!==e.button,middle:e=>"button"in e&&1!==e.button,right:e=>"button"in e&&2!==e.button,exact:(e,t)=>ke.some((n=>e[`${n}Key`]&&!t[n]))},Se=({el:e,get:t,exp:n,arg:s,modifiers:r})=>{if(!s)return;let i=$e.test(n)?t(`(e => ${n}(e))`):t(`($event => { ${n} })`);if("vue:mounted"!==s){if("vue:unmounted"===s)return()=>i();if(r){"click"===s&&(r.right&&(s="contextmenu"),r.middle&&(s="mouseup"));const e=i;i=t=>{if(!("key"in t)||k(t.key)in r){for(const e in r){const n=Oe[e];if(n&&n(t,r))return}return e(t)}}}we(e,s,i,r)}else he(i)},Ee=({el:e,get:t,effect:n})=>{n((()=>{e.textContent=Ce(t())}))},Ce=e=>null==e?"":g(e)?JSON.stringify(e,null,2):String(e),je=e=>"_value"in e?e._value:e.value,Ae=(e,t)=>{const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t},Pe=e=>{e.target.composing=!0},Re=e=>{const t=e.target;t.composing&&(t.composing=!1,Ne(t,"input"))},Ne=(e,t)=>{const n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)},Te=Object.create(null),Me=(e,t,n)=>Be(e,`return(${t})`,n),Be=(e,t,n)=>{const s=Te[t]||(Te[t]=Le(t));try{return s(e,n)}catch(r){console.error(r)}},Le=e=>{try{return new Function("$data","$el",`with($data){${e}}`)}catch(t){return console.error(`${t.message} in expression: ${e}`),()=>{}}},We={bind:ve,on:Se,show:({el:e,get:t,effect:n})=>{const s=e.style.display;n((()=>{e.style.display=t()?s:"none"}))},text:Ee,html:({el:e,get:t,effect:n})=>{n((()=>{e.innerHTML=t()}))},model:({el:e,exp:t,get:n,effect:s,modifiers:r})=>{const i=e.type,l=n(`(val) => { ${t} = val }`),{trim:f,number:u="number"===i}=r||{};if("SELECT"===e.tagName){const t=e;we(e,"change",(()=>{const e=Array.prototype.filter.call(t.options,(e=>e.selected)).map((e=>u?O(je(e)):je(e)));l(t.multiple?e:e[0])})),s((()=>{const e=n(),s=t.multiple;for(let n=0,r=t.options.length;n-1:r.selected=e.has(i);else if(o(je(r),e))return void(t.selectedIndex!==n&&(t.selectedIndex=n))}!s&&-1!==t.selectedIndex&&(t.selectedIndex=-1)}))}else if("checkbox"===i){let t;we(e,"change",(()=>{const t=n(),s=e.checked;if(a(t)){const n=je(e),r=c(t,n),i=-1!==r;if(s&&!i)l(t.concat(n));else if(!s&&i){const e=[...t];e.splice(r,1),l(e)}}else l(Ae(e,s))})),s((()=>{const s=n();a(s)?e.checked=c(s,je(e))>-1:s!==t&&(e.checked=o(s,Ae(e,!0))),t=s}))}else if("radio"===i){let t;we(e,"change",(()=>{l(je(e))})),s((()=>{const s=n();s!==t&&(e.checked=o(s,je(e)))}))}else{const t=e=>f?e.trim():u?O(e):e;we(e,"compositionstart",Pe),we(e,"compositionend",Re),we(e,(null==r?void 0:r.lazy)?"change":"input",(()=>{e.composing||l(t(e.value))})),f&&we(e,"change",(()=>{e.value=e.value.trim()})),s((()=>{if(e.composing)return;const s=e.value,r=n();document.activeElement===e&&t(s)===r||s!==r&&(e.value=r)}))}},effect:({el:e,ctx:t,exp:n,effect:s})=>{he((()=>s((()=>Be(t.scope,n,e)))))}},Ie=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,Ke=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Ve=/^\(|\)$/g,Fe=/^[{[]\s*((?:[\w_$]+\s*,?\s*)+)[\]}]$/,ze=(e,t,n)=>{const s=t.match(Ie);if(!s)return;const r=e.nextSibling,i=e.parentElement,o=new Text("");i.insertBefore(o,e),i.removeChild(e);const c=s[2].trim();let l,f,u,p,h=s[1].trim().replace(Ve,"").trim(),d=!1,m="key",v=e.getAttribute(m)||e.getAttribute(m=":key")||e.getAttribute(m="v-bind:key");v&&(e.removeAttribute(m),"key"===m&&(v=JSON.stringify(v))),(p=h.match(Ke))&&(h=h.replace(Ke,"").trim(),f=p[1].trim(),p[2]&&(u=p[2].trim())),(p=h.match(Fe))&&(l=p[1].split(",").map((e=>e.trim())),d="["===h[0]);let y,b,x,_=!1;const w=(e,t,s,r)=>{const i={};l?l.forEach(((e,n)=>i[e]=t[d?n:e])):i[h]=t,r?(f&&(i[f]=r),u&&(i[u]=s)):f&&(i[f]=s);const o=et(n,i),c=v?Me(o.scope,v):s;return e.set(c,s),o.key=c,o},$=(t,n)=>{const s=new nt(e,t);return s.key=t.key,s.insert(i,n),s};return n.effect((()=>{const e=Me(n.scope,c),t=x;if([b,x]=(e=>{const t=new Map,n=[];if(a(e))for(let s=0;s$(e,o))),_=!0})),r},He=({el:e,ctx:{scope:{$refs:t}},get:n,effect:s})=>{let r;return s((()=>{const s=n();t[s]=e,r&&s!==r&&delete t[r],r=s})),()=>{r&&delete t[r]}},Je=/^(?:v-|:|@)/,Ze=/\.([\w-]+)/g;let qe=!1;const De=(e,t)=>{const n=e.nodeType;if(1===n){const n=e;if(n.hasAttribute("v-pre"))return;let s;if(_e(n,"v-cloak"),s=_e(n,"v-if"))return((e,t,n)=>{const s=e.parentElement,r=new Comment("v-if");s.insertBefore(r,e);const i=[{exp:t,el:e}];let o,c;for(;(o=e.nextElementSibling)&&(c=null,""===_e(o,"v-else")||(c=_e(o,"v-else-if")));)s.removeChild(o),i.push({exp:c,el:o});const l=e.nextSibling;s.removeChild(e);let f,u=-1;const a=()=>{f&&(s.insertBefore(r,f.el),f.remove(),f=void 0)};return n.effect((()=>{for(let e=0;e{let n=e.firstChild;for(;n;)n=De(n,t)||n.nextSibling},Ue=(e,t,n,s)=>{let r,i,o;if(":"===(t=t.replace(Ze,((e,t)=>((o||(o={}))[t]=!0,""))))[0])r=ve,i=t.slice(1);else if("@"===t[0])r=Se,i=t.slice(1);else{const e=t.indexOf(":"),n=e>0?t.slice(2,e):t.slice(2);r=We[n]||s.dirs[n],i=e>0?t.slice(e+1):void 0}r&&(r===ve&&"ref"===i&&(r=He),Qe(e,r,n,s,i,o),e.removeAttribute(t))},Qe=(e,t,n,s,r,i)=>{const o=t({el:e,get:(t=n)=>Me(s.scope,t,e),effect:s.effect,ctx:s,exp:n,arg:r,modifiers:i});o&&s.cleanups.push(o)},Xe=(e,t)=>{if("#"!==t[0])e.innerHTML=t;else{const n=document.querySelector(t);e.appendChild(n.content.cloneNode(!0))}},Ye=e=>{const t={delimiters:["{{","}}"],delimitersRE:/\{\{([^]+?)\}\}/g,...e,scope:e?e.scope:oe({}),dirs:e?e.dirs:{},effects:[],blocks:[],cleanups:[],effect:e=>{if(qe)return de(e),e;const n=function(e,t){e.effect&&(e=e.effect.fn);const n=new W(e);t&&(l(n,t),t.scope&&S(n,t.scope)),(!t||!t.lazy)&&n.run();const s=n.run.bind(n);return s.effect=n,s}(e,{scheduler:()=>de(n)});return t.effects.push(n),n}};return t},et=(e,t={})=>{const n=e.scope,s=Object.create(n);Object.defineProperties(s,Object.getOwnPropertyDescriptors(t)),s.$refs=Object.create(n.$refs);const r=oe(new Proxy(s,{set:(e,t,s,i)=>i!==r||e.hasOwnProperty(t)?Reflect.set(e,t,s,i):Reflect.set(n,t,s)}));return tt(r),{...e,scope:r}},tt=e=>{for(const t of Object.keys(e))"function"==typeof e[t]&&(e[t]=e[t].bind(e))};class nt{constructor(e,t,n=!1){C(this,"template"),C(this,"ctx"),C(this,"key"),C(this,"parentCtx"),C(this,"isFragment"),C(this,"start"),C(this,"end"),this.isFragment=e instanceof HTMLTemplateElement,n?this.template=e:this.isFragment?this.template=e.content.cloneNode(!0):this.template=e.cloneNode(!0),n?this.ctx=t:(this.parentCtx=t,t.blocks.push(this),this.ctx=Ye(t)),De(this.template,this.ctx)}get el(){return this.start||this.template}insert(e,t=null){if(this.isFragment)if(this.start){let n,s=this.start;for(;s&&(n=s.nextSibling,e.insertBefore(s,t),s!==this.end);)s=n}else this.start=new Text(""),this.end=new Text(""),e.insertBefore(this.end,t),e.insertBefore(this.start,this.end),e.insertBefore(this.template,this.end);else e.insertBefore(this.template,t)}remove(){if(this.parentCtx&&((e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)})(this.parentCtx.blocks,this),this.start){const e=this.start.parentNode;let t,n=this.start;for(;n&&(t=n.nextSibling,e.removeChild(n),n!==this.end);)n=t}else this.template.parentNode.removeChild(this.template);this.teardown()}teardown(){this.ctx.blocks.forEach((e=>{e.teardown()})),this.ctx.effects.forEach(K),this.ctx.cleanups.forEach((e=>e()))}}const st=e=>e.replace(/[-.*+?^${}()|[\]\/\\]/g,"\\$&"),rt=e=>{const t=Ye();if(e&&(t.scope=oe(e),tt(t.scope),e.$delimiters)){const[n,s]=t.delimiters=e.$delimiters;t.delimitersRE=new RegExp(st(n)+"([^]+?)"+st(s),"g")}let n;return t.scope.$s=Ce,t.scope.$nextTick=he,t.scope.$refs=Object.create(null),{directive(e,n){return n?(t.dirs[e]=n,this):t.dirs[e]},mount(e){if("string"==typeof e&&!(e=document.querySelector(e)))return;let s;return s=(e=e||document.documentElement).hasAttribute("v-scope")?[e]:[...e.querySelectorAll("[v-scope]")].filter((e=>!e.matches("[v-scope] [v-scope]"))),s.length||(s=[e]),n=s.map((e=>new nt(e,t,!0))),this},unmount(){n.forEach((e=>e.teardown()))}}},it=document.currentScript;return it&&it.hasAttribute("init")&&rt().mount(),e.createApp=rt,e.nextTick=he,e.reactive=oe,Object.defineProperty(e,"__esModule",{value:!0}),e[Symbol.toStringTag]="Module",e}({}); diff --git a/refs/pull/443/merge/en/_static/js/theme.js b/refs/pull/443/merge/en/_static/js/theme.js new file mode 100644 index 000000000..bf36d744c --- /dev/null +++ b/refs/pull/443/merge/en/_static/js/theme.js @@ -0,0 +1,108 @@ + +/** + * We add extra br tags to the autodoc output, so each parameter is shown on + * its own line. + */ +function setupAutodocPy() { + const paramElements = document.querySelectorAll('.py .sig-param') + + Array(...paramElements).forEach((element) => { + let brElement = document.createElement('br') + element.parentNode.insertBefore(brElement, element) + }) + + const lastParamElements = document.querySelectorAll('.py em.sig-param:last-of-type') + + Array(...lastParamElements).forEach((element) => { + let brElement = document.createElement('br') + element.after(brElement) + }) +} + +function setupAutodocCpp() { + const highlightableElements = document.querySelectorAll(".c dt.sig-object, .cpp dt.sig-object") + + Array(...highlightableElements).forEach((element) => { + element.classList.add("highlight"); + }) + + const documentables = document.querySelectorAll("dt.sig-object.c,dt.sig-object.cpp"); + + Array(...documentables).forEach((element) => { + element.classList.add("highlight"); + + var parens = element.querySelectorAll(".sig-paren"); + var commas = Array(...element.childNodes).filter(e => e.textContent == ", ") + + if (parens.length != 2) return; + + commas.forEach(c => { + if (c.compareDocumentPosition(parens[0]) == Node.DOCUMENT_POSITION_PRECEDING && + c.compareDocumentPosition(parens[1]) == Node.DOCUMENT_POSITION_FOLLOWING + ) { + let brElement = document.createElement('br') + let spanElement = document.createElement('span') + spanElement.className = "sig-indent" + c.after(brElement) + brElement.after(spanElement) + } + }); + + if (parens[0].nextSibling != parens[1]) { + // not an empty argument list + let brElement = document.createElement('br') + let spanElement = document.createElement('span') + spanElement.className = "sig-indent" + parens[0].after(brElement) + brElement.after(spanElement) + let brElement1 = document.createElement('br') + parens[1].parentNode.insertBefore(brElement1, parens[1]); + } + }) +} + +function setupSearchSidebar() { + const searchInput = document.querySelector('form.search input[type=text]') + if (searchInput) { + searchInput.placeholder = 'Search...' + } + + const searchButton = document.querySelector('form.search input[type=submit]') + if (searchButton) { + searchButton.value = 'Search' + } +} + +function setupSidebarToggle() { + const sidebar = document.querySelector('.sphinxsidebar') + document.querySelector('#toggle_sidebar a').onclick = (event) => { + console.log("Toggling sidebar") + event.preventDefault() + sidebar.style.display = window.getComputedStyle(sidebar, null).display == 'none' ? 'block' : 'none' + } +} + +function setupRightSidebarToggle() { + const sidebar = document.querySelector('#right_sidebar') + + const links = document.querySelectorAll('a.toggle_right_sidebar') + + Array(...links).forEach((element) => { + element.onclick = (event) => { + console.log("Toggling right sidebar") + event.preventDefault() + sidebar.style.display = window.getComputedStyle(sidebar, null).display == 'none' ? 'block' : 'none' + } + }) +} + + +document.addEventListener("DOMContentLoaded", function() { + console.log("custom theme loaded") + + setupAutodocPy() + setupAutodocCpp() + setupSearchSidebar() + setupSidebarToggle() + setupRightSidebarToggle() +}) diff --git a/refs/pull/443/merge/en/_static/language_data.js b/refs/pull/443/merge/en/_static/language_data.js new file mode 100644 index 000000000..367b8ed81 --- /dev/null +++ b/refs/pull/443/merge/en/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/refs/pull/443/merge/en/_static/minus.png b/refs/pull/443/merge/en/_static/minus.png new file mode 100644 index 000000000..d96755fda Binary files /dev/null and b/refs/pull/443/merge/en/_static/minus.png differ diff --git a/refs/pull/443/merge/en/_static/pkce.py b/refs/pull/443/merge/en/_static/pkce.py new file mode 100644 index 000000000..95e8fe415 --- /dev/null +++ b/refs/pull/443/merge/en/_static/pkce.py @@ -0,0 +1,21 @@ +import hashlib +import base64 +import re + +def get_pkce(code_challenge_method: str = "S256", code_challenge_length: int = 64): + hashers = {"S256": hashlib.sha256} + + code_verifier = base64.urlsafe_b64encode(os.urandom(40)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + code_challenge = hashers.get(code_challenge_method)( + code_verifier.encode("utf-8") + ).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + return { + "code_verifier": code_verifier, + "code_challenge": code_challenge, + "code_challenge_method": code_challenge_method, + } \ No newline at end of file diff --git a/refs/pull/443/merge/en/_static/plus.png b/refs/pull/443/merge/en/_static/plus.png new file mode 100644 index 000000000..7107cec93 Binary files /dev/null and b/refs/pull/443/merge/en/_static/plus.png differ diff --git a/refs/pull/443/merge/en/_static/pygments.css b/refs/pull/443/merge/en/_static/pygments.css new file mode 100644 index 000000000..0d49244ed --- /dev/null +++ b/refs/pull/443/merge/en/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/refs/pull/443/merge/en/_static/searchtools.js b/refs/pull/443/merge/en/_static/searchtools.js new file mode 100644 index 000000000..b08d58c9b --- /dev/null +++ b/refs/pull/443/merge/en/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/refs/pull/443/merge/en/_static/sphinx_highlight.js b/refs/pull/443/merge/en/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/refs/pull/443/merge/en/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/refs/pull/443/merge/en/algorithms.html b/refs/pull/443/merge/en/algorithms.html new file mode 100644 index 000000000..73bb32dfd --- /dev/null +++ b/refs/pull/443/merge/en/algorithms.html @@ -0,0 +1,368 @@ + + + + + + + + Cryptographic Algorithms — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Cryptographic Algorithms

+

The following algorithms MUST be supported:

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Algorithm `alg` parameter value

Description

Operations

References

ES256

Elliptic Curve Digital Signature Algorithm (ECDSA) using one of the enabled curves listed in the section below and SHA256.

Signature

RFC 7518, [SOG-IS], [ETSI] .

ES384

Elliptic Curve Digital Signature Algorithm (ECDSA) using one of the enabled curves listed in the section below and SHA384.

Signature

RFC 7518, [SOG-IS], [ETSI] .

ES512

Elliptic Curve Digital Signature Algorithm (ECDSA) using one of the enabled curves listed in the section below and SHA521.

Signature

RFC 7518, [SOG-IS], [ETSI] .

RSA-OAEP-256

RSA Encryption Scheme with Optimal Asymmetric Encryption Padding (OAEP) using SHA256 hash function and the MGF1 with SHA-256 mask generation function.

Key Encryption

RFC 7516, RFC 7518.

A128CBC-HS256

AES encryption in Cipher Block Chaining mode with 128-bit Initial Vector value, plus HMAC authentication using SHA-256 and truncating HMAC to 128 bits.

Content Encryption

RFC 7516, RFC 7518.

A256CBC-HS512

AES encryption in Cipher Block Chaining mode with 256-bit Initial Vector value, plus HMAC authentication using SHA-512 and truncating HMAC to 256 bits.

Content Encryption

RFC 7516, RFC 7518.

+

The following Elliptic Curves MUST be supported for the Elliptic Curve Digital Signature Algorithm:

+ +++++ + + + + + + + + + + + + + + + + +

Curve Family

Short Curve Name

References

Brainpool

brainpoolP256r1, brainpoolP384r1, brainpoolP512r1.

RFC 5639, [ETSI] .

NIST

P-256, P-384, P-521

[ETSI], [FIPS-186-4], [ISO/IEC 14888-3].

+

The following algorithms are RECOMMENDED to be supported:

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Algorithm `alg` parameter value

Description

Operations

References

PS256

RSASSA (RSA with Signature Scheme Appendix) with PSS ( Probabilistic Signature Scheme) padding using SHA256 hash function and MGF1 mask generation function with SHA-256.

Signature

RFC 7518, [SOG-IS].

PS384

RSASSA (RSA with Signature Scheme Appendix) with PSS ( Probabilistic Signature Scheme) padding using SHA384 hash function and MGF1 mask generation function with SHA-384.

Signature

RFC 7518, [SOG-IS].

PS512

RSASSA (RSA with Signature Scheme Appendix) with PSS ( Probabilistic Signature Scheme) padding using SHA512 hash function and MGF1 mask generation function with SHA-512.

Signature

RFC 7518, [SOG-IS].

ECDH-ES

Elliptic Curve Diffie-Hellman (ECDH) Ephemeral Static key agreement using Concat Key Derivation Function (KDF).

Key Encryption

RFC 7518.

ECDH-ES+A128KW

ECDH-ES using Concat KDF and content encryption key (CEK) wrapped using AES with a key length of 128 (A128KW).

Key Encryption

RFC 7518.

ECDH-ES+A256KW

ECDH-ES using Concat KDF and content encryption key (CEK) wrapped using AES with a key length of 256 (A256KW).

Key Encryption

RFC 7518.

+

The following algorithms MUST NOT be supported:

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Algorithm `alg` parameter value

Description

Operations

References

none

    +
  • +
+

Signature

RFC 7518.

RSA_1_5

RSAES with PKCS1-v1_5 padding scheme. Use of this algorithm is generally not recommended.

Key Encryption

RFC 7516, [Security Vulnerability], [SOG-IS].

RSA-OAEP

RSA Encryption Scheme with Optimal Asymmetric Encryption Padding (OAEP) using default parameters.

Key Encryption

RFC 7518, [SOG-IS].

HS256

HMAC using SHA256.

Signature

RFC 7518.

HS384

HMAC using SHA384.

Signature

RFC 7518.

HS512

HMAC using SHA512

Signature

RFC 7518.

+
+ + +
+
+
+
+ + +
+
+
+ +
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/authentic-sources.html b/refs/pull/443/merge/en/authentic-sources.html new file mode 100644 index 000000000..56cb62bdd --- /dev/null +++ b/refs/pull/443/merge/en/authentic-sources.html @@ -0,0 +1,253 @@ + + + + + + + + Authentic Sources — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Authentic Sources

+

Authentic Sources are responsible for the authenticity of the User's attributes provided as Digital Credentials by the PID/(Q)EAA Provider. During the Issuance Flow, PID/(Q)EAA Providers, after authenticating the User, request from Authentic Sources the attributes required to provide the requested Credential. If PID/(Q)EAA Providers and Authentic Sources are both allowed to use PDND, the communication between them is accomplished in compliance with [MODI] and [PDND] and according to the rules defined within this specification. In particular,

+
+
    +
  • The Authentic Source MUST provide an e-service registered within the PDND catalogue which the PID/(Q)EAA Provider, as the recipient, MUST use to request the User's attributes.

  • +
  • In case of unavailability of the User's attributes, the Authentic Source MUST provide a response to the PID/(Q)EAA Provider with an estimation time when a new request can be sent.

  • +
  • The PID/(Q)EAA Provider MUST provide to the Authentic Source an evidence that:

    +
    +
      +
    • the request for Users attributes is related to data about themselves;

    • +
    • the request for User attributes comes from a valid Wallet Instance.

    • +
    +
    +
  • +
  • The PID/(Q)EAA Provider MUST make available to the Authentic Source an e-service for notifications on attributes availability and validity status (revocation or updates). The Authentic Source MUST use this e-service to notify to the PID/(Q)EAA Provider the notifications on the availability of the User's attributes as well as those relating to the attributes updates.

  • +
  • The protocol flow MUST ensure integrity, authenticity, and non-repudiation of the exchanged data between the Authentic Source and the PID/(Q)EAA Provider.

  • +
  • The e-services MUST be implemented in REST. SOAP protocol MUST NOT be used.

  • +
+
+
+

Security Patterns

+

The following security patterns and profiles are applicable:

+
+
    +
  • [REST_JWS_2021_POP] JWS POP Voucher Issuing Profile (Annex 3 - Standards and technical details used for Voucher Authorization [PDND]): REQUIRED. It adds a proof of possession on the Voucher. The client using the Voucher to access an e-service MUST demonstrate the proof of possession of the private key whose public is attested on the Voucher.

  • +
  • [ID_AUTH_REST_02] Client Authentication with X.509 certificate with uniqueness of the token/message (Annex 2 - Security Pattern [MODI]): REQUIRED. It guarantees trust between the Authentic Source and the PID/(Q)EAA Provider and provides a mitigation against replay attacks.

  • +
  • [INTEGRITY_REST_01] REST message payload integrity (Annex 2 - Security Pattern [MODI]): REQUIRED. It adds message payload integrity of the HTTP POST request.

  • +
  • [AUDIT_REST_02] submission of audit data within the request (Annex 2 - Security Pattern [MODI]): OPTIONAL. The Authentic Source MAY request an evidence about the User Authentication related to the User's attributes requested by the PID/(Q)EAA Provider and/or a proof that the Wallet Instance is valid. In this case this pattern MUST be used.

  • +
  • [PROFILE_NON_REPUDIATION_01] Profile for non-repudiation of transmission (Annex 3 - Interoperability Profile [MODI]): REQUIRED. This profile uses the following security patterns:

    +
    +
      +
    • ID_AUTH_CHANNEL_01 or ID_AUTH_CHANNEL_02

    • +
    • ID_AUTH_REST_02

    • +
    • INTEGRITY_REST_01

    • +
    +
    +
  • +
+
+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/backup-restore.html b/refs/pull/443/merge/en/backup-restore.html new file mode 100644 index 000000000..90a48f599 --- /dev/null +++ b/refs/pull/443/merge/en/backup-restore.html @@ -0,0 +1,267 @@ + + + + + + + + backup-restore.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

backup-restore.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/contribute.html b/refs/pull/443/merge/en/contribute.html new file mode 100644 index 000000000..e466d9042 --- /dev/null +++ b/refs/pull/443/merge/en/contribute.html @@ -0,0 +1,270 @@ + + + + + + + + How to contribute — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

How to contribute

+

The IT-Wallet project, including this document, follows an open development process. This approach ensures the development process is accessible to all, inviting all interested parties to participate.

+

Consequently, stakeholders, national and international community members are not only encouraged but also heartily welcomed to contribute to the refinement of these technical rules.

+

Below are several methods available for contributing to this project:

+
    +
  • GitHub issues. By opening an issue, you can seek clarification, propose enhancements, or report editorial typos. If you are working on an issue, we encourage you to open a draft pull request and link it.

  • +
  • Pull requests. Pull requests represent active contributions to the project, typically, but not always following issue-based discussions. Once a pull request is initiated, it facilitates discussion and review of the proposed changes before they are merged into the main branch (versione-corrente).

  • +
  • Developers Italia Slack channel. Slack is a messaging application designed for businesses, connecting people to the information they need. Developers Italia is an open community based on contributions and participation from public administrations, developers, technicians, students, and citizens. Developers Italia has initiated a Slack channel that [everyone can join for free](https://slack.developers.italia.it/), where you can learn about all their activities and partake in discussions.

  • +
+
+

Acknowledgements

+

We would like to thank the following individuals for their comments, +concerns, ideas, contributions, some of which substantial, to this +implementation profile and to the initial set of implementations.

+
    +
  • Alen Horvat

  • +
  • Amir Sharif

  • +
  • Andrea Moro

  • +
  • Andrea Prosseda

  • +
  • Elisa Nicolussi Paolaz

  • +
  • Emanuele De Cupis

  • +
  • Emiliano Vernini

  • +
  • Francesco Grauso

  • +
  • Francesco Marino

  • +
  • Francesco Ventola

  • +
  • Gabriella Cefalù

  • +
  • Giada Sciarretta

  • +
  • Giuseppe De Marco

  • +
  • Klaas Wierenga

  • +
  • Kristina Yasuda

  • +
  • Leif Johansson

  • +
  • Lorenzo Cerini

  • +
  • Mart Aarma

  • +
  • Marta Sciunnach

  • +
  • Michele Silletti

  • +
  • Nicola Saitto

  • +
  • Niels van Dijk

  • +
  • Oliver Terbu

  • +
  • Paul Bastien

  • +
  • Pasquale De Rose

  • +
  • Peter Altmann

  • +
  • Riccardo Iaconelli

  • +
  • Roland Hedberg

  • +
  • Salvatore Laiso

  • +
  • Salvatore Manfredi

  • +
  • Stefano Alifuoco

  • +
  • Takahiko Kawasaki

  • +
  • Thomas Chiozzi

  • +
  • Torsten Lodderstedt

  • +
  • Vladimir Duzhinov

  • +
+

If anyone has been forgotten, please accept our apologies with the +request to propose the modification of this page via a [Pull Request](https://github.com/italia/eudi-wallet-it-docs) +with a brief description of the contribution offered, during which +event or channel, and during which period. We will then have the opportunity +to apologize again and make amends as soon as possible, including you in the list.

+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/defined-terms.html b/refs/pull/443/merge/en/defined-terms.html new file mode 100644 index 000000000..325ae3eb4 --- /dev/null +++ b/refs/pull/443/merge/en/defined-terms.html @@ -0,0 +1,479 @@ + + + + + + + + Normative Language and Conventions — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Normative Language and Conventions

+

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

+
+
+

Defined Terms

+

The terms User, Trust Service, Trust Model, Trusted List, Trust Framework, Attribute, Electronic Attestations of Attributes Provider or Trust Service Provider (TSP), Person Identification Data (PID), Revocation List, Qualified Electronic Attestations of Attributes Provider or Qualified Trust Service Provider (QTSP), Electronic Attestation of Attributes (EAA), are defined in the EIDAS-ARF.

+

Below are the description of acronyms and definitions which are useful for further insights into topics that complement the it-wallet and the interacting components.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Description

Notes

User

A natural or legal person, or a natural person representing another natural person or a legal person, that uses a trust services or electronic identification means provided in accordance with EUDI Wallet Architecture Reference Framework. [ARF v1.4]

User Attribute

A characteristic, quality, right or permission of a natural or legal person or of an object. [ARF v1.4]

Other alternative terms: User Claim

Digital Identity Provider

Entity responsible for identifying citizens for the issuance of a digital identity.

Digital Credential

A signed set of Attributes encapsulated in a specific data format, such as mdoc format specified in [ISO 18013-5] or the SD-JWT VC format specified in [SD-JWT-VC]. This may be a Personal Identification Data (PID), (Qualified) Electronic Attestation of Attribute ((Q)EAA). [Revised from ARF v1.4]

Differences with ARF: The definition from ARF restricts the data format to mdoc and SD-JWT VC. For the scope of the Trust Model, a Digital Credential definition should be neutral on the format. ARF alternative terms: Electronic Attestation, Attestation. Other alternative terms: Verifiable Credential, Digital Attestation.

Organizational Entity

A legal person (only considering organizations and public entities, not natural/physical persons) recognized by the Member State through a unique identifier to operate a certain role within the EUDI Wallet ecosystem.

In this category the following entity roles are included: Wallet Provider, Credential Issuer, Relying Party, QTSP In general, any kind of Entity that must be registered through a national or European registration mechanism. ARF alternative terms: legal person (only considering organizations and public entities, not natural/physical persons)

Wallet Solution

A Wallet Solution is the entire eIDAS-compliant product and service provided by a Wallet Provider to all Users and certified as EUDI-compliant by a Conformity Assessment Body (CAB). [Revised from ARF v1.4]

Differences with ARF: editorial ARF alternative terms: EUDI Wallet Solution

Wallet Provider

An Organizational Entity, responsible for the management and release operation of a Wallet Solution. The Wallet Provider issues the Wallet Attestations to its Wallet Instances through an Attestation Service. The Wallet Attestation certifies the genuinity and authenticity of the Wallet Instance and its compliance with the security and privacy requirements. [Revised from ARF v1.4]

Differences with ARF: editorial ARF alternative terms: EUDI Wallet Provider

Wallet Instance

Instance of a Wallet Solution installed on a User’s device belonging to and which is controlled by a User. It enables the storage and management of Digital Credentials.The Wallet Instance provides graphical interfaces for User interaction with Relying Parties, PID, (Q)EAA Providers and the Wallet Provider. [Revised from ARF v1.4]

Differences with ARF: editorial ARF alternative terms: EUDI Wallet Instance

Wallet Provider Backend

Is the technical infrastructure and server-side components, including a set of endpoints, managed by a Wallet Provider.

Credential Issuer

An Organizational Entity providing Digital Credentials to Users. It may be PID Provider or (Q)EAA Providers. [Revised from ARF v1.4]

Differences with ARF: (i) merged the PID Providers and (Q)EEA Providers definitions using the general term Digital Credential, (ii) renamed “Member Stare or other legal entity” in “Organizational Entity” ARF alternative terms: PID Providers,(Q)EEA Providers, Attestation Provider Other alternative terms: Verifiable Credential Issuer

Relying Party

An Organizational Entity that relies upon an electronic identification or a Trust Service originating from a Wallet Instance. [Revised from ARF v1.4]

Differences with ARF: renamed “natural or legal person” in “Organizational Entity”.

Relying Party Instance

A Relying Party Instance in the context of a mobile application or a standalone embedded device refers to a specific deployment of the application or device. These instances depend on an User Authentication through a Wallet Instance to confirm User identities before granting access to their functionalities. Each version or environment where the application or device is running, be it a particular release of a mobile app installed on a User's smartphone or a specific embedded device in use, constitutes a separate instance. In case of proximity supervised scenarios, it belongs to and is controlled by a Verifier. [Revised from ARF v1.4]

Differences with ARF: added a sentence on proximity supervised scenarios. Other alternative terms: Verifier App

Verifier

A natural person or legal person using an RP Instance. [New]

Trust

Trust is the confidence in the security, reliability, and integrity of entities (such as systems, organizations, or individuals) and their actions, ensuring that they will operate as expected in a secure and predictable manner. It is often established through empirical proof, such as past performance, security certifications, or transparent operational practices, which demonstrate a track record of adherence to security standards and ethical conduct. [Revised from ARF v1.4]

Trust Framework

A legally enforceable set of operational and technical rules and agreements that govern a multi-party system designed for conducting specific types of transactions among a community of participants and bound by a common set of requirements. [ARF v1.4]

Trust Model

Collection of rules that ensure the legitimacy of the components and the entities involved in the EUDI Wallet ecosystem. [ARF v1.4]

Trusted List

Repository of information about authoritative entities in a particular legal or contractual context which provides information about their current and historical status. It serves as the bedrock of trust, acting as federative sources that publish the crucial information about root entities within the ecosystem. [Revised from ARF v1.4]

Differences with ARF: added the last sentence

Registration Authority

A party responsible for registering all the Organizational Entities by issuing a Trust Assertion.

ARF: Registrar

Conformity Assessment Body (CAB)

A conformity assessment body as defined in Article 2, point 13, of Regulation (EC) No 765/2008, which is accredited in accordance with that Regulation as competent to carry out conformity assessment of a qualified trust service provider and the qualified trust services it provides, or as competent to carry out certification of European Digital Identity Wallets or electronic identification means. [ARF v1.4]

National Accreditation Bodies (NAB)

A body that performs accreditation with authority derived from a Member State under Regulation (EC) No 765/2008. [ARF v1.4]

Other alternative terms: Accreditation Authority

Trust Evaluation

The process of verifying the trustworthiness of registered Organizational Entities, in accordance with pre-established rules. For example, involving the retrieval and validation of entity configurations and trust chains.

Other alternative terms: Trust Discovery, Trust Establishment

Trust Assertion

Cryptographically verifiable artifact that proves the compliance of an Organizational Entity with known rules and requirements defined within the Trust Model.

Other alternative terms: Verifiable Attestation, Access Certificate

Trust Relationship

Positive outcome of Trust Evaluation, which produces a reliable relationship between Organizational Entities, where one Organizational Entity trusts the other to securely handle data, execute transactions, or perform actions on its behalf.

Metadata

Digital artifact that contains all the required information about an Organizational Entity, e.g., protocol related endpoints and the Organizational Entity’s cryptographic public keys (for the complete list check requirement “Metadata Content”).

Policy Language

A formal language used to define security, privacy, and identity management policies that govern interactions and transactions within a Trust Framework. This language allows for the clear and unambiguous expression of rules and conditions, facilitating the automation of processes and interoperability among different systems and organizations.

Registration Process

Process performed by a Registration Authority verifying necessary information to ensure Organizational Entity eligibility and compliance with the relevant rules and standards. The main goal of the Registration Process is for the Organizational Entity to receive one or more Trust Assertions to be used for the Trust Evaluation processes.

Accreditation Process

Process performed by the National Accreditation Body to accreditate CABs. As a result of the Accreditation Process, a NAB issues an accreditation certificate to a CAB.

Currently, out of scope of the Trust Model requirements

Certification Process

Process performed by Conformity Assessment Bodies to certify the Wallet Solution. The Certification Process aims to periodically assess technical Wallet Solutions (e.g. performing vulnerability assessment and risk analysis). As a result of the Certification Process a certification is provided to the Wallet Solution. [New]

Currently, out of scope of the Trust Model requirements

Notification Process

Process defining how information is transferred to the European Commission and the inclusion of an entity in the Trusted List.

Supervision Process

Process performed by a Supervisory Body to review and ensure proper functioning of the Wallet Provider and other relevant actors.

Currently, out of scope of the Trust Model requirements

Federation Authority

A public governance entity that issues guidelines and technical rules, and administers - directly or through its intermediary - Trusted Lists, services, and accreditation processes, the status of participants, and their eligibility evaluation. It also performs oversight functions.

Wallet Attestation

Verifiable Attestation, issued by the Wallet Provider, that proves the security compliace of the Wallet Instance.

Wallet Secure Cryptographic Device (WSCD)

Hardware-backed secure environment for creating, storing, and/or managing cryptographic keys and data. A WSCD MAY implement an association proof in different ways. This largely depends on the implementation of the WSCD for example: remote HSM, external smart card, internal UICC, internal native cryptographic hardware, such as the iOS Secure Enclave or the Android Hardware Backed Keystore or StrongBox

Credential Status Attestation

Verifiable Attestation proving that a related Digital Credential is not revoked.

Device Integrity Service

A service provided by device manufacturers that verifies the integrity and authenticity of the app instance (Wallet Instance), as well as certifying the secure storage of private keys generated by the device within its dedicated hardware. It's important to note that the terminology used to describe this service varies among manufacturers.

Cryptographic Hardware Keys

During the app initialization, the Wallet Instance generates a pair of keys, one public and one private, which remain valid for the entire duration of the Wallet Instance's life. Functioning as a Master Key for the personal device, these Cryptographic Hardware Keys are confined to the OS domain and are not designed for signing arbitrary payloads. Their primary role is to provide a unique identification for each Wallet Instance.

Cryptographic Hardware Key Tag

A unique identifier created by the operating system for the Cryptographic Hardware Keys, utilized to gain access to the private key stored in the hardware.

Key Attestation

An attestation from the device's OEM that enhances your confidence in the keys used in your Wallet Instance being securely stored within the device's hardware-backed keystore. Its content is therefore defined by the operating system manufacturer. For Google Android, the term Key Attestation refers to the Strongbox Key Attestation feature. For Apple iOS, the reference is to the Device Check service, specifically the attestKey feature.

Qualified Electronic Attestation of Attributes (QEAA)

A digitally verifiable attestation in electronic form, issued by a QTSP, that substantiates a person's possession of attributes.

Qualified Electronic Signature Provider

The Electronic Trust Service Provider responsible for the issuing of Qualified Electronic Signature certificates to the User.

Qualified Electronic Attestation of Attributes Provider

Organizational Entity which serves as Credential issuer providing Qualified Electronic Attestations of Attributes (QEAAs).

PID Provider

Organizational Entity which serves as Credential issuer providing Person Identification Data to Users.

Differences with ARF: renamed “Member Stare or other legal entity” in “Organizational Entity”

National Identity Provider

It represents preexisting identity systems based on SAML2 or OpenID Connect Core 1.0, already in production in each Member State (eg: the Italian SPID and CIE id schemes notified eIDAS with LoA High, see SPID/CIE-OpenID-Connect-Specifications).

Relying Party

A natural or legal person that implements an authentication system requiring electronic attribute attestation submissions as an authentication mechanism.

Verifier

See Relying Party

Trust Attestation

Electronic attestation of an entity's compliance with the national regulatory framework, which is cryptographically verifiable and cannot be repudiated over time by the entity that issued it. A Trust Attestation is always related to a particular Trust Framework.

Trust Layer

Architectural component that enables IT-Wallet system participants to establish trust, in terms of reliability and compliance of all participants with the regulatory framework governing the digital identity system.

Trust Model

System defining how the participants of the ecosystem establish and maintain trust in their interactions. The Trust Model outlines the rules and the procedures for the entities (like users, systems, or applications) should validate each other's identities, authenticate, and establish the level of trust before exchanging information.

Level of Assurance

The degree of confidence in the vetting process used to establish the identity of the User and the degree of confidence that the User who presents the credential is the same User to whom the Digital Credential was issued.

Holder Key Binding

Ability of the Holder to prove legitimate possession of the private part, related to the public part attested by a Trusted Third Party.

Holder

Natural or Legal person that receives Verifiable Credentials from the Credential Issuers, manages the Verifiable Credentials within the Wallet, and presents them to Verifiers. The Holder is the User in control of the Wallet.

Pseudonym

Pseudonyms are alternative identifier used to represent an entity (such as a person or organization) without revealing their true identity. It provides a layer of privacy and anonymity while still allowing for consistent authentication and authorization within a system.

+
+

Acronyms

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Acronym

Description

OID4VP

OpenID for Verifiable Presentation

PID

Person Identification Data

VC

Verifiable Credential

VP

Verifiable Presentation

API

Application Programming Interface

LoA

Level of Assurance

AAL

Authenticator Assurance Level as defined in https://csrc.nist.gov/glossary/term/authenticator_assurance_level

WSCD

Wallet Secure Cryptographic Device

+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/genindex.html b/refs/pull/443/merge/en/genindex.html new file mode 100644 index 000000000..a1458e04a --- /dev/null +++ b/refs/pull/443/merge/en/genindex.html @@ -0,0 +1,292 @@ + + + + + + + Index — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ + +

Index

+ +
+ R + +
+

R

+ + +
+ + + +
+
+
+
+ + +
+
+
+
+
+ +
+ +
+ +
+
+
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/index.html b/refs/pull/443/merge/en/index.html new file mode 100644 index 000000000..b82ec036e --- /dev/null +++ b/refs/pull/443/merge/en/index.html @@ -0,0 +1,456 @@ + + + + + + + + The Italian EUDI Wallet implementation profile — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

The Italian EUDI Wallet implementation profile

+
+

Introduction

+

The European Parliament has adopted the revision of the eIDAS Regulation concerning electronic identification and trust services, introducing a significant innovation: the European Digital Identity Wallet. This update marks a pivotal advancement in the EU's digital strategy, aiming to enhance the security, interoperability, and usability of digital identities across Member States. For further details, resources, and notes on this legislative development, please refer to the official EU Commission and Parliament websites.

+

Italy has launched the National digital identity Wallet solution, known as IT-Wallet, established by the Legislative Decree of March 2, 2024, No. 19 (commonly referred to as the PNRR Decree)., in direct response to the European community's directives. This initiative ensures full interoperability with the digital identity solutions provided by other European Member States, aligning with European regulations.

+

The purpose of the following technical rules is to define the technical architecture and reference framework to be used as a guideline by all the parties involved in the development of the IT-Wallet project.

+

This documentation defines the national implementation profile of IT-Wallet, containing the technical details about components of the Wallet ecosystem, as listed below:

+
+
    +
  • Entities of the ecosystem according to EIDAS-ARF.

  • +
  • Infrastructure of trust attesting realiability and eligibility of the participants.

  • +
  • PID and EAAs data schemes and attribute sets.

  • +
  • PID/EAA in MDL CBOR format.

  • +
  • PID/EAA in SD-JWT format.

  • +
  • Wallet Solution general architecture.

  • +
  • Wallet Attestation.

  • +
  • Issuance of PID/EAA according to OpenID4VCI.

  • +
  • Presentation of PID/EAA according to OpenID4VP.

  • +
  • Presentation of pseudonyms according to SIOPv2.

  • +
  • PID/EAA backup and restore mechanisms.

  • +
  • PID/EAA revocation lists.

  • +
+
+
+
+

Index of content

+
+ +
+
+
+ + +
+
+
+
+ + + + + + +
+
+
+ +
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/objects.inv b/refs/pull/443/merge/en/objects.inv new file mode 100644 index 000000000..57a6782f1 Binary files /dev/null and b/refs/pull/443/merge/en/objects.inv differ diff --git a/refs/pull/443/merge/en/pid-eaa-data-model.html b/refs/pull/443/merge/en/pid-eaa-data-model.html new file mode 100644 index 000000000..0ef65a844 --- /dev/null +++ b/refs/pull/443/merge/en/pid-eaa-data-model.html @@ -0,0 +1,1474 @@ + + + + + + + + PID/(Q)EAA Data Model — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

PID/(Q)EAA Data Model

+

The Person Identification Data (PID) is issued by the PID Provider according to national laws. The main scope of the PID is allowing natural persons to be authenticated for the access to a service or to a protected resource. +The User attributes provided within the Italian PID are the ones listed below:

+
+
    +
  • Current Family Name

  • +
  • Current First Name

  • +
  • Date of Birth

  • +
  • Unique Identifier

  • +
  • Taxpayer identification number

  • +
+
+

The (Q)EAAs are issued by (Q)EAA Issuers to a Wallet Instance and MUST be provided in SD-JWT-VC or MDOC-CBOR data format.

+

The PID/(Q)EAA data format and the mechanism through which a digital credential is issued to the Wallet Instance and presented to a Relying Party are described in the following sections.

+
+

SD-JWT-VC Credential Format

+

The PID/(Q)EAA is issued in the form of a Digital Credential. The Digital Credential format is SD-JWT as specified in SD-JWT-VC.

+

SD-JWT MUST be signed using the Issuer's private key. SD-JWT MUST be provided along with a Type Metadata related to the issued Digital Credential according to Sections 6 and 6.3 of [SD-JWT-VC]. The payload MUST contain the _sd_alg claim described in the Section 5.1.1 SD-JWT and other claims specified in this section.

+

The claim _sd_alg indicates the hash algorithm used by the Issuer to generate the digests as described in Section 5.1.1 of SD-JWT. _sd_alg MUST be set to one of the specified algorithms in Section Cryptographic Algorithms.

+

Claims that are not selectively disclosable MUST be included in the SD-JWT as they are. The digests of the disclosures, along with any decoy if present, MUST be contained in the _sd array, as specified in Section 5.2.4.1 of SD-JWT.

+

Each digest value, calculated using a hash function over the disclosures, verifies the integrity and corresponds to a specific Disclosure. Each disclosure includes:

+
+
    +
  • a random salt,

  • +
  • the claim name (only when the claim is an object element),

  • +
  • the claim value.

  • +
+
+

In case of nested object in a SD-JWT payload each claim, on each level of the JSON, should be individually selectively disclosable or not. Therefore _sd claim containing digests MAY appear multiple times at different level in the SD-JWT.

+

For each claim that is an array element the digests of the respective disclosures and decoy digests are added to the array in the same position of the original claim values as specified in Section 5.2.4.2 of SD-JWT.

+

In case of array elements, digest values are calculated using a hash function over the disclosures, containing:

+
+
    +
  • a random salt,

  • +
  • the array element

  • +
+
+

In case of multiple array elements, the Issuer may wish to conceal presence of any statement while also allowing the Holder to reveal each of those elements individually (Section 5.2.6 SD-JWT). Both the entire array and the individuals entries can be selective disclosure.

+

The Disclosures are provided to the Holder together with the SD-JWT in the Combined Format for Issuance that is an ordered series of base64url-encoded values, each separated from the next by a single tilde ('~') character as follows:

+
<Issuer-Signed-JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure N>
+
+
+

See SD-JWT-VC and SD-JWT for additional details.

+
+

PID/(Q)EAA SD-JWT parameters

+

The JOSE header contains the following mandatory parameters:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

typ

REQUIRED. It MUST be set to vc+sd-jwt as defined in SD-JWT-VC.

RFC 7515 Section 4.1.9.

alg

REQUIRED. Signature Algorithm.

RFC 7515 Section 4.1.1.

kid

REQUIRED. Unique identifier of the public key.

RFC 7515 Section 4.1.8.

trust_chain

OPTIONAL. JSON array containing the trust chain that proves the reliability of the issuer of the JWT.

[OID-FED] Section 3.2.1.

x5c

OPTIONAL. Contains the X.509 public key certificate or certificate chain [RFC 5280] corresponding to the key used to digitally sign the JWS.

RFC 7515 Section 4.1.8 and [SD-JWT-VC] Section 3.5.

vctm

OPTIONAL. JSON array of base64url-encoded Type Metadata JSON documents. In case of extended type metadata, this claim contains the entire chain of JSON documents.

[SD-JWT-VC] Section 6.3.5.

+

The following claims MUST be in the JWT payload. Some of these claims can be disclosed, these are listed in the following tables that specify whether a claim is selectively disclosable [SD] or not [NSD].

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

iss

[NSD].URL string representing the PID/(Q)EAA Issuer unique identifier.

[RFC7519, Section 4.1.1].

sub

[NSD]. The identifier of the subject of the Digital Credential, the User, MUST be opaque and MUST NOT correspond to any anagraphic data or be derived from the User's anagraphic data via pseudonymization. Additionally, it is required that two different Credentials issued MUST NOT use the same sub value.

[RFC7519, Section 4.1.2].

iat

[SD].UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in RFC 7519.

[RFC7519, Section 4.1.6].

exp

[NSD].UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated in RFC 7519.

[RFC7519, Section 4.1.4].

status

[NSD]. It MUST be a valid JSON object containing the information on how to read the status of the Verifiable Credential. It MUST contain the JSON member status_assertion set to a JSON Object containing the credential_hash_alg claim indicating the Algorithm used for hashing the Digital Credential to which the Status Assertion is bound. It is RECOMMENDED to use sha-256.

Section 3.2.2.2 SD-JWT-VC and Section 11 OAUTH-STATUS-ASSERTION.

cnf

[NSD].JSON object containing the proof-of-possession key materials. By including a cnf (confirmation) claim in a JWT, the issuer of the JWT declares that the Holder is in control of the private key related to the public one defined in the cnf parameter. The recipient MUST cryptographically verify that the Holder is in control of that key.

[RFC7800, Section 3.1] and Section 3.2.2.2 SD-JWT-VC.

vct

[NSD]. Credential type value MUST be an HTTPS URL String and it MUST be set using one of the values obtained from the PID/(Q)EAA Issuer metadata. It is the identifier of the SD-JWT VC type and it MUST be set with a collision-resistant value as defined in Section 2 of RFC 7515. It MUST contain also the number of version of the Credential type (for instance: https://issuer.example.org/v1.0/personidentificationdata).

Section 3.2.2.2 SD-JWT-VC.

vct#integrity

[NSD].The value MUST be an "integrity metadata" string as defined in Section 3 of [W3C-SRI]. SHA-256, SHA-384 and SHA-512 MUST be supported as cryptographic hash functions. MD5 and SHA-1 MUST NOT be used. This claim MUST be verified according to Section 3.3.5 of [W3C-SRI].

Section 6.1 SD-JWT-VC, [W3C-SRI]

verification

[NSD].Object containing user authentication information. It MUST contain the following sub-value:

+
+
    +
  • trust_framework: String identifying the trust framework used for user digital authetication.

  • +
  • assurance_level: String identifying the level of identity assurance guarateed during the authentication process.

  • +
  • evidence: It MUST contain method claim identifying the digital identity system used for the authentication.

  • +
+
+

OIDC-IDA.

+
+

Note

+

Credential Type Metadata JSON Document MAY be retrieved directly from the URL contained in the claim vct, using the HTTP GET method or using the vctm header parameter if provided. Unlike specified in Section 6.3.1 of SD-JWT-VC the .well-known endpoint is not included in the current implementation profile. Implementers may decide to use it for interoperability with other systems.

+
+
+
+

Digital Credential Metadata Type

+

The Metadata type document MUST be a JSON object and contains the following parameters.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

name

REQUIRED. Human-readable name of the Digital Credential type. In case of multiple language, the language tags are added to member name, delimited by a # character as defined in RFC 5646 (e.g. name#it-IT).

[SD-JWT-VC] Section 6.2 and [OIDC] Section 5.2.

description

REQUIRED. A human-readable description of the Digital Credential type. In case of multiple language, the language tags are added to member name, delimited by a # character as defined in RFC 5646.

[SD-JWT-VC] Section 6.2 and [OIDC] Section 5.2.

extends

OPTIONAL. String Identitifier of an exteded metadata type document.

[SD-JWT-VC] Section 6.2.

extends#integrity

CONDITIONAL. REQUIRED if extends is present.

[SD-JWT-VC] Section 6.2.

schema

CONDITIONAL. REQUIRED if schema_uri is not present.

[SD-JWT-VC] Section 6.2.

schema_uri

CONDITIONAL. REQUIRED if schema is not present.

[SD-JWT-VC] Section 6.2.

schema#integrity

CONDITIONAL. REQUIRED if schema_uri is not present.

[SD-JWT-VC] Section 6.2.

data_source

REQUIRED. Object containing information about the data origin. It MUST contain the object verification with this following sub-value:

+
+
    +
  • trust_framework: MUST cointain trust framework used for digital authentication towards authentic source system.

  • +
  • authentic_source: MUST contain organization_name and organization_code cliam related to name and code identifier of the authentic source.

  • +
+
+

This specification

vc_claims

REQUIRED. Object containing useful information about the Digital credential graphical rappresentation. It MUST contain the for each credential claim the following objects:

+
+
    +
  • display: MUST cointain name human-readable display name.

  • +
  • graphics: MUST contain position, font character, color, size.

  • +
+
+

This specification

+

A non-normative Digital Credential metadata type is provided below.

+
{	
+    "name": "Person Identification Data",
+    "description": "Digital version of Person Identification Data",
+    "template_uri": "https://pidprovider.example.org/v1.0/templatepid",	
+    "schema_uri": "https://pidprovider.example.org/schema/v1.0/mdl",
+    "schema#integrity": "c8b708728e4c5756e35c03aeac257ca878d1f717d7b61f621be4d36dbd9b9c16",
+    "data_source": {
+        "verification": {
+        "trust_framework": "pdnd",
+        "authentic_source": {
+            "organization_name": "Ministero degli Interni",
+            "organization_code": "m_it"
+            }
+        }	
+    },					
+    "vc_claims": {
+        "unique_id": {
+            "display": [
+                {
+                    "name": "Nome",
+                    "locale": "it-IT"
+                },
+                {
+                    "name": "First Name",
+                    "locale": "en-US"
+                }
+            ],
+            "graphics": {
+                "position": {
+                    "x": 10,
+                    "y": 10
+                },
+                "font": "arial",
+                "color": "black",
+                "size": "12pt"
+            }
+        },
+        "given_name": {
+            "display": [
+                {
+                    "name": "Nome",
+                    "locale": "it-IT"
+                },
+                {
+                    "name": "First Name",
+                    "locale": "en-US"
+                }
+            ],
+            "graphics": {
+                "position": {
+                    "x": 10,
+                    "y": 20
+                },
+                "font": "arial",
+                "color": "black",
+                "size": "12pt"
+            }
+        },
+        "family_name": {
+            "value_type": "string",
+            "display": [
+                {
+                    "name": "Cognome",
+                    "locale": "it-IT"
+                },
+                {
+                    "name": "Family Name",
+                    "locale": "en-US"
+                }
+            ],
+            "graphics": {
+                "position": {
+                    "x": 10,
+                    "y": 30
+                },
+                "font": "arial",
+                "color": "black",
+                "size": "12pt"
+            }
+        },
+        "birth_date": {
+            "value_type": "string",
+            "display": [
+                {
+                    "name": "Data di nascita (YYYY-MM-GG)",
+                    "locale": "it-IT"
+                },
+                {
+                    "name": "Date of Birth (YYYY-MM-GG)",
+                    "locale": "en-US"
+                }
+            ],
+            "graphics": {
+                "position": {
+                    "x": 10,
+                    "y": 40
+                },
+                "font": "arial",
+                "color": "black",
+                "size": "12pt"
+                }
+        },
+        "tax_id_code": {
+            "value_type": "string",
+            "display": [
+                {
+                    "name": "Luogo di Nascita",
+                    "locale": "it-IT"
+                },
+                {
+                    "name": "Place of Birth",
+                    "locale": "en-US"
+                }
+            ],
+            "graphics": {
+                "position": {
+                    "x": 10,
+                    "y": 50
+                },
+                "font": "arial",
+                "color": "black",
+                "size": "12pt"
+            }
+        }
+    }
+}
+
+
+
+
+

PID Claims

+

Depending on the Digital Credential type vct, additional claims data MAY be added. The PID MUST support the following data:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

given_name

[SD]. Current First Name.

[OpenID Connect Core 1.0, Section 5.1]

family_name

[SD]. Current Family Name.

[OpenID Connect Core 1.0, Section 5.1]

birth_date

[SD]. Date of Birth.

unique_id

[SD]. Unique citizen identifier (ID ANPR) given by the National Register of the Resident Population (ANPR). It MUST be set according to ANPR rules

tax_id_code

[SD]. National tax identification code of natural person as a String format. It MUST be set according to ETSI EN 319 412-1. For example TINIT-<ItalianTaxIdentificationNumber>

+

The PID attribute schema, which encompasses all potential User data, is defined in ARF v1.4, and furthermore detailed in the PID Rulebook.

+
+
+

PID Non-Normative Examples

+

In the following, the non-normative example of the payload of a PID represented in JSON format.

+
{
+  "iss": "https://pidprovider.example.org",
+  "sub": "NzbLsXh8uDCcd7noWXFZAfHkxZsRGC9Xs",
+  "iat": 1683000000,
+  "exp": 1883000000,
+  "status": {
+    "status_assertion": {
+      "credential_hash_alg": "sha-256"
+    }
+  },
+  "vct": "https://pidprovider.example.org/v1.0/personidentificationdata",
+  "vct#integrity": "c5f73e250fe869f24d15118acce286c9bb56b63a443dc85af653cd73f6078b1f",
+  "verification": {
+    "trust_framework": "eidas",
+    "assurance_level": "high",
+    "evidence": {
+      "method": "cie"
+    }
+  },
+  "unique_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+  "given_name": "Mario",
+  "family_name": "Rossi",
+  "birth_date": "1980-01-10",
+  "tax_id_code": "TINIT-XXXXXXXXXXXXXXXX"
+}
+
+
+

The corresponding SD-JWT version for PID is given by

+
{
+  "typ":"vc+sd-jwt",
+  "alg":"ES256",
+  "kid":"dB67gL7ck3TFiIAf7N6_7SHvqk0MDYMEQcoGGlkUAAw",
+  "trust_chain" : [
+   "NEhRdERpYnlHY3M5WldWTWZ2aUhm ...",
+   "eyJhbGciOiJSUzI1NiIsImtpZCI6 ...",
+   "IkJYdmZybG5oQU11SFIwN2FqVW1B ..."
+  ]
+}
+
+
+
{
+  "_sd": [
+    "BoMGktW1rbikntw8Fzx_BeL4YbAndr6AHsdgpatFCig",
+    "ENNo31jfzFp8Y2DW0R-fIMeWwe7ELGvGoHMwMBpu14E",
+    "VQI-S1mT1Kxfq2o8J9io7xMMX2MIxaG9M9PeJVqrMcA",
+    "Yrc-s-WSr4exEYtqDEsmRl7spoVfmBxixP12e4syqNE",
+    "s1XK5f2pM3-aFTauXhmvd9pyQTJ6FMUhc-JXfHrxhLk",
+    "zVdghcmClMVWlUgGsGpSkCPkEHZ4u9oWj1SlIBlCc1o"
+  ],
+  "iss": "https://pidprovider.example.org",
+  "iat": 1683000000,
+  "exp": 1883000000,
+  "sub": "NzbLsXh8uDCcd7noWXFZAfHkxZsRGC9Xs",
+  "status": {
+    "status_assertion": {
+      "credential_hash_alg": "sha-256"
+    }
+  },
+  "vct": "https://pidprovider.example.org/v1.0/personidentificationdata",
+  "vct#integrity": "c5f73e250fe869f24d15118acce286c9bb56b63a443dc85af653cd73f6078b1f",
+  "verification": {
+    "trust_framework": "eidas",
+    "assurance_level": "high",
+    "evidence": {
+      "method": "cie"
+    }
+  },
+  "_sd_alg": "sha-256",
+  "cnf": {
+    "jwk": {
+      "kty": "EC",
+      "crv": "P-256",
+      "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
+      "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
+    }
+  }
+}
+
+
+

In the following the disclosure list is given

+

Claim iat:

+
    +
  • SHA-256 Hash: Yrc-s-WSr4exEYtqDEsmRl7spoVfmBxixP12e4syqNE

  • +
  • Disclosure: +WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImlhdCIsIDE2ODMwMDAwMDBd

  • +
  • Contents: ["2GLC42sKQveCfGfryNRN9w", "iat", 1683000000]

  • +
+

Claim unique_id:

+
    +
  • SHA-256 Hash: BoMGktW1rbikntw8Fzx_BeL4YbAndr6AHsdgpatFCig

  • +
  • Disclosure: +WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgInVuaXF1ZV9pZCIsICJ4eHh4 +eHh4eC14eHh4LXh4eHgteHh4eC14eHh4eHh4eHh4eHgiXQ

  • +
  • Contents: ["eluV5Og3gSNII8EYnsxA_A", "unique_id", +"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]

  • +
+

Claim given_name:

+
    +
  • SHA-256 Hash: zVdghcmClMVWlUgGsGpSkCPkEHZ4u9oWj1SlIBlCc1o

  • +
  • Disclosure: +WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImdpdmVuX25hbWUiLCAiTWFy +aW8iXQ

  • +
  • Contents: ["6Ij7tM-a5iVPGboS5tmvVA", "given_name", "Mario"]

  • +
+

Claim family_name:

+
    +
  • SHA-256 Hash: VQI-S1mT1Kxfq2o8J9io7xMMX2MIxaG9M9PeJVqrMcA

  • +
  • Disclosure: +WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgImZhbWlseV9uYW1lIiwgIlJv +c3NpIl0

  • +
  • Contents: ["eI8ZWm9QnKPpNPeNenHdhQ", "family_name", "Rossi"]

  • +
+

Claim birth_date:

+
    +
  • SHA-256 Hash: s1XK5f2pM3-aFTauXhmvd9pyQTJ6FMUhc-JXfHrxhLk

  • +
  • Disclosure: +WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImJpcnRoX2RhdGUiLCAiMTk4 +MC0wMS0xMCJd

  • +
  • Contents: ["Qg_O64zqAxe412a108iroA", "birth_date", "1980-01-10"]

  • +
+

Claim tax_id_code:

+
    +
  • SHA-256 Hash: ENNo31jfzFp8Y2DW0R-fIMeWwe7ELGvGoHMwMBpu14E

  • +
  • Disclosure: +WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgInRheF9pZF9jb2RlIiwgIlRJ +TklULVhYWFhYWFhYWFhYWFhYWFgiXQ

  • +
  • Contents: ["AJx-095VPrpTtN4QMOqROA", "tax_id_code", +"TINIT-XXXXXXXXXXXXXXXX"]

  • +
+

The combined format for the PID issuance is given by

+
eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBb
+IkJvTUdrdFcxcmJpa250dzhGenhfQmVMNFliQW5kcjZBSHNkZ3BhdEZDaWciLCAiRU5O
+bzMxamZ6RnA4WTJEVzBSLWZJTWVXd2U3RUxHdkdvSE13TUJwdTE0RSIsICJWUUktUzFt
+VDFLeGZxMm84Sjlpbzd4TU1YMk1JeGFHOU05UGVKVnFyTWNBIiwgIllyYy1zLVdTcjRl
+eEVZdHFERXNtUmw3c3BvVmZtQnhpeFAxMmU0c3lxTkUiLCAiczFYSzVmMnBNMy1hRlRh
+dVhobXZkOXB5UVRKNkZNVWhjLUpYZkhyeGhMayIsICJ6VmRnaGNtQ2xNVldsVWdHc0dw
+U2tDUGtFSFo0dTlvV2oxU2xJQmxDYzFvIl0sICJpc3MiOiAiaHR0cHM6Ly9waWRwcm92
+aWRlci5leGFtcGxlLm9yZyIsICJpYXQiOiAxNjgzMDAwMDAwLCAiZXhwIjogMTg4MzAw
+MDAwMCwgInN1YiI6ICJOemJMc1hoOHVEQ2NkN25vV1hGWkFmSGt4WnNSR0M5WHMiLCAi
+c3RhdHVzIjogeyJzdGF0dXNfYXNzZXJ0aW9uIjogeyJjcmVkZW50aWFsX2hhc2hfYWxn
+IjogInNoYS0yNTYifX0sICJ2Y3QiOiAiaHR0cHM6Ly9waWRwcm92aWRlci5leGFtcGxl
+Lm9yZy92MS4wL3BlcnNvbmlkZW50aWZpY2F0aW9uZGF0YSIsICJ2Y3QjaW50ZWdyaXR5
+IjogImM1ZjczZTI1MGZlODY5ZjI0ZDE1MTE4YWNjZTI4NmM5YmI1NmI2M2E0NDNkYzg1
+YWY2NTNjZDczZjYwNzhiMWYiLCAidmVyaWZpY2F0aW9uIjogeyJ0cnVzdF9mcmFtZXdv
+cmsiOiAiZWlkYXMiLCAiYXNzdXJhbmNlX2xldmVsIjogImhpZ2giLCAiZXZpZGVuY2Ui
+OiB7Im1ldGhvZCI6ICJjaWUifX0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjog
+eyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5
+WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdX
+YlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.NE_Q2unPGzoh
+rIyVI0kAZ8nz3DLhUXBBd-jji8302PyIU0xqLnGtcWrdM9NPE_-BfUe3H-XFahYOMI54
+PUvdZw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImlhdCIsIDE2ODMwMDAwMDBd~
+WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgInVuaXF1ZV9pZCIsICJ4eHh4eHh4eC14
+eHh4LXh4eHgteHh4eC14eHh4eHh4eHh4eHgiXQ~WyI2SWo3dE0tYTVpVlBHYm9TNXRtd
+lZBIiwgImdpdmVuX25hbWUiLCAiTWFyaW8iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZG
+hRIiwgImZhbWlseV9uYW1lIiwgIlJvc3NpIl0~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm
+9BIiwgImJpcnRoX2RhdGUiLCAiMTk4MC0wMS0xMCJd~WyJBSngtMDk1VlBycFR0TjRRT
+U9xUk9BIiwgInRheF9pZF9jb2RlIiwgIlRJTklULVhYWFhYWFhYWFhYWFhYWFgiXQ~
+
+
+
+
+

(Q)EAA non-normative examples

+

In the following, we provide a non-normative example of (Q)EAA in JSON.

+
{
+  "iss": "https://issuer.example.org",
+  "sub": "NzbLsXh8uDCcd7noWXFZAfHkxZsRGC9Xs",
+  "iat": 1683000000,
+  "exp": 1883000000,
+  "status": {
+    "status_assertion": {
+      "credential_hash_alg": "sha-256"
+    }
+  },
+  "vct": "https://issuer.example.org/v1.0/disabilitycard",
+  "vct#integrity": "2e40bcd6799008085ffb1a1f3517efee335298fd976b3e655bfb3f4eaa11d171",
+  "verification": {
+    "trust_framework": "eidas",
+    "assurance_level": "high",
+    "evidence": {
+      "method": "cie"
+    }
+  },
+  "document_number": "XXXXXXXXXX",
+  "given_name": "Mario",
+  "family_name": "Rossi",
+  "birth_date": "1980-01-10",
+  "expiry_date": "2024-01-01",
+  "tax_id_code": "TINIT-XXXXXXXXXXXXXXXX",
+  "constant_attendance_allowance": true
+}
+
+
+

The corresponding SD-JWT for the previous data is represented as follow, as decoded JSON for both header and payload.

+
{
+  "typ":"vc+sd-jwt",
+  "alg":"ES256",
+  "kid":"d126a6a856f7724560484fa9dc59d195",
+  "trust_chain" : [
+   "NEhRdERpYnlHY3M5WldWTWZ2aUhm ...",
+   "eyJhbGciOiJSUzI1NiIsImtpZCI6 ...",
+   "IkJYdmZybG5oQU11SFIwN2FqVW1B ..."
+  ]
+}
+
+
+
{
+  "_sd": [
+    "8JjozBfovMNvQ3HflmPWy4O19Gpxs61FWHjZebU589E",
+    "Dx-6hjvrcxNzF0slU6ukNmzHoL-YvBN-tFa0T8X-bY0",
+    "GE3Sjy_zAT34f8wa5DUkVB0FslaSJRAAc8I3lN11Ffc",
+    "VQI-S1mT1Kxfq2o8J9io7xMMX2MIxaG9M9PeJVqrMcA",
+    "Yrc-s-WSr4exEYtqDEsmRl7spoVfmBxixP12e4syqNE",
+    "aBVdfcnxT0Z5RrwdxZSUhuUxz3gM2vcEZLeYIj61Kas",
+    "s1XK5f2pM3-aFTauXhmvd9pyQTJ6FMUhc-JXfHrxhLk",
+    "zVdghcmClMVWlUgGsGpSkCPkEHZ4u9oWj1SlIBlCc1o"
+  ],
+  "iss": "https://issuer.example.org",
+  "iat": 1683000000,
+  "exp": 1883000000,
+  "sub": "NzbLsXh8uDCcd7noWXFZAfHkxZsRGC9Xs",
+  "status": {
+    "status_assertion": {
+      "credential_hash_alg": "sha-256"
+    }
+  },
+  "vct": "https://issuer.example.org/v1.0/disabilitycard",
+  "vct#integrity": "2e40bcd6799008085ffb1a1f3517efee335298fd976b3e655bfb3f4eaa11d171",
+  "verification": {
+    "trust_framework": "eidas",
+    "assurance_level": "high",
+    "evidence": {
+      "method": "cie"
+    }
+  },
+  "_sd_alg": "sha-256",
+  "cnf": {
+    "jwk": {
+      "kty": "EC",
+      "crv": "P-256",
+      "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
+      "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
+    }
+  }
+}
+
+
+

In the following the disclosure list is given:

+

Claim iat:

+
    +
  • SHA-256 Hash: Yrc-s-WSr4exEYtqDEsmRl7spoVfmBxixP12e4syqNE

  • +
  • Disclosure: +WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImlhdCIsIDE2ODMwMDAwMDBd

  • +
  • Contents: ["2GLC42sKQveCfGfryNRN9w", "iat", 1683000000]

  • +
+

Claim document_number:

+
    +
  • SHA-256 Hash: Dx-6hjvrcxNzF0slU6ukNmzHoL-YvBN-tFa0T8X-bY0

  • +
  • Disclosure: +WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImRvY3VtZW50X251bWJlciIs +ICJYWFhYWFhYWFhYIl0

  • +
  • Contents: +["eluV5Og3gSNII8EYnsxA_A", "document_number", "XXXXXXXXXX"]

  • +
+

Claim given_name:

+
    +
  • SHA-256 Hash: zVdghcmClMVWlUgGsGpSkCPkEHZ4u9oWj1SlIBlCc1o

  • +
  • Disclosure: +WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImdpdmVuX25hbWUiLCAiTWFy +aW8iXQ

  • +
  • Contents: ["6Ij7tM-a5iVPGboS5tmvVA", "given_name", "Mario"]

  • +
+

Claim family_name:

+
    +
  • SHA-256 Hash: VQI-S1mT1Kxfq2o8J9io7xMMX2MIxaG9M9PeJVqrMcA

  • +
  • Disclosure: +WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgImZhbWlseV9uYW1lIiwgIlJv +c3NpIl0

  • +
  • Contents: ["eI8ZWm9QnKPpNPeNenHdhQ", "family_name", "Rossi"]

  • +
+

Claim birth_date:

+
    +
  • SHA-256 Hash: s1XK5f2pM3-aFTauXhmvd9pyQTJ6FMUhc-JXfHrxhLk

  • +
  • Disclosure: +WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImJpcnRoX2RhdGUiLCAiMTk4 +MC0wMS0xMCJd

  • +
  • Contents: ["Qg_O64zqAxe412a108iroA", "birth_date", "1980-01-10"]

  • +
+

Claim expiry_date:

+
    +
  • SHA-256 Hash: aBVdfcnxT0Z5RrwdxZSUhuUxz3gM2vcEZLeYIj61Kas

  • +
  • Disclosure: +WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImV4cGlyeV9kYXRlIiwgIjIw +MjQtMDEtMDEiXQ

  • +
  • Contents: ["AJx-095VPrpTtN4QMOqROA", "expiry_date", "2024-01-01"]

  • +
+

Claim tax_id_code:

+
    +
  • SHA-256 Hash: 8JjozBfovMNvQ3HflmPWy4O19Gpxs61FWHjZebU589E

  • +
  • Disclosure: +WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgInRheF9pZF9jb2RlIiwgIlRJ +TklULVhYWFhYWFhYWFhYWFhYWFgiXQ

  • +
  • Contents: ["Pc33JM2LchcU_lHggv_ufQ", "tax_id_code", +"TINIT-XXXXXXXXXXXXXXXX"]

  • +
+

Claim constant_attendance_allowance:

+
    +
  • SHA-256 Hash: GE3Sjy_zAT34f8wa5DUkVB0FslaSJRAAc8I3lN11Ffc

  • +
  • Disclosure: +WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgImNvbnN0YW50X2F0dGVuZGFu +Y2VfYWxsb3dhbmNlIiwgdHJ1ZV0

  • +
  • Contents: +["G02NSrQfjFXQ7Io09syajA", "constant_attendance_allowance", +true]

  • +
+

The combined format for the (Q)EAA issuance is represented below:

+
eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBb
+IjhKam96QmZvdk1OdlEzSGZsbVBXeTRPMTlHcHhzNjFGV0hqWmViVTU4OUUiLCAiRHgt
+NmhqdnJjeE56RjBzbFU2dWtObXpIb0wtWXZCTi10RmEwVDhYLWJZMCIsICJHRTNTanlf
+ekFUMzRmOHdhNURVa1ZCMEZzbGFTSlJBQWM4STNsTjExRmZjIiwgIlZRSS1TMW1UMUt4
+ZnEybzhKOWlvN3hNTVgyTUl4YUc5TTlQZUpWcXJNY0EiLCAiWXJjLXMtV1NyNGV4RVl0
+cURFc21SbDdzcG9WZm1CeGl4UDEyZTRzeXFORSIsICJhQlZkZmNueFQwWjVScndkeFpT
+VWh1VXh6M2dNMnZjRVpMZVlJajYxS2FzIiwgInMxWEs1ZjJwTTMtYUZUYXVYaG12ZDlw
+eVFUSjZGTVVoYy1KWGZIcnhoTGsiLCAielZkZ2hjbUNsTVZXbFVnR3NHcFNrQ1BrRUha
+NHU5b1dqMVNsSUJsQ2MxbyJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUu
+b3JnIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjog
+Ik56YkxzWGg4dURDY2Q3bm9XWEZaQWZIa3hac1JHQzlYcyIsICJzdGF0dXMiOiB7InN0
+YXR1c19hc3NlcnRpb24iOiB7ImNyZWRlbnRpYWxfaGFzaF9hbGciOiAic2hhLTI1NiJ9
+fSwgInZjdCI6ICJodHRwczovL2lzc3Vlci5leGFtcGxlLm9yZy92MS4wL2Rpc2FiaWxp
+dHljYXJkIiwgInZjdCNpbnRlZ3JpdHkiOiAiMmU0MGJjZDY3OTkwMDgwODVmZmIxYTFm
+MzUxN2VmZWUzMzUyOThmZDk3NmIzZTY1NWJmYjNmNGVhYTExZDE3MSIsICJ2ZXJpZmlj
+YXRpb24iOiB7InRydXN0X2ZyYW1ld29yayI6ICJlaWRhcyIsICJhc3N1cmFuY2VfbGV2
+ZWwiOiAiaGlnaCIsICJldmlkZW5jZSI6IHsibWV0aG9kIjogImNpZSJ9fSwgIl9zZF9h
+bGciOiAic2hhLTI1NiIsICJjbmYiOiB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6
+ICJQLTI1NiIsICJ4IjogIlRDQUVSMTladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxz
+N3ZDZUdlbWMiLCAieSI6ICJaeGppV1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0
+NGpUOUYySFpRIn19fQ.FAIV8Cncch43N07yBcWleJg4ZO9o_XdefgIejdShK1cCj8yT9
+S022cvSpdxuV44x-c_XmTn3Db9t0jJJPtqebA~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STj
+l3IiwgImlhdCIsIDE2ODMwMDAwMDBd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgI
+mRvY3VtZW50X251bWJlciIsICJYWFhYWFhYWFhYIl0~WyI2SWo3dE0tYTVpVlBHYm9TN
+XRtdlZBIiwgImdpdmVuX25hbWUiLCAiTWFyaW8iXQ~WyJlSThaV205UW5LUHBOUGVOZW
+5IZGhRIiwgImZhbWlseV9uYW1lIiwgIlJvc3NpIl0~WyJRZ19PNjR6cUF4ZTQxMmExMD
+hpcm9BIiwgImJpcnRoX2RhdGUiLCAiMTk4MC0wMS0xMCJd~WyJBSngtMDk1VlBycFR0T
+jRRTU9xUk9BIiwgImV4cGlyeV9kYXRlIiwgIjIwMjQtMDEtMDEiXQ~WyJQYzMzSk0yTG
+NoY1VfbEhnZ3ZfdWZRIiwgInRheF9pZF9jb2RlIiwgIlRJTklULVhYWFhYWFhYWFhYWF
+hYWFgiXQ~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgImNvbnN0YW50X2F0dGVuZGF
+uY2VfYWxsb3dhbmNlIiwgdHJ1ZV0~
+
+
+
+
+
+

MDOC-CBOR

+

The PID/(Q)EAA MDOC-CBOR data model is defined in ISO/IEC 18013-5, the standard born for the the mobile driving license (mDL) use case.

+

The MDOC data elements MUST be encoded as defined in RFC 8949 - Concise Binary Object Representation (CBOR).

+

The PID encoded in MDOC-CBOR format uses the document type set to eu.europa.ec.eudiw.pid.1, according to the reverse domain approach defined in the +EIDAS-ARF and ISO/IEC 18013-5.

+

The document's data elements utilize a consistent namespace for the mandatory Mobile Driving License attributes, while the national PID attributes use the domestic namespace eu.europa.ec.eudiw.pid.it.1, as outlined in this implementation profile.

+

In compliance with ISO/IEC 18013-5, the MDOC data model in the domestic namespace eu.europa.ec.eudiw.pid.it.1, requires the following attributes:

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Attribute name

Description

Reference

version

tstr (text string). Version of the data structure being used. It's a way to track changes and updates to the standard or to a specific implementation profile. This allows for backward compatibility and understanding of the data if the standard or implementation evolves over time.

[ISO 18013-5#8.3.2.1.2]

status

uint (unsigned int). Status code. For example "status":0 means OK (normal processing).

[ISO 18013-5#8.3.2.1.2.3]

documents

bstr (byte string). The collection of digital documents. Each document in this collection represents a specific type of data or information related to the Digital Credential.

[ISO 18013-5#8.3.2.1.2]

+

Each document within the documents collection MUST have the following structure:

+ +++++ + + + + + + + + + + + + + + + + +

Attribute name

Description

Reference

docType

tstr (text string). Document type. For the PID, the value MUST be set to eu.europa.ec.eudiw.pid.1. For an mDL, the value MUST be org.iso.18013-5.1.mDL.

[ISO 18013-5#8.3.2.1.2]

issuerSigned

bstr (byte string). It MUST contain the Mobile Security Object for Issuer data authentication and the data elements protected by Issuer data authentication.

[ISO 18013-5#8.3.2.1.2]

+

The issuerSigned object MUST have the following structure:

+ +++++ + + + + + + + + + + + + + + + + +

Attribute name

Description

Reference

nameSpaces

bstr (byte string) with tag 24 and major type 6. Returned data elements for the namespaces. It MAY be possible to have one or more namespaces. The nameSpaces MUST use the same value for the document type. However, it MAY have a domestic namespace to include attributes defined in this implementation profile. The value MUST be set to eu.europa.ec.eudiw.pid.it.1.

[ISO 18013-5#8.3.2.1.2]

issuerAuth

bstr (byte string). Contains Mobile Security Object (MSO), a COSE Sign1 Document, issued by the Credential Issuer.

[ISO 18013-5#9.1.2.4]

+

During the presentation of the MDOC-CBOR credential, in addition to the objects in the table above, a deviceSigned object MUST also be added. deviceSigned MUST NOT be included in the issued credential provided by the PID/(Q)EAA Issuer.

+ +++++ + + + + + + + + + + + + +

Attribute name

Description

Reference

deviceSigned

bstr (byte string). Data elements signed by the Wallet Instance during the presentation phase.

[ISO 18013-5#8.3.2.1.2]

+

Where the deviceSigned MUST have the following structure:

+ +++++ + + + + + + + + + + + + + + + + +

Attribute name

Description

Reference

nameSpaces

tstr (text string). Returned data elements for the namespaces. It MAY be possible to have one or more namespaces. It MAY be used for self-attested claims.

[ISO 18013-5#8.3.2.1.2]

deviceAuth

bstr (byte string). It MUST contain either the DeviceSignature or the DeviceMac element.

[ISO 18013-5#8.3.2.1.2]

+
+

Note

+

A deviceSigned object given during the presentation phase has two purposes:

+
+
    +
  1. It provides optional self-attested attributes in the nameSpaces object. If no self-attested attributes are provided by the Wallet Instance, the nameSpaces object MUST be included with an empty structure.

  2. +
  3. Provide a cryptographic proof attesting that the Holder is the legitimate owner of the Credential, by means of a deviceAuth object.

  4. +
+
+
+
+

Note

+

The issuerSigned and the deviceSigned objects contain the nameSpaces object and the Mobile Security Object. The latter is the only signed object, while the nameSpaces object is not signed.

+
+
+

nameSpaces

+

The nameSpaces object contains one or more IssuerSignedItemBytes that are encoded using CBOR bitsring 24 tag (#6.24(bstr .cbor), marked with the CBOR Tag 24(<<... >>) and represented in the example using the diagnostic format). It represents the disclosure information for each digest within the Mobile Security Object and MUST contain the following attributes:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Encoding

Description

digestID

integer

Reference value to one of the ValueDigests provided in the Mobile Security Object (issuerAuth).

random

bstr (byte string)

Random byte value used as salt for the hash function. This value SHALL be different for each IssuerSignedItem and it SHALL have a minimum length of 16 bytes.

elementIdentifier

tstr (text string)

Data element identifier.

elementValue

depends by the value, see the next table.

Data element value.

+

The elementIdentifier data that MUST be included in a PID/(Q)EAA are:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Namespace

Element identifier

Description

eu.europa.ec.eudiw.pid.1

issue_date

full-date (CBORTag 1004). Date when the PID/(Q)EAA was issued.

eu.europa.ec.eudiw.pid.1

expiry_date

full-date (CBORTag 1004). Date when the PID/(Q)EAA will expire.

eu.europa.ec.eudiw.pid.1

issuing_authority

tstr (text string). Name of administrative authority that has issued the PID/(Q)EAA.

eu.europa.ec.eudiw.pid.1

issuing_country

tstr (text string). Alpha-2 country code as defined in [ISO 3166].

+

Depending on the Digital Credential type, additional elementIdentifier data MAY be added. The PID MUST support the following data:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Namespace

Element identifier

Description

eu.europa.ec.eudiw.pid.1

given_name

tstr (text string). See PID Claims fields Section.

eu.europa.ec.eudiw.pid.1

family_name

tstr (text string). See PID Claims fields Section.

eu.europa.ec.eudiw.pid.1

birth_date

full-date (CBORTag 1004). See PID Claims fields Section.

eu.europa.ec.eudiw.pid.1

unique_id

tstr (text string). See PID Claims fields Section.

eu.europa.ec.eudiw.pid.it.1

tax_id_code

tstr (text string). See PID Claims fields Section.

+
+
+

Mobile Security Object

+

The issuerAuth represents the Mobile Security Object which is a COSE Sign1 Document defined in RFC 9052 - CBOR Object Signing and Encryption (COSE): Structures and Process. It has the following data structure:

+
    +
  • protected header

  • +
  • unprotected header

  • +
  • payload

  • +
  • signature.

  • +
+

The protected header MUST contain the following parameter encoded in CBOR format:

+ +++++ + + + + + + + + + + + + +

Element

Description

Reference

Signature algorithm

-7 means ES256, SHA-256.

RFC8152

+
+

Note

+

Only the Signature Algorithm MUST be present in the protected headers, other elements SHOULD not be present in the protected header.

+
+

The unprotected header MUST contain the following parameter:

+ +++++ + + + + + + + + + + + + +

Element

Description

Reference

x5chain

Identified with the label 33

RFC 9360 CBOR Object Signing and Encryption (COSE) - Header Parameters for Carrying and Referencing X.509 Certificates.

+
+

Note

+

The x5chain is included in the unprotected header with the aim to make the Holder able to update the X.509 certificate chain, related to the Mobile Security Object issuer, without invalidating the signature.

+
+

The payload MUST contain the MobileSecurityObject, without the content-type COSE Sign header parameter and encoded as a byte string (bstr) using the CBOR Tag 24.

+

The MobileSecurityObjectBytes MUST have the following attributes:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Element

Description

Reference

docType

See Table.

[ISO 18013-5#9.1.2.4]

version

See Table.

[ISO 18013-5#9.1.2.4]

validityInfo

Object containing issuance and expiration datetimes. It MUST contain the following sub-value:

+
+
    +
  • signed

  • +
  • validFrom

  • +
  • validUntil

  • +
+
+

[ISO 18013-5#9.1.2.4]

digestAlgorithm

According to the algorithm defined in the protected header.

[ISO 18013-5#9.1.2.4]

valueDigests

Mapped digest by unique id, grouped by namespace.

[ISO 18013-5#9.1.2.4]

deviceKeyInfo

It MUST contain the Wallet Instance's public key containing the following sub-values.

+
+
    +
  • deviceKey (REQUIRED).

  • +
  • keyAuthorizations (OPTIONAL).

  • +
  • keyInfo (OPTIONAL).

  • +
+
+

[ISO 18013-5#9.1.2.4]

+
+

Note

+

The private key related to the public key stored in the deviceKey object is used to sign the DeviceSignedItems object and proof the possession of the PID during the presentation phase (see the presentation phase with MDOC-CBOR).

+
+
+
+

MDOC-CBOR Examples

+

A non-normative example of a PID in MDOC-CBOR format is represented below using the AF Binary encoding:

+
a366737461747573006776657273696f6e63312e3069646f63756d656e747381a267646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316c6973737565725369676e6564a26a697373756572417574688443a10126a1182159021930820215308201bca003020102021404ad06a30c1a6dc6e93be0e2e8f78dcafa7907c2300a06082a8648ce3d040302305b310b3009060355040613025a45312e302c060355040a0c25465053204d6f62696c69747920616e64205472616e73706f7274206f66205a65746f706961311c301a06035504030c1349414341205a65746573436f6e666964656e73301e170d3231303932393033333034355a170d3232313130333033333034345a3050311a301806035504030c114453205a65746573436f6e666964656e7331253023060355040a0c1c5a65746f70696120436974792044657074206f662054726166666963310b3009060355040613025a453059301306072a8648ce3d020106082a8648ce3d030107034200047c5545e9a0b15f4ff3ce5015121e8ad3257c28d541c1cd0d604fc9d1e352ccc38adef5f7902d44b7a6fc1f99f06eedf7b0018fd9da716aec2f1ffac173356c7da3693067301f0603551d23041830168014bba2a53201700d3c97542ef42889556d15b7ac4630150603551d250101ff040b3009060728818c5d050102301d0603551d0e04160414ce5fd758a8e88563e625cf056bfe9f692f4296fd300e0603551d0f0101ff040403020780300a06082a8648ce3d0403020347003044022012b06a3813ffec5679f3b8cddb51eaa4b95b0cbb1786b09405e2000e9c46618c02202c1f778ad252285ed05d9b55469f1cb78d773671f30fe7ab815371942328317c59032ad818590325a667646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316776657273696f6e63312e306c76616c6964697479496e666fa3667369676e6564c074323032332d30322d32325430363a32333a35365a6976616c696446726f6dc074323032332d30322d32325430363a32333a35365a6a76616c6964556e74696cc074323032342d30322d32325430303a30303a30305a6c76616c756544696765737473a2781865752e6575726f70612e65632e65756469772e7069642e31ac015820a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a025820cd372fb85148700fa88095e3492d3f9f5beb43e555e5ff26d95f5a6adc36f8e6035820e67e72111b363d80c8124d28193926000980e1211c7986cacbd26aacc5528d48045820f7d062d662826ed95869851db06bb539b402047baee53a00e0aa35bfbe98265d0658202a132dbfe4784627b86aa3807cd19cfeff487aab3dd7a60d0ab119a72e736936075820bdca9e8dbca354e824e67bfe1533fa4a238b9ea832f23fb4271ebeb3a5a8f7200858202c0eaec2f05b6c7fe7982683e3773b5d8d7a01e33d04dfcb162add8bd99bee9a095820bfe220d85657ccec3c67e7db1df747e9148a152334bb6d4b65b273279bcc36ec0a582018e38144f5044301d6a0b4ec9d5f98d4cd950e6ea2c29b849cbd457da29b6ad30b58203c71d2f0efa09d9e3fbbdffd29204f6b292c9f79570aef72dd86c91f7a3aa5c50c582065743d58d89d45e52044758f546034fd13a4f994bc270cdfa7844f74eb3f4b6e0d5820b4a8eb5d523bffa17b41bda12ddc7da32ae1e5f7ff3dcc394a35401f16919bbf781b65752e6575726f70612e65632e65756469772e7069642e69742e31a10e58209d6c11644651126c94acdaf0803e86d4c71d15d3b2712a14295416734efd514d6d6465766963654b6579496e666fa1696465766963654b6579a401022001215820ba01aea44eee1e338eb2f04e279dbd51b34655783ee185150838c9a7a7c4db7122582025ba0044439a3871a7b975a0994a85e79b705a9ac263b3fe899b0a93412ee8c96f646967657374416c676f726974686d675348412d32353658400813c28fd62f2602cbc14724e5865733c44a0fca589b55c085ec9d5c725d6cce25ba0044439a3871a7b975a0994a85e79b705a9ac263b3fe899b0a93412ee8c96a6e616d65537061636573a2781865752e6575726f70612e65632e65756469772e7069642e3188d818586da4686469676573744944016672616e646f6d5820156df9227ad341eaa61aabd301106fd21bdc18820e01dfc16bcf5fecc447111b71656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d30322d3232d818586fa4686469676573744944026672616e646f6d5820a3a1f13f05544d03a5b50b5fdb78465808393bcf3b7953a345fe28f820c7be0d71656c656d656e744964656e7469666965726d69737375616e63655f646174656c656c656d656e7456616c7565d903ec6a323032332d30322d3232d8185866a4686469676573744944036672616e646f6d5820852591f90f2c9ded57a03632e2c1322ab52a082a431e71a4149a6830c8f1ad0c71656c656d656e744964656e7469666965726f69737375696e675f636f756e7472796c656c656d656e7456616c7565624954d818587ca4686469676573744944046672616e646f6d5820d1d587b3512acce15c4f6b20944ceb002a464e4a158389788563408873c3fce571656c656d656e744964656e7469666965727169737375696e675f617574686f726974796c656c656d656e7456616c7565764d696e69737465726f2064656c6c27496e7465726e6fd8185864a4686469676573744944056672616e646f6d582094fdd7609c0e73dc8589b5cab11e1d9058cf8bff8a336da5f81fcba055396a0f71656c656d656e744964656e7469666965726a676976656e5f6e616d656c656c656d656e7456616c7565654d6172696fd8185865a4686469676573744944066672616e646f6d5820660c0a7bf79e0e0261ca1547a4294fb808aa70738f424b13ab1b9440b566ae1371656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756565526f737369d818586ba4686469676573744944076672616e646f6d5820315c53491286488fa07f5c2ce67135ef5c9959c3469c99a14e9b6dc924f9eba571656c656d656e744964656e746966696572696269727468646174656c656c656d656e7456616c7565d903ec6a313935362d30312d3132d818587da4686469676573744944086672616e646f6d5820764ef39c9d01f3aa6a87f441603cfe853fba3cee3bc2c168bcc9e96271d6e06371656c656d656e744964656e74696669657269756e697175655f69646c656c656d656e7456616c7565781e78787878787878782d7878782d787878782d787878787878787878787878781b65752e6575726f70612e65632e65756469772e7069642e69742e3181d8185877a46864696765737449440d6672616e646f6d5820717df3f583b1484366c33a1f869f2b5d201d466a8b589c79ab1a2d85e595432571656c656d656e744964656e7469666965726d7461785f69645f6e756d6265726c656c656d656e7456616c75657554494e49542d585858585858585858585858585858
+
+
+

The Diagnostic Notation of the above MDOC-CBOR is given below:

+
{     
+    "status": 0,     
+    "version": "1.0",     
+    "documents": [        
+    {             
+      "docType": "eu.europa.ec.eudiw.pid.1",                         
+      "issuerSigned": {                
+          "issuerAuth": [                
+          << {1: -7} >>, % protected header with the value alg:ES256                    
+          {                         
+              33: h'30820215308201BCA003020102021404AD30C…'% 33->X5chain:COSE X_509  
+          },
+          <<                       
+              24(<<    
+                  {                            
+                  "docType": "eu.europa.ec.eudiw.pid.1",                                
+                  "version": "1.0",  
+                  "validityInfo": {                                
+                      "signed": 0("2023-02-22T06:23:56Z"),                                     
+                      "validFrom": 0("2023-02-22T06:23:56Z"),                                   
+                      "validUntil": 0("2024-02-22T00:00:00Z")                               
+                  },
+                  "valueDigests": { 
+                      "eu.europa.ec.eudiw.pid.1": {        
+                          1: h'0F1571A97FFB799CC8FCDF2BA4FC2909929…',                                          
+                          2: h'0CDFE077400432C055A2B69596C90…',     
+                          3: h'E2382149255AE8E955AF9B8984395…',                                        
+                          4: h'BBC77E6CCA981A3AD0C3E544EDF86…',                                     
+                          6: h'BB6E6C68D1B4B4EC5A2AE9206F5t4…',
+                          7: h'F8A5966E6DAC9970E0334D8F75E25…',              
+                          8: h'DEFDF1AA746718016EF1B94BFE5R6…'
+                      },
+                      "eu.europa.ec.eudiw.pid.it.1": {  
+                          9: h'F9EE4D36F67DBD75E23311AC1C29…'
+                      }
+                  },                             
+                  "deviceKeyInfo": {                              
+                      "deviceKey": {                                  
+                          1: 2, % kty:EC2 (Eliptic curves with x and y coordinate pairs)           
+                          -1: 1, % crv:p256                     
+                          -2: h'B820963964E53AF064686DD9218303494A…', % x-coordiantes                                        
+                          -3: h'0A6DA0AF437E2943F1836F31C678D89298E9…'% y-ccordiantes                                     
+                      }                            
+                  },                             
+                  "digestAlgorithm": "SHA-256"    
+                  }                       
+              >>)                     
+          >>,                        
+          h'1AD0D6A7313EFDC38FCD765852FA2BD43DEBF48BF5A580D'                 
+          ],                 
+          "nameSpaces": {
+              "eu.europa.ec.eudiw.pid.1": [                         
+              24(<<    
+                  {      
+                  "digestID": 1,                                  
+                  "random": h'E0B70BCEFBD43686F345C9ED429343AA',                                 
+                  "elementIdentifier": "expiry_date",                                
+                  "elementValue": 1004("2024-02-22")                             
+                  }                         
+              >>), 
+              24(<<             
+                  {       
+                  "digestID": 2,                                  
+                  "random": h'AE84834F389EE69888665B90A3E4FCCE', 
+                  "elementIdentifier": "issue_date",   
+                  "elementValue": 1004("2023-02-22")                                
+                  }
+              >>),                         
+              24(<<   
+                  {                              
+                  "digestID": 3,                                 
+                  "random": h'960CB15A2EA9B68E5233CE902807AA95',                               
+                  "elementIdentifier": "issuing_country",                               
+                  "elementValue": "IT"                                                    
+                  }                       
+              >>), 
+              24(<<       
+                  {                        
+                  "digestID": 4,    
+                  "random": h'9D3774BD5994CCFED248674B32A4F76A', 
+                  "elementIdentifier": "issuing_authority",   
+                  "elementValue": "Ministero dell'Interno"  
+                  }   
+              >>),                 
+              24(<<        
+                  {                              
+                  "digestID": 5,                         
+                  "random": h'EB12193DC66C6174530CDC29B274381F', 
+                  "elementIdentifier": "given_name",
+                  "elementValue": "Mario"                             
+                  }                         
+              >>)),            
+              24(<<                            
+                  {                               
+                  "digestID": 6,                             
+                  "random": h'DB143143538F3C8D41DC024F9CB25C9D',
+                  "elementIdentifier": "family_name",  
+                  "elementValue": "Rossi"    
+                  } 
+              >>),                         
+              24(<<               
+                  {                          
+                  "digestID": 7, 
+                  "random": h'6059FF1CE27B4997B4ADE1DE7B01DC60',
+                  "elementIdentifier": "birth_date",
+                  "elementValue": 1004("1956-01-12")% the tag 1004 defines the value    
+                                                      is a full date 
+                  }  
+              >>),         
+              24(<<  
+                  {                              
+                  "digestID": 8,                              
+                  "random": h'53C15C57B3B076E788795829190220B4',
+                  "elementIdentifier": "unique_id",
+                  "elementValue": "xxxxxxxx-xxx-xxxx-xxxxxxxxxxxx" 
+                  }   
+              >>)
+              ],
+              "eu.europa.ec.eudiw.pid.it.1": [
+                  24(<<
+                      {
+                      "digestID": 9, 
+                      "random": h'11aa7273a2d2daa973f5951f0c34c2fbae',
+                      "elementIdentifier": "tax_id_number", 
+                      "elementValue": "TINIT-XXXXXXXXXXXXXXX"
+                      }                         
+                  >>)                    
+              ]            
+          }  
+      }           
+    }
+    ]
+  }
+
+
+
+
+
+ + +
+
+
+
+ + + + + + +
+
+
+ +
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/pid-eaa-entity-configuration.html b/refs/pull/443/merge/en/pid-eaa-entity-configuration.html new file mode 100644 index 000000000..6cea281b1 --- /dev/null +++ b/refs/pull/443/merge/en/pid-eaa-entity-configuration.html @@ -0,0 +1,1021 @@ + + + + + + + + Entity Configuration of PID/(Q)EAA Providers — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Entity Configuration of PID/(Q)EAA Providers

+

The PID/(Q)EAA Providers, as Federation Entity, are required to adhere to the guidelines outlined in Section Configuration of the Federation. Specifically, they MUST provide a well-known endpoint that hosts their Entity Configuration. +The Entity Configuration of PID/(Q)EAA Providers MUST contain the parameters defined in the Sections Entity Configuration Leaves and Intermediates and Entity Configurations Common Parameters.

+

The PID/(Q)EAA Providers MUST provide the following metadata types:

+
+
    +
  • federation_entity

  • +
  • oauth_authorization_server

  • +
  • openid_credential_issuer

  • +
+
+

In cases where the (Q)EAA Providers authenticate Users using their Wallet Instance, then the metadata for wallet_relying_party MUST be provided in addition to the metadata above. In case a national eID scheme is used by the PID/(Q)EAA Providers for the User authentication, they MAY include a metadata for openid_relying_party within their Entity Configuration. The openid_relying_party metadata MUST be compliant with the current version of SPID/CIE id OIDC Technical Specification.

+
+

Metadata for federation_entity

+

The federation_entity metadata MUST contain the parameters as defined in Section Metadata of federation_entity Leaves.

+
+
+

Metadata for oauth_authorization_server

+

The oauth_authorization_server metadata MUST contain the following parameters.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

issuer

It MUST contain an HTTPS URL that uniquely identifies the PID/(Q)EAA Provider.

pushed_authorization_request_endpoint

The URL of the pushed authorization request endpoint is where a Wallet Instance MUST submit an authorization request to obtain a request_uri value, which can then be used at the authorization endpoint. See RFC 9126#as_metadata.

authorization_endpoint

URL of the authorization server's authorization endpoint. See RFC 8414#section-2.

token_endpoint

URL of the authorization server's token endpoint. See RFC 8414#section-2.

client_registration_types_supported

Array specifying the registration types supported. The authorization server MUST support automatic. See OID-FED Section 5.1.3.

code_challenge_methods_supported

JSON array containing a list of Proof Key for Code Exchange (PKCE) RFC 7636 code challenge methods supported by the authorization server. The authorization server MUST support S256.

acr_values_supported

See OpenID Connect Discovery 1.0 Section 3. The supported values are:

+
    +
  • https://www.spid.gov.it/SpidL1

  • +
  • https://www.spid.gov.it/SpidL2

  • +
  • https://www.spid.gov.it/SpidL3

  • +
+

scopes_supported

JSON array containing a list of the supported scope values. See RFC 8414#section-2.

response_modes_supported

JSON array containing a list of the supported "response_mode" values, as specified in OAuth 2.0 Multiple Response Type Encoding Practices. The supported values MAY be query and form_post.jwt (see [oauth-v2-jarm-03]).

authorization_signing_alg_values_supported

JSON array containing a list of the JWS RFC 7515 supported signing algorithms (alg values). The values MUST be set according to Section Cryptographic Algorithms. See Section 4 of [oauth-v2-jarm-03].

grant_types_supported

JSON array containing a list of the supported grant type values. The authorization server MUST support authorization_code.

token_endpoint_auth_methods_supported

JSON array containing a list of supported client authentication methods. The Token Endpoint MUST support attest_jwt_client_auth as defined in OAUTH-ATTESTATION-CLIENT-AUTH.

token_endpoint_auth_signing_alg_values_supported

JSON array containing a list of the JWS signing algorithms ("alg" values) supported by the token endpoint for the signature on the JWT used to authenticate the client at the Token Endpoint. See RFC 8414#section-2.

request_object_signing_alg_values_supported

JSON array containing a list of the JWS signing algorithms ("alg" values) supported for Request Objects. See [openid-connect-discovery-1_0].

jwks

JSON Web Key Set containing the cryptographic keys for the authorization server. See OID-FED Section 5.2.1 and JWK.

+
+
+

Metadata for openid_credential_issuer

+

The openid_credential_issuer metadata MUST contain the following claims.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

credential_issuer

The PID/(Q)EAA Provider identifier. It MUST be a case sensitive URL using HTTPS scheme as defined in OpenID4VCI Sections 11.2.1 and 11.2.3.

credential_endpoint

URL of the credential endpoint. See OpenID4VCI Section 11.2.3.

revocation_endpoint

URL of the revocation endpoint. See RFC 8414#section-2.

status_attestation_endpoint

It MUST be an HTTPs URL indicating the endpoint where the Wallet Instances can request Status Attestations. See Section Credential Lifecycle for more details.

notification_endpoint

It MUST be an HTTPs URL indicating the notification endpoint. See Section 11.2.3 of [OpenID4VCI].

authorization_servers

OPTIONAL. Array of strings, where each string is an identifier of the OAuth 2.0 Authorization Server (as defined in [RFC 8414]) the PID/(Q)EAA Provider relies on for authorization. If this parameter is omitted, the entity providing the PID/(Q)EAA Provider is also acting as the Authorization Server.

display

See OpenID4VCI Section 11.2.3. Array of objects containing display language properties. The parameters that MUST be included are:

+
+
    +
  • name: String value of a display name for the PID/(Q)EAA Provider.

  • +
  • locale: String value that identifies the language of this object represented as a language tag taken from values defined in BCP47 RFC 5646. There MUST be only one object for each language identifier.

  • +
+
+

credential_configurations_supported

JSON object that outlines the details of the Credential supported by the PID/(Q)EAA Provider. It includes a list of name/value pairs, where each name uniquely identifies a specific supported Credential. This identifier is utilized to inform the Wallet Instance which Credential can be provided by the PID/(Q)EAA Provider. The associated value within the object MUST contain metadata specific to that Credential, as defined following. See OpenID4VCI Sections 11.2.3 and A.3.2.

+
+
    +
  • format: String identifying the format of this Credential. The PID/(Q)EAA MUST support the value string "vc+sd-jwt". See OpenID4VCI Section A.3.1.

  • +
  • scope: JSON String identifying the supported scope value. The Wallet Instance MUST use this value in the Pushed Authorization Request. Scope values MUST be the entire set or a subset of the scope values in the scopes_supported parameter of the Authorization Server. [See OpenID4VCI Section 11.2.3].

  • +
  • cryptographic_binding_methods_supported: JSON Array of case sensitive strings that identify the representation of the cryptographic key material that the issued Credential is bound to. The PID/(Q)EAA Provider MUST support the value "jwk".

  • +
  • credential_signing_alg_values_supported: JSON Array of case sensitive strings that identify the algorithms that the PID/(Q)EAA Provider MUST support to sign the issued Credential. See Section Cryptographic Algorithms for more details.

  • +
  • proof_types_supported: JSON object which provide detailed information about the key proof(s) supported by the PID/(Q)EAA Provider. It consists of a list of name/value pairs, where each name uniquely identifies a supported proof type. The PID/(Q)EAA Provider MUST support at least "jwt" as defined in OpenID4VCI Section 7.2. The value associated with each name/value pair is a JSON object containing metadata related to the key proof. The PID/(Q)EAA Provider MUST support at least the parameter proof_signing_alg_values_supported which MUST be a JSON Array of case sensitive strings that identify the supported algorithms (see Section Cryptographic Algorithms for more details about the supported algorithms).

  • +
  • display: Array of objects containing display language properties. The parameters that MUST be included are:

    +
    +
      +
    • name: String value of a display name for the Credential.

    • +
    • locale: String value that identifies the language of this object represented as a language tag taken from values defined in BCP47 RFC 5646. There MUST be only one object for each language identifier.

    • +
    +
    +
  • +
  • vct: As defined in [SD-JWT-VC Credential Format].

  • +
  • claims: JSON object comprising a collection of name/value pairs, where each name represents a claim related to the subject described in the Credential. The value associated with each name MAY be either another nested object or an array of objects. To provide detailed information about the claim, the innermost value MUST contain at least the following parameters. See OpenID4VCI Section A.3.2.

    +
    +
      +
    • value_type: String value determining the type of value of the claim. The values that MUST be supported by the PID/(Q)EAA Provider are String and Boolean.

    • +
    • display: Array of objects containing display language properties. The parameters that MUST be included are:

      +
      +
        +
      • name: String value of a display name for the claim.

      • +
      • locale: String value that identifies the language of this object represented as a language tag taken from values defined in BCP47 RFC 5646. There MUST be only one object for each language identifier.

      • +
      +
      +
    • +
    +
    +
  • +
+
+

jwks

JSON Web Key Set document, passed by value, containing the protocol specific keys for the Credential Issuer. See OID-FED Section 5.2.1 and JWK.

+
+
+

Metadata for wallet_relying_party

+

The wallet_relying_party metadata MUST contain the parameters as defined in Section Metadata for wallet_relying_party.

+
+
+

Example of a (Q)EAA Provider Entity Configuration

+

Below is a non-normative example of an Entity Configuration of a (Q)EAA Provider containing a metadata for

+
+
    +
  • federation_entity

  • +
  • oauth_authorization_server

  • +
  • openid_credential_issuer

  • +
  • wallet_relying_party

  • +
+
+
{
+    "iat": 1718207217,
+    "exp": 1749743216,
+    "iss": "https://eaa-provider.example.org",
+    "sub": "https://eaa-provider.example.org",
+    "authority_hints": [
+        "https://trust-anchor.example.org"
+    ],
+    "jwks": {
+        "keys": [
+            {
+                "kid": "FANFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMEEs",
+                "kty": "EC",
+                "crv": "P-256",
+                "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
+                "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
+            }
+        ]
+    },
+    "metadata": {
+        "federation_entity": {
+            "homepage_uri": "https://eaa-provider.example.org/",
+            "organization_name": "Organization Name",
+            "contacts": [
+                "informazioni@example.it",
+                "protocollo@pec.example.it"
+            ],
+            "tos_uri": "https://eaa-provider.example.org/public/info_policy.html",
+            "policy_uri": "https://eaa-provider.example.org/public/privacy_policy.html",
+            "logo_uri": "https://eaa-provider.example.org/public/logo.svg"
+        },
+        "oauth_authorization_server": {
+            "issuer": "https://eaa-provider.example.org",
+            "pushed_authorization_request_endpoint": "https://eaa-provider.example.org/as/par",
+            "authorization_endpoint": "https://eaa-provider.example.org/authorize",
+            "token_endpoint": "https://eaa-provider.example.org/token",
+            "client_registration_types_supported": [
+                "automatic"
+            ],
+            "code_challenge_methods_supported": [
+                "S256"
+            ],
+            "acr_values_supported": [
+                "https://www.spid.gov.it/SpidL2",
+                "https://www.spid.gov.it/SpidL3"
+            ],
+            "scopes_supported": [
+                "EuropeanDisabilityCard",
+                "MDL"
+            ],
+            "response_modes_supported": [
+                "form_post.jwt",
+                "query"
+            ],
+            "authorization_signing_alg_values_supported": [
+                "ES256",
+                "ES384",
+                "ES512"
+            ],
+            "grant_types_supported": [
+                "authorization_code"
+            ],
+            "token_endpoint_auth_methods_supported": [
+                "attest_jwt_client_auth"
+            ],
+            "token_endpoint_auth_signing_alg_values_supported": [
+                "ES256",
+                "ES384",
+                "ES512"
+            ],
+            "request_object_signing_alg_values_supported": [
+                "ES256",
+                "ES384",
+                "ES512"
+            ],
+            "jwks": {
+                "keys": [
+                    {
+                        "kid": "f10aca0992694b3581f6f699bfc8a2c6cc687725",
+                        "kty": "EC",
+                        "crv": "P-256",
+                        "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
+                        "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
+                    }
+                ]
+            }
+        },
+        "openid_credential_issuer": {
+            "credential_issuer": "https://eaa-provider.example.org",
+            "credential_endpoint": "https://eaa-provider.example.org/credential",
+            "revocation_endpoint": "https://eaa-provider.example.org/revoke",
+            "status_attestation_endpoint": "https://eaa-provider.example.org/status",
+            "notification_endpoint": "https://eaa-provider.example.org/notification",
+            "display": [
+                {
+                    "name": "EAA Provider",
+                    "locale": "it-IT"
+                },
+                {
+                    "name": "EAA Provider",
+                    "locale": "en-US"
+                }
+            ],
+            "credential_configurations_supported": {
+                "EuropeanDisabilityCard": {
+                    "format": "vc+sd-jwt",
+                    "scope": "EuropeanDisabilityCard",
+                    "cryptographic_binding_methods_supported": [
+                        "jwk"
+                    ],
+                    "credential_signing_alg_values_supported": [
+                        "ES256",
+                        "ES384",
+                        "ES512"
+                    ],
+                    "proof_types_supported": {
+                        "jwt": {
+                            "proof_signing_alg_values_supported": [
+                                "ES256",
+                                "ES384",
+                                "ES512"
+                            ]
+                        }
+                    },
+                    "display": [
+                        {
+                            "name": "Carta della disabilità europea",
+                            "locale": "it-IT"
+                        },
+                        {
+                            "name": "European Disability Card",
+                            "locale": "en-US"
+                        }
+                    ],
+                    "vct": "EuropeanDisabilityCard",
+                    "claims": {
+                        "document_number": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Numero Documento",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Document Number",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "given_name": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Nome",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Name",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "family_name": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Cognome",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Family Name",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "birth_date": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Data di Nascita (YYYY-MM-GG)",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Date of Birth (YYYY-MM-GG)",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "tax_id_code": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Codice Fiscale",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Tax Id Number",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "expiry_date": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Data di Scadenza (YYYY-MM-GG)",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Expiration Date (YYYY-MM-GG)",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "constant_attendance_allowance": {
+                            "value_type": "boolean",
+                            "display": [
+                                {
+                                    "name": "Diritto accompagnatore",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Constant attendance allowance",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "portrait": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Foto codificata in base64",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Portrait base64 encoded",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "link_qr_code": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Link QR Code",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Link QR Code",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        }
+                    }
+                },
+                "MDL": {
+                    "format": "vc+sd-jwt",
+                    "scope": "MDL",
+                    "cryptographic_binding_methods_supported": [
+                        "jwk"
+                    ],
+                    "credential_signing_alg_values_supported": [
+                        "ES256",
+                        "ES384",
+                        "ES512"
+                    ],
+                    "proof_types_supported": {
+                        "jwt": {
+                            "proof_signing_alg_values_supported": [
+                                "ES256",
+                                "ES384",
+                                "ES512"
+                            ]
+                        }
+                    },
+                    "display": [
+                        {
+                            "name": "Patente di guida",
+                            "locale": "it-IT"
+                        },
+                        {
+                            "name": "Mobile Driver's License",
+                            "locale": "en-US"
+                        }
+                    ],
+                    "vct": "MDL",
+                    "claims": {
+                        "given_name": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Nome",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "First Name",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "family_name": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Cognome",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Family Name",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "birth_date": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Data di nascita (YYYY-MM-GG)",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Date of Birth (YYYY-MM-GG)",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "place_of_birth": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Luogo di Nascita",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Place of Birth",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "issue_date": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Data di rilascio (YYYY-MM-GG)",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Issue Date (YYYY-MM-GG)",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "expiry_date": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Data di scadenza (YYYY-MM-GG)",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Expiry Date (YYYY-MM-GG)",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "issuing_country": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Paese di rilascio",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Issuing Country",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "issuing_authority": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Autorità di rilascio",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Issuing Authority",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "document_number": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Numero di documento",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Document Number",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "portrait": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Foto codificata in base64",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Portrait base64 encoded",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "driving_privileges": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Elenco delle categorie di abilitazione separate da spazio",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Driving Privileges separated by space",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "restrictions_conditions": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Annotazioni/Restrizioni valide per tutte le categorie separate da spazio",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Restriction/Condition for all driving privileges separated by space ",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        },
+                        "driving_privileges_details": {
+                            "value_type": "string",
+                            "display": [
+                                {
+                                    "name": "Dettagli delle categorie di abilitazione",
+                                    "locale": "it-IT"
+                                },
+                                {
+                                    "name": "Driving privilege details",
+                                    "locale": "en-US"
+                                }
+                            ]
+                        }
+                    }
+                }
+            },
+            "jwks": {
+                "keys": [
+                    {
+                        "kid": "f10aca0992694b3581f6f699bfc8a2c6cc687725",
+                        "kty": "EC",
+                        "crv": "P-256",
+                        "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
+                        "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
+                    }
+                ]
+            }
+        },
+        "wallet_relying_party": {
+            "application_type": "web",
+            "client_id": "https://eaa-provider.example.org",
+            "client_name": "Organization Name",
+            "contacts": [
+                "informazioni@example.it",
+                "protocollo@pec.example.it"
+            ],
+            "request_uris": [
+                "https://eaa-provider.example.org/request_uri"
+            ],
+            "response_uris": [
+                "https://eaa-provider.example.org/response_uri"
+            ],
+            "default_acr_values": [
+                "https://www.spid.gov.it/SpidL2",
+                "https://www.spid.gov.it/SpidL3"
+            ],
+            "request_object_signing_alg_values_supported": [
+                "ES256",
+                "ES384",
+                "ES512"
+            ],
+            "authorization_signed_response_alg": [
+                "ES256",
+                "ES384",
+                "ES512"
+            ],
+            "authorization_encrypted_response_alg": [
+                "RSA-OAEP-256"
+            ],
+            "authorization_encrypted_response_enc": [
+                "A128CBC-HS256",
+                "A192CBC-HS384",
+                "A256CBC-HS512",
+                "A128GCM",
+                "A192GCM",
+                "A256GCM"
+            ],
+            "vp_formats": {
+                "vc+sd-jwt": {
+                    "sd-jwt_alg_values": [
+                        "ES256",
+                        "ES384",
+                        "ES512"
+                    ]
+                }
+            },
+            "presentation_definitions_supported": [
+                {
+                    "id": "d76c51b7-ea90-49bb-8368-6b3d194fc131",
+                    "input_descriptors": [
+                        {
+                            "id": "PersonIdentificationData",
+                            "format": {
+                                "vc+sd-jwt": {
+                                    "alg": [
+                                        "ES256",
+                                        "ES384",
+                                        "ES512"
+                                    ]
+                                },
+                                "constraints": {
+                                    "limit_disclosure": "required",
+                                    "fields": [
+                                        {
+                                            "filter": {
+                                                "const": "PersonIdentificationData",
+                                                "type": "string"
+                                            },
+                                            "path": [
+                                                "$.vct"
+                                            ]
+                                        },
+                                        {
+                                            "filter": {
+                                                "type": "object"
+                                            },
+                                            "path": [
+                                                "$.cnf.jwk"
+                                            ]
+                                        },
+                                        {
+                                            "path": [
+                                                "$.unique_id"
+                                            ]
+                                        },
+                                        {
+                                            "path": [
+                                                "$.tax_id_code"
+                                            ]
+                                        }
+                                    ]
+                                }
+                            }
+                        },      
+                        {
+                            "id": "WalletAttestation",
+                            "format": {
+                                "jwt": {
+                                    "alg": [
+                                        "ES256",
+                                        "ES384",
+                                        "ES512"
+                                    ]
+                                },
+                                "constraints": {
+                                    "limit_disclosure": "required",
+                                    "fields": [
+                                        {
+                                            "filter": {
+                                                "type": "string"
+                                            },
+                                            "path": [
+                                                "$.iss"
+                                            ]
+                                        },
+                                        {
+                                            "filter": {
+                                                "type": "object"
+                                            },
+                                            "path": [
+                                                "$.cnf.jwk"
+                                            ]
+                                        }
+                                    ]
+                                }
+                            }
+                        }
+                    ]
+                } 
+            ],
+            "jwks": {
+                "keys": [
+                    {
+                        "kid": "f10aca0992694b3581f6f699bfc8a2c6cc687725",
+                        "kty": "EC",
+                        "crv": "P-256",
+                        "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
+                        "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
+                    }
+                ]
+            }
+        }
+    }
+}
+
+
+
+
+ + +
+
+
+
+ + + + + + +
+
+
+ +
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/pid-eaa-issuance.html b/refs/pull/443/merge/en/pid-eaa-issuance.html new file mode 100644 index 000000000..143b83868 --- /dev/null +++ b/refs/pull/443/merge/en/pid-eaa-issuance.html @@ -0,0 +1,1529 @@ + + + + + + + + PID/(Q)EAA Issuance — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

PID/(Q)EAA Issuance

+

This section describes the PID and (Q)EAAs issuance flow with an high level of security. +The relevant entities and interfaces involved in the issuance flow are:

+
+
    +
  • Wallet Provider,

  • +
  • Wallet Solution,

  • +
  • Wallet Instance,

  • +
  • PID Provider,

  • +
  • National Identity Provider,

  • +
  • (Q)EAA Provider.

  • +
+
+

PID/(Q)EAA Providers are composed of:

+
+
    +
  • Credential Issuer Component: based on the "OpenID for Verifiable Credential Issuance" specification [OpenID4VCI] to release the PID/(Q)EAA.

  • +
  • Relying Party Component: The component to authenticate the User. PID Providers authenticate users with the national Digital Identity Providers, based on OpenID Connect Core 1.0 or SAML2 while (Q)EAA Providers authenticate users with the PID.

  • +
+
+

The (Q)EAA Provider acts as a Verifier by sending a presentation request to the Wallet Instance, according to [OpenID4VP]. The Wallet Instance MUST have a valid PID, obtained in a previous time, to get authenticated with the (Q)EAA Provider.

+
+

High-Level PID flow

+

The Fig. 2 shows a general architecture and highlights the main operations involved in the issuance of a PID.

+
+_images/High-Level-Flow-ITWallet-PID-Issuance.svg +
+

Fig. 2 PID Issuance - General architecture and high level flow.

+
+
+

Below the description of the steps represented in the previous picture:

+
+
    +
  1. Wallet Instance Setup: the first time the Wallet Instance is started a preliminary setup phase is carried out. It consists of the release of the Wallet Attestation issued by Wallet Attestation Service asserting the genuineness and the compliance of the Wallet Instance with the shared trust framework. The Wallet Attestation binds the public key provided by the Wallet Instance, related to one of the private keys generated by the Wallet Instance.

  2. +
  3. PID/(Q)EAA Provider Discovery: the Wallet Instance discovers the trusted Digital Credential Issuers using the Federation API (e.g.: using the Subordinate Listing Endpoint of the Trust Anchor and its Intermediates), inspecting the Credential Issuer metadata and Trust Marks for filtering the PID Provider.

  4. +
  5. PID Provider Metadata: the Wallet Instance establishes the trust to the PID Provider according to the Trust Model and obtains the Metadata that discloses the formats of the PID, the algorithms supported, and any other parameter required for interoperability needs.

  6. +
  7. PID Request: using the Authorization Code Flow defined in [OpenID4VCI] the Wallet Instance requests the PID to the PID Provider.

  8. +
  9. User Authentication: the PID Provider authenticates the User with LoA High, acting as an Identity and Access Management Proxy to the National eID system.

  10. +
  11. PID Issuance: the User is authenticated with LoA High and the PID Provider releases a PID bound to the key material held by the requesting Wallet Instance.

  12. +
+
+

In the following sections the steps from 1 to 5 are further expanded into more technical details.

+
+
+

High-Level (Q)EAA flow

+

The Fig. 3 shows a general architecture and highlights the main operations involved in the issuance of a (Q)EAA, following the assumptions listed below:

+
+
    +
  • the User has a valid PID stored in their own Wallet Instance;

  • +
  • the (Q)EAA requires a high security implementation profile.

  • +
+
+
+_images/High-Level-Flow-ITWallet-QEAA-Issuance.svg +
+

Fig. 3 (Q)EAA Issuance - General architecture and high level flow

+
+
+

Below the description of the most relevant operations involved in the (Q)EAA issuance:

+
+
    +
  1. Discovery of the trusted (Q)EAA Provider: the Wallet Instance obtains the list of the trusted (Q)EAA Provider using the Federation API (e.g.: using the Subordinate Listing Endpoint of the Trust Anchor and its Intermediates), then inspects the metadata and Trust Mark looking for the Digital Credential capabilities of each (Q)EAA Provider.

  2. +
  3. (Q)EAA Provider Metadata: the Wallet Instance establishes the trust to the (Q)EAA Provider according to the Trust Model, obtaining the Metadata that discloses the formats of the (Q)EAA, the algorithms supported, and any other parameter required for interoperability needs.

  4. +
  5. (Q)EAA Request: using the Authorization Code Flow , defined in [OpenID4VCI], the Wallet Instance requests a (Q)EAA to the (Q)EAA Provider.

  6. +
  7. User Authentication: the (Q)EAA Provider, acting as a Verifier (Relying Party), authenticates the User evaluating the presentation of the PID.

  8. +
  9. (Q)EAA Issuance: the User is authenticated with a valid PID and the (Q)EAA Provider releases a (Q)EAA bound to the key material held by the requesting Wallet Instance.

  10. +
+
+
+
+

Low-Level Issuance Flow

+

The PID/(Q)EAA Issuance flow is based on [OpenID4VCI] and the following main reference standards/specifications MUST be supported on top of OpenID4VCI:

+
+
+
+

The PID/(Q)EAA Provider MUST use OAuth 2.0 Authorization Server based on RFC 6749 to authorize the User to obtain a Credential. PID/(Q)EAA Providers MUST support

+
+
    +
  • Authorization Code Flow: The PID/(Q)EAA Provider requires User authentication and consent at the Authorization Endpoint before collecting User information to create and provide a Credential.

  • +
  • Wallet Initiated Flow: The request from the Wallet Instance is sent to the PID/(Q)EAA Provider without any input from the latter.

  • +
  • Same-device Issuance flow: The User receives the Credential on the same device that initiated the flow.

  • +
  • Immediate Issuance flow: The PID/(Q)EAA Provider issues the Credential directly in response to the Credential Request.

  • +
  • Deferred Issuance flow: The PID/(Q)EAA Provider may require time to issue the requested Digital Credential, due to the Authentic Sources data provisioning rules, and allows the Wallet to retrieve the requested Credential in the future.

  • +
+
+
+_images/Low-Level-Flow-ITWallet-PID-QEAA-Issuance.svg +
+

Fig. 4 PID/(Q)EAA Issuance - Detailed flow

+
+
+

Steps 1-4 (Discovery): The User, using the Wallet Instance, selects the PID/(Q)EAA Provider from those listed in the list of trustworthy entities. The Wallet Instance then processes the Metadata for the selected PID/(Q)EAA Provider as defined in the Trust Model section of this specification.

+
+

Note

+

Federation Check: The Wallet Instance must verify whether the PID/(Q)EAA Provider is a member of the Federation, obtaining its protocol specific Metadata. A non-normative example of a response from the endpoint .well-known/openid-federation with the Entity Configuration and the Metadata of the PID/(Q)EAA Provider is represented within the section Entity Configuration of PID/(Q)EAA Providers.

+
+

Steps 5-6 (PAR Request): The Wallet Instance:

+
+
    +
  • creates a fresh PKCE code verifier, Wallet Attestation Proof of Possession, and state parameter for the Pushed Authorization Request.

  • +
  • provides to the PID/(Q)EAA Provider PAR endpoint the parameters previously listed above, using the request parameter (hereafter Request Object) according to RFC 9126 Section 3 to prevent Request URI swapping attack.

  • +
  • MUST create the code_verifier with enough entropy random string using the unreserved characters with a minimum length of 43 characters and a maximum length of 128 characters, making it impractical for an attacker to guess its value. The value MUST be generated following the recommendation in Section 4.1 of RFC 7636.

  • +
  • signs this request using the private key that is created during the setup phase to obtain the Wallet Attestation. The related public key that is attested by the Wallet Provider is provided within the Wallet Attestation cnf claim.

  • +
  • MUST use the OAuth-Client-Attestation and OAuth-Client-Attestation-PoP parameters according to OAuth 2.0 Attestation-based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH], since in this flow the Pushed Authorization Endpoint is a protected endpoint.

  • +
  • specifies the types of the requested credentials using the authorization_details [RAR RFC 9396] parameter and or scope parameter.

  • +
+
+

The PID/(Q)EAA Provider performs the following checks upon the receipt of the PAR request:

+
+
    +
  1. It MUST validate the signature of the Request Object using the algorithm specified in the alg header parameter (RFC 9126, RFC 9101) and the public key retrieved from the Wallet Attestation (cnf.jwk) referenced in the Request Object, using the kid JWS header parameter.

  2. +
  3. It MUST check that the used algorithm for signing the request in the alg header is one of the listed within the Section Cryptographic Algorithms.

  4. +
  5. It MUST check that the client_id in the request body of the PAR request matches the client_id claim included in the Request Object.

  6. +
  7. It MUST check that the iss claim in the Request Object matches the client_id claim in the Request Object (RFC 9126, RFC 9101).

  8. +
  9. It MUST check that the aud claim in the Request Object is equal to the identifier of the PID/(Q)EAA Provider (RFC 9126, RFC 9101).

  10. +
  11. It MUST reject the PAR request, if it contains the request_uri parameter (RFC 9126).

  12. +
  13. It MUST check that the Request Object contains all the mandatory parameters which values are validated according to Table of the HTTP parameters [derived from RFC 9126].

  14. +
  15. It MUST check that the Request Object is not expired, checking the exp claim.

  16. +
  17. It MUST check that the Request Object was issued in a previous time than the value exposed in the iat claim. It SHOULD reject the request if the iat claim is far from the current time (RFC 9126) of more than 5 minutes.

  18. +
  19. It MUST check that the jti claim in the Request Object has not been used before by the Wallet Instance identified by the client_id. This allows the PID/(Q)EAA Provider to mitigate replay attacks (RFC 7519).

  20. +
  21. It MUST validate the OAuth-Client-Attestation-PoP parameter based on Section 4 of [OAUTH-ATTESTATION-CLIENT-AUTH].

  22. +
+
+

Below a non-normative example of the PAR.

+
POST /as/par HTTP/1.1
+Host: eaa-provider.example.org
+Content-Type: application/x-www-form-urlencoded
+OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IkVVRzBFdlRWaUk1RU5aQXdVQ0lVTWdQQVk4X1VISW5fMkhIWlMxN3RfQzAifQ.eyJpc3MiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCAiYXVkIjogImh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCAibmJmIjogMTMwMDgxNTc4MCwgImV4cCI6IDEzMDA4MTkzODB9._v3bjJelKI0TNpbc4ysS7yJupwSZzMPQ0ZQ9N5zj8XGQ_T3NN9bghUyVzegR60xokqBnqmMS4iYgPOL7ekEspw
+OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiIgaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImp0aSI6IjVlZmY5YzFiLWVkMGQtNDdlOC1hNTUzLWY3NGRmMWJiZWVkZCIsImlhdCI6MTcyMjI0OTQ0NywiZXhwIjoxNzIyMjQ5NzQ3fQ.aZpx7u7R-W8q7fJh9BEaRf8LM7RQRxAVc-okalAVqxHWqUMh3ehYukMLaCsiDQ33pyS41Y5PEsZ3HXwAXQ3nMg
+
+&client_id=$thumprint-of-the-jwk-in-the-cnf-wallet-attestation$
+&request=$SIGNED-JWT
+
+
+

Below an non-normative example of the Wallet Attestation Proof of Possession (WIA-PoP) header and body:

+
{
+    "typ": "jwt-client-attestation-pop",
+    "alg": "ES256",
+    "kid": "47b982369791d08003a7283f059cb0d1"
+}
+
+
+
{
+    "iss": "47b982369791d08003a7283f059cb0d1",
+    "aud": "https://eaa-provider.example.org",
+    "iat": 1715842560,
+    "exp": 1778914560,
+    "jti": "f8555ceb-c65c-4025-9378-b6672b6149af"
+}
+
+
+

Below an non-normative example of the signed Request Object without encoding and signature applied:

+
{
+    "typ": "jwt",
+    "alg": "ES256",
+    "kid": "b01b8208d9e6cc834d87dc356ab50170"
+}
+
+
+
{
+    "jti": "f8555ceb-c65c-4025-9378-b6672b6149af",
+    "aud": "https://eaa-provider.example.org",
+    "iat": 1715842560,
+    "exp": 1715842860,
+    "response_type": "code",
+    "response_mode": "form_post.jwt",
+    "client_id": "47b982369791d08003a7283f059cb0d1",
+    "iss": "47b982369791d08003a7283f059cb0d1",
+    "state": "fyZiOL9Lf2CeKuNT2JzxiLRDink0uPcd",
+    "code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
+    "code_challenge_method": "S256",
+    "scope": "EuropeanDisabilityCard",
+    "authorization_details": [
+      {
+        "type": "openid_credential",
+        "credential_configuration_id": "EuropeanDisabilityCard"
+      }
+    ],
+    "redirect_uri": "https://client.example.com/cb"
+}
+
+
+
+

Note

+

Federation Check: The PID/(Q)EAA Provider MUST check that the Wallet Provider is part of the federation.

+
+
+

Note

+

The PID/(Q)EAA Provider MUST validate the signature of the the Wallet Attestation and that it is not expired.

+
+

Step 7 (PAR Response): The PID/(Q)EAA Provider provides a one-time use request_uri value. The issued request_uri value must be bound to the client identifier (client_id) that was provided in the Request Object.

+
+

Note

+

The entropy of the request_uri MUST be sufficiently large. The adequate shortness of the validity and the entropy of the request_uri depends on the risk calculation based on the value of the resource being protected. The validity time SHOULD be less than a minute, and the request_uri MUST include a cryptographic random value of 128 bits or more (RFC 9101). The entire request_uri SHOULD NOT exceed 512 ASCII characters due to the following two main reasons (RFC 9101):

+
+
    +
  1. Many phones on the market still do not accept large payloads. The restriction is typically either 512 or 1024 ASCII characters.

  2. +
  3. On a slow connection such as a 2G mobile connection, a large URL would cause a slow response; therefore, the use of such is not advisable from the user-experience point of view.

  4. +
+
+
+

The PID/(Q)EAA Provider returns the issued request_uri to the Wallet Instance. A non-normative example of the response is shown below.

+
HTTP/1.1 201 Created
+Cache-Control: no-cache, no-store
+Content-Type: application/json
+
+
+
{
+    "request_uri": "urn:ietf:params:oauth:request_uri:bwc4JK-ESC0w8acc191e-Y1LTC2",
+    "expires_in": 60
+}
+
+
+

Steps 8-9 (Authorization Request): The Wallet Instance sends an authorization request to the PID/(Q)EAA Provider Authorization Endpoint. Since parts of this Authorization Request content, e.g., the code_challenge parameter value, are unique to a particular Authorization Request, the Wallet Instance MUST only use a request_uri value once (RFC 9126); The PID/(Q)EAA Provider performs the following checks upon the receipt of the Authorization Request:

+
+
    +
  1. It MUST treat request_uri values as one-time use and MUST reject an expired request. However, it MAY allow for duplicate requests due to a user reloading/refreshing their user-agent (derived from RFC 9126).

  2. +
  3. It MUST identify the request as a result of the submitted PAR (derived from RFC 9126).

  4. +
  5. It MUST reject all the Authorization Requests that do not contain the request_uri parameter as the PAR is the only way to pass the Authorization Request from the Wallet Instance (derived from RFC 9126).

  6. +
+
+
GET /authorize?client_id=$thumprint-of-the-jwk-in-the-cnf-wallet-attestation$&request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3Abwc4JK-ESC0w8acc191e-Y1LTC2 HTTP/1.1
+Host: eaa-provider.example.org
+
+
+
+

Note

+

User Authentication and Consent: The PID Provider performs the User authentication based on the requirements of eIDAS LoA High by means of national notified eIDAS scheme and requires the User consent for the PID issuance. +The (Q)EAA Provider performs the User authentication requesting a valid PID to the Wallet Instance. The (Q)EAA Provider MUST use [OpenID4VP] to dynamically request the presentation of the PID. From a protocol perspective, the (Q)EAA Provider acts as a Relying Party, providing the presentation request to the Wallet Instance. The Wallet Instance MUST have a valid PID obtained prior to start the transaction with the (Q)EAA Provider.

+
+

Steps 10-11 (Authorization Response): The PID/(Q)EAA Provider sends an authorization code together with state and iss parameters to the Wallet Instance. The Wallet Instance performs the following checks on the Authorization Response:

+
+
    +
  1. It MUST check the Authorization Response contains all the defined parameters according to Table of the HTTP Response parameters.

  2. +
  3. It MUST check the returned value by the PID/(Q)EAA Provider for state parameter is equal to the value sent by Wallet Instance in the Request Object (RFC 6749).

  4. +
  5. It MUST check that the URL of PID/(Q)EAA Provider in iss parameter is equal to the URL identifier of intended PID/(Q)EAA Provider that the Wallet Instance start the communication with (RFC 9027).

  6. +
+
+
+

Note

+

The Wallet Instance redirect URI is a universal or app link registered with the local operating system, so this latter will resolve it and pass the response to the Wallet Instance.

+
+
HTTP/1.1 302 Found
+Location: https://start.wallet.example.org?code=SplxlOBeZQQYbYS6WxSbIA&state=fyZiOL9Lf2CeKuNT2JzxiLRDink0uPcd&iss=https%3A%2F%2Feaa-provider.example.org
+
+
+

Steps 12-13 (DPoP Proof for Token Endpoint): The Wallet Instance MUST create a new key pair for the DPoP and a fresh DPoP Proof JWT following the instruction provided in the Section 4 of (RFC 9449) for the token request to the PID/(Q)EAA Provider. The DPoP Proof JWT is signed using the private key for DPoP created by Wallet Instance for this scope. DPoP binds the Access Token to a certain Wallet Instance (RFC 9449) and mitigates the misuse of leaked or stolen Access Tokens at the Credential Endpoint.

+

Step 14 (Token Request): The Wallet Instance sends a token request to the PID/(Q)EAA Provider Token Endpoint with a DPoP Proof JWT and the parameters: code, code_verifier, and OAuth 2.0 Attestation based Client Authentication (OAuth-Client-Attestation and OAuth-Client-Attestation-PoP). +The OAuth-Client-Attestation is signed using the private key that is created during the setup phase to obtain the Wallet Attestation. The related public key that is attested by the Wallet Provider is provided within the Wallet Attestation (cnf claim). The PID/(Q)EAA Provider performs the following checks on the Token Request:

+
+
    +
  1. It MUST ensure that the Authorization code is issued to the authenticated Wallet Instance (RFC 6749) and was not replied.

  2. +
  3. It MUST ensure the Authorization code is valid and has not been previously used (RFC 6749).

  4. +
  5. It MUST ensure the redirect_uri matches the value included in the previous Request Object (see Section 3.1.3.1. of [OIDC]).

  6. +
  7. It MUST validate the DPoP Proof JWT, according to (RFC 9449) Section 4.3.

  8. +
+
+
POST /token HTTP/1.1
+Host: eaa-provider.example.org
+Content-Type: application/x-www-form-urlencoded
+DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
+OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IkVVRzBFdlRWaUk1RU5aQXdVQ0lVTWdQQVk4X1VISW5fMkhIWlMxN3RfQzAifQ.eyJpc3MiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCAiYXVkIjogImh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCAibmJmIjogMTMwMDgxNTc4MCwgImV4cCI6IDEzMDA4MTkzODB9._v3bjJelKI0TNpbc4ysS7yJupwSZzMPQ0ZQ9N5zj8XGQ_T3NN9bghUyVzegR60xokqBnqmMS4iYgPOL7ekEspw
+OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiIgaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImp0aSI6IjVlZmY5YzFiLWVkMGQtNDdlOC1hNTUzLWY3NGRmMWJiZWVkZCIsImlhdCI6MTcyMjI0OTQ0NywiZXhwIjoxNzIyMjQ5NzQ3fQ.aZpx7u7R-W8q7fJh9BEaRf8LM7RQRxAVc-okalAVqxHWqUMh3ehYukMLaCsiDQ33pyS41Y5PEsZ3HXwAXQ3nMg
+
+grant_type=authorization_code
+&code=SplxlOBeZQQYbYS6WxSbIA
+&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
+&redirect_uri=https://start.wallet.example.org/cb
+
+
+

Step 15 (Token Response): The PID/(Q)EAA Provider validates the request, if successful an Access Token (bound to the DPoP key) and a fresh c_nonce are provided by the Issuer to the Wallet Instance. The parameter c_nonce is a string value, which MUST be unpredictable and is used later by the Wallet Instance in Step 18 to create the proof of possession of the key (proof claim) and it is the primary countermeasure against key proof replay attack. Note that, the received c_nonce value can be used to create the proof as long as the Issuer provides the Wallet Instance with a new c_nonce value.

+
HTTP/1.1 200 OK
+Content-Type: application/json
+Cache-Control: no-store
+
+
+
{
+    "access_token": "eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJpc3MiOiJodHRwczovL2VhYS1wcm92aWRlci53YWxsZXQuaXB6cy5pdCIsInN1YiI6ImQ0ZTBiYjM4N2FhMjU1NmZmMzA2OTI1ZmRmYjlhNzY1IiwiYXVkIjoiaHR0cHM6Ly9lYWEtcHJvdmlkZXIud2FsbGV0LmlwenMuaXQvY3JlZGVudGlhbCIsImlhdCI6MTcxNTg0MjU2MCwiZXhwIjoxNzc4OTE0NTYwLCJqdGkiOiJmOTY1NWNlYi1jNjVjLTQwMjUtOTM3OC1iNjY3MmI2MTQ5YmciLCJjbGllbnRfaWQiOiI0N2I5ODIzNjk3OTFkMDgwMDNhNzI4M2YwNTljYjBkMSIsImNuZiI6eyJqa3QiOiI5NTE1NzRhZWUxYmI3OTA3YWUxZWMzMTA5ZGIyYjIyNSJ9fQ.3ZfQN6KuNtJHjbGiYxHYqXIe0WrFIqYXNUio2a0bFy4eWystd7ZNCcmfoRojmmHQwccjNADqBKG7beYwbQ4jPg",
+    "token_type": "DPoP",
+    "expires_in": 3600,
+    "c_nonce": "ts_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-4FZKwHilkY",
+    "c_nonce_expires_in": 86400,
+    "authorization_details": [
+      {
+        "type": "openid_credential",
+        "credential_configuration_id": "DisabilityCard"
+      }
+    ]
+}
+
+
+

The non-normative example of the DPoP Access Token is given below.

+
{
+    "typ": "at+jwt",
+    "alg": "ES256",
+    "kid": "c950c0e6fdeb5de50a50096b247af03c"
+}
+
+
+
{
+    "iss": "https://eaa-provider.example.org",
+    "sub": "d4e0bb387aa2556ff306925fdfb9a765",
+    "aud": "https://eaa-provider.example.org",
+    "iat": 1715842560,
+    "exp": 1778914560,
+    "jti": "f9655ceb-c65c-4025-9378-b6672b6149bg",
+    "client_id": "47b982369791d08003a7283f059cb0d1",
+    "cnf": {
+      "jkt": "951574aee1bb7907ae1ec3109db2b225"
+    }
+}
+
+
+

Steps 16-17 (DPoP Proof for Credential Endpoint): The Wallet Instance for requesting the Digital Credential creates a proof of possession with c_nonce obtained in Step 15 and using the private key used for the DPoP, signing a DPoP Proof JWT according to (RFC 9449) Section 4. The jwk value in the proof parameter MUST be equal to the public key referenced in the DPoP.

+

Step 18 (Credential Request): The Wallet Instance sends a request for the Digital Credential to the PID/(Q)EAA Credential endpoint. This request MUST include the Access Token, DPoP Proof JWT, credential type, proof (which demonstrates possession of the key), and format parameters. The proof parameter MUST be an object that contains evidence of possession of the cryptographic key material to which the issued PID/(Q)EAA Digital Credential will be bound. To verify the proof, the PID/(Q)EAA Provider conducts the following checks at the Credential endpoint:

+
+
    +
  1. the JWT proof MUST include all required claims as specified in the table of Section Token Request;

  2. +
  3. The key proof MUST be explicitly typed using header parameters as defined for the respective proof type;

  4. +
  5. The header parameter alg MUST indicate a registered asymmetric digital signature algorithm, and MUST NOT be set to none;

  6. +
  7. The signature on the key proof MUST be verified using the public key specified in the header parameter.

  8. +
  9. The header parameter MUST NOT contain a private key.

  10. +
  11. If a c_nonce value was previously provided by the server, the nonce claim in the JWT MUST match this c_nonce value. Furthermore, the creation time of the JWT, as indicated by the iat claim or a server-managed timestamp via the nonce claim, MUST be within an acceptable window of time as determined by the server.

  12. +
+
+
+

Note

+

PID/(Q)EAA Credential Schema and Status registration: The PID/(Q)EAA Provider MUST register all the issued Credentials for their later revocation, if needed.

+
+
+

Note

+

It is RECOMMENDED that the public key contained in the jwt_proof be specifically generated for the requested Credential (fresh cryptographic key) to ensure that different issued Credentials do not share the same public key, thereby remaining unlinkable to each other.

+
+

A non-normative example of the Credential Request is provided below.

+
POST /credential HTTP/1.1
+  Host: eaa-provider.example.org
+Content-Type: application/json
+Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
+DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
+    VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR
+    nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R
+    1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj
+    oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z
+    WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF
+    c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E
+    OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA
+
+
+
{
+    "format": "vc+sd-jwt",
+    "vct": "EuropeanDisabilityCard",
+    "proof": {
+      "proof_type": "jwt",
+      "jwt": "eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoicFZVM2phdHU0YTN0azljOWFvd1ZnTHlCQl9ySjdNLTNXbGprMWVqVXoyRSIsInkiOiJUTDVPTnZSLUlnYXJuZ3J6NWpkdnNwb2ZmekZ3Y2pQUnRGVWtlbmVIRUkwIn19.eyJpc3MiOiI0N2I5ODIzNjk3OTFkMDgwMDNhNzI4M2YwNTljYjBkMSIsImF1ZCI6Imh0dHBzOi8vZWFhLXByb3ZpZGVyLndhbGxldC5pcHpzLml0L2NyZWRlbnRpYWwiLCJpYXQiOjE3MDU1NzAwNTUsImV4cCI6MTc3ODkxNDU2MCwibm9uY2UiOiJ0c19FdFVRczBpZWlJUzFOWU5CSEVRU295M2N0NGdweS00RlpLd0hpbGtZIn0.ILIEIk_mBJp8BHyngsPHIUyM3WGaOkt9hsdref3Qek4kYAtAfRRER6DgTeRURNAWKBem8m1mILYhBTNFfZcJjg"
+    }
+}
+
+
+

Where a non-normative example of the decoded content of the jwt parameter is represented below, +without encoding and signature. The JWS header:

+
{
+    "typ": "openid4vci-proof+jwt",
+    "alg": "ES256",
+    "jwk": {
+      "kty": "EC",
+      "crv": "P-256",
+      "x": "pVU3jatu4a3tk9c9aowVgLyBB_rJ7M-3Wljk1ejUz2E",
+      "y": "TL5ONvR-Igarngrz5jdvspoffzFwcjPRtFUkeneHEI0"
+    }
+}
+
+
+
{
+    "iss": "47b982369791d08003a7283f059cb0d1",
+    "aud": "https://eaa-provider.example.org",
+    "iat": 1705570055,
+    "nonce": "ts_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-4FZKwHilkY"
+}
+
+
+

Steps 19-21 (Credential Response): The PID/(Q)EAA Provider MUST validate the DPoP JWT Proof based on the steps defined in Section 4.3 of (RFC 9449) and whether the Access Token is valid and suitable for the requested PID/(Q)EAA. It also MUST validate the proof of possession for the key material the new credential SHALL be bound to, according to OpenID4VCI Section 7.2.2. If all checks succeed, the PID/(Q)EAA Provider creates a new Credential bound to the key material and provide it to the Wallet Instance. The Wallet Instance MUST perform the following checks before proceeding with the secure storage of the PID/(Q)EAA:

+
+
    +
  1. It MUST check that the PID Credential Response contains all the mandatory parameters and values are validated according to Table of the credential response parameters.

  2. +
  3. It MUST check the PID integrity by verifying the signature using the algorithm specified in the alg header parameter of SD-JWT (PID/(Q)EAA Data Model) and the public key that is identified using using the kid header of the SD-JWT.

  4. +
  5. It MUST check that the received PID (in credential claim) matches the schema defined in PID/(Q)EAA Data Model.

  6. +
  7. It MUST process and verify the PID in SD-JWT VC format (according to SD-JWT Section 6.) or MDOC CBOR format.

  8. +
  9. It MUST verify the Trust Chain in the header of SD-JWT VC to verify that the PID Provider is trusted.

  10. +
+
+

If the checks defined above are successful the Wallet Instance proceeds with the secure storage of the PID/(Q)EAA.

+
HTTP/1.1 200 OK
+Content-Type: application/json
+Cache-Control: no-store
+Pragma: no-cache
+
+
+
{
+    "credential": "eyJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJfc2QiOlsiQ1JJQkdpbWhhbE1TSzhLZUxmNzg2N0w4cHV6MEZnRTVaS1VXLW12N0hiYyIsIlhhZjVJZFVGc0UzYWtabEszT0E5d3dHcjJKcVAwUU01M3BBY2hiempRZmMiLCJjR2FuQVdySG9WQVoyalBhNXk0SzE3U0xpYWFKcGRNUF9PdnBmTGx0VWJjIiwiNEFuZU1ZVVAxRWh3emRHdkRQOEhobnRaRGN1ejZrOHhHWVJ0NXo0SHh0SSIsIjRuYTVXSHRMYzdrYnNxdHFVaHd6WXdVdUQtY3hKVmdENmRaLTl0ZUdhZ3MiLCJiZS10a2U3YVU0WmhDNWUxcGZqRjcxUWpFRzRsZG1IaFRoUFl1TnQyOHo0IiwiSnNkaHhTMWRVTTJaN29MUmZYWVJvOFFEaDJ4M1dQNkdILUJnY21DdzJGayIsIlVobXBRSy1HS3hzaHJwXzZwYVpfZzROVG5fX29aeVdOb01zTGNaMUhlMjgiLCJOdDdQU3RxMkEyWkliUHBHdTJpdmVSek9rbWpYUEN1V0RBdy0tdktSQTBjIiwiV3Rtck5JVzFTVkN0UnZNUF9UM2YtRGlhRUdHNS1iVk5rWGJRckowRnpzRSJdLCJleHAiOjE3NDY1MTU5NzIsImlzcyI6Imh0dHBzOi8vZWFhLXByb3ZpZGVyLmlwenMuaXQiLCJzdWIiOiJOemJMc1hoOHVEQ2NkN25vV1hGWkFmSGt4WnNSR0M5WHMiLCJzdGF0dXMiOnsic3RhdHVzX2F0dGVzdGF0aW9uIjp7ImNyZWRlbnRpYWxfaGFzaF9hbGciOiJzaGEtMjU2In19LCJ2Y3QiOiJEaXNhYmlsaXR5Q2FyZCIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6InBWVTNqYXR1NGEzdGs5Yzlhb3dWZ0x5QkJfcko3TS0zV2xqazFlalV6MkUiLCJ5IjoiVEw1T052Ui1JZ2FybmdyejVqZHZzcG9mZnpGd2NqUFJ0RlVrZW5lSEVJMCJ9fX0.v9ynFXhKXPOhQSMmuLvIBKRWfPEPDf4QwDoNmDOjMROxr5J4Hshh9mBEM5qohH_PDE62i1TLc36C65jFYa7x3A~WyIwQUx5SzRfUi1aVUpTekVKdW5HTFdRIiwiaWF0IiwiMTc0NzExOTU5NSJd~WyItT25uM29FcGh6TDNncHJUcVF0YUd3IiwiZG9jdW1lbnRfbnVtYmVyIiwiMDAwMDAwMDIiXQ~WyJ2bmtVX2tJV2RSa1dPZzBoNlRYcDd3IiwiZ2l2ZW5fbmFtZSIsIk1hcmlvIl~WyJvRUdnaVZQaXV1dEJVby1wcTd6WURBIiwiZmFtaWx5X25hbWUiLCJSb3NzaSJd~WyJGVU1iQm5hLWhlLUlaWTZkOVZ1UkNBIiwiYmlydGhfZGF0ZSIsIjE5ODAtMDEtMTAiXQ~WyJjQ0ZDeXljV1J4alZINkZURVR5OTd3IiwidGF4X2lkX2NvZGUiLCJSU1NNUkE4MFIwMUg1MDFCIl0~WyJVSEFhaWZ1bzloTW9pbkVDU0loOG9RIiwiZXhwaXJ5X2RhdGUiLCIyMDMwLTAxLTEwIl~WyJ3TW1xYkkzTFRPMDVLajFoLXNpWWhRIiwiY29uc3RhbnRfYXR0ZW5kYW5jZV9hbGxvd2FuY2UiLCIwIl0~WyJBODVjeFI1REZyOElfaFZFQTZqZGNBIiwibGlua19xcl9jb2RlIiwiaHR0cHM6Ly9xci5leGFtcGxlLmNvbSJd~WyJHWHRYNXNueTctVEVpblhZajNMdGdBIiwicG9ydHJhaXQiLCIvOWovNEFBUVNrWkpSZ0FCQVFFQkxBRXNBQUQvNFFCV1JYaHBaZ0FBVFUwQUtnQUFBQWdBQkFFYUFBVUFBQUFCQUFBQVBnRWJBQVVBQUFBQkFBQUFSZ0VvQUFNQUFBQUJBQUlBQUFJVEFBTUFBQUFCQUFFQUFBQUFBQUFBQUFFc0FBQUFBUUFBQVN3QUFBQUIvKzBBTEZCb2IzUnZjMmh2Y0NBekxqQUFPRUpKVFFRRUFBQUFBQUFQSEFGYUFBTWJKVWNjQVFBQUFnQUVBUC9oRElGb2RIUndPaTh2Ym5NdVlXUnZZbVV1WTI5dEwzaGhjQzh4TGpBdkFEdy9lSEJoWTJ0bGRDQmlaV2RwYmowbjc3dS9KeUJwWkQwblZ6Vk5NRTF3UTJWb2FVaDZjbVZUZWs1VVkzcHJZemxrSno4K0NqeDRPbmh0Y0cxbGRHRWdlRzFzYm5NNmVEMG5ZV1J2WW1VNmJuTTZiV1YwWVM4bklIZzZlRzF3ZEdzOUowbHRZV2RsT2pwRmVHbG1WRzl2YkNBeE1DNHhNQ2MrQ2p4eVpHWTZVa1JHSUhodGJHNXpPbkprWmowbmFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1UazVPUzh3TWk4eU1pMXlaR1l0YzNsdWRHRjRMVzV6SXljK0Nnb2dQSEprWmpwRVpYTmpjbWx3ZEdsdmJpQnlaR1k2WVdKdmRYUTlKeWNLSUNCNGJXeHVjenAwYVdabVBTZG9kSFJ3T2k4dmJuTXVZV1J2WW1VdVkyOXRMM1JwWm1Zdk1TNHdMeWMrQ2lBZ1BIUnBabVk2VW1WemIyeDFkR2x2YmxWdWFYUStNand2ZEdsbVpqcFNaWE52YkhWMGFXOXVWVzVwZEQ0S0lDQThkR2xtWmpwWVVtVnpiMngxZEdsdmJqNHpNREF2TVR3dmRHbG1aanBZVW1WemIyeDFkR2x2Ymo0S0lDQThkR2xtWmpwWlVtVnpiMngxZEdsdmJqNHpNREF2TVR3dmRHbG1aanBaVW1WemIyeDFkR2x2Ymo0S0lEd3ZjbVJtT2tSbGMyTnlhWEIwYVc5dVBnb0tJRHh5WkdZNlJHVnpZM0pwY0hScGIyNGdjbVJtT21GaWIzVjBQU2NuQ2lBZ2VHMXNibk02ZUcxd1RVMDlKMmgwZEhBNkx5OXVjeTVoWkc5aVpTNWpiMjB2ZUdGd0x6RXVNQzl0YlM4blBnb2dJRHg0YlhCTlRUcEViMk4xYldWdWRFbEVQbUZrYjJKbE9tUnZZMmxrT25OMGIyTnJPamxqTmpabVpUZGxMVFkzWTJRdE5ETTRZeTA1WlRobUxUSXdPREE1TkRObU9UWTJaVHd2ZUcxd1RVMDZSRzlqZFcxbGJuUkpSRDRLSUNBOGVHMXdUVTA2U1c1emRHRnVZMlZKUkQ1NGJYQXVhV2xrT2pSaE16ZzBZVFUxTFdJek1UZ3ROR05rWVMwNE4yVXpMVE14TVRZd00yTmhaVEUzT0R3dmVHMXdUVTA2U1c1emRHRnVZMlZKUkQ0S0lEd3ZjbVJtT2tSbGMyTnlhWEIwYVc5dVBnbzhMM0prWmpwU1JFWStDand2ZURwNGJYQnRaWFJoUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBbzhQM2h3WVdOclpYUWdaVzVrUFNkM0p6OCsvOXNBUXdBRkF3UUVCQU1GQkFRRUJRVUZCZ2NNQ0FjSEJ3Y1BDd3NKREJFUEVoSVJEeEVSRXhZY0Z4TVVHaFVSRVJnaEdCb2RIUjhmSHhNWElpUWlIaVFjSGg4ZS85c0FRd0VGQlFVSEJnY09DQWdPSGhRUkZCNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlLzhBQUVRZ0JhQUZvQXdFUkFBSVJBUU1SQWYvRUFCMEFBUUFCQlFFQkFRQUFBQUFBQUFBQUFBQUdBUVVIQ0FrRUFnUC94QUJDRUFFQUFRTUNBZ01OQlFVSEJRQUFBQUFBQVFJREJBVUdCeEVoTVZFSUVoTVVGeUpCVm1GeG9hVFNRb0dSa3NFak1rT0NvaFVXWW5LRHNzSVlObEoxcy8vRUFCWUJBUUVCQUFBQUFBQUFBQUFBQUFBQUFBQUJBdi9FQUJZUkFRRUJBQUFBQUFBQUFBQUFBQUFBQUFBUkFmL2FBQXdEQVFBQ0VRTVJBRDhBM0xBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCNXRTejhMVE1HN25hamwyTVRGczA5OWN2WHJrVVVVUjJ6TTlFQXdudmZ1bHRwNlZjcnh0dDRPVHIxNm5uSGh1ZmdNZm43S3FvbXFyN3FlWHRJTVY2MTNTWEVQTnVUT0JScEdsMGVpTFdOTjJxUHZybVkrQ3dXWHk5Y1ZlLzc3KzgxUHU4UXNjdjloQmV0RjdwTGlIaFhJblBvMGpWS1BURjNHbTFWUDMwVEVmQWd5cHNqdWx0cDZyY294dHlZT1RvTjZybEhodWZoOGZuN2FxWWlxbjc2ZVh0U0RObW01K0ZxZUZhenRPeTdHWGkzcWUrdDNyTnlLNks0N1ltT2lRZWtBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFTTRyOFJkQzRlYUY0OXFkVTM4dTl6cHc4SzNWRVhMOVVmN2FZOU5VOUVlMmVVQTB2NGs4UXR6YisxT2NyWE15ZkZxS3BuSHdiVXpGaXhIc3A5TlgrS2VjKzdxVVJKUUFBQUJMZUczRUxjMndkVGpLMFBNbnhhdXFKeU1HN016WXZ4N2FmUlYvaWpsUHY2a0c2SENqaUxvWEVQUXZIdE1xbXhsMmVWT1poWEtvbTVZcW4vZFRQb3Fqb24yVHpoQk13QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVdQZm01OU4yZHRYTzNEcXRmTEh4YU9jVVJQblhhNTZLYUtmYlZQS1BqNkFhRWI4M1ZxKzg5elpXdjZ6ZTcvSXZ6eW90MHo1bGkzSDd0dWlQUlRIeG5uTTlNcUxFb0FBQUFBQXZ1dzkxYXZzemMyTHIralh1OHlMRThxN2RVK1pmdHorOWJyajAwejhKNVRIVENEZmZZZTU5TjNqdFhCM0RwVmZQSHlxT2MwVFBuV3E0NktxS3ZiVFBPUGo2VUY4QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQnFSM1l1OHE5VDNkajdReGJzK0o2VFRGM0ppSjZLOGl1bm5IUC9MUk1mZlhLNE1ES0FBQUFBQUFBTTg5eDF2S3ZUTjNaRzBNcTdQaWVxMHpkeG9tZWlqSW9wNXp5L3pVUlAzMFFtamJkQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCK2VUZHQyTWU1ZnUxZDdidDB6WFZQWkVSemtIT1RjK3JYdGUzSHFXdDVGVXpkejhxNWtWZnpWVE1SOTBjbys1UmJsQUFBQUFBQUFGeDJ4cTE3UWR4NmJyZVBWTVhjREt0NUZQOHRVVE1mZkhPUHZRZEc4YTdidjQ5dS9hcTc2M2NwaXVtZTJKam5DRDlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVI3aVhmcXh1SFc1TWlpZVZWdlNzcXFtZmJGcW9ITytpT1ZGTWRrUkRRcUFBQUFBQUFBQ2xjYzZLbzdZbUFkRU9HbCtySjRkYmJ5SzU1MVhOS3hhcXA5czJxV1JJUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFXWGZtSlZxR3lOZHdhSTUxNUdtNUZxbVBiVmJxaUFjNktPbWltWjdJYUZRQUFBQUFBQUFVcjZLS3Bqc2tIUmZZZUpWcCt5TkN3YTQ1VjQrbTQ5cXFQYlRicGlXUmVnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVVxaUppWW1PY0E1NThUZHYzTnJjUU5iMEt1aWFhY1hNcjhEempydFZUMzF1ZnkxUW9qaWdBQUFBQUFBQ1I4TXR2M04wY1FORTBLaWlhcWNyTW84TnlqcXRVejMxeWZ5MHlnNkdVeEVSRVJIS0VGUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBYTNkMlRzV3UvalltKzlQc3pWT1BUR0xxVVV4L0Q1L3M3ays2Wm1tWi94VTlpNE5ZRkFBQUFBQUFBR3ovY2JiRnJzWTJYdnZVTE0wemtVemk2YkZVZncrZjdTNUh2bUlwai9BQzFkcWFOa1VBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFIbjFIQ3hkUndMK0JuV0tNakZ5TGRWcTlhcmpuVFhSVkhLWW4yVEFOSGVPWEREUDRkN2hud1ZGM0kwSExybWNIS21PZmUrbndWYytpdU8zN1VkUGJFVVk1VUFBQUFBQVpHNEc4TU0vaUp1R1BDMFhjZlFjU3VKenNxSTVkOTZmQlVUL3dDYzl2Mlk2ZXlKZzNpMDdDeGRPd0xHQmcyS01mRng3ZE5xemFvamxUUlJUSEtJajJSQ0QwQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE4RzRORzB2WDlJeU5KMWpDczV1RmtVOTdkczNZNXhWSDZUSFhFeDB4UFVEVTdpMzNQbXZiZXUzdFMyalRlMXZTZWMxZUx4MDVWaU96bC9FajJ4NTNiSHBXakNOeWl1M2NydDNLYXFLNko1VjAxUnlxcG5zbUo2WWxSOGdBQStyZEZkeTVSYnQwMVYxMXp5b3Bwam5WVlBaRVIweklNM2NKTzU4MTdjTjJ6cVc3cWIyaWFUemlyeGVlakt2eDJjdjRjZTJmTzdJOUtVYlk3ZjBiUzlBMGpIMG5SOEt6aFlXUFQzdHF6YWpsRk1mck05Y3pQVE05YUQzZ0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY3dlRFU5WjBqVEtacTFMVk1IQ3Bqcm5JeUtMY2YxVEFJSnJPQndlNGxabHpGeWIyM2RYejZQTjhKajVWRk9SSHVyb21LcCtNQWhldGR5OXRYSXJtdlNkd2F4cDhUOWk3RkYrbVB4aUorSzBXYi9wV283Ly9BTDVxNzMvMWtjLy9BS0ZGNTBYdVh0cTQ5Y1Y2dHVEV05RaVBzV29vc1V6K0VWVDhTaWFhTmdjSHVHdVpieGNhOXQzU00rdnpmQ1pHVlJWa1Q3NjY1bXFQaENDZDZack9rYW5URldtNnBnNXRNOVU0K1JSY2orbVpCNytZQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFMSnZEZG0zZG82ZC9hRzR0V3h0UHNUUEtqd2xYT3E1UFpSVEhuVlQ3SWlRWWIxM3VvdHM0OTJxalJ0dTZycU1SMVhMMWRHUFRWN284NnJsNzRoWUlacTNkUmJvdmQ5R21iYjBqRXBucW0vZHVYNm8vRHZZSUlocTNIdmlobnhWVFRyOXJDb243T0poMjZPWDMxUlZQeElJanErK041NnZFeHFXNjlieXFaNjZhczJ1S2Z5eE1SOEFSKzVNM0s1cnVmdEtwKzFYNTAvaktpbnBpZlRIVlBZQ1JhUHZuZW1rVVJiMHpkbXQ0dHVPcWlqTnJtbVA1Wm1ZUVhmeXZjVGU4NzMrK3VxOHZmUnovQUI3MGd0R3NiNTNwcTlFMjlUM1pyZVZibnJvcnphNHBuK1dKaUFSMzB6UHBucm50VVZ0ek51dUs3ZjdPcVB0VWViUDR3Q1FhUnZqZWVrUkVhYnV2VzhXbU9xbW5Ocm1uOHN6TWZCQkx0SjQ5OFVNQ0thYXRmdFp0RWVqTHc3ZGZQNzZZcG40a0V2MG51b3QwV2U5alU5dDZSbDB4MXpZdTNMRlUvajMwRUV6MEx1b3RzNUYybWpXZHZhcnAwVDEzTE5kR1JUSDNlYlZ5OTBTUVprMmZ1emJ1N3RPL3REYnVyWTJvV0lubFg0T3JsVmJuc3JwbnpxWjlreENDOWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWhuR0hmdUR3OTJmZDFqSW9wdjVkeXJ3T0ZqVFZ5OE5kbU9jUlBaVEVkTXoyUjJ6QU5HTjI3ajFuZFd1WHRaMTdPdVptWmRuOTZyb3BvcDlGRkZQVlRUSG9pUGpQU290S2dBQUFBQUFBQUFBQUFBQzdiUzNIck8xZGNzNnpvV2Rjdzh5MVA3MVBUVFhUNmFLNmVxcW1leWZoUFNnM240UGI5d2VJV3o3V3NZOUZOakx0MWVCemNhS3VmZ2JzUnptSTdhWmpwaWV5ZTJKUVRNQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUdtZmRkN2l2YXR4VHEwZUxremk2TmowV2FLWW5vOEpjaUs2NnZmeW1pUDVWd1liVUFBQUFBQUFBQUFBQUFBQUFabDdrVGNWN1NlS2RPanpjbU1YV2NldXpYVE05SGhMY1RYUlY3K1VWeC9NbWpjdEFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFucUJvRnh5ditNY1lkMTNPZlZxZHlqOHNSVC94WEJERkFBQUFBQUFBQUFBQUFBQUFFejRHMy9GK01PMUxuUHIxTzNSK2FKcC81Sm8zOWpxUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUpCenM0aDVIamUvOEFjV1Z6NStGMVhLcWlmOVdwUllsQUFBQUFBQUFBQUFBQUFBQUY5NGVaSGltLzl1NVhQbDRMVmNXcVovMWFVSFJPRUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUZLcGlLWm1laUk2UWMyZFV2VGthbmw1RTlNM2NpNWMvTlhNL3FvOHlnQUFBQUFBQUFBQUFBQUFBRDA2WGVuSDFQRXlJNkp0WkZ1NStXdUovUkIwbXBtSnBpWTZZbnBRVkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQjRkd1gvRmRDejhtWjVSYXhydGY0VVRQNkE1dVVUem9wcW5ybUlsb1ZBQUFBQUFBQUFBQUFBQUFBQlN1ZVZGVlVkY1JNZzZSN2Z2K05hRmdaTVR6aTdqV3EveG9pZjFaSHVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJIT0tHUkdKdzMzTGs4K1hnOUp5WmlmYjRLb0hQR21PVk1SMlJFTkNvQUFBQUFBQUFBQUFBQUFBQUtWUnpwbU8ySmdIUTdoZmtSbDhOOXRaUFBuNFRTY2FabjIrQ3BaRWpBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJCTzZDeVBGdURHNnJrVHk1NmZYYi9OTVUvcURRdWV1V2hRQUFBQUFBQUFBQUFBQUFBQUZZNjRCdnAzUHVSNHp3WTJyY21lZkxUNkxmNVptbjlHUk93QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFZLzdvckN5Yy9ndHViSHhLS3E3bE9MRjJhYVk1ek5OdXVtdXIrbW1RYUh0QUFBQUFBQUFBQUFBQUFBQUFBRGZEdWRjTEp3T0MyMmNmTG9xb3UxWXMzWXBxamxNVTNLNnE2ZjZhb1pHUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWZOeWlpN2JxdDNLS2E2S29tS3FhbzV4TVQxeE1BMWI0cGR6ZHFsR3FYdFEySGN4NytGZXFtcU5PdjNmQjEySm43TkZjK2JWVDJSTXhNZFhPVm9nUGtINHErcS93QTlZK3NvZVFmaXI2ci9BRDFqNnloNUIrS3ZxdjhBUFdQcktIa0g0cStxL3dBOVkrc29lUWZpcjZyL0FEMWo2eWg1QitLdnF2OEFQV1ByS0hrSDRxK3Evd0E5WStzb2VRZmlyNnIvQUQxajZ5aDVCK0t2cXY4QVBXUHJLSGtINHErcS93QTlZK3NvZVFmaXI2ci9BRDFqNnloNUIrS3ZxdjhBUFdQcktIa0g0cStxL3dBOVkrc29lUWZpcjZyL0FEMWo2eWg1QitLdnF2OEFQV1ByS0hrSDRxK3Evd0E5WStzb2VRZmlyNnIvQUQxajZ5aWZjTGU1dTFTdlZMT29iOHVZOWpDczFSVk9uV0x2aEs3OHg5bXV1UE5wcDdZaVptZXJuQlJ0SmJvb3RXNmJkdWltaWltSWltbW1PVVJFZFVSQ0Q2QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCLy9aIl0",
+    "c_nonce": "ff_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-89JKwHilrT",
+    "c_nonce_expires_in": 86400,
+    "notification_id": "dab8ef51-fb43-43a5-a5c1-247c93ddb942"
+}
+
+
+
+

Note

+

If the issuance of the requested Credential cannot be issued immediately and it requires more time to be issued, then the PID/(Q)EAA Provider MAY support the Deferred Flow (step 24) as specified in Section Deferred Flow.

+
+

Steps 22 (Notification Request): According to Section 10.1 of [OpenID4VCI], the Wallet sends an HTTP POST request to the Notification Endpoint using the application/json media type as in the following non-normative example.

+
POST /notification HTTP/1.1
+Host: eaa-provider.example.org
+Content-Type: application/json
+Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
+DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
+    VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR
+    nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R
+    1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj
+    oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z
+    WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF
+    c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E
+    OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA
+
+
+
{
+    "notification_id": "dab8ef51-fb43-43a5-a5c1-247c93ddb942",
+    "event": "credential_accepted"
+}
+
+
+

Steps 23 (Notification Response): When the Credential Issuer has successfully received the Notification Request from the Wallet, it MUST respond with an HTTP status code 204 as recommended in Section 10.2 of [OpenID4VCI]. Below is a non-normative example of response to a successful Notification Request:

+
HTTP/1.1 204 No Content
+
+
+
+
+

Deferred Flow

+

The PID/(Q)EAA Providers MAY support a Deferred Flow which has the aim of handling the cases where an immediate issuance is not possible for some reasons due to errors during the communication between the PID/(Q)EAA Provider and the Authentic Source (for example the Authentic Source is temporarily unavailable, etc.) or due to administrative or technical processes that do not allow the Credential to be provided immediately.

+
+

General Requirements

+
+
    +
  1. The Deferred Credential request MAY also happen several days after the initial Credential request.

  2. +
  3. The User MUST be informed that the Credential is available and ready to be issued.

  4. +
  5. The Wallet Provider MUST NOT be informed about which Credential is available to be issued or which Credential Provider the User needs to contact.

  6. +
  7. The Wallet Instance MUST be informed about the amount of time to wait before making a new Credential request.

  8. +
  9. As, in general, an unavailability may be an unexpected event, the PID/(Q)EAA Provider MUST be able to switch on the fly between a immediate and an deferred flow. This decision MUST be taken after the authorization step.

  10. +
+
+
+
+

Technical Flow

+

If PID/(Q)EAA Providers, supporting this flow, are not able to immediately issue a requested Credential, they MUST provide the Wallet Instance with an HTTP Credential Response cointaining the amount of time to wait before making a new Credential request. The HTTP status code MUST be 202 (see Section 15.3.3 of [RFC 9110]). Below a non-normative example is given.

+
HTTP/1.1 202 Accepted
+Content-Type: application/json
+Cache-Control: no-store
+
+
+
{
+    "lead_time": 864000,
+    "c_nonce": "ff_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-89JKwHilrT",
+    "c_nonce_expires_in": 86400
+}
+
+
+

The Wallet Instance MUST use the value given in the lead_time parameter to inform the User when the Credential becomes available (e.g. using a local notification triggered by the lead_time time value). PID/(Q)EAA Providers MAY send a notification to the User through a communication channel (e.g. email address), if available from the PID/(Q)EAA Provider.

+

Upon receipt of the notification (by the Wallet Instance and/or by the PID/(Q)EAA Provider), the User opens the Wallet Instance and start the Issuance Flow again from the beginning as defined in the previous section.

+

If the lead_time parameter is less than the expiration time of the Access Token, the Wallet Instance MAY use it along with the c_nonce provided in the Credential Response to perform a new Credential Request without requiring the User to submit a new authentication request.

+

In the case where the Authentic Source and the PID/(Q)EAA Provider are both enabled to use PDND, what is described in Section Authentic Sources MUST apply.

+
+
+
+

Pushed Authorization Request Endpoint

+
+

Pushed Authorization Request (PAR) Request

+

The request to the PID/(Q)EAA authorization endpoint MUST use HTTP Headers parameters and HTTP POST parameters.

+

The HTTP POST method MUST use the parameters in the message body encoded in application/x-www-form-urlencoded format.

+ + +++++ + + + + + + + + + + + + + + + + +
Table 3 PAR http request parameters

Claim

Description

Reference

client_id

MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.

RFC 6749

request

It MUST be a signed JWT. The private key corresponding to the public one in the cnf parameter inside the Wallet Attestation MUST be used for signing the Request Object.

OpenID Connect Core. Section 6

+

The Pushed Authorization Endpoint is protected with OAuth 2.0 Attestation-based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH], therefore +the request to the PID/(Q)EAA authorization endpoint MUST use the following HTTP Headers parameters:

+ + +++++ + + + + + + + + + + + + +
Table 4 http request header parameters

OAuth-Client-Attestation

It MUST be set to a value containing the Wallet Attestation JWT.

OAUTH-ATTESTATION-CLIENT-AUTH.

OAuth-Client-Attestation-PoP

It MUST be set to a value containing the Wallet Attestation JWT Proof of Possession.

OAUTH-ATTESTATION-CLIENT-AUTH.

+

The JWT Request Object has the following JOSE header parameters:

+ +++++ + + + + + + + + + + + + + + + + +

JOSE header

Description

Reference

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section Cryptographic Algorithms and MUST NOT be set to none or any symmetric algorithm (MAC) identifier.

RFC 7516#section-4.1.1.

kid

Unique identifier of the jwk inside the cnf claim of Wallet Attestation as base64url-encoded JWK Thumbprint value.

RFC 7638#section_3.

+
+

Note

+

The parameter typ, if omitted, assumes the implicit value JWT.

+
+

The request JWT payload contained in the HTTP POST message is given with the following parameters:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

iss

It MUST be set to the client_id.

RFC 9126 and RFC 7519.

aud

It MUST be set to the identifier of the PID/(Q)EAA Provider.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT. The claim value MUST be not greater than 300 seconds from the issuance time.

RFC 9126 and RFC 7519.

iat

UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

response_type

MUST be set to code.

RFC 6749

response_mode

It MUST be a string indicating the "response_mode", as specified in [OAUTH-MULT-RESP-TYPE]. It MUST be one of the supported values (response_modes_supported) provided in the metadata of the PID/(Q)EAA Provider. It informs the PID/(Q)EAA Provider of the mechanism to be used for returning parameters from the Authorization Endpoint. In case of HTTP 302 Redirect Response the value MUST be query. In this mode, Authorization Response parameters are encoded in the query string added to the redirect_uri when redirecting back to the Wallet Instance. In case of HTTP POST Response the value MUST be form_post.jwt according to [OAUTH-V2-JARM-04]. In this mode, Authorization Response parameters are specified into a JWT encoded as HTML form value that is auto-submitted in the user-agent, and thus is transmitted via the HTTP POST method to the Wallet Instance, with the result parameters being encoded in the body using the application/x-www-form-urlencoded format. The action attribute of the form MUST be the Redirection URI of the Wallet Instance. The method of the form attribute MUST be POST.

See [OAUTH-MULT-RESP-TYPE] and [OAUTH-V2-JARM-04].

client_id

It MUST be set as in the Table of the HTTP parameters.

See Table of the HTTP parameters.

state

Unique session identifier at the client side. This value will be returned to the client in the response, at the end of the authentication. It MUST be a random string composed by alphanumeric characters and with a minimum length of 32 digits. Special characters MUST be considered non-alphanumeric characters as defined in [NIST].

See [OIDC] Section 3.1.2.1.

code_challenge

A challenge derived from the code verifier that is sent in the authorization request.

RFC 7636#section-4.2.

code_challenge_method

A method that was used to derive code challenge. It MUST be set to S256.

RFC 7636#section-4.3.

scope

JSON String. String specifying a unique identifier of the Credential being described in the credential_configurations_supported map in the Credential Issuer Metadata. For example, in the case of the PID, it MUST be set to PersonIdentificationData. It MAY be multivalued, each value MUST be separated by a space.

RFC 6749

authorization_details

Array of JSON Objects. Each JSON Object MUST include the following claims:

+
+
    +
  • type: it MUST be set to openid_credential,

  • +
  • credential_configuration_id: JSON String. String specifying a unique identifier of the Credential being described in the credential_configurations_supported map in the Credential Issuer Metadata. For example, in the case of the PID, it MUST be set to PersonIdentificationData.

  • +
+
+

See [RAR RFC 9396] and [OpenID4VCI].

redirect_uri

Redirection URI to which the response is intended to be sent. It MUST be an universal or app link registered with the local operating system, so this latter will provide the response to the Wallet Instance.

See [OIDC] Section 3.1.2.1.

jti

Unique identifier of the JWT that, together with the value contained in the iss claim, prevents the reuse of the JWT (replay attack). Since the jti value alone is not collision resistant, it MUST be identified uniquely together with its issuer.

[RFC 7519].

+
+

Note

+

If the request cointains scope value and the authorization_details parameter the Credential Issuer MUST interpret these individually. However, if both request the same Credential type, then the Credential Issuer MUST follow the request as given by the authorization details object.

+
+

The JOSE header of the Wallet Attestation proof of possession, contained in the HTTP Request headers, MUST contain:

+ +++++ + + + + + + + + + + + + +

JOSE header

Description

Reference

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section Cryptographic Algorithms and MUST NOT be set to none or any symmetric algorithm (MAC) identifier.

RFC 7516#section-4.1.1.

+

The body of the Wallet Attestation proof of possession JWT, contained in the HTTP Request headers, MUST contain:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

iss

Thumbprint of the JWK in the cnf parameter.

RFC 9126 and RFC 7519.

aud

It MUST be set to the identifier of the PID/(Q)EAA Provider.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT.

RFC 9126 and RFC 7519.

iat

UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

jti

Unique identifier for the DPoP proof JWT. The value SHOULD be set using a UUID v4 value according to [RFC 4122].

[RFC 7519. Section 4.1.7].

+
+
+

Pushed Authorization Request (PAR) Response

+

If the verification is successful, the PID/(Q)EAA Issuer MUST provide the response with a 201 HTTP status code. The following parameters are included as top-level members in the HTTP response message body, using the application/json media type as defined in [RFC 8259].

+ +++++ + + + + + + + + + + + + + + + + +

Claim

Description

Reference

request_uri

The request URI corresponding to the authorization request posted. This URI MUST be a single-use reference to the respective authorization request. It MUST contain some part generated using a cryptographically strong pseudorandom algorithm. The value format MUST be urn:ietf:params:oauth:request_uri:<reference-value> with <reference-value> as the random part of the URI that references the respective authorization request data.

[RFC 9126].

expires_in

A JSON number that represents the lifetime of the request URI in seconds as a positive integer.

[RFC 9126].

+

If any errors occur during the PAR Request, the Authorization Server MUST return an error response as defined in RFC 9126#section-2.3. The response MUST use application/json as the content type and MUST include the following parameters:

+
+
    +
  • error. The error code.

  • +
  • error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.

  • +
+
+

Below is a non-normative example of an error response.

+
HTTP/1.1 400 Bad Request
+Content-Type: application/json
+
+
+
{
+    "error": "invalid_request",
+    "error_description": "The redirect_uri is not valid for the given client"
+}
+
+
+
+
+
+

Authorization endpoint

+

The authorization endpoint is used to interact with the PID/(Q)EAA Issuer and obtain an authorization grant. +The authorization server MUST first verify the identity of the User that own the credential.

+
+

Authorization Request

+

The Authorization request is issued by the Web Browser in use by the Wallet Instance, the HTTP methods POST or GET are used. When the method POST is used, the parameters MUST be sent using the Form Serialization. When the method GET is used, the parameters MUST be sent using the Query String Serialization. For more details see Section 13 of [OIDC].

+

The mandatory parameters in the HTTP authentication request are specified in the following table.

+ +++++ + + + + + + + + + + + + + + + + +

Claim

Description

Reference

client_id

It MUST be set as in the Table of the HTTP parameters.

See Table of the HTTP parameters.

request_uri

It MUST be set to the same value as obtained by PAR Response. See Table of the HTTP PAR Response parameters.

[RFC 9126].

+
+

Note

+

In the case of PID issuance, the Wallet Instance MAY include the idphinting parameter as a URL encoded string. This parameter specifies the Identity Provider where the User wishes to authenticate.. See AARC-G061 - A specification for IdP hinting. for more details.

+
+
+
+

Authorization Response

+

The authentication response is returned by the PID/(Q)EAA authorization endpoint at the end of the authentication flow.

+

If the authentication is successful the PID/(Q)EAA Issuer redirects the User by adding the following query parameters as required to the redirect_uri. The redirect URI MUST be an universal or app link registered with the local operating system, so this latter is able to provide the response to the Wallet Instance.

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

code

Unique Authorization Code that the Wallet Instance submits to the Token Endpoint.

[RFC 6749#section-4.1.2], [RFC 7521].

state

The Wallet Instance MUST check the correspondence with the state parameter value in the Request Object. It is defined as in the Table of the JWT Request parameters.

[RFC 6749#section-4.1.2].

iss

Unique identifier of the PID/(Q)EAA Issuer who created the Authentication Response. The Wallet Instance MUST validate this parameter.

[RFC 9207], [RFC 7519, Section 4.1.1.].

+

If any errors occur during the Authorization Request, the Authorization Server MUST return an error response as defined in RFC 6749#section-4.1.2.1. The response MUST use application/json as the content type and MUST include the following parameters:

+
+
    +
  • error. The error code.

  • +
  • error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.

  • +
+
+
+
+
+

Token endpoint

+

The token endpoint is used by the Wallet Instance to obtain an Access Token by presenting an authorization grant, as +defined in RFC 6749. The Token Endpoint is a protected endpoint with a client authentication based on the model defined in OAuth 2.0 Attestation-based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH ].

+
+

Token Request

+

The request to the PID/(Q)EAA Token endpoint MUST be an HTTP request with method POST, with the body message encoded in application/x-www-form-urlencoded format. The Wallet Instance sends the Token endpoint request with OAuth-Client-Attestation and OAuth-Client-Attestation-PoP as header parameters according to OAUTH-ATTESTATION-CLIENT-AUTH.

+

The Token endpoint is protected with OAuth 2.0 Attestation-based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH], therefore +the request to the PID/(Q)EAA authorization endpoint MUST use the following HTTP Headers parameters OAuth-Client-Attestation as OAuth-Client-Attestation-PoP +as defined in the "Pushed Authorization Request (PAR) Endpoint".

+

The Token endpoint issues DPoP tokens, therefore it is REQUIRED that the request incluides in its HTTP header the DPoP proof parameter. +The Token endpoint MUST validate the DPoP proof according to Section 4.3 of the DPoP specifications (RFC 9449). This mitigates the misuse of leaked or stolen Access Tokens at the credential endpoint. If the DPoP proof is invalid, the Token endpoint returns an error response, according to Section 5.2 of [RFC 6749] with invalid_dpop_proof as the value of the error parameter.

+

All the parameters listed below are REQUIRED:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

grant_type

It MUST be set to authorization_code.

[RFC 7521].

code

Authorization code returned in the Authentication Response.

[RFC 7521].

redirect_uri

It MUST be set as in the Request Object Table of the JWT Request parameters.

[RFC 7521].

code_verifier

Verification code of the code_challenge.

Proof Key for Code Exchange by OAuth Public Clients.

+

A DPoP Proof JWT is included in the HTTP request using the DPoP header parameter containing a DPoP JWS.

+

The JOSE header of a DPoP JWT MUST contain at least the following parameters:

+ +++++ + + + + + + + + + + + + + + + + + + + + +

JOSE header

Description

Reference

typ

It MUST be equal to dpop+jwt.

[RFC 7515] and [RFC 8725. Section 3.11].

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to none or with a symmetric algorithm (MAC) identifier.

[RFC 7515].

jwk

It represents the public key chosen by the Wallet Instance, in JSON Web Key (JWK) [RFC 7517] format that the Access Token MUST be bound to, as defined in [RFC 7515] Section 4.1.3. It MUST NOT contain a private key.

[RFC 7517] and [RFC 7515].

+

The payload of a DPoP JWT Proof MUST contain the following claims:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

jti

Unique identifier for the DPoP proof JWT. The value SHOULD be set using a UUID v4 value according to [RFC 4122].

[RFC 7519. Section 4.1.7].

htm

The value of the HTTP method of the request to which the JWT is attached.

[RFC 9110. Section 9.1].

htu

The HTTP target URI, without query and fragment parts, of the request to which the JWT is attached.

[RFC 9110. Section 7.1].

iat

UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in RFC 7519.

[RFC 7519. Section 4.1.6].

+
+
+

Token Response

+

If the Token Request is successfully validated, the Authorization Server provides an HTTP Token Response with a 200 (OK) status code. The Token Response MUST contain the following mandatory claims.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

access_token

The DPoP-bound Access Token, in signed JWT format, allows accessing the PID/(Q)EAA Credential Endpoint for obtaining the credential.

RFC 6749.

token_type

Type of Access Token returned. It MUST be equal to DPoP.

RFC 6749.

expires_in

Expiry time of the Access Token in seconds.

RFC 6749.

c_nonce

JSON string containing a nonce value to be used to create a proof of possession of key material when requesting a Credential.

[OpenID4VCI].

c_nonce_expires_in

JSON integer, it represents the lifetime in seconds of the c_nonce.

[OpenID4VCI].

authorization_details

Array of JSON Objects, used to identify Credentials with the same metadata but different claimset/claim values and/or simplify the Credential request even when only one Credential is being issued.

[OpenID4VCI].

+

If any errors occur during the validation of the Token Request, the Authorization Server MUST return an error response as defined in RFC 6749#section-5.2.

+
HTTP/1.1 400 Bad Request
+Content-Type: application/json;charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+
+
+
{
+    "error": "invalid_client",
+    "error_description": "Client authentication failed"
+}
+
+
+
+
+

Access Token

+

A DPoP-bound Access Token is provided by the PID/(Q)EAA Token endpoint as a result of a successful token request. The Access Token is encoded in JWT format, according to [RFC 7519]. The Access Token MUST have at least the following mandatory claims and it MUST be bound to the public key that is provided by the DPoP proof. This binding can be accomplished based on the methodology defined in Section 6 of (RFC 9449).

+

The JOSE header of a DPoP JWT MUST contain the following claims.

+ +++++ + + + + + + + + + + + + + + + + + + + + +

JOSE header

Description

Reference

typ

It MUST be equal to at+jwt.

[RFC 7515].

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to none or with a symmetric algorithm (MAC) identifier.

[RFC 7515].

kid

Unique identifier of the jwk used by the PID/(Q)EAA Provider to sign the Access Token.

RFC 7638#section_3.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

iss

It MUST be an HTTPS URL that uniquely identifies the PID/(Q)EAA Issuer. The Wallet Instance MUST verify that this value matches the PID/(Q)EAA Issuer where it has requested the credential.

[RFC 9068], [RFC 7519].

sub

It identifies the subject of the JWT. It MUST be set to the value of the sub field in the PID/(Q)EAA SD-JWT-VC.

[RFC 9068], [RFC 7519] and Section 8 of [OIDC].

client_id

The identifier for the Wallet Instance that requested the Access Token; it MUST be equal to the to kid of the public key of the Wallet Instance specified into the Wallet Attestation (cnf.jwk).

[RFC 9068], [RFC 7519] and Section 8 of [OIDC].

aud

It MUST be set to the identifier of the PID/(Q)EAA Provider.

[RFC 9068].

iat

UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in RFC 7519.

[RFC 9068], [RFC 7519. Section 4.1.6].

exp

UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated in RFC 7519.

[RFC 9068], [RFC 7519].

jti

It MUST be a String in uuid4 format. Unique Token ID identifier that the RP SHOULD use to prevent reuse by rejecting the Token ID if already processed.

[RFC 9068], [RFC 7519].

cnf

It MUST contain a jkt claim being JWK SHA-256 Thumbprint Confirmation Method. The value of the jkt member MUST be the base64url encoding (as defined in [RFC 7515]) of the JWK SHA-256 Thumbprint of the DPoP public key (in JWK format) to which the Access Token is bound.

[RFC 9449. Section 6.1] and [RFC 7638].

+
+
+
+

Credential endpoint

+

The Credential Endpoint issues a Credential upon the presentation of a valid Access Token, as defined in OpenID4VCI.

+
+

Credential Request

+

The Wallet Instance when requests the PID/(Q)EAA to the PID/(Q)EAA Credential endpoint, MUST use the following parameters in the message body of the HTTP POST request, using the application/json media type.

+

The Credential endpoint MUST accept and validate the DPoP proof sent in the DPoP HTTP Header parameter, according to the steps defined in (RFC 9449) Section 4.3. The DPoP proof in addition to the values that are defined in the Token Endpoint section MUST contain the following claim:

+
+
    +
  • ath: hash value of the Access Token encoded in ASCII. The value MUST use the base64url encoding (as defined in Section 2 of RFC 7515) with the SHA-256 algorithm.

  • +
+
+

If the DPoP proof is invalid, the Credential endpoint returns an error response per Section 5.2 of [RFC 6749] with invalid_dpop_proof as the value of the error parameter.

+
+

Warning

+

The Wallet Instance MUST create a new DPoP proof for the Credential request and MUST NOT use the previously created proof for the Token Endpoint.

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

format

Format of the Credential to be issued. This MUST be vc+sd-jwt or mso_mdoc.

[OpenID4VCI].

vct

CONDITIONAL. REQUIRED only if the format identifier is vc+sd-jwt.

See Annex A3.4. of [OpenID4VCI]

doctype

CONDITIONAL. REQUIRED only if the format identifier is mso_mdoc.

See Annex A2.4. of [OpenID4VCI]

proof

JSON object containing proof of possession of the key material the issued credential shall be bound to. The proof object MUST contain the following mandatory claims:

+
    +
  • proof_type: JSON string denoting the proof type. It MUST be jwt.

  • +
  • jwt: the JWT used as proof of possession.

  • +
+

[OpenID4VCI].

+

The JWT proof type MUST contain the following parameters for the JOSE header and the JWT body:

+ +++++ + + + + + + + + + + + + + + + + + + + + +

JOSE Header

Description

Reference

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to none or to a symmetric algorithm (MAC) identifier.

[OpenID4VCI], [RFC 7515], [RFC 7517].

typ

It MUST be set to openid4vci-proof+jwt.

[OpenID4VCI], [RFC 7515], [RFC 7517].

jwk

Representing the public key chosen by the Wallet Instance, in JSON Web Key (JWK) [RFC 7517] format that the PID/(Q)EAA shall be bound to, as defined in Section 4.1.3 of [RFC 7515].

[OpenID4VCI], [RFC 7515], [RFC 7517].

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

iss

The value of this claim MUST be the client_id of the Wallet Instance.

[OpenID4VCI], [RFC 7519, Section 4.1.1].

aud

It MUST be set to the identifier of the PID/(Q)EAA Provider.

[OpenID4VCI].

iat

UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in RFC 7519.

[OpenID4VCI], [RFC 7519. Section 4.1.6].

nonce

The value type of this claim MUST be a string, where the value is a c_nonce provided by the PID/(Q)EAA Issuer in the Token response.

[OpenID4VCI].

+
+
+

Credential Response

+

Credential Response to the Wallet Instance MUST be sent using application/json media type. If the Credential Request is successfully validated, and the Credential is immediately available, the PID/(Q)EAA Provider MUST return HTTP response with a 200 (OK) status code. If the Credential is not available and the deferred flow is supported by the PID/(Q)EAA Provider, an HTTP status code 202 MUST be returned.

+

The Credential Response contains the following parameters:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

credential

CONDITIONAL. REQUIRED if lead_time is not present. String Containing the issued PID/(Q)EAA. If the requested format identifier is vc+sd-jwt then the credential parameter MUST NOT be re-encoded. If the requested format identifier is mso_mdoc then the credential parameter MUST be a base64url-encoded representation of the issued Credential.

Section 7.3, Annex A2.5 and Annex A3.5 of [OpenID4VCI].

lead_time

CONDITIONAL. REQUIRED if credential is not present. The amount of time (in seconds) required before making a new Credential Request.

This Specification

c_nonce

REQUIRED. JSON string containing a nonce value to be used to create a proof of possession of the key material when requesting a further Credential or for the renewal of a Credential.

Section 7.3 of [OpenID4VCI].

c_nonce_expires_in

REQUIRED. JSON integer corresponding to the c_nonce lifetime in seconds.

Section 7.3 of [OpenID4VCI].

notification_id

OPTIONAL. String identifying an issued Credential that the Wallet includes in the Notification Request as defined in Section Notification Request. It MUST NOT be present if the credential parameter is not present

Section 7.3 of [OpenID4VCI].

+

If the Credential Request is invalid, the PID/(Q)EAA Provider MUST return an error response as defined in Section 7.3.1 of [OpenID4VCI]. The response MUST use the content type application/json and MUST include the following parameters:

+
+
    +
  • error. The error code.

  • +
  • error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.

  • +
+
+
HTTP/1.1 400 Bad Request
+Content-Type: application/json
+Cache-Control: no-store
+
+
+
{
+    "error": "invalid_proof",
+    "error_description": "The proof field is not present or the provided key proof is invalid or not bound to a nonce provided by the Credential Issuer."
+}
+
+
+
+
+
+

Notification endpoint

+

The Notification Endpoint is used by the Wallet to notify the PID/(Q)EAA Provider of certain events for issued Credentials, such as if the Credential was successfully stored in the Wallet Instance or in case of unsuccessful Credential issuance caused by a User action.

+

This endpoint MUST be protected using a DPoP Access Token. TLS for the confidentiality of the HTTP transport is REQUIRED according to Section 10 of [OpenID4VCI].

+
+

Notification Request

+

The Notification Request MUST be an HTTP POST using the application/json media type with the following parameters.

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

notification_id

REQUIRED. It MUST be equal to the notification_id value returned in the Credential Response by the PID/(Q)EAA Provider.

Section 10.1 of [OpenID4VCI].

event

REQUIRED. Type of the notification event. It MUST be a case sensitive string and it MUST support the following values:

+
    +
  • credential_accepted: when the Credential was successfully stored in the Wallet Instance.

  • +
  • credential_deleted: when the unsuccessful Credential issuance was caused by a user action.

  • +
  • credential_failure: in all other unsuccessful cases.

  • +
+

Section 10.1 of [OpenID4VCI].

event_description

OPTIONAL. Human-readable ASCII [USASCII] text providing additional information, used to inform about the event that occurred. Values for the event_description parameter MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E.

Section 10.1 of [OpenID4VCI].

+
+
+

Notification Response

+

The Notification Response MUST be use an HTTP status code 204 (No Content), as recommended in Section 10.2 of [OpenID4VCI].

+

In case of errors, what is described in Section 10.3 of [OpenID4VCI] MUST apply.

+
+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/proximity-flow.html b/refs/pull/443/merge/en/proximity-flow.html new file mode 100644 index 000000000..8d6fbf917 --- /dev/null +++ b/refs/pull/443/merge/en/proximity-flow.html @@ -0,0 +1,631 @@ + + + + + + + + Proximity Flow — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Proximity Flow

+

This section describes how a Verifier requests the presentation of an mDoc-CBOR Credential to a Wallet Instance according to the ISO 18013-5 Specification. Only Supervised Device Retrieval flow is supported in this technical implementation profile.

+

The presentation phase is divided into three sub-phases:

+
+

1. Device Engagement: This subphase begins when the User is prompted to disclose certain attributes from the mDoc(s). The objective of this subphase is to establish a secure communication channel between the Wallet Instance and the Verifier App, so that the mDoc requests and responses can be exchanged during the communication subphase. +The messages exchanged in this subphase are transmitted through short-range technologies to limit the possibility of interception and eavesdropping. +This technical implementation profile exclusively supports QR code for Device Engagement.

+

2. Session establishment: During the session establishment phase, the Verifier App sets up a secure connection. All data transmitted over this connection is encrypted using a session key, which is known to both the Wallet Instance and the Verifier at this stage. +The established session MAY be terminated based on the conditions as detailed in [ISO18013-5#9.1.1.4].

+

3. Communication - Device Retrieval: The Verifier App encrypts the mDoc request with the appropriate session key and sends it to the Wallet Instance together with its public key in a session establishment message. The mDoc uses the data from the session establishment message to derive the session key and decrypt the mDoc request. +During the communication subphase, the Verifier App has the option to request information from the Wallet using mDoc requests and responses. The primary mode of communication is the secure channel established during the session setup. The Wallet Instance encrypts the mDoc response using the session key and transmits it to the Verifier App via a session data message. This technical implementation profile only supports Bluetooth Low Energy (BLE) for the communication sub-phase.

+
+

The following figure illustrates the flow diagram compliant with ISO 18013-5 for proximity flow.

+
+_images/High-Level-Flow-ITWallet-Presentation-ISO.svg +
+

High-Level Proximity Flow

+
+
+

Step 1-3: The Verifier requests the User to reveal certain attributes from their mDoc(s) stored in the Wallet Instance. The User initiates the Wallet Instance. The Wallet Instance MUST create a new temporary key pair (EDeviceKey.Priv, EDeviceKey.Pub), and incorporate the cipher suite identifier, the identifier of the elliptic curve for key agreement, and the EDeviceKey public point into the device engagement structure (refer to [ISO18013-5#9.1.1.4]). This key pair is temporary and MUST be invalidated immediately after the secure channel is established. Finally, the Wallet Instance displays the QR Code for Device Engagement.

+

Below an example of a device engagement structure that utilizes QR for device engagement and Bluetooth Low Energy (BLE) for data retrieval.

+

CBOR data:

+
a30063312e30018201d818584ba4010220012158205a88d182bce5f42efa59943f33359d2e8a968ff289d93e5fa444b624343167fe225820b16e8cf858ddc7690407ba61d4c338237a8cfcf3de6aa672fc60a557aa32fc670281830201a300f401f50b5045efef742b2c4837a9a3b0e1d05a6917
+
+
+

In diagnostic notation:

+
{
+  0: "1.0", % Version
+
+  1:        % Security
+  [
+      1,     % defines the cipher suite 1 which contains only EC curves
+      24(<<  % embedded CBOR data item
+        {
+          1: 2, % kty:EC2 (Elliptic curves with x and y coordinate pairs)
+        -1: 1, % crv:p256
+-2:h'5A88D182BCE5F42EFA59943F33359D2E8A968FF289D93E5FA444B624343  167FE',% x-coordinate
+-3:h'B16E8CF858DDC7690407BA61D4C338237A8CFCF3DE6AA672FC60A557AA32FC67' % y-coordinate
+        }
+      >>)
+    ],
+
+    2: %DeviceRetrievalMethods(Device engagement using QR code)
+    [
+      [
+        2, %BLE
+        1, % Version
+      {    %BLE options
+          0: false, % no support for mdoc peripheral server mode
+          1: true, % support mdoc central client mode
+          11: h'45EFEF742B2C4837A9A3B0E1D05A6917' % UUID of mdoc client central mode
+        }
+      ]
+    ]
+}
+
+
+

Step 4-6: The Verifier App scans the QR Code and generates its own ephemeral key pair (EReaderKey.Priv, EReaderKey.Pub). It then calculates the session key, using the public key received in the Engagement Structure and its newly-generated private key, as outlined in [ISO18013-5#9.1.1.5]. Finally, it generates its session key, which must be independently derived by both the Wallet Instance and the Verifier App.

+

Step 7: The Verifier App creates an mDoc request that MUST be encrypted using the relevant session key, and transmits it to the Wallet Instance along with EReaderKey.Pub within a session establishment message. The mDoc request MUST be encoded in CBOR, as demonstrated in the following non-normative example.

+

CBOR data: +.. code-block:

+
a26776657273696f6e63312e306b646f63526571756573747381a26c6974656d7352657175657374d818590152a267646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e4954a375766572696669636174696f6e2e65766964656e6365f4781c766572696669636174696f6e2e6173737572616e63655f6c6576656cf4781c766572696669636174696f6e2e74727573745f6672616d65776f726bf4716f72672e69736f2e31383031332e352e31ab76756e5f64697374696e6775697368696e675f7369676ef47264726976696e675f70726976696c65676573f46f646f63756d656e745f6e756d626572f46a69737375655f64617465f46f69737375696e675f636f756e747279f47169737375696e675f617574686f72697479f46a62697274685f64617465f46b6578706972795f64617465f46a676976656e5f6e616d65f468706f727472616974f46b66616d696c795f6e616d65f46a726561646572417574688443a10126a11821590129308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97bf6584058a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9
+
+
+

The above CBOR data is represented in diagnostic notation as follows: +.. code-block:

+
{
+  "version": "1.0",
+  "docRequests": [
+  {
+    "itemsRequest": 24(<< {
+      "docType": "org.iso.18013.5.1.mDL",
+      "nameSpaces": {
+        "org.iso.18013.5.1.IT": {
+          "verification.evidence": false,
+          "verification.assurance_level": false,
+          "verification.trust_framework": false
+        },
+        "org.iso.18013.5.1": {
+          "un_distinguishing_sign": false,
+          "driving_privileges": false,
+          "document_number": false,
+          "issue_date": false,
+          "issuing_country": false,
+          "issuing_authority": false,
+          "birth_date": false,
+          "expiry_date": false,
+          "given_name": false,
+          "portrait": false,
+          "family_name": false
+        }
+      }
+    } >>),
+    "readerAuth": [
+      h'a10126',
+      {
+        33: h'308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97b'
+      },
+      null,
+      h'58a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9'
+    ]
+  }
+  ]
+}
+
+
+

Step 8: The Wallet Instance uses the session establishment message to derive the session keys and decrypt the mDoc request. It computes the session key using the public key received from the Verifier App and its private key.

+

Step 9-10: When the Wallet Instance receives the mDoc request, it locates the documents that contain the requested attributes and asks the User for permission to provide this information to the Verifier. If the User agrees, the Wallet generates an mDoc response and transmits it to the Verifier App through the secure channel.

+

Step 11-12: If the User gives consent, the Wallet Instance creates an mDoc response and transmits it to the Verifier App via the secure channel. The mDoc response MUST be encoded in CBOR, with its structure outlined in [ISO18013-5#8.3.2.1.2.2]. Below is a non-normative example of an mDoc response.

+

CBOR Data: +.. code-block:

+
a36776657273696f6e63312e3069646f63756d656e747381a367646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6c6973737565725369676e6564a26a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e495483d81858f7a46864696765737449440b6672616e646f6d506d44f21ee875f2c1d502b43198e5a15271656c656d656e744964656e74696669657275766572696669636174696f6e2e65766964656e63656c656c656d656e7456616c756581a2647479706571656c656374726f6e69635f7265636f7264667265636f7264bf6474797065781f68747470733a2f2f657564692e77616c6c65742e70646e642e676f762e697466736f75726365bf716f7267616e697a6174696f6e5f6e616d65754d6f746f72697a7a617a696f6e6520436976696c656f6f7267616e697a6174696f6e5f6964656d5f696e666c636f756e7472795f636f6465626974ffffd8185866a4686469676573744944046672616e646f6d50185d84dfb71ce9b173010ddd62174fbe71656c656d656e744964656e746966696572781c766572696669636174696f6e2e74727573745f6672616d65776f726b6c656c656d656e7456616c7565656569646173d8185865a4686469676573744944006672616e646f6d50137f903174253c4585358267aae2ea4e71656c656d656e744964656e746966696572781c766572696669636174696f6e2e6173737572616e63655f6c6576656c6c656c656d656e7456616c75656468696768716f72672e69736f2e31383031332e352e318bd8185852a46864696765737449440c6672616e646f6d5053e29d0ddbbc7d2306a32bdbe2e56e5171656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756563446f65d8185855a4686469676573744944036672616e646f6d50990cba2069fa1b33b8d6ae910b6549dc71656c656d656e744964656e7469666965726a676976656e5f6e616d656c656c656d656e7456616c756567416e746f6e696fd818585ba46864696765737449440a6672616e646f6d504086c1379975f805f1b1f4975e6a126571656c656d656e744964656e7469666965726a69737375655f646174656c656c656d656e7456616c7565d903ec6a323031392d31302d3230d818585ca4686469676573744944016672616e646f6d50ab4ca30c918dd2fd0bf35242c15fa2d871656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d31302d3230d8185855a4686469676573744944076672616e646f6d508d9066f6c8da16619867cd4e2fab0c8871656c656d656e744964656e7469666965726f69737375696e675f636f756e7472796c656c656d656e7456616c7565624954d818587ea4686469676573744944056672616e646f6d5059fe68db795dee4c20976380ea24770571656c656d656e744964656e7469666965727169737375696e675f617574686f726974796c656c656d656e7456616c75657828497374697475746f20506f6c696772616669636f2065205a656363612064656c6c6f20537461746fd818585ba4686469676573744944026672616e646f6d5008b3f1ca5517019767be3dee3bb0614571656c656d656e744964656e7469666965726a62697274685f646174656c656c656d656e7456616c7565d903ec6a313935362d30312d3230d818585ca4686469676573744944096672616e646f6d50a2395ec214350c26066306e23279b3ae71656c656d656e744964656e7469666965726f646f63756d656e745f6e756d6265726c656c656d656e7456616c756569393837363534333231d8185850a4686469676573744944066672616e646f6d50a25e1a5b915d2d6eafee9674e023293971656c656d656e744964656e74696669657268706f7274726169746c656c656d656e7456616c75654420212223d81858eea46864696765737449440d6672616e646f6d50eeed6a3b856563627589a360939d12f771656c656d656e744964656e7469666965727264726976696e675f70726976696c656765736c656c656d656e7456616c756582a37576656869636c655f63617465676f72795f636f646561416a69737375655f64617465d903ec6a323031382d30382d30396b6578706972795f64617465d903ec6a323032342d31302d3230a37576656869636c655f63617465676f72795f636f646561426a69737375655f64617465d903ec6a323031372d30322d32336b6578706972795f64617465d903ec6a323032342d31302d3230d818585ba4686469676573744944086672616e646f6d50c0ef486b2a194ed3cbf7f354fd40092171656c656d656e744964656e74696669657276756e5f64697374696e6775697368696e675f7369676e6c656c656d656e7456616c756561496a697373756572417574688443a10126a118215901423082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb
+
+
+

In diagnostic notation: +.. code-block:

+
{
+  "version": "1.0",
+  "documents": [
+  {
+    "docType": "org.iso.18013.5.1.mDL",
+    "issuerSigned": {
+      "nameSpaces": {
+        "org.iso.18013.5.1.IT": [
+          24(<< {
+            "digestID": 11,
+            "random": h'6d44f21ee875f2c1d502b43198e5a152',
+            "elementIdentifier": "verification.evidence",
+            "elementValue": [
+              {
+                "type": "electronic_record",
+                "record": {
+                  "type": "https://eudi.wallet.pdnd.gov.it",
+                  "source": {
+                    "organization_name": "Motorizzazione Civile",
+                    "organization_id": "m_inf",
+                    "country_code": "it"
+                  }
+                }
+              }
+            ]
+          } >>),
+          24(<< {
+            "digestID": 4,
+            "random": h'185d84dfb71ce9b173010ddd62174fbe',
+            "elementIdentifier": "verification.trust_framework",
+            "elementValue": "eidas"
+          } >>),
+          24(<< {
+            "digestID": 0,
+            "random": h'137f903174253c4585358267aae2ea4e',
+            "elementIdentifier": "verification.assurance_level",
+            "elementValue": "high"
+          } >>)
+        ],
+        "org.iso.18013.5.1": [
+          24(<< {
+            "digestID": 12,
+            "random": h'53e29d0ddbbc7d2306a32bdbe2e56e51',
+            "elementIdentifier": "family_name",
+            "elementValue": "Doe"
+          } >>),
+          24(<< {
+            "digestID": 3,
+            "random": h'990cba2069fa1b33b8d6ae910b6549dc',
+            "elementIdentifier": "given_name",
+            "elementValue": "Antonio"
+          } >>),
+          24(<< {
+            "digestID": 10,
+            "random": h'4086c1379975f805f1b1f4975e6a1265',
+            "elementIdentifier": "issue_date",
+            "elementValue": 1004("2019-10-20")
+          } >>),
+          24(<< {
+            "digestID": 1,
+            "random": h'ab4ca30c918dd2fd0bf35242c15fa2d8',
+            "elementIdentifier": "expiry_date",
+            "elementValue": 1004("2024-10-20")
+          } >>),
+          24(<< {
+            "digestID": 7,
+            "random": h'8d9066f6c8da16619867cd4e2fab0c88',
+            "elementIdentifier": "issuing_country",
+            "elementValue": "IT"
+          } >>),
+          24(<< {
+            "digestID": 5,
+            "random": h'59fe68db795dee4c20976380ea247705',
+            "elementIdentifier": "issuing_authority",
+            "elementValue": "Istituto Poligrafico e Zecca dello Stato"
+          } >>),
+          24(<< {
+            "digestID": 2,
+            "random": h'08b3f1ca5517019767be3dee3bb06145',
+            "elementIdentifier": "birth_date",
+            "elementValue": 1004("1956-01-20")
+          } >>),
+          24(<< {
+            "digestID": 9,
+            "random": h'a2395ec214350c26066306e23279b3ae',
+            "elementIdentifier": "document_number",
+            "elementValue": "987654321"
+          } >>),
+          24(<< {
+            "digestID": 6,
+            "random": h'a25e1a5b915d2d6eafee9674e0232939',
+            "elementIdentifier": "portrait",
+            "elementValue": h'20212223'
+          } >>),
+          24(<< {
+            "digestID": 13,
+            "random": h'eeed6a3b856563627589a360939d12f7',
+            "elementIdentifier": "driving_privileges",
+            "elementValue": [
+              {
+                "vehicle_category_code": "A",
+                "issue_date": 1004("2018-08-09"),
+                "expiry_date": 1004("2024-10-20")
+              },
+              {
+                "vehicle_category_code": "B",
+                "issue_date": 1004("2017-02-23"),
+                "expiry_date": 1004("2024-10-20")
+              }
+            ]
+          } >>),
+          24(<< {
+            "digestID": 8,
+            "random": h'c0ef486b2a194ed3cbf7f354fd400921',
+            "elementIdentifier": "un_distinguishing_sign",
+            "elementValue": "I"
+          } >>)
+        ]
+      },
+      "issuerAuth": [
+        h'a10126',
+        {
+          33: h'3082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb7d518bd9a519583e082d67effff06565804fc09abf0e4a08e699c9dba3796285a15f68e40ac7f9fc7700a15153a4065300a06082a8648ce3d040302034800304502210099b7d62e6bf7b1823db3713df889bf73e70bb4d9c58c21e92c58d2f1beffe932022058d039747a00d70e6d66be4797e6142b3608a014ee09b7b79af2cae2aaf27788'
+        },
+        24(<< {
+      "version": "1.0",
+      "digestAlgorithm": "SHA-256",
+      "docType": "org.iso.18013.5.1.mDL",
+      "valueDigests": {
+        "org.iso.18013.5.1": {
+        1: h'0E5F0B6B33418E508740771E82F893372EAF5B2445BC4C84DCF08B005E9493FC',
+        2: h'DE21BB62FF2897D8B986D2CDA9F9BC5865C02807F7B4D9DD1FA4A79DF4C0D37F',
+        3: h'BC5568239E35CE9FF8798C27FFDCD757B134B679F0FE05729AA3491381912E65',
+        5: h'E6048BDC7FD6454296F1E3F54536107C9C5B24C4064DE46A98121E3630EECCA2',
+        6: h'73690D92DCAA61B0203870F67C6AA9FDFEA889B6F0C720DE757B4B0A8516A206',
+        7: h'E353EA0B0FD92B6BE90C64CC3B2EE1284153A8F0F5066B99AAC599200E6EEEB2',
+        8: h'29227872CEB49923D267B5F4BADE6D387B42AC2DC4B2AE26C9013067FEE7018A',
+        9: h'A6A119F7CACAC0B8C6AACAC747FD3FE7E50B6D9BB8A507FDA79F0DF6646F285D',
+        10: h'6D8025D2F02A5E7E1406FB6AAEB67F9EDE9B07191A53F3E23B77C528223A94E2',
+        12: h'B0D43E4E2EA534E4D5304E64BCF7A0F13E2C8EE8304B9CD23ABA4909652A4647',
+        13: h'FBF4DE318982F2DBAD43C601CAEB22628B301AC18AA8264C5831B2AAAC89C486'
+        },
+        "org.iso.18013.5.1.IT": {
+        0: h'CF57377B675F64F37314739592C1E8A911A7DDAF341CE2902FE877C5A835E4C1',
+        4: h'4A4B4CC64EC9299C1A2501EA449F577005E9F7A60408057C07A7C67FB151E5F5',
+        11: h'78824FBD6FBBA88A2AAB44DF8B6F5E9759126D87D1F4415995E658FD9239E1FE'
+        }
+      },
+      "deviceKeyInfo": {
+        "deviceKey": {
+        1: 2,
+        -1: 1,
+        -2: h'AFD09E720B918CEDC2B8A881950BAB6A1051E18AE16A814D51E609938663D5E1',
+        -3: h'61FBC6C8AD24EC86A78BB4E9AC377DD2B7C711D9F2EB9AFD4AA0963662847AED'}},
+        "validityInfo": {
+          "signed": 0("2023-11-24T14:54:05Z"),
+          "validFrom": 0("2023-11-24T14:54:05Z"),
+          "validUntil": 0("2024-11-24T14:54:05Z")}
+        }  >>),
+        h'f2461e4fab69e9f7bcffe552395424514524d1679440036213173101448d1b1ab4a293859b389ffa8b47aeed10e9b0c1545412ac37c51a76482cd9bbbe110152'
+      ]
+    },
+    "deviceSigned": {
+      "nameSpaces": 24(<< {} >>),
+      "deviceAuth": {
+        "deviceSignature": [
+          h'a10126',
+          {},
+          null,
+          h'1fed7190d2975ab79c072e6f1d9d52436059d1fc959d55baf74f057d89b10fcc0dc77a50d433d4c76ddf26223c5560c4ab123b5cb5eb805a90036aa147493076'
+        ]
+      }
+    }
+  }
+  ],
+  "status": 0
+}
+
+
+

Step 13: The Verifier App is required to validate the signatures in the mDoc's issuerSigned field using the public key of the Credential Issuer specified within the mDoc. Subsequently, the Verifier MUST validate the signature in the deviceSigned field. If these signature checks pass, the Verifier can confidently consider the received information as valid.

+
+

Device Engagement

+

The Device Engagement structure MUST be have at least the following components:

+
+
    +
  • Version: tstr. Version of the data structure being used.

  • +
  • Security: an array that contains two mandatory values

    +
      +
    • the cipher identifier: see Table 22 of [ISO18013-5]

    • +
    • the mDL public ephemeral key generated by the Wallet Instance and required by the Verifier App to derive the Session Key. The mDL public ephemeral key MUST be of a type allowed by the indicated cipher suite.

    • +
    +
  • +
  • transferMethod: an array that contains one or more transferMethod arrays when performing device engagement using the QR code. This array is for offline data retrieval methods. A transferMethod array holds two mandatory values (type and version). Only the BLE option is supported by this technical implementation profile, then the type value MUST be set to 2.

  • +
  • BleOptions: this elements MUST provide options for the BLE connection (support for Peripheral Server or Central Client Mode, and the device UUID).

  • +
+
+
+
+

mDoc Request

+

The messages in the mDoc Request MUST be encoded using CBOR. The resulting CBOR byte string for the mDoc Request MUST be encrypted with the Session Key obtained after the Device Engagement phase and MUST be transmitted using the BLE protocol. +The details on the structure of mDoc Request, including identifier and format of the data elements, are provided below.

+
+
    +
  • version: (tstr). Version of the data structure.

  • +
  • docRequests: Requested DocType, NameSpace and data elements.

    +
      +
    • itemsRequest: #6.24(bstr .cbor ItemsRequest).

      +
        +
      • docType: (tstr). The DocType element contains the type of document requested. See Data Model Section.

      • +
      • nameSpaces: (tstr). See Data Model Section for more details.

        +
          +
        • dataElements: (tstr). Requested data elements with Intent to Retain value for each requested element.

          +
            +
          • IntentToRetain: (bool). It indicates that the Verifier App intends to retain the received data element.

          • +
          +
        • +
        +
      • +
      +
    • +
    • readerAuth: COSE_Sign1. It is required for the Verifier App authentication.

    • +
    +
  • +
+
+
+

Note

+

The domestic data elements MUST not be returned unless specifically requested by the Verifier App.

+
+
+
+

mDoc Response

+

The messages in the mDoc Response MUST be encoded using CBOR and MUST be encrypted with the Session Key obtained after the Device Engagement phase. +The details on the structure of mDoc Response are provided below.

+
+
    +
  • version: (tstr). Version of the data structure.

  • +
  • documents: Returned DocType, and ResponseData.

    +
      +
    • docType: (tstr). The DocType element contains the type of document returned. See Data Model Section.

    • +
    • ResponseData:

      +
        +
      • IssuerSigned: Responded data elements signed by the issuer.

        +
          +
        • nameSpaces: (tstr). See Data Model Section for more details.

          +
            +
          • IssuerSignedItemBytes: #6.24(bstr .cbor).

            +
              +
            • digestID: (uint). Reference value to one of the ValueDigests provided in the Mobile Security Object (issuerAuth).

            • +
            • random: (bstr). Random byte value used as salt for the hash function. This value SHALL be different for each IssuerSignedItem and it SHALL have a minimum length of 16 bytes.

            • +
            • elementIdentifier: (tstr). Identifier of User attribute name contained in the Credential.

            • +
            • elementValue: (any). User attribute value

            • +
            +
          • +
          +
        • +
        +
      • +
      • DeviceSigned: Responded data elements signed by the Wallet Instance.

        +
          +
        • NameSpaces: #6.24(bstr .cbor DeviceNameSpaces). The DeviceNameSpaces structure MAY be an empty structure. DeviceNameSpaces contains the data element identifiers and values. It is returned as part of the corresponding namespace in DeviceNameSpace.

          +
            +
          • DataItemName: (tstr). The identifier of the element.

          • +
          • DataItemValue: (any). The value of the element.

          • +
          +
        • +
        • DeviceAuth: The DeviceAuth structure MUST contain the DeviceSignature elements.

          +
            +
          • DeviceSignature: It MUST contain the device signature for the Wallet Instance authentication.

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • status: It contains a status code. For detailed description and action required refer to to Table 8 (ResponseStatus) of the [ISO18013-5]

  • +
+
+
+
+

Session Termination

+

The session MUST be terminated if at least one of the following conditions occur.

+
+
    +
  • After a time-out of no activity of receiving or sending session establishment or session data messages occurs. The time-out for no activity implemented by the Wallet Instance and the Verifier App SHOULD be no less than 300 seconds.

  • +
  • When the Wallet Instance doesn't accept any more requests.

  • +
  • When the Verifier App does not send any further requests.

  • +
+
+

If the Wallet Instance and the Verifier App does not send or receive any further requests, the session termination MUST be initiated as follows.

+
+
    +
  • Send the status code for session termination, or

  • +
  • dispatch the "End" command as outlined in [ISO18013-5#8.3.3.1.1.5].

  • +
+
+

When a session is terminated, the Wallet Instance and the Verifier App MUST perform at least the following actions:

+
+
    +
  • destruction of session keys and related ephemeral key material;

  • +
  • closure of the communication channel used for data retrieval.

  • +
+
+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+
+ +
+ +
+ +
+
+
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/pseudonyms.html b/refs/pull/443/merge/en/pseudonyms.html new file mode 100644 index 000000000..b38f910f7 --- /dev/null +++ b/refs/pull/443/merge/en/pseudonyms.html @@ -0,0 +1,260 @@ + + + + + + + + Pseudonyms — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Pseudonyms

+
+

What it is useful for

+

Pseudonyms are useful for: +- Protecting user privacy in online platforms +- Allowing anonymous participation in discussions or transactions +- Maintaining consistent identities across multiple services without revealing personal information +- Compliance with data protection regulations that require data minimization

+
+
+

Example

+

In a social media platform, a user might choose the pseudonym "SunflowerDreamer" +instead of using their real name "Jane Smith". This allows Jane +to participate in discussions while maintaining her privacy.

+
+
+

General Properties

+
    +
  • Uniqueness within a given context.

  • +
  • Consistency (the same entity always uses the same pseudonym in a given context).

  • +
  • Reversibility (optional, depending on the system's requirements).

  • +
  • Non-linkability to the real identity (without additional information).

  • +
+
+
+

Requirements

+
    +
  • IT-Wallet MUST be able to generate or assign unique pseudonyms.

  • +
  • The pseudonym SHOULD NOT contain information that directly reveals the entity's real identity.

  • +
  • The system SHOULD maintain a secure mapping between pseudonyms and real identities (if reversibility is required).

  • +
  • The pseudonym generation process SHOULD be resistant to guessing attacks.

  • +
+
+
+

Implementation Considerations

+
    +
  • IT-Wallet MUST use a pseudonym format that balances uniqueness, readability, and security.

  • +
  • IT-Wallet MUST implement a secure method for generating and storing pseudonyms.

  • +
  • IT-Wallet SHOULD use different pseudonyms for the same entity across different contexts to prevent cross-context linking.

  • +
  • IT-Wallet SHOULD implement access controls to protect the mapping between pseudonyms and real identities.

  • +
  • IT-Wallet SHOULD implements policies for pseudonym rotation or expiration.

  • +
+
+
+ + +
+
+
+
+ + + + + + +
+
+
+ +
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/relying-party-entity-configuration.html b/refs/pull/443/merge/en/relying-party-entity-configuration.html new file mode 100644 index 000000000..9e721b005 --- /dev/null +++ b/refs/pull/443/merge/en/relying-party-entity-configuration.html @@ -0,0 +1,447 @@ + + + + + + + + Entity Configuration of Relying Parties — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Entity Configuration of Relying Parties

+

According to Section Configuration of the Federation, as a Federation Entity, the Relying Party is required to maintain a well-known endpoint that hosts its Entity Configuration. +The Entity Configuration of Relying Parties MUST contain the parameters defined in the Sections Entity Configuration Leaves and Intermediates and Entity Configurations Common Parameters.

+

The Relying Parties MUST provide the following metadata types:

+
+
    +
  • federation_entity

  • +
  • wallet_relying_party

  • +
+
+
+

Metadata for federation_entity

+

The federation_entity metadata MUST contain the claims as defined in Section Metadata of federation_entity Leaves.

+
+
+

Metadata for wallet_relying_party

+

The wallet_relying_party metadata MUST contain the following parameters.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

client_id

It MUST contain an HTTPS URL that uniquely identifies the RP. See RFC 7591#section-3.2.1 and OpenID Connect Dynamic Client Registration 1.0 Section 3.2.

client_name

Human-readable string name of the RP. See RFC 7591#section-2.

application_type

String indicating the type of application. It MUST be set to "web" value. See OpenID Connect Dynamic Client Registration 1.0 Section 2.

request_uris

JSON Array of request_uri values that are pre-registered by the RP. These URLs MUST use the https scheme. See OpenID Connect Dynamic Client Registration 1.0 Section 2.

response_uris_supported

JSON Array of response URI strings to which the Wallet Instance MUST send the Authorization Response using an HTTP POST request as defined by the Response Mode direct_post and direct_post.jwt (see OpenID4VP Draft 20 Sections 6.2 and 6.3).

authorization_signed_response_alg

String representing the JWS [RFC 7515] alg algorithm that MUST be used for signing authorization responses. The algorithm none MUST NOT be used. See [oauth-v2-jarm-03] Section 3.

vp_formats

JSON object defining the formats and proof types of Verifiable Presentations and Verifiable Credentials the RP supports. It consists of a list of name/value pairs, where each name uniquely identifies a supported type. The RP MUST support at least "vc+sd-jwt" according to OPENID4VC-HAIP Draft 00 Section 7.2.7. The value associated with each name/value pair MUST be a JSON object "sd-jwt_alg_values" that MUST contain a JSON array containing identifiers of cryptographic algorithms the RP supports for protection of a SD-JWT. The alg JOSE header (as defined in RFC 7515) of the presented SD-JWT MUST match one of the array values. See also OpenID4VP Draft 20 Section 9.1.

presentation_definitions_supported

JSON Array of supported presentation_definition objects that MUST be compliant to the syntax defined in Section 5 of [DIF.PresentationExchange] and Section 7.2.8 of OPENID4VC-HAIP Draft 00. For presentation_definition objects see also OpenID4VP Section 5.1.

jwks

JSON Web Key Set document, passed by value, containing the protocol specific keys for the Relying Party. See [oauth-v2-jarm-03] Section 3, OID-FED Draft 36 Section 5.2.1 and JWK.

+
+

Note

+

The claims response_uris_supported and presentation_definitions_supported are introduced in this Specification.

+
+
+
+

Example of a Relying Party Entity Configuration

+

Below a non-normative example of the request made by the Wallet Instance to the openid-federation well-known endpoint to obtain the Relying Party Entity Configuration:

+
GET /.well-known/openid-federation HTTP/1.1
+HOST: relying-party.example.org
+
+
+

Below is a non-normative response example:

+
{
+    "iat": 1718207217,
+    "exp": 1749743216,
+    "iss": "https://relying-party.example.org",
+    "sub": "https://relying-party.example.org",
+    "authority_hints": [
+        "https://trust-anchor.example.org"
+    ],
+    "jwks": {
+        "keys": [
+            {
+                "kid": "FANFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMEEs",
+                "kty": "EC",
+                "crv": "P-256",
+                "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
+                "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
+            }
+        ]
+    },
+    "metadata": {
+        "federation_entity": {
+            "homepage_uri": "https://relying-party.example.org",
+            "organization_name": "Organization Name",
+            "contacts": [
+                "informazioni@example.it",
+                "protocollo@pec.example.it"
+            ],
+            "tos_uri": "https://relying-party.example.org/public/info_policy.html",
+            "policy_uri": "https://relying-party.example.org/public/privacy_policy.html",
+            "logo_uri": "https://relying-party.example.org/public/logo.svg"
+        },
+        "wallet_relying_party": {
+            "application_type": "web",
+            "client_id": "https://relying-party.example.org",
+            "client_name": "Organization Name",
+            "contacts": [
+                "informazioni@example.it",
+                "protocollo@pec.example.it"
+            ],
+            "request_uris": [
+                "https://relying-party.example.org/request_uri"
+            ],
+            "response_uris_supported": [
+                "https://relying-party.example.org/response_uri"
+            ],
+            "authorization_signed_response_alg": "ES256",
+            "vp_formats": {
+                "vc+sd-jwt": {
+                    "sd-jwt_alg_values": [
+                        "ES256",
+                        "ES384",
+                        "ES512"
+                    ]
+                }
+            },
+            "presentation_definitions_supported": [
+                {
+                    "id": "d76c51b7-ea90-49bb-8368-6b3d194fc131",
+                    "input_descriptors": [
+                        {
+                            "id": "PersonIdentificationData",
+                            "name": "Person Identification Data",
+                            "purpose": "User Authentication",
+                            "format": {
+                                "vc+sd-jwt": {
+                                    "alg": [
+                                        "ES256",
+                                        "ES384",
+                                        "ES512"
+                                    ]
+                                }
+                            },
+                            "constraints": {
+                                "limit_disclosure": "required",
+                                "fields": [
+                                    {
+                                        "filter": {
+                                            "const": "PersonIdentificationData",
+                                            "type": "string"
+                                        },
+                                        "path": [
+                                            "$.vct"
+                                        ]
+                                    },
+                                    {
+                                        "filter": {
+                                            "type": "object"
+                                        },
+                                        "path": [
+                                            "$.cnf.jwk"
+                                        ]
+                                    },
+                                    {
+                                        "path": [
+                                            "$.unique_id"
+                                        ]
+                                    },
+                                    {
+                                        "path": [
+                                            "$.tax_id_code"
+                                        ]
+                                    }
+                                ]
+                            }
+                        
+                        },      
+                        {
+                            "id": "WalletAttestation",
+                            "name": "Wallet Attestation",
+                            "purpose": "Wallet Authentication",
+                            "format": {
+                                "jwt": {
+                                    "alg": [
+                                        "ES256",
+                                        "ES384",
+                                        "ES512"
+                                    ]
+                                }
+                            },
+                            "constraints": {
+                                "limit_disclosure": "required",
+                                "fields": [
+                                    {
+                                        "filter": {
+                                            "type": "string"
+                                        },
+                                        "path": [
+                                            "$.iss"
+                                        ]
+                                    },
+                                    {
+                                        "filter": {
+                                            "type": "object"
+                                        },
+                                        "path": [
+                                            "$.cnf.jwk"
+                                        ]
+                                    }
+                                ]
+                            }
+                        }
+                    
+                    ]
+                } 
+            ],
+            "jwks": {
+                "keys": [
+                    {
+                        "kid": "f10aca0992694b3581f6f699bfc8a2c6cc687725",
+                        "kty": "EC",
+                        "crv": "P-256",
+                        "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
+                        "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
+                    }
+                ]
+            }
+        }
+    }
+}
+
+
+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/relying-party-solution.html b/refs/pull/443/merge/en/relying-party-solution.html new file mode 100644 index 000000000..9b82d3b30 --- /dev/null +++ b/refs/pull/443/merge/en/relying-party-solution.html @@ -0,0 +1,1383 @@ + + + + + + + + Relying Party Solution — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Relying Party Solution

+

This section describes how a remote Relying Party or a Verifier App requests to a Wallet Instance the presentation of the PID/EAAs.

+

In this section the following flows are described:

+
    +
  • Remote Flow, where the User presents a Credential to a remote Relying Party according to OpenID4VP Draft 20. In this scenario the user-agent and the Wallet Instance can be used in the same device (Same Device Flow), or in different devices (Cross Device Flow).

  • +
  • Proximity Flow, where the User presents a Credential to a Verifier App according to ISO 18013-5. The User interacts with a Verifier using proximity connection technologies such as QR Code and Bluetooth Low Energy (BLE).

  • +
+
+

Remote Flow

+

In this flow the Relying Party MUST provide the URL where the signed presentation Request Object is available for download.

+

Depending on whether the User is using a mobile device or a workstation, the Relying Party MUST support the following remote flows:

+
    +
  • Same Device, the Relying Party MUST provide a HTTP redirect (302) location to the Wallet Instance;

  • +
  • Cross Device, the Relying Party MUST provide a QR Code which the User frames with the Wallet Instance.

  • +
+

Once the Wallet Instance establishes the trust with the Relying Party and evaluates the request, the User gives the consent for the disclosure of the Digital Credentials, in the form of a Verifiable Presentation.

+

A High-Level description of the remote flow, from the User's perspective, is given below:

+
+
    +
  1. the Wallet Instance obtains an URL in the Same Device flow or a QR Code containing the URL in Cross Device flow;

  2. +
  3. the Wallet Instance extracts from the payload the following parameters: client_id, request_uri, state, request_uri_method and client_id_scheme;

  4. +
  5. If the client_id_scheme is provided and set with the value entity_id, the Wallet Instance MUST collect and validate the OpenID Federation Trust Chain related to the Relying Party. If the client_id_scheme is either not provided or is assigned a value different from entity_id, the Wallet Instance MUST establish the trust by utilizing the client_id or an alternative client_id_scheme value. This alternative value MUST enable the Wallet Instance to establish trust with the Relying Party, ensuring compliance with the assurance levels mandated by the trust framework;

  6. +
  7. If request_uri_method is provided and set with the value post, the Wallet Instance SHOULD transmit its metadata to the Relying Party's request_uri endpoint using the HTTP POST method and obtain the signed Request Object. If request_uri_method is set with the value get or not present, the Wallet Instance MUST fetch the signed Request Object using an HTTP request with method GET to the endpoint provided in the request_uri parameter;

  8. +
  9. the Wallet Instance verifies the signature of the signed Request Object, using the public key identifier within the Request Object JWT header parameter to select the correct public key obtained within Trust Chain related to the RP;

  10. +
  11. the Wallet Instance verifies that the client_id contained in the Request Object issuer (RP) matches with the one obtained at the step number 2 and with the sub parameter contained in the RP's Entity Configuration within the Trust Chain;

  12. +
  13. the Wallet Instance evaluates the requested Digital Credentials and checks the elegibility of the Relying Party in asking these by applying the policies related to that specific Relying Party, obtained with the trust chain;

  14. +
  15. the Wallet Instance asks User disclosure and consent;

  16. +
  17. the Wallet Instance presents the requested information to the Relying Party along with the Wallet Attestation. The Relying Party validates the presented Credentials checking the trust with their Issuers, and validates the Wallet Attestation by also checking that the Wallet Provider is trusted;

  18. +
  19. the Wallet Instance informs the User about the successfull authentication with the Relying Party, the User continues the navigation.

  20. +
+
+

Below a sequence diagram that summarizes the interactions between all the involved parties.

+
+_images/cross_device_auth_seq_diagram.svg +
+

Fig. 5 Remote Protocol Flow

+
+
+

The details of each step shown in the previous picture are described in the table below.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Id

Description

1, 2

The User requests to access to a protected resource of the Relying Party.

3, 4,

The Relying Party provides the Wallet Instance with a URL where the information about the Relying Party are provided, along with the information about where the signed request is available for download.

5, 6, 7, 8, 9

In the Cross Device Flow, the Request URI is presented as a QR Code displayed to the User. The User scans the QR Code using the Wallet Instance, which retrieves a URL with the parameters client_id, request_uri, state, client_id_scheme, and request_uri_method. Conversely, in the Same Device Flow, the Relying Party supplies identical information as in the Cross-Device flow, but directly through a URL.

10,

The Wallet Instance evaluates the trust with the Relying Party.

11, 12

The Wallet Instance checks if the Relying Party has provided the request_uri_method within its signed Request Object. If provided and it is equal to post, the Wallet Instance provides its metadata to the Relying Party. The Relying Party returns a signed Request Object compliant to the Wallet technical capabilities.

13

When the Wallet Instance capabilities discovery is not supported by RP, the Wallet Instance request the signed Request Object using the HTTP method GET.

14

The RP issues the Request Object signin it using one of its cryptographic private keys, where their public parts have been published within its Entity Configuration (metadata.wallet_relying_party.jwks). The Wallet Instance obtains the signed Request Object.

15, 16, 17

The Request Object JWS is verified by the Wallet Instance. The Wallet Instance processes the Relying Party metadata and applies the policies related to the Relying Party, attesting whose Digital Credentials and User data the Relying Party is granted to request.

18, 19

The Wallet Instance requests the User's consent for the release of the Credentials. The User authorizes and consents the presentation of the Credentials by selecting/deselecting the personal data to release.

20

The Wallet Instance provides the Authorization Response to the Relying Party using an HTTP request with the method POST (response mode "direct_post.jwt").

21, 22, 23, 24, 25

The Relying Party verifies the Authorization Response, extracts the Wallet Attestation to establish the trust with the Wallet Solution. The Relying Party extracts the Digital Credentials and attests the trust to the Credentials Issuer and the proof of possession of the Wallet Instance about the presented Digital Credentials. Finally, the Relying Party verifies the revocation status of the presented Digital Credentials.

26 (Same Device Flow only)

The Relying Party provides to the Wallet Instance a redirect URI with a response code to be used by the Wallet Instance to finalize the authentication.

27, 28 and 29

The User is informed by the Wallet Instance that the Autentication succeded, then the protected resource is made available to the User.

+
+

Request URI with HTTP POST

+

The Relying Party SHOULD provide the POST method with its request_uri endpoint +allowing the Wallet Instance to inform the Relying Party about its technical capabilities.

+

This feature can be useful when, for example, the Wallet Instance supports +a restricted set of features, supported algorithms or a specific url for +its authorization_endpoint, and any other information that it deems necessary to +provide to the Relying Party for better interoperability.

+
+

Warning

+

The Wallet Instance, when providing its technical capabilities to the +Relying Party, MUST NOT include any User information or other explicit +information regarding the hardware used or usage preferences of its User.

+
+

If both the Relying Party and the Wallet Instance +support the request_uri_method with HTTP POST, +the Wallet Instance capabilities (metadata) MUST +be provided using an HTTP request to the request_uri endpoint of the Relying Party, +with the method POST and content type set to application/json.

+

A non-normative example of the HTTP request is represented below:

+
POST /request-uri HTTP/1.1
+HOST: relying-party.example.org
+Content-Type: application/json
+
+{
+    "authorization_endpoint": "https://wallet-solution.digital-strategy.europa.eu/authorization",
+    "response_types_supported": [
+      "vp_token"
+    ],
+    "response_modes_supported": [
+      "form_post.jwt"
+    ],
+    "vp_formats_supported": {
+      "vc+sd-jwt": {
+          "sd-jwt_alg_values": [
+              "ES256",
+              "ES384"
+          ]
+      }
+    },
+    "request_object_signing_alg_values_supported": [
+      "ES256"
+    ],
+    "presentation_definition_uri_supported": false
+}
+
+
+

The response of the Relying Party is defined in the section below.

+
+
+

Authorization Request Details

+

The Relying Party MUST create a Request Object in the form of a signed JWT and +MUST provide it to the Wallet Instance through an HTTP URL (request URI). +The HTTP URL points to the web resource where the signed Request Object is +available for download. The URL parameters contained in the Relying Party +response, containing the request URI, are described in the Table below.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

Name

Description

client_id

REQUIRED. Unique identifier of the Relying Party.

request_uri

REQUIRED. The HTTPs URL where the Relying Party provides the signed Request Object to the Wallet Instance.

client_id_scheme

OPTIONAL. The scheme used by the Relying Party for the client_id, detailing the format and structure and the trust evaluation method. It SHOULD be set with entity_id.

state

OPTIONAL. A unique identifier for the current transaction generated by the Relying Party. The value SHOULD be opaque to the Wallet Instance.

request_uri_method

OPTIONAL. The HTTP method MUST be set with get or post. The Wallet Instance should use this method to obtain the signed Request Object from the request_uri. If not provided or equal to get, the Wallet Instance SHOULD use the HTTP method get. Otherwise, the Wallet Instance SHOULD provide its metadata within the HTTP POST body encoded in application/json.

+

Below a non-normative example of the response containing the required parameters previously described.

+
https://wallet-solution.digital-strategy.europa.eu/authorization?client_id=...&request_uri=...&client_id_scheme=entity_id&request_uri_method=post
+
+
+

The value corresponding to the request_uri endpoint SHOULD be randomized, according to RFC 9101, The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR) Section 5.2.1.

+

In the Same Device Flow the Relying Party uses an HTTP response redirect (with status code set to 302) as represented in the following non-normative example:

+
HTTP/1.1 /authorization Found
+Location: https://wallet-solution.digital-strategy.europa.eu?
+client_id=https%3A%2F%2Frelying-party.example.org%2Fcb
+&request_uri=https%3A%2F%2Frelying-party.example.org%2Frequest_uri
+&client_id_scheme=entity_id
+&request_uri_method=post
+
+
+

In the Cross Device Flow, a QR Code is shown by the Relying Party to the User in order to provide the Authorization Request. The User frames the QR Code using their Wallet Instance.

+

Below is represented a non-normative example of a QR Code issued by the Relying Party.

+
+_images/verifier_qr_code.svg +
+

Below is represented a non-normative example of the QR Code raw payload:

+
https://wallet-solution.digital-strategy.europa.eu/authorization?client_id=https%3A%2F%2Frelying-party.example.org&request_uri=https%3A%2F%2Frelying-party.example.org&client_id_scheme=entity_id&request_uri_method=post
+
+
+
+

Note

+

The error correction level chosen for the QR Code MUST be Q (Quartily - up to 25%), since it offers a good balance between error correction capability and data density/space. This level of quality and error correction allows the QR Code to remain readable even if it is damaged or partially obscured.

+
+
+
+

Cross Device Flow Status Checks and Security

+

When the flow is Cross Device, the user-agent needs to check the session status to the endpoint made available by Relying Party (status endpoint). This check MAY be implemented in the form of JavaScript code, within the page that shows the QRCode, then the user-agent checks the status with a polling strategy in seconds or a push strategy (eg: web socket).

+

Since the QRcode page and the status endpoint are implemented by the Relying Party, it is under the Relying Party responsability the implementation details of this solution, since it is related to the Relying Party's internal API. However, the text below describes an implementation example.

+

The Relying Party binds the request of the user-agent, with a session cookie marked as Secure and HttpOnly, with the issued request. The request url SHOULD include a parameter with a random value. The HTTP response returned by this specialized endpoint MAY contain the HTTP status codes listed below:

+
    +
  • 201 Created. The signed Request Object was issued by the Relying Party that waits to be downloaded by the Wallet Instance at the request_uri endpoint.

  • +
  • 202 Accepted. This response is given when the signed Request Object was obtained by the Wallet Instance.

  • +
  • 200 OK. The Wallet Instance has provided the presentation to the Relying Party's response_uri endpoint and the User authentication is successful. The Relying Party updates the session cookie allowing the user-agent to access to the protected resource. An URL is provided carrying the location where the user-agent is intended to navigate.

  • +
  • 401 Unauthorized. The Wallet Instance or its User have rejected the request, or the request is expired. The QRCode page SHOULD be updated with an error message.

  • +
+

Below a non-normative example of the HTTP Request to this specialized endpoint, where the parameter id contains an opaque and random value:

+
GET /session-state?id=3be39b69-6ac1-41aa-921b-3e6c07ddcb03
+HTTP/1.1
+HOST: relying-party.example.org
+
+
+
+
+

Request Object Details

+

Below a non-normative example of HTTP request made by the Wallet Instance to the Relying Party.

+
GET /request_uri HTTP/1.1
+HOST: relying-party.example.org
+
+
+
+
+

Request URI Response

+

The Relying Party issues the signed Request Object using the content type set to application/oauth-authz-req+jwt, +where a non-normative example in the form of decoded header and payload is shown below:

+
{
+  "alg": "ES256",
+  "typ": "JWT",
+  "kid": "9tjiCaivhWLVUJ3AxwGGz_9",
+  "trust_chain": [
+    "MIICajCCAdOgAwIBAgIC...awz",
+    "MIICajCCAdOgAwIBAgIC...2w3",
+    "MIICajCCAdOgAwIBAgIC...sf2"
+  ]
+}
+.
+{
+  "scope": "PersonIdentificationData WalletAttestation",
+  "client_id_scheme": "entity_id",
+  "client_id": "https://relying-party.example.org",
+  "response_mode": "direct_post.jwt",
+  "response_type": "vp_token",
+  "response_uri": "https://relying-party.example.org/response_uri",
+  "nonce": "2c128e4d-fc91-4cd3-86b8-18bdea0988cb",
+  "state": "3be39b69-6ac1-41aa-921b-3e6c07ddcb03",
+  "iss": "https://relying-party.example.org",
+  "iat": 1672418465,
+  "exp": 1672422065,
+  "request_uri_method": "post"
+}
+
+
+

The JWS header parameters are described below:

+ ++++ + + + + + + + + + + + + + + + + + + + +

Name

Description

alg

Algorithm used to sign the JWT, according to [RFC 7516#section-4.1.1]. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to none or to a symmetric algorithm (MAC) identifier.

typ

Media Type of the JWT, as defined in [RFC 7519].

kid

Key ID of the public key needed to verify the JWS signature, as defined in [RFC 7517]. REQUIRED when trust_chain is used.

trust_chain

Sequence of Entity Statements that composes the Trust Chain related to the Relying Party, as defined in OID-FED Section 3.2.1. Trust Chain Header Parameter.

+

The JWS payload parameters are described herein:

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Description

scope

Aliases for well-defined Presentation Definitions IDs. It is used to identify which required Credentials and User attributes are requested by the Relying Party, according to the Section "Using scope Parameter to Request Verifiable Credential(s)" of [OID4VP].

client_id_scheme

String identifying the scheme of the value in the client_id. It MUST be set to the value entity_id.

client_id

Unique Identifier of the Relying Party.

response_mode

It MUST be set to direct_post.jwt.

response_type

It MUST be set to vp_token.

response_uri

The Response URI to which the Wallet Instance MUST send the Authorization Response using an HTTP request using the method POST.

nonce

Fresh cryptographically random number with sufficient entropy, which length MUST be at least 32 digits.

state

Unique identifier of the Authorization Request.

iss

The entity that has issued the JWT. It will be populated with the Relying Party client id.

iat

Unix Timestamp, representing the time at which the JWT was issued.

exp

Unix Timestamp, representing the expiration time on or after which the JWT MUST NOT be valid anymore.

request_uri_method

String determining the HTTP method to be used with the request_uri endpoint to provide the Wallet Instance metadata to the Relying Party. The value is case-insensitive and can be set to: get or post. The GET method, as defined in [@RFC9101], involves the Wallet Instance sending a GET request to retrieve a Request Object. The POST method involves the Wallet Instance requesting the creation of a new Request Object by sending an HTTP POST request, with its metadata, to the request URI of the Relying Party.

+
+

Warning

+

Using the parameter scope requires that the Relying Party Metadata MUST contain the presentation_definition, where a non-normative example of it is given below:

+
+
{
+    "id": "presentation definitions",
+    "input_descriptors": [
+        {
+			"id": "eu.europa.ec.eudiw.pid.it.1",
+            "name": "Person Identification Data",
+            "purpose": "User authentication",
+			"group": [
+                "group1"
+            ],
+			"format": {
+                "vc+sd-jwt": {
+                    "alg": [
+                        "ES256",
+                        "ES384",
+                        "ES512"
+                    ]
+                }
+            },
+            "constraints": {
+                "limit_disclosure": "preferred",
+                "fields": [
+                    {
+                        "filter": {
+                            "const": "unique_id",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.unique_id"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "given_name",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.given_name"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "family_name",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.family_name"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "bith_date",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.bith_date"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "tax_id_code",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.tax_id_code"
+                        ]
+                    }
+                ]
+            }
+        },
+        {
+			"id": "WalletAttestation",
+            "name": "Wallet Attestation",
+            "purpose": "Wallet Authentication",
+			"format": "jwt",
+            "group": [
+                "group2"
+            ],
+            "constraints": {
+                "fields": [
+                    {
+                        "filter": {
+                            "enum": [
+                                "https://issuer.example.org"
+                            ],
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.iss"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "minimum": 1504700136,
+                            "type": "number"
+                        },
+                        "path": [
+                            "$.exp"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "minimum": 1504700136,
+                            "type": "number"
+                        },
+                        "path": [
+                            "$.iat"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "type": "object"
+                        },
+                        "path": [
+                            "$.cnf.jwk"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "aal",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.aal"
+                        ]
+                    }
+                ]
+            }
+        }
+    ],
+    "submission_requirements": [
+        {
+			"name": "Sample requirement",
+            "count": 1,
+			"rule": "pick",
+            "from": "group1"
+        }
+    ]
+}
+
+
+
+

Note

+

The following parameters, even if defined in [OID4VP], are not mentioned in the previous non-normative example, since their usage is conditional and may change in future release of this documentation.

+
    +
  • presentation_definition: JSON object according to Presentation Exchange. This parameter MUST not be present when presentation_definition_uri or scope are present.

  • +
  • presentation_definition_uri: Not supported. String containing an HTTPS URL pointing to a resource where a Presentation Definition JSON object can be retrieved. This parameter MUST be present when presentation_definition parameter or a scope value representing a Presentation Definition is not present.

  • +
  • client_metadata: A JSON object containing the Relying Party metadata values. If the client_metadata parameter is present when client_id_scheme is entity_id, the Wallet Instance MUST consider the client metadata obtained through the OpenID Federation Trust Chain.

  • +
+
+
+

Request URI Endpoint Errors

+

When the Relying Party encounters errors while issuing the Request Object from the request_uri endpoint, the following error responses are applicable:

+
    +
  • invalid_request: The request_uri URL is missing in some part within its webpath or urlparams, therefore it does not point to a valid Request Object and then it cannot be retrieved. This error is returned when the Request Object is not well referenced in the request_uri.

  • +
  • server_error: The server encountered an unexpected condition that prevented it from fulfilling the request. This error is returned when the Relying Party's server is unable to process the Request Object due to a server-side issue, such as a malfunction or maintenance. The Wallet Instance should advise the User to try again later.

  • +
+

The following is an example of an error response from request_uri endpoint:

+
HTTP/1.1 400 Bad Request
+Content-Type: application/json
+
+{
+ "error": "invalid_request",
+ "error_description": "The request_uri is malformed or does not point to a valid Request Object."
+}
+
+
+

Another example:

+
HTTP/1.1 500 Internal Server Error
+Content-Type: application/json
+
+{
+ "error": "server_error",
+ "error_description": "The request_uri cannot be retrieved due to an internal server error."
+}
+
+
+

There are cases where the Wallet Instance cannot validate the Request Object or the Request Object results invalid. This error occurs if the Request Object is successfully fetched from the request_uri but fails validation checks by the Wallet Instance. This could be due to incorrect signatures, malformed claims, or other validation failures, such as the revocation of its issuer (Relying Party).

+

Upon receiving an error response, the Wallet Instance SHOULD inform the User of the error condition in an appropriate manner. Additionally, the Wallet Instance SHOULD log the error and MAY attempt to recover from certain errors if feasible. For example, if the error is server_error, the Wallet Instance MAY prompt the User to re-enter or scan a new QR code, if applicable.

+

It is crucial for Wallet Instances to implement robust error handling to maintain a secure and user-friendly experience. Adhering to the specified error responses ensures interoperability and helps in diagnosing issues during the interaction with the Relying Party's endpoints.

+
+

Warning

+

The current OpenID4VP specification outlines various error responses that a Wallet Instance may return to the Relying Party (Verifier) in case of faulty requests (OpenID4VP, Section 6.4. Error Response). For privacy enhancement, Wallet Instances SHOULD NOT notify the Relying Party of faulty requests in certain scenarios. This is to prevent any potential misuse of error responses that could lead to gather informations that could be exploited.

+
+
+
+
+

Authorization Response Details

+

After getting the User authorization and consent for the presentation of the Credentials, the Wallet Instance sends the Authorization Response to the Relying Party response_uri endpoint, the content SHOULD be encrypted according OpenID4VP Section 6.3, using the Relying Party public key.

+
+

Note

+

Why the response is encrypted?

+

The response sent from the Wallet Instance to the Relying Party is encrypted to prevent a malicious agent from gaining access to the plaintext information transmitted within the Relying Party's network. This is only possible if the network environment of the Relying Party employs TLS termination. Such technique employs a termination proxy that acts as an intermediary between the client and the webserver and handles all TLS-related operations. In this manner, the proxy deciphers the transmission's content and either forwards it in plaintext or by negotiates an internal TLS session with the actual webserver's intended target. In the first scenario, any malicious actor within the network segment could intercept the transmitted data and obtain sensitive information, such as an unencrypted response, by sniffing the transmitted data.

+
+

Below a non-normative example of the request:

+
POST /response_uri HTTP/1.1
+HOST: relying-party.example.org
+Content-Type: application/x-www-form-urlencoded
+
+response=eyJhbGciOiJFUzI1NiIs...9t2LQ
+
+
+

Below is a non-normative example of the decrypted payload of the JWT contained in the response, before base64url encoding:

+
{
+  "state": "3be39b69-6ac1-41aa-921b-3e6c07ddcb03",
+  "vp_token": [
+      "eyJhbGciOiJFUzI1NiIs...PT0iXX0",
+      $WalletAttestation-JWT
+  ],
+  "presentation_submission": {
+      "definition_id": "32f54163-7166-48f1-93d8-ff217bdb0653",
+      "id": "04a98be3-7fb0-4cf5-af9a-31579c8b0e7d",
+      "descriptor_map": [
+          {
+              "id": "PersonIdentificationData",
+              "path": "$.vp_token[0]",
+              "format": "vc+sd-jwt"
+          },
+          {
+              "id": "WalletAttestation",
+              "path": "$.vp_token[1]",
+              "format": "wallet-attestation+jwt"
+          }
+      ]
+  }
+}
+
+
+

Where the following parameters are used:

+ ++++ + + + + + + + + + + + + + + + + +

Name

Description

vp_token

JSON Array containing the Verifiable Presentation(s). There MUST be at least two signed presentations in this Array:

+
    +
  • The requested Digital Credential (one or more, in format of SD-JWT VC)

  • +
  • The Wallet Attestation

  • +
+

presentation_submission

JSON Object containing the mappings between the requested Verifiable Credentials and where to find them within the returned Verifiable Presentation Token, according to the Presentation Exchange. This is expressed via elements in the descriptor_map array (Input Descriptor Mapping Objects) that contain a field called path, which MUST have the value $ (top level root path) when only one Verifiable Presentation is contained in the VP Token, and MUST have the value $[n] (indexed path from root) when there are multiple Verifiable Presentations, where n is the index to select. The Relying Party receiving the presentation_submission descriptor therefore is able to use the correct method to decode each credential data format provided within the vp_token.

state

Unique identifier provided by the Relying Party within the Authorization Request.

+

The items contained in the vp_token array are Verifiable Presentations of Credentials.

+
+
+

SD-JWT Presentation

+

SD-JWT defines how an Holder can present a Credential to a Verifier proving the legitimate possession +of the Credential. For doing this the Holder MUST include the KB-JWT in the SD-JWT, +by appending the KB-JWT at the end of the of the SD-JWT, as represented in the example below:

+
<Issuer-Signed-JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure N>~<KB-JWT>
+
+
+

To validate the signature on the Key Binding JWT, the Verifier MUST use the key material included in the Issuer-Signed-JWT. +The Key Binding JWT (KB-JWT) signature validation MUST use the public key included in the SD-JWT, +using the cnf parameter contained in the Issuer-Signed-JWT.

+

When an SD-JWT is presented, its KB-JWT MUST contain the following parameters in the JWS header:

+ ++++ + + + + + + + + + + + + + +

Claim

Description

typ

REQUIRED. MUST be kb+jwt, which explicitly types the Key Binding JWT as recommended in Section 3.11 of [RFC8725].

alg

REQUIRED. Signature Algorithm using one of the specified in the section Cryptographic Algorithms.

+

When an SD-JWT is presented, its KB-JWT MUST contain the following parameters in the JWS payload:

+ ++++ + + + + + + + + + + + + + + + + + + + +

Claim

Description

iat

REQUIRED. The value of this claim MUST be the time at which the Key Binding JWT was issued, using the syntax defined in [RFC7519].

aud

REQUIRED. The intended receiver of the Key Binding JWT. The value of this parameter MUST match the Relying Party unique entity identifier.

nonce

REQUIRED. Ensures the freshness of the signature. The value type of this claim MUST be a string. The value MUST match with the one provided in the request object.

sd_hash

REQUIRED. The base64url-encoded hash digest over the Issuer-signed JWT and the selected disclosures.

+
+

Revocation Checks

+

The revocation mechanisms that the Relying Parties MUST implement are defined in the section (Revocations).

+

In the context of Digital Credential evaluation, any Relying Parties (RPs) establishes internal policies that define the meaning and value of presented Credentials. This is particularly important in scenarios where a Credential may be suspended but still holds value for certain purposes. For example, a suspended mobile driving license might still be valid for verifying the age of the holder.

+

The process begins with the RP requesting specific Credentials from the Holder. This request should align with the Relying Party's requirements and the context in which the Credentials will be used. The Holder then responds by releasing the requested Credentials.

+

Upon receiving the Credentials, the Relying Party evaluates their validity and value based on its internal policies. This evaluation considers the current status of the Credential (e.g., active, suspended, revoked) and the specific use case for which the Credential is being presented.

+

Relying Parties should develop comprehensive internal policies that outline how different types of Credentials are to be evaluated. These policies should address scenarios where a Credential may be partially valid or have limited applicability. Flexibility in evaluation processes is important to accommodate various use cases. For instance, a Credential that is suspended for driving purposes might still be acceptable for age verification.

+
+
+

Authorization Response Errors

+

When the Wallet sends a response using direct_post.jwt to the Relying Party, several errors may occur, including:

+
+
    +
  • Invalid Credential: This error occurs when one or more Credentials or VPs, included in the vp_token, fail validation because they are malformed. The correct HTTP status code for this error is 400 (Bad Request). The error should be set to invalid_request, and the error_description SHOULD identify the malformed Credentials.

  • +
  • Issuer Credential Trust Failure: This error arises when the Relying Party cannot establish trust with the issuer of a presented Credential, included in the vp_token. The appropriate HTTP status code for this error is 403 (Forbidden). The error should be labeled as invalid_request, and the error_description SHOULD specify the issuer for which trust could not be established.

  • +
  • Invalid Nonce: This error happens when the nonce provided in the request is incorrect. The HTTP status code for this error should be 403 (Forbidden). The error SHOULD be labeled as invalid_request, with an error_description indicating that the nonce is incorrect.

  • +
  • Invalid Wallet Attestation: This error occours when it's not possible to establish trust with the Wallet Attestation's issuer (Wallet Provider), or if the Wallet Attestation is invalid or does not meet the Relying Party's minimum security criteria. The correct HTTP status code for this error is 403 (Forbidden). The error SHOULD be marked as invalid_request, and the error_description should clarify that the issue stems from the Wallet Attestation's failure to establish trust with its issuer or its non-compliance with required security standards.

  • +
  • Invalid Presentation Submission: This error occurs when the presentation submission is not valid. The appropriate HTTP status code for this error is 400 Bad Request. The error should be labeled as invalid_request, and the error_description should specify the invalid aspects of the presentation submission.

  • +
+

To enhance clarity and ensure proper error handling, it's crucial to provide detailed error responses. Below are two examples of HTTP responses using application/json that include both the error and error_description members:

+
+
HTTP/1.1 403 Forbidden
+Content-Type: application/json
+
+{
+  "error": "invalid_request",
+  "error_description": "Trust cannot be established with the issuer: https://issuer.example.com"
+}
+
+
+
HTTP/1.1 400 Bad Request
+Content-Type: application/json
+
+{
+  "error": "invalid_request",
+  "error_description": "The following Credentials/VP are malformed: [CredentialX, vp_token[2]]"
+}
+
+
+
+
+
+

Redirect URI

+

When the Relying Party provides the redirect URI, the Wallet Instance MUST send the user-agent to this redirect URI. The redirect URI allows the Relying Party to continue the interaction with the End-User on the device where the Wallet Instance resides after the Wallet Instance has sent the Authorization Response to the response URI.

+

The Relying Party MUST include a response code within the redirect URI. The response code is a fresh, cryptographically random number used to ensure only the receiver of the redirect can fetch and process the Authorization Response. The number could be added as a path component, as a parameter or as a fragment to the URL. It is RECOMMENDED to use a cryptographic random value of 128 bits or more at the time of the writing of this specification.

+

The following is a non-normative example of the response from the Relying Party to the Wallet Instance upon receiving the Authorization Response at the Response Endpoint.

+
HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+  "redirect_uri": "https://relying-party.example.org/cb?response_code=091535f699ea575c7937fa5f0f454aee"
+}
+
+
+

The redirect_uri value MUST be used with an HTTP method GET by either the Wallet Instance or the user-agent to redirect the User to the Relying Party in order to complete the process. The value can be added as a path component, as a fragment or as a parameter to the URL according to Section 6.2 of OpenID4VP. The specific entity that performs this action depends on whether the flow is Same device or Cross device.

+
+
+

Redirect URI Errors

+

When the Wallet Instance sends the user-agent to the Redirect URI provided by the Relying Party, several errors may occur that prevent the successful completion of the process. These errors are critical as they directly impact the User experience by hindering the seamless flow of information between the Wallet Instance and the Relying Party. Below are potential errors related to the Redirect URI and their implications:

+
    +
  • Mismatched Redirect URI: This error occurs when the Redirect URI provided by the Relying Party does not match any of the URIs linked with the User session. This mismatch can lead to a HTTP status error code set to 403 (Forbidden), indicating that the request cannot be processed due session/URI mismatch.

  • +
  • Redirect URI Security Issues: If the Relying Party incurs in security issues when evaluating the User session with the provided URI, the Relying Party MUST raise an error. In such cases, an HTTP status code set to 403 (Forbidden) MUST be returned, indicating that the request is valid but the server is refusing action due to security precautions.

  • +
+

Handling these errors requires clear communication to the User within the returned navigation web page. It is crucial for the Relying Party to implement robust error handling and validation mechanisms for Redirect URIs to ensure a secure implementation.

+
+
+
+

Proximity Flow

+

This section describes how a Verifier requests the presentation of an mDoc-CBOR Credential to a Wallet Instance according to the ISO 18013-5 Specification. Only Supervised Device Retrieval flow is supported in this technical implementation profile.

+

The presentation phase is divided into three sub-phases:

+
+

1. Device Engagement: This subphase begins when the User is prompted to disclose certain attributes from the mDoc(s). The objective of this subphase is to establish a secure communication channel between the Wallet Instance and the Verifier App, so that the mDoc requests and responses can be exchanged during the communication subphase. +The messages exchanged in this subphase are transmitted through short-range technologies to limit the possibility of interception and eavesdropping. +This technical implementation profile exclusively supports QR code for Device Engagement.

+

2. Session establishment: During the session establishment phase, the Verifier App sets up a secure connection. All data transmitted over this connection is encrypted using a session key, which is known to both the Wallet Instance and the Verifier at this stage. +The established session MAY be terminated based on the conditions as detailed in [ISO18013-5#9.1.1.4].

+

3. Communication - Device Retrieval: The Verifier App encrypts the mDoc request with the appropriate session key and sends it to the Wallet Instance together with its public key in a session establishment message. The mDoc uses the data from the session establishment message to derive the session key and decrypt the mDoc request. +During the communication subphase, the Verifier App has the option to request information from the Wallet using mDoc requests and responses. The primary mode of communication is the secure channel established during the session setup. The Wallet Instance encrypts the mDoc response using the session key and transmits it to the Verifier App via a session data message. This technical implementation profile only supports Bluetooth Low Energy (BLE) for the communication sub-phase.

+
+

The following figure illustrates the flow diagram compliant with ISO 18013-5 for proximity flow.

+
+_images/High-Level-Flow-ITWallet-Presentation-ISO.svg +
+

Fig. 6 High-Level Proximity Flow

+
+
+

Step 1-3: The Verifier requests the User to reveal certain attributes from their mDoc(s) stored in the Wallet Instance. The User initiates the Wallet Instance. The Wallet Instance MUST create a new temporary key pair (EDeviceKey.Priv, EDeviceKey.Pub), and incorporate the cipher suite identifier, the identifier of the elliptic curve for key agreement, and the EDeviceKey public point into the device engagement structure (refer to [ISO18013-5#9.1.1.4]). This key pair is temporary and MUST be invalidated immediately after the secure channel is established. Finally, the Wallet Instance displays the QR Code for Device Engagement.

+

Below an example of a device engagement structure that utilizes QR for device engagement and Bluetooth Low Energy (BLE) for data retrieval.

+

CBOR data:

+
a30063312e30018201d818584ba4010220012158205a88d182bce5f42efa59943f33359d2e8a968ff289d93e5fa444b624343167fe225820b16e8cf858ddc7690407ba61d4c338237a8cfcf3de6aa672fc60a557aa32fc670281830201a300f401f50b5045efef742b2c4837a9a3b0e1d05a6917
+
+
+

In diagnostic notation:

+
{
+  0: "1.0", % Version
+
+  1:        % Security
+  [
+      1,     % defines the cipher suite 1 which contains only EC curves
+      24(<<  % embedded CBOR data item
+        {
+          1: 2, % kty:EC2 (Elliptic curves with x and y coordinate pairs)
+        -1: 1, % crv:p256
+-2:h'5A88D182BCE5F42EFA59943F33359D2E8A968FF289D93E5FA444B624343  167FE',% x-coordinate
+-3:h'B16E8CF858DDC7690407BA61D4C338237A8CFCF3DE6AA672FC60A557AA32FC67' % y-coordinate
+        }
+      >>)
+    ],
+
+    2: %DeviceRetrievalMethods(Device engagement using QR code)
+    [
+      [
+        2, %BLE
+        1, % Version
+      {    %BLE options
+          0: false, % no support for mdoc peripheral server mode
+          1: true, % support mdoc central client mode
+          11: h'45EFEF742B2C4837A9A3B0E1D05A6917' % UUID of mdoc client central mode
+        }
+      ]
+    ]
+}
+
+
+

Step 4-6: The Verifier App scans the QR Code and generates its own ephemeral key pair (EReaderKey.Priv, EReaderKey.Pub). It then calculates the session key, using the public key received in the Engagement Structure and its newly-generated private key, as outlined in [ISO18013-5#9.1.1.5]. Finally, it generates its session key, which must be independently derived by both the Wallet Instance and the Verifier App.

+

Step 7: The Verifier App creates an mDoc request that MUST be encrypted using the relevant session key, and transmits it to the Wallet Instance along with EReaderKey.Pub within a session establishment message. The mDoc request MUST be encoded in CBOR, as demonstrated in the following non-normative example.

+

CBOR data: +.. code-block:

+
a26776657273696f6e63312e306b646f63526571756573747381a26c6974656d7352657175657374d818590152a267646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e4954a375766572696669636174696f6e2e65766964656e6365f4781c766572696669636174696f6e2e6173737572616e63655f6c6576656cf4781c766572696669636174696f6e2e74727573745f6672616d65776f726bf4716f72672e69736f2e31383031332e352e31ab76756e5f64697374696e6775697368696e675f7369676ef47264726976696e675f70726976696c65676573f46f646f63756d656e745f6e756d626572f46a69737375655f64617465f46f69737375696e675f636f756e747279f47169737375696e675f617574686f72697479f46a62697274685f64617465f46b6578706972795f64617465f46a676976656e5f6e616d65f468706f727472616974f46b66616d696c795f6e616d65f46a726561646572417574688443a10126a11821590129308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97bf6584058a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9
+
+
+

The above CBOR data is represented in diagnostic notation as follows: +.. code-block:

+
{
+  "version": "1.0",
+  "docRequests": [
+  {
+    "itemsRequest": 24(<< {
+      "docType": "org.iso.18013.5.1.mDL",
+      "nameSpaces": {
+        "org.iso.18013.5.1.IT": {
+          "verification.evidence": false,
+          "verification.assurance_level": false,
+          "verification.trust_framework": false
+        },
+        "org.iso.18013.5.1": {
+          "un_distinguishing_sign": false,
+          "driving_privileges": false,
+          "document_number": false,
+          "issue_date": false,
+          "issuing_country": false,
+          "issuing_authority": false,
+          "birth_date": false,
+          "expiry_date": false,
+          "given_name": false,
+          "portrait": false,
+          "family_name": false
+        }
+      }
+    } >>),
+    "readerAuth": [
+      h'a10126',
+      {
+        33: h'308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97b'
+      },
+      null,
+      h'58a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9'
+    ]
+  }
+  ]
+}
+
+
+

Step 8: The Wallet Instance uses the session establishment message to derive the session keys and decrypt the mDoc request. It computes the session key using the public key received from the Verifier App and its private key.

+

Step 9-10: When the Wallet Instance receives the mDoc request, it locates the documents that contain the requested attributes and asks the User for permission to provide this information to the Verifier. If the User agrees, the Wallet generates an mDoc response and transmits it to the Verifier App through the secure channel.

+

Step 11-12: If the User gives consent, the Wallet Instance creates an mDoc response and transmits it to the Verifier App via the secure channel. The mDoc response MUST be encoded in CBOR, with its structure outlined in [ISO18013-5#8.3.2.1.2.2]. Below is a non-normative example of an mDoc response.

+

CBOR Data: +.. code-block:

+
a36776657273696f6e63312e3069646f63756d656e747381a367646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6c6973737565725369676e6564a26a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e495483d81858f7a46864696765737449440b6672616e646f6d506d44f21ee875f2c1d502b43198e5a15271656c656d656e744964656e74696669657275766572696669636174696f6e2e65766964656e63656c656c656d656e7456616c756581a2647479706571656c656374726f6e69635f7265636f7264667265636f7264bf6474797065781f68747470733a2f2f657564692e77616c6c65742e70646e642e676f762e697466736f75726365bf716f7267616e697a6174696f6e5f6e616d65754d6f746f72697a7a617a696f6e6520436976696c656f6f7267616e697a6174696f6e5f6964656d5f696e666c636f756e7472795f636f6465626974ffffd8185866a4686469676573744944046672616e646f6d50185d84dfb71ce9b173010ddd62174fbe71656c656d656e744964656e746966696572781c766572696669636174696f6e2e74727573745f6672616d65776f726b6c656c656d656e7456616c7565656569646173d8185865a4686469676573744944006672616e646f6d50137f903174253c4585358267aae2ea4e71656c656d656e744964656e746966696572781c766572696669636174696f6e2e6173737572616e63655f6c6576656c6c656c656d656e7456616c75656468696768716f72672e69736f2e31383031332e352e318bd8185852a46864696765737449440c6672616e646f6d5053e29d0ddbbc7d2306a32bdbe2e56e5171656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756563446f65d8185855a4686469676573744944036672616e646f6d50990cba2069fa1b33b8d6ae910b6549dc71656c656d656e744964656e7469666965726a676976656e5f6e616d656c656c656d656e7456616c756567416e746f6e696fd818585ba46864696765737449440a6672616e646f6d504086c1379975f805f1b1f4975e6a126571656c656d656e744964656e7469666965726a69737375655f646174656c656c656d656e7456616c7565d903ec6a323031392d31302d3230d818585ca4686469676573744944016672616e646f6d50ab4ca30c918dd2fd0bf35242c15fa2d871656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d31302d3230d8185855a4686469676573744944076672616e646f6d508d9066f6c8da16619867cd4e2fab0c8871656c656d656e744964656e7469666965726f69737375696e675f636f756e7472796c656c656d656e7456616c7565624954d818587ea4686469676573744944056672616e646f6d5059fe68db795dee4c20976380ea24770571656c656d656e744964656e7469666965727169737375696e675f617574686f726974796c656c656d656e7456616c75657828497374697475746f20506f6c696772616669636f2065205a656363612064656c6c6f20537461746fd818585ba4686469676573744944026672616e646f6d5008b3f1ca5517019767be3dee3bb0614571656c656d656e744964656e7469666965726a62697274685f646174656c656c656d656e7456616c7565d903ec6a313935362d30312d3230d818585ca4686469676573744944096672616e646f6d50a2395ec214350c26066306e23279b3ae71656c656d656e744964656e7469666965726f646f63756d656e745f6e756d6265726c656c656d656e7456616c756569393837363534333231d8185850a4686469676573744944066672616e646f6d50a25e1a5b915d2d6eafee9674e023293971656c656d656e744964656e74696669657268706f7274726169746c656c656d656e7456616c75654420212223d81858eea46864696765737449440d6672616e646f6d50eeed6a3b856563627589a360939d12f771656c656d656e744964656e7469666965727264726976696e675f70726976696c656765736c656c656d656e7456616c756582a37576656869636c655f63617465676f72795f636f646561416a69737375655f64617465d903ec6a323031382d30382d30396b6578706972795f64617465d903ec6a323032342d31302d3230a37576656869636c655f63617465676f72795f636f646561426a69737375655f64617465d903ec6a323031372d30322d32336b6578706972795f64617465d903ec6a323032342d31302d3230d818585ba4686469676573744944086672616e646f6d50c0ef486b2a194ed3cbf7f354fd40092171656c656d656e744964656e74696669657276756e5f64697374696e6775697368696e675f7369676e6c656c656d656e7456616c756561496a697373756572417574688443a10126a118215901423082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb
+
+
+

In diagnostic notation: +.. code-block:

+
{
+  "version": "1.0",
+  "documents": [
+  {
+    "docType": "org.iso.18013.5.1.mDL",
+    "issuerSigned": {
+      "nameSpaces": {
+        "org.iso.18013.5.1.IT": [
+          24(<< {
+            "digestID": 11,
+            "random": h'6d44f21ee875f2c1d502b43198e5a152',
+            "elementIdentifier": "verification.evidence",
+            "elementValue": [
+              {
+                "type": "electronic_record",
+                "record": {
+                  "type": "https://eudi.wallet.pdnd.gov.it",
+                  "source": {
+                    "organization_name": "Motorizzazione Civile",
+                    "organization_id": "m_inf",
+                    "country_code": "it"
+                  }
+                }
+              }
+            ]
+          } >>),
+          24(<< {
+            "digestID": 4,
+            "random": h'185d84dfb71ce9b173010ddd62174fbe',
+            "elementIdentifier": "verification.trust_framework",
+            "elementValue": "eidas"
+          } >>),
+          24(<< {
+            "digestID": 0,
+            "random": h'137f903174253c4585358267aae2ea4e',
+            "elementIdentifier": "verification.assurance_level",
+            "elementValue": "high"
+          } >>)
+        ],
+        "org.iso.18013.5.1": [
+          24(<< {
+            "digestID": 12,
+            "random": h'53e29d0ddbbc7d2306a32bdbe2e56e51',
+            "elementIdentifier": "family_name",
+            "elementValue": "Doe"
+          } >>),
+          24(<< {
+            "digestID": 3,
+            "random": h'990cba2069fa1b33b8d6ae910b6549dc',
+            "elementIdentifier": "given_name",
+            "elementValue": "Antonio"
+          } >>),
+          24(<< {
+            "digestID": 10,
+            "random": h'4086c1379975f805f1b1f4975e6a1265',
+            "elementIdentifier": "issue_date",
+            "elementValue": 1004("2019-10-20")
+          } >>),
+          24(<< {
+            "digestID": 1,
+            "random": h'ab4ca30c918dd2fd0bf35242c15fa2d8',
+            "elementIdentifier": "expiry_date",
+            "elementValue": 1004("2024-10-20")
+          } >>),
+          24(<< {
+            "digestID": 7,
+            "random": h'8d9066f6c8da16619867cd4e2fab0c88',
+            "elementIdentifier": "issuing_country",
+            "elementValue": "IT"
+          } >>),
+          24(<< {
+            "digestID": 5,
+            "random": h'59fe68db795dee4c20976380ea247705',
+            "elementIdentifier": "issuing_authority",
+            "elementValue": "Istituto Poligrafico e Zecca dello Stato"
+          } >>),
+          24(<< {
+            "digestID": 2,
+            "random": h'08b3f1ca5517019767be3dee3bb06145',
+            "elementIdentifier": "birth_date",
+            "elementValue": 1004("1956-01-20")
+          } >>),
+          24(<< {
+            "digestID": 9,
+            "random": h'a2395ec214350c26066306e23279b3ae',
+            "elementIdentifier": "document_number",
+            "elementValue": "987654321"
+          } >>),
+          24(<< {
+            "digestID": 6,
+            "random": h'a25e1a5b915d2d6eafee9674e0232939',
+            "elementIdentifier": "portrait",
+            "elementValue": h'20212223'
+          } >>),
+          24(<< {
+            "digestID": 13,
+            "random": h'eeed6a3b856563627589a360939d12f7',
+            "elementIdentifier": "driving_privileges",
+            "elementValue": [
+              {
+                "vehicle_category_code": "A",
+                "issue_date": 1004("2018-08-09"),
+                "expiry_date": 1004("2024-10-20")
+              },
+              {
+                "vehicle_category_code": "B",
+                "issue_date": 1004("2017-02-23"),
+                "expiry_date": 1004("2024-10-20")
+              }
+            ]
+          } >>),
+          24(<< {
+            "digestID": 8,
+            "random": h'c0ef486b2a194ed3cbf7f354fd400921',
+            "elementIdentifier": "un_distinguishing_sign",
+            "elementValue": "I"
+          } >>)
+        ]
+      },
+      "issuerAuth": [
+        h'a10126',
+        {
+          33: h'3082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb7d518bd9a519583e082d67effff06565804fc09abf0e4a08e699c9dba3796285a15f68e40ac7f9fc7700a15153a4065300a06082a8648ce3d040302034800304502210099b7d62e6bf7b1823db3713df889bf73e70bb4d9c58c21e92c58d2f1beffe932022058d039747a00d70e6d66be4797e6142b3608a014ee09b7b79af2cae2aaf27788'
+        },
+        24(<< {
+      "version": "1.0",
+      "digestAlgorithm": "SHA-256",
+      "docType": "org.iso.18013.5.1.mDL",
+      "valueDigests": {
+        "org.iso.18013.5.1": {
+        1: h'0E5F0B6B33418E508740771E82F893372EAF5B2445BC4C84DCF08B005E9493FC',
+        2: h'DE21BB62FF2897D8B986D2CDA9F9BC5865C02807F7B4D9DD1FA4A79DF4C0D37F',
+        3: h'BC5568239E35CE9FF8798C27FFDCD757B134B679F0FE05729AA3491381912E65',
+        5: h'E6048BDC7FD6454296F1E3F54536107C9C5B24C4064DE46A98121E3630EECCA2',
+        6: h'73690D92DCAA61B0203870F67C6AA9FDFEA889B6F0C720DE757B4B0A8516A206',
+        7: h'E353EA0B0FD92B6BE90C64CC3B2EE1284153A8F0F5066B99AAC599200E6EEEB2',
+        8: h'29227872CEB49923D267B5F4BADE6D387B42AC2DC4B2AE26C9013067FEE7018A',
+        9: h'A6A119F7CACAC0B8C6AACAC747FD3FE7E50B6D9BB8A507FDA79F0DF6646F285D',
+        10: h'6D8025D2F02A5E7E1406FB6AAEB67F9EDE9B07191A53F3E23B77C528223A94E2',
+        12: h'B0D43E4E2EA534E4D5304E64BCF7A0F13E2C8EE8304B9CD23ABA4909652A4647',
+        13: h'FBF4DE318982F2DBAD43C601CAEB22628B301AC18AA8264C5831B2AAAC89C486'
+        },
+        "org.iso.18013.5.1.IT": {
+        0: h'CF57377B675F64F37314739592C1E8A911A7DDAF341CE2902FE877C5A835E4C1',
+        4: h'4A4B4CC64EC9299C1A2501EA449F577005E9F7A60408057C07A7C67FB151E5F5',
+        11: h'78824FBD6FBBA88A2AAB44DF8B6F5E9759126D87D1F4415995E658FD9239E1FE'
+        }
+      },
+      "deviceKeyInfo": {
+        "deviceKey": {
+        1: 2,
+        -1: 1,
+        -2: h'AFD09E720B918CEDC2B8A881950BAB6A1051E18AE16A814D51E609938663D5E1',
+        -3: h'61FBC6C8AD24EC86A78BB4E9AC377DD2B7C711D9F2EB9AFD4AA0963662847AED'}},
+        "validityInfo": {
+          "signed": 0("2023-11-24T14:54:05Z"),
+          "validFrom": 0("2023-11-24T14:54:05Z"),
+          "validUntil": 0("2024-11-24T14:54:05Z")}
+        }  >>),
+        h'f2461e4fab69e9f7bcffe552395424514524d1679440036213173101448d1b1ab4a293859b389ffa8b47aeed10e9b0c1545412ac37c51a76482cd9bbbe110152'
+      ]
+    },
+    "deviceSigned": {
+      "nameSpaces": 24(<< {} >>),
+      "deviceAuth": {
+        "deviceSignature": [
+          h'a10126',
+          {},
+          null,
+          h'1fed7190d2975ab79c072e6f1d9d52436059d1fc959d55baf74f057d89b10fcc0dc77a50d433d4c76ddf26223c5560c4ab123b5cb5eb805a90036aa147493076'
+        ]
+      }
+    }
+  }
+  ],
+  "status": 0
+}
+
+
+

Step 13: The Verifier App is required to validate the signatures in the mDoc's issuerSigned field using the public key of the Credential Issuer specified within the mDoc. Subsequently, the Verifier MUST validate the signature in the deviceSigned field. If these signature checks pass, the Verifier can confidently consider the received information as valid.

+
+

Device Engagement

+

The Device Engagement structure MUST be have at least the following components:

+
+
    +
  • Version: tstr. Version of the data structure being used.

  • +
  • Security: an array that contains two mandatory values

    +
      +
    • the cipher identifier: see Table 22 of [ISO18013-5]

    • +
    • the mDL public ephemeral key generated by the Wallet Instance and required by the Verifier App to derive the Session Key. The mDL public ephemeral key MUST be of a type allowed by the indicated cipher suite.

    • +
    +
  • +
  • transferMethod: an array that contains one or more transferMethod arrays when performing device engagement using the QR code. This array is for offline data retrieval methods. A transferMethod array holds two mandatory values (type and version). Only the BLE option is supported by this technical implementation profile, then the type value MUST be set to 2.

  • +
  • BleOptions: this elements MUST provide options for the BLE connection (support for Peripheral Server or Central Client Mode, and the device UUID).

  • +
+
+
+
+

mDoc Request

+

The messages in the mDoc Request MUST be encoded using CBOR. The resulting CBOR byte string for the mDoc Request MUST be encrypted with the Session Key obtained after the Device Engagement phase and MUST be transmitted using the BLE protocol. +The details on the structure of mDoc Request, including identifier and format of the data elements, are provided below.

+
+
    +
  • version: (tstr). Version of the data structure.

  • +
  • docRequests: Requested DocType, NameSpace and data elements.

    +
      +
    • itemsRequest: #6.24(bstr .cbor ItemsRequest).

      +
        +
      • docType: (tstr). The DocType element contains the type of document requested. See Data Model Section.

      • +
      • nameSpaces: (tstr). See Data Model Section for more details.

        +
          +
        • dataElements: (tstr). Requested data elements with Intent to Retain value for each requested element.

          +
            +
          • IntentToRetain: (bool). It indicates that the Verifier App intends to retain the received data element.

          • +
          +
        • +
        +
      • +
      +
    • +
    • readerAuth: COSE_Sign1. It is required for the Verifier App authentication.

    • +
    +
  • +
+
+
+

Note

+

The domestic data elements MUST not be returned unless specifically requested by the Verifier App.

+
+
+
+

mDoc Response

+

The messages in the mDoc Response MUST be encoded using CBOR and MUST be encrypted with the Session Key obtained after the Device Engagement phase. +The details on the structure of mDoc Response are provided below.

+
+
    +
  • version: (tstr). Version of the data structure.

  • +
  • documents: Returned DocType, and ResponseData.

    +
      +
    • docType: (tstr). The DocType element contains the type of document returned. See Data Model Section.

    • +
    • ResponseData:

      +
        +
      • IssuerSigned: Responded data elements signed by the issuer.

        +
          +
        • nameSpaces: (tstr). See Data Model Section for more details.

          +
            +
          • IssuerSignedItemBytes: #6.24(bstr .cbor).

            +
              +
            • digestID: (uint). Reference value to one of the ValueDigests provided in the Mobile Security Object (issuerAuth).

            • +
            • random: (bstr). Random byte value used as salt for the hash function. This value SHALL be different for each IssuerSignedItem and it SHALL have a minimum length of 16 bytes.

            • +
            • elementIdentifier: (tstr). Identifier of User attribute name contained in the Credential.

            • +
            • elementValue: (any). User attribute value

            • +
            +
          • +
          +
        • +
        +
      • +
      • DeviceSigned: Responded data elements signed by the Wallet Instance.

        +
          +
        • NameSpaces: #6.24(bstr .cbor DeviceNameSpaces). The DeviceNameSpaces structure MAY be an empty structure. DeviceNameSpaces contains the data element identifiers and values. It is returned as part of the corresponding namespace in DeviceNameSpace.

          +
            +
          • DataItemName: (tstr). The identifier of the element.

          • +
          • DataItemValue: (any). The value of the element.

          • +
          +
        • +
        • DeviceAuth: The DeviceAuth structure MUST contain the DeviceSignature elements.

          +
            +
          • DeviceSignature: It MUST contain the device signature for the Wallet Instance authentication.

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • status: It contains a status code. For detailed description and action required refer to to Table 8 (ResponseStatus) of the [ISO18013-5]

  • +
+
+
+
+

Session Termination

+

The session MUST be terminated if at least one of the following conditions occur.

+
+
    +
  • After a time-out of no activity of receiving or sending session establishment or session data messages occurs. The time-out for no activity implemented by the Wallet Instance and the Verifier App SHOULD be no less than 300 seconds.

  • +
  • When the Wallet Instance doesn't accept any more requests.

  • +
  • When the Verifier App does not send any further requests.

  • +
+
+

If the Wallet Instance and the Verifier App does not send or receive any further requests, the session termination MUST be initiated as follows.

+
+
    +
  • Send the status code for session termination, or

  • +
  • dispatch the "End" command as outlined in [ISO18013-5#8.3.3.1.1.5].

  • +
+
+

When a session is terminated, the Wallet Instance and the Verifier App MUST perform at least the following actions:

+
+
    +
  • destruction of session keys and related ephemeral key material;

  • +
  • closure of the communication channel used for data retrieval.

  • +
+
+
+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/remote-flow.html b/refs/pull/443/merge/en/remote-flow.html new file mode 100644 index 000000000..8e11f000b --- /dev/null +++ b/refs/pull/443/merge/en/remote-flow.html @@ -0,0 +1,933 @@ + + + + + + + + Remote Flow — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Remote Flow

+

In this flow the Relying Party MUST provide the URL where the signed presentation Request Object is available for download.

+

Depending on whether the User is using a mobile device or a workstation, the Relying Party MUST support the following remote flows:

+
    +
  • Same Device, the Relying Party MUST provide a HTTP redirect (302) location to the Wallet Instance;

  • +
  • Cross Device, the Relying Party MUST provide a QR Code which the User frames with the Wallet Instance.

  • +
+

Once the Wallet Instance establishes the trust with the Relying Party and evaluates the request, the User gives the consent for the disclosure of the Digital Credentials, in the form of a Verifiable Presentation.

+

A High-Level description of the remote flow, from the User's perspective, is given below:

+
+
    +
  1. the Wallet Instance obtains an URL in the Same Device flow or a QR Code containing the URL in Cross Device flow;

  2. +
  3. the Wallet Instance extracts from the payload the following parameters: client_id, request_uri, state, request_uri_method and client_id_scheme;

  4. +
  5. If the client_id_scheme is provided and set with the value entity_id, the Wallet Instance MUST collect and validate the OpenID Federation Trust Chain related to the Relying Party. If the client_id_scheme is either not provided or is assigned a value different from entity_id, the Wallet Instance MUST establish the trust by utilizing the client_id or an alternative client_id_scheme value. This alternative value MUST enable the Wallet Instance to establish trust with the Relying Party, ensuring compliance with the assurance levels mandated by the trust framework;

  6. +
  7. If request_uri_method is provided and set with the value post, the Wallet Instance SHOULD transmit its metadata to the Relying Party's request_uri endpoint using the HTTP POST method and obtain the signed Request Object. If request_uri_method is set with the value get or not present, the Wallet Instance MUST fetch the signed Request Object using an HTTP request with method GET to the endpoint provided in the request_uri parameter;

  8. +
  9. the Wallet Instance verifies the signature of the signed Request Object, using the public key identifier within the Request Object JWT header parameter to select the correct public key obtained within Trust Chain related to the RP;

  10. +
  11. the Wallet Instance verifies that the client_id contained in the Request Object issuer (RP) matches with the one obtained at the step number 2 and with the sub parameter contained in the RP's Entity Configuration within the Trust Chain;

  12. +
  13. the Wallet Instance evaluates the requested Digital Credentials and checks the elegibility of the Relying Party in asking these by applying the policies related to that specific Relying Party, obtained with the trust chain;

  14. +
  15. the Wallet Instance asks User disclosure and consent;

  16. +
  17. the Wallet Instance presents the requested information to the Relying Party along with the Wallet Attestation. The Relying Party validates the presented Credentials checking the trust with their Issuers, and validates the Wallet Attestation by also checking that the Wallet Provider is trusted;

  18. +
  19. the Wallet Instance informs the User about the successfull authentication with the Relying Party, the User continues the navigation.

  20. +
+
+

Below a sequence diagram that summarizes the interactions between all the involved parties.

+
+_images/cross_device_auth_seq_diagram.svg +
+

Remote Protocol Flow

+
+
+

The details of each step shown in the previous picture are described in the table below.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Id

Description

1, 2

The User requests to access to a protected resource of the Relying Party.

3, 4,

The Relying Party provides the Wallet Instance with a URL where the information about the Relying Party are provided, along with the information about where the signed request is available for download.

5, 6, 7, 8, 9

In the Cross Device Flow, the Request URI is presented as a QR Code displayed to the User. The User scans the QR Code using the Wallet Instance, which retrieves a URL with the parameters client_id, request_uri, state, client_id_scheme, and request_uri_method. Conversely, in the Same Device Flow, the Relying Party supplies identical information as in the Cross-Device flow, but directly through a URL.

10,

The Wallet Instance evaluates the trust with the Relying Party.

11, 12

The Wallet Instance checks if the Relying Party has provided the request_uri_method within its signed Request Object. If provided and it is equal to post, the Wallet Instance provides its metadata to the Relying Party. The Relying Party returns a signed Request Object compliant to the Wallet technical capabilities.

13

When the Wallet Instance capabilities discovery is not supported by RP, the Wallet Instance request the signed Request Object using the HTTP method GET.

14

The RP issues the Request Object signin it using one of its cryptographic private keys, where their public parts have been published within its Entity Configuration (metadata.wallet_relying_party.jwks). The Wallet Instance obtains the signed Request Object.

15, 16, 17

The Request Object JWS is verified by the Wallet Instance. The Wallet Instance processes the Relying Party metadata and applies the policies related to the Relying Party, attesting whose Digital Credentials and User data the Relying Party is granted to request.

18, 19

The Wallet Instance requests the User's consent for the release of the Credentials. The User authorizes and consents the presentation of the Credentials by selecting/deselecting the personal data to release.

20

The Wallet Instance provides the Authorization Response to the Relying Party using an HTTP request with the method POST (response mode "direct_post.jwt").

21, 22, 23, 24, 25

The Relying Party verifies the Authorization Response, extracts the Wallet Attestation to establish the trust with the Wallet Solution. The Relying Party extracts the Digital Credentials and attests the trust to the Credentials Issuer and the proof of possession of the Wallet Instance about the presented Digital Credentials. Finally, the Relying Party verifies the revocation status of the presented Digital Credentials.

26 (Same Device Flow only)

The Relying Party provides to the Wallet Instance a redirect URI with a response code to be used by the Wallet Instance to finalize the authentication.

27, 28 and 29

The User is informed by the Wallet Instance that the Autentication succeded, then the protected resource is made available to the User.

+
+

Request URI with HTTP POST

+

The Relying Party SHOULD provide the POST method with its request_uri endpoint +allowing the Wallet Instance to inform the Relying Party about its technical capabilities.

+

This feature can be useful when, for example, the Wallet Instance supports +a restricted set of features, supported algorithms or a specific url for +its authorization_endpoint, and any other information that it deems necessary to +provide to the Relying Party for better interoperability.

+
+

Warning

+

The Wallet Instance, when providing its technical capabilities to the +Relying Party, MUST NOT include any User information or other explicit +information regarding the hardware used or usage preferences of its User.

+
+

If both the Relying Party and the Wallet Instance +support the request_uri_method with HTTP POST, +the Wallet Instance capabilities (metadata) MUST +be provided using an HTTP request to the request_uri endpoint of the Relying Party, +with the method POST and content type set to application/json.

+

A non-normative example of the HTTP request is represented below:

+
POST /request-uri HTTP/1.1
+HOST: relying-party.example.org
+Content-Type: application/json
+
+{
+    "authorization_endpoint": "https://wallet-solution.digital-strategy.europa.eu/authorization",
+    "response_types_supported": [
+      "vp_token"
+    ],
+    "response_modes_supported": [
+      "form_post.jwt"
+    ],
+    "vp_formats_supported": {
+      "vc+sd-jwt": {
+          "sd-jwt_alg_values": [
+              "ES256",
+              "ES384"
+          ]
+      }
+    },
+    "request_object_signing_alg_values_supported": [
+      "ES256"
+    ],
+    "presentation_definition_uri_supported": false
+}
+
+
+

The response of the Relying Party is defined in the section below.

+
+
+

Authorization Request Details

+

The Relying Party MUST create a Request Object in the form of a signed JWT and +MUST provide it to the Wallet Instance through an HTTP URL (request URI). +The HTTP URL points to the web resource where the signed Request Object is +available for download. The URL parameters contained in the Relying Party +response, containing the request URI, are described in the Table below.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

Name

Description

client_id

REQUIRED. Unique identifier of the Relying Party.

request_uri

REQUIRED. The HTTPs URL where the Relying Party provides the signed Request Object to the Wallet Instance.

client_id_scheme

OPTIONAL. The scheme used by the Relying Party for the client_id, detailing the format and structure and the trust evaluation method. It SHOULD be set with entity_id.

state

OPTIONAL. A unique identifier for the current transaction generated by the Relying Party. The value SHOULD be opaque to the Wallet Instance.

request_uri_method

OPTIONAL. The HTTP method MUST be set with get or post. The Wallet Instance should use this method to obtain the signed Request Object from the request_uri. If not provided or equal to get, the Wallet Instance SHOULD use the HTTP method get. Otherwise, the Wallet Instance SHOULD provide its metadata within the HTTP POST body encoded in application/json.

+

Below a non-normative example of the response containing the required parameters previously described.

+
https://wallet-solution.digital-strategy.europa.eu/authorization?client_id=...&request_uri=...&client_id_scheme=entity_id&request_uri_method=post
+
+
+

The value corresponding to the request_uri endpoint SHOULD be randomized, according to RFC 9101, The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR) Section 5.2.1.

+

In the Same Device Flow the Relying Party uses an HTTP response redirect (with status code set to 302) as represented in the following non-normative example:

+
HTTP/1.1 /authorization Found
+Location: https://wallet-solution.digital-strategy.europa.eu?
+client_id=https%3A%2F%2Frelying-party.example.org%2Fcb
+&request_uri=https%3A%2F%2Frelying-party.example.org%2Frequest_uri
+&client_id_scheme=entity_id
+&request_uri_method=post
+
+
+

In the Cross Device Flow, a QR Code is shown by the Relying Party to the User in order to provide the Authorization Request. The User frames the QR Code using their Wallet Instance.

+

Below is represented a non-normative example of a QR Code issued by the Relying Party.

+
+_images/verifier_qr_code.svg +
+

Below is represented a non-normative example of the QR Code raw payload:

+
https://wallet-solution.digital-strategy.europa.eu/authorization?client_id=https%3A%2F%2Frelying-party.example.org&request_uri=https%3A%2F%2Frelying-party.example.org&client_id_scheme=entity_id&request_uri_method=post
+
+
+
+

Note

+

The error correction level chosen for the QR Code MUST be Q (Quartily - up to 25%), since it offers a good balance between error correction capability and data density/space. This level of quality and error correction allows the QR Code to remain readable even if it is damaged or partially obscured.

+
+
+
+

Cross Device Flow Status Checks and Security

+

When the flow is Cross Device, the user-agent needs to check the session status to the endpoint made available by Relying Party (status endpoint). This check MAY be implemented in the form of JavaScript code, within the page that shows the QRCode, then the user-agent checks the status with a polling strategy in seconds or a push strategy (eg: web socket).

+

Since the QRcode page and the status endpoint are implemented by the Relying Party, it is under the Relying Party responsability the implementation details of this solution, since it is related to the Relying Party's internal API. However, the text below describes an implementation example.

+

The Relying Party binds the request of the user-agent, with a session cookie marked as Secure and HttpOnly, with the issued request. The request url SHOULD include a parameter with a random value. The HTTP response returned by this specialized endpoint MAY contain the HTTP status codes listed below:

+
    +
  • 201 Created. The signed Request Object was issued by the Relying Party that waits to be downloaded by the Wallet Instance at the request_uri endpoint.

  • +
  • 202 Accepted. This response is given when the signed Request Object was obtained by the Wallet Instance.

  • +
  • 200 OK. The Wallet Instance has provided the presentation to the Relying Party's response_uri endpoint and the User authentication is successful. The Relying Party updates the session cookie allowing the user-agent to access to the protected resource. An URL is provided carrying the location where the user-agent is intended to navigate.

  • +
  • 401 Unauthorized. The Wallet Instance or its User have rejected the request, or the request is expired. The QRCode page SHOULD be updated with an error message.

  • +
+

Below a non-normative example of the HTTP Request to this specialized endpoint, where the parameter id contains an opaque and random value:

+
GET /session-state?id=3be39b69-6ac1-41aa-921b-3e6c07ddcb03
+HTTP/1.1
+HOST: relying-party.example.org
+
+
+
+
+

Request Object Details

+

Below a non-normative example of HTTP request made by the Wallet Instance to the Relying Party.

+
GET /request_uri HTTP/1.1
+HOST: relying-party.example.org
+
+
+
+
+

Request URI Response

+

The Relying Party issues the signed Request Object using the content type set to application/oauth-authz-req+jwt, +where a non-normative example in the form of decoded header and payload is shown below:

+
{
+  "alg": "ES256",
+  "typ": "JWT",
+  "kid": "9tjiCaivhWLVUJ3AxwGGz_9",
+  "trust_chain": [
+    "MIICajCCAdOgAwIBAgIC...awz",
+    "MIICajCCAdOgAwIBAgIC...2w3",
+    "MIICajCCAdOgAwIBAgIC...sf2"
+  ]
+}
+.
+{
+  "scope": "PersonIdentificationData WalletAttestation",
+  "client_id_scheme": "entity_id",
+  "client_id": "https://relying-party.example.org",
+  "response_mode": "direct_post.jwt",
+  "response_type": "vp_token",
+  "response_uri": "https://relying-party.example.org/response_uri",
+  "nonce": "2c128e4d-fc91-4cd3-86b8-18bdea0988cb",
+  "state": "3be39b69-6ac1-41aa-921b-3e6c07ddcb03",
+  "iss": "https://relying-party.example.org",
+  "iat": 1672418465,
+  "exp": 1672422065,
+  "request_uri_method": "post"
+}
+
+
+

The JWS header parameters are described below:

+ ++++ + + + + + + + + + + + + + + + + + + + +

Name

Description

alg

Algorithm used to sign the JWT, according to [RFC 7516#section-4.1.1]. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to none or to a symmetric algorithm (MAC) identifier.

typ

Media Type of the JWT, as defined in [RFC 7519].

kid

Key ID of the public key needed to verify the JWS signature, as defined in [RFC 7517]. REQUIRED when trust_chain is used.

trust_chain

Sequence of Entity Statements that composes the Trust Chain related to the Relying Party, as defined in OID-FED Section 3.2.1. Trust Chain Header Parameter.

+

The JWS payload parameters are described herein:

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Description

scope

Aliases for well-defined Presentation Definitions IDs. It is used to identify which required Credentials and User attributes are requested by the Relying Party, according to the Section "Using scope Parameter to Request Verifiable Credential(s)" of [OID4VP].

client_id_scheme

String identifying the scheme of the value in the client_id. It MUST be set to the value entity_id.

client_id

Unique Identifier of the Relying Party.

response_mode

It MUST be set to direct_post.jwt.

response_type

It MUST be set to vp_token.

response_uri

The Response URI to which the Wallet Instance MUST send the Authorization Response using an HTTP request using the method POST.

nonce

Fresh cryptographically random number with sufficient entropy, which length MUST be at least 32 digits.

state

Unique identifier of the Authorization Request.

iss

The entity that has issued the JWT. It will be populated with the Relying Party client id.

iat

Unix Timestamp, representing the time at which the JWT was issued.

exp

Unix Timestamp, representing the expiration time on or after which the JWT MUST NOT be valid anymore.

request_uri_method

String determining the HTTP method to be used with the request_uri endpoint to provide the Wallet Instance metadata to the Relying Party. The value is case-insensitive and can be set to: get or post. The GET method, as defined in [@RFC9101], involves the Wallet Instance sending a GET request to retrieve a Request Object. The POST method involves the Wallet Instance requesting the creation of a new Request Object by sending an HTTP POST request, with its metadata, to the request URI of the Relying Party.

+
+

Warning

+

Using the parameter scope requires that the Relying Party Metadata MUST contain the presentation_definition, where a non-normative example of it is given below:

+
+
{
+    "id": "presentation definitions",
+    "input_descriptors": [
+        {
+			"id": "eu.europa.ec.eudiw.pid.it.1",
+            "name": "Person Identification Data",
+            "purpose": "User authentication",
+			"group": [
+                "group1"
+            ],
+			"format": {
+                "vc+sd-jwt": {
+                    "alg": [
+                        "ES256",
+                        "ES384",
+                        "ES512"
+                    ]
+                }
+            },
+            "constraints": {
+                "limit_disclosure": "preferred",
+                "fields": [
+                    {
+                        "filter": {
+                            "const": "unique_id",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.unique_id"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "given_name",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.given_name"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "family_name",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.family_name"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "bith_date",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.bith_date"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "tax_id_code",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.credentialSubject.tax_id_code"
+                        ]
+                    }
+                ]
+            }
+        },
+        {
+			"id": "WalletAttestation",
+            "name": "Wallet Attestation",
+            "purpose": "Wallet Authentication",
+			"format": "jwt",
+            "group": [
+                "group2"
+            ],
+            "constraints": {
+                "fields": [
+                    {
+                        "filter": {
+                            "enum": [
+                                "https://issuer.example.org"
+                            ],
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.iss"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "minimum": 1504700136,
+                            "type": "number"
+                        },
+                        "path": [
+                            "$.exp"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "minimum": 1504700136,
+                            "type": "number"
+                        },
+                        "path": [
+                            "$.iat"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "type": "object"
+                        },
+                        "path": [
+                            "$.cnf.jwk"
+                        ]
+                    },
+                    {
+                        "filter": {
+                            "const": "aal",
+                            "type": "string"
+                        },
+                        "path": [
+                            "$.aal"
+                        ]
+                    }
+                ]
+            }
+        }
+    ],
+    "submission_requirements": [
+        {
+			"name": "Sample requirement",
+            "count": 1,
+			"rule": "pick",
+            "from": "group1"
+        }
+    ]
+}
+
+
+
+

Note

+

The following parameters, even if defined in [OID4VP], are not mentioned in the previous non-normative example, since their usage is conditional and may change in future release of this documentation.

+
    +
  • presentation_definition: JSON object according to Presentation Exchange. This parameter MUST not be present when presentation_definition_uri or scope are present.

  • +
  • presentation_definition_uri: Not supported. String containing an HTTPS URL pointing to a resource where a Presentation Definition JSON object can be retrieved. This parameter MUST be present when presentation_definition parameter or a scope value representing a Presentation Definition is not present.

  • +
  • client_metadata: A JSON object containing the Relying Party metadata values. If the client_metadata parameter is present when client_id_scheme is entity_id, the Wallet Instance MUST consider the client metadata obtained through the OpenID Federation Trust Chain.

  • +
+
+
+

Request URI Endpoint Errors

+

When the Relying Party encounters errors while issuing the Request Object from the request_uri endpoint, the following error responses are applicable:

+
    +
  • invalid_request: The request_uri URL is missing in some part within its webpath or urlparams, therefore it does not point to a valid Request Object and then it cannot be retrieved. This error is returned when the Request Object is not well referenced in the request_uri.

  • +
  • server_error: The server encountered an unexpected condition that prevented it from fulfilling the request. This error is returned when the Relying Party's server is unable to process the Request Object due to a server-side issue, such as a malfunction or maintenance. The Wallet Instance should advise the User to try again later.

  • +
+

The following is an example of an error response from request_uri endpoint:

+
HTTP/1.1 400 Bad Request
+Content-Type: application/json
+
+{
+ "error": "invalid_request",
+ "error_description": "The request_uri is malformed or does not point to a valid Request Object."
+}
+
+
+

Another example:

+
HTTP/1.1 500 Internal Server Error
+Content-Type: application/json
+
+{
+ "error": "server_error",
+ "error_description": "The request_uri cannot be retrieved due to an internal server error."
+}
+
+
+

There are cases where the Wallet Instance cannot validate the Request Object or the Request Object results invalid. This error occurs if the Request Object is successfully fetched from the request_uri but fails validation checks by the Wallet Instance. This could be due to incorrect signatures, malformed claims, or other validation failures, such as the revocation of its issuer (Relying Party).

+

Upon receiving an error response, the Wallet Instance SHOULD inform the User of the error condition in an appropriate manner. Additionally, the Wallet Instance SHOULD log the error and MAY attempt to recover from certain errors if feasible. For example, if the error is server_error, the Wallet Instance MAY prompt the User to re-enter or scan a new QR code, if applicable.

+

It is crucial for Wallet Instances to implement robust error handling to maintain a secure and user-friendly experience. Adhering to the specified error responses ensures interoperability and helps in diagnosing issues during the interaction with the Relying Party's endpoints.

+
+

Warning

+

The current OpenID4VP specification outlines various error responses that a Wallet Instance may return to the Relying Party (Verifier) in case of faulty requests (OpenID4VP, Section 6.4. Error Response). For privacy enhancement, Wallet Instances SHOULD NOT notify the Relying Party of faulty requests in certain scenarios. This is to prevent any potential misuse of error responses that could lead to gather informations that could be exploited.

+
+
+
+
+

Authorization Response Details

+

After getting the User authorization and consent for the presentation of the Credentials, the Wallet Instance sends the Authorization Response to the Relying Party response_uri endpoint, the content SHOULD be encrypted according OpenID4VP Section 6.3, using the Relying Party public key.

+
+

Note

+

Why the response is encrypted?

+

The response sent from the Wallet Instance to the Relying Party is encrypted to prevent a malicious agent from gaining access to the plaintext information transmitted within the Relying Party's network. This is only possible if the network environment of the Relying Party employs TLS termination. Such technique employs a termination proxy that acts as an intermediary between the client and the webserver and handles all TLS-related operations. In this manner, the proxy deciphers the transmission's content and either forwards it in plaintext or by negotiates an internal TLS session with the actual webserver's intended target. In the first scenario, any malicious actor within the network segment could intercept the transmitted data and obtain sensitive information, such as an unencrypted response, by sniffing the transmitted data.

+
+

Below a non-normative example of the request:

+
POST /response_uri HTTP/1.1
+HOST: relying-party.example.org
+Content-Type: application/x-www-form-urlencoded
+
+response=eyJhbGciOiJFUzI1NiIs...9t2LQ
+
+
+

Below is a non-normative example of the decrypted payload of the JWT contained in the response, before base64url encoding:

+
{
+  "state": "3be39b69-6ac1-41aa-921b-3e6c07ddcb03",
+  "vp_token": [
+      "eyJhbGciOiJFUzI1NiIs...PT0iXX0",
+      $WalletAttestation-JWT
+  ],
+  "presentation_submission": {
+      "definition_id": "32f54163-7166-48f1-93d8-ff217bdb0653",
+      "id": "04a98be3-7fb0-4cf5-af9a-31579c8b0e7d",
+      "descriptor_map": [
+          {
+              "id": "PersonIdentificationData",
+              "path": "$.vp_token[0]",
+              "format": "vc+sd-jwt"
+          },
+          {
+              "id": "WalletAttestation",
+              "path": "$.vp_token[1]",
+              "format": "wallet-attestation+jwt"
+          }
+      ]
+  }
+}
+
+
+

Where the following parameters are used:

+ ++++ + + + + + + + + + + + + + + + + +

Name

Description

vp_token

JSON Array containing the Verifiable Presentation(s). There MUST be at least two signed presentations in this Array:

+
    +
  • The requested Digital Credential (one or more, in format of SD-JWT VC)

  • +
  • The Wallet Attestation

  • +
+

presentation_submission

JSON Object containing the mappings between the requested Verifiable Credentials and where to find them within the returned Verifiable Presentation Token, according to the Presentation Exchange. This is expressed via elements in the descriptor_map array (Input Descriptor Mapping Objects) that contain a field called path, which MUST have the value $ (top level root path) when only one Verifiable Presentation is contained in the VP Token, and MUST have the value $[n] (indexed path from root) when there are multiple Verifiable Presentations, where n is the index to select. The Relying Party receiving the presentation_submission descriptor therefore is able to use the correct method to decode each credential data format provided within the vp_token.

state

Unique identifier provided by the Relying Party within the Authorization Request.

+

The items contained in the vp_token array are Verifiable Presentations of Credentials.

+
+
+

SD-JWT Presentation

+

SD-JWT defines how an Holder can present a Credential to a Verifier proving the legitimate possession +of the Credential. For doing this the Holder MUST include the KB-JWT in the SD-JWT, +by appending the KB-JWT at the end of the of the SD-JWT, as represented in the example below:

+
<Issuer-Signed-JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure N>~<KB-JWT>
+
+
+

To validate the signature on the Key Binding JWT, the Verifier MUST use the key material included in the Issuer-Signed-JWT. +The Key Binding JWT (KB-JWT) signature validation MUST use the public key included in the SD-JWT, +using the cnf parameter contained in the Issuer-Signed-JWT.

+

When an SD-JWT is presented, its KB-JWT MUST contain the following parameters in the JWS header:

+ ++++ + + + + + + + + + + + + + +

Claim

Description

typ

REQUIRED. MUST be kb+jwt, which explicitly types the Key Binding JWT as recommended in Section 3.11 of [RFC8725].

alg

REQUIRED. Signature Algorithm using one of the specified in the section Cryptographic Algorithms.

+

When an SD-JWT is presented, its KB-JWT MUST contain the following parameters in the JWS payload:

+ ++++ + + + + + + + + + + + + + + + + + + + +

Claim

Description

iat

REQUIRED. The value of this claim MUST be the time at which the Key Binding JWT was issued, using the syntax defined in [RFC7519].

aud

REQUIRED. The intended receiver of the Key Binding JWT. The value of this parameter MUST match the Relying Party unique entity identifier.

nonce

REQUIRED. Ensures the freshness of the signature. The value type of this claim MUST be a string. The value MUST match with the one provided in the request object.

sd_hash

REQUIRED. The base64url-encoded hash digest over the Issuer-signed JWT and the selected disclosures.

+
+

Revocation Checks

+

The revocation mechanisms that the Relying Parties MUST implement are defined in the section (Revocations).

+

In the context of Digital Credential evaluation, any Relying Parties (RPs) establishes internal policies that define the meaning and value of presented Credentials. This is particularly important in scenarios where a Credential may be suspended but still holds value for certain purposes. For example, a suspended mobile driving license might still be valid for verifying the age of the holder.

+

The process begins with the RP requesting specific Credentials from the Holder. This request should align with the Relying Party's requirements and the context in which the Credentials will be used. The Holder then responds by releasing the requested Credentials.

+

Upon receiving the Credentials, the Relying Party evaluates their validity and value based on its internal policies. This evaluation considers the current status of the Credential (e.g., active, suspended, revoked) and the specific use case for which the Credential is being presented.

+

Relying Parties should develop comprehensive internal policies that outline how different types of Credentials are to be evaluated. These policies should address scenarios where a Credential may be partially valid or have limited applicability. Flexibility in evaluation processes is important to accommodate various use cases. For instance, a Credential that is suspended for driving purposes might still be acceptable for age verification.

+
+
+

Authorization Response Errors

+

When the Wallet sends a response using direct_post.jwt to the Relying Party, several errors may occur, including:

+
+
    +
  • Invalid Credential: This error occurs when one or more Credentials or VPs, included in the vp_token, fail validation because they are malformed. The correct HTTP status code for this error is 400 (Bad Request). The error should be set to invalid_request, and the error_description SHOULD identify the malformed Credentials.

  • +
  • Issuer Credential Trust Failure: This error arises when the Relying Party cannot establish trust with the issuer of a presented Credential, included in the vp_token. The appropriate HTTP status code for this error is 403 (Forbidden). The error should be labeled as invalid_request, and the error_description SHOULD specify the issuer for which trust could not be established.

  • +
  • Invalid Nonce: This error happens when the nonce provided in the request is incorrect. The HTTP status code for this error should be 403 (Forbidden). The error SHOULD be labeled as invalid_request, with an error_description indicating that the nonce is incorrect.

  • +
  • Invalid Wallet Attestation: This error occours when it's not possible to establish trust with the Wallet Attestation's issuer (Wallet Provider), or if the Wallet Attestation is invalid or does not meet the Relying Party's minimum security criteria. The correct HTTP status code for this error is 403 (Forbidden). The error SHOULD be marked as invalid_request, and the error_description should clarify that the issue stems from the Wallet Attestation's failure to establish trust with its issuer or its non-compliance with required security standards.

  • +
  • Invalid Presentation Submission: This error occurs when the presentation submission is not valid. The appropriate HTTP status code for this error is 400 Bad Request. The error should be labeled as invalid_request, and the error_description should specify the invalid aspects of the presentation submission.

  • +
+

To enhance clarity and ensure proper error handling, it's crucial to provide detailed error responses. Below are two examples of HTTP responses using application/json that include both the error and error_description members:

+
+
HTTP/1.1 403 Forbidden
+Content-Type: application/json
+
+{
+  "error": "invalid_request",
+  "error_description": "Trust cannot be established with the issuer: https://issuer.example.com"
+}
+
+
+
HTTP/1.1 400 Bad Request
+Content-Type: application/json
+
+{
+  "error": "invalid_request",
+  "error_description": "The following Credentials/VP are malformed: [CredentialX, vp_token[2]]"
+}
+
+
+
+
+
+

Redirect URI

+

When the Relying Party provides the redirect URI, the Wallet Instance MUST send the user-agent to this redirect URI. The redirect URI allows the Relying Party to continue the interaction with the End-User on the device where the Wallet Instance resides after the Wallet Instance has sent the Authorization Response to the response URI.

+

The Relying Party MUST include a response code within the redirect URI. The response code is a fresh, cryptographically random number used to ensure only the receiver of the redirect can fetch and process the Authorization Response. The number could be added as a path component, as a parameter or as a fragment to the URL. It is RECOMMENDED to use a cryptographic random value of 128 bits or more at the time of the writing of this specification.

+

The following is a non-normative example of the response from the Relying Party to the Wallet Instance upon receiving the Authorization Response at the Response Endpoint.

+
HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+  "redirect_uri": "https://relying-party.example.org/cb?response_code=091535f699ea575c7937fa5f0f454aee"
+}
+
+
+

The redirect_uri value MUST be used with an HTTP method GET by either the Wallet Instance or the user-agent to redirect the User to the Relying Party in order to complete the process. The value can be added as a path component, as a fragment or as a parameter to the URL according to Section 6.2 of OpenID4VP. The specific entity that performs this action depends on whether the flow is Same device or Cross device.

+
+
+

Redirect URI Errors

+

When the Wallet Instance sends the user-agent to the Redirect URI provided by the Relying Party, several errors may occur that prevent the successful completion of the process. These errors are critical as they directly impact the User experience by hindering the seamless flow of information between the Wallet Instance and the Relying Party. Below are potential errors related to the Redirect URI and their implications:

+
    +
  • Mismatched Redirect URI: This error occurs when the Redirect URI provided by the Relying Party does not match any of the URIs linked with the User session. This mismatch can lead to a HTTP status error code set to 403 (Forbidden), indicating that the request cannot be processed due session/URI mismatch.

  • +
  • Redirect URI Security Issues: If the Relying Party incurs in security issues when evaluating the User session with the provided URI, the Relying Party MUST raise an error. In such cases, an HTTP status code set to 403 (Forbidden) MUST be returned, indicating that the request is valid but the server is refusing action due to security precautions.

  • +
+

Handling these errors requires clear communication to the User within the returned navigation web page. It is crucial for the Relying Party to implement robust error handling and validation mechanisms for Redirect URIs to ensure a secure implementation.

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+
+ +
+ +
+ +
+
+
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/revocation-lists.html b/refs/pull/443/merge/en/revocation-lists.html new file mode 100644 index 000000000..cbbf1b00d --- /dev/null +++ b/refs/pull/443/merge/en/revocation-lists.html @@ -0,0 +1,1048 @@ + + + + + + + + Credential Lifecycle — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Credential Lifecycle

+

The value of a Digital Credential is conditional on its validity. A Credential that has been revoked, due to legal requirements, inaccuracy or compromise, is valueless and potentially harmful. +For these reasons a robust mechanism for managing the life-cycle and the revocation of a Digital Credential is required.

+

This section outlines the key technical requirements and processes related to the revocation of Digital Credentials. +Furthermore, it provides the technical details that the Verifiers MUST implement to verify, in a secure and reliable manner, the validity of a Digital Credential during the presentation phase.

+

The verification of the validity of a Digital Credential is based on the OAUTH-STATUS-ASSERTION.

+

A Status Assertion is a signed document serving as proof of a Digital Credential's current validity status. The Credential Issuer provides these assertions to Holders who can present them to Verifiers together with the corresponding Digital Credentials.

+

The Status Assertions have the following features:

+
    +
  • automated issuance, as the User authentication is not required for the provisioning of the Status Assertion;

  • +
  • verification of the Digital Credential validity status in both online and offline scenarios;

  • +
  • privacy-preserving, according to the following evidences:

    +
      +
    1. the Verifier can check the validity of the Credential during the presentation phase. It is not able to check the validity of a given Digital Credential related to the User over time and out of the scope of the User authentication;

    2. +
    3. the Credential Issuers is not able to know to which Verifier the Digital Credential or the Status Assertion will be presented;

    4. +
    5. it doesn't reveal any information about the Users or the content of their Digital Credentials.

    6. +
    +
  • +
+
+

Operational Requirements

+
    +
  • Internet Connection for Status Assertions: Status Assertions can be obtained only when the Wallet Instance is connected to the internet and actively operated by the User.

  • +
  • Role of a Credential Issuer: A Credential Issuer is responsible for creating and issuing Credentials, as well as managing their lifecycle and validity status.

  • +
  • Involvement of Authentic Sources: When one or more Authentic Sources are involved in the issuance of a Digital Credential, the information exchanged between the Authentic Source and the Credential Issuer is crucial for the Digital Credential's issuance. Furthermore, in cases where the Authentic Source initiates a revocation or data changes, revoking the Digital Credential becomes necessary.

  • +
+
+
+

Functional Requirements

+

In addition to the requirements in Section 5 of OAUTH-STATUS-ASSERTION, The Status Assertion:

+
    +
  • MUST have a validity period not greater than 24 hours;

  • +
  • MUST NOT reveal any information about the Relying Party, the User's device or the User's data contained in the Digital Credential the assertion is related to;

  • +
  • MUST be non-repudiable even beyond its expiration time and even in the case of cryptographic keys rotation.

  • +
+

The Credential Issuer MUST:

+
    +
  • ensure that the data contained in a Digital Credential is kept up to date, including the status of validity of the data from the Authentic Source;

  • +
  • revoke a Digital Credential when the following circumstances occur:

    +
      +
    • the Digital Credential requires to be updated, whenever one or more attributes are changed; in this case the User will request a new issuance for that Digital Credential;

    • +
    • the Holder needs to address the loss or compromise of cryptographic key material associated with the issued Digital Credential. In such case, the End-User should request the revocation of the Digital Credential through a service provided by the Credential Issuer and using an authentication method that offers the same Level of Assurance obtained during the Credential Issuance;

    • +
    • the User deletes the Digital Credential from the Wallet Instance. The Wallet Instance therefore should request the revocation of such Digital Credential to the Credential Issuer;

    • +
    +
  • +
  • provide a web service for allowing a Wallet Instance, with a proof of possession of a specific Digital Credential, to

    +
      +
    • request a revocation of that Digital Credential;

    • +
    • obtain a related Status Assertion;

    • +
    +
  • +
  • provide out-of-band mechanisms through which the User can request the revocation of their Digital Credentials, using a robust procedure for identity proofing and User authentication, in particular when the User is unable to use the personal Wallet Instance.

  • +
+

The Wallet Instance MUST:

+
    +
  • check periodically the validity status of the Digital Credential that is stored in it, requesting a Status Assertion for each Digital Credential;

  • +
  • be able to present a Status Assertion if required by a Verifier, along with the corresponding Digital Credential;

  • +
  • request a revocation of a Digital Credential when the Users delete it from the storage.

  • +
+

The Authentic Sources MUST:

+
    +
  • provide web services for the providing of updated User data and the validity status;

  • +
  • store in local databases only the minimum information required to provide the Credential Issuer with the User data or a change in the validity status.

  • +
+
+
+

Revocation Use Cases

+

The revocation of a Digital Credential MAY be triggered by:

+
    +
  • Users using their personal Wallet Instance or by some out-of-band touchpoints.

  • +
  • Revocation of the Wallet Instance.

  • +
  • Authentic Sources (e.g., for attribute updates) following administrative purposes.

  • +
  • Law-Enforcing Bodies for the fulfillment of their functions and any other judicial reasons (e.g., Police).

  • +
+

Credential Revocation Flows can start under different scenarios, such as:

+
+
    +
  • The User reports the loss or theft of their own physical document to the Law-Enforcement Authorities: this implies that the Credentials, if any, shall be revoked.

  • +
  • The User notifies an Authentic Source that one or more attributes are changed (e.g. the current resident address): in this case the Credentials MUST be revoked, as they are no longer valid due to the change in attributes.

  • +
  • Users who lose access to their Wallet Instance (e.g., due to theft or loss of the device) can request the Credential Issuer to revoke their Credentials or ask the Wallet Provider to revoke the Wallet Instance. If the Wallet Provider is authorized by the User and is aware of the types of Credentials and their issuers stored in the Wallet, it can then initiate the revocation of all Digital Credentials contained within the Wallet Instance on behalf of the User.

  • +
  • The Law-Enforcing Authorities, for the fulfillment of their functions and any other judicial reasons, may request the Authentic Source to revoke entitlements, licenses, certificates, identification documents, etc., which in turn leads to the revocation of any linked Credentials.

  • +
  • The Authentic Sources that for any update of one or more User attributes, SHOULD inform the Credential Issuer that has previously requested those data for the issuance of a Credential about that User.

  • +
  • The Credential Issuers, for technical security reasons (e.g. in the case of compromised cryptographic keys), SHOULD decide to revoke the Credentials.

  • +
+
+

The revocation scenarios involve two main flows:

+
+
    +
  • The Revocation flows: these flows describe how an Entity requests for a Digital Credential revocation.

  • +
  • The Status Assertion flows: these flows define the technical protocols for requesting and obtaining a Status Assertion and how the Wallet Instance SHOULD provide it to a Verifier as a proof of validity of a corresponding Digital Credential.

  • +
+
+
+
+

Revocation Flows

+

Depending on the different scenarios that may involve the revocation of a Digital Credential, different processes and technical flows may be implemented, according to national laws or Regulations of specific domains. +The subsequent sections define the protocol interface between the Wallet Instances and the Credential Issuers during the revocation request. The communication between the Credential Issuers and other Entities is out-of-scope of this technical implementation profile.

+
+

Revocation Request by Wallet Instance

+

A Wallet Instance MUST request the revocation of a Digital Credential as defined below.

+
+_images/Low-Level-Flow-Revocation.svg +
+

Fig. 7 Wallet Instance Initiated Revocation Flow

+
+
+

Step 1 (Credential Revocation Request): The Wallet Instance initiates the process by creating a Credential Revocation Request. This request MUST be sent to the Credential Issuer who has previously issued that Credential. The Credential Revocation Request MUST contain a JSON object with the member revocation_requests.

+

The revocation_requests MUST be set with an array of strings, where each string within the array represents a Credential Revocation Request object, enabling the Wallet Instance to request multiple Credential Revocation Requests to a single Credential Issuer.

+

The request MUST be signed with the private key related to the public key contained within the Credential (such as the Credential Issuer Signed JWT in the case of SD-JWT, or the MSO in the case of Mdoc CBOR). Then, the Wallet Instance sends the request to the Credential Issuer as in the following non-normative example representing a Revocation Assertion Request array.

+
POST /revoke HTTP/1.1
+Host: pid-provider.example.org
+Content-Type: application/json
+
+revocation_requests : ["${base64url(json({typ: revocation-assertion+jwt, ...}))}.payload.signature", ... ]
+
+
+

Below, is given a non-normative example of a single Revocation Assertion Request object with decoded JWT headers and payload and without signature for better readability:

+
{
+  "alg": "ES256",
+  "typ": "credential-revocation-request+jwt",
+  "kid": $CREDENTIAL-CNF-JWKID
+}
+.
+{
+  "iss": "0b434530-e151-4c40-98b7-74c75a5ef760",
+  "aud": "https://pid-provider.example.org",
+  "iat": 1698744039,
+  "exp": 1698744139,
+  "jti": "6f204f7e-e453-4dfd-814e-9d155319408c",
+  "credential_hash": $Issuer-Signed-JWT-Hash,
+  "credential_hash_alg": "sha-256"
+}
+
+
+

Step 2 (Revocation Assertion Request verification): The Credential Issuer verifies the proof of possession of the Credential requested to be revoked, using the the confirmation method that was attested in the Credential. If the verification is successful the revocation request is allowed.

+

Step 3 (Credential Revocation): The Credential Issuer revokes the Credential provided in the Revocation Request object. After the revocation, the Credential Issuer MAY also send a notification to the User (e.g. using a User's email address, telephone number, or any other verified and secure communication channel), with all needed information related to the Credential revocation status update. This communication is out of scope of the current technical implementation profile.

+

Step 4 (Credential Revocation Response): The Credential Issuer sends a response back to the Wallet Instance with the result of the revocation request.

+
.. code-block:: http
+            HTTP/1.1 200 Ok
+            Content-Type: application/json
+
+            {
+                    "revocation_assertion_responses": ["${base64url(json({typ: revocation_assertion+jwt, ...}))}.payload.signature", ... ]
+            }
+
+
+
+

Credential Revocation HTTP Request

+

The requests to the Credential Issuer Revocation endpoint MUST be HTTP with method POST, using the mandatory parameters listed below within the HTTP request message body. These MUST be encoded in application/json format.

+ +++++ + + + + + + + + + + + + +

Claim

Description

Reference

revocation_requests

It MUST be an array of strings, where each represents a Revocation Assertion Request object. Each element MUST contain a signed JWT as a cryptographic proof of possession to which the Digital Credential to be revoked shall be bound. See Section Credential Proof of Possession for more details.

OAUTH-STATUS-ASSERTION .

+

The Revocation Endpoint MUST be provided by the Credential Issuer within its Metadata.

+
+
+

Credential Revocation HTTP Response

+

In case of succesfully Revocation Request validation, the Credential Issuer MUST return an HTTP response with the status code set to 200. If the Credential Issuer is able to provide a valid Status Assertion for a requested Credential, the response MUST contains a revocation Assertion object within a JSON Array. Otherwise, a Revocation Assertion Errors related to that Credential MUST be included in the Response JSON Array as an entry.

+

If the Revocation Request fails (e.g. invalid request, server unavailability, etc.), an HTTP Error Status Code MUST be provided within the Revocation Response.

+

In the following table are listed HTTP Status Codes that MUST be supported:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Status Code

Body

Description

200 Created

Revocation Assertion Response

The Revocation Assertion Response has been successfully created.

400 Bad Request

Error code and description

The Credential Issuer cannot fulfill the request because of invalid parameters.

500 Internal Server Error

The Credential Issuer encountered an internal problem. (RFC 6749#section-5.2).

503 Service Unavailable

The Credential Issuer is temporary unavailable. (RFC 6749#section-5.2).

+

The response MUST:

+
    +
  • include a JSON object with a member named revocation_assertion_responses;

  • +
  • be encoded in application/json format.

  • +
+

The revocation_assertion_responses object MUST contain the following mandatory claims.

+ +++++ + + + + + + + + + + + + +

Claim

Description

Reference

revocation_assertion_responses

the Revocation Assertions and or the Revocation Assertion Errors related to the request made by the Wallet Instance.

OAUTH-STATUS-ASSERTION.

+

The Revocation Assertion object MUST contain the parameter credential_status_validity with the value set to false. +Below a non-normative example of a Revocation Assertion object in JWT format, with the headers and payload represented in JSON and without applying the signature.

+
 {
+   "alg": "ES256",
+   "typ": "revocation-assertion+jwt",
+   "kid": "Issuer-JWK-KID"
+ }
+.
+ {
+   "iss": "https://issuer.example.org",
+   "jti": "6f204f7e-e453-4dfd-814e-9d155319408c"
+   "credential_hash": $CREDENTIAL-HASH,
+   "credential_hash_alg": "sha-256",
+   "credential_status_validity": false,
+   "cnf": {
+     "jwk": {
+       "kty": "EC",
+       "crv": "P-256",
+       "x": "_2ySUmWFjwmraNlo15r6dIBXerVdy_NpJuwAKJMFdoc",
+       "y": "MV3C88MhhEMba6oyMBWuGeB3dKHP4YADJmGyJwwILsk"
+     }
+   }
+ }
+
+
+

The Revocation Assertion Error object MUST contain the following parameters:

+
+
    +
  • error. The error code, as registerd in the table below;

  • +
  • error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.

  • +
+
+

Errors are meant to provide additional information about the failure so that the User can be informed and take the appropriate action. +The error parameter for the Revocation Assertion Error object MUST be set with one of the values defined in the table below, in addition to the values specified in RFC 6749#section-5.2:

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Error Code

Description

invalid_request

The request is not valid due to the lack or incorrectness of one or more parameters. (RFC 6749#section-5.2).

credential_already_revoked

The Digital Credential is already revoked.

credential_updated

One or more information contained in the Digital Credential are changed. The error_description field SHOULD contain a human-readable text describing the general parameters updated without specifying each one.

credential_invalid

The Digital Credential is invalid. The error_description field SHOULD contain the reason of invalidation.

invalid_request_signature

The Revocation Assertion Request signature validation has failed. This error type is used when the proof of possession of the Digital Credential is found not valid within the Revocation Assertion Request.

credential_not_found

The credential_hash value provided in the Revocation Assertion Request doesn't match with any active Digital Credential.

unsupported_hash_alg

The hash algorithm set in credential_hash_alg is not supported.

+

Below a non-normative example of a Revocation Assertion Error object in JWT format, with the headers and payload represented in JSON and without applying the signature.

+
{
+  "alg": "ES256",
+  "typ": "revocation-assertion-error+jwt",
+  "kid": "Issuer-JWK-KID"
+}
+.
+{
+  "iss": "https://issuer.example.org",
+  "jti": "6f204f7e-e453-4dfd-814e-9d155319408c"
+  "credential_hash": $CREDENTIAL-HASH,
+  "credential_hash_alg": "sha-256",
+  "error": "unsupported_hash_alg",
+  "error_description": "The hash algorithm is not supported"
+}
+
+
+
+
+
+
+

Status Assertion Flows

+

The Status Assertion process is divided into the following phases:

+
+
    +
  1. The Status Assertion Request by a Wallet Instance: it involves the Wallet Instance and the Credential Issuer.

  2. +
  3. The Status Assertion Presentation to a Verifier: it involves the Wallet Instance and the Verifier.

  4. +
+
+
+_images/High-Level-Flow-Status-Attestation.svg +
+

Fig. 8 High-Level Status Assertion Flows

+
+
+
+

Status Assertion Request by Wallet Instance

+

The presentation of a Credential to a Verifier may occur long after it has been issued by the Credential Issuer. During this time interval, the Credential can be invalidated for any reason and therefore the Verifier also needs to verify its revocation or suspension status. To address this scenario, the Credential Issuer provides the Wallet Instance with a Status Assertion. This Assertion is bound to a Credential so that the Wallet Instance can present it to a Verifier, along with the Credential itself, as proof of non-revocation status of the Credential.

+

The following diagram shows how the Wallet Instance requests a Status Assertion to the Credential Issuer.

+
+_images/Low-Level-Flow-Revocation-Attestation.svg +
+

Fig. 9 Status Assertion Request Flow

+
+
+

Step 1 (Status Assertion Request): The Wallet Instance sends the Status Assertion Request to the Credential Issuer, where:

+
    +
  • The request MUST contain the base64url encoded hash value of the Digital Credential, for which the Status Assertion is requested, and enveloped in a signed Status Assertion Request object.

  • +
  • The Status Assertion Request object MUST be signed with the private key corresponding to the confirmation claim assigned by the Issuer and contained within the Digital Credential.

  • +
+

Below a non-normative example representing a Status Assertion Request array with a single Status Assertion Request object in JWT format.

+
POST /status HTTP/1.1
+Host: issuer.example.org
+Content-Type: application/json
+
+    {
+            "status_assertion_requests" : ["${base64url(json({typ: status-assertion+jwt, ...}))}.payload.signature", ... ]
+    }
+
+
+

The Status Assertion HTTP request can be sent to a single Credential Issuer regarding multiple Digital Credentials, and MUST contain a JSON object with the member status_assertion_requests. +The status_assertion_requests MUST be set with an array of strings, where each string within the array represents a Digital Credential Status Assertion Request object.

+

A non-normative example of Credential Proof of Possession is provided in the previous section.

+

Step 2 (Status Assertion Request verification): The Credential Issuer that receives the Status Assertion Request object MUST validate that the Wallet Instance making the request is authorized to request Status Assertions. Therefore the following requirements MUST be satisfied:

+
    +
  • The Credential Issuer MUST verify the compliance of all elements in the status_assertion_requests object using the confirmation method contained within the Digital Credential where the Status Assertion Request object is referred to;

  • +
  • The Credential Issuer MUST verify that it is the legitimate Issuer of the Digital Credential to which each Status Assertion Request object refers.

  • +
+

Step 3 (Check for validity): The Credential Issuer checks that the User's attributes are not updated by the Authentic Source or that the latter has not revoked them. The technical mechanisms for obtaining this information are out-of-scope of this technical implementation profile.

+

Step 4 (Status Assertion Creation): The Credential Issuer creates the corresponding Status Assertion. When a Status Assertion is requested to a Credential Issuer, the Credential Issuer checks the status of the Digital Credential and creates a Status Assertion bound to it. If the Digital Credential is valid, the Credential Issuer creates a new Status Assertion, which a non-normative example is given below where the format is JWT.

+
{
+"alg": "ES256",
+"typ": "status-assertion+jwt",
+"kid": $ISSUER-JWKID
+    }
+    .
+    {
+            "iss": "https://issuer.example.org",
+            "iat": 1504699136,
+            "exp": 1504785536,
+            "credential_hash": $CREDENTIAL-HASH,
+            "credential_hash_alg": "sha-256",
+            "credential_status_validity": true,
+            "cnf": {
+                    "jwk": {...}
+            }
+    }
+
+
+

Step 4 (Status Assertion Response): The response MUST include a JSON object with a member named status_assertion_responses, which contains the Status Assertions and or the Status Assertion Errors related to the request made by the Wallet Instance, as in the following non-normative example.

+
HTTP/1.1 200 Created
+    Content-Type: application/json
+
+    {
+            "status_assertion_responses": ["${base64url(json({typ: status-assertion+jwt, ...}))}.payload.signature", ... ]
+    }
+
+
+

The member status_assertion_responses MUST be an array of strings, where each of them represent a Status Assertion Response object as defined in OAUTH-STATUS-ASSERTION.

+
+

Status Assertion HTTP Request

+

The requests to the Credential status endpoint of the Credential Issuers MUST be HTTP with method POST, using the same mandatory parameters as in the Table of Credential Request parameters. These MUST be encoded in application/json format.

+ +++++ + + + + + + + + + + + + +

Claim

Description

Reference

status_assertion_requests

It MUST be an array of strings, where each of them represent a Status Assertion Request object. Each element MUST contain a signed JWT as a cryptographic proof of possession of the Digital Credential. See Section Credential Proof of Possession for more details.

OAUTH-STATUS-ASSERTION .

+

The typ value in the credential_pop JWT MUST be set to status-assertion+jwt

+

The Credential status endpoint MUST be provided by the Credential Issuers within their Metadata. The Credential Issuers MUST include in the issued Digital Credentials the object status_assertion_requests with the JSON member status_assertion set to a JSON Object containing the credential_hash_alg claim. It MUST contain the algorithm used for hashing the Digital Credential. Among the hash algorithms, the value sha-256 is RECOMMENDED .

+
+
+

Status Assertion HTTP Response

+

In case of succesfully Status Assertion Request validation, the Credential Issuer MUST return an HTTP response with the status code set to 200. If the Credential Issuer is able to provide a valid Status Assertion for a requested Credential, the response MUST contains a Status Assertion object within a JSON Array. Otherwise, a Status Assertion Errors related to that Credential MUST be included in the Response JSON Array as an entry.

+

If the Status Request fails (e.g. invalid request, server unavailability, etc.), an HTTP Error Status Code MUST be provided within the Status Assertion Response.

+

In the following table are listed HTTP Status Codes that MUST be supported:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Status Code

Body

Description

200 Created

Status Assertion Response

The Status Assertion Response has been successfully created and it has been returned.

400 Bad Request

Error code and description

The Credential Issuer cannot fulfill the request because of invalid parameters.

500 Internal Server Error

The Credential Issuer encountered an internal problem. (RFC 6749#section-5.2).

503 Service Unavailable

The Credential Issuer is temporary unavailable. (RFC 6749#section-5.2).

+

The response MUST:

+
    +
  • include a JSON object with a member named status_assertion_responses;

  • +
  • be encoded in application/json format.

  • +
+

The status_assertion_responses object MUST contain the following mandatory claims.

+ +++++ + + + + + + + + + + + + +

Claim

Description

Reference

status_assertion_responses

the Status Assertions and or the Status Assertion Errors related to the request made by the Wallet Instance.

OAUTH-STATUS-ASSERTION.

+

The Status Assertion Error object MUST contain the following parameters:

+
+
    +
  • error. The error code, as registerd in the table below;

  • +
  • error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.

  • +
+
+

Errors are meant to provide additional information about the failure so that the User can be informed and take the appropriate action. +The error parameter for the Status Assertion Error object MUST be set with one of the values defined in the table below, in addition to the values specified in RFC 6749#section-5.2:

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Error Code

Description

invalid_request

The request is not valid due to the lack or incorrectness of one or more parameters. (RFC 6749#section-5.2).

credential_revoked

The Digital Credential is revoked. The reason of revocation MUST be provided in the error_description field.

credential_updated

One or more information contained in the Digital Credential are changed. The error_description field SHOULD contain a human-readable text describing the general parameters updated without specifying each one.

credential_invalid

The Digital Credential is invalid. The error_description field SHOULD contain the reason of invalidation.

invalid_request_signature

The Status Assertion Request signature validation has failed. This error type is used when the proof of possession of the Digital Credential is found not valid within the Status Assertion Request.

credential_not_found

The credential_hash value provided in the Status Assertion Request doesn't match with any active Digital Credential.

unsupported_hash_alg

The hash algorithm set in credential_hash_alg is not supported.

+

Below a non-normative example of a Status Assertion Error object in JWT format, with the headers and payload represented in JSON and without applying the signature.

+
{
+  "alg": "ES256",
+  "typ": "status-assertion-error+jwt",
+  "kid": "Issuer-JWK-KID"
+}
+      .
+{
+  "iss": "https://issuer.example.org",
+  "jti": "6f204f7e-e453-4dfd-814e-9d155319408c"
+  "credential_hash": $CREDENTIAL-HASH,
+  "credential_hash_alg": "sha-256",
+  "error": "credential_revoked",
+  "error_description": "Credential is revoked."
+}
+
+
+
+
+
+

Status Assertion Presentation to the Verifiers

+

During the presentation phase, a Verifier MAY request the Wallet Instance to provide a Non-Revocation Assertion along with the requested Credential. If a Verifier requests a Status Assertion for a requested Digital Credential, the Wallet Instance MUST provide the Status Assertions in the vp_token JSON array. If the Status Assertion is requested by the Verifier and the Wallet Instance is not able to provide it or it is expired or it is issued far back in time, the Verifier MAY decide to accept or reject the Credential according to its security policy.

+

Law-Enforcement Authorities or Third Parties authorized by national law, MAY require deferred non-revocation status verification but the definition of these protocols is currently out-of-scope for this technical implementation profile.

+
+
+
+

Credential Proof of Possession

+

The Credential Proof of Possession (credential_pop) MUST be a JWT that MUST contain the parameters (Header and Payload) in the following table.

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Header

Description

Reference

typ

In case of revocation request it MUST be set to revocation-request+jwt. In case of Status Assertion request it MUST be set to status-assertion-request+jwt, according to OAUTH-STATUS-ASSERTION .

RFC 7516#section-4.1.1.

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section Cryptographic Algorithms and MUST NOT be set to none or any symmetric algorithm (MAC) identifier.

RFC 7516#section-4.1.1.

kid

Unique identifier of the jwk or COSE_Key inside the cnf claim of the Credential to be revoked, as base64url-encoded JWK Thumbprint value, according to OAUTH-STATUS-ASSERTION.

RFC 7638#section_3.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Payload

Description

Reference

iss

Thumbprint of the JWK in the cnf parameter of the Wallet Assertion.

RFC 9126 and RFC 7519.

aud

It MUST be set to the identifier of the Issuer.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT. It MUST be greater than the value set for iat.

RFC 9126 and RFC 7519.

iat

UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

jti

Unique identifier for the proof of possession JWT. The value SHOULD be set using a UUID v4 value according to [RFC 4122].

RFC 7519#section-4.1.7.

credential_hash

It MUST contain the hash value of a Digital Credential, derived by computing the base64url encoded hash of the Digital Credential.

OAUTH-STATUS-ASSERTION.

credential_hash_alg

It MUST contain the Algorithm used for hashing the Digital Credential. The value SHOULD be set to S256.

OAUTH-STATUS-ASSERTION.

+
+
+

Revocation Assertion

+

When the JWT format is used, the Revocation Assertion MUST contain the following claims.

+ +++++ + + + + + + + + + + + + + + + + +

Header

Description

Reference

alg

Algorithm used to verify the cryptographic signature of the Revocation Assertion. Revocation Assertion that do not need to be signed SHOULD set the alg value to none in according with OAUTH-STATUS-ASSERTION.

[OIDC4VCI. Draft 13], [RFC 7515], [RFC 7517].

typ

It MUST be set to revocation-assertion-response+jwt when JWT format is used.

[RFC 7515], [RFC 7517], OAUTH-STATUS-ASSERTION.

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Payload

Description

Reference

iss

It MUST be set to the identifier of the Credential Issuer.

RFC 9126 and RFC 7519.

jti

Unique identifier for the JWT.

RFC 7519#section-4.1.7.

credential_status_validity

Boolean value indicating the absolute validity of the Credential linked to the Status Assertion. It MUST be set with the value false.

OAUTH-STATUS-ASSERTION.

+
+
+

Status Assertion

+

When the JWT format is used, the Status Assertion MUST contain the following claims.

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Header

Description

Reference

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to none or to a symmetric algorithm (MAC) identifier.

[OIDC4VCI. Draft 13], [RFC 7515], [RFC 7517].

typ

It MUST be set to status-assertion-request+jwt when JWT format is used.

[RFC 7515], [RFC 7517], [OAuth Status Attestation draft 01]..

kid

Unique identifier of the Credential Issuer jwk as base64url-encoded JWK Thumbprint value.

RFC 7638#section_3.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Payload

Description

Reference

iss

It MUST be set to the identifier of the Credential Issuer.

RFC 9126 and RFC 7519.

iat

UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT. It MUST be greater than the value set for iat.

RFC 9126 and RFC 7519.

credential_hash

Hash value of the Credential the Status Assertion is bound to.

OAUTH-STATUS-ASSERTION.

credential_hash_alg

The Algorithm used for hashing the Credential to which the Status Assertion is bound. The value SHOULD be set to S256.

OAUTH-STATUS-ASSERTION.

credential_status_validity

Boolean value indicating the absolute validity of the Credential linked to the Status Assertion. It is REQUIRED and it MUST be set with the value "false" or "true".

OAUTH-STATUS-ASSERTION.

cnf

JSON object containing confirmation methods. The sub-member contained within cnf member, such as jwk for JWT, MUST match with the one provided within the related Digital Credential. Other confirmation methods can be utilized when the referenced Digital Credential supports them, in accordance with the relevant standards.

[RFC7800, Section 3.1] and [RFC8747, Section 3.1].

+
+
+

Error Assertion

+

When the JWT format is used, the Revocation or Status Assertion Error MUST contain the following claims.

+ +++++ + + + + + + + + + + + + + + + + +

Header

Description

Reference

alg

Algorithm used to verify the cryptographic signature of the Assertion Error. Assertion Error that do not need to be signed SHOULD set the alg value to none in according with OAUTH-STATUS-ASSERTION.

[OIDC4VCI. Draft 13], [RFC 7515], [RFC 7517].

typ

It MUST be set to status-assertion-response+jwt or revocation-assertion-response+jwt when JWT format is used.

[RFC 7515], [RFC 7517], OAUTH-STATUS-ASSERTION .

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Payload

Description

Reference

iss

It MUST be set to the identifier of the Credential Issuer.

RFC 9126 and RFC 7519.

jti

Unique identifier for the JWT.

RFC 7519#section-4.1.7.

error

Status code returned from the Credential Issuer after revocation. The value SHOULD be assigned with one of the error types defined in {{RFC6749}}[Section 5.2]<https://tools.ietf.org/html/rfc6749#section-5.2> or defined in OAUTH-STATUS-ASSERTION.

[RFC6749, Section 5.2], OAUTH-STATUS-ASSERTION

error_description

Text that clarifies the nature of the error, such as attribute changes, revocation reasons, in relation to the error value.

OAUTH-STATUS-ASSERTION.

+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/search.html b/refs/pull/443/merge/en/search.html new file mode 100644 index 000000000..09c34716d --- /dev/null +++ b/refs/pull/443/merge/en/search.html @@ -0,0 +1,201 @@ + + + + + + + Search — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + +
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+ +
+ +
+
+
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/searchindex.js b/refs/pull/443/merge/en/searchindex.js new file mode 100644 index 000000000..5aba20234 --- /dev/null +++ b/refs/pull/443/merge/en/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"(Q)EAA non-normative examples": [[6, "q-eaa-non-normative-examples"]], "Access Token": [[8, "access-token"]], "Acknowledgements": [[3, "acknowledgements"]], "Acronyms": [[4, "acronyms"]], "Attributes": [[2, "attributes"]], "Authentic Sources": [[1, null]], "Authorization Request": [[8, "authorization-request"]], "Authorization Request Details": [[12, "authorization-request-details"], [13, "authorization-request-details"]], "Authorization Response": [[8, "authorization-response"]], "Authorization Response Details": [[12, "authorization-response-details"], [13, "authorization-response-details"]], "Authorization Response Errors": [[12, "authorization-response-errors"], [13, "authorization-response-errors"]], "Authorization endpoint": [[8, "authorization-endpoint"]], "Configuration of the Federation": [[17, "configuration-of-the-federation"]], "Considerations about Decentralization": [[17, "considerations-about-decentralization"]], "Credential Lifecycle": [[14, null]], "Credential Proof of Possession": [[14, "credential-proof-of-possession"]], "Credential Request": [[8, "credential-request"]], "Credential Response": [[8, "credential-response"]], "Credential Revocation HTTP Request": [[14, "credential-revocation-http-request"]], "Credential Revocation HTTP Response": [[14, "credential-revocation-http-response"]], "Credential endpoint": [[8, "credential-endpoint"]], "Cross Device Flow Status Checks and Security": [[12, "cross-device-flow-status-checks-and-security"], [13, "cross-device-flow-status-checks-and-security"]], "Cryptographic Algorithms": [[0, null]], "Deactivation": [[19, "deactivation"]], "Deferred Flow": [[8, "deferred-flow"]], "Defined Terms": [[4, "defined-terms"]], "Device Engagement": [[9, "device-engagement"], [12, "device-engagement"]], "Digital Credential Metadata Type": [[6, "digital-credential-metadata-type"]], "Dynamic Component View": [[18, "dynamic-component-view"]], "Entity Configuration": [[17, "entity-configuration"]], "Entity Configuration Leaves and Intermediates": [[17, "entity-configuration-leaves-and-intermediates"]], "Entity Configuration Trust Anchor": [[17, "entity-configuration-trust-anchor"]], "Entity Configuration of PID/(Q)EAA Providers": [[7, null]], "Entity Configuration of Relying Parties": [[11, null]], "Entity Configurations Common Parameters": [[17, "entity-configurations-common-parameters"]], "Entity Statement": [[17, "entity-statement"]], "Entity Statements": [[17, "entity-statements"]], "Error Assertion": [[14, "error-assertion"]], "Example": [[10, "example"]], "Example of a (Q)EAA Provider Entity Configuration": [[7, "example-of-a-q-eaa-provider-entity-configuration"]], "Example of a Relying Party Entity Configuration": [[11, "example-of-a-relying-party-entity-configuration"]], "External references": [[2, "external-references"], [19, "external-references"]], "Federation API endpoints": [[17, "federation-api-endpoints"]], "Federation Roles": [[17, "federation-roles"]], "Functional Requirements": [[14, "functional-requirements"], [17, "id3"]], "General Properties": [[2, "general-properties"], [10, "general-properties"], [17, "general-properties"]], "General Requirements": [[8, "general-requirements"]], "Header": [[19, "header"]], "High-Level (Q)EAA flow": [[8, "high-level-q-eaa-flow"]], "High-Level PID flow": [[8, "high-level-pid-flow"]], "How to contribute": [[3, null]], "Implementation Considerations": [[10, "implementation-considerations"]], "Implementation considerations": [[2, "implementation-considerations"]], "Index of content": [[5, "index-of-content"]], "Initialization Process": [[19, "initialization-process"]], "Introduction": [[5, "introduction"]], "Libraries and code snippets": [[2, "libraries-and-code-snippets"]], "Low-Level Issuance Flow": [[8, "low-level-issuance-flow"]], "MDOC-CBOR": [[6, "mdoc-cbor"]], "MDOC-CBOR Examples": [[6, "mdoc-cbor-examples"]], "Metadata Types": [[17, "id1"]], "Metadata for federation_entity": [[7, "metadata-for-federation-entity"], [11, "metadata-for-federation-entity"]], "Metadata for oauth_authorization_server": [[7, "metadata-for-oauth-authorization-server"]], "Metadata for openid_credential_issuer": [[7, "metadata-for-openid-credential-issuer"]], "Metadata for wallet_relying_party": [[7, "metadata-for-wallet-relying-party"], [11, "metadata-for-wallet-relying-party"]], "Metadata of federation_entity Leaves": [[17, "metadata-of-federation-entity-leaves"]], "Mobile Security Object": [[6, "mobile-security-object"]], "Non-repudiability of the Long Lived Attestations": [[17, "non-repudiability-of-the-long-lived-attestations"]], "Normative Language and Conventions": [[4, null]], "Notification Request": [[8, "notification-request"]], "Notification Response": [[8, "notification-response"]], "Notification endpoint": [[8, "notification-endpoint"]], "Offline Relying Party Metadata": [[17, "offline-relying-party-metadata"]], "Offline Trust Attestation Mechanisms": [[17, "offline-trust-attestation-mechanisms"]], "Offline Wallet Trust Attestation": [[17, "offline-wallet-trust-attestation"]], "Operational Requirements": [[14, "operational-requirements"]], "PAR http request parameters": [[8, "id6"]], "PID Claims": [[6, "pid-claims"]], "PID Non-Normative Examples": [[6, "pid-non-normative-examples"]], "PID/(Q)EAA Data Model": [[6, null]], "PID/(Q)EAA Issuance": [[8, null]], "PID/(Q)EAA SD-JWT parameters": [[6, "pid-q-eaa-sd-jwt-parameters"]], "Payload": [[19, "payload"]], "Payload federation_entity": [[19, "payload-federation-entity"]], "Privacy Remarks": [[17, "privacy-remarks"]], "Proximity Flow": [[9, null], [12, "proximity-flow"]], "Pseudonyms": [[10, null]], "Pushed Authorization Request (PAR) Request": [[8, "pushed-authorization-request-par-request"]], "Pushed Authorization Request (PAR) Response": [[8, "pushed-authorization-request-par-response"]], "Pushed Authorization Request Endpoint": [[8, "pushed-authorization-request-endpoint"]], "Redirect URI": [[12, "redirect-uri"], [13, "redirect-uri"]], "Redirect URI Errors": [[12, "redirect-uri-errors"], [13, "redirect-uri-errors"]], "Relying Party Solution": [[12, null]], "Relying Party Trust Evaluation": [[17, "relying-party-trust-evaluation"]], "Remote Flow": [[12, "remote-flow"], [13, null]], "Request Object Details": [[12, "request-object-details"], [13, "request-object-details"]], "Request URI Endpoint Errors": [[12, "request-uri-endpoint-errors"], [13, "request-uri-endpoint-errors"]], "Request URI Response": [[12, "request-uri-response"], [13, "request-uri-response"]], "Request URI with HTTP POST": [[12, "request-uri-with-http-post"], [13, "request-uri-with-http-post"]], "Requirements": [[2, "requirements"], [10, "requirements"], [18, "requirements"], [19, "requirements"]], "Return to Operational state": [[19, "return-to-operational-state"]], "Revocation Assertion": [[14, "revocation-assertion"]], "Revocation Checks": [[12, "revocation-checks"], [13, "revocation-checks"]], "Revocation Flows": [[14, "revocation-flows"]], "Revocation Request by Wallet Instance": [[14, "revocation-request-by-wallet-instance"]], "Revocation Use Cases": [[14, "revocation-use-cases"]], "Revocations": [[18, "revocations"]], "SD-JWT Presentation": [[12, "sd-jwt-presentation"], [13, "sd-jwt-presentation"]], "SD-JWT-VC Credential Format": [[6, "sd-jwt-vc-credential-format"]], "Security Patterns": [[1, "security-patterns"]], "Session Termination": [[9, "session-termination"], [12, "session-termination"]], "States": [[18, "states"]], "Static Component View": [[18, "static-component-view"]], "Status Assertion": [[14, "status-assertion"]], "Status Assertion Flows": [[14, "status-assertion-flows"]], "Status Assertion HTTP Request": [[14, "status-assertion-http-request"]], "Status Assertion HTTP Response": [[14, "status-assertion-http-response"]], "Status Assertion Presentation to the Verifiers": [[14, "status-assertion-presentation-to-the-verifiers"]], "Status Assertion Request by Wallet Instance": [[14, "status-assertion-request-by-wallet-instance"]], "Technical Flow": [[8, "technical-flow"]], "Technical References": [[16, null]], "The Digital Identity Wallet Paradigm": [[15, null]], "The Infrastructure of Trust": [[17, null]], "The Italian EUDI Wallet implementation profile": [[5, null]], "Token Request": [[8, "token-request"]], "Token Response": [[8, "token-response"]], "Token endpoint": [[8, "token-endpoint"]], "Transition to Valid state": [[19, "transition-to-valid-state"]], "Transitions": [[18, "transitions"]], "Trust Chain": [[17, "trust-chain"]], "Trust Chain Fast Renewal": [[17, "trust-chain-fast-renewal"]], "Trust Evaluation Mechanism": [[17, "trust-evaluation-mechanism"]], "Trust Infrastructure Functional Requirements": [[17, "trust-infrastructure-functional-requirements"]], "Wallet Attestation": [[17, "wallet-attestation"], [18, null], [18, "table-wallet-attestation-claim"], [19, "wallet-attestation"]], "Wallet Attestation Issuance": [[18, "wallet-attestation-issuance"]], "Wallet Attestation Request": [[18, "wallet-attestation-request"]], "Wallet Instance": [[19, "wallet-instance"]], "Wallet Instance Initialization and Registration": [[18, "wallet-instance-initialization-and-registration"]], "Wallet Instance Lifecycle": [[18, "wallet-instance-lifecycle"], [19, "wallet-instance-lifecycle"]], "Wallet Instance registration http request parameters": [[18, "id6"]], "Wallet Provider Endpoints": [[19, "wallet-provider-endpoints"]], "Wallet Provider Metadata": [[19, "wallet-provider-metadata"]], "Wallet Solution": [[19, null]], "What it is useful for": [[10, "what-it-is-useful-for"]], "backup-restore.rst": [[2, null]], "http request header parameters": [[8, "id7"]], "mDoc Request": [[9, "mdoc-request"], [12, "mdoc-request"]], "mDoc Response": [[9, "mdoc-response"], [12, "mdoc-response"]], "nameSpaces": [[6, "namespaces"]], "wallet_provider metadata": [[19, "id1"]]}, "docnames": ["algorithms", "authentic-sources", "backup-restore", "contribute", "defined-terms", "index", "pid-eaa-data-model", "pid-eaa-entity-configuration", "pid-eaa-issuance", "proximity-flow", "pseudonyms", "relying-party-entity-configuration", "relying-party-solution", "remote-flow", "revocation-lists", "ssi-introduction", "standards", "trust", "wallet-attestation", "wallet-solution"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2}, "filenames": ["algorithms.rst", "authentic-sources.rst", "backup-restore.rst", "contribute.rst", "defined-terms.rst", "index.rst", "pid-eaa-data-model.rst", "pid-eaa-entity-configuration.rst", "pid-eaa-issuance.rst", "proximity-flow.rst", "pseudonyms.rst", "relying-party-entity-configuration.rst", "relying-party-solution.rst", "remote-flow.rst", "revocation-lists.rst", "ssi-introduction.rst", "standards.rst", "trust.rst", "wallet-attestation.rst", "wallet-solution.rst"], "indexentries": {"rfc": [[0, "index-0", false], [0, "index-1", false], [0, "index-10", false], [0, "index-11", false], [0, "index-12", false], [0, "index-13", false], [0, "index-14", false], [0, "index-15", false], [0, "index-16", false], [0, "index-17", false], [0, "index-18", false], [0, "index-19", false], [0, "index-2", false], [0, "index-20", false], [0, "index-21", false], [0, "index-3", false], [0, "index-4", false], [0, "index-5", false], [0, "index-6", false], [0, "index-7", false], [0, "index-8", false], [0, "index-9", false], [6, "index-0", false], [6, "index-1", false], [6, "index-2", false], [6, "index-3", false], [6, "index-4", false], [6, "index-5", false], [6, "index-6", false], [6, "index-7", false], [6, "index-8", false], [6, "index-9", false], [7, "index-0", false], [7, "index-1", false], [7, "index-10", false], [7, "index-11", false], [7, "index-2", false], [7, "index-3", false], [7, "index-4", false], [7, "index-5", false], [7, "index-6", false], [7, "index-7", false], [7, "index-8", false], [7, "index-9", false], [8, "index-0", false], [8, "index-1", false], [8, "index-10", false], [8, "index-100", false], [8, "index-101", false], [8, "index-102", false], [8, "index-103", false], [8, "index-104", false], [8, "index-105", false], [8, "index-106", false], [8, "index-107", false], [8, "index-108", false], [8, "index-109", false], [8, "index-11", false], [8, "index-110", false], [8, "index-111", false], [8, "index-112", false], [8, "index-113", false], [8, "index-114", false], [8, "index-115", false], [8, "index-116", false], [8, "index-117", false], [8, "index-118", false], [8, "index-119", false], [8, "index-12", false], [8, "index-120", false], [8, "index-121", false], [8, "index-122", false], [8, "index-123", false], [8, "index-124", false], [8, "index-125", false], [8, "index-126", false], [8, "index-127", false], [8, "index-128", false], [8, "index-129", false], [8, "index-13", false], [8, "index-130", false], [8, "index-131", false], [8, "index-132", false], [8, "index-133", false], [8, "index-14", false], [8, "index-15", false], [8, "index-16", false], [8, "index-17", false], [8, "index-18", false], [8, "index-19", false], [8, "index-2", false], [8, "index-20", false], [8, "index-21", false], [8, "index-22", false], [8, "index-23", false], [8, "index-24", false], [8, "index-25", false], [8, "index-26", false], [8, "index-27", false], [8, "index-28", false], [8, "index-29", false], [8, "index-3", false], [8, "index-30", false], [8, "index-31", false], [8, "index-32", false], [8, "index-33", false], [8, "index-34", false], [8, "index-35", false], [8, "index-36", false], [8, "index-37", false], [8, "index-38", false], [8, "index-39", false], [8, "index-4", false], [8, "index-40", false], [8, "index-41", false], [8, "index-42", false], [8, "index-43", false], [8, "index-44", false], [8, "index-45", false], [8, "index-46", false], [8, "index-47", false], [8, "index-48", false], [8, "index-49", false], [8, "index-5", false], [8, "index-50", false], [8, "index-51", false], [8, "index-52", false], [8, "index-53", false], [8, "index-54", false], [8, "index-55", false], [8, "index-56", false], [8, "index-57", false], [8, "index-58", false], [8, "index-59", false], [8, "index-6", false], [8, "index-60", false], [8, "index-61", false], [8, "index-62", false], [8, "index-63", false], [8, "index-64", false], [8, "index-65", false], [8, "index-66", false], [8, "index-67", false], [8, "index-68", false], [8, "index-69", false], [8, "index-7", false], [8, "index-70", false], [8, "index-71", false], [8, "index-72", false], [8, "index-73", false], [8, "index-74", false], [8, "index-75", false], [8, "index-76", false], [8, "index-77", false], [8, "index-78", false], [8, "index-79", false], [8, "index-8", false], [8, "index-80", false], [8, "index-81", false], [8, "index-82", false], [8, "index-83", false], [8, "index-84", false], [8, "index-85", false], [8, "index-86", false], [8, "index-87", false], [8, "index-88", false], [8, "index-89", false], [8, "index-9", false], [8, "index-90", false], [8, "index-91", false], [8, "index-92", false], [8, "index-93", false], [8, "index-94", false], [8, "index-95", false], [8, "index-96", false], [8, "index-97", false], [8, "index-98", false], [8, "index-99", false], [11, "index-0", false], [11, "index-1", false], [11, "index-2", false], [11, "index-3", false], [12, "index-0", false], [12, "index-1", false], [12, "index-2", false], [13, "index-0", false], [13, "index-1", false], [13, "index-2", false], [14, "index-0", false], [14, "index-1", false], [14, "index-10", false], [14, "index-11", false], [14, "index-12", false], [14, "index-13", false], [14, "index-14", false], [14, "index-15", false], [14, "index-16", false], [14, "index-17", false], [14, "index-18", false], [14, "index-19", false], [14, "index-2", false], [14, "index-20", false], [14, "index-21", false], [14, "index-22", false], [14, "index-23", false], [14, "index-24", false], [14, "index-25", false], [14, "index-26", false], [14, "index-27", false], [14, "index-28", false], [14, "index-29", false], [14, "index-3", false], [14, "index-30", false], [14, "index-31", false], [14, "index-32", false], [14, "index-33", false], [14, "index-34", false], [14, "index-35", false], [14, "index-36", false], [14, "index-37", false], [14, "index-38", false], [14, "index-39", false], [14, "index-4", false], [14, "index-40", false], [14, "index-41", false], [14, "index-42", false], [14, "index-43", false], [14, "index-44", false], [14, "index-45", false], [14, "index-5", false], [14, "index-6", false], [14, "index-7", false], [14, "index-8", false], [14, "index-9", false], [16, "index-0", false], [16, "index-1", false], [16, "index-10", false], [16, "index-11", false], [16, "index-12", false], [16, "index-13", false], [16, "index-14", false], [16, "index-15", false], [16, "index-16", false], [16, "index-17", false], [16, "index-2", false], [16, "index-3", false], [16, "index-4", false], [16, "index-5", false], [16, "index-6", false], [16, "index-7", false], [16, "index-8", false], [16, "index-9", false], [17, "index-0", false], [17, "index-1", false], [17, "index-2", false], [17, "index-3", false], [18, "index-0", false], [18, "index-1", false], [18, "index-10", false], [18, "index-11", false], [18, "index-12", false], [18, "index-13", false], [18, "index-14", false], [18, "index-15", false], [18, "index-16", false], [18, "index-17", false], [18, "index-18", false], [18, "index-19", false], [18, "index-2", false], [18, "index-20", false], [18, "index-21", false], [18, "index-22", false], [18, "index-23", false], [18, "index-3", false], [18, "index-4", false], [18, "index-5", false], [18, "index-6", false], [18, "index-7", false], [18, "index-8", false], [18, "index-9", false], [19, "index-0", false]], "rfc 2119": [[16, "index-0", false]], "rfc 2616": [[16, "index-1", false]], "rfc 3339": [[16, "index-2", false]], "rfc 3986": [[16, "index-3", false]], "rfc 4122": [[8, "index-61", false], [8, "index-87", false], [14, "index-19", false]], "rfc 5280": [[6, "index-3", false]], "rfc 5639": [[0, "index-9", false]], "rfc 5646": [[6, "index-8", false], [6, "index-9", false], [7, "index-10", false], [7, "index-11", false], [7, "index-9", false]], "rfc 6749": [[8, "index-0", false], [8, "index-122", false], [8, "index-25", false], [8, "index-29", false], [8, "index-30", false], [8, "index-35", false], [8, "index-46", false], [8, "index-49", false], [8, "index-5", false], [8, "index-74", false], [8, "index-76", false], [8, "index-93", false], [8, "index-94", false], [8, "index-95", false], [16, "index-14", false]], "rfc 6749#section-4.1.2": [[8, "index-68", false], [8, "index-70", false]], "rfc 6749#section-4.1.2.1": [[8, "index-73", false]], "rfc 6749#section-5.2": [[8, "index-96", false], [14, "index-0", false], [14, "index-1", false], [14, "index-2", false], [14, "index-3", false], [14, "index-4", false], [14, "index-5", false], [14, "index-6", false], [14, "index-7", false]], "rfc 7159": [[16, "index-4", false]], "rfc 7515": [[6, "index-0", false], [6, "index-1", false], [6, "index-2", false], [6, "index-4", false], [6, "index-7", false], [7, "index-5", false], [8, "index-100", false], [8, "index-117", false], [8, "index-121", false], [8, "index-123", false], [8, "index-125", false], [8, "index-128", false], [8, "index-129", false], [8, "index-80", false], [8, "index-82", false], [8, "index-84", false], [8, "index-86", false], [8, "index-99", false], [11, "index-2", false], [11, "index-3", false], [14, "index-21", false], [14, "index-23", false], [14, "index-28", false], [14, "index-30", false], [14, "index-39", false], [14, "index-41", false], [16, "index-5", false]], "rfc 7516": [[0, "index-17", false], [0, "index-3", false], [0, "index-5", false], [0, "index-7", false], [16, "index-6", false]], "rfc 7516#section-4.1.1": [[8, "index-36", false], [8, "index-52", false], [12, "index-0", false], [13, "index-0", false], [14, "index-8", false], [14, "index-9", false], [18, "index-0", false], [18, "index-12", false]], "rfc 7517": [[8, "index-124", false], [8, "index-126", false], [8, "index-127", false], [8, "index-130", false], [8, "index-83", false], [8, "index-85", false], [12, "index-2", false], [13, "index-2", false], [14, "index-22", false], [14, "index-24", false], [14, "index-29", false], [14, "index-31", false], [14, "index-40", false], [14, "index-42", false], [16, "index-7", false], [17, "index-2", false], [17, "index-3", false]], "rfc 7518": [[0, "index-0", false], [0, "index-1", false], [0, "index-10", false], [0, "index-11", false], [0, "index-12", false], [0, "index-13", false], [0, "index-14", false], [0, "index-15", false], [0, "index-16", false], [0, "index-18", false], [0, "index-19", false], [0, "index-2", false], [0, "index-20", false], [0, "index-21", false], [0, "index-4", false], [0, "index-6", false], [0, "index-8", false], [16, "index-8", false]], "rfc 7519": [[6, "index-5", false], [6, "index-6", false], [8, "index-103", false], [8, "index-105", false], [8, "index-107", false], [8, "index-109", false], [8, "index-111", false], [8, "index-112", false], [8, "index-114", false], [8, "index-116", false], [8, "index-131", false], [8, "index-132", false], [8, "index-133", false], [8, "index-18", false], [8, "index-39", false], [8, "index-41", false], [8, "index-43", false], [8, "index-45", false], [8, "index-51", false], [8, "index-54", false], [8, "index-56", false], [8, "index-58", false], [8, "index-60", false], [8, "index-62", false], [8, "index-72", false], [8, "index-88", false], [8, "index-91", false], [8, "index-92", false], [8, "index-97", false], [12, "index-1", false], [13, "index-1", false], [14, "index-12", false], [14, "index-14", false], [14, "index-16", false], [14, "index-18", false], [14, "index-26", false], [14, "index-34", false], [14, "index-36", false], [14, "index-38", false], [14, "index-44", false], [16, "index-9", false], [17, "index-0", false], [17, "index-1", false], [18, "index-15", false], [18, "index-17", false], [18, "index-19", false], [18, "index-21", false], [18, "index-3", false], [18, "index-5", false], [18, "index-7", false], [18, "index-9", false]], "rfc 7519#section-4.1.7": [[14, "index-20", false], [14, "index-27", false], [14, "index-45", false]], "rfc 7521": [[8, "index-69", false], [8, "index-77", false], [8, "index-78", false], [8, "index-79", false], [16, "index-17", false]], "rfc 7591#section-2": [[11, "index-1", false]], "rfc 7591#section-3.2.1": [[11, "index-0", false]], "rfc 7636": [[7, "index-3", false], [8, "index-2", false], [8, "index-7", false]], "rfc 7636#section-4.2": [[8, "index-47", false]], "rfc 7636#section-4.3": [[8, "index-48", false]], "rfc 7638": [[8, "index-119", false], [16, "index-10", false], [19, "index-0", false]], "rfc 7638#section_3": [[8, "index-101", false], [8, "index-37", false], [14, "index-10", false], [14, "index-32", false], [18, "index-1", false], [18, "index-13", false]], "rfc 7800": [[16, "index-11", false], [18, "index-10", false], [18, "index-22", false]], "rfc 8174": [[16, "index-12", false]], "rfc 8259": [[8, "index-63", false]], "rfc 8414": [[7, "index-8", false], [18, "index-11", false], [18, "index-23", false]], "rfc 8414#section-2": [[7, "index-1", false], [7, "index-2", false], [7, "index-4", false], [7, "index-6", false], [7, "index-7", false]], "rfc 8725": [[8, "index-81", false], [16, "index-13", false]], "rfc 9027": [[8, "index-26", false]], "rfc 9068": [[8, "index-102", false], [8, "index-104", false], [8, "index-106", false], [8, "index-108", false], [8, "index-110", false], [8, "index-113", false], [8, "index-115", false]], "rfc 9101": [[8, "index-10", false], [8, "index-12", false], [8, "index-14", false], [8, "index-19", false], [8, "index-20", false], [8, "index-3", false]], "rfc 9110": [[8, "index-34", false], [8, "index-89", false], [8, "index-90", false]], "rfc 9126": [[8, "index-1", false], [8, "index-11", false], [8, "index-13", false], [8, "index-15", false], [8, "index-16", false], [8, "index-17", false], [8, "index-21", false], [8, "index-22", false], [8, "index-23", false], [8, "index-24", false], [8, "index-38", false], [8, "index-40", false], [8, "index-42", false], [8, "index-44", false], [8, "index-53", false], [8, "index-55", false], [8, "index-57", false], [8, "index-59", false], [8, "index-6", false], [8, "index-64", false], [8, "index-65", false], [8, "index-67", false], [8, "index-9", false], [14, "index-11", false], [14, "index-13", false], [14, "index-15", false], [14, "index-17", false], [14, "index-25", false], [14, "index-33", false], [14, "index-35", false], [14, "index-37", false], [14, "index-43", false], [18, "index-14", false], [18, "index-16", false], [18, "index-18", false], [18, "index-2", false], [18, "index-20", false], [18, "index-4", false], [18, "index-6", false], [18, "index-8", false]], "rfc 9126#as_metadata": [[7, "index-0", false]], "rfc 9126#section-2.3": [[8, "index-66", false]], "rfc 9207": [[8, "index-71", false], [16, "index-16", false]], "rfc 9396": [[8, "index-4", false], [8, "index-50", false], [8, "index-8", false]], "rfc 9449": [[8, "index-118", false], [8, "index-120", false], [8, "index-27", false], [8, "index-28", false], [8, "index-31", false], [8, "index-32", false], [8, "index-33", false], [8, "index-75", false], [8, "index-98", false], [16, "index-15", false]]}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [1, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19], "0": [4, 6, 7, 8, 9, 11, 12, 13, 16, 17, 18, 19], "00": [6, 11], "00z": 6, "01": [6, 9, 12, 14], "02": [6, 9, 12], "03": [7, 11], "04": [8, 16], "04a98be3": [12, 13], "05z": [9, 12], "08": [9, 12], "08b3f1ca5517019767be3dee3bb06145": [9, 12], "09": [9, 12], "091535f699ea575c7937fa5f0f454ae": [12, 13], "095vprpttn4qmoqroa": 6, "0a6da0af437e2943f1836f31c678d89298e9": 6, "0b434530": 14, "0cdfe077400432c055a2b69596c90": 6, "0e5f0b6b33418e508740771e82f893372eaf5b2445bc4c84dcf08b005e9493fc": [9, 12], "0f1571a97ffb799cc8fcdf2ba4fc2909929": 6, "0fe3cbe0": 18, "1": [2, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19], "10": [6, 8, 9, 12, 13, 16, 18], "1004": [6, 9, 12], "1024": 8, "11": [6, 7, 8, 9, 12, 13, 18], "11aa7273a2d2daa973f5951f0c34c2fba": 6, "12": [6, 8, 9, 12, 13, 18], "128": [0, 8, 12, 13], "12pt": 6, "13": [4, 8, 9, 12, 13, 14, 16, 18], "137f903174253c4585358267aae2ea4": [9, 12], "14": [4, 8, 12, 13, 16, 18], "14888": 0, "15": [8, 12, 13], "1504699136": 14, "1504700136": [12, 13], "1504785536": 14, "16": [6, 8, 9, 12, 13], "1649373279": 17, "1649375259": 17, "1649450746": 17, "1649623546": 17, "1672418465": [12, 13], "1672422065": [12, 13], "167fe": [9, 12], "1683000000": 6, "1686645115": 18, "1686652315": 18, "1687171759": 19, "1687281195": 18, "1687288395": 18, "1698744039": 14, "1698744139": 14, "17": [8, 12, 13, 18], "1705570055": 8, "1709290159": 19, "1715842560": 8, "1715842860": 8, "1718207217": [7, 11], "17487": 16, "1749743216": [7, 11], "1778914560": 8, "18": [8, 12, 13, 18], "18013": [4, 6, 9, 12, 16], "185d84dfb71ce9b173010ddd62174fb": [9, 12], "186": 0, "1883000000": 6, "18bdea0988cb": [12, 13], "19": [5, 8, 12, 13], "1956": [6, 9, 12], "1980": 6, "1986": 16, "1997": 16, "1999": 16, "1_0": 7, "1ad0d6a7313efdc38fcd765852fa2bd43debf48bf5a580d": 6, "1fbao": 8, "1fed7190d2975ab79c072e6f1d9d52436059d1fc959d55baf74f057d89b10fcc0dc77a50d433d4c76ddf26223c5560c4ab123b5cb5eb805a90036aa147493076": [9, 12], "1h0cwdyggvu8w": 19, "1jeqsisimnydii6ilatmju2in19": 8, "1knr9ar3mzmokyty8brvriue85nixryx4xd3k4jw7vi": 17, "2": [1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19], "20": [6, 9, 11, 12, 13, 16], "200": [8, 12, 13, 14, 18], "2002": 16, "2008": 4, "201": [8, 12, 13], "2013": 18, "2014": 16, "2015": 16, "2016": 16, "2017": [9, 12, 16], "2018": [9, 12], "2019": [9, 12], "202": [8, 12, 13], "2020": 16, "2021": 16, "20212223": [9, 12], "2022": 16, "2023": [6, 9, 12, 16], "2024": [5, 6, 9, 12, 16], "204": [8, 18], "21": [8, 12, 13], "2119": 16, "22": [6, 8, 9, 12, 13], "22t00": 6, "22t06": 6, "23": [6, 8, 9, 12, 13, 16], "24": [6, 8, 9, 12, 13, 14, 16, 17, 18], "247c93ddb942": 8, "24t14": [9, 12], "25": [12, 13], "256": [0, 6, 7, 8, 9, 11, 12, 14, 17, 18, 19], "26": [12, 13], "2616": 16, "27": [12, 13], "28": [12, 13], "29": [12, 13], "29227872ceb49923d267b5f4bade6d387b42ac2dc4b2ae26c9013067fee7018a": [9, 12], "2c128e4d": [12, 13], "2e40bcd6799008085ffb1a1f3517efee335298fd976b3e655bfb3f4eaa11d171": 6, "2f": [8, 12, 13], "2fcb": [12, 13], "2feaa": 8, "2freli": [12, 13], "2frequest_uri": [12, 13], "2g": 8, "2glc42skqvecfgfrynrn9w": 6, "2hnofs3ync9tjicaivhwlvuj3axwggz_98urfaqme": 17, "2ow9rp35yrqzhrtnp86l": 8, "2w3": [12, 13], "3": [0, 1, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19], "30": 6, "300": [8, 9, 12], "302": [8, 12, 13], "308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97b": [9, 12], "3082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb7d518bd9a519583e082d67effff06565804fc09abf0e4a08e699c9dba3796285a15f68e40ac7f9fc7700a15153a4065300a06082a8648ce3d040302034800304502210099b7d62e6bf7b1823db3713df889bf73e70bb4d9c58c21e92c58d2f1beffe932022058d039747a00d70e6d66be4797e6142b3608a014ee09b7b79af2cae2aaf27788": [9, 12], "30820215308201bca003020102021404ad30c": 6, "31579c8b0e7d": [12, 13], "3166": 6, "319": 6, "32": [8, 12, 13], "32f54163": [12, 13], "33": [6, 9, 12], "3339": 16, "36": [11, 16, 17], "3600": 8, "38": 18, "384": [0, 6], "3986": 16, "3a": [8, 12, 13], "3abwc4jk": 8, "3agrant": 18, "3aietf": [8, 18], "3ajwt": 18, "3aoauth": [8, 18], "3aparam": [8, 18], "3arequest_uri": 8, "3be39b69": [12, 13], "3e6c07ddcb03": [12, 13], "3wljk1ejuz2": 8, "3zfqn6kuntjhjbgiyxhyqxie0wrfiqyxnuio2a0bfy4ewystd7znccmforojmmhqwccjnadqbkg7beywbq4jpg": 8, "4": [0, 4, 6, 7, 8, 9, 12, 13, 14, 18], "40": 6, "400": [8, 12, 13, 14], "401": [12, 13], "4025": 8, "403": [12, 13], "4086c1379975f805f1b1f4975e6a1265": [9, 12], "412": 6, "4122": [8, 14], "41aa": [12, 13], "43": 8, "43a5": 8, "44b5": 18, "45efef742b2c4837a9a3b0e1d05a6917": [9, 12], "47b982369791d08003a7283f059cb0d1": 8, "48f1": [12, 13], "49bb": [7, 11], "4a4b4cc64ec9299c1a2501ea449f577005e9f7a60408057c07a7c67fb151e5f5": [9, 12], "4c40": 14, "4cd3": [12, 13], "4cf5": [12, 13], "4dfd": 14, "4e5b": 18, "4fzkwhilki": 8, "4hnpti": 18, "4ljp": 8, "5": [4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18], "50": 6, "500": [12, 13, 14], "503": 14, "509": [1, 6, 17], "512": [0, 6, 8], "521": 0, "5280": 6, "53c15c57b3b076e788795829190220b4": 6, "53e29d0ddbbc7d2306a32bdbe2e56e51": [9, 12], "54": [9, 12], "5639": 0, "5646": [6, 7], "56z": 6, "58a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9": [9, 12], "59fe68db795dee4c20976380ea247705": [9, 12], "5a88d182bce5f42efa59943f33359d2e8a968ff289d93e5fa444b624343": [9, 12], "5b": 8, "5izghriiwgimzhbwlsev9uyw1liiwgiljvc3npil0": 6, "5t5yypbhn": [18, 19], "6": [6, 8, 9, 11, 12, 13, 17, 18], "60": 8, "6059ff1ce27b4997b4ade1de7b01dc60": 6, "60a8": 18, "61fbc6c8ad24ec86a78bb4e9ac377dd2b7c711d9f2eb9afd4aa0963662847a": [9, 12], "646d": 18, "6749": [8, 14, 16], "6ac1": [12, 13], "6b3d194fc131": [7, 11], "6d44f21ee875f2c1d502b43198e5a152": [9, 12], "6d8025d2f02a5e7e1406fb6aaeb67f9ede9b07191a53f3e23b77c528223a94e2": [9, 12], "6ec69324": 18, "6f204f7e": 14, "6hjvrcxnzf0slu6uknmzhol": 6, "6ij7tm": 6, "6s0a": 18, "7": [6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18], "7159": 16, "7166": [12, 13], "73690d92dcaa61b0203870f67c6aa9fdfea889b6f0c720de757b4b0a8516a206": [9, 12], "74c75a5ef760": 14, "7515": [6, 7, 8, 11, 14, 16], "7516": [0, 8, 12, 13, 14, 16, 18], "7517": [8, 12, 13, 14, 16, 17, 19], "7518": [0, 16], "7519": [6, 8, 12, 13, 14, 16, 17, 18], "7521": [8, 16], "7523": 18, "7591": 11, "7636": [7, 8], "7638": [8, 14, 16, 18, 19], "765": 4, "7800": [16, 18], "78824fbd6fbba88a2aab44df8b6f5e9759126d87d1f4415995e658fd9239e1f": [9, 12], "7e": 8, "7fb0": [12, 13], "8": [6, 8, 9, 11, 12, 13, 18], "814e": 14, "8174": 16, "8259": 8, "8368": [7, 11], "8414": [7, 18], "86400": 8, "864000": 8, "86b8": [12, 13], "8725": [8, 16], "8808": 18, "8949": 6, "89jkwhilrt": 8, "8d9066f6c8da16619867cd4e2fab0c88": [9, 12], "8jjozbfovmnvq3hflmpwy4o19gpxs61fwhjzebu589": 6, "8mxk1ealyznwh": 8, "9": [6, 8, 9, 11, 12, 13, 18], "9027": 8, "9052": 6, "9068": 8, "9101": [8, 12, 13], "9110": 8, "9126": [7, 8, 14, 18], "917dd5391bd9": 18, "9207": [8, 16], "921b": [12, 13], "9360": 6, "9378": 8, "9396": 8, "93d8": [12, 13], "9449": [8, 16], "951574aee1bb7907ae1ec3109db2b225": 8, "960cb15a2ea9b68e5233ce902807aa95": 6, "987654321": [9, 12], "98b7": 14, "990cba2069fa1b33b8d6ae910b6549dc": [9, 12], "9biiwgimjpcnrox2rhdguilcaimtk4mc0wms0xmcjd": 6, "9d155319408c": 14, "9d3774bd5994ccfed248674b32a4f76a": 6, "9t2lq": [12, 13], "9tjicaivhwlvuj3axwggz_9": [12, 13], "A": [4, 6, 7, 8, 9, 12, 13, 14, 16, 17, 18, 19], "As": [4, 7, 8, 18], "At": [17, 18], "By": [3, 6, 19], "For": [4, 5, 6, 8, 9, 11, 12, 13, 14, 17, 18, 19], "IT": [3, 4, 5, 6, 7, 9, 10, 12, 19], "If": [1, 3, 6, 7, 8, 9, 12, 13, 14, 17, 18], "In": [1, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18], "It": [1, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19], "Its": [4, 18], "NOT": [0, 1, 4, 6, 8, 10, 11, 12, 13, 14, 17, 18], "No": [4, 5, 8, 17, 18], "Not": [12, 13], "On": [8, 18], "One": 14, "Such": [12, 13], "The": [0, 1, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19], "Their": 4, "Then": 14, "There": [7, 12, 13, 17], "These": [4, 11, 12, 13, 14, 17, 18, 19], "To": [7, 8, 12, 13, 14, 17, 18, 19], "_2ysumwfjwmranlo15r6dibxervdy_npjuwakjmfdoc": 14, "_qt5": 17, "_sd": 6, "_sd_alg": 6, "_v3bjjelki0tnpbc4yss7yjupwszzmpq0zq9n5zj8xgq_t3nn9bghuyvzegr60xokqbnqmms4iygpol7ekespw": 8, "a10126": [9, 12], "a128cbc": [0, 7], "a128gcm": 7, "a128kw": 0, "a192cbc": 7, "a192gcm": 7, "a2": 8, "a2395ec214350c26066306e23279b3a": [9, 12], "a256cbc": [0, 7], "a256gcm": 7, "a256kw": 0, "a25e1a5b915d2d6eafee9674e0232939": [9, 12], "a26776657273696f6e63312e306b646f63526571756573747381a26c6974656d7352657175657374d818590152a267646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e4954a375766572696669636174696f6e2e65766964656e6365f4781c766572696669636174696f6e2e6173737572616e63655f6c6576656cf4781c766572696669636174696f6e2e74727573745f6672616d65776f726bf4716f72672e69736f2e31383031332e352e31ab76756e5f64697374696e6775697368696e675f7369676ef47264726976696e675f70726976696c65676573f46f646f63756d656e745f6e756d626572f46a69737375655f64617465f46f69737375696e675f636f756e747279f47169737375696e675f617574686f72697479f46a62697274685f64617465f46b6578706972795f64617465f46a676976656e5f6e616d65f468706f727472616974f46b66616d696c795f6e616d65f46a726561646572417574688443a10126a11821590129308201253081cda00302010202012a300a06082a8648ce3d0403023020311e301c06035504030c15536f6d652052656164657220417574686f72697479301e170d3233313132343130323832325a170d3238313132323130323832325a301a3118301606035504030c0f536f6d6520526561646572204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004aa1092fb59e26ddd182cfdbc85f1aa8217a4f0fae6a6a5536b57c5ef7be2fb6d0dfd319839e6c24d087cd26499ec4f87c8c766200ba4c6218c74de50cd1243b1300a06082a8648ce3d0403020347003044022048466e92226e042add073b8cdc43df5a19401e1d95ab226e142947e435af9db30220043af7a8e7d31646a424e02ea0c853ec9c293791f930bf589bee557370a4c97bf6584058a0d421a7e53b7db0412a196fea50ca6d4c8a530a47dd84d88588ab145374bd0ab2a724cf2ed2facf32c7184591c5969efd53f5aba63194105440bc1904e1b9": [9, 12], "a3": 8, "a30063312e30018201d818584ba4010220012158205a88d182bce5f42efa59943f33359d2e8a968ff289d93e5fa444b624343167fe225820b16e8cf858ddc7690407ba61d4c338237a8cfcf3de6aa672fc60a557aa32fc670281830201a300f401f50b5045efef742b2c4837a9a3b0e1d05a6917": [9, 12], "a366737461747573006776657273696f6e63312e3069646f63756d656e747381a267646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316c6973737565725369676e6564a26a697373756572417574688443a10126a1182159021930820215308201bca003020102021404ad06a30c1a6dc6e93be0e2e8f78dcafa7907c2300a06082a8648ce3d040302305b310b3009060355040613025a45312e302c060355040a0c25465053204d6f62696c69747920616e64205472616e73706f7274206f66205a65746f706961311c301a06035504030c1349414341205a65746573436f6e666964656e73301e170d3231303932393033333034355a170d3232313130333033333034345a3050311a301806035504030c114453205a65746573436f6e666964656e7331253023060355040a0c1c5a65746f70696120436974792044657074206f662054726166666963310b3009060355040613025a453059301306072a8648ce3d020106082a8648ce3d030107034200047c5545e9a0b15f4ff3ce5015121e8ad3257c28d541c1cd0d604fc9d1e352ccc38adef5f7902d44b7a6fc1f99f06eedf7b0018fd9da716aec2f1ffac173356c7da3693067301f0603551d23041830168014bba2a53201700d3c97542ef42889556d15b7ac4630150603551d250101ff040b3009060728818c5d050102301d0603551d0e04160414ce5fd758a8e88563e625cf056bfe9f692f4296fd300e0603551d0f0101ff040403020780300a06082a8648ce3d0403020347003044022012b06a3813ffec5679f3b8cddb51eaa4b95b0cbb1786b09405e2000e9c46618c02202c1f778ad252285ed05d9b55469f1cb78d773671f30fe7ab815371942328317c59032ad818590325a667646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316776657273696f6e63312e306c76616c6964697479496e666fa3667369676e6564c074323032332d30322d32325430363a32333a35365a6976616c696446726f6dc074323032332d30322d32325430363a32333a35365a6a76616c6964556e74696cc074323032342d30322d32325430303a30303a30305a6c76616c756544696765737473a2781865752e6575726f70612e65632e65756469772e7069642e31ac015820a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a025820cd372fb85148700fa88095e3492d3f9f5beb43e555e5ff26d95f5a6adc36f8e6035820e67e72111b363d80c8124d28193926000980e1211c7986cacbd26aacc5528d48045820f7d062d662826ed95869851db06bb539b402047baee53a00e0aa35bfbe98265d0658202a132dbfe4784627b86aa3807cd19cfeff487aab3dd7a60d0ab119a72e736936075820bdca9e8dbca354e824e67bfe1533fa4a238b9ea832f23fb4271ebeb3a5a8f7200858202c0eaec2f05b6c7fe7982683e3773b5d8d7a01e33d04dfcb162add8bd99bee9a095820bfe220d85657ccec3c67e7db1df747e9148a152334bb6d4b65b273279bcc36ec0a582018e38144f5044301d6a0b4ec9d5f98d4cd950e6ea2c29b849cbd457da29b6ad30b58203c71d2f0efa09d9e3fbbdffd29204f6b292c9f79570aef72dd86c91f7a3aa5c50c582065743d58d89d45e52044758f546034fd13a4f994bc270cdfa7844f74eb3f4b6e0d5820b4a8eb5d523bffa17b41bda12ddc7da32ae1e5f7ff3dcc394a35401f16919bbf781b65752e6575726f70612e65632e65756469772e7069642e69742e31a10e58209d6c11644651126c94acdaf0803e86d4c71d15d3b2712a14295416734efd514d6d6465766963654b6579496e666fa1696465766963654b6579a401022001215820ba01aea44eee1e338eb2f04e279dbd51b34655783ee185150838c9a7a7c4db7122582025ba0044439a3871a7b975a0994a85e79b705a9ac263b3fe899b0a93412ee8c96f646967657374416c676f726974686d675348412d32353658400813c28fd62f2602cbc14724e5865733c44a0fca589b55c085ec9d5c725d6cce25ba0044439a3871a7b975a0994a85e79b705a9ac263b3fe899b0a93412ee8c96a6e616d65537061636573a2781865752e6575726f70612e65632e65756469772e7069642e3188d818586da4686469676573744944016672616e646f6d5820156df9227ad341eaa61aabd301106fd21bdc18820e01dfc16bcf5fecc447111b71656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d30322d3232d818586fa4686469676573744944026672616e646f6d5820a3a1f13f05544d03a5b50b5fdb78465808393bcf3b7953a345fe28f820c7be0d71656c656d656e744964656e7469666965726d69737375616e63655f646174656c656c656d656e7456616c7565d903ec6a323032332d30322d3232d8185866a4686469676573744944036672616e646f6d5820852591f90f2c9ded57a03632e2c1322ab52a082a431e71a4149a6830c8f1ad0c71656c656d656e744964656e7469666965726f69737375696e675f636f756e7472796c656c656d656e7456616c7565624954d818587ca4686469676573744944046672616e646f6d5820d1d587b3512acce15c4f6b20944ceb002a464e4a158389788563408873c3fce571656c656d656e744964656e7469666965727169737375696e675f617574686f726974796c656c656d656e7456616c7565764d696e69737465726f2064656c6c27496e7465726e6fd8185864a4686469676573744944056672616e646f6d582094fdd7609c0e73dc8589b5cab11e1d9058cf8bff8a336da5f81fcba055396a0f71656c656d656e744964656e7469666965726a676976656e5f6e616d656c656c656d656e7456616c7565654d6172696fd8185865a4686469676573744944066672616e646f6d5820660c0a7bf79e0e0261ca1547a4294fb808aa70738f424b13ab1b9440b566ae1371656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756565526f737369d818586ba4686469676573744944076672616e646f6d5820315c53491286488fa07f5c2ce67135ef5c9959c3469c99a14e9b6dc924f9eba571656c656d656e744964656e746966696572696269727468646174656c656c656d656e7456616c7565d903ec6a313935362d30312d3132d818587da4686469676573744944086672616e646f6d5820764ef39c9d01f3aa6a87f441603cfe853fba3cee3bc2c168bcc9e96271d6e06371656c656d656e744964656e74696669657269756e697175655f69646c656c656d656e7456616c7565781e78787878787878782d7878782d787878782d787878787878787878787878781b65752e6575726f70612e65632e65756469772e7069642e69742e3181d8185877a46864696765737449440d6672616e646f6d5820717df3f583b1484366c33a1f869f2b5d201d466a8b589c79ab1a2d85e595432571656c656d656e744964656e7469666965726d7461785f69645f6e756d6265726c656c656d656e7456616c75657554494e49542d585858585858585858585858585858": 6, "a36776657273696f6e63312e3069646f63756d656e747381a367646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6c6973737565725369676e6564a26a6e616d65537061636573a2746f72672e69736f2e31383031332e352e312e495483d81858f7a46864696765737449440b6672616e646f6d506d44f21ee875f2c1d502b43198e5a15271656c656d656e744964656e74696669657275766572696669636174696f6e2e65766964656e63656c656c656d656e7456616c756581a2647479706571656c656374726f6e69635f7265636f7264667265636f7264bf6474797065781f68747470733a2f2f657564692e77616c6c65742e70646e642e676f762e697466736f75726365bf716f7267616e697a6174696f6e5f6e616d65754d6f746f72697a7a617a696f6e6520436976696c656f6f7267616e697a6174696f6e5f6964656d5f696e666c636f756e7472795f636f6465626974ffffd8185866a4686469676573744944046672616e646f6d50185d84dfb71ce9b173010ddd62174fbe71656c656d656e744964656e746966696572781c766572696669636174696f6e2e74727573745f6672616d65776f726b6c656c656d656e7456616c7565656569646173d8185865a4686469676573744944006672616e646f6d50137f903174253c4585358267aae2ea4e71656c656d656e744964656e746966696572781c766572696669636174696f6e2e6173737572616e63655f6c6576656c6c656c656d656e7456616c75656468696768716f72672e69736f2e31383031332e352e318bd8185852a46864696765737449440c6672616e646f6d5053e29d0ddbbc7d2306a32bdbe2e56e5171656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756563446f65d8185855a4686469676573744944036672616e646f6d50990cba2069fa1b33b8d6ae910b6549dc71656c656d656e744964656e7469666965726a676976656e5f6e616d656c656c656d656e7456616c756567416e746f6e696fd818585ba46864696765737449440a6672616e646f6d504086c1379975f805f1b1f4975e6a126571656c656d656e744964656e7469666965726a69737375655f646174656c656c656d656e7456616c7565d903ec6a323031392d31302d3230d818585ca4686469676573744944016672616e646f6d50ab4ca30c918dd2fd0bf35242c15fa2d871656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d31302d3230d8185855a4686469676573744944076672616e646f6d508d9066f6c8da16619867cd4e2fab0c8871656c656d656e744964656e7469666965726f69737375696e675f636f756e7472796c656c656d656e7456616c7565624954d818587ea4686469676573744944056672616e646f6d5059fe68db795dee4c20976380ea24770571656c656d656e744964656e7469666965727169737375696e675f617574686f726974796c656c656d656e7456616c75657828497374697475746f20506f6c696772616669636f2065205a656363612064656c6c6f20537461746fd818585ba4686469676573744944026672616e646f6d5008b3f1ca5517019767be3dee3bb0614571656c656d656e744964656e7469666965726a62697274685f646174656c656c656d656e7456616c7565d903ec6a313935362d30312d3230d818585ca4686469676573744944096672616e646f6d50a2395ec214350c26066306e23279b3ae71656c656d656e744964656e7469666965726f646f63756d656e745f6e756d6265726c656c656d656e7456616c756569393837363534333231d8185850a4686469676573744944066672616e646f6d50a25e1a5b915d2d6eafee9674e023293971656c656d656e744964656e74696669657268706f7274726169746c656c656d656e7456616c75654420212223d81858eea46864696765737449440d6672616e646f6d50eeed6a3b856563627589a360939d12f771656c656d656e744964656e7469666965727264726976696e675f70726976696c656765736c656c656d656e7456616c756582a37576656869636c655f63617465676f72795f636f646561416a69737375655f64617465d903ec6a323031382d30382d30396b6578706972795f64617465d903ec6a323032342d31302d3230a37576656869636c655f63617465676f72795f636f646561426a69737375655f64617465d903ec6a323031372d30322d32336b6578706972795f64617465d903ec6a323032342d31302d3230d818585ba4686469676573744944086672616e646f6d50c0ef486b2a194ed3cbf7f354fd40092171656c656d656e744964656e74696669657276756e5f64697374696e6775697368696e675f7369676e6c656c656d656e7456616c756561496a697373756572417574688443a10126a118215901423082013e3081e5a00302010202012a300a06082a8648ce3d040302301a3118301606035504030c0f5374617465204f662055746f706961301e170d3233313132343134353430345a170d3238313132323134353430345a30383136303406035504030c2d5374617465204f662055746f7069612049737375696e6720417574686f72697479205369676e696e67204b65793059301306072a8648ce3d020106082a8648ce3d03010703420004c338ec1000b351ce8bcdfc167450aeceb": [9, 12], "a5c1": 8, "a5ivpgbos5tmvva": 6, "a697": 18, "a6a119f7cacac0b8c6aacac747fd3fe7e50b6d9bb8a507fda79f0df6646f285d": [9, 12], "a766d85790ea": 18, "aal": [4, 12, 13, 18], "aal_values_support": 19, "aarc": 8, "aarma": 3, "ab4ca30c918dd2fd0bf35242c15fa2d8": [9, 12], "abil": [4, 15, 17, 18, 19], "abilitazion": 7, "abl": [6, 8, 10, 12, 13, 14, 17, 18], "about": [1, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15, 18, 19], "abov": [6, 7, 8, 9, 12, 17, 18], "absolut": 14, "abstract": 17, "abvdfcnxt0z5rrwdxzsuhuuxz3gm2vcezleyij61ka": 6, "accept": [3, 8, 9, 12, 13, 14], "access": [1, 3, 4, 5, 6, 10, 12, 13, 14, 15, 17, 18, 19], "access_token": 8, "accommod": [12, 13, 17], "accompagnator": 7, "accomplish": [1, 8, 19], "accord": [1, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "account": 17, "accredit": 4, "achiev": 18, "acknowledg": 5, "acquir": [15, 18, 19], "acquisit": 18, "acr_values_support": 7, "acronym": 5, "across": [5, 10, 15], "act": [4, 7, 8, 12, 13, 17], "action": [4, 8, 9, 12, 13, 14, 18, 19], "activ": [3, 9, 12, 13, 14, 15, 17, 18, 19], "actor": [4, 12, 13, 15, 18, 19], "actual": [12, 13, 18, 19], "ad": [4, 6, 8, 12, 13], "adapt": 17, "add": 1, "addit": [6, 7, 8, 10, 14, 17], "addition": [6, 12, 13, 18], "address": [8, 12, 13, 14, 17, 18], "adequ": [8, 17, 19], "adher": [4, 7, 12, 13, 17, 18, 19], "adjust": 17, "administ": 4, "administr": [3, 6, 8, 14, 15, 17], "adopt": 5, "advanc": [5, 17], "advis": [8, 12, 13], "ae": 0, "ae84834f389ee69888665b90a3e4fcc": 6, "af": 6, "af9a": [12, 13], "afd09e720b918cedc2b8a881950bab6a1051e18ae16a814d51e609938663d5e1": [9, 12], "aftauxhmvd9pyqtj6fmuhc": 6, "after": [1, 8, 9, 12, 13, 14, 18, 19], "ag": [12, 13], "again": [3, 8, 12, 13, 17], "against": [1, 8, 17, 18], "agent": [8, 12, 13], "agre": [9, 12, 17], "agreement": [0, 4, 9, 12], "aid": 17, "aim": [4, 5, 6, 8, 18], "ajx": 6, "akhaw": 16, "alen": 3, "alg": [0, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "alg_values_support": 18, "algorithm": [5, 6, 7, 8, 11, 12, 13, 14, 16, 17, 18, 19], "alias": [12, 13], "alifuoco": 3, "align": [5, 12, 13, 17], "all": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "allow": [1, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19], "allowed_leaf_entity_typ": 17, "alon": 8, "along": [6, 8, 9, 12, 13, 14, 18, 19], "alpha": 6, "alphanumer": 8, "alreadi": [4, 8, 14, 18], "also": [3, 4, 6, 7, 8, 11, 12, 13, 14, 15, 17, 18, 19], "altern": [4, 12, 13], "altmann": 3, "alwai": [3, 4, 10, 15, 17], "ambigu": 16, "amend": 3, "american": 16, "amir": 3, "amministrazioni": 16, "among": [4, 14, 17], "amount": [8, 17], "an": [1, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19], "anagraph": 6, "analysi": 4, "anchor": [5, 7, 8, 11, 19], "andrea": 3, "android": [4, 18, 19], "anew": 17, "ani": [4, 6, 8, 9, 12, 13, 14, 17, 18], "annex": [1, 8], "annotazioni": 7, "anonym": [4, 10, 17], "anoth": [4, 7, 12, 13, 15, 18], "anpr": 6, "antonio": [9, 12], "anymor": [12, 13, 18], "anyon": 3, "api": [4, 5, 8, 12, 13, 18, 19], "apolog": 3, "apologi": 3, "app": [4, 8, 9, 12, 18, 19], "appear": [4, 6], "append": [12, 13], "appendix": 0, "appl": [4, 18], "appli": [8, 12, 13, 14, 17, 18], "applic": [1, 3, 4, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19], "application_typ": [7, 11], "approach": [3, 6, 15, 17, 18], "appropri": [9, 12, 13, 14, 18], "april": 16, "ar": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "arbitrari": 4, "architectur": [4, 5, 8, 15, 16, 17, 18, 19], "area": 18, "arf": [4, 5, 6, 16, 17, 18], "arial": 6, "aris": [12, 13], "arrai": [6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "articl": 4, "artifact": [4, 17], "as_metadata": 7, "ascii": 8, "ask": [9, 12, 13, 14, 19], "aspect": [12, 13], "assert": [4, 5, 6, 8, 16, 17, 18, 19], "assess": [4, 17, 18], "assign": [10, 12, 13, 14, 17], "associ": [4, 7, 11, 14, 17, 18, 19], "assum": [8, 17], "assumpt": 8, "assur": [4, 6, 12, 13, 14, 16, 19], "assurance_level": [6, 9, 12], "asymmetr": [0, 8, 18], "ath": 8, "attach": [8, 17], "attack": [1, 8, 10, 17, 18], "attain": 17, "attempt": [12, 13, 18], "attend": 7, "attest": [1, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16], "attest_jwt_client_auth": 7, "attestkei": 4, "attribut": [1, 4, 5, 6, 8, 9, 12, 13, 14, 17, 19], "aud": [8, 12, 13, 14, 18], "audit": [1, 17], "audit_rest_02": 1, "autent": [12, 13], "auth": [7, 8, 16], "authent": [0, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19], "authentic_sourc": 6, "authenticator_assurance_level": 4, "authet": 6, "author": [1, 4, 5, 6, 7, 11, 14, 15, 16, 17, 18, 19], "authorit": 4, "authority_hint": [7, 11, 17, 19], "authorization_cod": [7, 8], "authorization_detail": 8, "authorization_encrypted_response_alg": 7, "authorization_encrypted_response_enc": 7, "authorization_endpoint": [7, 12, 13, 18], "authorization_serv": [7, 17], "authorization_signed_response_alg": [7, 11], "authorization_signing_alg_values_support": 7, "authz": [12, 13], "auto": 8, "autom": [4, 14, 17], "automat": [7, 17], "autonom": 17, "autonomi": 17, "autorit\u00e0": 7, "avail": [1, 3, 8, 12, 13, 17, 18, 19], "avoid": 15, "aw8ixq": 6, "awar": 14, "awrlci5legftcgxllm9yzyisicjpyxqioiaxnjgzmdawmdawlcaizxhwijogmtg4mzaw": 6, "awz": [12, 13], "azpx7u7r": 8, "b": [9, 12, 16], "b01b8208d9e6cc834d87dc356ab50170": 8, "b0d43e4e2ea534e4d5304e64bcf7a0f13e2c8ee8304b9cd23aba4909652a4647": [9, 12], "b16e8cf858ddc7690407ba61d4c338237a8cfcf3de6aa672fc60a557aa32fc67": [9, 12], "b3jniiwgimlhdci6ide2odmwmdawmdasicjlehaioiaxodgzmdawmdawlcaic3viijog": 6, "b6672b6149af": 8, "b6672b6149bg": 8, "b820963964e53af064686dd9218303494a": 6, "back": [4, 8, 14, 18], "backend": [4, 18], "backup": 5, "backward": 6, "bad": [8, 12, 13, 14], "balanc": [10, 12, 13], "band": [14, 17], "base": [3, 4, 8, 9, 12, 13, 14, 15, 16, 17, 18], "base64": [7, 18], "base64url": [6, 8, 12, 13, 14, 18], "basi": 16, "basic": 19, "bastian": 16, "bastien": 3, "bb6e6c68d1b4b4ec5a2ae9206f5t4": 6, "bbc77e6cca981a3ad0c3e544edf86": 6, "bc5568239e35ce9ff8798c27ffdcd757b134b679f0fe05729aa3491381912e65": [9, 12], "bcp": [4, 16], "bcp47": 7, "bearer": 18, "becaus": [12, 13, 14, 18], "becom": [8, 14, 18, 19], "bedrock": 4, "been": [3, 8, 12, 13, 14, 18], "befor": [3, 4, 8, 12, 13, 17], "begin": [8, 9, 12, 13], "behalf": [4, 14, 17], "behavior": 17, "behind": 17, "being": [4, 6, 8, 9, 12, 13, 18], "belong": 4, "below": [0, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "berner": 16, "best": 16, "better": [12, 13, 14], "between": [1, 4, 8, 9, 10, 12, 13, 14, 15, 17, 18], "beyond": [14, 17], "bfue3h": 6, "bgcioiaic2hhlti1niisicjjbmyioib7imp3ayi6ihsia3r5ijogikvdiiwgimnydii6": 6, "binari": 6, "bind": [4, 8, 12, 13, 17, 18], "biometr": 19, "birth": [6, 7], "birth_dat": [6, 7, 9, 12], "bit": [0, 8, 12, 13, 16], "bith_dat": [12, 13], "bitsr": 6, "black": 6, "ble": [9, 12], "bleoption": [9, 12], "block": [0, 9, 12, 14], "bluetooth": [9, 12], "bodi": [4, 8, 12, 13, 14, 17, 18], "bomgktw1rbikntw8fzx_bel4ybandr6ahsdgpatfcig": 6, "bool": [9, 12], "boolean": [7, 14, 18], "bootload": 18, "border": [15, 17], "born": 6, "both": [1, 6, 8, 9, 12, 13, 14, 15, 17, 18, 19], "bound": [4, 6, 7, 8, 14, 17, 18], "bradlei": 16, "bradner": 16, "brai": 16, "brainpool": 0, "brainpoolp256r1": 0, "brainpoolp384r1": 0, "brainpoolp512r1": 0, "branch": 3, "braun": 16, "breach": 17, "brief": 3, "browser": 8, "bstr": [6, 9, 12], "build": 17, "built": 17, "busi": 3, "bwc4jk": 8, "by0": 6, "byleaf": 17, "byte": [6, 9, 12], "bytrustanchor": 17, "bzmxamz6rna4wtjevzbslwzjtwvxd2u3ruxhdkdvse13tujwdte0rsisicjwuuktuzft": 6, "c": 16, "c05yv0jimhhxwg9htnk1oulps0nbcwtzbvffbyj9": 8, "c0ef486b2a194ed3cbf7f354fd400921": [9, 12], "c3npil0": 6, "c3rhdhvzijogeyjzdgf0dxnfyxnzzxj0aw9uijogeyjjcmvkzw50awfsx2hhc2hfywxn": 6, "c5f73e250fe869f24d15118acce286c9bb56b63a443dc85af653cd73f6078b1f": 6, "c65c": 8, "c8b708728e4c5756e35c03aeac257ca878d1f717d7b61f621be4d36dbd9b9c16": 6, "c950c0e6fdeb5de50a50096b247af03c": 8, "c_nonc": 8, "c_nonce_expires_in": 8, "c_xmtn3db9t0jjjptqeba": 6, "cab": 4, "cach": 8, "calcul": [6, 8, 9, 12], "call": [12, 13, 17], "campbel": 16, "can": [1, 3, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19], "candid": 17, "cannot": [4, 8, 12, 13, 14, 17, 18], "capabl": [8, 12, 13, 17, 18, 19], "capit": 4, "card": [4, 7, 18], "carri": [4, 6, 8, 12, 13, 17], "carta": 7, "case": [1, 4, 5, 6, 7, 8, 12, 13, 17, 18], "catalogu": 1, "categori": [4, 7], "caus": 8, "cb": [8, 12, 13], "cbor": [5, 8, 9, 12, 14], "cbortag": 6, "ccordiant": 6, "cefal\u00f9": 3, "cek": 0, "central": [9, 12, 15, 17], "cerini": 3, "certain": [4, 8, 9, 12, 13], "certif": [1, 4, 6, 14, 15, 17, 18], "certifi": [4, 17, 18, 19], "cf57377b675f64f37314739592c1e8a911a7ddaf341ce2902fe877c5a835e4c1": [9, 12], "chain": [0, 4, 5, 6, 8, 12, 13, 18], "challeng": [7, 8, 18], "chang": [3, 6, 12, 13, 14, 17], "channel": [3, 8, 9, 12, 14], "charact": [6, 8, 16], "character": 15, "characterist": 4, "charset": 8, "check": [4, 5, 8, 9, 14, 17, 18], "chiozzi": 3, "choos": [10, 15], "chosen": [8, 12, 13], "cie": [4, 6, 7, 16], "cipher": [0, 9, 12], "circumst": [14, 19], "citizen": [3, 4, 6, 15], "civil": [9, 12], "claim": [2, 4, 5, 7, 8, 11, 12, 13, 14, 17, 18, 19], "claimset": 8, "clarif": 3, "clarifi": [8, 12, 13, 14, 18], "clariti": [12, 13], "clear": [4, 12, 13, 17], "cliam": 6, "client": [1, 7, 8, 9, 11, 12, 13, 16, 17, 18, 19], "client_data": 18, "client_data_hash": 18, "client_id": [7, 8, 11, 12, 13], "client_id_schem": [12, 13], "client_metadata": [12, 13], "client_nam": [7, 11], "client_registration_types_support": 7, "close": 17, "closur": [9, 12], "cm": 8, "cmsioiaizwlkyxmilcaiyxnzdxjhbmnlx2xldmvsijogimhpz2gilcaizxzpzgvuy2ui": 6, "cnf": [6, 7, 8, 11, 12, 13, 14, 18], "code": [5, 6, 7, 8, 9, 12, 13, 14, 16, 17, 18], "code_challeng": 8, "code_challenge_method": 8, "code_challenge_methods_support": 7, "code_verifi": 8, "codic": 7, "codificata": 7, "cogfqwztpbirqpnlrg": 18, "cognom": [6, 7], "cointain": [6, 8], "collect": [4, 6, 7, 8, 12, 13, 17], "collis": [6, 8, 18], "color": 6, "com": [3, 8, 12, 13, 18], "combin": [6, 17, 18], "come": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "command": [9, 12], "comment": 3, "commiss": [4, 5], "common": [4, 5, 7, 11], "commonli": 5, "commun": [1, 3, 4, 5, 8, 9, 12, 13, 14], "compani": 15, "compar": 17, "compat": [6, 17, 19], "compet": 4, "complement": [4, 17], "complet": [4, 12, 13, 15, 19], "complex": 17, "compli": 17, "compliac": 4, "complianc": [1, 4, 6, 8, 10, 12, 13, 14, 17, 18, 19], "compliant": [4, 7, 9, 11, 12, 13, 16, 18], "compon": [4, 5, 8, 9, 12, 13, 17], "compos": [8, 12, 13, 18], "comprehens": [12, 13], "compris": 7, "compromis": [14, 17, 18], "comput": [9, 12, 14, 18], "concat": 0, "concaten": [17, 18], "conceal": 6, "concern": [3, 5, 17], "concis": 6, "condit": [4, 6, 7, 8, 9, 12, 13, 14], "conduct": [4, 8], "confid": [4, 9, 12], "confidenti": [8, 17], "configur": [4, 5, 8, 12, 13, 18, 19], "confin": 4, "confirm": [4, 6, 8, 14, 18], "conform": 4, "connect": [3, 4, 6, 7, 8, 9, 11, 12, 14, 16, 19], "consent": [8, 9, 12, 13, 17, 18], "consequ": 3, "consid": [4, 8, 9, 12, 13, 17, 18], "consider": 5, "consist": [4, 6, 7, 8, 10, 11, 19], "const": [7, 11, 12, 13], "constant": 7, "constant_attendance_allow": [6, 7], "constitut": 4, "constraint": [7, 11, 12, 13, 17, 18], "construct": 18, "contact": [7, 8, 11, 17], "contain": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "content": [0, 4, 6, 8, 12, 13, 14, 18], "contenuti": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "context": [4, 10, 12, 13, 18, 19], "continu": [12, 13], "contractu": 4, "contribut": 5, "control": [4, 6, 8, 10, 15, 17, 18, 19], "convei": 17, "convent": 5, "convers": [12, 13], "cooki": [12, 13], "coordiant": 6, "coordin": [6, 9, 12], "core": [4, 6, 8, 16, 17], "correct": [12, 13], "corrent": 3, "correspond": [6, 8, 9, 12, 13, 14, 17, 18], "cose": 6, "cose_kei": 14, "cose_sign1": [9, 12], "cost": [15, 17], "could": [12, 13, 17], "count": [12, 13], "countermeasur": 8, "countri": [6, 7], "country_cod": [9, 12], "creat": [4, 8, 9, 12, 13, 14, 18], "creation": [8, 12, 13, 14, 17, 18], "credenti": [1, 4, 5, 7, 9, 11, 12, 13, 15, 16, 17, 18, 19], "credential_accept": 8, "credential_already_revok": 14, "credential_configuration_id": 8, "credential_configurations_support": [7, 8], "credential_delet": 8, "credential_endpoint": 7, "credential_failur": 8, "credential_hash": 14, "credential_hash_alg": [6, 14], "credential_invalid": 14, "credential_issu": 7, "credential_not_found": 14, "credential_pop": 14, "credential_revok": 14, "credential_signing_alg_values_support": 7, "credential_status_valid": 14, "credential_upd": 14, "credentialsubject": [12, 13], "credentialx": [12, 13], "criteria": [12, 13, 17], "critic": [12, 13], "cross": [5, 10, 17], "crucial": [4, 12, 13, 14], "crv": [6, 7, 8, 9, 11, 12, 14, 17, 18, 19], "cryptograf": 17, "cryptograph": [4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 17, 18, 19], "cryptographi": 17, "cryptographic_binding_methods_support": 7, "csrc": 4, "cupi": 3, "curfc21sbddzcg9wzm1cegl4udeyztrzexforsisicjhqlzkzmnuefqwwjvscndkefpt": 6, "current": [4, 6, 7, 8, 12, 13, 14, 16, 17, 18], "curv": [0, 6, 9, 12, 18], "custom": 18, "cycl": 14, "d": 16, "d126a6a856f7724560484fa9dc59d195": 6, "d2jhy2nhbg91cmvqdwfuzgft": 18, "d4e0bb387aa2556ff306925fdfb9a765": 8, "d76c51b7": [7, 11], "da": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "dab8ef51": 8, "dai": 8, "damag": [12, 13], "data": [1, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "data_sourc": 6, "databas": 14, "datael": [9, 12], "dataitemnam": [9, 12], "dataitemvalu": [9, 12], "date": [6, 7, 14, 16, 17, 18], "datetim": [6, 19], "dati": 16, "db143143538f3c8d41dc024f9cb25c9d": 6, "db67gl7ck3tfiiaf7n6_7shvqk0mdymeqcogglkuaaw": 6, "dbjftjez4cvp": 8, "de": [3, 16], "de21bb62ff2897d8b986d2cda9f9bc5865c02807f7b4d9dd1fa4a79df4c0d37f": [9, 12], "deactiv": [5, 18], "decemb": 16, "decentr": 5, "decid": [6, 14, 18], "deciph": [12, 13], "decis": 8, "declar": 6, "decod": [6, 8, 12, 13, 14], "decoi": 6, "decre": 5, "decrypt": [9, 12, 13], "dedic": [4, 17, 18], "deem": [12, 13], "default": [0, 17], "default_acr_valu": 7, "defdf1aa746718016ef1b94bfe5r6": 6, "defens": 18, "defer": [5, 14], "defin": [1, 5, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "definit": [4, 12, 13, 14, 16, 17, 19], "definition_id": [12, 13], "degli": 6, "degre": 4, "dei": 16, "deleg": [17, 18], "delet": [14, 18], "delimit": 6, "dell": [6, 7, 16], "della": [7, 16], "dello": [9, 12], "demonstr": [1, 4, 8, 9, 12, 16, 17, 19], "denot": 8, "densiti": [12, 13], "depend": [4, 6, 8, 10, 12, 13, 14, 18, 19], "depict": 18, "deploy": 4, "deriv": [0, 4, 6, 8, 9, 12, 14, 17], "describ": [4, 6, 7, 8, 9, 12, 13, 14, 17, 18], "descript": [0, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18], "descriptor": [12, 13], "descriptor_map": [12, 13], "deselect": [12, 13], "design": [3, 4, 15, 17], "destruct": [9, 12], "detail": [1, 5, 6, 7, 8, 9, 14, 17, 18, 19], "detect": [17, 18], "determin": [7, 8, 12, 13, 15, 17, 18, 19], "dettagli": 7, "develop": [3, 5, 12, 13, 17, 18], "devic": [4, 5, 8, 14, 17, 18, 19], "deviceauth": [6, 9, 12], "devicecheck": 18, "devicekei": [6, 9, 12], "devicekeyinfo": [6, 9, 12], "devicemac": 6, "devicenamespac": [9, 12], "deviceretrievalmethod": [9, 12], "devicesign": [6, 9, 12], "devicesignatur": [6, 9, 12], "devicesigneditem": 6, "dhljyxjkiiwginzjdcnpbnrlz3jpdhkioiaimmu0mgjjzdy3otkwmdgwodvmzmixytfm": 6, "di": [6, 7, 16, 18], "diagnos": [12, 13], "diagnost": [6, 9, 12], "diagram": [9, 12, 13, 14, 18], "dif": 11, "differ": [4, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18], "diffi": 0, "digest": [6, 12, 13], "digestalgorithm": [6, 9, 12], "digestid": [6, 9, 12], "digit": [0, 1, 4, 5, 8, 12, 13, 14, 17, 18, 19], "digital": 16, "dijk": 3, "direct": 5, "direct_post": [11, 12, 13], "directli": [4, 6, 8, 10, 12, 13, 17, 18], "diritto": 7, "disabilitycard": [6, 8], "disabilit\u00e0": 7, "disabl": [7, 17], "discard": 17, "disclos": [6, 8, 9, 12, 17], "disclosur": [6, 12, 13, 16, 17], "discov": 8, "discoveri": [4, 7, 8, 12, 13, 17], "discret": 18, "discuss": [3, 10, 18], "dispatch": [9, 12], "displai": [6, 7, 9, 12, 13], "disput": 17, "distinct": [18, 19], "distribut": 17, "divers": 17, "divid": [9, 12, 14, 17, 18], "dn": 17, "do": [8, 12, 13, 14, 17, 18], "doc": 3, "docrequest": [9, 12], "doctyp": [6, 8, 9, 12], "document": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "document_numb": [6, 7, 9, 12], "documentazion": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "documento": 7, "doe": [9, 12, 13, 17, 18], "doesn": [9, 12, 14, 17], "doi": 16, "domain": [4, 6, 14], "domest": [6, 9, 12], "don": 17, "download": [12, 13], "dpop": [8, 16], "draft": [3, 11, 12, 14, 16, 17], "drive": [6, 7, 12, 13, 16], "driver": 7, "driving_privileg": [7, 9, 12], "driving_privileges_detail": 7, "due": [8, 12, 13, 14], "duplic": 8, "durat": 4, "dure": [1, 3, 4, 6, 8, 9, 12, 13, 14, 15, 17, 18, 19], "duzhinov": 3, "dvhobxzkoxb5uvrknkznvwhjlupyzkhyeghmayisicj6vmrnagntq2xnvldsvwdhc0dw": 6, "dx": 6, "dynam": [5, 8, 11, 17], "dzhuvinov": 16, "e": [0, 1, 4, 6, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19], "e0b70bcefbd43686f345c9ed429343aa": 6, "e151": 14, "e2382149255ae8e955af9b8984395": 6, "e353ea0b0fd92b6be90c64cc3b2ee1284153a8f0f5066b99aac599200e6eeeb2": [9, 12], "e453": 14, "e6048bdc7fd6454296f1e3f54536107c9c5b24c4064de46a98121e3630eecca2": [9, 12], "e9melhoa2owvfremtjguchaoek1t8urwbugjsstw": 8, "ea90": [7, 11], "eaa": [1, 4, 5, 12, 17, 18, 19], "each": [4, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "earli": 17, "earliest": 17, "eavesdrop": [9, 12], "eb12193dc66c6174530cdc29b274381f": 6, "ec": [4, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "ec2": [6, 9, 12], "ecdh": 0, "ecdsa": 0, "ecosystem": [4, 5, 15, 17, 18, 19], "eddsa": 18, "edevicekei": [9, 12], "editori": [3, 4], "educ": 15, "eea": 4, "eeed6a3b856563627589a360939d12f7": [9, 12], "eevzdhferxntumw3c3bvvmztqnhpefaxmmu0c3lxtkuilcaiczfyszvmmnbnmy1hrlrh": 6, "effici": [15, 17], "eg": [4, 12, 13, 17], "egieei5iuzr6r0mr02lnvq0omekmnkcji": [18, 19], "ehh4ec14ehh4lxh4ehgtehh4ec14ehh4ehh4ehh4ehgixq": 6, "ehh4lxh4ehgtehh4ec14ehh4ehh4ehh4ehgixq": 6, "ei8zwm9qnkppnpenenhdhq": 6, "eid": [7, 8], "eida": [4, 5, 6, 8, 9, 12, 15, 16, 17], "either": [6, 7, 8, 12, 13, 17, 18], "ej9vmzwmcxoccuwin0zt0js4m_shneig6tlxrqj": 17, "ekfumzrmohdhnurva1zcmezzbgftsljbqwm4stnstjexrmzjiiwgilzrss1tmw1umut4": 6, "electron": [4, 5, 17, 19], "electronic_record": [9, 12], "eleg": [12, 13], "element": [6, 9, 12, 13, 14, 15, 18], "elementidentifi": [6, 9, 12], "elementvalu": [6, 9, 12], "elenco": 7, "elig": [4, 5], "elimin": [15, 18], "elipt": 6, "elisa": 3, "ellipt": [0, 9, 12, 18], "eluv5og3gsnii8eynsxa_a": 6, "em3cmnzghiyfsq090n6b3op7laaqj8rghmhxgmjstqg": 17, "email": [8, 14, 17], "emanuel": 3, "embed": [4, 9, 12], "emerg": 17, "emiliano": 3, "empir": 4, "emploi": [12, 13, 17], "empow": 17, "empti": [6, 9, 12], "en": [6, 7], "enabl": [0, 4, 8, 12, 13, 14, 15, 17], "encapsul": 4, "enclav": [4, 18, 19], "encod": [6, 7, 8, 9, 12, 13, 14, 16, 18], "encompass": [6, 18], "encount": [8, 12, 13, 14, 18], "encourag": 3, "encrypt": [0, 6, 8, 9, 12, 13, 14, 16, 17, 18], "end": [8, 9, 12, 13, 14, 17], "endpoint": [4, 5, 6, 7, 11, 14, 18], "energi": [9, 12], "enforc": [4, 14, 17], "engag": [5, 19], "enhanc": [3, 4, 5, 12, 13, 15, 17], "enno31jfzfp8y2dw0r": 6, "enough": 8, "ensur": [1, 3, 4, 5, 8, 12, 13, 14, 15, 17, 18, 19], "enter": [12, 13, 17, 19], "entir": [4, 6, 7, 8, 17, 18, 19], "entiti": [4, 5, 8, 10, 12, 13, 14, 18, 19], "entitl": 14, "entity_id": [12, 13], "entity_typ": 17, "entityconfigur": 17, "entitystat": 17, "entri": [6, 14, 17], "entropi": [8, 12, 13], "enum": [12, 13], "enus": 19, "envelop": 14, "environ": [4, 12, 13, 18, 19], "envis": 15, "ephemer": [0, 9, 12, 18], "equal": [8, 12, 13, 17, 18], "ereaderkei": [9, 12], "errata": 16, "error": [5, 8, 18], "error_descript": [8, 12, 13, 14, 18], "es256": [0, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "es256k": 18, "es384": [0, 7, 11, 12, 13, 17, 18, 19], "es512": [0, 7, 11, 12, 13, 19], "esc0w8acc191": 8, "esempi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "especi": 17, "essenti": 18, "establish": [4, 5, 8, 9, 12, 13, 15, 17, 19], "estim": 1, "etc": [8, 14, 17], "ethic": 4, "etsi": [0, 6], "eu": [5, 6, 12, 13, 17, 18], "eudi": [3, 4, 9, 12, 16, 17, 19], "eudiw": [6, 12, 13, 17, 18], "euicc": 18, "europa": [6, 12, 13, 17, 18], "europea": 7, "european": [4, 5, 7, 15], "europeandisabilitycard": [7, 8], "evalu": [4, 5, 8, 12, 13, 18], "even": [8, 12, 13, 14, 15, 17], "event": [3, 8], "event_descript": 8, "everyon": 3, "evfusjzgtvvoyy1kwgzicnhotgsilcaielzkz2hjbunstvzxbfvnr3nhcfnrq1brruha": 6, "evid": [1, 6, 8, 9, 12, 14], "evolv": [6, 17], "exampl": [0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19], "exce": 8, "except": 17, "exchang": [1, 4, 7, 8, 9, 12, 13, 14, 15, 16, 17], "exclus": [9, 12, 18], "execut": [4, 18, 19], "exist": 18, "exp": [6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "expand": 8, "expect": 4, "experi": [8, 12, 13, 15], "experiment": 19, "expir": [6, 7, 8, 10, 12, 13, 14, 17, 18, 19], "expires_in": 8, "expiri": [6, 7, 8, 14, 17, 18], "expiry_d": [6, 7, 9, 12], "explicit": [12, 13], "explicitli": [8, 12, 13], "exploit": [12, 13], "expos": [8, 17], "express": [4, 12, 13], "exted": 6, "extend": [6, 19], "extens": 17, "extern": [4, 5, 17, 18], "extract": [12, 13], "ey71": 8, "eyj0exaioij2yytzzc1qd3qilcjhbgcioijfuzi1niisimtpzci6imm5ntbjmgu2zmrlyjvkztuwytuwmdk2yji0n2fmmdnjin0": 8, "eyj0exaioijhdctqd3qilcjhbgcioijfuzi1niisimtpzci6imm5ntbjmgu2zmrlyjvkztuwytuwmdk2yji0n2fmmdnjin0": 8, "eyj0exaioijkcg9wk2p3dcisimfszyi6ikvtmju2iiwiandrijp7imt0esi6ik": 8, "eyj0exaioijvcgvuawq0dmnplxbyb29mk2p3dcisimfszyi6ikvtmju2iiwiandrijp7imt0esi6ikvdiiwiy3j2ijoiuc0yntyilcj4ijoicfzvm2phdhu0ytn0azljowfvd1znthlcql9ysjdnltnxbgprmwvqvxoyrsisinkioijutdvptnzslulnyxjuz3j6nwpkdnnwb2zmekz3y2pqunrgvwtlbmvirukwin19": 8, "eyjfc2qioibb": 6, "eyjfc2qiolsiq1jjqkdpbwhhbe1tszhlzuxmnzg2n0w4chv6meznrtvas1vxlw12n0hiyyisilhhzjvjzfvgc0uzywtabeszt0e5d3dhcjjkcvawuu01m3bby2hiemprzmmilcjjr2fuqvdysg9wqvoyalbhnxk0sze3u0xpywfkcgrnuf9pdnbmtgx0vwjjiiwinefuzu1zvvaxrwh3emrhdkrqoehobnrargn1ejzrohhhwvj0nxo0shh0ssisijruytvxshrmyzdrynnxdhfvahd6wxdvduqty3hkvmdenmraltl0zudhz3milcjizs10a2u3yvu0wmhdnwuxcgzqrjcxuwpfrzrszg1iafroufl1tnqyoho0iiwisnnkahhtmwrvttjan29mumzywvjvoffeadj4m1dqnkdilujny21ddzjgayisilvobxbrsy1hs3hzahjwxzzwyvpfzzrovg5fx29aevdob01ztgnamuhlmjgilcjodddqu3rxmkeywkliuhbhdtjpdmvsek9rbwpyuen1v0rbdy0tdktsqtbjiiwiv3rtck5jvzftvkn0unznuf9um2ytrglhrudhns1ivk5rwgjrckowrnpzrsjdlcjlehaioje3ndy1mtu5nzisimlzcyi6imh0dhbzoi8vzwfhlxbyb3zpzgvylmlwenmuaxqilcjzdwiioijoemjmc1hoohveq2nkn25vv1hgwkfmsgt4wnnsr0m5whmilcjzdgf0dxmionsic3rhdhvzx2f0dgvzdgf0aw9uijp7imnyzwrlbnrpywxfagfzaf9hbgcioijzagetmju2in19lcj2y3qioijeaxnhymlsaxr5q2fyzcisil9zzf9hbgcioijzagetmju2iiwiy25mijp7imp3ayi6eyjrdhkioijfqyisimnydii6ilatmju2iiwieci6inbwvtnqyxr1ngezdgs5yzlhb3dwz0x5qkjfcko3ts0zv2xqazflalv6mkuilcj5ijoivew1t052ui1jz2fybmdyejvqzhzzcg9mznpgd2nqufj0rlvrzw5lsevjmcj9fx0": 8, "eyjhbgcioiairvmyntyilcaidhlwijogimv4yw1wbgurc2qtand0in0": 6, "eyjhbgcioijfuz": 18, "eyjhbgcioijfuzi1nii": [12, 13], "eyjhbgcioijfuzi1niisimtpzci6ik5gttfxvvzpvwxzelvxcexhbwxmy0vwufjwwtjwwfpjumpcblfywm1ssghlwvvwwvvszfrrbkeytkeilcj0exaioijhchbsawnhdglvbi9lbnrpdhktc3rhdgvtzw50k2p3dcj9": 17, "eyjhbgcioijfuzi1niisimtpzci6ikvvrzbfdlrwauk1ru5aqxdvq0lvtwdqqvk4x1visw5fmkhiwlmxn3rfqzaifq": 8, "eyjhbgcioijfuzi1niisimtpzci6ilnurkrxv2hky0dwwfgzqjnsvmraywtsq0xutnvna000wtngnlfutk9krxryzfhgwvlywjjjwgn0uveilcj0exaioijhchbsawnhdglvbi9lbnrpdhktc3rhdgvtzw50k2p3dcj9": 17, "eyjhbgcioijfuzi1niisimtpzci6imtoakzwte9nrjnheg": 18, "eyjhbgcioijfuzi1niisimtpzci6imvxa3pubwt0ww5kblzhmwxhmju1zdjkq2rvzersazqwuwt0wvlvmwfhrfzyt1robfphdfdxsgq1wncilcj0exaioijhchbsawnhdglvbi9lbnrpdhktc3rhdgvtzw50k2p3dcj9": 17, "eyjhbgcioijfuzi1niisinr5cci6indhbgx": 18, "eyjhbgcioijfuzi1nij9": 8, "eyjhbgcioijsuzi1niisimtpzci6": 6, "eyjlehaioje2ndk1ota2mdisimlhdci6mty0otqxnzg2miwiaxnzijoiahr0chm6ly9ycc5legftcgxllm9yzyisinn1yii6imh0dhbzoi8vcnauzxhhbxbszs5vcmcilcjqd2tzijp7imtlexmiolt7imt0esi6ikvdiiwia2lkijoitkznmvdvvmlvbfl6vvdwtgftbgzjrxbqulzzmlzywklsakjuuvhabvjiaetzvvzzvwxkvffuqtjoqsisimnydii6ilatmju2iiwieci6invzbemzd2qtcfgzd3o0yljzbnd5m2x6cgjhwkzotjk2aewyquhbm01rnlkilcj5ijoivkxdqlhgv2xktlnosxo4a0gyoxzmujromthca3dht1gynnprb3j1utfnncj9xx0sim1ldgfkyxrhijp7im9wzw5pzf9yzwx5aw5nx3bhcnr5ijp7imfwcgxpy2f0aw9ux3r5cguioij3zwiilcjjbgllbnrfawqioijodhrwczovl3jwlmv4yw1wbguub3jnlyisimnsawvudf9yzwdpc3ryyxrpb25fdhlwzxmiolsiyxv0b21hdgljil0simp3a3mionsia2v5cyi6w3sia3r5ijoirumilcjrawqioijork0xv1vwavvswxpvv3bmyw1szmnfcfbsvlkyvlhasvjqqm5rwfptukhos1lvvllvbgruuw5bmk5biiwiy3j2ijoiuc0yntyilcj4ijoidxnsqzn3zc1wwdn3ejriullud3kzbhpwykdarmhootzotdjbseeztve2wsisinkioijwtencwezxbgrou05jejhrsdi5dkxsne4xoejrd0dpwdi2elfvcnvrmu00in1dfswiy2xpzw50x25hbwuioijoyw1lig9migfuigv4yw1wbgugb3jnyw5pemf0aw9uiiwiy29udgfjdhmiolsib3bzqhjwlmv4yw1wbguuaxqixswiz3jhbnrfdhlwzxmiolsicmvmcmvzaf90b2tlbiisimf1dghvcml6yxrpb25fy29kzsjdlcjyzwrpcmvjdf91cmlzijpbimh0dhbzoi8vcnauzxhhbxbszs5vcmcvb2lkyy9ycc9jywxsymfjay8ixswicmvzcg9uc2vfdhlwzxmiolsiy29kzsjdlcjzy29wzsi6imv1lmv1cm9wys5lyy5ldwrpdy5wawqumsblds5ldxjvcgeuzwmuzxvkaxcucglklml0ljegzw1hawwilcjzdwjqzwn0x3r5cguioijwywlyd2lzzsj9lcjmzwrlcmf0aw9ux2vudgl0esi6eyjmzwrlcmf0aw9ux3jlc29sdmvfzw5kcg9pbnqioijodhrwczovl3jwlmv4yw1wbguub3jnl3jlc29sdmuviiwib3jnyw5pemf0aw9ux25hbwuioijfegftcgxlifjqiiwiag9tzxbhz2vfdxjpijoiahr0chm6ly9ycc5legftcgxllml0iiwicg9sawn5x3vyasi6imh0dhbzoi8vcnauzxhhbxbszs5pdc9wb2xpy3kilcjsb2dvx3vyasi6imh0dhbzoi8vcnauzxhhbxbszs5pdc9zdgf0awmvbg9nby5zdmcilcjjb250ywn0cyi6wyj0zwnoqgv4yw1wbguuaxqixx19lcj0cnvzdf9tyxjrcyi6w3siawqioijodhrwczovl3jlz2lzdhj5lmvpzgfzlnrydxn0lwfuy2hvci5legftcgxllmv1l29wzw5pzf9yzwx5aw5nx3bhcnr5l3b1ymxpyy8ilcj0cnvzdf9tyxjrijoizxlkacbcdtiwmjyifv0simf1dghvcml0ev9oaw50cyi6wyjodhrwczovl2ludgvybwvkawf0zs5lawrhcy5legftcgxllm9yzyjdfq": 17, "eyjlehaioje2ndk2mjm1ndysimlhdci6mty0otq1mdc0niwiaxnzijoiahr0chm6ly90cnvzdc1hbmnob3iuzxhhbxbszs5ldsisinn1yii6imh0dhbzoi8vaw50zxjtzwrpyxrllmvpzgfzlmv4yw1wbguub3jniiwiandrcyi6eyjrzxlzijpbeyjrdhkioijfqyisimtpzci6ilnurkrxv2hky0dwwfgzqjnsvmraywtsq0xutnvna000wtngnlfutk9krxryzfhgwvlywjjjwgn0uveilcjjcnyioijqlti1niisingioijyql9bogdcunh5njhvtkxzrkzlr0zmr2vmwu5xymgtszh1os1gylqyzkzjiiwiesi6ilnuwvk2y3njznkxcjbisfhltgjuvfzsamfndzhozznrues2wfvoc2uzdkuifv19lcj0cnvzdf9tyxjrcyi6w3siawqioijodhrwczovl3rydxn0lwfuy2hvci5legftcgxllmv1l2zlzgvyyxrpb25fzw50axr5l3royxqtchjvzmlszsisinrydxn0x21hcmsioijleupoyibcdtiwmjyifv19": 17, "eyjlehaioje2ndk2mjm1ndysimlhdci6mty0otq1mdc0niwiaxnzijoiahr0chm6ly9pbnrlcm1lzglhdguuzwlkyxmuzxhhbxbszs5vcmcilcjzdwiioijodhrwczovl3jwlmv4yw1wbguub3jniiwiandrcyi6eyjrzxlzijpbeyjrdhkioijfqyisimtpzci6ik5gttfxvvzpvwxzelvxcexhbwxmy0vwufjwwtjwwfpjumpcblfywm1ssghlwvvwwvvszfrrbkeytkeilcjjcnyioijqlti1niisingioij1c2xdm3dklxbym3d6ngjsww53etnsenbir1pgae45nmhmmkfiqtnnutzziiwiesi6ilzmq0jyrldsze5ttkl6ogtimjl2tfi0tje4qmt3r09ymjz6uw9ydvexttqifv19lcjtzxrhzgf0yv9wb2xpy3kionsib3blbmlkx3jlbhlpbmdfcgfydhkionsic2nvcguionsic3vic2v0x29mijpbimv1lmv1cm9wys5lyy5ldwrpdy5wawqumswgigv1lmv1cm9wys5lyy5ldwrpdy5wawquaxqumsjdfswicmvxdwvzdf9hdxrozw50awnhdglvbl9tzxrob2rzx3n1chbvcnrlzci6eyjvbmvfb2yiolsicmvxdwvzdf9vymply3qixx0sinjlcxvlc3rfyxv0agvudgljyxrpb25fc2lnbmluz19hbgdfdmfsdwvzx3n1chbvcnrlzci6eyjzdwjzzxrfb2yiolsiulmyntyilcjsuzuxmiisikvtmju2iiwirvm1mtiilcjquzi1niisilbtnteyil19fx0sinrydxn0x21hcmtzijpbeyjpzci6imh0dhbzoi8vdhj1c3qtyw5jag9ylmv4yw1wbguuzxuvb3blbmlkx3jlbhlpbmdfcgfydhkvchvibgljlyisinrydxn0x21hcmsioijleupoyibcdtiwmjyifv19": 17, "eyjpc3mioiaiahr0chm6ly9jbgllbnquzxhhbxbszs5jb20ilcaiyxvkijogimh0dhbzoi8vyxmuzxhhbxbszs5jb20ilcaibmjmijogmtmwmdgxntc4mcwgimv4cci6idezmda4mtkzodb9": 8, "eyjpc3mioii0n2i5odiznjk3otfkmdgwmdnhnzi4m2ywntljyjbkmsisimf1zci6imh0dhbzoi8vzwfhlxbyb3zpzgvylndhbgxldc5pchpzlml0l2nyzwrlbnrpywwilcjpyxqioje3mdu1nzawntusimv4cci6mtc3odkxndu2mcwibm9uy2uioij0c19fdfvrczbpzwljuzfowu5csevru295m2n0ngdwes00rlpld0hpbgtzin0": 8, "eyjpc3mioiigahr0chm6ly9jbgllbnquzxhhbxbszs5jb20ilcjhdwqioiigahr0chm6ly9hcy5legftcgxllmnvbsisimp0asi6ijvlzmy5yzfilwvkmgqtnddloc1hntuzlwy3ngrmmwjizwvkzcisimlhdci6mtcymji0otq0nywizxhwijoxnziymjq5nzq3fq": 8, "eyjpc3mioijodhrwczovl2vhys1wcm92awrlci53ywxszxquaxb6cy5pdcisinn1yii6imq0ztbiyjm4n2fhmju1nmzmmza2oti1zmrmyjlhnzy1iiwiyxvkijoiahr0chm6ly9lywetchjvdmlkzxiud2fsbgv0lmlwenmuaxqvy3jlzgvudglhbcisimlhdci6mtcxntg0mju2mcwizxhwijoxnzc4ote0ntywlcjqdgkioijmoty1nwnlyi1jnjvjltqwmjutotm3oc1injy3mmi2mtq5ymcilcjjbgllbnrfawqioii0n2i5odiznjk3otfkmdgwmdnhnzi4m2ywntljyjbkmsisimnuzii6eyjqa3qioii5nte1nzrhzwuxymi3ota3ywuxzwmzmta5zgiyyjiynsj9fq": 8, "eyjqd2sioib7imt0esi6icjfqyisicjjcnyioiaiuc0yntyilcaieci6icjuq0ffuje5": 6, "eyjqdgkioijlmwozvl9is2ljoc1mquvciiwiahrtij": 8, "f": 16, "f10aca0992694b3581f6f699bfc8a2c6cc687725": [7, 11], "f2461e4fab69e9f7bcffe552395424514524d1679440036213173101448d1b1ab4a293859b389ffa8b47aeed10e9b0c1545412ac37c51a76482cd9bbbe110152": [9, 12], "f8555ceb": 8, "f8a5966e6dac9970e0334d8f75e25": 6, "f9655ceb": 8, "f9ee4d36f67dbd75e23311ac1c29": 6, "facial": 19, "facilit": [3, 4, 17], "fact": 15, "factori": 18, "fail": [8, 12, 13, 14, 17], "failur": [12, 13, 14], "faiv8cncch43n07ybcwlejg4zo9o_xdefgiejdshk1ccj8yt9": 6, "fals": [9, 12, 13, 14, 18], "falsif": 18, "famili": [0, 6, 7], "family_nam": [6, 7, 9, 12, 13, 17], "fanfs3ync9tjicaivhwlvuj3axwggz_98urfaqme": [7, 11], "far": [8, 14], "fast": 5, "faulti": [12, 13], "fb43": 8, "fbf4de318982f2dbad43c601caeb22628b301ac18aa8264c5831b2aaac89c486": [9, 12], "fc91": [12, 13], "feasibl": [12, 13], "featur": [4, 12, 13, 14, 17, 18], "februari": 16, "fed": [6, 7, 8, 11, 12, 13, 16, 17, 18], "feder": [4, 5, 7, 8, 11, 12, 13, 16, 18, 19], "federation_ent": 5, "federation_fetch_endpoint": 17, "federation_list_endpoint": 17, "federation_resolve_endpoint": 17, "federation_trust_mark_status_endpoint": 17, "fetch": [12, 13, 17], "fett": 16, "ff217bdb0653": [12, 13], "ff_etuqs0ieiis1nynbheqsoy3ct4gpi": 8, "field": [6, 7, 8, 9, 11, 12, 13, 14, 15, 16], "fifyx03bnosd8m6gyqifnhnp9cm_sam9tc5nlloiirc": 17, "fig": 8, "figur": [9, 12], "filter": [7, 8, 11, 12, 13], "fimewwe7elgvgohmwmbpu14": 6, "final": [9, 12, 13, 17], "find": [12, 13], "fingerprint": 19, "fip": 0, "first": [6, 7, 8, 12, 13, 18], "fiscal": 7, "flaw": 18, "flexibl": [12, 13, 17], "flow": [1, 5, 17, 18], "fly": 8, "fmlgrxfrzuv2gwmquh8": [7, 11], "focus": 17, "follow": [0, 1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18], "font": 6, "forbidden": [12, 13], "forc": 17, "forgotten": 3, "form": [4, 6, 8, 12, 13, 14, 15, 17, 18, 19], "form_post": [7, 8, 12, 13, 18], "formal": 4, "format": [4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19], "forward": [12, 13], "foster": 17, "foto": 7, "found": [8, 12, 13, 14, 18], "fr1": 17, "fr10": 17, "fr11": 17, "fr12": 17, "fr13": 17, "fr14": 17, "fr15": 17, "fr16": 17, "fr17": 17, "fr18": 17, "fr19": 17, "fr2": 17, "fr20": 17, "fr21": 17, "fr22": 17, "fr23": 17, "fr24": 17, "fr25": 17, "fr26": 17, "fr27": 17, "fr28": 17, "fr29": 17, "fr3": 17, "fr4": 17, "fr5": 17, "fr6": 17, "fr7": 17, "fr8": 17, "fr9": 17, "fragment": [8, 12, 13], "frame": [12, 13, 18], "framework": [4, 5, 6, 8, 12, 13, 16, 17, 18, 19], "francesco": 3, "fraud": 15, "free": 3, "fresh": [8, 12, 13, 17, 18], "friendli": [12, 13], "from": [1, 3, 4, 6, 7, 8, 9, 12, 13, 14, 17, 18, 19], "frystyk": 16, "fswginzjdci6icjodhrwczovl2lzc3vlci5legftcgxllm9yzy92ms4wl2rpc2fiawxp": 6, "fulfil": [12, 13, 14], "full": [5, 6, 17, 19], "function": [0, 4, 5, 6, 9, 12, 18, 19], "further": [4, 5, 8, 9, 12, 14, 17, 18, 19], "furthermor": [6, 8, 14, 17, 19], "futur": [8, 12, 13, 17, 18], "fyziol9lf2cekunt2jzxilrdink0upcd": 8, "g": [4, 6, 8, 12, 13, 14, 15, 16, 17, 18, 19], "g02nsrqfjfxq7io09syaja": 6, "g061": 8, "gabriella": 3, "gain": [4, 12, 13, 18], "gather": [12, 13], "gdpr": 17, "ge3sjy_zat34f8wa5dukvb0fslasjraac8i3ln11ffc": 6, "gener": [0, 4, 5, 6, 9, 12, 13, 14, 16, 18], "genuin": [4, 8, 18], "get": [6, 8, 11, 12, 13, 17, 18, 19], "getti": 16, "gg": [6, 7], "giada": 3, "github": 3, "giusepp": 3, "give": [9, 12, 13, 17], "given": [6, 8, 10, 12, 13, 14, 17, 18], "given_nam": [6, 7, 9, 12, 13, 17], "gli": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "globalplatform": 18, "glossari": 4, "goal": 4, "goland": 16, "good": [12, 13], "googl": 4, "gov": [4, 7, 9, 12], "govern": [4, 15, 17], "grant": [4, 7, 8, 12, 13, 15, 16, 18, 19], "grant_typ": [8, 18], "grant_types_support": [7, 19], "graphic": [4, 6], "grauso": 3, "greater": [8, 14], "group": [6, 12, 13], "group1": [12, 13], "group2": [12, 13], "grow": 17, "guarante": [1, 18, 19], "guarate": 6, "guess": [8, 10], "guida": [7, 16], "guidelin": [4, 5, 7, 18], "gxu": 8, "h": [6, 9, 12, 16], "h9gw": 18, "ha": [3, 5, 6, 8, 9, 12, 13, 14, 17, 18, 19], "hain": 16, "haip": [11, 16, 18], "handl": [4, 8, 12, 13, 17], "happen": [8, 12, 13, 17], "hardt": 16, "hardwar": [4, 12, 13, 17, 18], "hardware_key_tag": 18, "hardware_signatur": 18, "harm": 14, "hash": [0, 6, 8, 9, 12, 13, 14, 18], "hasn": 17, "have": [3, 6, 8, 9, 12, 13, 14, 15, 17, 18, 19], "header": [5, 6, 11, 12, 13, 14, 17, 18], "heartili": 3, "hedberg": [3, 16], "held": 8, "hellman": 0, "help": [12, 13, 17, 18], "henc": 18, "her": 10, "here": [4, 19], "hereaft": [8, 18], "herein": [12, 13], "high": [4, 5, 6, 9, 12, 13, 14, 16, 18, 19], "higher": 17, "highlight": 8, "hildebrand": 16, "hinder": [12, 13], "hint": [8, 17], "histor": [4, 17], "histori": 15, "hmac": 0, "hold": [9, 12, 13, 19], "holder": [4, 6, 12, 13, 14, 15, 18], "homepage_uri": [7, 11, 17, 19], "horizont": 17, "horvat": 3, "host": [7, 8, 11, 12, 13, 14, 18], "hour": [14, 17, 18], "how": [4, 5, 6, 9, 12, 13, 14, 18], "howev": [6, 8, 12, 13, 17], "hpcm9biiwgimjpcnrox2rhdguilcaimtk4mc0wms0xmcjd": 6, "hriiwgimzhbwlsev9uyw1liiwgiljvc3npil0": 6, "hs256": [0, 7], "hs384": [0, 7], "hs512": [0, 7], "hsm": [4, 18], "hti70g": 17, "htm": 8, "html": [7, 8, 11, 14], "http": [1, 3, 4, 5, 6, 7, 9, 11, 16, 17, 19], "httponli": [12, 13], "htu": 8, "human": [6, 8, 11, 14, 18], "hybrid": [18, 19], "hypertext": 16, "hywfgixq": 6, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19], "iaconelli": 3, "iam": 15, "iana": [8, 14, 18], "iat": [6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "icjqlti1niisicj4ijogilrdquvsmtladnuzt0hgngo0vzr2zlnwb0hjudfjtglsrgxz": 6, "icjywfhywfhywfhyil0": 6, "id": [4, 6, 7, 8, 11, 12, 13, 17, 19], "id_auth_channel_01": 1, "id_auth_channel_02": 1, "id_auth_rest_02": 1, "ida": [6, 16], "idea": 3, "ident": [4, 5, 6, 8, 10, 12, 13, 14, 16, 17], "identif": [4, 5, 6, 11, 12, 13, 14, 16, 17, 18, 19], "identifi": [4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19], "identitifi": 6, "idp": 8, "idphint": 8, "iec": [0, 6, 16], "ietf": [8, 14, 18, 19], "igarngrz5jdvspoffzfwcjprtfukenehei0": 8, "ii": 4, "ijhkam96qmzvdk1odlezsgzsbvbxetrpmtlhchhznjfgv0hqwmvivtu4ouuilcairhgt": 6, "ijogimm1zjczzti1mgzlody5zji0zde1mte4ywnjzti4nmm5ymi1nmi2m2e0ndnkyzg1": 6, "ijoginnoys0yntyifx0sicj2y3qioiaiahr0chm6ly9wawrwcm92awrlci5legftcgxl": 6, "ik56ykxzwgg4durdy2q3bm9xwezaqwzia3hac1jhqzlycyisicjzdgf0dxmioib7inn0": 6, "ikjvtudrdfcxcmjpa250dzhgenhfqmvmnfliqw5kcjzbshnkz3bhdezdawcilcairu5o": 6, "ikjydmzybg5oqu11sfiwn2fqvw1b": 6, "ilieik_mbjp8bhyngsphiuym3wgaokt9hsdref3qek4kyatafrrer6dgterurnawkbem8m1milyhbtnffzcjjg": 8, "illustr": [9, 12], "immedi": [8, 9, 12, 17, 19], "impact": [12, 13], "implement": [1, 3, 4, 6, 8, 9, 12, 13, 14, 17, 18], "impli": [14, 18], "implic": [12, 13], "implicit": 8, "import": [4, 12, 13], "impract": 8, "improv": 15, "inaccuraci": 14, "includ": [3, 4, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19], "incluid": 8, "inclus": [4, 18], "incorpor": [9, 12, 16, 17, 18], "incorrect": [12, 13, 14], "increas": 17, "incur": [12, 13], "independ": [9, 12, 17], "index": [12, 13], "indic": [6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 19], "indirectli": 17, "individu": [3, 4, 6, 8, 15, 17], "info_polici": [7, 11, 19], "inform": [3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19], "informativi": 16, "informazioni": [7, 11], "infrastructur": [4, 5, 15], "infrastruttura": 16, "inherit": 19, "initi": [0, 3, 4, 5, 8, 9, 12, 14, 17], "innermost": 7, "innov": 5, "input": [8, 12, 13], "input_descriptor": [7, 11, 12, 13], "inquir": 17, "insensit": [12, 13], "insid": [8, 14, 18], "insight": 4, "inspect": 8, "instal": [4, 18, 19], "instanc": [1, 4, 5, 6, 7, 8, 9, 11, 12, 13, 17], "instead": [10, 17], "institut": [15, 16, 17], "instruct": 8, "int": 6, "integ": [6, 8], "integr": [1, 4, 6, 8, 15, 16, 17, 18, 19], "integrity_assert": 18, "integrity_rest_01": 1, "intend": [8, 9, 12, 13, 17], "intendersi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "intent": [9, 12], "intenttoretain": [9, 12], "interact": [4, 8, 12, 13, 15, 17, 18, 19], "intercept": [9, 12, 13], "interchang": 16, "interest": 3, "interfac": [4, 8, 14, 17, 18, 19], "intermedi": [5, 7, 8, 11, 19], "intermediari": [4, 12, 13, 15, 17], "intern": [3, 4, 12, 13, 14, 16, 18, 19], "internet": [14, 16], "interni": 6, "interno": 6, "interoper": [1, 4, 5, 6, 8, 12, 13, 15, 16, 17], "interoperabilit\u00e0": 16, "interpret": [4, 8], "interv": 14, "introduc": [5, 11], "invalid": [6, 8, 9, 12, 13, 14, 17, 18], "invalid_cli": 8, "invalid_dpop_proof": 8, "invalid_proof": 8, "invalid_request": [8, 12, 13, 14], "invalid_request_signatur": 14, "invit": 3, "involv": [4, 5, 8, 12, 13, 14, 15, 17, 18], "io": [4, 18, 19], "iphon": 18, "irregzaml7pnfjqh2apz82blqo5s0sl1jr0tefp5e1t913g8gnuwggtmquqhpzwv6bvtla8g": 17, "iso": [0, 4, 6, 9, 12, 16], "iso18013": [9, 12, 16], "iss": [6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "isser": 19, "issu": [1, 3, 4, 6, 7, 8, 12, 13, 14, 15, 17, 18, 19], "issuanc": [1, 4, 5, 6, 14, 16, 17, 19], "issue_d": [6, 7, 9, 12], "issuer": [4, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19], "issuerauth": [6, 9, 12], "issuersign": [6, 9, 12], "issuersigneditem": [6, 9, 12], "issuersigneditembyt": [6, 9, 12], "issuing_author": [6, 7, 9, 12], "issuing_countri": [6, 7, 9, 12], "istituto": [9, 12], "itali": 5, "italia": 3, "italian": [4, 6, 17], "italiantaxidentificationnumb": 6, "item": [9, 12, 13], "itemsrequest": [9, 12], "its": [4, 8, 9, 11, 12, 13, 14, 17, 18, 19], "itself": [14, 17, 18, 19], "j": 16, "jane": 10, "jar": [8, 12, 13], "jarm": [7, 8, 11, 16], "javacard": 18, "javascript": [12, 13, 16], "je2rpcqbfqxkpmqehahgzv6smmxd0i": [7, 11], "jfxsyomxhajplja": 8, "jji8302pyiu0xqlngtcwrdm9npe_": 6, "jjla": 18, "jkt": 8, "johansson": 3, "join": 3, "jone": 16, "jose": [6, 8, 11, 18], "jrrtu9xuk9biiwgimv4cglyev9kyxrliiwgijiwmjqtmdetmdeixq": 6, "json": [6, 7, 8, 11, 12, 13, 14, 16, 17, 18, 19], "jti": [8, 14], "judici": 14, "juli": 16, "june": 16, "jurisdict": 17, "jw": [1, 6, 7, 8, 11, 12, 13, 16, 17, 18, 19], "jwa": 16, "jwe": 16, "jwk": [6, 7, 8, 11, 12, 13, 14, 16, 17, 18, 19], "jwk_thumbprint": 18, "jwkid": 14, "jwt": [4, 5, 7, 8, 11, 14, 16, 17, 18, 19], "jwt_alg_valu": [7, 11, 12, 13, 17, 18], "jwt_proof": 8, "jwt_vc_json": 18, "jwt_vp_json": 18, "jxfhrxhlk": 6, "k": 16, "kawasaki": 3, "kb": [12, 13, 17], "kdf": 0, "keep": [17, 18], "kei": [0, 1, 2, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19], "kept": 14, "key_attest": 18, "keyauthor": 6, "keyinfo": 6, "keymast": 18, "keystor": [4, 18], "kid": [6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "kind": 4, "klaa": 3, "klyne": 16, "know": [14, 15, 17], "known": [4, 5, 6, 7, 8, 9, 11, 12, 17, 18, 19], "koiwai": 16, "kozihvcnaqccoiawgaib": 18, "kpku_xycocunt2o0bwsliqtnpu6im": 19, "kristina": 3, "kty": [6, 7, 8, 9, 11, 12, 14, 17, 18, 19], "kz": 8, "l": 16, "l3iiwgimlhdciside2odmwmdawmdbd": 6, "label": [6, 12, 13], "lack": 14, "laiso": 3, "languag": [5, 6, 7, 17], "larg": [4, 8], "last": 4, "later": [8, 12, 13], "latest": 17, "latter": [6, 8, 14], "launch": [5, 18], "law": [6, 14], "layer": [4, 16], "lc": 8, "le": 7, "leach": 16, "lead": [12, 13, 14, 18], "lead_tim": 8, "leaf": 17, "leak": 8, "learn": 3, "least": [7, 8, 9, 11, 12, 13, 18], "leav": [5, 7, 11], "lee": 16, "legal": [4, 14, 17, 19], "legisl": 5, "legitim": [4, 6, 12, 13, 14], "legitimaci": [4, 17], "lehmann": 16, "leiba": 16, "leif": 3, "length": [0, 6, 8, 9, 12, 13], "less": [8, 9, 12, 17], "level": [4, 5, 6, 9, 12, 13, 14, 15, 16, 18, 19], "leverag": [15, 17, 18], "liabil": 17, "librari": [5, 18], "licens": [6, 7, 12, 13, 14, 16], "life": [4, 14], "lifecycl": [5, 7], "lifetim": 8, "like": [3, 4, 17, 18], "limit": [9, 12, 13, 18], "limit_disclosur": [7, 11, 12, 13], "line": 16, "link": [3, 7, 8, 10, 12, 13, 14, 18], "link_qr_cod": 7, "linkabl": 10, "list": [0, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 17, 18, 19], "live": [5, 18], "liznsb39vfjhygs3k7jxe4r3": 18, "lm9yzy92ms4wl3blcnnvbmlkzw50awzpy2f0aw9uzgf0ysisicj2y3qjaw50zwdyaxr5": 6, "loa": [4, 8, 19], "load": 17, "local": [6, 7, 8, 14, 17, 18], "locat": [8, 9, 12, 13, 17], "lodderstedt": [3, 16], "log": [12, 13, 17], "login": 15, "logo": [7, 11, 17, 19], "logo_uri": [7, 11, 17, 19], "long": [5, 8, 14], "longer": [14, 17, 18], "look": 8, "looker": 16, "lorenzo": 3, "lose": [14, 18], "loss": 14, "lost": 18, "low": [5, 9, 12, 19], "lowercas": 16, "ltp2qrzmadk4": [7, 11], "lues_support": 19, "luogo": [6, 7], "lzbiiwgimdpdmvux25hbwuilcaitwfyaw8ixq": 6, "m": 16, "m_inf": [9, 12], "m_it": 6, "mac": [8, 12, 13, 14, 18], "made": [11, 12, 13, 14, 17, 18], "mai": [1, 4, 6, 7, 8, 9, 12, 13, 14, 16, 17, 18, 19], "main": [3, 4, 6, 8, 14, 15, 17, 18], "maintain": [4, 10, 11, 12, 13, 15, 17, 18, 19], "mainten": [12, 13], "major": 6, "make": [1, 3, 6, 8, 14, 17, 19], "malform": [12, 13], "malfunct": [12, 13], "malici": [12, 13, 18], "manag": [4, 8, 14, 15, 17, 18, 19], "mandat": [12, 13], "mandatori": [6, 8, 9, 12, 14], "manfredi": 3, "mani": 8, "manipul": [17, 18], "manner": [4, 12, 13, 14, 18, 19], "manufactur": [4, 18], "map": [6, 8, 10, 12, 13, 17], "march": [5, 16], "marco": [3, 16], "marier": 16, "marino": [3, 16], "mario": 6, "mark": [5, 6, 8, 12, 13, 17, 18], "market": 8, "mart": 3, "marta": 3, "masint": 16, "mask": 0, "master": 4, "match": [8, 11, 12, 13, 14, 17, 18], "materi": [6, 7, 8, 9, 12, 13, 14], "matter": 17, "max_path_length": 17, "maximum": [8, 17], "mb92k27uhbuju1p1r_ww1gfwfoejxk": 8, "mc0wms0xmcjd": 6, "md5": 6, "mdawmcwginn1yii6icjoemjmc1hoohveq2nkn25vv1hgwkfmsgt4wnnsr0m5whmilcai": 6, "mdl": [5, 6, 7, 9, 12, 16], "mdoc": [4, 5, 8, 14], "mean": [4, 6, 8, 12, 13, 17], "meant": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "measur": [17, 18], "mechan": [4, 5, 6, 8, 12, 13, 14, 15, 18, 19], "medeiro": 16, "media": [8, 10, 12, 13, 17, 19], "medium": 19, "meet": [12, 13, 17, 18], "member": [3, 4, 5, 6, 8, 12, 13, 14, 15, 17], "mention": [12, 13, 18], "merg": [3, 4], "messag": [1, 3, 8, 9, 12, 13, 14, 18], "met": [18, 19], "metadata": [4, 5, 8, 12, 13, 14, 15, 18], "metadata_polici": 17, "method": [3, 6, 7, 8, 9, 10, 12, 13, 14, 17, 18, 19], "methodologi": 8, "meyer": 16, "mgf1": 0, "michel": 3, "might": [10, 12, 13, 17], "miicajccadogawibag": [12, 13], "minim": [10, 17], "minimum": [6, 8, 9, 12, 13, 14, 18], "ministero": 6, "minor": 17, "minut": 8, "mismatch": [12, 13], "miss": [12, 13], "misus": [8, 12, 13], "mitig": [1, 8, 17], "mix": 18, "mjqtmdetmdeixq": 6, "mm": [6, 7], "mobil": [4, 5, 7, 8, 9, 12, 13, 15, 16, 18, 19], "mobilesecurityobject": 6, "mobilesecurityobjectbyt": 6, "mode": [0, 8, 9, 11, 12, 13, 16], "model": [4, 5, 8, 9, 12, 15, 17, 18, 19], "modi": [1, 16], "modif": [3, 17], "modul": 18, "mogul": 16, "monitor": 17, "more": [4, 6, 7, 8, 9, 12, 13, 14, 17, 18, 19], "moro": 3, "mortimor": 16, "most": 8, "motherboard": 18, "motiv": 17, "motorizzazion": [9, 12], "mrvy3vtzw50x251bwjlciisicjywfhywfhywfhyil0": 6, "mso": [6, 14], "mso_mdoc": 8, "mult": [8, 16], "multi": 4, "multipl": [6, 7, 10, 12, 13, 14, 15, 16, 17, 18], "multivalu": 8, "must": [0, 1, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19], "mv3c88mhhemba6oymbwugeb3dkhp4yadjmgyjwwilsk": 14, "mzuxn2vmzwuzmzuyothmzdk3nmizzty1nwjmyjnmngvhytexzde3msisicj2zxjpzmlj": 6, "n": [6, 12, 13, 16], "n3zdzudlbwmilcaiesi6icjaegppv1diwk1rr0hwv0twutroylnjaxjzvmz1zwndrtz0": 6, "nab": 4, "name": [0, 4, 6, 7, 9, 10, 11, 12, 13, 14, 17, 18, 19], "namespac": [5, 9, 12], "nascita": [6, 7], "nation": [3, 4, 5, 6, 7, 8, 14, 15, 16, 18], "nativ": [4, 18], "natur": [4, 6, 8, 14, 18, 19], "navig": [12, 13], "nazional": 16, "ne_q2unpgzoh": 6, "necess": 17, "necessari": [4, 12, 13, 14, 17, 18], "necessit": 18, "need": [3, 8, 12, 13, 14, 15, 17, 18], "negoti": [12, 13], "nehrderpynlhy3m5wldwtwz2auhm": 6, "nest": [6, 7], "network": [12, 13], "neutral": 4, "new": [1, 4, 8, 9, 12, 13, 14, 15, 17, 18], "newli": [9, 12], "newman": 16, "next": 6, "ngpuouyysfprin19fq": 6, "nhu5b1dqmvnssujsq2mxbyjdlcaiaxnzijogimh0dhbzoi8vaxnzdwvylmv4yw1wbguu": 6, "nicola": 3, "nicolussi": 3, "niel": 3, "nist": [0, 4, 8], "nmhqdnjjee56rjbzbfu2dwtobxpib0wtwxzcti10rmewvdhylwjzmcisicjhrtntanlf": 6, "nmilcj5ijoiovzfngpmx09rx282nhpivfrsy3vosmfqsg10nny5verwcluwq2r2r": 8, "nome": [6, 7], "non": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19], "nonc": [8, 12, 13, 18, 19], "nonce_endpoint": 19, "none": [0, 8, 11, 12, 13, 14, 18], "norm": [0, 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "normal": 6, "normativi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "notat": [6, 9, 12, 16], "note": [4, 5, 8, 17], "notif": [1, 4, 5, 7, 14], "notifi": [1, 4, 8, 12, 13, 14, 17], "notification_endpoint": 7, "notification_id": 8, "novemb": 16, "noy1vfbehnz3zfdwzriiwginrhef9pzf9jb2rliiwgilrjtklulvhywfhywfhywfhywf": 6, "nsd": 6, "null": [9, 12], "number": [6, 7, 8, 12, 13, 14, 17, 18, 19], "numericd": [6, 8, 17], "numero": 7, "nzblsxh8udccd7nowxfzafhkxzsrgc9x": 6, "o": [4, 16], "o2nmbxrvyxbwbgutyxbw": 18, "o2nmbxrvyxbwbgutyxbwyx": 18, "oaep": [0, 7], "oauth": [6, 7, 8, 11, 12, 13, 14, 16, 18, 19], "oauth_authorization_serv": [5, 17], "object": [4, 5, 7, 8, 9, 11, 14, 16, 17, 18], "obscur": [12, 13], "obtain": [6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "occour": [12, 13], "occur": [8, 9, 12, 13, 14, 17, 18], "oem": [4, 18], "offer": [3, 12, 13, 14, 17, 18, 19], "offici": 5, "offlin": [5, 9, 12, 14], "often": 4, "oib7im1ldghvzci6icjjawuifx0sicjfc2rfywxnijoginnoys0yntyilcaiy25mijog": 6, "oid": [6, 7, 8, 11, 12, 13, 16, 17, 18], "oid4vp": [4, 12, 13], "oidc": [6, 7, 8, 15, 16], "oidc4vci": 14, "oir0vuiiwiahr1ijoiahr0chm6ly9yzxnvdxjjzs5legftcgxllm9yzy9wcm90zwn0z": 8, "ok": [6, 8, 12, 13, 14, 18], "okalavqxhwqumh3ehyukmlacsidq33pys41y5pesz3hxwaxq3nmg": 8, "oliv": 3, "omit": [7, 8], "onc": [3, 8, 12, 13, 18, 19], "one": [0, 4, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "ones": 6, "ongo": 17, "onli": [3, 4, 6, 7, 8, 9, 12, 13, 14, 17, 18, 19], "onlin": [10, 14, 17], "opaqu": [6, 12, 13], "open": [3, 8, 19], "openid": [4, 6, 7, 8, 11, 12, 13, 16, 17, 18, 19], "openid4vc": [11, 16, 18], "openid4vci": [5, 7, 8, 16, 17], "openid4vp": [5, 8, 11, 12, 13, 16, 17], "openid_credenti": 8, "openid_credential_issu": [5, 17], "openid_relying_parti": [7, 17], "oper": [0, 4, 5, 8, 12, 13, 17, 18], "opportun": 3, "optim": 0, "option": [1, 4, 6, 7, 8, 9, 10, 12, 13, 15], "optxrimpptoa1plemagr6pxhf8y6": 8, "order": [6, 12, 13, 18], "org": [6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "organ": [4, 7, 11, 15, 16, 19], "organiz": [4, 17], "organization_cod": 6, "organization_id": [9, 12], "organization_nam": [6, 7, 9, 11, 12, 17, 19], "origin": [4, 6, 17, 18], "other": [4, 5, 6, 8, 12, 13, 14, 15, 17, 18, 19], "otherwis": [12, 13, 14], "our": 3, "out": [4, 8, 9, 12, 14, 17], "outcom": 4, "outlin": [4, 6, 7, 9, 12, 13, 14, 17, 19], "outsid": 8, "over": [4, 6, 9, 12, 13, 14, 15, 17, 18, 19], "overal": 17, "overload": 17, "overse": [17, 18], "oversight": 4, "own": [8, 9, 12, 14, 15, 17, 18], "owner": [6, 15, 17, 18], "ownership": 15, "p": [0, 6, 7, 8, 11, 14, 16, 17, 18, 19], "p1": 17, "p2": 17, "p256": [6, 9, 12], "p3": 17, "p4": 17, "p5": 17, "p6": 17, "p7": 17, "p8": 17, "p9": 17, "pad": 0, "paes": 7, "page": [3, 12, 13, 17, 18, 19], "pair": [4, 6, 7, 8, 9, 11, 12, 18], "paolaz": 3, "par": [5, 7], "paradigm": 5, "param": [8, 18, 19], "paramet": [0, 2, 5, 7, 11, 12, 13, 14, 19], "parliament": 5, "part": [4, 8, 9, 12, 13, 16, 17, 18, 19], "partak": 3, "parti": [3, 4, 5, 6, 8, 13, 14, 15, 18, 19], "partial": [12, 13], "particip": [3, 4, 5, 10, 17, 19], "particular": [1, 4, 8, 14, 17, 18], "particularli": [12, 13, 17], "pasqual": 3, "pass": [7, 8, 9, 11, 12, 18], "past": 4, "patent": 7, "path": [7, 11, 12, 13, 17], "pattern": 5, "paul": 3, "payload": [1, 4, 5, 6, 8, 12, 13, 14, 18], "pc33jm2lchcu_lhggv_ufq": 6, "pdnd": [1, 6, 8, 9, 12, 16], "peak": 17, "pec": [7, 11, 17], "peopl": 3, "per": [7, 8, 14, 16, 18], "perform": [4, 8, 9, 12, 13, 18, 19], "perimet": 17, "period": [3, 4, 14, 17, 18, 19], "peripher": [9, 12], "permiss": [4, 9, 12], "permit": 18, "person": [4, 6, 10, 11, 12, 13, 14, 15, 16, 17, 19], "personidentificationdata": [6, 7, 8, 11, 12, 13], "perspect": [8, 12, 13, 17], "pertain": [17, 18], "peter": 3, "phase": [6, 8, 9, 12, 14, 15, 17, 18], "phone": [8, 15], "physic": [4, 14, 18], "piattaforma": 16, "pick": [12, 13], "pictur": [8, 12, 13], "pid": [1, 4, 5, 12, 13, 14, 17, 18, 19], "pidprovid": 6, "pin": 19, "pivot": 5, "pkce": [7, 8], "pkcs1": 0, "pki": 17, "place": [6, 7, 18], "place_of_birth": 7, "plai": [18, 19], "plain": 17, "plaintext": [12, 13], "platform": 10, "pleas": [3, 5, 17, 19], "plu": 0, "pluggabl": 18, "pnrr": 5, "point": [4, 8, 9, 12, 13, 17, 18], "polic": 14, "polici": [4, 10, 12, 13, 14, 17, 19], "policy_uri": [7, 11, 17, 19], "poligrafico": [9, 12], "poll": [12, 13], "pop": [1, 8], "popul": [6, 12, 13], "portrait": [7, 9, 12], "posit": [4, 6, 8], "possess": [1, 4, 5, 6, 8, 12, 13, 15, 16, 17, 18, 19], "possibl": [3, 6, 8, 9, 12, 13, 17, 19], "post": [1, 5, 8, 11, 14, 17, 18], "potenti": [6, 12, 13, 14, 17, 18], "practic": [4, 7, 16], "pragma": 8, "pre": [4, 11, 17], "precaut": [12, 13], "predefin": 18, "predetermin": 18, "predict": 4, "preexist": 4, "prefer": [12, 13, 19], "preliminari": 8, "prerequisit": 18, "presenc": 6, "present": [4, 5, 6, 8, 9, 11, 15, 16, 17, 18, 19], "presentation_definit": [11, 12, 13, 18], "presentation_definition_uri": [12, 13], "presentation_definition_uri_support": [12, 13, 18], "presentation_definitions_support": [7, 11], "presentation_submiss": [12, 13], "presentationexch": 16, "presentationexchang": 11, "preserv": [14, 18, 19], "prevent": [8, 10, 12, 13, 18, 19], "previou": [6, 8, 12, 13, 14, 18], "previous": [8, 12, 13, 14, 17, 18], "primari": [4, 8, 9, 12, 19], "primarili": 18, "principl": 17, "prior": 8, "priv": [9, 12], "privaci": [4, 5, 10, 12, 13, 14, 15, 18, 19], "privacy_polici": [7, 11, 19], "privat": [1, 4, 6, 8, 9, 12, 13, 14, 17, 18], "private_key_jwt": 19, "privileg": 7, "probabilist": 0, "problem": 14, "proce": 8, "procedur": [4, 14, 15, 17], "proceed": 8, "process": [3, 4, 5, 6, 8, 10, 12, 13, 14, 15, 17, 18], "processor": 18, "produc": [4, 18], "product": 4, "profil": [1, 3, 6, 8, 9, 12, 14, 16, 17, 18], "profile_non_repudiation_01": 1, "program": 4, "project": [3, 5], "promot": [15, 17], "prompt": [9, 12, 13], "proof": [1, 4, 5, 6, 7, 8, 11, 12, 13, 16, 17, 18, 19], "proof_signing_alg_values_support": 7, "proof_typ": 8, "proof_types_support": 7, "propag": 17, "proper": [4, 12, 13, 18], "properti": [5, 7, 18], "propos": 3, "prosseda": 3, "protect": [6, 8, 10, 11, 12, 13, 17], "protocol": [1, 4, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18], "protocollo": [7, 11], "prove": [4, 6, 12, 13, 17], "provid": [1, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 17, 18], "provis": [8, 14, 17], "proxi": [8, 12, 13], "proxim": [4, 5], "ps256": 0, "ps384": 0, "ps512": 0, "pseudonym": [4, 5, 6], "pseudorandom": 8, "pss": 0, "pt0ixx0": [12, 13], "pub": [9, 12], "pubblich": 16, "public": [1, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19], "publicli": 17, "publish": [4, 12, 13, 15, 17], "pulido": 16, "pull": 3, "purpos": [5, 6, 11, 12, 13, 14, 15, 18], "push": [5, 7, 12, 13], "pushed_authorization_request_endpoint": 7, "puvdzw": 6, "pvu3jatu4a3tk9c9aowvglybb_rj7m": 8, "q": [1, 4, 5, 12, 13, 17, 18, 19], "qeaa": [4, 19], "qg_o64zqaxe412a108iroa": 6, "qkmx5iqt5phpu5tfcts6hsp": [7, 11], "qr": [7, 9, 12, 13], "qrcode": [12, 13], "qrjrj3af_b57sboirrcbm7br7woc8ynj7lhfpteffuk": 19, "qtsp": [4, 17], "qualifi": [4, 17, 19], "qualiti": [4, 12, 13], "quartili": [12, 13], "queri": [7, 8], "questa": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "quickli": 17, "r": 16, "r3uoi": 17, "rais": [12, 13], "random": [6, 8, 9, 12, 13, 18], "rang": [9, 12], "rappresent": 6, "rar": 8, "rational": 17, "raw": [12, 13], "re": [8, 12, 13], "read": 6, "readabl": [6, 8, 10, 11, 12, 13, 14, 18], "readerauth": [9, 12], "readi": 8, "real": [10, 17], "realiabl": 5, "reason": [8, 14, 18], "receipt": 8, "receiv": [4, 8, 9, 12, 13, 14, 17, 18], "recipi": [1, 6], "recogn": [4, 15], "recognit": 19, "recommend": [0, 4, 6, 8, 12, 13, 14, 17, 18], "reconstruct": 18, "record": [4, 9, 12], "recov": [12, 13], "redact": 18, "redirect": [5, 8], "redirect_uri": [8, 12, 13], "reduc": [15, 17], "reduct": 15, "reestablish": 19, "refer": [0, 4, 5, 6, 8, 9, 12, 14, 15, 17, 18], "referenc": [6, 8, 12, 13, 14], "refin": 3, "reflect": [17, 18], "refresh": 8, "refus": [12, 13], "regard": [12, 13, 14, 17, 18], "regist": [1, 4, 6, 8, 11, 17, 18], "registerd": 14, "registr": [4, 5, 7, 8, 11, 17], "registrar": 4, "registri": [8, 14, 15, 17, 18, 19], "regul": [4, 5, 10, 14, 15, 17], "regulatori": [4, 17], "reiniti": 18, "reject": [8, 12, 13, 14], "relat": [1, 4, 6, 7, 8, 9, 12, 13, 14, 17, 18, 19], "relationship": [4, 17], "releas": [4, 8, 12, 13, 15], "relev": [4, 8, 9, 12, 14, 15, 17, 18, 19], "reli": [4, 5, 6, 7, 8, 13, 14, 15, 18, 19], "reliabl": [4, 6, 14, 17, 19], "relianc": 17, "reload": 8, "remain": [4, 8, 12, 13, 15, 17], "remark": 5, "remot": [4, 5, 17, 18], "remov": [17, 18, 19], "renam": 4, "renew": [5, 8], "repeat": 18, "repetit": 15, "replai": [1, 8, 18], "repli": 8, "report": [3, 14, 17], "repositori": [4, 17], "repres": [3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "represent": [6, 7, 8, 17], "repudi": [1, 4, 5, 14], "reput": 18, "req": [2, 12, 13], "request": [1, 3, 5, 7, 11, 15, 17, 19], "request_object_signing_alg_values_support": [7, 12, 13, 18], "request_uri": [7, 8, 11, 12, 13], "request_uri_method": [12, 13], "requir": [1, 4, 5, 6, 7, 9, 11, 12, 13, 16], "research": 17, "reset": 18, "resid": [6, 12, 13, 14], "resist": [6, 8, 10, 18], "resolut": 17, "resolv": [8, 17], "resourc": [5, 6, 8, 12, 13, 16, 17], "resp": [8, 16], "respect": [6, 8, 17, 19], "respond": [8, 9, 12, 13, 18], "respons": [1, 4, 5, 7, 11, 16, 17, 18, 19], "response_cod": [12, 13], "response_mod": [7, 8, 12, 13, 18], "response_modes_support": [7, 8, 12, 13, 18], "response_typ": [8, 12, 13, 18], "response_types_support": [12, 13, 18], "response_uri": [7, 11, 12, 13], "response_uris_support": 11, "responsedata": [9, 12], "responsestatu": [9, 12], "rest": [1, 17, 19], "rest_jws_2021_pop": 1, "restor": [5, 18], "restrict": [4, 7, 8, 12, 13, 17], "restrictions_condit": 7, "restrizioni": 7, "result": [4, 8, 9, 12, 13, 14, 17], "retain": [9, 12, 17], "retent": 17, "retriev": [4, 6, 8, 9, 12, 13, 19], "return": [5, 6, 8, 9, 12, 13, 14, 17, 18], "reus": 8, "reveal": [4, 6, 9, 10, 12, 14], "revers": [6, 10], "revert": 19, "review": [3, 4, 19], "revis": [4, 5], "revoc": [1, 4, 5, 7, 8, 17, 19], "revocation_assert": 14, "revocation_assertion_respons": 14, "revocation_endpoint": 7, "revocation_request": 14, "revok": [4, 7, 12, 13, 14, 15, 17, 18], "rfc": [0, 6, 7, 8, 11, 12, 13, 14, 16, 17, 18, 19], "rfc2119": 4, "rfc3339": 16, "rfc6749": 14, "rfc7515": 16, "rfc7517": 16, "rfc7519": [6, 12, 13, 16], "rfc7800": [6, 14, 16], "rfc8152": 6, "rfc8174": [4, 16], "rfc8725": [12, 13], "rfc8747": 14, "rfc9101": [12, 13], "riccardo": 3, "rich": 8, "right": 4, "rilascio": 7, "risk": [4, 8, 15, 17], "riyvi0kaz8nz3dlhuxbbd": 6, "robust": [12, 13, 14, 17], "roland": 3, "role": [4, 5, 14, 15], "root": [4, 12, 13], "rose": 3, "rossi": 6, "rotat": [10, 14], "rp": [4, 8, 11, 12, 13, 17], "rsa": [0, 7], "rsa_1_5": 0, "rsae": 0, "rsassa": 0, "rst": 5, "rule": [1, 3, 4, 5, 6, 8, 12, 13, 17], "rulebook": 6, "run": 4, "s022cvspdxuv44x": 6, "s1mt1kxfq2o8j9io7xmmx2mixag9m9pejvqrmca": 6, "s1xk5f2pm3": 6, "s256": [7, 8, 14], "safeguard": 18, "said": 15, "saitto": 3, "sakimura": 16, "salt": [6, 9, 12], "salvator": 3, "same": [4, 6, 8, 10, 12, 13, 14, 17, 19], "saml2": [4, 8, 15], "sampl": [12, 13], "satisfi": [14, 18], "scadenza": 7, "scalabl": 17, "scale": 17, "scan": [9, 12, 13], "scenario": [4, 12, 13, 14, 17, 18], "schema": [6, 8, 17, 18], "schema_uri": 6, "scheme": [0, 4, 5, 7, 8, 11, 12, 13, 15], "sciarretta": 3, "sciunnach": 3, "scope": [4, 6, 7, 8, 12, 13, 14, 17], "scopes_support": 7, "scurtescu": 16, "sd": [4, 5, 7, 8, 11, 14, 16, 17, 18], "sd_hash": [12, 13], "sdk": 18, "se": 18, "seamless": [12, 13, 15, 17], "second": [8, 9, 12, 13, 18], "section": [0, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "section_3": [8, 14, 18], "secur": [0, 4, 5, 8, 9, 10, 14, 15, 16, 17, 18, 19], "see": [4, 6, 7, 8, 9, 11, 12, 14, 17, 18], "seek": 3, "seen": 18, "segment": [12, 13], "select": [6, 8, 12, 13, 16, 18], "self": [6, 15], "selfissu": 17, "selhausen": 16, "semant": 16, "send": [8, 9, 11, 12, 13, 14, 18], "sensit": [7, 8, 12, 13], "sent": [1, 8, 12, 13, 14], "sentenc": 4, "separ": [4, 6, 7, 8], "septemb": 16, "sequenc": [12, 13, 17, 18], "seri": 6, "serial": 8, "serv": [4, 14, 17, 18, 19], "server": [4, 7, 8, 9, 12, 13, 14, 16, 17, 18], "server_error": [12, 13], "servic": [1, 4, 5, 6, 8, 10, 14, 15, 17, 18, 19], "session": [5, 8, 13], "set": [3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19], "setup": [8, 9, 12], "sever": [3, 8, 12, 13, 17, 18], "sf2": [12, 13], "sha": [0, 6, 8, 9, 12, 14], "sha256": [0, 18], "sha384": 0, "sha512": 0, "sha521": 0, "shall": [4, 6, 8, 9, 12, 14], "share": [8, 17], "sharif": 3, "sheffer": 16, "short": [0, 8, 9, 12, 17, 18, 19], "should": [4, 6, 8, 9, 10, 12, 13, 14, 17, 18], "show": [8, 12, 13, 14], "shown": [4, 8, 12, 13], "side": [4, 8, 12, 13], "sign": [4, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "sign1": 6, "signatur": [0, 4, 6, 7, 8, 9, 12, 13, 14, 16, 17, 18, 19], "signedjwt": 17, "signific": [5, 15, 17], "significantli": 17, "signin": [12, 13], "silletti": 3, "similar": 17, "simplifi": 8, "sinc": [8, 12, 13, 15, 17, 18], "singl": [6, 8, 14, 17, 18], "siopv2": 5, "sistemi": 16, "size": 6, "slack": 3, "slow": 8, "slt14644zbyxyf": 17, "smart": [4, 18], "smartphon": [4, 18], "smith": 10, "snapshot": 17, "snif": [12, 13], "snippet": 5, "so": [8, 9, 12, 14], "soap": 1, "soc": 18, "social": 10, "socket": [12, 13], "sog": 0, "solberg": 16, "sole": 17, "solicit": 18, "solut": [4, 5, 8, 13, 17, 18], "some": [3, 6, 8, 12, 13, 14, 17], "sono": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "soon": 3, "sourc": [4, 5, 6, 8, 9, 12, 14], "source_endpoint": 17, "sovereign": 15, "space": [7, 8, 12, 13], "spazio": 7, "spec": 17, "special": [8, 12, 13, 18], "specif": [1, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19], "specifi": [4, 6, 7, 8, 9, 12, 13, 14, 18, 19], "spid": [4, 7, 16, 17], "spidl1": 7, "spidl2": 7, "spidl3": 7, "splxlobezqqybys6wxsbia": 8, "sri": [6, 16], "ssi": 15, "stage": [9, 12, 18], "stakehold": [3, 17], "stamp": 17, "standalon": 4, "standard": [1, 4, 6, 8, 12, 13, 14, 16, 17, 18], "stare": 4, "start": [8, 14, 17, 18], "state": [4, 5, 8, 12, 13, 15, 17], "statement": [5, 6, 12, 13, 18, 19], "static": [0, 5, 17], "stato": [9, 12], "statu": [1, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19], "status": 17, "status_assert": [6, 14], "status_assertion_request": 14, "status_assertion_respons": 14, "status_attestation_endpoint": 7, "steel": 16, "stefano": 3, "stem": [12, 13], "step": [8, 9, 12, 13, 14, 18, 19], "still": [4, 8, 12, 13, 17, 18], "stolen": 8, "storag": [4, 8, 14, 17, 18], "store": [4, 6, 8, 9, 10, 12, 14, 15, 17, 18, 19], "strategi": [5, 12, 13, 17, 18], "streamlin": [15, 17], "string": [6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "strong": [8, 19], "strongbox": [4, 18], "strongli": 18, "structur": [6, 9, 12, 13, 17, 18, 19], "student": 3, "sub": [6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "subject": [6, 7, 8, 17, 18, 19], "submiss": [1, 4, 12, 13], "submission_requir": [12, 13], "submit": [7, 8, 18], "subordin": [8, 17], "subphas": [9, 12], "subresourc": 16, "subsequ": [9, 12, 14], "subset": 7, "subset_of": 17, "substanti": [3, 4], "succe": 8, "succed": [12, 13], "succesfulli": 14, "success": [8, 12, 13, 14, 17, 18], "successful": [12, 13], "successfulli": [8, 12, 13, 14], "suffici": [8, 12, 13], "suit": [9, 12], "suitabl": 8, "sull": 16, "summar": [12, 13], "summari": 17, "summaris": 17, "sunflowerdream": 10, "superior": [17, 19], "supervis": [4, 9, 12], "supervisori": 4, "suppli": [12, 13], "support": [0, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "suspend": [12, 13], "suspens": 14, "svg": [7, 11, 17, 19], "swap": 8, "switch": 8, "symmetr": [8, 12, 13, 14, 18], "syntax": [11, 12, 13, 16], "system": [4, 6, 8, 10, 15, 17, 18, 19], "t": [9, 12, 14, 16, 17], "t6dahp3tuwa_27kle8i9z_spk2ftqlky6pgmpchbsi2ahxy3aaxdurobpo4chtqgg3j2xcrghdfucfgeq": 17, "ta": 17, "tabl": [2, 6, 8, 9, 12, 13, 14, 17, 18, 19], "tag": [4, 6, 7, 18], "takahiko": 3, "take": [14, 18], "taken": [7, 8, 18], "tamper": [17, 19], "target": [8, 12, 13], "tarjan": 16, "task": 17, "tax": [6, 7], "tax_id_cod": [6, 7, 11, 12, 13], "tax_id_numb": 6, "taxpay": 6, "tcaer19zvu3ohf4j4w4vfsvohip1ilildls7vcegemc": 6, "tech": 17, "technic": [1, 3, 4, 5, 7, 9, 12, 13, 14, 17, 18], "technician": 3, "techniqu": [12, 13], "technolog": 17, "technologi": [9, 12, 16], "tecnica": 16, "tecnologica": 16, "ted": 19, "tee": [18, 19], "telephon": 14, "template_uri": 6, "templatepid": 6, "temporari": [9, 12, 14], "temporarili": 8, "terbu": [3, 16], "term": [5, 17, 19], "termin": [5, 13, 18], "terminologi": 4, "text": [6, 8, 12, 13, 14, 18], "tfa0t8x": 6, "than": [8, 9, 12, 14, 17], "thank": [3, 17], "theft": [14, 15], "thei": [3, 4, 6, 7, 8, 12, 13, 14, 15, 17, 18], "them": [1, 4, 12, 13, 14, 15, 17, 18, 19], "themselv": 1, "therebi": 8, "therefor": [4, 6, 8, 12, 13, 14, 18], "thereof": 17, "thi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "third": [4, 14, 17, 18], "thoma": 3, "those": [1, 6, 8, 14, 17], "threat": [17, 18], "three": [9, 12, 19], "through": [4, 6, 8, 9, 12, 13, 14, 17, 18], "throught": 18, "thu": [8, 17, 18, 19], "thumbprint": [8, 14, 16, 18, 19], "thumprint": 8, "tild": 6, "time": [1, 4, 6, 8, 9, 12, 13, 14, 16, 17, 18, 19], "timestamp": [6, 8, 12, 13, 14, 16, 17, 18, 19], "tinit": 6, "tklulvhywfhywfhywfhywfhywfgixq": 6, "tl": [8, 12, 13, 17], "tl5onvr": 8, "todo": 2, "togeth": [6, 8, 9, 12, 14], "token": [1, 5, 7, 12, 13, 16, 18, 19], "token_endpoint": [7, 19], "token_endpoint_auth_methods_suppor": 19, "token_endpoint_auth_methods_support": [7, 19], "token_endpoint_auth_signing_alg_va": 19, "token_endpoint_auth_signing_alg_values_support": [7, 19], "token_typ": 8, "tool": [14, 17, 18], "top": [8, 12, 13], "topic": [4, 18], "torsten": 3, "tos_uri": [7, 11, 19], "touchpoint": 14, "toward": 6, "track": [4, 6, 18], "tradit": [15, 17], "transact": [4, 8, 10, 12, 13, 17, 19], "transfer": [4, 16, 18], "transfermethod": [9, 12], "transit": [5, 17], "transmiss": [1, 12, 13, 17], "transmit": [8, 9, 12, 13], "transpar": [4, 17], "transport": 8, "treat": 8, "trigger": [8, 14], "true": [4, 6, 9, 12, 14], "truncat": 0, "trust": [1, 4, 5, 6, 7, 8, 11, 12, 13, 15, 18, 19], "trust_chain": [6, 12, 13, 17, 18], "trust_framework": [6, 9, 12], "trust_mark": 17, "trust_mark_id": 17, "trust_mark_issu": 17, "trust_mark_own": 17, "trust_mark_statu": 17, "trusti": 19, "trustworthi": [4, 8, 17, 18], "try": [12, 13], "ts_etuqs0ieiis1nynbheqsoy3ct4gpi": 8, "tschofenig": 16, "tsp": [4, 17], "tstr": [6, 9, 12], "turn": 14, "tutt": 7, "tutti": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "two": [6, 8, 9, 12, 13, 14, 18], "typ": [6, 8, 12, 13, 14, 17, 18, 19], "type": [4, 5, 7, 8, 9, 11, 12, 13, 14, 16, 18, 19], "typic": [3, 8, 15], "typo": 3, "u": [6, 7], "u0tx0gdflndditbcwznupy7m2tnh08jld": 17, "u2tdugtfsfo0dtlvv2oxu2xjqmxdyzfvil0sicjpc3mioiaiahr0chm6ly9wawrwcm92": 6, "u9xuk9biiwginrhef9pzf9jb2rliiwgilrjtklulvhywfhywfhywfhywfhywfgixq": 6, "uicc": 4, "uint": [6, 9, 12], "un315hdckvhya": 17, "un_distinguishing_sign": [9, 12], "unabl": [12, 13, 14], "unalt": 18, "unambigu": 4, "unauthor": [12, 13, 15, 18, 19], "unavail": [1, 8, 14, 17, 18], "under": [4, 12, 13, 14, 15, 17, 19], "undergo": [17, 18], "understand": 6, "unencrypt": [12, 13], "unexpect": [8, 12, 13], "uniform": [16, 18], "unilater": 18, "uninstal": 18, "uniqu": [1, 4, 6, 7, 8, 10, 11, 12, 13, 14, 17, 18, 19], "unique_id": [6, 7, 11, 12, 13], "univers": [8, 18], "unix": [6, 8, 12, 13, 14, 17, 18, 19], "unless": [9, 12], "unlik": [6, 17], "unlink": 8, "unlock": 19, "unpredict": [8, 18], "unprotect": 6, "unreserv": 8, "unsign": 6, "unsuccess": 8, "unsupported_hash_alg": 14, "unus": 18, "up": [9, 12, 13, 14, 17], "updat": [1, 5, 6, 12, 13, 14, 17], "upon": [4, 8, 12, 13, 17, 18], "uppercas": 16, "uri": [5, 8, 11, 16], "url": [6, 7, 8, 11, 12, 13, 17, 18, 19], "urlencod": [8, 12, 13, 18], "urlparam": [12, 13], "urn": [8, 18, 19], "us": [0, 1, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19], "usabl": [5, 18], "usag": [12, 13, 17, 18, 19], "usascii": [8, 16], "useful": 2, "user": [1, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19], "utf": 8, "util": [4, 6, 7, 9, 12, 13, 14, 18, 19], "utmost": 19, "uuid": [8, 9, 12, 14], "uuid4": 8, "uy2vfywxsb3dhbmnliiwgdhj1zv0": 6, "v": 16, "v1": [4, 6], "v1_5": 0, "v2": [7, 8, 11, 16], "v4": [8, 14], "v9ynfxhkxpohqsmmulvibkrwfpepdf4qwdonmdojmroxr5j4hshh9mbem5qohh_pde62i1tlc36c65jfya7x3a": 8, "valid": [1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 17, 18], "validfrom": [6, 9, 12], "validityinfo": [6, 9, 12], "validuntil": [6, 9, 12], "valu": [0, 2, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "value_typ": [6, 7], "valuedigest": [6, 9, 12], "valueless": 14, "van": 3, "var": 18, "vari": [4, 17, 18], "variou": [12, 13, 17, 19], "vbexjksm45xphtanncig6mcyuu4jfgnzopgukvogg9c": 18, "vc": [4, 5, 7, 8, 11, 12, 13, 16, 17, 18], "vc_claim": 6, "vct": [6, 7, 8, 11], "vctm": 6, "vdflegzxmm84sjlpbzd4tu1ymk1jegfhou05ugvkvnfytwnbiiwgillyyy1zlvdtcjrl": 6, "vdiiwieci6imw4dezyahgtmzr0vjnoukldukrzoxpda0rscejorjqyvvfvzldwqvdcr": 8, "vector": 0, "vehicle_category_cod": [9, 12], "vendor": 18, "ventola": 3, "verif": [6, 8, 9, 12, 13, 14, 15, 17, 18], "verifi": [4, 5, 6, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19], "vernini": 3, "version": [3, 4, 6, 7, 9, 12, 16, 18, 19], "vet": 4, "via": [3, 6, 8, 9, 12, 13, 17, 18], "view": [5, 8, 19], "vladimir": 3, "volum": 17, "voluntarili": 19, "voucher": 1, "vp": [4, 12, 13], "vp_format": [7, 11, 17], "vp_formats_support": [12, 13, 18], "vp_token": [12, 13, 14, 18], "vqi": 6, "vulner": [0, 4], "vwh1vxh6m2dnmnzjrvpmzvljajyxs2fziiwginmxwes1zjjwttmtyuzuyxvyag12zdlw": 6, "w3c": [6, 16], "w8q7fjh9bearf8lm7rqrxavc": 8, "wa": [4, 6, 8, 12, 13, 14, 18, 19], "wai": [4, 6, 8, 17, 18], "wait": [8, 12, 13, 16], "wallet": [1, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 16], "wallet_provid": [5, 17], "wallet_relying_parti": [5, 12, 13, 17], "walletattest": [7, 11, 12, 13], "walletprovid": 18, "want": 15, "war": 18, "we": [3, 6], "web": [7, 8, 11, 12, 13, 14, 16, 17, 18, 19], "webpath": [12, 13], "webserv": [12, 13], "websit": [5, 17, 19], "weinberg": 16, "welcom": 3, "well": [1, 4, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "were": 18, "what": [2, 5, 8, 15, 17, 18], "when": [1, 4, 6, 8, 9, 12, 13, 14, 17, 18, 19], "whenev": 14, "where": [3, 4, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "whether": [6, 8, 12, 13, 17, 18], "which": [1, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19], "while": [4, 6, 8, 10, 12, 13, 15, 17, 18], "who": [4, 8, 14, 15, 17, 18], "whom": [4, 15], "whose": [1, 12, 13, 18], "why": [12, 13], "wia": 8, "wierenga": 3, "window": 8, "wish": [6, 8], "within": [1, 4, 6, 7, 8, 9, 10, 12, 13, 14, 17, 18, 19], "without": [4, 6, 8, 10, 14, 15, 17, 18], "wnz1m09irjrqnfc0dmztvm9isvaxsuxpbersczd2q2vhzw1jiiwginkioiaiwnhqavdx": 6, "word": [4, 16], "work": 3, "workstat": [12, 13], "would": [3, 8], "wp": 18, "wqhydymfksp95ifqpzdedww4l7avna2fn4jcewhytbu": 18, "wrap": 0, "write": [12, 13, 19], "wryzxnvdxjjzsisimlhdci6mtu2mji2mjyxocwiyxroijoizlvieu8ycjjam0rantnf": 8, "wscd": [4, 18, 19], "wsr4exeytqdesmrl7spovfmbxixp12e4syqn": 6, "www": [7, 8, 12, 13, 18], "wyi2swo3de0tytvpvlbhym9tn": 6, "wyi2swo3de0tytvpvlbhym9tnxrtd": 6, "wyi2swo3de0tytvpvlbhym9tnxrtdlzbiiwgimdpdmvux25hbwuilcaitwfi": 6, "wyitt25um29fcgh6tdnnchjucvf0yud3iiwizg9jdw1lbnrfbnvtymvyiiwimdawmdawmdiixq": 8, "wyiwqux5szrfui1avuptekvkdw5htfdriiwiawf0iiwimtc0nzexotu5nsjd": 8, "wyiyr0xdndjzs1f2zunmr2zyeu5stj": 6, "wyiyr0xdndjzs1f2zunmr2zyeu5stjl3iiwgimlhdciside2odmwmdawmdbd": 6, "wyj2bmtvx2tjv2rsa1dpzzbonlrycdd3iiwiz2l2zw5fbmftzsisik1hcmlvil": 8, "wyj3tw1xykkztfrpmdvlajfolxnpwwhriiwiy29uc3rhbnrfyxr0zw5kyw5jzv9hbgxvd2fuy2uilciwil0": 8, "wyjbodvjefi1rezyoelfafzfqtzqzgnbiiwibglua19xcl9jb2rliiwiahr0chm6ly9xci5legftcgxllmnvbsjd": 8, "wyjbsngtmdk1vlbycfr0t": 6, "wyjbsngtmdk1vlbycfr0tjrrt": 6, "wyjbsngtmdk1vlbycfr0tjrrtu9xuk9biiwgimv4cglyev9kyxrliiwgijiw": 6, "wyjbsngtmdk1vlbycfr0tjrrtu9xuk9biiwginrhef9pzf9jb2rliiwgilrj": 6, "wyjgvu1iqm5hlwhllulawtzkovz1uknbiiwiymlydghfzgf0zsisije5odatmdetmtaixq": 8, "wyjhmdjou3jrzmpgwfe3sw8woxn5ywpbiiwgimnvbnn0yw50x2f0dgvuzgf": 6, "wyjhmdjou3jrzmpgwfe3sw8woxn5ywpbiiwgimnvbnn0yw50x2f0dgvuzgfu": 6, "wyjhwhrynxnuetctvevpblhzajnmdgdbiiwicg9ydhjhaxqilcivowovnefbuvnrwkpsz0fcqvffqkxbrxnbquqvnffcv1jyahbaz0fbvfuwqutnqufbqwdbqkffyufbvufbqufcqufbqvbnrwjbqvvbqufbqkfbqufsz0vvqufnqufbqujbqulbqufjvefbtufbqufcquffqufbqufbqufbquffc0fbqufbuufbqvn3qufbquivkzbbtezcb2izunzjmmh2y0nbekxqqufprupkvffrrufbqufbqufqsefgyufbtwjkvwnjqvfbqufnquvbuc9orelgb2riundpath2ym5ndvlxunzzbvv1wti5dewzaghjqzh4tgpbdkfedy9lsejowtj0bgrdqmlav2rwymowbjc3ds9keujwwkqwblz6vk5nrtf3utjwb2fvadzjbvzuzws1vvkzchjzemxrsno4k0nqedrpbmh0y0cxbgrhrwdlrzfzym5nnmvemg5zv1j2ww1vnmjuttziv1ywwvm4bklizzzlrzf3zedzouowbhrzv2rst2pwrmvhbg1wrzl2yknbee1dnhhnq2mrq2p4evphwtzva1jhsuhodgjhnxppbkprwmowbmfiujbjrg92tdnkm2r5ntnnetv2y21jdk1uazvpuzh3twk4eu1pmxlar1l0yznsdwrhrjrmvzv6sxljk0nnb2dqseprwmpwrvpytmpjbwx3zedsdmjpqnlar1k2wvdkdmryutlkewnlsuncngjxehvjenawyvdabvbtzg9ksfj3t2k4dmjutxvzv1j2ww1vdvkyoxrmm1jwwm1zdk1tnhdmewmrq2lbz1biunbabvk2vw1wemiyedfkr2x2ymxwdwfyustnand2zedsbvpqcfnawe52ykhwmgfxoxvwvzvwzeq0s0ldqthkr2xtwmpwwvvtvnpimngxzedsdmjqnhpnref2tvr3dmrhbg1aanbzvw1wemiyedfkr2x2ymo0s0ldqthkr2xtwmpwwlvtvnpimngxzedsdmjqnhpnref2tvr3dmrhbg1aanbavw1wemiyedfkr2x2ymo0s0led3zjbvjtt2tsbgmytnlhweiwyvc5dvbnb0tjrhh5wkdznljhvnpzm0pwy0hscgiyngdjbvjtt21gawizvjbqu2nuq2lbz2vhmxnibk02zucxd1rvmdlkmmgwzehbnkx5oxvjetvowkc5avptnwpimjb2zudgd0x6rxvnqzl0ylm4blbnb2djrhg0ylhctlrucevimk4xyldwdwrfbevqbuzryjjkbe9tunzzmmxrt25omgiytnjpamxqtmpabvpuzgxmvfkzwtjrde5ettrzeta1wlrobuxusxdpree1tkrobu9uwtjavhd2zucxd1rvmdzsrzlqzfcxbgjuukpsrdrlsunbogvhmxduvta2u1c1emrhrnvzmlzkukq1ngjyqxvhv2xrt2psae16zzbzvfuxtfdjek1uz3ror05rwvmwne4yvxpmve14tvrzd00ytmhaveuzt0r3dmvhmxduvta2u1c1emrhrnvzmlzkukq0s0led3zjbvjtt2tsbgmytnlhweiwyvc5dvbnbzhmm0prwmpwu1jfwstdand2zurwngjyqnrawfjougdvz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0npqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqutjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjqw9nsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnq2lbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbs0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0lbb2djq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwddaufnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0flsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsufvz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0npqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqutjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjqw9nsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnq2lbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbs0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0lbb2djq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwddaufnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0flsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsufvz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0npqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqutjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjqw9nsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnq2lbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbs0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0ldqwdjq0fnsunbz0lbbzhqm2h3wvdoclpyuwdavzvrufnkm0p6ocsvoxnbuxdbrkf3uuvcqu1gqkfrrujrvuzcz2nnq0fjsej3y1bdd3nkrejfuevosvjeeevsrxhzy0z4tvvhafvsrvjnaedcb2riujhmshhnwelpuwliavfjsgg4zs85c0frd0vgqlfvsejny09dqwdpsghrukzcngviadrlsgg0zuhongviadrlsgg0zuhongviadrlsgg0zuhongviadrlsgg0zuhongviadrlsgg0zuhongviadrllzhbquvrz0jhquzvqxdfukfbsvjbuu1sqwyvrufcmefbuufcqlffqkfrqufbqufbqufbqufbqudbuvviq0frrufnuc94qujdruffqufrtunbz01oqlfvsejrqufbqufbqvfjrejbvudceevotvzfsuvotvvgeupcvm1geg9hvfnrb0dsa3nfak1rt0nvafvxww5lrhnzsvlobeoxcy8vrufcwujbuuvcqufbqufbqufbqufbqufbqufbqujbdi9fqujzukfrrujbqufbqufbqufbqufbqufbqufbukfml2fbqxdeqvfbq0vrtvjbrdhbm0xbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufcnxrtejhmve1hn25hamwytvrgcza5own2whjrvvvvujj6ttlfqxdudmz1bhrwnlzjcnh0ddrpvhixnm5usgh1zmdnzm43s3fvbxfyn3flwhrjtvy2mtntwevqtnvut0jscedsmgvptfdotjjxuhzybvkrq3dxwhk5y1zllzc3kzgxuhu4uxnjdjloqmv0rjdwtgliafhjblbvmgpws1burjnhbtfwudmwvevmqwd5chnqdwx0cdzyy294dhlzt1rvtjzybehodwzoogzun2fxwwlxbjc2zvh0u0robw01k0zxzuzhenrpetdhwgkzcwurddnytnllnks0n1ltt2lrzwtbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbquffttryofjkqzrlyuy0oxfkvtm4dtl6chc4sznwrvhmovvmn2fzou5vouvlmmvvqtb2ngs4uxr6yisxt2nywe15zkzxs3bushdivxpgaxhic3a5tlgrs2vjkzdxvvjkuufbqujmzuczruxjmndkvgplmfbnbnhhdxfkeu1hn016wxz4n2fmulyvawpsuhy2a0c2senqauxvwevquxzide1xbxhsmmvwt1powetvbtvzcw4vzfrqb3fqb24yvhpoqk13qufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqvdqzm01ou4yzhrytznecxrmteh4yu9jvvjqblhhntzlyutmylzqs1bqnkfhrwi4m1zxkzg5elpxdjz6ztcvsxz6ew90mho1bgkzsdd0dwlqulrieg5uttlncuxfb0fbqufbqxz1dzkxyxzzemmythiralh1ohlmrthxn2rvk1pmdhorowjyajawejhknvrivenezmzzztu5tjnqdfhcm0rwvmzqshlxt2mwvfbuv3e0nktxs3zivfbpugo2vuy4qufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqnfsm1l1ohe5vdnkajdregjzk0o2vfrgm0ppsjzlogl1bm5iuc9muk1mzlhlne1es0fbqufbqufbttg5edf2s3zutjnarzbnctdqawvxmhpkeg9tzwlqsw9wnxp5l3pvulazmfftamjkqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufck2vuzhqytwu1znuxzddiddb6wfzqwkvsemtit1rjk3jydguzshfxddvgvxpkejhxnwtwznpwve1sotbjbys1umjsqufbqufbqufgedj4cte3uwr4nmjyzvbwtvhjret0nuzqohrvve1mzkhpuhzrzec4ytdidjq5ds9hctc2m2nwaxvtztjkam5drdlbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqvi3avhmcxh1sfc1twlpzvzwdlnzcxftzmjgcw9itytpt1zgtwrrukrrcufbqufbqufbq2xjyzzlbzdzbufkru9hbctysjrkymj5szu1mvhos3hhcxa5czjxv1jjuufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufxwgztslzxr3lozhdhstuxnudtnuzxbvbivmjxaufjnktpbwltwjdjyuzrqufbqufbqufvcjzls3bqc2tiumzzzupwcct5tkn3ytq1vjqrbtq5cxfqylricglxumvnqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqvvxauppww1py0e1nthuzhyztnjjuu5imet1awfhy1hncjheempydfzumzf1znkxuw9qawdbqufbqufbq1i4txr2m04wy1fortblawlhcwnytw84tnlqcxrvejmxewz5mhlnnkdveevsrvjis0vguufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbytnkmlrzv3uvalltkzlqc3pwt1bur0xxvvv4l0q1l3m3ays2wm1twi94vtlpne5zrkfbqufbqufbr3ovy2jirnjzwtjydnzvte0wemtvemk2ykzvzncrzjdtnuh2bulwai9bqzfkcwfoa1vbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufibjfiq3hkundmk0juv0tnakz5tgrwctlhcmpuvfhsvkhlww4yvefosgvpwereudrkn2hud1zgm0kwsexybwnis21pzmurbndwyytpdu8zn1vkugjfvvk1vufbqufbqvphnec4tu0vaup1r1bdmfhjzlfju3vkennxstvkotzmqlvul3ddyzl2mlk2zxlkzznpmdddegrpd0xhqmcys01mrng3ze5xemfvamxuuljusetjajjsq0qwqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbque4rzrorzb2wdljeu5kmwpdczv1rmtvotdkcznznxhwsdzusfhfedb4ufvevtdpmznqbxzizxuzdfmyalrlmxztzwmxzux4mdvwau96bc9fajj4ntnishbxaknoewl1m2nyddnlyxflnko1vjaxunlxcg5zbuo2wwxsogdbqstyzezketvsynqwmvyxmxp5b3bwam5wvlbarviweklnm2nktzu4mtdjtjj6cvc3cwiyawfuemlyegvlakt2edjjdjrjztjmtzdjoutvylk3zjbiuzlbmgpimg5soet6aflxufqzdhf6ywpsrk1mck05y3pqve05yuqzz0fbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufby3dlrfu5wjbqvetactfmvk1iq3bqcm5jeutmy2yxvefjsnjpqndlngxabhpgewiym2ryejzqtjhkajvwrk9sshvyb21lcctnqwhldgr5oxrysxjtdlnkd2f4cdhuowk3rkyrbvb4auorszbxyi9wv283ly9btdvxnzmvmwtjly9bs0zgntbydvh0ctq5y1y2dhvev05ravbzv29vc1v6k0vwvdhtawfhtmdjshvhdvpiegnhoxqzu00rdnpmq1phvljwa1q3njy1bxfqaendzdzack9ryw5urldtnnbnnxrnovu0k1jsy2orbvpcnytzqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufmsnzezg0zzg82zc9hrzr0v3h0uhnuuetqd2xyt3e1ufpsvehuvlq3swlrwwixm3vvdhm0otjxalj0dtzycu1smvhmmwrhufrwn284nnjsnzrowulactnkumjvdmq5r21iyjbqrxbucw0vzhvynm8vrhzzsuloctnidmlobnhwvfryoxjdb243t0pomjzpwdmxulzqeeljanerk041nnzfehfxnjliexfanjzhczj1s2z5ee1soefskzvnm0s1cnvmdetwkzfyntavaktpbnbpzlrivlbzq1jhuhzuzw1rvvjimhpkbxq0dhvpcwlqtnjtbva1wm1zuvhmexzjvgu4nzmrk3vxohzmunovqui3mgd0r3nintnwctlfmjlum1pyzvzibnjvcnphnhbuk1dkaufsmzb6uhbucm50vvz0ek51dus3zjdpcvb0vwviudr3q1fhunzqzwvrukvhynv2vzhxbu9xbw5ocm1uohn6twzcqkx0sjq5ofvnq0thyxrmdfp0rwvqthc3zgzqnzzzcg40a0v2mg51b3qwv2u5alu5ddzsbdb4mxpzdtnmrluvajmwruv6mex1b3rznuyybwpxzhzhcnawvdezte5kr1jusdnlylz5otbtuvprmmz1emj1n3rpl3reynvywtjvv0lubfg0t3jsvmjuc3jwbnpxwjlreendowdbqufbqufbqufbqufbqufbqufbqufbqufbqwhur0hmdur3otjmzdfqsw9wdjvkexj3t0zqvfz5oe5kbu9julbavevktxoyujj6qu5htji3ajfuzfd1whramtdpdvptwmruotzyb3bvcdlgrkzqvlrusg9pugpqu290s2dbqufbqufbqufbqufbqzdiuznick8xzgnznnpvv2rjdzh5mva3mvbuvfhunmflnmvxcw1lewzoufnnm240ugi5d2vjv3o3v3nzouzoakx0mwvcemnhs3vmz2jzunptstdhwmpwawv5ztjkuvrnqufbqufbqufbqufbqufbqufbqufbqufbqudtzmrkn2l2yxr4vhewzuxremk2tmowv2flww5voepjaus2nnzmew1pudvwd1livufbqufbqufbqufbqufbqufabddrvgnwn1nls2rpanpjbu1yv2nldxpyve05sghmy1ryuly3k1vwec9nbwpjdefbqufbqufbqufbqufbqufbqufbqufbqufucujvrnh5ditny1lkmtnpzlzxzhlqohnsvc94wejerkfbqufbqufbqufbqufbquffejrhmy9gk01pmuxuuhixtznsk2fkcc81sm8zowpxuufbqufbqufbqufbqufbqufbqufbqufbqupcenm0adviamuvoefjv1z6nstgmvhlcwlmovdwullsqufbqufbqufbqufbqufbquy5ngvasgltlzl1nvhqbdrmvmnxcvovmwfvsfjprufbqufbqufbqufbqufbqufbqufbqufbquzlcgllwm1lauk2uwmyzfv2vgthbmw1rtlnm2npnwmvtlhnl3fvohlnqufbqufbqufbqufbqufbrda2wgvusdfqrxljnkp0wkz1nstxduovukiwbxbtsnbpwtzzbnbrvkfbqufbqufbqufbqufbqufbqufbqufbqjrkd1gvrmrdejhtwjvsyxhydgy0vvrqnke1dvvuem9wcw5ybulsb1zbqufbqufbqufbqufbqufbqln1zvzgvlvky1jnzzzsn2z2k05hrmdatvr6atdqv3eveg9pzjfashvbqufbqufbqufbqufbqufbqufbqufbqujit0thukdkdzmztgs4k1hnoup5wmlmyjrlb0hqr21pvk1smljftknvqufbqufbqufbqufbqufbqutwunpwbu8ysmdiutdozmtsbdhooxraufbunfrty2fabjirq3barwpbqufbqufbqufbqufbqufbqufbqufbqujctzzdevbgdurhnnjrvhk1nmzyyi9otvuvcurrdwv1v2hrqufbqufbqufbqufbqufbquzznjrcdnazuhvsnhp3wtjyy21lzkxunkxmnvptbjlhuk93qufbqufbqufbqufbqufbqufbqufbqufzlzdvckn5yy9ndhvishhls3e3be9mrjjhyvk1ek5odxvtdxirbw1ryuh0qufbqufbqufbqufbqufbqufbrgzedwrjtep3t0mymmnmtg9xb3uxwxmzwxbxamxnvtnlnne2zjzhb1phuufbqufbqufbqufbqufbqufbqufbqufbqwzoewlpn2jxddnls2e2s29ts3fhbzv4tvqxee1bmwi0cgr6zhfsr3fydfeysgn4nytgzxftcu5pdjnmqjeysm43tkzjk2jwvdjstxhnzfhpvm9nugtinhercs93qtlzk3nvzvfmaxi2ci9brdfqnnlonuirs3zxdjhbufdqcktia0g0cstxl3dbovkrc29luwzpcjzyl0femwo2ewg1qitldnf2oefqv1bys0hrsdrxk3evd0e5wstzb2vrzmlynnivquqxajz5advck0t2cxy4qvbxuhjlsgtinhercs93qtlzk3nvzvfmaxi2ci9brdfqnnlonuirs3zxdjhbufdqcktia0g0cstxl3dbovkrc29luwzpcjzyl0femwo2ewg1qitldnf2oefqv1bys0hrsdrxk3evd0e5wstzb2vrzmlynnivquqxajz5awzjtgu1dtftdlzmt29iohvzowpdczfsvk9uv0x2aes3ohg5bxv1ue5wcddzavptzxjuqlj0smjvb3rxnmjkdwltawltswltbw1pvvjfzfvsq0q2qufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufbqufcly9ail0": 8, "wyjjq0zdexljv1j4alzinkzurvr5otd3iiwidgf4x2lkx2nvzguilcjsu1nnuke4mfiwmug1mdfcil0": 8, "wyjlbhvwnu9nm2dttkljoevzbnn4qv9biiwgi": 6, "wyjlbhvwnu9nm2dttkljoevzbnn4qv9biiwgimrvy3vtzw50x251bwjlcii": 6, "wyjlbhvwnu9nm2dttkljoevzbnn4qv9biiwginvuaxf1zv9pzcisicj4ehh4": 6, "wyjlbhvwnu9nm2dttkljoevzbnn4qv9biiwginvuaxf1zv9pzcisicj4ehh4ehh4ec14": 6, "wyjlsthav205uw5luhbougvozw": 6, "wyjlsthav205uw5luhbougvozw5izg": 6, "wyjlsthav205uw5luhbougvozw5izghriiwgimzhbwlsev9uyw1liiwgiljv": 6, "wyjqyzmzsk0ytg": 6, "wyjqyzmzsk0ytgnoy1vfbehnz3zfdwzriiwginrhef9pzf9jb2rliiwgilrj": 6, "wyjrz19pnjr6cuf4ztqxmmexmd": 6, "wyjrz19pnjr6cuf4ztqxmmexmdhpcm": 6, "wyjrz19pnjr6cuf4ztqxmmexmdhpcm9biiwgimjpcnrox2rhdguilcaimtk4": 6, "wyjvrudnavzqaxv1dejvby1wctd6wurbiiwizmftawx5x25hbwuilcjsb3nzasjd": 8, "wyjvsefhawz1bzlotw9pbkvdu0loog9riiwizxhwaxj5x2rhdguilciymdmwltaxltewil": 8, "x": [1, 6, 7, 8, 9, 11, 12, 13, 14, 17, 18, 19], "x20": 8, "x23": 8, "x2zomhngsdc4zlbrcxhmt3mzrmrzog9jd3o2qjzdam51cuhhufruowd0wq": 17, "x5c": [6, 17], "x5chain": 6, "x5d": 8, "x_509": 6, "xfahyomi54": 6, "xmw7apdlbmuw3t1urwi4nafmtkri": 17, "xr2pjyrjkgmnz4wmdnqd_ujsq4r95nj98b44": 18, "xrtdlzbiiwgimdpdmvux25hbwuilcaitwfyaw8ixq": 6, "xxx": 6, "xxxx": 6, "xxxxxxxx": 6, "xxxxxxxxxx": 6, "xxxxxxxxxxxx": 6, "xxxxxxxxxxxxxxx": 6, "xxxxxxxxxxxxxxxx": 6, "y": [6, 7, 8, 9, 11, 12, 14, 16, 17, 18, 19], "y1ltc2": 8, "y2vfywxsb3dhbmnliiwgdhj1zv0": 6, "yasuda": [3, 16], "ylpnuudivldlvle0agjtswlyc1zmdwvjq0u2ddrqvdlgmkhausj9fx0": 6, "you": 3, "your": 4, "yqyvnmcw6fy1dqd": 8, "yrc": 6, "yvbn": 6, "ywy2ntnjzdczzjywnzhimwyilcaidmvyawzpy2f0aw9uijogeyj0cnvzdf9mcmftzxdv": 6, "yxr1c19hc3nlcnrpb24ioib7imnyzwrlbnrpywxfagfzaf9hbgcioiaic2hhlti1nij9": 6, "yxrpb24ioib7inrydxn0x2zyyw1ld29yayi6icjlawrhcyisicjhc3n1cmfuy2vfbgv2": 6, "yyyi": [6, 7], "zecca": [9, 12], "zneybzhkowlvn3hntvgytul4yuc5ttlqzupwcxjny0eilcaiwxjjlxmtv1nyngv4rvl0": 6, "zspe_neo": 8, "zu": 16, "zvdghcmclmvwluggsgpskcpkehz4u9owj1sliblcc1o": 6, "zwwioiaiaglnacisicjldmlkzw5jzsi6ihsibwv0ag9kijogimnpzsj9fswgil9zzf9h": 6, "zxjiwwbzmqghvwkvq4hbsiirsvfuecce6t4jt9f2hzq": 6, "\u00e5": 16}, "titles": ["Cryptographic Algorithms", "Authentic Sources", "backup-restore.rst", "How to contribute", "Normative Language and Conventions", "The Italian EUDI Wallet implementation profile", "PID/(Q)EAA Data Model", "Entity Configuration of PID/(Q)EAA Providers", "PID/(Q)EAA Issuance", "Proximity Flow", "Pseudonyms", "Entity Configuration of Relying Parties", "Relying Party Solution", "Remote Flow", "Credential Lifecycle", "The Digital Identity Wallet Paradigm", "Technical References", "The Infrastructure of Trust", "Wallet Attestation", "Wallet Solution"], "titleterms": {"The": [5, 15, 17], "about": 17, "access": 8, "acknowledg": 3, "acronym": 4, "algorithm": 0, "anchor": 17, "api": 17, "assert": 14, "attest": [17, 18, 19], "attribut": 2, "authent": 1, "author": [8, 12, 13], "backup": 2, "case": 14, "cbor": 6, "chain": 17, "check": [12, 13], "claim": 6, "code": 2, "common": 17, "compon": 18, "configur": [7, 11, 17], "consider": [2, 10, 17], "content": 5, "contribut": 3, "convent": 4, "credenti": [6, 8, 14], "cross": [12, 13], "cryptograph": 0, "data": 6, "deactiv": 19, "decentr": 17, "defer": 8, "defin": 4, "detail": [12, 13], "devic": [9, 12, 13], "digit": [6, 15], "dynam": 18, "eaa": [6, 7, 8], "endpoint": [8, 12, 13, 17, 19], "engag": [9, 12], "entiti": [7, 11, 17], "error": [12, 13, 14], "eudi": 5, "evalu": 17, "exampl": [6, 7, 10, 11], "extern": [2, 19], "fast": 17, "feder": 17, "federation_ent": [7, 11, 17, 19], "flow": [8, 9, 12, 13, 14], "format": 6, "function": [14, 17], "gener": [2, 8, 10, 17], "header": [8, 19], "high": 8, "how": 3, "http": [8, 12, 13, 14, 18], "i": 10, "ident": 15, "implement": [2, 5, 10], "index": 5, "infrastructur": 17, "initi": [18, 19], "instanc": [14, 18, 19], "intermedi": 17, "introduct": 5, "issuanc": [8, 18], "italian": 5, "jwt": [6, 12, 13], "languag": 4, "leav": 17, "level": 8, "librari": 2, "lifecycl": [14, 18, 19], "live": 17, "long": 17, "low": 8, "mdoc": [6, 9, 12], "mechan": 17, "metadata": [6, 7, 11, 17, 19], "mobil": 6, "model": 6, "namespac": 6, "non": [6, 17], "norm": [4, 6], "notif": 8, "oauth_authorization_serv": 7, "object": [6, 12, 13], "offlin": 17, "openid_credential_issu": 7, "oper": [14, 19], "par": 8, "paradigm": 15, "paramet": [6, 8, 17, 18], "parti": [11, 12, 17], "pattern": 1, "payload": 19, "pid": [6, 7, 8], "possess": 14, "post": [12, 13], "present": [12, 13, 14], "privaci": 17, "process": 19, "profil": 5, "proof": 14, "properti": [2, 10, 17], "provid": [7, 19], "proxim": [9, 12], "pseudonym": 10, "push": 8, "q": [6, 7, 8], "redirect": [12, 13], "refer": [2, 16, 19], "registr": 18, "reli": [11, 12, 17], "remark": 17, "remot": [12, 13], "renew": 17, "repudi": 17, "request": [8, 9, 12, 13, 14, 18], "requir": [2, 8, 10, 14, 17, 18, 19], "respons": [8, 9, 12, 13, 14], "restor": 2, "return": 19, "revoc": [12, 13, 14, 18], "role": 17, "rst": 2, "sd": [6, 12, 13], "secur": [1, 6, 12, 13], "session": [9, 12], "snippet": 2, "solut": [12, 19], "sourc": 1, "state": [18, 19], "statement": 17, "static": 18, "statu": [12, 13, 14], "technic": [8, 16], "term": 4, "termin": [9, 12], "token": 8, "transit": [18, 19], "trust": 17, "type": [6, 17], "uri": [12, 13], "us": [10, 14], "valid": 19, "vc": 6, "verifi": 14, "view": 18, "wallet": [5, 14, 15, 17, 18, 19], "wallet_provid": 19, "wallet_relying_parti": [7, 11], "what": 10}}) \ No newline at end of file diff --git a/refs/pull/443/merge/en/ssi-introduction.html b/refs/pull/443/merge/en/ssi-introduction.html new file mode 100644 index 000000000..6df9e989b --- /dev/null +++ b/refs/pull/443/merge/en/ssi-introduction.html @@ -0,0 +1,221 @@ + + + + + + + + The Digital Identity Wallet Paradigm — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

The Digital Identity Wallet Paradigm

+

The Digital Identity Wallet paradigm refers to a new architecture in Identity and Access Management (IAM) that improves the privacy and grants complete control and ownership over the personal data by their owner, the users. +Users possess their digital documents and determine to which actors they present these documents, with the ability to revoke the use of said documents, all while maintaining a history of their activities.

+

The main difference between this new approach and the traditional IAM infrastructure is that during the presentation phase there are no intermediaries between the Wallet and the Relying Party, while in the SAML2 or OIDC based infrastructure an Identity Provider is always involved, knowing which services a citizen is accessing to.

+

Self-Sovereign Identity (SSI) is also significant in the field of data exchange and data governance. This is relevant at both national and European levels, including the new eIDAS Regulation. In fact, it envisions a login option designed for European Users - be they citizens, public administrations, or companies - who want to access another Member State's services using their national authentication systems.

+

The main roles in a Wallet ecosystem are are listed as follow:

+
+
    +
  • Issuers: parties who can issue digital credentials about a person;

  • +
  • Verifiers: parties who request Holders' digital credentials for authentication and authorization purposes;

  • +
  • Holders: individuals who own a Wallet and have control over the digital credentials they can request, acquire, store, and present to verifiers;

  • +
  • Verifiable Data Registries: Authorities that publish certificates, attestations, metadata, and schemes needed for allowing the trust establishment between the parties.

  • +
+
+

In this model, the credential issuer (e.g., an educational institution) provides digital credentials to the user, who can store them in their digital Wallet. +The Wallet typically comes in the form of an application on the User's mobile phone.

+

Other key elements that characterize an SSI system include:

+
+
    +
  • Privacy and control: Wallets enable individuals to maintain control over their personal data. They can choose what information to release, to whom, and for what purpose;

  • +
  • Security: Wallets leverage cryptographic mechanism to ensure the integrity and security of identity information. It avoids the risk of identity theft, fraud, and unauthorized access since the data remains under the individual's control;

  • +
  • Interoperability: Wallets promote interoperability by enabling different systems and organizations to recognize and verify identities without relying on a central authority. This allows for seamless and trusted interactions between individuals, organizations, and even across borders;

  • +
  • Efficiency and cost reduction: individuals can manage their own identities, eliminating the need for multiple identity credentials and repetitive identity verification processes. This can streamline administrative procedures, reduce costs, and enhance the user experience.

  • +
+
+
+ + +
+
+
+
+ + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/standards.html b/refs/pull/443/merge/en/standards.html new file mode 100644 index 000000000..88e637ae3 --- /dev/null +++ b/refs/pull/443/merge/en/standards.html @@ -0,0 +1,328 @@ + + + + + + + + Technical References — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Technical References

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

OID-FED

Hedberg, R., Jones, M.B., Solberg, A.Å., Bradley, J., De Marco, G., Dzhuvinov, V., "OpenID Federation 1.0", May 2024, Draft 36.

OpenID4VCI

Lodderstedt, T., Yasuda, K., Looker, T., "OpenID for Verifiable Credential Issuance", February 2024, Draft 13.

SD-JWT-VC

    +
  1. Terbu, D.Fett, B. Campbell, "SD-JWT-based Verifiable Credentials (SD-JWT VC)".

  2. +
+

EIDAS-ARF

EUDI Wallet - Architecture and Reference Framework.

OpenID4VP

Terbu, O., Lodderstedt, T., Yasuda, K., Looker, T., "OpenID for Verifiable Presentations", November 2023, Draft 20.

PresentationExch

Presentation Exchange 2.0 for Presentation Definition.

RFC 2119

Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels" BCP 14, RFC 2119, March 1997.

RFC 2616

Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1,” RFC 2616, June 1999.

RFC 3339

Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002.

RFC 3986

Uniform Resource Identifier (URI): Generic Syntax.

RFC 7159

Bray, T., “The JavaScript Object Notation (JSON) Data Interchange Format” RFC 7159, March 2014.

RFC 7515

Jones, M., Bradley, J. and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 2015.

RFC 7516

Jones, M., Hildebrand, J., "JSON Web Encryption (JWE)", May 2015.

RFC 7517

Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, May 2015.

RFC 7518

Jones, M., "JSON Web Algorithms (JWA)", May 2015.

RFC 7519

Jones, M., Bradley, J. and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015.

RFC 7638

Jones, M., Sakimura, N., “JSON Web Key (JWK) Thumbprint”, September 2015.

RFC 7800

Jones, M., Bradley, J. and H. Tschofenig, "Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)", RFC 7800, DOI 10.17487/RFC7800, April 2016.

RFC 8174

Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", RFC 8174, DOI 10.17487/RFC8174, May 2017.

RFC 8725

Jones, M., D. Hardt, Sheffer, Y., "JSON Web Token Best Current Practices", February 2020.

JARM

Lodderstedt, T., Campbell, B., "JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)", November 2022.

RFC 6749

The OAuth 2.0 Authorization Framework.

RFC 9449

    +
  1. Fett, B. Campbell, J. Bradley, T. Lodderstedt, M. Jones, D. Waite, "OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)".

  2. +
+

RFC 9207

Meyer zu Selhausen, K., Fett, D., "OAuth 2.0 Authorization Server Issuer Identification", March 2022.

RFC 7521

Campbell, Mortimore, C., Jones, M., Goland, Y., "Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants", May 2015.

OPENID4VC-HAIP

Lodderstedt, T., K. Yasuda, "OpenID4VC High Assurance Interoperability Profile with SD-JWT VC".

OAUTH-STATUS-ASSERTION

De Marco, G., Steele, O., Marino, F., "OpenID4VC High Assurance Interoperability Profile with SD-JWT VC", June 2024, Draft 2.

OAUTH-ATTESTATION-CLIENT-AUTH

Looker, T., Bastian, P., "OAuth 2.0 Attestation-Based Client Authentication", May 2024, Draft 3.

OAUTH-V2-JARM-04

Lodderstedt, T., Campbell, B., "JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)".

OAUTH-MULT-RESP-TYPE

de Medeiros, B., Scurtescu, M., Tarjan, P., Jones, M., "OAuth 2.0 Multiple Response Type Encoding Practices", February 2014.

ISO18013-5

ISO/IEC 18013-5 2020. Information technology — Personal identification — ISO-compliant driving license — Part 5: Mobile driving license (mDL) application. International Organization for Standardization.

OIDC

Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., Mortimore, C., "OpenID Connect Core 1.0 incorporating errata set 2", December 2023.

SD-JWT

Fett, D., Yasuda, K., Campbell, B., "Selective Disclosure for JWTs (SD-JWT)".

OAUTH-ATTESTATION-CLIENT-AUTH

Looker, T., Bastian, P., "OAuth 2.0 Attestation-Based Client Authentication".

USASCII

American National Standards Institute, "Coded Character Set -- 7-bit American Standard Code for Information Interchange", 1986.

MODI

"Linee Guida sull'interoperabilità tecnica delle Pubbliche Amministrazioni", November 2023, Version 1.2.

PDND

"Linee Guida sull'infrastruttura tecnologica della Piattaforma Digitale Nazionale Dati per l'interoperabilità dei sistemi informativi e delle basi di dati", December 2021, Version 1.0.

W3C-SRI

Akhawe, D., Braun, F., Marier, F., and J. Weinberger, "Subresource Integrity", 23 June 2016.

OIDC-IDA

Lodderstedt, T., Fett, D., Haine, M., Pulido, A., Lehmann, K., Koiwai, K., "OpenID Connect for Identity Assurance 1.0", 24 July 2024.

SPID/CIE-OpenID-Connect-Specifications

SPID/CIE OpenID Connect.

+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+ +
+
+
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/trust.html b/refs/pull/443/merge/en/trust.html new file mode 100644 index 000000000..6f4217ca8 --- /dev/null +++ b/refs/pull/443/merge/en/trust.html @@ -0,0 +1,1022 @@ + + + + + + + + The Infrastructure of Trust — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

The Infrastructure of Trust

+

The EUDI Wallet Architecture Reference Framework (EIDAS-ARF) describes the Trust Model as a "collection of rules that ensure the legitimacy of the components and the entities involved in the EUDI Wallet ecosystem".

+

This section outlines the implementation of the Trust Model in an infrastructure that complies with OpenID Federation 1.0 OID-FED. This infrastructure involves a RESTful API for distributing metadata, metadata policies, trust marks, public keys, X.509 certificates, and the revocation status of the participants, also called Federation Entities.

+

The Infrastructure of trust facilitates the application of a trust assessment mechanism among the parties defined in the EIDAS-ARF.

+
+federation portrait +
+

Fig. 1 The roles within the Federation, where the Trust Anchor oversees its subordinates, +which include one or more Intermediates and Leaves. In this +representation, both the Trust Anchor and the Intermediates assume the role of Registration Authority.

+
+
+
+

Federation Roles

+

All the participants are Federation Entities that MUST be registered by an Registration Body, +except for Wallet Instances which are End-User's personal devices certified by their Wallet Provider.

+
+

Note

+

The Wallet Instance, as a personal device, is certified as reliable through a verifiable attestation issued and signed by a trusted third party.

+

This is called Wallet Attestation and is documented in the dedicated section.

+
+

Below the table with the summary of the Federation Entity roles, mapped on the corresponding EUDI Wallet roles, as defined in the EIDAS-ARF.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

EUDI Role

Federation Role

Notes

Public Key Infrastructure (PKI)

Trust Anchor

The Federation has PKI capabilities. The Entity that configures the entire infrastructure is the Trust Anchor.

Qualified Trust Service Provider (QTSP)

Leaf

Person Identification Data Provider

Leaf

Qualified Electronic Attestations of Attributes Provider

Leaf

Electronic Attestations of Attributes Provider

Leaf

Relying Party

Leaf

Trust Service Provider (TSP)

Leaf

Trusted List

Trust Anchor

The listing endpoint, the trust mark status endpoint, and the fetch endpoint must be exposed by both Trust Anchors and Intermediates, making the Trusted List distributed over multiple Federation Entities, where each of these is responsible for their registered subordinates.

Wallet Provider

Leaf

+
+
+

General Properties

+

The architecture of the trust infrastructure based on OpenID Federation is built upon several core principles:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Identifier

Property

Description

P1

Security

Incorporates mechanisms to ensure the integrity, confidentiality, and authenticity of the trust relationships and interactions within the federation.

P2

Privacy

Designed to respect and protect the privacy of the entities and individuals involved, minimal disclosure is part of this.

P3

Interoperability

Supports seamless interaction and trust establishment between diverse systems and entities within the federation.

P4

Transitive Trust

Trust established indirectly through a chain of trusted relationships, enabling entities to trust each other based on common authorities and trusted intermediaries.

P5

Delegation

Technical ability/feature to delegate authority or responsibilities to other entities, allowing for a distributed trust mechanism.

P6

Scalability

Designed to efficiently manage an increasing number of entities or interactions without a significant increase in trust management complexity.

P7

Flexibility

Adaptable to various operational and organizational needs, allowing entities to define and adjust their trust relationships and policies.

P8

Autonomy

While part of a federated ecosystem, each entity retains control over its own definitions and configurations.

P9

Decentralization

Unlike traditional centralized systems, the OpenID Federation model promotes a decentralized approach. This ensures that no single entity has control over the entire system, enhancing privacy and security for all participants.

+
+
+

Trust Infrastructure Functional Requirements

+

This section includes the requirements necessary for the successful implementation and operation of the infrastructure of trust.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1 Functional Requirements

ID

Description

FR1

Federation Trust Establishment: the system must be able to establish trust between different entities (Credential Issuers, Relying Parties, etc.) within a federation, using cryptographic signatures for secure information exchange about the participants in the ecosystem.

FR2

Entity Authentication: the system must implement mechanisms for authenticating entities within the federation, ensuring compliance with the shared rules.

FR3

Signature Validation: the system must support the creation, verification, and validation of electronic signatures and provide standard and secure mechanisms to obtain the public keys required for the signature validation.

FR4

Time Stamping: the signed artifacts must contain time stamps to ensure the integrity and non-repudiation of transactions over time, thanks to the interfaces, services, storage model and approaches defined within the federation.

FR5

Certificate Validation: the system requires confidential transmission, secured via TLS over HTTP, and validation of certificates for website authentication, ensuring they meet eIDAS criteria.

FR6

Interoperability and Standards Compliance: ensure interoperability between federation members by adhering to technical standards, facilitating cross-border electronic transactions.

FR7

Data Protection and Privacy: implement data protection measures in compliance with GDPR and eIDAS regulations, ensuring the privacy and security of personal data processed within the federation.

FR8

User Consent and Control: design mechanisms for obtaining and managing user consent, empowering users with control over their personal information.

FR9

Audit and Logging: the system must minimize data, anonymize if possible, define retention periods, secure access, and storage encryption. This protects privacy while enabling security and accountability.

FR10

Dispute Resolution and Liability: establish clear procedures for dispute resolution and define liability among federation members, in accordance with eIDAS provisions.

FR11

Accessibility: ensure that the system is accessible to all users, including those with disabilities, aligning with eIDAS and local accessibility standards.

FR12

Emergency and Revocation Services: implement mechanisms for the immediate revocation of electronic identification means and participants in case of security breaches or other emergencies.

FR13

Scalable Trust Infrastructure: the system must support scalable trust establishment mechanisms, leveraging approaches and technical solutions that complement delegation transitive approaches to efficiently manage trust relationships as the federation grows, removing central registries that might technically or administratively fail.

FR14

Efficient Storage Scalability: implement a storage solution that scales horizontally to accommodate increasing data volumes while minimizing central storage and administrative costs. The system should enable members to independently store and present historical trust attestations and signed artifacts during dispute resolutions, with the federation infrastructure maintaining only a registry of historical keys to validate the historical data, stored and provided by the participants.

FR15

Verifiable Attestation (Trust Mark): incorporate a mechanism for issuing and verifying verifiable attestations that serve as proof of compliance with specific profiles or standards. This allows entities within the federation to demonstrate adherence to agreed-upon security, privacy, and operational standards.

FR16

Dynamic Policy Language: develop and implement a dynamic, extensible policy language that allows for the creation and modification of federation policies in response to evolving requirements, technological advancements, and regulatory changes. This policy language should support the specification of rules governing entity behavior, metadata handling, and trust validation within the federation.

FR17

Automated Policy Enforcement: the system must automatically enforce federation policies as defined by policy language and verifiable attestations, ensuring that all operations and transactions comply with current rules and standards.

FR18

Decentralized Dispute Resolution Mechanism: design a decentralized mechanism for dispute resolution that allows federation members to independently verify historical trust establishment and signed artifacts, reducing reliance on central authorities and streamlining the resolution process.

FR19

Adaptive Load Management: implement adaptive load management strategies to ensure the system remains responsive and efficient under varying loads, particularly during peak usage times or when processing complex tasks.

FR20

Cross-Federation Interoperability: ensure the system is capable of interoperating with other federations or trust frameworks, facilitating cross-federation transactions and trust establishment without compromising security or compliance.

FR21

Future-Proof Cryptography: the system should employ a flexible cryptographic framework that can be updated in response to new threats or advancements in cryptographic research, ensuring long-term security and integrity of federation operations.

FR22

Autonomous Registration Bodies: the system must facilitate the integration of autonomous registration bodies that operate in compliance with federation rules. These bodies are tasked with evaluating and registering entities within the federation, according to the pre-established rules and their compliance that must be periodically asserted.

FR23

Compliance Evaluation for Federation Entity Candidates: registration bodies must evaluate the compliance of candidate entities against federation standards before their registration in the federation.

FR24

Periodic Auditing of Registration Bodies and Entities: implement mechanisms for the periodic auditing and monitoring of the compliance status of both registration bodies and their registered entities. This ensures ongoing adherence to federation standards and policies.

FR25

Certification of Compliance for Personal Devices: trusted bodies, in the form of federation entities, should issue certifications of compliance and provide signed proof of such compliance for the hardware of personal devices used within the federation. These certifications should be attested and periodically renewed to ensure the devices meet current security standards.

FR26

Certification of Compliance for Cryptographic Devices: similar to personal devices, personal cryptographic devices used within the federation must also receive certifications of compliance and signed proof thereof from trusted bodies. These certifications should be subject to periodic renewal to reflect the latest security and compliance standards.

FR27

Transparent Compliance Reporting: develop a system for transparent reporting and publication of compliance statuses, audit results, and certification renewals for all federation entities. This transparency fosters trust within the federation and with external stakeholders.

FR28

Automated Compliance Monitoring: the system should include automated tools for monitoring the compliance of entities with federation standards. This automation aids in the early detection of potential compliance issues.

FR29

Secure Protocol Capabilities Binding: the secure protocol must enable the exchange of protocol-specific capabilities data as cryptographically-bound metadata attached to a specific identity. This metadata should define the technical capabilities associated with the identity, ensuring verifiable proof and tamper-proof association for robust trust establishment and access control.

+
+
+

Federation API endpoints

+

OpenID Federation 1.0 uses RESTful Web Services secured over +HTTPs. OpenID Federation 1.0 defines which are the web endpoints that the participants MUST make +publicly available. The table below summarises the endpoints and their scopes.

+

All the endpoints listed below are defined in the OID-FED specs.

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

endpoint name

http request

scope

required for

federation metadata

GET .well-known/openid-federation

Metadata that an Entity publishes about itself, verifiable with a trusted third party (Superior Entity). It's called Entity Configuration.

Trust Anchor, Intermediate, Wallet Provider, Relying Party, Credential Issuer

subordinate list endpoint

GET /list

Lists the Subordinates.

Trust Anchor, Intermediate

fetch endpoint

GET /fetch?sub=https://rp.example.org

Returns a signed document (JWS) about a specific subject, its Subordinate. It's called Entity Statement.

Trust Anchor, Intermediate

trust mark status

POST /status?sub=...&trust_mark_id=...

Returns the status of the issuance (validity) of a Trust Mark related to a specific subject.

Trust Anchor, Intermediate

historical keys

GET /historical-jwks

Lists the expired and revoked keys, with the motivation of the revocation.

Trust Anchor, Intermediate

+

All the responses of the federation endpoints are in the form of JWS, with the exception of the Subordinate Listing endpoint and the Trust Mark Status endpoint that are served as plain JSON by default.

+
+
+

Configuration of the Federation

+

The configuration of the federation is published by the Trust Anchor within its Entity Configuration, it is available at the well-known web path corresponding to .well-known/openid-federation.

+

All the participants in the federation MUST obtain the federation configuration before entering the operational phase, and they +MUST keep it up-to-date. The federation configuration is the Trust Anchor's Entity Configuration, it contains the +public keys for signature operations and the maximum number of Intermediates allowed between a Leaf and the Trust Anchor (max_path_length).

+

Below is a non-normative example of a Trust Anchor Entity Configuration, where each parameter is documented in the OpenID Federation specification:

+
{
+    "alg": "ES256",
+    "kid": "FifYx03bnosD8m6gYQIfNHNP9cM_Sam9Tc5nLloIIrc",
+    "typ": "entity-statement+jwt"
+}
+.
+{
+    "exp": 1649375259,
+    "iat": 1649373279,
+    "iss": "https://registry.eidas.trust-anchor.example.eu",
+    "sub": "https://registry.eidas.trust-anchor.example.eu",
+    "jwks": {
+        "keys": [
+            {
+
+                "kty": "EC",
+                "kid": "X2ZOMHNGSDc4ZlBrcXhMT3MzRmRZOG9Jd3o2QjZDam51cUhhUFRuOWd0WQ",
+                "crv": "P-256",
+                "x": "1kNR9Ar3MzMokYTY8BRvRIue85NIXrYX4XD3K4JW7vI",
+                "y": "slT14644zbYXYF-xmw7aPdlbMuw3T1URwI4nafMtKrY"
+            }
+        ]
+    },
+    "metadata": {
+        "federation_entity": {
+            "organization_name": "example TA",
+            "contacts":[
+                "tech@eidas.trust-anchor.example.eu"
+            ],
+            "homepage_uri": "https://registry.eidas.trust-anchor.example.eu",
+            "logo_uri":"https://registry.eidas.trust-anchor.example.eu/static/svg/logo.svg",
+            "federation_fetch_endpoint": "https://registry.eidas.trust-anchor.example.eu/fetch",
+            "federation_resolve_endpoint": "https://registry.eidas.trust-anchor.example.eu/resolve",
+            "federation_list_endpoint": "https://registry.eidas.trust-anchor.example.eu/list",
+            "federation_trust_mark_status_endpoint": "https://registry.eidas.trust-anchor.example.eu/trust_mark_status"
+        }
+    },
+    "trust_mark_issuers": {
+        "https://registry.eidas.trust-anchor.example.eu/openid_relying_party/public": [
+            "https://registry.spid.eidas.trust-anchor.example.eu",
+            "https://public.intermediary.spid.org"
+        ],
+        "https://registry.eidas.trust-anchor.example.eu/openid_relying_party/private": [
+            "https://registry.spid.eidas.trust-anchor.example.eu",
+            "https://private.other.intermediary.org"
+        ]
+    }
+}
+
+
+
+
+

Entity Configuration

+

The Entity Configuration is the verifiable document that each Federation Entity MUST publish on its own behalf, in the .well-known/openid-federation endpoint.

+

The Entity Configuration HTTP Response MUST set the media type to application/entity-statement+jwt.

+

The Entity Configuration MUST be cryptographically signed. The public part of this key MUST be provided in the +Entity Configuration and within the Entity Statement issued by a immediate superior and related to its subordinate Federation Entity.

+

The Entity Configuration MAY also contain one or more Trust Marks.

+
+

Note

+

Entity Configuration Signature

+

All the signature-check operations regarding the Entity Configurations, Entity Statements and Trust Marks, are carried out with the Federation public keys. For the supported algorithms refer to Section Cryptografic Algorithm.

+
+
+

Entity Configurations Common Parameters

+

The Entity Configurations of all the participants in the federation MUST have in common the parameters listed below.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

iss

String. Identifier of the issuing Entity.

sub

String. Identifier of the Entity to which it is referred. It MUST be equal to iss.

iat

UNIX Timestamp with the time of generation of the JWT, coded as NumericDate as indicated at RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated at RFC 7519.

jwks

A JSON Web Key Set (JWKS) RFC 7517 that represents the public part of the signing keys of the Entity at issue. Each JWK in the JWK set MUST have a key ID (claim kid) and MAY have a x5c parameter, as defined in RFC 7517. It contains the Federation Entity Keys required for the operations of trust evaluation.

metadata

JSON Object. Each key of the JSON Object represents a metadata type identifier +containing JSON Object representing the metadata, according to the metadata +schema of that type. An Entity Configuration MAY contain more metadata statements, but only one for each type of +metadata (<entity_type>). the metadata types are defined in the section Metadata Types.

+
+
+

Entity Configuration Trust Anchor

+

The Trust Anchor Entity Configuration, in addition of the common parameters listed above, MAY contain the following parameters:

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Required

constraints

JSON Object that describes the trust evaluation mechanisms bounds. It MUST contain the attribute max_path_length that +defines the maximum number of Intermediates between a Leaf and the Trust Anchor.

check-icon

trust_mark_issuers

JSON Array that defines which Federation authorities are considered trustworthy +for issuing specific Trust Marks, assigned with their unique identifiers.

uncheck-icon

trust_mark_owners

JSON Array that lists which entities are considered to be the owners of +specific Trust Marks.

uncheck-icon

+
+
+

Entity Configuration Leaves and Intermediates

+

In addition to the previously defined claims, the Entity Configuration of the Leaf and of the Intermediate Entities, MAY contain the parameters listed below:

+ +++++ + + + + + + + + + + + + + + + + +

Claim

Description

Required

authority_hints

Array of URLs (String). It contains a list of URLs of the immediate superior entities, such as the Trust Anchor or +an Intermediate, that issues an Entity Statement related to this subject.

check-icon

trust_marks

A JSON Array containing the Trust Marks.

uncheck-icon

+
+
+

Metadata Types

+

In this section are defined the main metadata types mapped to the roles of the ecosystem, +giving the references of the metadata protocol for each of these.

+
+

Note

+

The entries that don't have any reference to a known draft or standard are intended to be defined in this technical reference.

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

OpenID Entity

EUDI Entity

Metadata Type

References

Trust Anchor

Trust Anchor

federation_entity

OID-FED

Intermediate

Intermediate

federation_entity

OID-FED

Wallet Provider

Wallet Provider

federation_entity, wallet_provider

--

Authorization Server

federation_entity, oauth_authorization_server

OPENID4VCI

Credential Issuer

PID Provider, (Q)EAA Provider

federation_entity, openid_credential_issuer, [oauth_authorization_server]

OPENID4VCI

Relying Party

Relying Party

federation_entity, wallet_relying_party

OID-FED, OpenID4VP

+
+

Note

+

Wallet Provider metadata is defined in the section below.

+

Wallet Solution section.

+
+
+

Note

+

In instances where a PID/EAA Provider implements both the Credential Issuer and the Authorization Server, +it MUST incorporate both +oauth_authorization_server and openid_credential_issuer within its metadata types. +Other implementations may divide the Credential Issuer from the Authorization Server, when this happens the Credential Issuer metadata MUST contain the authorization_servers parameters, including the Authorization Server unique identifier. +Furthermore, should there be a necessity for User Authentication by the Credential Issuer, +it could be necessary to include the relevant metadata type, either openid_relying_party +or wallet_relying_party.

+
+
+
+
+

Metadata of federation_entity Leaves

+

The federation_entity metadata for Leaves MUST contain the following claims.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

organization_name

See OID-FED Draft 36 Section 5.2.2

homepage_uri

See OID-FED Draft 36 Section 5.2.2

policy_uri

See OID-FED Draft 36 Section 5.2.2

logo_uri

URL of the entity's logo; it MUST be in SVG format. See OID-FED Draft 36 Section 5.2.2

contacts

Institutional certified email address (PEC) of the entity. See OID-FED Draft 36 Section 5.2.2

federation_resolve_endpoint

See OID-FED Draft 36 Section 5.1.1

+
+
+

Entity Statements

+

Trust Anchors and Intermediates publish Entity Statements related to their immediate Subordinates. +The Entity Statement MAY contain a metadata policy and the Trust Marks related to a Subordinate.

+

The metadata policy, when applied, makes one or more changes to the final metadata of the Leaf. The final metadata of a Leaf is derived from the Trust Chain that contains all the statements, starting from the Entity Configuration up to the Entity Statement issued by the Trust Anchor.

+

Trust Anchors and Intermediates MUST expose the Federation Fetch endpoint, where the Entity Statements are requested to validate the Leaf's Entity Configuration signature.

+
+

Note

+

The Federation Fetch endpoint MAY also publish X.509 certificates for each of the public keys of the Subordinate. Making the distribution of the issued X.509 certificates via a RESTful service.

+
+

Below there is a non-normative example of an Entity Statement issued by an Registration Body (such as the Trust Anchor or its Intermediate) in relation to one of its Subordinates.

+
{
+    "alg": "ES256",
+    "kid": "em3cmnZgHIYFsQ090N6B3Op7LAAqj8rghMhxGmJstqg",
+    "typ": "entity-statement+jwt"
+}
+.
+{
+    "exp": 1649623546,
+    "iat": 1649450746,
+    "iss": "https://intermediate.eidas.example.org",
+    "sub": "https://rp.example.it",
+    "jwks": {
+        "keys": [
+            {
+                "kty": "EC",
+                "kid": "2HnoFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMEEs",
+                "crv": "P-256",
+                "x": "1kNR9Ar3MzMokYTY8BRvRIue85NIXrYX4XD3K4JW7vI",
+                "y": "slT14644zbYXYF-xmw7aPdlbMuw3T1URwI4nafMtKrY",
+                "x5c": [ <X.509 certificate> ]
+            }
+        ]
+    },
+    "metadata_policy": {
+        "wallet_relying_party": {
+            "scope": {
+                "subset_of": [
+                     "eu.europa.ec.eudiw.pid.1",
+                     "given_name",
+                     "family_name",
+                     "email"
+                  ]
+            },
+            "vp_formats": {
+                "vc+sd-jwt": {
+                    "sd-jwt_alg_values": [
+                        "ES256",
+                        "ES384"
+                    ],
+                    "kb-jwt_alg_values": [
+                        "ES256",
+                        "ES384"
+                    ]
+                }
+            }
+        }
+     }
+}
+
+
+
+

Note

+

Entity Statement Signature

+

The same considerations and requirements made for the Entity Configuration +and in relation to the signature mechanisms MUST be applied for the Entity Statements.

+
+
+

Entity Statement

+

The Entity Statement issued by Trust Anchors and Intermediates contains the following attributes:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Required

iss

See OID-FED Section 3.1 for further details.

check-icon

sub

See OID-FED Section 3.1 for further details.

check-icon

iat

See OID-FED Section 3.1 for further details.

check-icon

exp

See OID-FED Section 3.1 for further details.

check-icon

jwks

Federation JWKS of the sub entity. See OID-FED Section 3.1 for further details.

check-icon

metadata_policy

JSON Object that describes the Metadata policy. Each key of the JSON Object represents an identifier of the metadata type and each value MUST be a JSON Object that represents the metadata policy according to that metadata type. Please refer to the OID-FED specifications, Section-5.1, for the implementation details.

uncheck-icon

trust_marks

JSON Array containing the Trust Marks issued by itself for the subordinate subject.

uncheck-icon

constraints

It MAY contain the allowed_leaf_entity_types, that restricts what types of metadata the subject is allowed to publish.

check-icon

+
+
+
+

Trust Evaluation Mechanism

+

Trust Anchors MUST distribute their Federation Public Keys through secure out-of-band mechanisms, such as publishing them on a verified web page or storing them in a remote repository as part of a trust list. The rationale behind this requirement is that relying solely on the data provided within the Trust Anchor's Entity Configuration does not adequately mitigate risks associated with DNS and TLS manipulation attacks. To ensure security, all participants MUST obtain the Trust Anchor's public keys using these out-of-band methods. They should then compare these keys with those obtained from the Trust Anchor's Entity Configuration, discarding any keys that do not match. This process helps to ensure the integrity and authenticity of the Trust Anchor's public keys and the overall security of the federation.

+

The Trust Anchor publishes the list of its Subordinates (Federation Subordinate Listing endpoint) and the attestations of their metadata and public keys (Entity Statements).

+

Each participant, including Trust Anchor, Intermediate, Credential Issuer, Wallet Provider, and Relying Party, publishes its own metadata and public keys (Entity Configuration endpoint) in the well-known web resource .well-known/openid-federation.

+

Each of these can be verified using the Entity Statement issued by a superior, such as the Trust Anchor or an Intermediate.

+

Each Entity Statement is verifiable over time and MUST have an expiration date. The revocation of each statement is verifiable in real time and online (only for remote flows) through the federation endpoints.

+
+

Note

+

The revocation of an Entity is made with the unavailability of the Entity Statement related to it. If the Trust Anchor or its Intermediate doesn't publish a valid Entity Statement, or if it publishes an expired/invalid Entity Statement, the subject of the Entity Statement MUST be intended as not valid or revoked.

+
+

The concatenation of the statements, through the combination of these signing mechanisms and the binding of claims and public keys, forms the Trust Chain.

+

The Trust Chains can also be verified offline, using one of the Trust Anchor's public keys.

+
+

Note

+

Since the Wallet Instance is not a Federation Entity, the Trust Evaluation Mechanism related to it requires the presentation of the Wallet Attestation during the credential issuance and presentation phases.

+

The Wallet Attestation conveys all the required information pertaining to the instance, such as its public key and any other technical or administrative information, without any User's personal data.

+
+
+

Relying Party Trust Evaluation

+

The Relying Party is registered by a Trust Anchor or its Intermediate and obtains a Trust Mark to be included in its Entity Configuration. In its Entity Configuration the Relying Party publishes its specific metadata, including the supported signature and encryption algorithms and any other necessary information for the interoperability requirements.

+

Any requests for User attributes, such as PID or (Q)EAA, from the Relying Party to Wallet Instances are signed and SHOULD contain the verifiable Trust Chain regarding the Relying Party.

+

The Wallet Instance verifies that the Trust Chain related to the Relying Party is still active, proving that the Relying Party is still part of the Federation and not revoked.

+

The Trust Chain SHOULD be contained within the signed request in the form of a JWS header parameter.

+

In offline flows, Trust Chain verification enables the assessment of the reliability of Trust Marks and Attestations contained within.

+
+
+

Wallet Attestation

+

The Wallet Provider issues the Wallet Attestation, certifying the operational status of its Wallet Instances and including one of their public keys.

+

The Wallet Attestation contains the Trust Chain that attests the reliability for its issuer (Wallet Provider) at the time of issuance.

+

The Wallet Instance provides its Wallet Attestation within the signed request during the PID issuance phase, containing the Trust Chain related to the Wallet Provider.

+
+
+

Trust Chain

+

The Trust Chain is a sequence of verified statements that validates a participant's compliance with the Federation. It has an expiration date time, beyond which it MUST be renewed to obtain the fresh and updated metadata. The expiration date of the Trust Chain is determined by the earliest expiration timestamp among all the expiration timestamp contained in the statements. No Entity can force the expiration date of the Trust Chain to be higher than the one configured by the Trust Anchor.

+

Below is an abstract representation of a Trust Chain.

+
[
+    "EntityConfiguration-as-SignedJWT-selfissued-byLeaf",
+    "EntityStatement-as-SignedJWT-issued-byTrustAnchor"
+]
+
+
+

Below is a non-normative example of a Trust Chain in its original format (JSON Array containing JWS as strings) with an Intermediate involved.

+
[
+  "eyJhbGciOiJFUzI1NiIsImtpZCI6Ik5GTTFXVVZpVWxZelVXcExhbWxmY0VwUFJWWTJWWFpJUmpCblFYWm1SSGhLWVVWWVVsZFRRbkEyTkEiLCJ0eXAiOiJhcHBsaWNhdGlvbi9lbnRpdHktc3RhdGVtZW50K2p3dCJ9.eyJleHAiOjE2NDk1OTA2MDIsImlhdCI6MTY0OTQxNzg2MiwiaXNzIjoiaHR0cHM6Ly9ycC5leGFtcGxlLm9yZyIsInN1YiI6Imh0dHBzOi8vcnAuZXhhbXBsZS5vcmciLCJqd2tzIjp7ImtleXMiOlt7Imt0eSI6IkVDIiwia2lkIjoiTkZNMVdVVmlVbFl6VVdwTGFtbGZjRXBQUlZZMlZYWklSakJuUVhabVJIaEtZVVZZVWxkVFFuQTJOQSIsImNydiI6IlAtMjU2IiwieCI6InVzbEMzd2QtcFgzd3o0YlJZbnd5M2x6cGJHWkZoTjk2aEwyQUhBM01RNlkiLCJ5IjoiVkxDQlhGV2xkTlNOSXo4a0gyOXZMUjROMThCa3dHT1gyNnpRb3J1UTFNNCJ9XX0sIm1ldGFkYXRhIjp7Im9wZW5pZF9yZWx5aW5nX3BhcnR5Ijp7ImFwcGxpY2F0aW9uX3R5cGUiOiJ3ZWIiLCJjbGllbnRfaWQiOiJodHRwczovL3JwLmV4YW1wbGUub3JnLyIsImNsaWVudF9yZWdpc3RyYXRpb25fdHlwZXMiOlsiYXV0b21hdGljIl0sImp3a3MiOnsia2V5cyI6W3sia3R5IjoiRUMiLCJraWQiOiJORk0xV1VWaVVsWXpVV3BMYW1sZmNFcFBSVlkyVlhaSVJqQm5RWFptUkhoS1lVVllVbGRUUW5BMk5BIiwiY3J2IjoiUC0yNTYiLCJ4IjoidXNsQzN3ZC1wWDN3ejRiUllud3kzbHpwYkdaRmhOOTZoTDJBSEEzTVE2WSIsInkiOiJWTENCWEZXbGROU05JejhrSDI5dkxSNE4xOEJrd0dPWDI2elFvcnVRMU00In1dfSwiY2xpZW50X25hbWUiOiJOYW1lIG9mIGFuIGV4YW1wbGUgb3JnYW5pemF0aW9uIiwiY29udGFjdHMiOlsib3BzQHJwLmV4YW1wbGUuaXQiXSwiZ3JhbnRfdHlwZXMiOlsicmVmcmVzaF90b2tlbiIsImF1dGhvcml6YXRpb25fY29kZSJdLCJyZWRpcmVjdF91cmlzIjpbImh0dHBzOi8vcnAuZXhhbXBsZS5vcmcvb2lkYy9ycC9jYWxsYmFjay8iXSwicmVzcG9uc2VfdHlwZXMiOlsiY29kZSJdLCJzY29wZSI6ImV1LmV1cm9wYS5lYy5ldWRpdy5waWQuMSBldS5ldXJvcGEuZWMuZXVkaXcucGlkLml0LjEgZW1haWwiLCJzdWJqZWN0X3R5cGUiOiJwYWlyd2lzZSJ9LCJmZWRlcmF0aW9uX2VudGl0eSI6eyJmZWRlcmF0aW9uX3Jlc29sdmVfZW5kcG9pbnQiOiJodHRwczovL3JwLmV4YW1wbGUub3JnL3Jlc29sdmUvIiwib3JnYW5pemF0aW9uX25hbWUiOiJFeGFtcGxlIFJQIiwiaG9tZXBhZ2VfdXJpIjoiaHR0cHM6Ly9ycC5leGFtcGxlLml0IiwicG9saWN5X3VyaSI6Imh0dHBzOi8vcnAuZXhhbXBsZS5pdC9wb2xpY3kiLCJsb2dvX3VyaSI6Imh0dHBzOi8vcnAuZXhhbXBsZS5pdC9zdGF0aWMvbG9nby5zdmciLCJjb250YWN0cyI6WyJ0ZWNoQGV4YW1wbGUuaXQiXX19LCJ0cnVzdF9tYXJrcyI6W3siaWQiOiJodHRwczovL3JlZ2lzdHJ5LmVpZGFzLnRydXN0LWFuY2hvci5leGFtcGxlLmV1L29wZW5pZF9yZWx5aW5nX3BhcnR5L3B1YmxpYy8iLCJ0cnVzdF9tYXJrIjoiZXlKaCBcdTIwMjYifV0sImF1dGhvcml0eV9oaW50cyI6WyJodHRwczovL2ludGVybWVkaWF0ZS5laWRhcy5leGFtcGxlLm9yZyJdfQ.Un315HdckvhYA-iRregZAmL7pnfjQH2APz82blQO5S0sl1JR0TEFp5E1T913g8GnuwgGtMQUqHPZwV6BvTLA8g",
+  "eyJhbGciOiJFUzI1NiIsImtpZCI6IlNURkRXV2hKY0dWWFgzQjNSVmRaYWtsQ0xUTnVNa000WTNGNlFUTk9kRXRyZFhGWVlYWjJjWGN0UVEiLCJ0eXAiOiJhcHBsaWNhdGlvbi9lbnRpdHktc3RhdGVtZW50K2p3dCJ9.eyJleHAiOjE2NDk2MjM1NDYsImlhdCI6MTY0OTQ1MDc0NiwiaXNzIjoiaHR0cHM6Ly9pbnRlcm1lZGlhdGUuZWlkYXMuZXhhbXBsZS5vcmciLCJzdWIiOiJodHRwczovL3JwLmV4YW1wbGUub3JnIiwiandrcyI6eyJrZXlzIjpbeyJrdHkiOiJFQyIsImtpZCI6Ik5GTTFXVVZpVWxZelVXcExhbWxmY0VwUFJWWTJWWFpJUmpCblFYWm1SSGhLWVVWWVVsZFRRbkEyTkEiLCJjcnYiOiJQLTI1NiIsIngiOiJ1c2xDM3dkLXBYM3d6NGJSWW53eTNsenBiR1pGaE45NmhMMkFIQTNNUTZZIiwieSI6IlZMQ0JYRldsZE5TTkl6OGtIMjl2TFI0TjE4Qmt3R09YMjZ6UW9ydVExTTQifV19LCJtZXRhZGF0YV9wb2xpY3kiOnsib3BlbmlkX3JlbHlpbmdfcGFydHkiOnsic2NvcGUiOnsic3Vic2V0X29mIjpbImV1LmV1cm9wYS5lYy5ldWRpdy5waWQuMSwgIGV1LmV1cm9wYS5lYy5ldWRpdy5waWQuaXQuMSJdfSwicmVxdWVzdF9hdXRoZW50aWNhdGlvbl9tZXRob2RzX3N1cHBvcnRlZCI6eyJvbmVfb2YiOlsicmVxdWVzdF9vYmplY3QiXX0sInJlcXVlc3RfYXV0aGVudGljYXRpb25fc2lnbmluZ19hbGdfdmFsdWVzX3N1cHBvcnRlZCI6eyJzdWJzZXRfb2YiOlsiUlMyNTYiLCJSUzUxMiIsIkVTMjU2IiwiRVM1MTIiLCJQUzI1NiIsIlBTNTEyIl19fX0sInRydXN0X21hcmtzIjpbeyJpZCI6Imh0dHBzOi8vdHJ1c3QtYW5jaG9yLmV4YW1wbGUuZXUvb3BlbmlkX3JlbHlpbmdfcGFydHkvcHVibGljLyIsInRydXN0X21hcmsiOiJleUpoYiBcdTIwMjYifV19._qt5-T6DahP3TuWa_27klE8I9Z_sPK2FtQlKY6pGMPchbSI2aHXY3aAXDUrObPo4CHtqgg3J2XcrghDFUCFGEQ",
+  "eyJhbGciOiJFUzI1NiIsImtpZCI6ImVXa3pUbWt0WW5kblZHMWxhMjU1ZDJkQ2RVZERSazQwUWt0WVlVMWFhRFZYT1RobFpHdFdXSGQ1WnciLCJ0eXAiOiJhcHBsaWNhdGlvbi9lbnRpdHktc3RhdGVtZW50K2p3dCJ9.eyJleHAiOjE2NDk2MjM1NDYsImlhdCI6MTY0OTQ1MDc0NiwiaXNzIjoiaHR0cHM6Ly90cnVzdC1hbmNob3IuZXhhbXBsZS5ldSIsInN1YiI6Imh0dHBzOi8vaW50ZXJtZWRpYXRlLmVpZGFzLmV4YW1wbGUub3JnIiwiandrcyI6eyJrZXlzIjpbeyJrdHkiOiJFQyIsImtpZCI6IlNURkRXV2hKY0dWWFgzQjNSVmRaYWtsQ0xUTnVNa000WTNGNlFUTk9kRXRyZFhGWVlYWjJjWGN0UVEiLCJjcnYiOiJQLTI1NiIsIngiOiJyQl9BOGdCUnh5NjhVTkxZRkZLR0ZMR2VmWU5XYmgtSzh1OS1GYlQyZkZJIiwieSI6IlNuWVk2Y3NjZnkxcjBISFhLTGJuVFZsamFndzhOZzNRUEs2WFVoc2UzdkUifV19LCJ0cnVzdF9tYXJrcyI6W3siaWQiOiJodHRwczovL3RydXN0LWFuY2hvci5leGFtcGxlLmV1L2ZlZGVyYXRpb25fZW50aXR5L3RoYXQtcHJvZmlsZSIsInRydXN0X21hcmsiOiJleUpoYiBcdTIwMjYifV19.r3uoi-U0tx0gDFlnDdITbcwZNUpy7M2tnh08jlD-Ej9vMzWMCXOCCuwIn0ZT0jS4M_sHneiG6tLxRqj-htI70g"
+]
+
+
+
+

Note

+

The entire Trust Chain is verifiable by only possessing the Trust Anchor's public keys.

+
+
+
+

Offline Trust Attestation Mechanisms

+

The offline flows do not allow for real-time evaluation of an Entity's status, such as its revocation. At the same time, using short-lived Trust Chains enables the attainment of trust attestations compatible with the required revocation administrative protocols (e.g., a revocation must be propagated in less than 24 hours, thus the Trust Chain must not be valid for more than that period).

+
+

Offline Wallet Trust Attestation

+

Given that the Wallet Instance cannot publish its metadata online at the .well-known/openid-federation endpoint, +it MUST obtain a Wallet Attestation issued by its Wallet Provider. The Wallet Attestation MUST contain all the relevant information regarding the security capabilities of the Wallet Instance and its protocol related configuration. It SHOULD contain the Trust Chain related to its issuer (Wallet Provider).

+
+
+

Offline Relying Party Metadata

+

Since the Federation Entity Discovery is only applicable in online scenarios, it is possible to include the Trust Chain in the presentation requests that the Relying Party may issue for a Wallet Instance.

+

The Relying Party MUST sign the presentation request, the request SHOULD include the trust_chain claim in its JWS header parameters, containing the Federation Trust Chain related to itself.

+

The Wallet Instance that verifies the request issued by the Relying Party MUST use the Trust Anchor's public keys to validate the entire Trust Chain related to the Relying Party before attesting its reliability.

+

Furthermore, the Wallet Instance applies the metadata policy, if any.

+
+
+
+
+

Trust Chain Fast Renewal

+

The Trust Chain fast renewal method offers a streamlined way to maintain the validity of a trust chain without undergoing the full discovery +process again. It's particularly useful for quickly updating trust relationships when minor changes occur or when the +Trust Chain is close to expiration but the overall structure of the federation hasn't changed significantly.

+

The Trust Chain fast renewal process is initiated by fetching the leaf's Entity Configuration anew. However, unlike the federation discovery process that may involve fetching Entity Configurations starting from the authority hints, the fast renewal focuses on directly obtaining the Subordinate Statements. These statements are requested using the source_endpoint provided within them, which points to the location where the statements can be fetched.

+
+
+

Non-repudiability of the Long Lived Attestations

+

The Trust Anchor and its Intermediate MUST expose the Federation Historical Keys endpoint, where are published all the public part of the Federation Entity Keys that are no longer used, whether expired or revoked.

+

The details of this endpoint are defined in the OID-FED Section 7.6.

+

Each JWS containing a Trust Chain in the form of a JWS header parameter can be verified over time, since the entire Trust Chain is verifiable using the Trust Anchor's public key.

+

Even if the Trust Anchor has changed its cryptographic keys for digital signature, the Federation Historical Keys endpoint always makes the keys no longer used available for historical signature verifications.

+
+
+

Privacy Remarks

+
    +
  • Wallet Instances MUST NOT publish their metadata through an online service.

  • +
  • The trust infrastructure MUST be public, with all endpoints publicly accessible without any client credentials that may disclose who is requesting access.

  • +
  • When a Wallet Instance requests the Entity Statements to build the Trust Chain for a specific Relying Party or validates a Trust Mark online, issued for a specific Relying Party, the Trust Anchor or its Intermediate do not know that a particular Wallet Instance is inquiring about a specific Relying Party; instead, they only serve the statements related to that Relying Party as a public resource.

  • +
  • The Wallet Instance metadata MUST not contain information that may disclose technical information about the hardware used.

  • +
  • Leaf entity, Intermediate, and Trust Anchor metadata may include the necessary amount of data as part of administrative, technical, and security contact information. It is generally not recommended to use personal contact details in such cases. From a legal perspective, the publication of such information is needed for operational support concerning technical and security matters and the GDPR regulation.

  • +
+
+
+

Considerations about Decentralization

+
    +
  • There may be more than a single Trust Anchor.

  • +
  • In some cases, a trust verifier may trust an Intermediate, especially when the Intermediate acts as a Trust Anchor within a specific perimeter, such as cases where the Leafs are both in the same perimeter like a Member State jurisdiction (eg: an Italian Relying Party with an Italian Wallet Instance may consider the Italian Intermediate as a Trust Anchor for the scopes of their interactions).

  • +
  • Trust attestations (Trust Chain) should be included in the JWS issued by Credential Issuers, and the Presentation Requests of RPs should contain the Trust Chain related to them (issuers of the presentation requests).

  • +
  • Since the credential presentation must be signed, storing the signed presentation requests and responses, which include the Trust Chain, the Wallet Instance may have the snapshot of the federation configuration (Trust Anchor Entity Configuration in the Trust Chain) and the verifiable reliability of the Relying Party it has interacted with.

  • +
  • Each signed attestation is long-lived since it can be cryptographically validated even when the federation configuration changes or the keys of its issuers are renewed.

  • +
  • Each participant should be able to update its Entity Configuration without notifying the changes to any third party. The metadata policy contained within a Trust Chain must be applied to overload any information related to protocol specific metadata.

  • +
+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/wallet-attestation.html b/refs/pull/443/merge/en/wallet-attestation.html new file mode 100644 index 000000000..90624cb41 --- /dev/null +++ b/refs/pull/443/merge/en/wallet-attestation.html @@ -0,0 +1,914 @@ + + + + + + + + Wallet Attestation — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Wallet Attestation

+

Wallet Attestation contains information regarding the security level of the device hosting the Wallet Instance. +It primarily certifies the authenticity, integrity, security, privacy, and trustworthiness of a particular Wallet Instance.

+
+

Requirements

+

The requirements for the Wallet Attestation are defined below:

+
    +
  • The Wallet Attestation MUST contain a Wallet Instance public key.

  • +
  • The Wallet Attestation MUST use the signed JSON Web Token (JWT) format;

  • +
  • The Wallet Attestation MUST provide all the relevant information to attest to the integrity and security of the device where the Wallet Instance is installed.

  • +
  • The Wallet Attestation MUST be signed by the Wallet Provider that has authority over and is the owner of the Wallet Solution, as specified by the overseeing registration authority. This ensures that the Wallet Attestation uniquely links the Wallet Provider to this particular Wallet Instance.

  • +
  • The Wallet Provider MUST ensure the integrity, authenticity, and genuineness of the Wallet Instance, preventing any attempts at manipulation or falsification by unauthorized third parties. The Wallet Provider MUST also verify the Wallet Instance using the App Store vendor's API, such as the Play Integrity API for Android and DeviceCheck for iOS. These services are defined in this specification as Device Integrity Service (DIS).

  • +
  • The Wallet Attestation MUST have a mechanism in place for revoking the Wallet Instance, allowing the Wallet Provider to terminate service for a specific instance at any time.

  • +
  • The Wallet Attestation MUST be securely bound to the Wallet Instance's ephemeral public key.

  • +
  • The Wallet Attestation MAY be used multiple times during its validity period, allowing for repeated authentication and authorization without the need to request new attestations with each interaction.

  • +
  • The Wallet Attestation MUST be short-lived and MUST have an expiration date/time, after which it SHOULD no longer be considered valid.

  • +
  • The Wallet Attestation MUST NOT be issued by the Wallet Provider if the authenticity, integrity, and genuineness are not guaranteed. In this case, the Wallet Instance MUST be revoked.

  • +
  • Each Wallet Instance SHOULD be able to request multiple attestations with different ephemeral public keys associated with them. This requirement provides a privacy-preserving measure, as the public key MAY be used as a tracking tool during the presentation phase (see also the point listed below).

  • +
  • The Wallet Attestation MUST NOT contain any information that can be used to directly identify the User.

  • +
  • The Wallet Instance MUST secure a Wallet Attestation as a prerequisite for transitioning to the Operational state, as defined by ARF.

  • +
  • Private keys MUST be generated and stored in the WSCD using at least one of the approaches listed below:

    +
      +
    • Local Internal WSCD: The WSCD relies entirely on the device's native cryptographic hardware, such as the Secure Enclave on iOS devices or the Hardware-Backed Keystore or Strongbox on Android devices.

    • +
    • Local External WSCD: The WSCD is hardware external to the User's device, such as a smart card compliant with GlobalPlatform and supporting JavaCard.

    • +
    • Remote WSCD: The WSCD utilizes a remote Hardware Security Module (HSM).

    • +
    • Local Hybrid WSCD: The WSCD involves a pluggable internal hardware component within the User's device, such as an eUICC that adheres to GlobalPlatform standards and supports JavaCard.

    • +
    • Remote Hybrid WSCD: The WSCD involves a local component mixed with a remote service.

    • +
    +
  • +
  • The Wallet Provider MUST offer a set of services, exclusively available to its Wallet Solution instances, for the issuance of Wallet Attestations.

  • +
+
+

Warning

+

At the current stage, the implementation profile defined in this document supports only the Local Internal WSCD. Future versions of this specification MAY include other approaches depending on the required AAL.

+
+
+
+

Static Component View

+
+The image illustrates the containment of Wallet Provider and Wallet Instances within the Wallet Solution, managed by the Wallet Provider. +
+
+
+

Dynamic Component View

+

The Wallet Attestation acquisition flow can be divided into two main phases. The first phase involves device initialization and registration, which occurs only during the initial launch of the Wallet Instance (after installation). The second phase pertains to the actual acquisition of the Wallet Attestation.

+
+

Wallet Instance Initialization and Registration

+
+The figure illustrates the sequence diagram for initializing a Wallet Instance, with the steps explained below. +
+

Step 1: The User starts the Wallet Instance mobile app for the first time.

+

Step 2: The Wallet Instance:

+
+
    +
  • Checks whether the device meets the minimum security requirements.

  • +
  • Checks if the Device Integrity Service is available.

  • +
+
+
+

Note

+

Federation Check: The Wallet Instance needs to check if the Wallet Provider is part of the Federation, obtaining its protocol-specific Metadata. A non-normative example of a response from the endpoint .well-known/openid-federation with the Entity Configuration and the Metadata of the Wallet Provider is represented within the section Wallet Provider metadata.

+
+

Steps 3-5: The Wallet Instance sends a request to the Wallet Provider Backend and receives a one-time challenge. This "challenge" is a nonce, which must be unpredictable to serve as the main defense against replay attacks. The backend must generate the nonce value in a manner that ensures it is single-use and valid only within a specific time frame. This endpoint is compliant with the specification OAuth 2.0 Nonce Endpoint.

+
GET /nonce HTTP/1.1
+Host: walletprovider.example.com
+
+
+
HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+  "nonce": "d2JhY2NhbG91cmVqdWFuZGFt"
+}
+
+
+

Step 6: The Wallet Instance, through the operating system, creates a pair of Cryptographic Hardware Keys and stores the corresponding Cryptographic Hardware Key Tag in local storage once the following requirements are met:

+
+
    +
  1. It MUST ensure that Cryptographic Hardware Keys do not already exist. If they do exist and the Wallet is in the initialization phase, they MUST be deleted.

  2. +
  3. It MUST generate a pair of asymmetric Elliptic Curve keys (Cryptographic Hardware Keys) via a local WSCD.

  4. +
  5. It SHOULD obtain a unique identifier (Cryptographic Hardware Key Tag) for the generated Cryptographic Hardware Keys from the operating system. If the operating system permits specifying a tag during the creation of keys, then a random string for the Cryptographic Hardware Key Tag MUST be selected. This random value MUST be collision-resistant and unpredictable to ensure security. To achieve this, consider using a cryptographic hash function or a secure random number generator provided by the operating system or a reputable cryptographic library.

  6. +
  7. If the previous points are satisfied, it MUST store the Cryptographic Hardware Key Tag in local storage.

  8. +
+
+
+

Note

+

WSCD: The Wallet Instance MAY use a local WSCD for key generation on devices that support this feature. On Android devices, Strongbox is RECOMMENDED; Trusted Execution Environment (TEE) MAY be used only when Strongbox is unavailable. For iOS devices, Secure Elements (SE) MUST be used. Given that each OEM offers a distinct SDK for accessing the local WSCD, the discussion hereafter will address this topic in a general context.

+
+

Step 7: The Wallet Instance uses the Device Integrity Service, providing the "challenge" and the Cryptographic Hardware Key Tag to acquire the Key Attestation.

+
+

Note

+

Device Integrity Service: In this section, the Device Integrity Service is considered as it is provided by device manufacturers. This service allows the verification of a key being securely stored within the device's hardware through a signed object. Additionally, it offers verifiable proof that a specific Wallet Instance is authentic, unaltered, and in its original state using a specialized signed document made for this purpose.

+

The service also incorporates details in the signed object, such as the device type, model, app version, operating system version, bootloader status, and other relevant information to assess whether the device has been compromised. For Android, the DIS is represented by Key Attestation, a feature supported by StrongBox Keymaster, which is a physical HSM installed directly on the motherboard, and the TEE (Trusted Execution Environment), a secure area of the main processor. Key Attestation aims to provide a way to strongly determine if a key pair is hardware-backed, what the properties of the key are, and what constraints are applied to its usage. Developers can leverage its functionality through the Play Integrity API. For Apple devices, the DIS is represented by DeviceCheck, which provides a framework and server interface to manage device-specific data securely. DeviceCheck is used in combination with the Secure Enclave, a dedicated HSM integrated into Apple's SoCs. DeviceCheck can be used to attest to the integrity of the device, apps, and/or encryption keys generated on the device, ensuring they were created in a secure environment like Secure Enclave. Developers can leverage DeviceCheck functionality by using the framework itself. +These services, specifically developed by the manufacturer, are integrated within the Android or iOS SDKs, eliminating the need for a predefined endpoint to access them. Additionally, as they are specifically developed for mobile architecture, they do not need to be registered as Federation Entities through national registration systems. +Secure Enclave has been available on Apple devices since the iPhone 5s (2013). +For Android devices, the inclusion of Strongbox Keymaster may vary by manufacturer, who decides whether to include it or not.

+
+

Step 8: The Device Integrity Service performs the following actions:

+
    +
  • Creates a Key Attestation that is linked with the provided "challenge" and the public key of the Wallet Hardware.

  • +
  • Incorporates information pertaining to the device's security.

  • +
  • Uses an OEM private key to sign the Key Attestation, therefore verifieable with the related OEM certificate, confirming that the Cryptographic Hardware Keys are securely managed by the operating system.

  • +
+

Step 9: The Wallet Instance sends the challenge with Key Attestation and Cryptographic Hardware Key Tag to the Wallet Provider Backend in order to register the Wallet Instance identified with the Cryptographic Hardware Key public key.

+

In order to register the Wallet Instance, the request to the Wallet Provider MUST use the HTTP POST method. The parameters MUST be encoded using the application/json format and included in the message body. The following parameters MUST be provided:

+ + +++++ + + + + + + + + + + + + + + + + + + + + +
Table 2 Wallet Instance registration http request parameters

Claim

Description

Reference

challenge

MUST be set to the challenge obtained from the Wallet Provider throught the nonce endpoint.

OAuth 2.0 Nonce Endpoint

key_attestation

It MUST be a base64url encoded Key Attestation obtained from the Device Integrity Service.

hardware_key_tag

It MUST be set with the unique identifier of the Cryptographic Hardware Keys and encoded in base64url.

+

Below is a non-normative example of the request.

+
POST /wallet-instance HTTP/1.1
+Host: walletprovider.example.com
+Content-Type: application/json
+
+{
+  "challenge": "0fe3cbe0-646d-44b5-8808-917dd5391bd9",
+  "key_attestation": "o2NmbXRvYXBwbGUtYXBw... redacted",
+  "hardware_key_tag": "WQhyDymFKsP95iFqpzdEDWW4l7aVna2Fn4JCeWHYtbU="
+}
+
+
+
+

Note

+

It is not necessary to send the Wallet Hardware public key because it is already included in the key_attestation. +As seen in the previous steps, the Device Integrity Service (DIS) creates a Key Attestation linked to the provided "challenge" and the public key of the Wallet Hardware. This process eliminates the need to send the Wallet Hardware public key directly, as it is already included in the key attestation. The hardware_key_tag serves as a reference or identifier for the corresponding Cryptographic Hardware key stored by the Wallet Provider. Therefore, the Wallet Provider can associate the received hardware_key_tag with the appropriate Cryptographic Hardware key in its storage.

+
+
+

Warning

+

During the registration phase of the Wallet Instance with the Wallet Provider it is also necessary to associate it with a specific user +uniquely identifiable by the Wallet Provider. This association is at the discretion of the Wallet PRovider and will not be addressed +within these guidelines as each Wallet Provider may or may not have a user identification system already implemented.

+
+

Steps 10-12: The Wallet Provider validates the challenge and key_attestation signature, therefore:

+
+
    +
  1. It MUST verify that the challenge was generated by Wallet Provider and has not already been used.

  2. +
  3. It MUST validate the key_attestation as defined by the device manufacturers' guidelines.

  4. +
  5. It MUST verify that the device in use has no security flaws and reflects the minimum security requirements defined by the Wallet Provider.

  6. +
  7. If these checks are passed, it MUST register the Wallet Instance, keeping the Cryptographic Hardware Key Tag and all useful information related to the device.

  8. +
  9. It SHOULD associate the Wallet Instance with a specific User uniquely identified within the Wallet Provider's systems. This will be useful for the lifecycle of the Wallet Instance and for a future revocation.

  10. +
+
+

Upon successful registration of the Wallet Instance, the Wallet Provider MUST respond with a status code set to 204 (No Content). +Below is a non-normative example of the response.

+
HTTP/1.1 204 No content
+
+
+

If any errors occur during the Wallet Instance registration, the Wallet Provider MUST return an error response. The response MUST use the content type set to application/json and MUST include the following parameters:

+
+
    +
  • error. The error code.

  • +
  • error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.

  • +
+
+

Steps 13-14: The Wallet Instance has been initialized and becomes operational.

+
+

Note

+

Threat Model: while the registration endpoint does not necessitate any client authentication, it is safeguarded through the use of key_attestation. Proper validation of this attestation permits the registration of authentic and unaltered app instances. Any other claims submitted will not undergo validation, leading the endpoint to respond with an error. Additionally, the inclusion of a challenge helps prevent replay attacks. The authenticity of both the challenge and the hardware_key_tag is ensured by the signature found within the key_attestation.

+
+
+
+

Wallet Attestation Issuance

+

This section describes the Wallet Attestation format and how the Wallet Provider issues it.

+
+The figure illustrates the sequence diagram for issuing a Wallet Attestation, with the steps explained below. +
+

Step 1: The User initiates a new operation that necessitates the acquisition of a Wallet Attestation.

+

Steps 2-3: The Wallet Instance checks if a Cryptographic Hardware Key exists and generates an ephemeral asymmetric key pair. The Wallet Instance also:

+
+
    +
  1. MUST ensure that Cryptographic Hardware Keys exist. If they do not exist, it is necessary to reinitialize the Wallet.

  2. +
  3. MUST generates an ephemeral asymmetric key pair whose public key will be linked with the Wallet Attestation.

  4. +
  5. MUST check if Wallet Provider is part of the federation and obtain its metadata.

  6. +
+
+

Steps 4-6: The Wallet Instance solicits a one-time "challenge" from the Wallet Provider Backend. This "challenge" takes the form of a "nonce," which is required to be unpredictable and serves as the main defense against replay attacks. The backend MUST produce the "nonce" in a manner that ensures its single-use within a predetermined time frame.

+
GET /nonce HTTP/1.1
+Host: walletprovider.example.com
+
+
+
HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+  "nonce": "d2JhY2NhbG91cmVqdWFuZGFt"
+}
+
+
+

Step 7: The Wallet Instance performs the following actions:

+
+
    +
  • Creates a client_data, a JSON structure that includes the challenge and the thumbprint of ephemeral public jwk.

  • +
  • Computes a client_data_hash by applying the SHA256 algorithm to the client_data.

  • +
+
+

Below a non-normative example of the client_data.

+
{
+  "challenge": "0fe3cbe0-646d-44b5-8808-917dd5391bd9",
+  "jwk_thumbprint": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c"
+}
+
+
+

Steps 8-10: The Wallet Instance takes the following steps:

+
+
    +
  • It produces an hardware_signature by signing the client_data_hash with the Wallet Hardware's private key, serving as a proof of possession for the Cryptographic Hardware Keys.

  • +
  • It requests the Device Integrity Service to create an integrity_assertion linked to the client_data_hash.

  • +
  • It receives a signed integrity_assertion from the Device Integrity Service, authenticated by the OEM.

  • +
+
+
+

Note

+

integrity_assertion is a custom payload generated by Device Integrity Service, signed by device OEM and encoded in base64 to have uniformity between different devices.

+
+

Steps 11-12: The Wallet Instance:

+
+
    +
  • Constructs the Wallet Attestation Request in the form of a JWT. This JWT includes the integrity_assertion, hardware_signature, challenge, hardware_key_tag, cnf and other configuration related parameters (see Table of the Wallet Attestation Request Body below) and is signed using the private key of the initially generated ephemeral key pair.

  • +
  • Submits the Wallet Attestation Request to the token endpoint of the Wallet Provider Backend.

  • +
+
+

Below an non-normative example of the Wallet Attestation Request JWT without encoding and signature applied:

+
{
+  "alg": "ES256",
+  "kid": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
+  "typ": "war+jwt"
+}
+.
+{
+  "iss": "https://wallet-provider.example.org/instance/vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
+  "sub": "https://wallet-provider.example.org/",
+  "challenge": "6ec69324-60a8-4e5b-a697-a766d85790ea",
+  "hardware_signature": "KoZIhvcNAQcCoIAwgAIB...redacted",
+  "integrity_assertion": "o2NmbXRvYXBwbGUtYXBwYX...redacted",
+  "hardware_key_tag": "WQhyDymFKsP95iFqpzdEDWW4l7aVna2Fn4JCeWHYtbU=",
+  "cnf": {
+    "jwk": {
+      "crv": "P-256",
+      "kty": "EC",
+      "x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44",
+      "y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg"
+    }
+  },
+  "vp_formats_supported": {
+      "jwt_vc_json": {
+        "alg_values_supported": ["ES256K", "ES384"]
+      },
+      "jwt_vp_json": {
+        "alg_values_supported": ["ES256K", "EdDSA"]
+      },
+    },
+  },
+  authorization_endpoint": "https://wallet-solution.digital-strategy.europa.eu/authorization",
+  "response_types_supported": [
+    "vp_token"
+  ],
+  "response_modes_supported": [
+    "form_post.jwt"
+  ],
+  "request_object_signing_alg_values_supported": [
+    "ES256"
+  ],
+  "presentation_definition_uri_supported": false,
+  "iat": 1686645115,
+  "exp": 1686652315
+}
+
+
+

The Wallet Instance MUST do an HTTP request to the Wallet Provider's token endpoint, +using the method POST.

+

The token endpoint (as defined in RFC 7523 section 4) requires the following parameters +encoded in application/x-www-form-urlencoded format:

+
    +
  • grant_type set to urn:ietf:params:oauth:grant-type:jwt-bearer;

  • +
  • assertion containing the signed JWT of the Wallet Attestation Request.

  • +
+
POST /token HTTP/1.1
+Host: wallet-provider.example.org
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer
+&assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6ImtoakZWTE9nRjNHeG...
+
+
+

Steps 13-17: The Wallet Provider Backend assesses the Wallet Attestation Request and issues a Wallet Attestation, if the requirements described below are satisfied:

+
+
    +
  1. It MUST check the Wallet Attestation Request contains all the defined HTTP Request header parameters according to Table of the Wallet Attestation Request Header.

  2. +
  3. It MUST verify that the signature of the received Wallet Attestation Request is valid and associated with public jwk.

  4. +
  5. It MUST verify that the challenge was generated by Wallet Provider and has not already been used.

  6. +
  7. It MUST check that there is a Wallet Instance registered with that hardware_key_tag and that it is still valid.

  8. +
  9. It MUST reconstruct the client_data via the challenge and the jwk public key, to validate hardware_signature via the Cryptographic Hardware Key public key registered and associated with the Wallet Instance.

  10. +
  11. It MUST validate the integrity_assertion as defined by the device manufacturers' guidelines. The list of checks that the Wallet Provider MUST perform are defined by the operating system manufacturers documentation.

  12. +
  13. It MUST verify that the device in use has no security flaws and reflects the minimum security requirements defined by the Wallet Provider.

  14. +
  15. It MUST check that the URL in iss parameter is equal to the URL identifier of Wallet Provider.

  16. +
+
+

If all checks are passed, Wallet Provider issues a Wallet Attestation with an expiration limited to 24 hours.

+

Below an non-normative example of the Wallet Attestation without encoding and signature applied:

+
  {
+  "alg": "ES256",
+  "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY",
+  "trust_chain": [
+    "eyJhbGciOiJFUz...6S0A",
+    "eyJhbGciOiJFUz...jJLA",
+    "eyJhbGciOiJFUz...H9gw",
+  ],
+  "typ": "wallet-attestation+jwt",
+}
+.
+{
+  "iss": "https://wallet-provider.example.org",
+  "sub": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
+  "aal": "https://trust-list.eu/aal/high",
+  "cnf":
+  {
+    "jwk":
+    {
+      "crv": "P-256",
+      "kty": "EC",
+      "x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44",
+      "y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg"
+    }
+  },
+  "authorization_endpoint": "eudiw:",
+  "response_types_supported": [
+    "vp_token"
+  ],
+  "response_modes_supported": [
+    "form_post.jwt"
+  ],
+  "vp_formats_supported": {
+      "vc+sd-jwt": {
+          "sd-jwt_alg_values": [
+              "ES256",
+              "ES384"
+          ]
+      }
+  },
+  "request_object_signing_alg_values_supported": [
+    "ES256"
+  ],
+  "presentation_definition_uri_supported": false,
+  "iat": 1687281195,
+  "exp": 1687288395
+}
+
+
+

Step 18: The response is returned by the Wallet Provider. If successful, the HTTP response code MUST be set with the value 200 OK and contain the Wallet Attestation signed by the Wallet Provider. The Wallet Instance therefore performs security, integrity and trust verification about the Wallet Attestation and its issuer.

+

Below is a non-normative example of the response.

+
HTTP/1.1 200 OK
+Content-Type: application/jwt
+
+eyJhbGciOiJFUzI1NiIsInR5cCI6IndhbGx ...
+
+
+
+
+

Wallet Attestation Request

+

The JOSE header of the Wallet Attestation Request JWT MUST contain:

+ +++++ + + + + + + + + + + + + + + + + + + + + +

JOSE header

Description

Reference

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section Cryptographic Algorithms and MUST NOT be set to none or any symmetric algorithm (MAC) identifier.

RFC 7516#section-4.1.1.

kid

Unique identifier of the jwk used by the Wallet Provider to sign the Wallet Attestation, essential for matching the Wallet Provider's cryptographic public key needed for signature verification.

RFC 7638#section_3.

typ

It MUST be set to var+jwt

+

The body of the Wallet Attestation Request JWT MUST contain:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

iss

Identifier of the Wallet Provider concatenated with thumbprint of the JWK in the cnf parameter.

RFC 9126 and RFC 7519.

aud

It MUST be set to the identifier of the Wallet Provider.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT.

RFC 9126 and RFC 7519.

iat

REQUIRED. UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

challenge

Challenge data obtained from nonce endpoint

hardware_signature

The signature of client_data obtained using Cryptographic Hardware Key base64 encoded.

integrity_assertion

The integrity assertion obtained from the Device Integrity Service with the holder binding of client_data.

hardware_key_tag

Unique identifier of the Cryptographic Hardware Keys

cnf

JSON object, containing the public part of an asymmetric key pair owned by the Wallet Instance.

RFC 7800

vp_formats_supported

JSON object with name/value pairs, identifying a Credential format supported by the Wallet.

authorization_endpoint

URL of the Wallet Authorization Endpoint (custom url schema or universal link of the Wallet Instance).

response_types_supported

JSON array containing a list of the OAuth 2.0 response_type values.

response_modes_supported

JSON array containing a list of the OAuth 2.0 "response_mode" values that this authorization server supports.

RFC 8414

request_object_signing_alg_values_supported

JSON array containing a list of the JWS signing algorithms (alg values) supported.

presentation_definition_uri_supported

Boolean value specifying whether the Wallet Instance supports the transfer of presentation_definition by reference. MUST be set to false.

+
+
+

Wallet Attestation

+

The JOSE header of the Wallet Attestation JWT MUST contain:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

JOSE header

Description

Reference

alg

A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms listed in the Section Cryptographic Algorithms and MUST NOT be set to none or any symmetric algorithm (MAC) identifier.

RFC 7516#section-4.1.1.

kid

Unique identifier of the jwk inside the cnf claim of Wallet Instance as base64url-encoded JWK Thumbprint value.

RFC 7638#section_3.

typ

It MUST be set to wallet-attestation+jwt

OPENID4VC-HAIP

trust_chain

Sequence of Entity Statements that composes the Trust Chain related to the Relying Party.

OID-FED Section 3.2.1. Trust Chain Header Parameter.

+

The body of the Wallet Attestation JWT MUST contain:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Claim

Description

Reference

iss

Identifier of the Wallet Provider

RFC 9126 and RFC 7519.

sub

Identifier of the Wallet Instance which is the thumbprint of the Wallet Instance JWK contained in the cnf claim.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT.

RFC 9126 and RFC 7519.

iat

UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

cnf

JSON object, containing the public part of an asymmetric key pair owned by the Wallet Instance.

RFC 7800

aal

JSON String asserting the authentication level of the Wallet and the key as asserted in the cnf claim.

authorization_endpoint

URL of the Wallet Authorization Endpoint (Universal Link).

response_types_supported

JSON array containing a list of the OAuth 2.0 response_type values.

response_modes_supported

JSON array containing a list of the OAuth 2.0 "response_mode" values that this authorization server supports.

RFC 8414

vp_formats_supported

JSON object with name/value pairs, identifying a Credential format supported by the Wallet.

request_object_signing_alg_values_supported

JSON array containing a list of the JWS signing algorithms (alg values) supported.

presentation_definition_uri_supported

Boolean value specifying whether the Wallet Instance supports the transfer of presentation_definition by reference. MUST be set to false.

+
+
+
+

Wallet Instance Lifecycle

+

The ability of the Wallet Instance to obtain a Wallet Attestation is bound to its current state. +The Wallet Instance assesses its current state based on the Credentials stored locally and the Wallet Attestation issued by the Wallet Provider.

+

The lifecycle of a Wallet Instance encompasses all the potential states it can configure, along with the transitions from one state to another. This lifecycle is depicted in the diagram below:

+
+Illustration representing the Wallet Instance lifecycle, with the states explained below. +
+

A Wallet Instance SHOULD obtain a Wallet Attestation if it's in either Installed, Operational or Valid state; that implies that a Deactivated Wallet Instance cannot obtain a Wallet Attestation hence it cannot interact with other entities of the ecosystem, such as PID/(Q)EAA Providers and Relying Parties.

+
+

States

+ ++++ + + + + + + + + + + + + + + + + + + + +

State

Description

Installed

The User has installed the Wallet Solution on the device.

Operational

The Wallet Instance has been verified and the Wallet Hardware Key has been registered; no valid PID is present in the storage.

Valid

A valid PID is present in the storage.

Deactivated

The Wallet Instance has been revoked and its Wallet Hardware Key has been marked as not usable.

+
+
+

Transitions

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

Transition

Description

install

The User performs a fresh installation or restores the initial state of the Wallet Instance on the device.

verify

The Wallet Instance has been verified by the Wallet Provider and its Wallet Hardware Key has been registered.

validate

The Wallet Instance obtains a valid PID.

invalidate

The PID expires or gets revoked.

revoke

The Wallet Provider marks the Wallet Instance as not usable.

uninstall

The User removes the Wallet Instance from the device.

+
+
+

Revocations

+

As mentioned in the Wallet Instance initialization and registration section above, a Wallet Instance is bound to a Wallet Hardware Key and it's uniquely identified by it. +The Wallet Instance SHOULD send its public Wallet Hardware Key with the Wallet Provider, thus the Wallet Provider MUST identify a Wallet Instance by its Wallet Hardware Key.

+

When a Wallet Instance is not usable anymore, the Wallet Provider MUST revoke it. The revocation process is a unilateral action taken by the Wallet Provider, and it MUST be performed when the Wallet Instance is in the Operational or Valid state. +A Wallet Instance becomes unusable for several reasons, such as: the User requests the revocation, the Wallet Provider detects a security issue, or the Wallet Instance is no longer compliant with the Wallet Provider's security requirements.

+

The details of the revocation mechanism used by the Wallet Provider as well as the data model for maintaining the Wallet Instance references is delegated to the Wallet Provider's implementation.

+

According to ARF, Section 6.5.4 and more specifically in Topic 38 the Wallet Instance can be revoked by the following entities:

+
+
    +
  1. Its owner, the User

  2. +
  3. Wallet Provider

  4. +
  5. PID Provider

  6. +
+
+

During the Wallet Instance initialization and registration phase the Wallet Provider MAY associate the Wallet Instance with a specific User, subject to obtaining the User's consent. The Wallet Provider MUST evaluate the operating system and general technical capabilities of the device to check compliance with the technical and security requirements and to produce the Wallet Instance metadata. +When the User consents to being linked with the Wallet Instance, they gain the ability to directly request Wallet revocation from the Wallet Provider, and it also allows the Wallet Provider to revoke the Wallet Instance associated with that User.

+

Regarding the reasons for revoking a Wallet Instance, the following scenarios may occur:

+
    +
  • The smartphone is lost;

  • +
  • The smartphone has been compromised (e.g., a malicious actor gains control of the smartphone);

  • +
  • The smartphone has been reset to factory settings;

  • +
  • Any other scenarios where the User loses the control of the Wallet Instance.

  • +
+

If any of the previous scenarios occur, the Wallet Instance MUST be revoked. +To allow the User to revoke the Wallet Instance, the Wallet Provider (WP) MUST offer a remote service, such as a web page, where the User can authenticate and request the revocation of a previously activated Wallet Instance.

+
+
+
+ + +
+
+
+
+ + + + + + +
+
+
+ +
+ + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/en/wallet-solution.html b/refs/pull/443/merge/en/wallet-solution.html new file mode 100644 index 000000000..cf7b65705 --- /dev/null +++ b/refs/pull/443/merge/en/wallet-solution.html @@ -0,0 +1,538 @@ + + + + + + + + Wallet Solution — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Wallet Solution

+

The Wallet Solution is issued by the Wallet Provider in the form of a mobile app and services, such as web interfaces.

+

The mobile app serves as the primary interface for Users, +allowing them to hold their Digital Credentials and interact with other participants of the ecosystem, +such as Credential Issuers and Relying Parties.

+

These Credentials are a set of data that can uniquely identify a natural or legal person, +along with other Qualified and non-qualified Electronic Attestations of Attributes, +also known as QEAAs and EAAs respectively, or (Q)EAAs for short[1].

+

Once a User installs the mobile app on their device, such an installation is referred to as a Wallet Instance for the User.

+

By supporting the mobile app, the Wallet Provider enusers the security and reliability of the entire Wallet Solution, +as it is responsible for issuing the Wallet Attestation, +which is a cryptographic proof about the authenticity and integrity of the Wallet Instance.

+
+

Requirements

+

This section lists the requirements that are be met by Wallet Providers and Wallet Solutions.

+
+
    +
  • The Wallet Provider MUST offer a RESTful set of services for issuing the Wallet Attestations.

  • +
  • The Wallet Instance MUST periodically reestablish trust with its Wallet Provider.

  • +
  • The Wallet Instance MUST establish trust with other participants of the Wallet ecosystem, such as Credential Issers and Relying Parties.

  • +
  • The Wallet Solutions MUST adhere to the specifications set by this document for obtaining Personal Identification (PID) and (Q)EAAs.

  • +
  • The Wallet Instance MUST be compatible and functional on both Android and iOS operating systems and available on the Play Store and App Store, respectively.

  • +
  • The Wallet Instance MUST provide a mechanism to verify the User's actual possession and full control of their personal device.

  • +
+
+
+
+

Wallet Instance

+

The Wallet Instance serves as a unique and secure device for authenticating the User within the Wallet ecosystem. +It establishes a strong and reliable mechanism for the User to engage in various digital transactions in a secure and privacy-preserving manner.

+

The Wallet Instance allows other entities within the ecosystem to establish trust with it, by consistently +presenting a Wallet Attestation during interactions with PID Providers, +(Q)EAA Providers, and Relying Parties. These verifiable attestations, provided by the Wallet Provider, +serve to authenticate the Wallet Instance itself, ensuring its reliability when engaging with other ecosystem actors.

+

To guarantee the utmost security, these cryptographic keys MUST be securely stored within the WSCD, which MAY be internal (device's Trusted Execution Environment (TEE)[3]), external, or hybrid. This ensures that only the User can access them, thus preventing unauthorized usage or tampering. For more detailed information, please refer to the Wallet Attestation section and the Trust Model section of this document.

+
+
+

Wallet Instance Lifecycle

+

The Wallet Instance has three distinct states: Operational, Valid, and Deactivated. +Each state represents a specific functional status and determines the actions that can be performed[2].

+
+

Initialization Process

+

To activate the Wallet Instance, Users MUST install the mobile Wallet application on their device and open it. Furthermore, Users will be asked to set their preferred method of unlocking their device; this can be accomplished by entering a personal identification number (PIN) or by utilizing biometric authentication, such as fingerprint or facial recognition, according to their personal preferences and device's capabilities.

+

After completing these steps, the Wallet Instance enters the Operational state.

+
+
+

Transition to Valid state

+

To transition from the Operational state to the Valid state, the Wallet Instance MUST obtain a valid Personal Identification (PID). Once a valid PID is acquired, the Wallet Instance becomes Valid.

+

The Wallet Instance MUST demonstrate to the Credential Issuer adequate security compliance to maintain the Credential at the same LoA at which it was issued.

+

Once the Wallet Instance is in the Valid state, Users can:

+
+
    +
  • Obtain, view, and manage (Q)EAAs from trusted (Q)EAA Providers[1];

  • +
  • Authenticate to Relying Parties[1];

  • +
  • Authorize the presentation of their digital Credentials to Relying Parties.

  • +
+
+

Please refer to the relevant sections for further information about PID and (Q)EAAs issuance and presentation.

+
+
+

Return to Operational state

+

A Valid Wallet Instance may revert to the Operational state under specific circumstances. These circumstances include the expiration or revocation of the associated PID by its PID Provider.

+
+
+

Deactivation

+

Users have the ability to deactivate the Wallet Instance voluntarily. This action removes the operational capabilities of the Wallet Instance and sets it to the Deactivated state. Deactivation provides Users with control over access and usage according to their preferences.

+
+
+
+

Wallet Provider Endpoints

+

The Wallet Provider that issues the Wallet Attestations MUST make its APIs available in the form of RESTful services, as listed below.

+
+

Wallet Provider Metadata

+

An HTTP GET request to the /.well-known/openid-federation endpoint allows the retrieval of the Wallet Provider Entity Configuration.

+

The Wallet Provider Entity Configuration is a JWS containing the public keys and supported algorithms of the Wallet Provider metadata definition. It is structured in accordance with the OpenID Connect Federation and the Trust Model section outlined in this specification.

+

The returning Entity Configuration of the Wallet Provider MUST contain the attributes listed below:

+
+
+ +
+

Payload

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Key

Value

iss

Public URL of the Wallet Provider.

sub

Public URL of the Wallet Provider.

iat

Issuance datetime in Unix Timestamp format.

exp

Expiration datetime in Unix Timestamp format.

authority_hints

Array of URLs (String) containing the list of URLs of the immediate superior Entities, such as the Trust Anchor or an Intermediate, that MAY issue an Entity Statement related to this subject.

jwks

A JSON Web Key Set (JWKS) RFC 7517 that represents the public part of the signing keys of the Entity at issue. Each JWK in the JWK set MUST have a key ID (claim kid).

metadata

Contains the wallet_provider and federation_entity metadata.

+
+

wallet_provider metadata

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

Key

Value

jwks

A JSON Web Key Set (JWKS) +that represents the Wallet +Provider's public keys.

token_endpoint

Endpoint for obtaining the Wallet +Instance Attestation.

nonce_endpoint

HTTPs URL indicating the endpoint +where the client can request the nonce.

aal_values_supported

List of supported values for the +certifiable security context. These +values specify the security level +of the app, according to the levels: low, medium, or high. +Authenticator Assurance Level values supported.

grant_types_supported

The types of grants supported by +the token endpoint. It MUST be set to +urn:ietf:params:oauth:client-assertion-type: +jwt-client-attestation.

token_endpoint_auth_methods_suppor +ted

Supported authentication methods for +the token endpoint.

token_endpoint_auth_signing_alg_va +lues_supported

Supported signature +algorithms for the token endpoint.

+
+

Note

+

The aal_values_supported parameter is experimental and under review.

+
+
+
+

Payload federation_entity

+ + + + + + + + + + + + + + + + + + + + + +

Key

Value

organization_name

Organization name.

homepage_uri

Organization's website URL.

tos_uri

URL to the terms of service.

policy_uri

URL to the privacy policy.

logo_uri

URL of the organization's logo in SVG format.

+

Below a non-normative example of the Entity Configuration.

+
{
+  "alg": "ES256",
+  "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY",
+  "typ": "entity-statement+jwt"
+}
+.
+{
+"iss": "https://wallet-provider.example.org",
+"sub": "https://wallet-provider.example.org",
+"jwks": {
+  "keys": [
+    {
+      "crv": "P-256",
+      "kty": "EC",
+      "x": "qrJrj3Af_B57sbOIRrcBM7br7wOc8ynj7lHFPTeffUk",
+      "y": "1H0cWDyGgvU8w-kPKU_xycOCUNT2o0bwslIQtnPU6iM",
+      "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY"
+    }
+  ]
+},
+"metadata": {
+  "wallet_provider": {
+    "jwks": {
+      "keys": [
+        {
+          "crv": "P-256",
+          "kty": "EC",
+          "x": "qrJrj3Af_B57sbOIRrcBM7br7wOc8ynj7lHFPTeffUk",
+          "y": "1H0cWDyGgvU8w-kPKU_xycOCUNT2o0bwslIQtnPU6iM",
+          "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY"
+        }
+      ]
+    },
+    "token_endpoint": "https://wallet-provider.example.org/token",
+    "nonce_endpoint": "https://wallet-provider.example.org/nonce",
+    "aal_values_supported": [
+      "https://wallet-provider.example.org/LoA/basic",
+      "https://wallet-provider.example.org/LoA/medium",
+      "https://wallet-provider.example.org/LoA/high"
+    ],
+    "grant_types_supported": [
+      "urn:ietf:params:oauth:client-assertion-type:jwt-client-attestation"
+    ],
+    "token_endpoint_auth_methods_supported": [
+      "private_key_jwt"
+    ],
+    "token_endpoint_auth_signing_alg_values_supported": [
+      "ES256",
+      "ES384",
+      "ES512"
+    ]
+  },
+  "federation_entity": {
+    "organization_name": "IT-Wallet Provider",
+    "homepage_uri": "https://wallet-provider.example.org",
+    "policy_uri": "https://wallet-provider.example.org/privacy_policy",
+    "tos_uri": "https://wallet-provider.example.org/info_policy",
+    "logo_uri": "https://wallet-provider.example.org/logo.svg"
+  }
+},
+"authority_hints": [
+  "https://registry.eudi-wallet.example.it"
+]
+"iat": 1687171759,
+"exp": 1709290159
+}
+
+
+
+
+

Wallet Attestation

+

Please refer to the Wallet Attestation section.

+
+
+
+

External references

+ +
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/.buildinfo b/refs/pull/443/merge/it/.buildinfo new file mode 100644 index 000000000..1f9da0289 --- /dev/null +++ b/refs/pull/443/merge/it/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 32b31b48cb58ccfb0a4e0ae83365da92 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/refs/pull/443/merge/it/.doctrees/backup-restore.doctree b/refs/pull/443/merge/it/.doctrees/backup-restore.doctree new file mode 100644 index 000000000..f43e3dd84 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/backup-restore.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/contribute.doctree b/refs/pull/443/merge/it/.doctrees/contribute.doctree new file mode 100644 index 000000000..7c14e9396 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/contribute.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/defined-terms.doctree b/refs/pull/443/merge/it/.doctrees/defined-terms.doctree new file mode 100644 index 000000000..81c86a151 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/defined-terms.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/environment.pickle b/refs/pull/443/merge/it/.doctrees/environment.pickle new file mode 100644 index 000000000..708cf7827 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/environment.pickle differ diff --git a/refs/pull/443/merge/it/.doctrees/index.doctree b/refs/pull/443/merge/it/.doctrees/index.doctree new file mode 100644 index 000000000..045fbab8e Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/index.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/issuance.doctree b/refs/pull/443/merge/it/.doctrees/issuance.doctree new file mode 100644 index 000000000..66a942052 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/issuance.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/pid-eaa-data.doctree b/refs/pull/443/merge/it/.doctrees/pid-eaa-data.doctree new file mode 100644 index 000000000..96d97cdf8 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/pid-eaa-data.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/pid-eaa-mdoc-cbor.doctree b/refs/pull/443/merge/it/.doctrees/pid-eaa-mdoc-cbor.doctree new file mode 100644 index 000000000..bd902f94f Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/pid-eaa-mdoc-cbor.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/pid-eaa-sd-jwt.doctree b/refs/pull/443/merge/it/.doctrees/pid-eaa-sd-jwt.doctree new file mode 100644 index 000000000..1a83df038 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/pid-eaa-sd-jwt.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/pseudonyms.doctree b/refs/pull/443/merge/it/.doctrees/pseudonyms.doctree new file mode 100644 index 000000000..f1e83bfca Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/pseudonyms.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/revocation-lists.doctree b/refs/pull/443/merge/it/.doctrees/revocation-lists.doctree new file mode 100644 index 000000000..aaaf6fa0b Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/revocation-lists.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/ssi-introduction.doctree b/refs/pull/443/merge/it/.doctrees/ssi-introduction.doctree new file mode 100644 index 000000000..1eedb0ba0 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/ssi-introduction.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/standards.doctree b/refs/pull/443/merge/it/.doctrees/standards.doctree new file mode 100644 index 000000000..dc64ede2b Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/standards.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/trust.doctree b/refs/pull/443/merge/it/.doctrees/trust.doctree new file mode 100644 index 000000000..ae5b516e5 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/trust.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/wallet-instance-attestation.doctree b/refs/pull/443/merge/it/.doctrees/wallet-instance-attestation.doctree new file mode 100644 index 000000000..b1e9665f2 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/wallet-instance-attestation.doctree differ diff --git a/refs/pull/443/merge/it/.doctrees/wallet-solution.doctree b/refs/pull/443/merge/it/.doctrees/wallet-solution.doctree new file mode 100644 index 000000000..e05b36652 Binary files /dev/null and b/refs/pull/443/merge/it/.doctrees/wallet-solution.doctree differ diff --git a/refs/pull/443/merge/it/_images/Eo_circle_green_checkmark.svg b/refs/pull/443/merge/it/_images/Eo_circle_green_checkmark.svg new file mode 100644 index 000000000..19e0bd7f0 --- /dev/null +++ b/refs/pull/443/merge/it/_images/Eo_circle_green_checkmark.svg @@ -0,0 +1,2 @@ + diff --git a/refs/pull/443/merge/it/_images/Eo_circle_red_letter-x.svg b/refs/pull/443/merge/it/_images/Eo_circle_red_letter-x.svg new file mode 100644 index 000000000..4c3c8e785 --- /dev/null +++ b/refs/pull/443/merge/it/_images/Eo_circle_red_letter-x.svg @@ -0,0 +1 @@ + diff --git a/refs/pull/443/merge/it/_sources/backup-restore.rst.txt b/refs/pull/443/merge/it/_sources/backup-restore.rst.txt new file mode 100644 index 000000000..186042348 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/backup-restore.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _backup-restore.rst: + +backup-restore.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/contribute.rst.txt b/refs/pull/443/merge/it/_sources/contribute.rst.txt new file mode 100644 index 000000000..9d984dea8 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/contribute.rst.txt @@ -0,0 +1,8 @@ +.. include:: ../common/common_definitions.rst + +.. _contribute.rst: + +contribute.rst ++++++++++++++++++++++++++++ + +Instruction to join in the development here. diff --git a/refs/pull/443/merge/it/_sources/defined-terms.rst.txt b/refs/pull/443/merge/it/_sources/defined-terms.rst.txt new file mode 100644 index 000000000..e0b9acdc3 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/defined-terms.rst.txt @@ -0,0 +1,89 @@ +.. include:: ../common/common_definitions.rst + +.. _defined-terms.rst: + +defined-terms.rst ++++++++++++++++++++++++++++ + +Di seguito le descrizioni di acronimi e definizioni, correlati al presente documento utili ad approfondimenti su tematiche che completano l' it-wallet e i componenti con i quali interagisce. + + +Acronimi +-------- +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - **Acronimo** + - **Descrizione** + * - **OID4VP** + - OpenID for Verifiable Presentation + * - **PID** + - Person Identification Data + * - **VC** + - Verifiable Credential + * - **VP** + - Verifiable Presentation + * - **API** + - Application Programming Interface. Insieme componenti previsti per semplificare gli scenari di integrazione di uno specifico Sistema. + + +Definizioni +----------- + +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - **Definizione** + - **Descrizione** + * - **Wallet Instance** + - Mobile App che gestisce, memorizza e protegge le Verifiable Credentials di un holder e ne consente la presentazione ad una Relying Party + * - **Relying Party** + - Entità che riceve da una Wallet Instance una o più VP e processa le stesse + + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/index.rst.txt b/refs/pull/443/merge/it/_sources/index.rst.txt new file mode 100644 index 000000000..abe2399cd --- /dev/null +++ b/refs/pull/443/merge/it/_sources/index.rst.txt @@ -0,0 +1,55 @@ +.. include:: ../common/common_definitions.rst + +============================================== +The Italian EUDI Wallet implementation profile +============================================== + +[TODO INTRO] + +Introduzione + +cos'è eIDAS + +cos’è IT-Wallet + +scopo delle regole tecniche + + +In this documentation you can find the technical specification +for implementing the following components: + + - Entities of the ecosystem according to `EIDAS-ARF`_. + - Infrastructure of trust attesting realiability and eligibility of the participants. + - PID and EAAs data schemes and attribute sets. + - PID/EAA in MDL CBOR format. + - PID/EAA in `SD-JWT`_ format. + - Wallet Solution general architecture. + - Wallet Instance Attestation data model in `JWS`_ format. + - Issuance of PID/EAA according to `OpenID4VCI`_. + - Presentation of PID/EAA according to `OpenID4VP`_. + - Presentation of pseudonyms according to `SIOPv2`_. + - PID/EAA backup and restore mechanisms. + - PID/EAA revocation lists. + + +Index of content +---------------- + +.. toctree:: + :maxdepth: 2 + + ssi-introduction.rst + defined-terms.rst + trust.rst + pid-eaa-data.rst + pid-eaa-mdoc-cbor.rst + pid-eaa-sd-jwt.rst + wallet-solution.rst + wallet-instance-attestation.rst + issuance.rst + relying-party-solution.rst + pseudonyms.rst + backup-restore.rst + revocation-lists.rst + contribute.rst + standards.rst diff --git a/refs/pull/443/merge/it/_sources/issuance.rst.txt b/refs/pull/443/merge/it/_sources/issuance.rst.txt new file mode 100644 index 000000000..1effd9399 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/issuance.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _issuance.rst: + +issuance.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/pid-eaa-data.rst.txt b/refs/pull/443/merge/it/_sources/pid-eaa-data.rst.txt new file mode 100644 index 000000000..8ab0305c9 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/pid-eaa-data.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _pid-eaa-data.rst: + +pid-eaa-data.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/pid-eaa-mdoc-cbor.rst.txt b/refs/pull/443/merge/it/_sources/pid-eaa-mdoc-cbor.rst.txt new file mode 100644 index 000000000..d96df2fff --- /dev/null +++ b/refs/pull/443/merge/it/_sources/pid-eaa-mdoc-cbor.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _pid-eaa-mdoc-cbor.rst: + +pid-eaa-mdoc-cbor.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/pid-eaa-sd-jwt.rst.txt b/refs/pull/443/merge/it/_sources/pid-eaa-sd-jwt.rst.txt new file mode 100644 index 000000000..b4daf4770 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/pid-eaa-sd-jwt.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _pid-eaa-sd-jwt.rst: + +pid-eaa-sd-jwt.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/pseudonyms.rst.txt b/refs/pull/443/merge/it/_sources/pseudonyms.rst.txt new file mode 100644 index 000000000..7b20567f9 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/pseudonyms.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _pseudonyms.rst: + +pseudonyms.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/revocation-lists.rst.txt b/refs/pull/443/merge/it/_sources/revocation-lists.rst.txt new file mode 100644 index 000000000..49cc7b174 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/revocation-lists.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _revocation-lists.rst: + +revocation-lists.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/ssi-introduction.rst.txt b/refs/pull/443/merge/it/_sources/ssi-introduction.rst.txt new file mode 100644 index 000000000..bf8e0a9e6 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/ssi-introduction.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _ssi-introduction.rst: + +ssi-introduction.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/standards.rst.txt b/refs/pull/443/merge/it/_sources/standards.rst.txt new file mode 100644 index 000000000..924e882fc --- /dev/null +++ b/refs/pull/443/merge/it/_sources/standards.rst.txt @@ -0,0 +1,8 @@ +.. include:: ../common/common_definitions.rst + +.. _standards.rst: + +Standards ++++++++++ + +TODO diff --git a/refs/pull/443/merge/it/_sources/trust.rst.txt b/refs/pull/443/merge/it/_sources/trust.rst.txt new file mode 100644 index 000000000..aa613216a --- /dev/null +++ b/refs/pull/443/merge/it/_sources/trust.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _trust.rst: + +trust.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/wallet-instance-attestation.rst.txt b/refs/pull/443/merge/it/_sources/wallet-instance-attestation.rst.txt new file mode 100644 index 000000000..35d4b69c0 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/wallet-instance-attestation.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _wallet-instance-attestation.rst: + +wallet-instance-attestation.rst ++++++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_sources/wallet-solution.rst.txt b/refs/pull/443/merge/it/_sources/wallet-solution.rst.txt new file mode 100644 index 000000000..bb3964a70 --- /dev/null +++ b/refs/pull/443/merge/it/_sources/wallet-solution.rst.txt @@ -0,0 +1,57 @@ +.. include:: ../common/common_definitions.rst + +.. _wallet-solution.rst: + +wallet-solution.rst ++++++++++++++++++++++++++++ + +[What is it] + +[What it is usefull for] + +[Example] + +General Properties +------------------ + +[TODO] + + +Requirements +------------ + + - req 1 + - req 2 + + +Attributes +---------- + +[Table with parameters/attributes] + +.. list-table:: + :widths: 20 60 + :header-rows: 1 + + * - **Claim** + - **Description** + * - key + - value + + +Implementation considerations +----------------------------- + +TODO + + +Libraries and code snippets +--------------------------- + +TODO + + +External references +------------------- + +TODO diff --git a/refs/pull/443/merge/it/_static/basic.css b/refs/pull/443/merge/it/_static/basic.css new file mode 100644 index 000000000..f316efcb4 --- /dev/null +++ b/refs/pull/443/merge/it/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/refs/pull/443/merge/it/_static/basic_mod.css b/refs/pull/443/merge/it/_static/basic_mod.css new file mode 100644 index 000000000..0df77588f --- /dev/null +++ b/refs/pull/443/merge/it/_static/basic_mod.css @@ -0,0 +1,1194 @@ +@font-face { + font-family: Roboto; + font-style: normal; + font-weight: 400; + src: local("Roboto"), local("Roboto-Regular"), url(fonts/roboto/roboto.woff2) format("woff2"); +} +@font-face { + font-family: Roboto; + font-style: italic; + font-weight: 400; + src: local("Roboto Italic"), local("Roboto-Italic"), url(fonts/roboto/roboto-italic.woff2) format("woff2"); +} +@font-face { + font-family: Roboto; + font-style: normal; + font-weight: 700; + src: local("Roboto Bold"), local("Roboto-Bold"), url(fonts/roboto/roboto-bold.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: normal; + font-weight: 400; + src: local("Roboto Mono Regular"), local("RobotoMono-Regular"), url(fonts/roboto-mono/roboto-mono.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: italic; + font-weight: 400; + src: local("Roboto Mono Italic"), local("RobotoMono-Italic"), url(fonts/roboto-mono/roboto-mono-italic.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: normal; + font-weight: 700; + src: local("Roboto Mono Bold"), local("RobotoMono-Bold"), url(fonts/roboto-mono/roboto-mono-bold.woff2) format("woff2"); +} +@font-face { + font-family: Roboto Mono; + font-style: italic; + font-weight: 700; + src: local("Roboto Mono Bold Italic"), local("RobotoMono-BoldItalic"), url(fonts/roboto-mono/roboto-mono-bold-italic.woff2) format("woff2"); +} +/*****************************************************************************/ +/* Typography */ +:root { + --codeBackgroundColor: #f8f8f8; + --inlineCodeBackgroundColor: #f8f8f8; + --codeBlue: #0000ff; + --codeGreen: #008000; + --dividerColor: rgba(0, 0, 0, 0.08); + --faintFontColor: rgba(0, 0, 0, 0.6); + --fontColor: #252630; + --linkColor: #2980b9; + --mainBackgroundColor: white; + --mainNavColor: #3889ce; + --notificationBannerColor: #176bb0; + --searchHighlightColor: #fff150; + --sidebarColor: white; + --navbarHeight: 4rem; +} +:root[data-mode=darkest] { + --mainBackgroundColor: black; + --sidebarColor: black; + --codeBackgroundColor: rgba(255, 255, 255, 0.1); + --inlineCodeBackgroundColor: rgba(255, 255, 255, 0.1); +} +:root[data-mode=dark] { + --mainBackgroundColor: #242429; + --sidebarColor: #242429; + --codeBackgroundColor: rgba(0, 0, 0, 0.1); + --inlineCodeBackgroundColor: rgba(255, 255, 255, 0.06); +} +:root[data-mode=dark], :root[data-mode=darkest] { + --codeBlue: #77baff; + --codeGreen: #38c038; + --dividerColor: rgba(255, 255, 255, 0.1); + --faintFontColor: rgba(255, 255, 255, 0.6); + --fontColor: white; + --linkColor: #319be0; + --searchHighlightColor: #fe8e04; +} + +body { + font-family: Roboto, "OpenSans", sans-serif; + background-color: var(--mainBackgroundColor); + color: var(--fontColor); +} + +h1 { + font-size: 2rem; +} + +h2 { + font-size: 1.5rem; +} + +h3 { + font-size: 1.17rem; +} + +a { + color: var(--linkColor); + text-decoration: none; +} + +/*****************************************************************************/ +html { + height: 100%; + scroll-padding-top: var(--navbarHeight); +} + +html, +body { + padding: 0; + margin: 0; + min-height: 100%; +} + +body { + display: flex; + flex-direction: column; +} + +/*****************************************************************************/ +/* Top nav */ +#searchbox h3#searchlabel { + display: none; +} +#searchbox form.search { + display: flex; + flex-direction: row; +} +#searchbox form.search input { + display: block; + box-sizing: border-box; + padding: 0.3rem; + color: rgba(0, 0, 0, 0.7); + border-radius: 0.2rem; +} +#searchbox form.search input[type=text] { + border: none; + background-color: rgba(255, 255, 255, 0.6); + flex-grow: 1; + margin-right: 0.2rem; +} +#searchbox form.search input[type=text]::placeholder { + color: rgba(0, 0, 0, 0.6); +} +#searchbox form.search input[type=submit] { + cursor: pointer; + color: var(--mainNavColor); + flex-grow: 0; + border: none; + background-color: white; +} + +div#top_nav { + position: fixed; + top: 0; + left: 0; + right: 0; + color: white; + z-index: 100; +} +div#top_nav div#notification_banner { + background-color: var(--notificationBannerColor); + box-sizing: border-box; + padding: 0.1rem 1rem; + display: flex; + flex-direction: row; + align-items: center; + justify-content: right; +} +div#top_nav div#notification_banner a.close { + flex-grow: 0; + flex-shrink: 0; + color: rgba(255, 255, 255, 0.85); + text-align: right; + font-size: 0.6rem; + text-transform: uppercase; + display: block; + text-decoration: none; + margin-left: 0.5rem; +} +div#top_nav div#notification_banner a.close:hover { + color: white; +} +div#top_nav div#notification_banner p { + flex-grow: 1; + margin: 0; + text-align: center; + font-size: 0.9rem; + line-height: 1.2; + padding: 0.4rem 0; +} +div#top_nav div#notification_banner p a { + color: white; + text-decoration: underline; +} +div#top_nav nav { + background-color: var(--mainNavColor); + box-sizing: border-box; + padding: 1rem; + display: flex; + flex-direction: row; + align-items: center; +} +div#top_nav nav h1 { + flex-grow: 1; + font-size: 1.2rem; + margin: 0; + padding: 0 0 0 0.8rem; + line-height: 1; +} +div#top_nav nav h1 a { + color: white; +} +div#top_nav nav h1 img { + height: 1.3rem; + width: auto; +} +div#top_nav nav p#toggle_sidebar { + transform: rotate(90deg); + letter-spacing: 0.1rem; + flex-grow: 0; + margin: 0; + padding: 0; +} +div#top_nav nav p#toggle_sidebar a { + color: white; + font-weight: bold; +} +div#top_nav nav a#mode_toggle, div#top_nav nav a#source_link { + margin-right: 1rem; + display: block; + flex-grow: 0; +} +div#top_nav nav a#mode_toggle svg, div#top_nav nav a#source_link svg { + height: 1.3rem; + width: 1.3rem; + vertical-align: middle; +} +div#top_nav nav p.mobile_search_link { + margin: 0; +} +@media (min-width: 50rem) { + div#top_nav nav p.mobile_search_link { + display: none; + } +} +div#top_nav nav p.mobile_search_link a { + color: white; +} +div#top_nav nav p.mobile_search_link a svg { + height: 1rem; + vertical-align: middle; +} +@media (max-width: 50rem) { + div#top_nav nav div.searchbox_wrapper { + display: none; + } +} +div#top_nav nav div.searchbox_wrapper #searchbox { + align-items: center; + display: flex !important; + flex-direction: row-reverse; +} +div#top_nav nav div.searchbox_wrapper #searchbox p.highlight-link { + margin: 0 0.5rem 0 0; +} +div#top_nav nav div.searchbox_wrapper #searchbox p.highlight-link a { + color: rgba(255, 255, 255, 0.8); + font-size: 0.8em; + padding-right: 0.5rem; + text-decoration: underline; +} +div#top_nav nav div.searchbox_wrapper #searchbox p.highlight-link a:hover { + color: white; +} + +/*****************************************************************************/ +/* Main content */ +div.document { + flex-grow: 1; + margin-top: 2rem; + margin-bottom: 5rem; + margin-left: 15rem; + margin-right: 15rem; + padding-top: var(--navbarHeight); + /***************************************************************************/ + /***************************************************************************/ +} +@media (max-width: 50rem) { + div.document { + margin-left: 0px; + margin-right: 0px; + } +} +div.document section, +div.document div.section { + margin: 4rem 0; +} +div.document section:first-child, +div.document div.section:first-child { + margin-top: 0; +} +div.document section > section, +div.document div.section > div.section { + margin: 4rem 0; +} +div.document section > section > section, +div.document div.section > div.section > div.section { + margin: 2rem 0 0 0; +} +div.document section > section > section > section, +div.document div.section > div.section > div.section > div.section { + margin: 1.5rem 0 0 0; +} +div.document h1 + section, +div.document h1 + div.section { + margin-top: 2.5rem !important; +} +div.document h2 + section, +div.document h2 + div.section { + margin-top: 1.5rem !important; +} +div.document img { + max-width: 100%; +} +div.document code { + padding: 2px 4px; + background-color: var(--inlineCodeBackgroundColor); + border-radius: 0.2rem; + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; + font-size: 0.9em; +} +div.document div.documentwrapper { + max-width: 45rem; + margin: 0 auto; + flex-grow: 1; + box-sizing: border-box; + padding: 1rem; +} +div.document div.highlight { + color: #252630; + box-sizing: border-box; + padding: 0.2rem 1rem; + margin: 0.5rem 0; + border-radius: 0.2rem; + font-size: 0.9rem; +} +div.document div.highlight pre { + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; +} +div.document div[class*=highlight] { + overflow-x: auto; +} +div.document a.headerlink { + font-size: 0.6em; + display: none; + padding-left: 0.5rem; + vertical-align: middle; +} +div.document h1, +div.document h2, +div.document h3, +div.document h4, +div.document h5, +div.document h6, +div.document str, +div.document b { + font-weight: 700; +} +div.document h1 { + margin: 0.8rem 0 0.5rem 0; +} +div.document h2 { + margin: 0.8rem 0 0.5rem 0; +} +div.document h3, div.document h4 { + margin: 1rem 0 0.5rem 0; +} +div.document h1:hover a.headerlink, +div.document h2:hover a.headerlink, +div.document h3:hover a.headerlink, +div.document h4:hover a.headerlink { + display: inline-block; +} +div.document p, +div.document li { + font-size: 1rem; + line-height: 1.5; +} +div.document li p { + margin: 0 0 0.5rem 0; +} +div.document ul, div.document ol { + padding-left: 2rem; +} +div.document ol.loweralpha { + list-style: lower-alpha; +} +div.document ol.arabic { + list-style: decimal; +} +div.document ol.lowerroman { + list-style: lower-roman; +} +div.document ol.upperalpha { + list-style: upper-alpha; +} +div.document ol.upperroman { + list-style: upper-roman; +} +div.document dd { + margin-left: 1.5rem; +} +div.document hr { + border: none; + height: 1px; + background-color: var(--dividerColor); + margin: 2rem 0; +} +div.document table.docutils { + border-collapse: collapse; +} +div.document table.docutils th, div.document table.docutils td { + border: 1px solid var(--dividerColor); + box-sizing: border-box; + padding: 0.5rem 1rem; +} +div.document table.docutils th p, div.document table.docutils th ul, div.document table.docutils td p, div.document table.docutils td ul { + margin: 0.3rem 0; +} +div.document table.docutils th ul, div.document table.docutils td ul { + padding-left: 1rem; +} +div.document form input { + padding: 0.5rem; +} +div.document form input[type=submit], div.document form button { + border: none; + background-color: var(--mainNavColor); + color: white; + padding: 0.5rem 1rem; + border-radius: 0.2rem; +} +div.document span.highlighted { + background-color: var(--searchHighlightColor); + padding: 0 0.1em; +} +div.document div#search-results { + padding-top: 2rem; +} +div.document div#search-results p.search-summary { + font-size: 0.8em; +} +div.document div#search-results ul.search { + list-style: none; + padding-left: 0; +} +div.document div#search-results ul.search li { + border-bottom: 1px solid var(--dividerColor); + margin: 0; + padding: 2rem 0; +} +div.document div#search-results ul.search li > a:first-child { + font-size: 1.2rem; +} +div.document dd ul, div.document dd ol { + padding-left: 1rem; +} +div.document dl.py { + margin-bottom: 2rem; +} +div.document dl.py dt.sig { + background-color: var(--codeBackgroundColor); + color: var(--fontColor); + box-sizing: border-box; + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; + font-size: 0.9rem; + padding: 1rem; + border-left: 5px solid rgba(0, 0, 0, 0.1); + border-radius: 0.2rem; +} +div.document dl.py em.property { + color: var(--sidebarColor); + font-weight: bold; +} +div.document dl.py span.sig-name { + color: var(--codeBlue); + font-weight: bold; +} +div.document dl.py em.property { + color: var(--codeGreen); +} +div.document dl.py em.sig-param { + margin-left: 2rem; +} +div.document dl.py em.sig-param span.default_value { + color: var(--codeGreen); +} +div.document dl.py span.sig-return span.sig-return-typehint { + color: var(--fontColor); +} +div.document dl.py span.sig-return span.sig-return-typehint pre { + color: var(--fontColor); +} +div.document dl.py em.sig-param > span:first-child { + font-weight: bold; +} +div.document dl.cpp, div.document dl.c { + margin-bottom: 1rem; +} +div.document dl.cpp dt.sig, div.document dl.c dt.sig { + background-color: var(--codeBackgroundColor); + color: var(--fontColor); + box-sizing: border-box; + font-family: "Roboto Mono", monospace, Monaco, Consolas, Andale Mono; + font-size: 0.9rem; + padding: 1rem; + border-left: 5px solid rgba(0, 0, 0, 0.1); + border-radius: 0.2rem; + line-height: 1.4; +} +div.document dl.cpp span.sig-name, div.document dl.c span.sig-name { + color: var(--codeBlue); + font-weight: bold; +} +div.document dl.cpp span.sig-indent, div.document dl.c span.sig-indent { + margin-left: 2rem; +} +div.document dl.cpp span.target + span, div.document dl.c span.target + span { + color: var(--codeGreen); +} +div.document dl.cpp span.sig-param > span:first-child, div.document dl.c span.sig-param > span:first-child { + font-weight: bold; +} +div.document div.admonition { + box-shadow: 0px 0px 0px 1px var(--dividerColor); + border-radius: 0.2rem; + margin: 1rem 0; + overflow: hidden; +} +div.document div.admonition p { + box-sizing: border-box; + font-size: 0.9rem; + padding: 0.5rem; + margin: 0; +} +div.document div.admonition p:first-child { + padding-bottom: 0; + margin-bottom: 0; +} +div.document div.admonition p + p { + padding-top: 0.2rem; +} +div.document div.admonition p.admonition-title { + font-weight: bolder; + letter-spacing: 0.01rem; +} +div.document div.admonition.hint, div.document div.admonition.important, div.document div.admonition.tip { + border-left: 5px solid #56b79c; +} +div.document div.admonition.hint p.admonition-title, div.document div.admonition.important p.admonition-title, div.document div.admonition.tip p.admonition-title { + color: #56b79c; +} +div.document div.admonition.note { + border-left: 5px solid #587f9f; +} +div.document div.admonition.note p.admonition-title { + color: #587f9f; +} +div.document div.admonition.danger, div.document div.admonition.error { + border-left: 5px solid #e6a39a; +} +div.document div.admonition.danger p.admonition-title, div.document div.admonition.error p.admonition-title { + color: #e6a39a; +} +div.document div.admonition.attention, div.document div.admonition.caution, div.document div.admonition.warning { + border-left: 5px solid #e7b486; +} +div.document div.admonition.attention p.admonition-title, div.document div.admonition.caution p.admonition-title, div.document div.admonition.warning p.admonition-title { + color: #e7b486; +} + +/*****************************************************************************/ +/* Sidebar */ +div.sphinxsidebar { + background-color: var(--sidebarColor); + border-right: 1px solid var(--dividerColor); + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: 15rem; + box-sizing: border-box; + padding: var(--navbarHeight) 1rem 1rem; + z-index: 50; +} +@media (max-width: 50rem) { + div.sphinxsidebar { + display: none; + } +} +div.sphinxsidebar div.sphinxsidebarwrapper { + height: 100%; + overflow-y: auto; +} +div.sphinxsidebar ul { + padding-left: 0rem; + list-style: none; +} +div.sphinxsidebar ul li { + font-size: 0.9rem; + line-height: 1.2; +} +div.sphinxsidebar ul li a { + display: block; + box-sizing: border-box; + padding: 0 0.2rem 0.6rem; + color: var(--fontColor); + text-decoration: none; +} +div.sphinxsidebar ul li a.current { + color: var(--linkColor); +} +div.sphinxsidebar ul li a:hover { + color: var(--linkColor); +} +div.sphinxsidebar ul li > ul { + padding-left: 1rem; +} +div.sphinxsidebar p { + color: var(--faintFontColor); +} + +/*****************************************************************************/ +/* The right sidebar, showing the table of contents for the current page. */ +div#show_right_sidebar { + position: fixed; + right: 0; + top: 0; + z-index: 20; + background-color: var(--sidebarColor); + border-left: 1px solid var(--dividerColor); + border-bottom: 1px solid var(--dividerColor); + padding: var(--navbarHeight) 1rem 0rem; +} +div#show_right_sidebar p { + font-size: 0.9em; +} +div#show_right_sidebar p span { + color: var(--faintFontColor); + vertical-align: middle; +} +div#show_right_sidebar p span.icon { + color: var(--linkColor); + font-size: 0.9em; + padding-right: 0.2rem; +} + +div#right_sidebar { + position: fixed; + right: 0; + top: 0; + z-index: 50; + background-color: var(--sidebarColor); + width: 15rem; + border-left: 1px solid var(--dividerColor); + box-sizing: border-box; + padding: var(--navbarHeight) 1rem 1rem; + height: 100%; + overflow-y: auto; +} +div#right_sidebar p span { + color: var(--faintFontColor); + vertical-align: middle; +} +div#right_sidebar p span.icon { + color: var(--linkColor); + font-size: 0.9em; + padding-right: 0.2rem; +} +div#right_sidebar ul { + padding-left: 0rem; + list-style: none; +} +div#right_sidebar ul li { + font-size: 0.9rem; + line-height: 1.2; +} +div#right_sidebar ul li a { + display: block; + box-sizing: border-box; + padding: 0 0.2rem 0.6rem; + color: var(--fontColor); + text-decoration: none; +} +div#right_sidebar ul li a.current { + color: var(--linkColor); +} +div#right_sidebar ul li a:hover { + color: var(--linkColor); +} +div#right_sidebar ul li > ul { + padding-left: 1rem; +} +div#right_sidebar p { + color: var(--faintFontColor); +} +@media (max-width: 50rem) { + div#right_sidebar { + display: none; + } +} + +/*****************************************************************************/ +/* Footer */ +div.footer { + box-sizing: border-box; + padding-top: 2rem; + font-size: 0.7rem; + text-align: center; + text-transform: uppercase; + color: var(--faintFontColor); +} + +p#theme_credit { + font-size: 0.6rem; + text-transform: uppercase; + text-align: center; + color: var(--faintFontColor); +} + +/*****************************************************************************/ +/* Buttons */ +div.button_nav_wrapper { + margin-left: 15rem; + margin-right: 15rem; +} +@media (max-width: 50rem) { + div.button_nav_wrapper { + margin-left: 0px; + margin-right: 0px; + } +} +div.button_nav_wrapper div.button_nav { + max-width: 45rem; + margin: 0 auto; + display: flex; + flex-direction: row; + width: 100%; +} +div.button_nav_wrapper div.button_nav div { + box-sizing: border-box; + padding: 1rem; + flex: 50%; +} +div.button_nav_wrapper div.button_nav div a { + display: block; +} +div.button_nav_wrapper div.button_nav div a span { + vertical-align: middle; +} +div.button_nav_wrapper div.button_nav div a span.icon { + font-weight: bold; + font-size: 0.8em; +} +div.button_nav_wrapper div.button_nav div.left a { + text-align: left; +} +div.button_nav_wrapper div.button_nav div.left a span.icon { + padding-right: 0.4rem; +} +div.button_nav_wrapper div.button_nav div.right a { + text-align: right; +} +div.button_nav_wrapper div.button_nav div.right a span.icon { + padding-left: 0.4rem; +} + +/*****************************************************************************/ +/* Pygments overrides in dark mode */ +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight { + --black: #000000; + --red: #ff9393; + --darkBlue: #6b83fe; + --grey: #a8a8a8; + --pink: #ff99d8; + --torquoise: #68e9e9; + --brown: #d48a00; + --purple: #ce04e9; + --paleYellow: #454534; + background: var(--codeBackgroundColor); + color: var(--fontColor); + /* Comment */ + /* Error */ + /* Keyword */ + /* Operator */ + /* Comment.Hashbang */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.PreprocFile */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Deleted */ + /* Generic.Emph */ + /* Generic.Error */ + /* Generic.Heading */ + /* Generic.Inserted */ + /* Generic.Output */ + /* Generic.Prompt */ + /* Generic.Strong */ + /* Generic.Subheading */ + /* Generic.Traceback */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Namespace */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Number */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Decorator */ + /* Name.Entity */ + /* Name.Exception */ + /* Name.Function */ + /* Name.Label */ + /* Name.Namespace */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Bin */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Affix */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Delimiter */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Function.Magic */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Name.Variable.Magic */ + /* Literal.Number.Integer.Long */ +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight pre, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight pre { + line-height: 125%; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight td.linenos .normal, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight td.linenos .normal { + color: inherit; + background-color: transparent; + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight span.linenos, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight span.linenos { + color: inherit; + background-color: transparent; + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight td.linenos .special, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight td.linenos .special { + color: var(--black); + background-color: var(--paleYellow); + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight span.linenos.special, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight span.linenos.special { + color: var(--black); + background-color: var(--paleYellow); + padding-left: 5px; + padding-right: 5px; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .hll, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .hll { + background-color: var(--paleYellow); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .c, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .c { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .err, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .err { + border: 1px solid var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .k, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .k { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .o, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .o { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ch, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ch { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cm, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cm { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cp { + color: var(--brown); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cpf, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cpf { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .c1, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .c1 { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .cs, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .cs { + color: var(--torquoise); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gd { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ge, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ge { + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gr, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gr { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gh, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gh { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gi, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gi { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .go, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .go { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gp { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gs, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gs { + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gu, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gu { + color: var(--purple); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .gt, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .gt { + color: var(--codeBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kc { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kd { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kn, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kn { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kp { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kr, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kr { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .kt, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .kt { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .m, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .m { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .s, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .s { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .na, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .na { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nb, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nb { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nc { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .no, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .no { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nd { + color: var(--purple); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ni, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ni { + color: var(--grey); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ne, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ne { + color: var(--red); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nf, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nf { + color: var(--codeBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nl, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nl { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nn, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nn { + color: var(--codeBlue); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nt, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nt { + color: var(--codeGreen); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .nv, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .nv { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ow, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ow { + color: var(--pink); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .w, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .w { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mb, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mb { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mf, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mf { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mh, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mh { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mi, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mi { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .mo, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .mo { + color: var(--grey); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sa, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sa { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sb, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sb { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sc { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .dl, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .dl { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sd, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sd { + color: var(--red); + font-style: italic; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .s2, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .s2 { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .se, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .se { + color: var(--brown); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sh, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sh { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .si, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .si { + color: var(--pink); + font-weight: bold; +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sx, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sx { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .sr, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .sr { + color: var(--pink); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .s1, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .s1 { + color: var(--red); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .ss, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .ss { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .bp, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .bp { + color: var(--codeGreen); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .fm, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .fm { + color: var(--codeBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vc, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vc { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vg, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vg { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vi, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vi { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .vm, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .vm { + color: var(--darkBlue); +} +:root[data-mode=dark] body[data-dark_mode_code_blocks=true] .highlight .il, +:root[data-mode=darkest] body[data-dark_mode_code_blocks=true] .highlight .il { + color: var(--grey); +} + +/*# sourceMappingURL=basic_mod.css.map */ diff --git a/refs/pull/443/merge/it/_static/basic_mod.css.map b/refs/pull/443/merge/it/_static/basic_mod.css.map new file mode 100644 index 000000000..332d772fb --- /dev/null +++ b/refs/pull/443/merge/it/_static/basic_mod.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../../src/sass/basic_mod.scss"],"names":[],"mappings":"AAGA;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAID;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;;AAaD;AACA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;AAEA;EACE;EAEA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AACA;AAKE;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA,eAhHS;;AAmHX;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE,OA9Na;EA+Nb;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;;AAEA;EACE;EACA;;AAOJ;EADF;IAEI;;;AAKF;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AASd;AACA;AAEA;EACE;EACA;EACA;EACA,aAnSa;EAoSb,cApSa;EAqSb;AAOA;AAqDA;;AA1DA;EARF;IASI;IACA;;;AAgBF;AAAA;EAEE;;AAGA;AAAA;EACE;;AAOJ;AAAA;EAEE;;AAIF;AAAA;EAEE;;AAIF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAKF;EACE;;AAGF;EACE;EACA;EACA,eA7WW;EA8WX,aAhXO;EAiXP;;AAGF;EACE,WAlXW;EAmXX;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA,eA/XW;EAgYX;;AAEA;EACE,aArYK;;AA0YT;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAOA;AAAA;AAAA;AAAA;EACE;;AAIJ;AAAA;EAEE;EACA;;AAQA;EACE;;AAIJ;EACE;;AAOA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AACA;EACE;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;AAMJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAOJ;EACE;EACA;;AAGF;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AASN;EACE;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA,aAzjBK;EA0jBL;EACA;EACA;EACA,eA3jBS;;AA+jBX;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKF;EACE;;AAEA;EACE;;AAMN;EACE;;AAMJ;EACE;;AAEA;EACE;EACA;EACA;EACA,aAlnBK;EAmnBL;EACA;EACA;EACA,eApnBS;EAqnBT;;AAIF;EACE;EACA;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;AAMJ;EACE;EACA,eAlpBW;EAmpBX;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EAIE;;AAEA;EACE,OAJM;;AAQV;EAEE;;AAEA;EACE,OAJM;;AAQV;EAGE;;AAEA;EACE,OAJM;;AAQV;EAIE;;AAEA;EACE,OAJM;;;AAUd;AACA;AAwCA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OAnwBa;EAowBb;EACA;EACA;;AAEA;EAZF;IAaI;;;AAGF;EACE;EACA;;AAvDF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAKN;EACE;;AAMJ;EACE;;;AA6BJ;AACA;AAiBA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAxBF;EACE;EACA;;AAEA;EACE;EACA;EACA;;;AAuBN;EACE;EACA;EACA;EACA;EACA;EACA,OA9zBa;EA+zBb;EACA;EACA;EACA;EACA;;AAzCA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AA1EJ;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAKN;EACE;;AAMJ;EACE;;AAoFF;EApBF;IAqBI;;;;AAIJ;AACA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;AACA;AAEA;EACE,aAx2Ba;EAy2Bb,cAz2Ba;;AA22Bb;EAJF;IAKI;IACA;;;AAGF;EACE,WAn3BW;EAo3BX;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAKF;EACE;;AAEA;EACE;;AAMJ;EACE;;AAEA;EACE;;;AAQZ;AACA;AAOE;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;AAoCE;AAGA;AAIA;AAGA;AAIA;AAIA;AAGA;AAIA;AAIA;AAIA;AAGA;AAGA;AAGA;AAIA;AAGA;AAGA;AAIA;AAGA;AAIA;AAGA;AAIA;AAIA;AAIA;AAGA;AAIA;AAGA;AAGA;AAGA;AAGA;AAGA;AAIA;AAGA;AAGA;AAIA;AAIA;AAGA;AAGA;AAIA;AAIA;AAGA;AAIA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAIA;AAGA;AAIA;AAGA;AAIA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;;AA9PF;AAAA;EACE;;AAGF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;EACA;EACA;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;EACA;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACE","file":"basic_mod.css"} \ No newline at end of file diff --git a/refs/pull/443/merge/it/_static/doctools.js b/refs/pull/443/merge/it/_static/doctools.js new file mode 100644 index 000000000..4d67807d1 --- /dev/null +++ b/refs/pull/443/merge/it/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/refs/pull/443/merge/it/_static/documentation_options.js b/refs/pull/443/merge/it/_static/documentation_options.js new file mode 100644 index 000000000..9feebd4c3 --- /dev/null +++ b/refs/pull/443/merge/it/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: 'version: latest', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/refs/pull/443/merge/it/_static/file.png b/refs/pull/443/merge/it/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/refs/pull/443/merge/it/_static/file.png differ diff --git a/refs/pull/443/merge/it/_static/fonts/roboto-mono/LICENSE.txt b/refs/pull/443/merge/it/_static/fonts/roboto-mono/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/refs/pull/443/merge/it/_static/fonts/roboto-mono/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-bold-italic.woff2 b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-bold-italic.woff2 new file mode 100644 index 000000000..595f902d6 Binary files /dev/null and b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-bold-italic.woff2 differ diff --git a/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-bold.woff2 b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-bold.woff2 new file mode 100644 index 000000000..eb7eb9d48 Binary files /dev/null and b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-bold.woff2 differ diff --git a/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-italic.woff2 b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-italic.woff2 new file mode 100644 index 000000000..8f5146aa0 Binary files /dev/null and b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono-italic.woff2 differ diff --git a/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono.woff2 b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono.woff2 new file mode 100644 index 000000000..9e69f6d1a Binary files /dev/null and b/refs/pull/443/merge/it/_static/fonts/roboto-mono/roboto-mono.woff2 differ diff --git a/refs/pull/443/merge/it/_static/fonts/roboto/LICENSE.txt b/refs/pull/443/merge/it/_static/fonts/roboto/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/refs/pull/443/merge/it/_static/fonts/roboto/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/refs/pull/443/merge/it/_static/fonts/roboto/roboto-bold.woff2 b/refs/pull/443/merge/it/_static/fonts/roboto/roboto-bold.woff2 new file mode 100644 index 000000000..ed8b5520c Binary files /dev/null and b/refs/pull/443/merge/it/_static/fonts/roboto/roboto-bold.woff2 differ diff --git a/refs/pull/443/merge/it/_static/fonts/roboto/roboto-italic.woff2 b/refs/pull/443/merge/it/_static/fonts/roboto/roboto-italic.woff2 new file mode 100644 index 000000000..719979294 Binary files /dev/null and b/refs/pull/443/merge/it/_static/fonts/roboto/roboto-italic.woff2 differ diff --git a/refs/pull/443/merge/it/_static/fonts/roboto/roboto.woff2 b/refs/pull/443/merge/it/_static/fonts/roboto/roboto.woff2 new file mode 100644 index 000000000..39cd5a6f0 Binary files /dev/null and b/refs/pull/443/merge/it/_static/fonts/roboto/roboto.woff2 differ diff --git a/refs/pull/443/merge/it/_static/js/petite-vue.js b/refs/pull/443/merge/it/_static/js/petite-vue.js new file mode 100644 index 000000000..b2acae462 --- /dev/null +++ b/refs/pull/443/merge/it/_static/js/petite-vue.js @@ -0,0 +1 @@ +var pn=Object.defineProperty,hn=(e,t,n)=>t in e?pn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,C=(e,t,n)=>(hn(e,"symbol"!=typeof t?t+"":t,n),n),PetiteVue=function(e){"use strict";function t(e){if(a(e)){const n={};for(let s=0;s{if(e){const n=e.split(s);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}function i(e){let t="";if(d(e))t=e;else if(a(e))for(let n=0;no(e,t)))}const l=Object.assign,f=Object.prototype.hasOwnProperty,u=(e,t)=>f.call(e,t),a=Array.isArray,p=e=>"[object Map]"===y(e),h=e=>e instanceof Date,d=e=>"string"==typeof e,m=e=>"symbol"==typeof e,g=e=>null!==e&&"object"==typeof e,v=Object.prototype.toString,y=e=>v.call(e),b=e=>d(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,x=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},_=/-(\w)/g,w=x((e=>e.replace(_,((e,t)=>t?t.toUpperCase():"")))),$=/\B([A-Z])/g,k=x((e=>e.replace($,"-$1").toLowerCase())),O=e=>{const t=parseFloat(e);return isNaN(t)?e:t};function S(e,t){(t=t||undefined)&&t.active&&t.effects.push(e)}const E=e=>{const t=new Set(e);return t.w=0,t.n=0,t},j=e=>(e.w&N)>0,A=e=>(e.n&N)>0,P=new WeakMap;let R=0,N=1;const T=[];let M;const B=Symbol(""),L=Symbol("");class W{constructor(e,t=null,n){this.fn=e,this.scheduler=t,this.active=!0,this.deps=[],S(this,n)}run(){if(!this.active)return this.fn();if(!T.includes(this))try{return T.push(M=this),F.push(V),V=!0,N=1<<++R,R<=30?(({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let s=0;s0?T[e-1]:void 0}}stop(){this.active&&(I(this),this.onStop&&this.onStop(),this.active=!1)}}function I(e){const{deps:t}=e;if(t.length){for(let n=0;n{("length"===t||t>=s)&&c.push(e)}));else switch(void 0!==n&&c.push(o.get(n)),t){case"add":a(e)?b(n)&&c.push(o.get("length")):(c.push(o.get(B)),p(e)&&c.push(o.get(L)));break;case"delete":a(e)||(c.push(o.get(B)),p(e)&&c.push(o.get(L)));break;case"set":p(e)&&c.push(o.get(B))}if(1===c.length)c[0]&&Z(c[0]);else{const e=[];for(const t of c)t&&e.push(...t);Z(E(e))}}function Z(e,t){for(const n of a(e)?e:[...e])(n!==M||n.allowRecurse)&&(n.scheduler?n.scheduler():n.run())}const q=function(e,t){const n=Object.create(null),s=e.split(",");for(let r=0;r!!n[e.toLowerCase()]:e=>!!n[e]}("__proto__,__v_isRef,__isVue"),D=new Set(Object.getOwnPropertyNames(Symbol).map((e=>Symbol[e])).filter(m)),G=X(),U=X(!0),Q=function(){const e={};return["includes","indexOf","lastIndexOf"].forEach((t=>{e[t]=function(...e){const n=le(this);for(let t=0,r=this.length;t{e[t]=function(...e){F.push(V),V=!1;const n=le(this)[t].apply(this,e);return z(),n}})),e}();function X(e=!1,t=!1){return function(n,s,r){if("__v_isReactive"===s)return!e;if("__v_isReadonly"===s)return e;if("__v_raw"===s&&r===(e?t?re:se:t?ne:te).get(n))return n;const i=a(n);if(!e&&i&&u(Q,s))return Reflect.get(Q,s,r);const o=Reflect.get(n,s,r);return(m(s)?D.has(s):q(s))||(e||H(n,0,s),t)?o:fe(o)?i&&b(s)?o:o.value:g(o)?e?function(e){return ce(e,!0,ee,null,se)}(o):oe(o):o}}const Y={get:G,set:function(e=!1){return function(t,n,s,r){let i=t[n];if(!e&&!function(e){return!(!e||!e.__v_isReadonly)}(s)&&(s=le(s),i=le(i),!a(t)&&fe(i)&&!fe(s)))return i.value=s,!0;const o=a(t)&&b(n)?Number(n)!Object.is(e,t))(s,i)&&J(t,"set",n,s):J(t,"add",n,s)),c}}(),deleteProperty:function(e,t){const n=u(e,t);e[t];const s=Reflect.deleteProperty(e,t);return s&&n&&J(e,"delete",t,void 0),s},has:function(e,t){const n=Reflect.has(e,t);return(!m(t)||!D.has(t))&&H(e,0,t),n},ownKeys:function(e){return H(e,0,a(e)?"length":B),Reflect.ownKeys(e)}},ee={get:U,set:(e,t)=>!0,deleteProperty:(e,t)=>!0},te=new WeakMap,ne=new WeakMap,se=new WeakMap,re=new WeakMap;function ie(e){return e.__v_skip||!Object.isExtensible(e)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}((e=>y(e).slice(8,-1))(e))}function oe(e){return e&&e.__v_isReadonly?e:ce(e,!1,Y,null,te)}function ce(e,t,n,s,r){if(!g(e)||e.__v_raw&&(!t||!e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const o=ie(e);if(0===o)return e;const c=new Proxy(e,2===o?s:n);return r.set(e,c),c}function le(e){const t=e&&e.__v_raw;return t?le(t):e}function fe(e){return Boolean(e&&!0===e.__v_isRef)}Promise.resolve();let ue=!1;const ae=[],pe=Promise.resolve(),he=e=>pe.then(e),de=e=>{ae.includes(e)||ae.push(e),ue||(ue=!0,he(me))},me=()=>{for(const e of ae)e();ae.length=0,ue=!1},ge=/^(spellcheck|draggable|form|list|type)$/,ve=({el:e,get:t,effect:n,arg:s,modifiers:r})=>{let i;"class"===s&&(e._class=e.className),n((()=>{let n=t();if(s)(null==r?void 0:r.camel)&&(s=w(s)),ye(e,s,n,i);else{for(const t in n)ye(e,t,n[t],i&&i[t]);for(const t in i)(!n||!(t in n))&&ye(e,t,null)}i=n}))},ye=(e,n,s,r)=>{if("class"===n)e.setAttribute("class",i(e._class?[e._class,s]:s)||"");else if("style"===n){s=t(s);const{style:n}=e;if(s)if(d(s))s!==r&&(n.cssText=s);else{for(const e in s)xe(n,e,s[e]);if(r&&!d(r))for(const e in r)null==s[e]&&xe(n,e,"")}else e.removeAttribute("style")}else e instanceof SVGElement||!(n in e)||ge.test(n)?"true-value"===n?e._trueValue=s:"false-value"===n?e._falseValue=s:null!=s?e.setAttribute(n,s):e.removeAttribute(n):(e[n]=s,"value"===n&&(e._value=s))},be=/\s*!important$/,xe=(e,t,n)=>{a(n)?n.forEach((n=>xe(e,t,n))):t.startsWith("--")?e.setProperty(t,n):be.test(n)?e.setProperty(k(t),n.replace(be,""),"important"):e[t]=n},_e=(e,t)=>{const n=e.getAttribute(t);return null!=n&&e.removeAttribute(t),n},we=(e,t,n,s)=>{e.addEventListener(t,n,s)},$e=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,ke=["ctrl","shift","alt","meta"],Oe={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&0!==e.button,middle:e=>"button"in e&&1!==e.button,right:e=>"button"in e&&2!==e.button,exact:(e,t)=>ke.some((n=>e[`${n}Key`]&&!t[n]))},Se=({el:e,get:t,exp:n,arg:s,modifiers:r})=>{if(!s)return;let i=$e.test(n)?t(`(e => ${n}(e))`):t(`($event => { ${n} })`);if("vue:mounted"!==s){if("vue:unmounted"===s)return()=>i();if(r){"click"===s&&(r.right&&(s="contextmenu"),r.middle&&(s="mouseup"));const e=i;i=t=>{if(!("key"in t)||k(t.key)in r){for(const e in r){const n=Oe[e];if(n&&n(t,r))return}return e(t)}}}we(e,s,i,r)}else he(i)},Ee=({el:e,get:t,effect:n})=>{n((()=>{e.textContent=Ce(t())}))},Ce=e=>null==e?"":g(e)?JSON.stringify(e,null,2):String(e),je=e=>"_value"in e?e._value:e.value,Ae=(e,t)=>{const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t},Pe=e=>{e.target.composing=!0},Re=e=>{const t=e.target;t.composing&&(t.composing=!1,Ne(t,"input"))},Ne=(e,t)=>{const n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)},Te=Object.create(null),Me=(e,t,n)=>Be(e,`return(${t})`,n),Be=(e,t,n)=>{const s=Te[t]||(Te[t]=Le(t));try{return s(e,n)}catch(r){console.error(r)}},Le=e=>{try{return new Function("$data","$el",`with($data){${e}}`)}catch(t){return console.error(`${t.message} in expression: ${e}`),()=>{}}},We={bind:ve,on:Se,show:({el:e,get:t,effect:n})=>{const s=e.style.display;n((()=>{e.style.display=t()?s:"none"}))},text:Ee,html:({el:e,get:t,effect:n})=>{n((()=>{e.innerHTML=t()}))},model:({el:e,exp:t,get:n,effect:s,modifiers:r})=>{const i=e.type,l=n(`(val) => { ${t} = val }`),{trim:f,number:u="number"===i}=r||{};if("SELECT"===e.tagName){const t=e;we(e,"change",(()=>{const e=Array.prototype.filter.call(t.options,(e=>e.selected)).map((e=>u?O(je(e)):je(e)));l(t.multiple?e:e[0])})),s((()=>{const e=n(),s=t.multiple;for(let n=0,r=t.options.length;n-1:r.selected=e.has(i);else if(o(je(r),e))return void(t.selectedIndex!==n&&(t.selectedIndex=n))}!s&&-1!==t.selectedIndex&&(t.selectedIndex=-1)}))}else if("checkbox"===i){let t;we(e,"change",(()=>{const t=n(),s=e.checked;if(a(t)){const n=je(e),r=c(t,n),i=-1!==r;if(s&&!i)l(t.concat(n));else if(!s&&i){const e=[...t];e.splice(r,1),l(e)}}else l(Ae(e,s))})),s((()=>{const s=n();a(s)?e.checked=c(s,je(e))>-1:s!==t&&(e.checked=o(s,Ae(e,!0))),t=s}))}else if("radio"===i){let t;we(e,"change",(()=>{l(je(e))})),s((()=>{const s=n();s!==t&&(e.checked=o(s,je(e)))}))}else{const t=e=>f?e.trim():u?O(e):e;we(e,"compositionstart",Pe),we(e,"compositionend",Re),we(e,(null==r?void 0:r.lazy)?"change":"input",(()=>{e.composing||l(t(e.value))})),f&&we(e,"change",(()=>{e.value=e.value.trim()})),s((()=>{if(e.composing)return;const s=e.value,r=n();document.activeElement===e&&t(s)===r||s!==r&&(e.value=r)}))}},effect:({el:e,ctx:t,exp:n,effect:s})=>{he((()=>s((()=>Be(t.scope,n,e)))))}},Ie=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,Ke=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Ve=/^\(|\)$/g,Fe=/^[{[]\s*((?:[\w_$]+\s*,?\s*)+)[\]}]$/,ze=(e,t,n)=>{const s=t.match(Ie);if(!s)return;const r=e.nextSibling,i=e.parentElement,o=new Text("");i.insertBefore(o,e),i.removeChild(e);const c=s[2].trim();let l,f,u,p,h=s[1].trim().replace(Ve,"").trim(),d=!1,m="key",v=e.getAttribute(m)||e.getAttribute(m=":key")||e.getAttribute(m="v-bind:key");v&&(e.removeAttribute(m),"key"===m&&(v=JSON.stringify(v))),(p=h.match(Ke))&&(h=h.replace(Ke,"").trim(),f=p[1].trim(),p[2]&&(u=p[2].trim())),(p=h.match(Fe))&&(l=p[1].split(",").map((e=>e.trim())),d="["===h[0]);let y,b,x,_=!1;const w=(e,t,s,r)=>{const i={};l?l.forEach(((e,n)=>i[e]=t[d?n:e])):i[h]=t,r?(f&&(i[f]=r),u&&(i[u]=s)):f&&(i[f]=s);const o=et(n,i),c=v?Me(o.scope,v):s;return e.set(c,s),o.key=c,o},$=(t,n)=>{const s=new nt(e,t);return s.key=t.key,s.insert(i,n),s};return n.effect((()=>{const e=Me(n.scope,c),t=x;if([b,x]=(e=>{const t=new Map,n=[];if(a(e))for(let s=0;s$(e,o))),_=!0})),r},He=({el:e,ctx:{scope:{$refs:t}},get:n,effect:s})=>{let r;return s((()=>{const s=n();t[s]=e,r&&s!==r&&delete t[r],r=s})),()=>{r&&delete t[r]}},Je=/^(?:v-|:|@)/,Ze=/\.([\w-]+)/g;let qe=!1;const De=(e,t)=>{const n=e.nodeType;if(1===n){const n=e;if(n.hasAttribute("v-pre"))return;let s;if(_e(n,"v-cloak"),s=_e(n,"v-if"))return((e,t,n)=>{const s=e.parentElement,r=new Comment("v-if");s.insertBefore(r,e);const i=[{exp:t,el:e}];let o,c;for(;(o=e.nextElementSibling)&&(c=null,""===_e(o,"v-else")||(c=_e(o,"v-else-if")));)s.removeChild(o),i.push({exp:c,el:o});const l=e.nextSibling;s.removeChild(e);let f,u=-1;const a=()=>{f&&(s.insertBefore(r,f.el),f.remove(),f=void 0)};return n.effect((()=>{for(let e=0;e{let n=e.firstChild;for(;n;)n=De(n,t)||n.nextSibling},Ue=(e,t,n,s)=>{let r,i,o;if(":"===(t=t.replace(Ze,((e,t)=>((o||(o={}))[t]=!0,""))))[0])r=ve,i=t.slice(1);else if("@"===t[0])r=Se,i=t.slice(1);else{const e=t.indexOf(":"),n=e>0?t.slice(2,e):t.slice(2);r=We[n]||s.dirs[n],i=e>0?t.slice(e+1):void 0}r&&(r===ve&&"ref"===i&&(r=He),Qe(e,r,n,s,i,o),e.removeAttribute(t))},Qe=(e,t,n,s,r,i)=>{const o=t({el:e,get:(t=n)=>Me(s.scope,t,e),effect:s.effect,ctx:s,exp:n,arg:r,modifiers:i});o&&s.cleanups.push(o)},Xe=(e,t)=>{if("#"!==t[0])e.innerHTML=t;else{const n=document.querySelector(t);e.appendChild(n.content.cloneNode(!0))}},Ye=e=>{const t={delimiters:["{{","}}"],delimitersRE:/\{\{([^]+?)\}\}/g,...e,scope:e?e.scope:oe({}),dirs:e?e.dirs:{},effects:[],blocks:[],cleanups:[],effect:e=>{if(qe)return de(e),e;const n=function(e,t){e.effect&&(e=e.effect.fn);const n=new W(e);t&&(l(n,t),t.scope&&S(n,t.scope)),(!t||!t.lazy)&&n.run();const s=n.run.bind(n);return s.effect=n,s}(e,{scheduler:()=>de(n)});return t.effects.push(n),n}};return t},et=(e,t={})=>{const n=e.scope,s=Object.create(n);Object.defineProperties(s,Object.getOwnPropertyDescriptors(t)),s.$refs=Object.create(n.$refs);const r=oe(new Proxy(s,{set:(e,t,s,i)=>i!==r||e.hasOwnProperty(t)?Reflect.set(e,t,s,i):Reflect.set(n,t,s)}));return tt(r),{...e,scope:r}},tt=e=>{for(const t of Object.keys(e))"function"==typeof e[t]&&(e[t]=e[t].bind(e))};class nt{constructor(e,t,n=!1){C(this,"template"),C(this,"ctx"),C(this,"key"),C(this,"parentCtx"),C(this,"isFragment"),C(this,"start"),C(this,"end"),this.isFragment=e instanceof HTMLTemplateElement,n?this.template=e:this.isFragment?this.template=e.content.cloneNode(!0):this.template=e.cloneNode(!0),n?this.ctx=t:(this.parentCtx=t,t.blocks.push(this),this.ctx=Ye(t)),De(this.template,this.ctx)}get el(){return this.start||this.template}insert(e,t=null){if(this.isFragment)if(this.start){let n,s=this.start;for(;s&&(n=s.nextSibling,e.insertBefore(s,t),s!==this.end);)s=n}else this.start=new Text(""),this.end=new Text(""),e.insertBefore(this.end,t),e.insertBefore(this.start,this.end),e.insertBefore(this.template,this.end);else e.insertBefore(this.template,t)}remove(){if(this.parentCtx&&((e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)})(this.parentCtx.blocks,this),this.start){const e=this.start.parentNode;let t,n=this.start;for(;n&&(t=n.nextSibling,e.removeChild(n),n!==this.end);)n=t}else this.template.parentNode.removeChild(this.template);this.teardown()}teardown(){this.ctx.blocks.forEach((e=>{e.teardown()})),this.ctx.effects.forEach(K),this.ctx.cleanups.forEach((e=>e()))}}const st=e=>e.replace(/[-.*+?^${}()|[\]\/\\]/g,"\\$&"),rt=e=>{const t=Ye();if(e&&(t.scope=oe(e),tt(t.scope),e.$delimiters)){const[n,s]=t.delimiters=e.$delimiters;t.delimitersRE=new RegExp(st(n)+"([^]+?)"+st(s),"g")}let n;return t.scope.$s=Ce,t.scope.$nextTick=he,t.scope.$refs=Object.create(null),{directive(e,n){return n?(t.dirs[e]=n,this):t.dirs[e]},mount(e){if("string"==typeof e&&!(e=document.querySelector(e)))return;let s;return s=(e=e||document.documentElement).hasAttribute("v-scope")?[e]:[...e.querySelectorAll("[v-scope]")].filter((e=>!e.matches("[v-scope] [v-scope]"))),s.length||(s=[e]),n=s.map((e=>new nt(e,t,!0))),this},unmount(){n.forEach((e=>e.teardown()))}}},it=document.currentScript;return it&&it.hasAttribute("init")&&rt().mount(),e.createApp=rt,e.nextTick=he,e.reactive=oe,Object.defineProperty(e,"__esModule",{value:!0}),e[Symbol.toStringTag]="Module",e}({}); diff --git a/refs/pull/443/merge/it/_static/js/theme.js b/refs/pull/443/merge/it/_static/js/theme.js new file mode 100644 index 000000000..bf36d744c --- /dev/null +++ b/refs/pull/443/merge/it/_static/js/theme.js @@ -0,0 +1,108 @@ + +/** + * We add extra br tags to the autodoc output, so each parameter is shown on + * its own line. + */ +function setupAutodocPy() { + const paramElements = document.querySelectorAll('.py .sig-param') + + Array(...paramElements).forEach((element) => { + let brElement = document.createElement('br') + element.parentNode.insertBefore(brElement, element) + }) + + const lastParamElements = document.querySelectorAll('.py em.sig-param:last-of-type') + + Array(...lastParamElements).forEach((element) => { + let brElement = document.createElement('br') + element.after(brElement) + }) +} + +function setupAutodocCpp() { + const highlightableElements = document.querySelectorAll(".c dt.sig-object, .cpp dt.sig-object") + + Array(...highlightableElements).forEach((element) => { + element.classList.add("highlight"); + }) + + const documentables = document.querySelectorAll("dt.sig-object.c,dt.sig-object.cpp"); + + Array(...documentables).forEach((element) => { + element.classList.add("highlight"); + + var parens = element.querySelectorAll(".sig-paren"); + var commas = Array(...element.childNodes).filter(e => e.textContent == ", ") + + if (parens.length != 2) return; + + commas.forEach(c => { + if (c.compareDocumentPosition(parens[0]) == Node.DOCUMENT_POSITION_PRECEDING && + c.compareDocumentPosition(parens[1]) == Node.DOCUMENT_POSITION_FOLLOWING + ) { + let brElement = document.createElement('br') + let spanElement = document.createElement('span') + spanElement.className = "sig-indent" + c.after(brElement) + brElement.after(spanElement) + } + }); + + if (parens[0].nextSibling != parens[1]) { + // not an empty argument list + let brElement = document.createElement('br') + let spanElement = document.createElement('span') + spanElement.className = "sig-indent" + parens[0].after(brElement) + brElement.after(spanElement) + let brElement1 = document.createElement('br') + parens[1].parentNode.insertBefore(brElement1, parens[1]); + } + }) +} + +function setupSearchSidebar() { + const searchInput = document.querySelector('form.search input[type=text]') + if (searchInput) { + searchInput.placeholder = 'Search...' + } + + const searchButton = document.querySelector('form.search input[type=submit]') + if (searchButton) { + searchButton.value = 'Search' + } +} + +function setupSidebarToggle() { + const sidebar = document.querySelector('.sphinxsidebar') + document.querySelector('#toggle_sidebar a').onclick = (event) => { + console.log("Toggling sidebar") + event.preventDefault() + sidebar.style.display = window.getComputedStyle(sidebar, null).display == 'none' ? 'block' : 'none' + } +} + +function setupRightSidebarToggle() { + const sidebar = document.querySelector('#right_sidebar') + + const links = document.querySelectorAll('a.toggle_right_sidebar') + + Array(...links).forEach((element) => { + element.onclick = (event) => { + console.log("Toggling right sidebar") + event.preventDefault() + sidebar.style.display = window.getComputedStyle(sidebar, null).display == 'none' ? 'block' : 'none' + } + }) +} + + +document.addEventListener("DOMContentLoaded", function() { + console.log("custom theme loaded") + + setupAutodocPy() + setupAutodocCpp() + setupSearchSidebar() + setupSidebarToggle() + setupRightSidebarToggle() +}) diff --git a/refs/pull/443/merge/it/_static/language_data.js b/refs/pull/443/merge/it/_static/language_data.js new file mode 100644 index 000000000..367b8ed81 --- /dev/null +++ b/refs/pull/443/merge/it/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/refs/pull/443/merge/it/_static/minus.png b/refs/pull/443/merge/it/_static/minus.png new file mode 100644 index 000000000..d96755fda Binary files /dev/null and b/refs/pull/443/merge/it/_static/minus.png differ diff --git a/refs/pull/443/merge/it/_static/pkce.py b/refs/pull/443/merge/it/_static/pkce.py new file mode 100644 index 000000000..95e8fe415 --- /dev/null +++ b/refs/pull/443/merge/it/_static/pkce.py @@ -0,0 +1,21 @@ +import hashlib +import base64 +import re + +def get_pkce(code_challenge_method: str = "S256", code_challenge_length: int = 64): + hashers = {"S256": hashlib.sha256} + + code_verifier = base64.urlsafe_b64encode(os.urandom(40)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + code_challenge = hashers.get(code_challenge_method)( + code_verifier.encode("utf-8") + ).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + return { + "code_verifier": code_verifier, + "code_challenge": code_challenge, + "code_challenge_method": code_challenge_method, + } \ No newline at end of file diff --git a/refs/pull/443/merge/it/_static/plus.png b/refs/pull/443/merge/it/_static/plus.png new file mode 100644 index 000000000..7107cec93 Binary files /dev/null and b/refs/pull/443/merge/it/_static/plus.png differ diff --git a/refs/pull/443/merge/it/_static/pygments.css b/refs/pull/443/merge/it/_static/pygments.css new file mode 100644 index 000000000..0d49244ed --- /dev/null +++ b/refs/pull/443/merge/it/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/refs/pull/443/merge/it/_static/searchtools.js b/refs/pull/443/merge/it/_static/searchtools.js new file mode 100644 index 000000000..b08d58c9b --- /dev/null +++ b/refs/pull/443/merge/it/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/refs/pull/443/merge/it/_static/sphinx_highlight.js b/refs/pull/443/merge/it/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/refs/pull/443/merge/it/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/refs/pull/443/merge/it/backup-restore.html b/refs/pull/443/merge/it/backup-restore.html new file mode 100644 index 000000000..679b55bc9 --- /dev/null +++ b/refs/pull/443/merge/it/backup-restore.html @@ -0,0 +1,256 @@ + + + + + + + + backup-restore.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

backup-restore.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/contribute.html b/refs/pull/443/merge/it/contribute.html new file mode 100644 index 000000000..11da7f8b7 --- /dev/null +++ b/refs/pull/443/merge/it/contribute.html @@ -0,0 +1,187 @@ + + + + + + + + contribute.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

contribute.rst

+

Instruction to join in the development here.

+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+ + Standards> + +
+
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/defined-terms.html b/refs/pull/443/merge/it/defined-terms.html new file mode 100644 index 000000000..975ae50e1 --- /dev/null +++ b/refs/pull/443/merge/it/defined-terms.html @@ -0,0 +1,309 @@ + + + + + + + + defined-terms.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

defined-terms.rst

+

Di seguito le descrizioni di acronimi e definizioni, correlati al presente documento utili ad approfondimenti su tematiche che completano l' it-wallet e i componenti con i quali interagisce.

+
+

Acronimi

+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

Acronimo

Descrizione

OID4VP

OpenID for Verifiable Presentation

PID

Person Identification Data

VC

Verifiable Credential

VP

Verifiable Presentation

API

Application Programming Interface. Insieme componenti previsti per semplificare gli scenari di integrazione di uno specifico Sistema.

+
+
+

Definizioni

+ ++++ + + + + + + + + + + + + + +

Definizione

Descrizione

Wallet Instance

Mobile App che gestisce, memorizza e protegge le Verifiable Credentials di un holder e ne consente la presentazione ad una Relying Party

Relying Party

Entità che riceve da una Wallet Instance una o più VP e processa le stesse

+
+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + +
+ + trust.rst> + +
+
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/genindex.html b/refs/pull/443/merge/it/genindex.html new file mode 100644 index 000000000..82a627521 --- /dev/null +++ b/refs/pull/443/merge/it/genindex.html @@ -0,0 +1,181 @@ + + + + + + + Index — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ + +

Index

+ +
+ +
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+ +
+ +
+
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/index.html b/refs/pull/443/merge/it/index.html new file mode 100644 index 000000000..ae1c797a9 --- /dev/null +++ b/refs/pull/443/merge/it/index.html @@ -0,0 +1,341 @@ + + + + + + + + The Italian EUDI Wallet implementation profile — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

The Italian EUDI Wallet implementation profile

+

[TODO INTRO]

+

Introduzione

+

cos'è eIDAS

+

cos’è IT-Wallet

+

scopo delle regole tecniche

+

In this documentation you can find the technical specification +for implementing the following components:

+
+
    +
  • Entities of the ecosystem according to EIDAS-ARF.

  • +
  • Infrastructure of trust attesting realiability and eligibility of the participants.

  • +
  • PID and EAAs data schemes and attribute sets.

  • +
  • PID/EAA in MDL CBOR format.

  • +
  • PID/EAA in SD-JWT format.

  • +
  • Wallet Solution general architecture.

  • +
  • Wallet Instance Attestation data model in JWS format.

  • +
  • Issuance of PID/EAA according to OpenID4VCI.

  • +
  • Presentation of PID/EAA according to OpenID4VP.

  • +
  • Presentation of pseudonyms according to SIOPv2.

  • +
  • PID/EAA backup and restore mechanisms.

  • +
  • PID/EAA revocation lists.

  • +
+
+
+

Index of content

+
+ +
+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+
+ +
+ + +
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/issuance.html b/refs/pull/443/merge/it/issuance.html new file mode 100644 index 000000000..e7dcbd565 --- /dev/null +++ b/refs/pull/443/merge/it/issuance.html @@ -0,0 +1,256 @@ + + + + + + + + issuance.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

issuance.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/objects.inv b/refs/pull/443/merge/it/objects.inv new file mode 100644 index 000000000..63a6cce05 Binary files /dev/null and b/refs/pull/443/merge/it/objects.inv differ diff --git a/refs/pull/443/merge/it/pid-eaa-data.html b/refs/pull/443/merge/it/pid-eaa-data.html new file mode 100644 index 000000000..bbac226fc --- /dev/null +++ b/refs/pull/443/merge/it/pid-eaa-data.html @@ -0,0 +1,256 @@ + + + + + + + + pid-eaa-data.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

pid-eaa-data.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+
+ + + <trust.rst + +
+ + +
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/pid-eaa-mdoc-cbor.html b/refs/pull/443/merge/it/pid-eaa-mdoc-cbor.html new file mode 100644 index 000000000..b75197264 --- /dev/null +++ b/refs/pull/443/merge/it/pid-eaa-mdoc-cbor.html @@ -0,0 +1,256 @@ + + + + + + + + pid-eaa-mdoc-cbor.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

pid-eaa-mdoc-cbor.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/pid-eaa-sd-jwt.html b/refs/pull/443/merge/it/pid-eaa-sd-jwt.html new file mode 100644 index 000000000..a670403ca --- /dev/null +++ b/refs/pull/443/merge/it/pid-eaa-sd-jwt.html @@ -0,0 +1,256 @@ + + + + + + + + pid-eaa-sd-jwt.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

pid-eaa-sd-jwt.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+ +
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/pseudonyms.html b/refs/pull/443/merge/it/pseudonyms.html new file mode 100644 index 000000000..c8c81a21d --- /dev/null +++ b/refs/pull/443/merge/it/pseudonyms.html @@ -0,0 +1,256 @@ + + + + + + + + pseudonyms.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

pseudonyms.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/revocation-lists.html b/refs/pull/443/merge/it/revocation-lists.html new file mode 100644 index 000000000..a7b97d384 --- /dev/null +++ b/refs/pull/443/merge/it/revocation-lists.html @@ -0,0 +1,256 @@ + + + + + + + + revocation-lists.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

revocation-lists.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + +
+ + contribute.rst> + +
+
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/search.html b/refs/pull/443/merge/it/search.html new file mode 100644 index 000000000..6c916fe77 --- /dev/null +++ b/refs/pull/443/merge/it/search.html @@ -0,0 +1,190 @@ + + + + + + + Search — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + +
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+ +
+ +
+
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/searchindex.js b/refs/pull/443/merge/it/searchindex.js new file mode 100644 index 000000000..bf8549751 --- /dev/null +++ b/refs/pull/443/merge/it/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Acronimi": [[2, "acronimi"]], "Attributes": [[0, "attributes"], [2, "attributes"], [4, "attributes"], [5, "attributes"], [6, "attributes"], [7, "attributes"], [8, "attributes"], [9, "attributes"], [10, "attributes"], [12, "attributes"], [13, "attributes"], [14, "attributes"]], "Definizioni": [[2, "definizioni"]], "External references": [[0, "external-references"], [2, "external-references"], [4, "external-references"], [5, "external-references"], [6, "external-references"], [7, "external-references"], [8, "external-references"], [9, "external-references"], [10, "external-references"], [12, "external-references"], [13, "external-references"], [14, "external-references"]], "General Properties": [[0, "general-properties"], [2, "general-properties"], [4, "general-properties"], [5, "general-properties"], [6, "general-properties"], [7, "general-properties"], [8, "general-properties"], [9, "general-properties"], [10, "general-properties"], [12, "general-properties"], [13, "general-properties"], [14, "general-properties"]], "Implementation considerations": [[0, "implementation-considerations"], [2, "implementation-considerations"], [4, "implementation-considerations"], [5, "implementation-considerations"], [6, "implementation-considerations"], [7, "implementation-considerations"], [8, "implementation-considerations"], [9, "implementation-considerations"], [10, "implementation-considerations"], [12, "implementation-considerations"], [13, "implementation-considerations"], [14, "implementation-considerations"]], "Index of content": [[3, "index-of-content"]], "Libraries and code snippets": [[0, "libraries-and-code-snippets"], [2, "libraries-and-code-snippets"], [4, "libraries-and-code-snippets"], [5, "libraries-and-code-snippets"], [6, "libraries-and-code-snippets"], [7, "libraries-and-code-snippets"], [8, "libraries-and-code-snippets"], [9, "libraries-and-code-snippets"], [10, "libraries-and-code-snippets"], [12, "libraries-and-code-snippets"], [13, "libraries-and-code-snippets"], [14, "libraries-and-code-snippets"]], "Requirements": [[0, "requirements"], [2, "requirements"], [4, "requirements"], [5, "requirements"], [6, "requirements"], [7, "requirements"], [8, "requirements"], [9, "requirements"], [10, "requirements"], [12, "requirements"], [13, "requirements"], [14, "requirements"]], "Standards": [[11, null]], "The Italian EUDI Wallet implementation profile": [[3, null]], "backup-restore.rst": [[0, null]], "contribute.rst": [[1, null]], "defined-terms.rst": [[2, null]], "issuance.rst": [[4, null]], "pid-eaa-data.rst": [[5, null]], "pid-eaa-mdoc-cbor.rst": [[6, null]], "pid-eaa-sd-jwt.rst": [[7, null]], "pseudonyms.rst": [[8, null]], "revocation-lists.rst": [[9, null]], "ssi-introduction.rst": [[10, null]], "trust.rst": [[12, null]], "wallet-instance-attestation.rst": [[13, null]], "wallet-solution.rst": [[14, null]]}, "docnames": ["backup-restore", "contribute", "defined-terms", "index", "issuance", "pid-eaa-data", "pid-eaa-mdoc-cbor", "pid-eaa-sd-jwt", "pseudonyms", "revocation-lists", "ssi-introduction", "standards", "trust", "wallet-instance-attestation", "wallet-solution"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2}, "filenames": ["backup-restore.rst", "contribute.rst", "defined-terms.rst", "index.rst", "issuance.rst", "pid-eaa-data.rst", "pid-eaa-mdoc-cbor.rst", "pid-eaa-sd-jwt.rst", "pseudonyms.rst", "revocation-lists.rst", "ssi-introduction.rst", "standards.rst", "trust.rst", "wallet-instance-attestation.rst", "wallet-solution.rst"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"1": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "2": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "IT": 3, "In": 3, "accord": 3, "acronimi": 3, "acronimo": 2, "ad": 2, "al": 2, "all": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "api": 2, "app": 2, "applic": 2, "approfondimenti": 2, "ar": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "architectur": 3, "arf": 3, "attest": 3, "attribut": 3, "backup": 3, "can": 3, "cbor": 3, "che": 2, "claim": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "co": 3, "code": 3, "come": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "completano": 2, "compon": 3, "componenti": 2, "con": 2, "consent": 2, "consider": 3, "contain": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "contenuti": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "contribut": 3, "correlati": 2, "credenti": 2, "da": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "data": [2, 3], "defin": 3, "definizion": 2, "definizioni": 3, "dell": 3, "descript": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "descrizion": 2, "descrizioni": 2, "develop": 1, "di": 2, "document": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "documentazion": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "documento": 2, "e": 2, "eaa": 3, "ecosystem": 3, "eida": 3, "elig": 3, "entiti": 3, "entit\u00e0": 2, "esempi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "exampl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "extern": 3, "find": 3, "follow": 3, "format": 3, "gener": 3, "gestisc": 2, "gli": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "here": 1, "holder": 2, "i": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "identif": 2, "infrastructur": 3, "insiem": 2, "instanc": [2, 3], "instruct": 1, "integrazion": 2, "intendersi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "interagisc": 2, "interfac": 2, "intro": 3, "introduct": 3, "introduzion": 3, "issuanc": 3, "join": 1, "jw": 3, "jwt": 3, "kei": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "l": 2, "la": 2, "le": 2, "librari": 3, "list": 3, "mdl": 3, "mdoc": 3, "meant": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "mechan": 3, "memorizza": 2, "mobil": 2, "model": 3, "ne": 2, "non": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "norm": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "normativi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "o": 2, "oid4vp": 2, "openid": 2, "openid4vci": 3, "openid4vp": 3, "paramet": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "parti": 2, "particip": 3, "per": 2, "person": 2, "pid": [2, 3], "pi\u00f9": 2, "present": [2, 3], "presentazion": 2, "previsti": 2, "processa": 2, "program": 2, "properti": 3, "protegg": 2, "pseudonym": 3, "quali": 2, "questa": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "realiabl": 3, "refer": 3, "regol": 3, "reli": 2, "req": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "requir": 3, "restor": 3, "revoc": 3, "ricev": 2, "rst": 3, "scenari": 2, "scheme": 3, "scopo": 3, "sd": 3, "seguito": 2, "semplificar": 2, "set": 3, "siopv2": 3, "sistema": 2, "snippet": 3, "solut": 3, "sono": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "specif": 3, "specifico": 2, "ssi": 3, "standard": 3, "stess": 2, "su": 2, "tabl": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "technic": 3, "tecnich": 3, "tematich": 2, "term": 3, "thi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "todo": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "trust": 3, "tutti": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "un": 2, "una": 2, "uno": 2, "useful": [0, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "utili": 2, "valu": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "vc": 2, "verifi": 2, "vp": 2, "wallet": 2, "what": [0, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "you": 3, "\u00e8": 3}, "titles": ["backup-restore.rst", "contribute.rst", "defined-terms.rst", "The Italian EUDI Wallet implementation profile", "issuance.rst", "pid-eaa-data.rst", "pid-eaa-mdoc-cbor.rst", "pid-eaa-sd-jwt.rst", "pseudonyms.rst", "revocation-lists.rst", "ssi-introduction.rst", "Standards", "trust.rst", "wallet-instance-attestation.rst", "wallet-solution.rst"], "titleterms": {"The": 3, "acronimi": 2, "attest": 13, "attribut": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "backup": 0, "cbor": 6, "code": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "consider": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "content": 3, "contribut": 1, "data": 5, "defin": 2, "definizioni": 2, "eaa": [5, 6, 7], "eudi": 3, "extern": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "gener": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "implement": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "index": 3, "instanc": 13, "introduct": 10, "issuanc": 4, "italian": 3, "jwt": 7, "librari": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "list": 9, "mdoc": 6, "pid": [5, 6, 7], "profil": 3, "properti": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "pseudonym": 8, "refer": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "requir": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "restor": 0, "revoc": 9, "rst": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "sd": 7, "snippet": [0, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14], "solut": 14, "ssi": 10, "standard": 11, "term": 2, "trust": 12, "wallet": [3, 13, 14]}}) \ No newline at end of file diff --git a/refs/pull/443/merge/it/ssi-introduction.html b/refs/pull/443/merge/it/ssi-introduction.html new file mode 100644 index 000000000..94ebc73d5 --- /dev/null +++ b/refs/pull/443/merge/it/ssi-introduction.html @@ -0,0 +1,256 @@ + + + + + + + + ssi-introduction.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

ssi-introduction.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/standards.html b/refs/pull/443/merge/it/standards.html new file mode 100644 index 000000000..6c56104be --- /dev/null +++ b/refs/pull/443/merge/it/standards.html @@ -0,0 +1,184 @@ + + + + + + + + Standards — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

Standards

+

TODO

+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+ +
+
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/trust.html b/refs/pull/443/merge/it/trust.html new file mode 100644 index 000000000..60a1586a8 --- /dev/null +++ b/refs/pull/443/merge/it/trust.html @@ -0,0 +1,256 @@ + + + + + + + + trust.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

trust.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/wallet-instance-attestation.html b/refs/pull/443/merge/it/wallet-instance-attestation.html new file mode 100644 index 000000000..0040ff63c --- /dev/null +++ b/refs/pull/443/merge/it/wallet-instance-attestation.html @@ -0,0 +1,256 @@ + + + + + + + + wallet-instance-attestation.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

wallet-instance-attestation.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+
+
+ + +
+ + issuance.rst> + +
+
+
+ + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file diff --git a/refs/pull/443/merge/it/wallet-solution.html b/refs/pull/443/merge/it/wallet-solution.html new file mode 100644 index 000000000..4491d7404 --- /dev/null +++ b/refs/pull/443/merge/it/wallet-solution.html @@ -0,0 +1,256 @@ + + + + + + + + wallet-solution.rst — The Italian EUDI Wallet implementation profile version: latest documentation + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
+
+ +
+

wallet-solution.rst

+

[What is it]

+

[What it is usefull for]

+

[Example]

+
+

General Properties

+

[TODO]

+
+
+

Requirements

+
+
    +
  • req 1

  • +
  • req 2

  • +
+
+
+
+

Attributes

+

[Table with parameters/attributes]

+ ++++ + + + + + + + + + + +

Claim

Description

key

value

+
+
+

Implementation considerations

+

TODO

+
+
+

Libraries and code snippets

+

TODO

+
+
+

External references

+

TODO

+
+
+ + +
+
+
+
+ + + + + + +
+
+ + + + + +

Styled using the Piccolo Theme

+ + \ No newline at end of file