Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update of the wallet provider APIs / Initalisation, authentication and configuration update #2704

Open
ThierryThevenet opened this issue Jun 3, 2024 · 4 comments
Assignees

Comments

@ThierryThevenet
Copy link
Member

ThierryThevenet commented Jun 3, 2024

IN PROGRESS

This ticket is the first of a series to improve the current APIs between the wallet and the wallet provider back end with a 2FA authentication and allow the use of remote keys (HSM). Wallet uses a long life hardware key as first factor and a derivation of the user PIN as a second factor. In this process the wallet is not considered as a trusty device from the wallet provider standpoint and so after the initialization process, the PIN code is checked by the wallet provider back end for each authentication.

Generally speaking different keys are used in the wallet :

  • P-256 keys to authenticate to the wallet provider backend (only hardware device keys)
  • keys for wallet attestations (hardware device or remote HSM keys)
  • keys for credentials (software or hardware device or remote HSM)

For this implementation, wallet attestation key will be a P-256 hardware device key.

The APIs specified in this ticket are :

  • /challenge
  • /Initialisation
  • /token
  • /update-configuration

Other tickets specify other APIs :

User can log as GUEST and in that case the login is an email starting with "guest@". As GUEST, user cannot access the following APIs :

  • /update-attestation
  • /update-pin
  • /generate-key
  • /sign

Check the different flows https://swimlanes.io/u/Rt5vg-FWI

User initializes the wallet

  1. User scans QR code provided by the wallet-provider back end to configure the wallet

Example :
configuration://[email protected]&password=KJHGFT&walett-provider=https://wlallet-provider.talao.co

Password will be only used in this initialisation process but wallet provider URL and login must be saved and attached to the wallet instance life time.

  1. Wallet calls the nonce endpoint

This API is opened to GUESTs.

From the wallet provider standpoint the nonce is the session identifier, the lifetime of the nonce is no more than 20 sec. The nonce is a 32 bytes random. This endpoint is exposed by the wallet provider back end without any protection but eventually with a rate limit.

GET /challenge HTTP/1.1
Host: wallet-provider.talao.co 
Accept: 'application/json'

response is a json

HTTP/1.1 200 OK
Content-Type: application/json

{
  "nonce": "d2JhY2NhbG91cmVqdWFuZGFt"
}
  1. Wallet requests user to enter PIN code

For this process PIN code is checked by the wallet to be sure it is the PIN code of the app.

  1. Wallet calls the initialisation endpoint

Parameters are added to the body of the POST request.

  • Wallet generates a hardware P-256 key from the device secure element to manage the authentication with the wallet provider back end. This key is attached to the wallet instance life time. It will be used later to get a token each time the wallet needs to access the wallet provider back end. The pub key is transferred in the jwk attribute of the body of the call.

  • Wallet generates a salt as a 32 bytes random stored in the secure storage and attached to the wallet instance life time.

  • The PIN code + salt are concatenated and hashed (sha256) then added to the wallet assertion as 'salted_pin_code. It will be necessary to recalculate the salted_pin_code each time it is needed.

  • Wallet generates a wallet attestation P-256 hardware key from the device secure element. This key certificate is provided by the secure element and added as key_attestation. This key is not attached to the wallet instance life time as the wallet can generate a new attestation if needed.

  • The login and password of the initial QR code are provided. Password does not need to be stored in the wallet as it could be updated later on directly in the wallet provider back end by the user.

Example of the call

POST /initialisation HTTP/1.1
Host: wallet-provider.talao.co 
Content-Type: 'application/x-www-form-urlencoded'

 nonce=nonce
 &salted_pin_code=<hash256(PIN code + salt)
 &key_attestation=o2NmbXRvYXBwbGUtYXBw
 &[email protected]
 &password=KJHGFT
 &jwk= '{
             "kty":"EC",
              "crv":"P256",
              "x":"BL2ueJxeRMpOdaqitOHeQQ0x5AnUBPG5nAzJa8D1KhQ",
              "y":"bHET7kx6NT9HgDmNXhRoi5_I6yegxQEd2qAcXQ_jdM-"
          }'

In response wallet receives the wallet attestation and the wallet configuration in a json :

HTTP/1.1 201 OK
Content-Type: application/json

{
    wallet-attestation" : "eyJhbGciOiIUYYUzI1NiIsInR5cCI6IndhbGx... ",
    wallet-configuration" : "eymkjhlkjhmgmjmkjh...."
}

The configuration is a jwt signed by the wallet provider back end.

The configuration file has a new attribute walletFor to specify if the wallet is used as an individual wallet (default as today) or a business wallet.
"walletFor": "np" for natural person (individual wallet)
"walletFor": "lp" for legal person (business wallet)

Example of an extract of configuration file:

{
    "version": "2.0",
    "generalOptions": {
        "walletType": "altme",
        "walletFor": "np",
        "companyName": "Altme",
        .....

For Business wallets (legal person) the data needed for the wallet is provided in the companySignature nested json of the configuration file

Example of an extract of the configuration file for a company using a DID on Ethereum


  "companySignature": {
        "client_id": "did:ethr:0x1356744765ACD56756",
         "kid": "did:ethr:0x1356744765ACD56756#key-1",
         "jwk" : null
    },

Example of an extract of the configuration file for a company using a HSM key


  "companySignature": {
        "client_id": "talao",
         "kid": "mjhmkjh65765Mlk",
          "jwk" : {
             "kty":"EC",
              "crv":"P256",
              "x":"BL2ueJxeRMpOdaqitOHeQQ0x5AnUBPG5nAzJa8D1KhQ",
              "y":"bHET7kx6NT9HgDmNXhRoi5_I6yegxQEd2qAcXQ_jdM-"
        }
    },

The wallet attestation is a jwt signed by the wallet provider back end.

Example of a wallet attestation signed by the wallet provider backend.

  {
  "alg": "ES256",
  "kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY",
  "x5c": [....],
  "typ": "wallet-attestation+jwt",
}
.


{
  "iss": "https://wallet-provider.example.org",
  "sub": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
  "jti": "urn:123456",
   "status": {
            "status_list": {
                "idx": 45678,
                "uri": "https://talao.co/sandbox/issuer/statuslist/1"
            }
        },
  "cnf":
  {
    "jwk":
    {
      "crv": "P-256",
      "kty": "EC",
      "x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44",
      "y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg",
      "kid": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c"
    }
  },
  "key_type": "software",
  "user_authentication": "system_biometry",
  "authorization_endpoint": "https://app.altme.io/app/download/authorize",
  "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
}

Wallet provider back end must check login/password of the user and associate hardware key for authentication and salted PIN code to the user data.

Wallet authenticates with the wallet provider backend

This API is opened to GUESTs.

  1. Wallet requests to user the PIN code

  2. Wallet calls the token endpoint

Wallet uses client_secret_jwt method to authenticate see https://datatracker.ietf.org/doc/html/rfc7523 to get a bearer token bound to the wallet provider authentication key. The jwt is called assertion below and provides the hardware key as first factor and the salted pin code for second factor.

Wallet uses the hardware P-256 key generated at initialisation to manage the authentication with the wallet provider back end. It will be used to get a token each time the wallet needs to access the wallet provider back end services. The token issued through this endpoint is bound to that key for future use. This key is the attribute jwk of the assertion payload. The assertion is signed with this key through the secure element of the smartphone.

The PIN code + salt is transformed by sha256 and added to the wallet assertion 'salted_pin_code as previously. The salted pin code is not stored in the wallet.

The user login is passed in the assertion, password is not needed.

The life time of the assertion is no more than 10 sec (exp - iat).

POST /token HTTP/1.1
Host: wallet-provider.talao.co 
Content-Type: 'application/x-www-form-urlencoded'

client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer".
&client_assertion = <assertion>

Example of an assertion payload and header

{
        "alg": "ES256",
         "typ": "JWT",
         "jwk": {
             "kty":"EC",
              "crv":"P256",
              "x":"BL2ueJxeRMpOdaqitOHeQQ0x5AnUBPG5nAzJa8D1KhQ",
              "y":"bHET7kx6NT9HgDmNXhRoi5_I6yegxQEd2qAcXQ_jdM-"
          }
}

{
        "iss": <client_id>,
         "sub": <client_id>,
         "aud": "https://wallet-provider.talao.co",
        "iat": 1717590924,
        "exp": 1717700924,
        "nonce": <nonce>,
        "salted_pin_code" : <hash256(PIN code + salt)>,
        "login"; "[email protected]"
 }

Wallet receives a short life bearer token bound to its key. The life time of the token is 5 minutes.

NB : if the token is a jwt it must be encrypted (jwe).


HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

  {
    "access_token": "JhbGciOiJSUzI1NiIsInR5cCI6sHQ",
    "token_type": "bearer",
    "expires_in": 300,
}

If the salted_pin_code or authentication key do not fit with what has been stored the user data base at initialisation, the token endpoint return a 401 unauthorized response. User can make 3 trials maximum with new PIN code.

For GUEST, the wallet provider back end does not need to check the salted_pin_code and authentication key as they are not stored but the issued token will be restricted to a few APIs.

User updates wallet configuration

This API is opened to GUESTs.

  1. User clics on "Update the configuration"
  2. Wallet calls nonce endpoint
  3. Wallet authenticates to the wallet provider back end to get a bearer token
  4. Wallet calls /update-configuration endpoint with the bearer token and a DPoP

DPoP (Demonstrating Proof of Possession) is a jwt transferred through the header of the POST request. It is used to avoid a leak of the access token as it proves that the wallet still owns the key attached to the Bearer token.
DPoP life time is very short (10 sec). DPoP is recalculated each time as it is single use.

See DPoP specifications if needed : https://www.rfc-editor.org/rfc/rfc9449.html

DPoP specific attributes :
jwk: the key used to get the token (wallet provider back end authentication key)
htm: "POST"
htu: url of the endpoint (https://wallet-provider.talao.co/update-configuration)
ath: the sha256 hash of the access token

DPoP is signed by the wallet provider back end authentication key.

Example of the DPoP :

{
      "alg": "ES256"
      "typ": "dpop+jwt"
      "jwk": {
             "kty":"EC",
              "crv":"P256",
              "x":"BL2ueJxeRMpOdaqitOHeQQ0x5AnUBPG5nAzJa8D1KhQ",
              "y":"bHET7kx6NT9HgDmNXhRoi5_I6yegxQEd2qAcXQ_jdM-"
          }
}
.
{
      "ath": < hash sh256 of the access token>
      "htm": "POST",
      "htu": "https://wallet-provider.talao.co/update-configuration",
      "exp":1300819380,
      "jti": <random>
}

No data are transferred in the body of the call for this endpoint.

Example of the call to the update-configuration endpoint :

POST /update-configuration HTTP/1.1
Host: wallet-provider.talao.co 
Authorization: Bearer <token>
DPoP : eylkjglkjhdlkjhlkjhhjkljhlkjhlkjhgvsmkjhlkjlkj...
Content-Type: 'application/x-www-form-urlencoded'

Wallet provider back end responds with new configuration (200) or unauthorized (401) .

Example :

HTTP/1.1 200 OK
Content-Type: application/jwt

eyJhbGciOiJFUzI1NiIsInR5cCI6IndhbGx... 

Wallet applies the new configuration.

@ThierryThevenet ThierryThevenet changed the title Request ¨PIN code to get the wallet attestation or update cioinfiguratioj Integrate a strong authentication process (2FA) between the wallet instance and the wallet provider. Jun 3, 2024
@ThierryThevenet ThierryThevenet self-assigned this Jun 3, 2024
@ThierryThevenet ThierryThevenet changed the title Integrate a strong authentication process (2FA) between the wallet instance and the wallet provider. Signature on behalf of a company Jun 5, 2024
@ThierryThevenet ThierryThevenet changed the title Signature on behalf of a company Business wallets (user acts on behalf of a company) Jun 5, 2024
@ThierryThevenet ThierryThevenet changed the title Business wallets (user acts on behalf of a company) Update of interface with portal and Business wallets (user acts on behalf of a company) Jun 5, 2024
@ThierryThevenet ThierryThevenet changed the title Update of interface with portal and Business wallets (user acts on behalf of a company) Update of APIs with portal and Business wallets (user acts on behalf of a company) Jun 5, 2024
@ThierryThevenet ThierryThevenet changed the title Update of APIs with portal and Business wallets (user acts on behalf of a company) Update of wallet provider APIs and Business wallets (user acts on behalf of a company) Jun 5, 2024
@ThierryThevenet ThierryThevenet changed the title Update of wallet provider APIs and Business wallets (user acts on behalf of a company) Update of the wallet provider APIs and Business wallets management (user acts on behalf of a company) Jun 5, 2024
@patatoid
Copy link

patatoid commented Jun 7, 2024

I think using bearer tokens force to perform authorization at each signature, since we do not have an OAuth server that would help to obtain such tokens, using the instance key pair for authorization would be better.

The securitization of the endpoints may be made using DPoP at first, adding the pin code later on. https://datatracker.ietf.org/doc/html/rfc9449 making the requests looking like:

POST /sign HTTP/1.1
Host: wallet-provider.talao.co 
DPoP: eyJ0eXAiOiJk...
Content-Type: 'application/x-www-form-urlencoded'

message = <base64 url safe (message)>

where the DPoP would be signed with the instance private key and verified with the public key obtained while performing the wallet attestation flow. The payload of the DPoP looking like:

{
  "jti":"-BwC3ESc6acc2lTc",
  "htm":"POST",
  "htu":"https://wallet-provider.talao.co/sign",
  "iat":1562262616
}

We would even add the salted pin code to this which would help by having a second factor.

The wallet attestation flow is from a standard, we should keep it as close to the specification as possible.

@ThierryThevenet
Copy link
Member Author

ThierryThevenet commented Jun 8, 2024

utiliser une autre clé que celle de l attestation pour l'authentificaion au portail
pour eventuellement pourvoir gerer des attestations de wallet single use (eudi wallet np)

@ThierryThevenet
Copy link
Member Author

remove the basic aith as the login/password could be changed by user with wallet

@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider APIs and Business wallets management (user acts on behalf of a company) Update of the wallet provider APIs / Initalisation Jun 10, 2024
@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider APIs / Initalisation Update of the wallet provider APIs / Initalisation and update configuration Jun 10, 2024
@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider APIs / Initalisation and update configuration Update of the wallet provider backend APIs / Initalisation and update configuration Jun 10, 2024
@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider backend APIs / Initalisation and update configuration Update of the wallet provider backend APIs / Initalisation, token and update configuration Jun 11, 2024
@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider backend APIs / Initalisation, token and update configuration Update of the wallet provider backend APIs / Initalisation, authetication and update configuration Jun 11, 2024
@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider backend APIs / Initalisation, authetication and update configuration Update of the wallet provider backend APIs / Initalisation, authentication and update configuration Jun 11, 2024
@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider backend APIs / Initalisation, authentication and update configuration Update of the wallet provider backend APIs / Initalisation, authentication and configuration update Jun 12, 2024
@ThierryThevenet ThierryThevenet changed the title Update of the wallet provider backend APIs / Initalisation, authentication and configuration update Update of the wallet provider APIs / Initalisation, authentication and configuration update Jun 12, 2024
@ThierryThevenet
Copy link
Member Author

Probleme du GUEST

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants