OpenID4VCI icon indicating copy to clipboard operation
OpenID4VCI copied to clipboard

clarifications about the uniqueness of the c_nonce value

Open peppelinux opened this issue 1 year ago • 5 comments
trafficstars

This PR aims to resolve part of the points contained in the issue: https://github.com/openid/OpenID4VCI/issues/313#issuecomment-2121942187

peppelinux avatar May 22 '24 13:05 peppelinux

FYI: The following is my intepretation when I implemented c_nonce.

  • Uniqueness: When a server issues a new c_nonce, its value must differ from any previously issued c_nonce values.
  • Multiple Use: A wallet can use a c_nonce value multiple times until the server rejects it.
  • Issuance Timing: A c_nonce in a server response is not always new. Including a c_nonce in the response does not necessarily mean a new one has been issued. In other words, the server may include the latest valid c_nonce it issued to the wallet in the past instead of issuing a new one.

TakahikoKawasaki avatar May 27 '24 10:05 TakahikoKawasaki

@TakahikoKawasaki ILGTM with the following notes in addition where we aim to define the cases where the exceptions may occur:

  1. Uniqueness: indeed. Perfect to me.
  2. Multiple Use: A Wallet may reuse a c_nonce value until the server rejects it due to invalidation or prior use.
  3. Issuance Timing: A c_nonce in a server response should generally be new. However, there are scenarios where a response may not contain a new nonce, such as when the previously issued nonce has not yet been used by the Wallet.

peppelinux avatar May 27 '24 12:05 peppelinux

@peppelinux Unless I misread the specification or it has changed since I last read it, the specification does not require the one-time use of c_nonce.

The OID4VCI specification may require the one-time use of c_nonce, but before making that decision, it would be advisable to ask experts why Section 8.2, "Providing a New Nonce Value", of RFC 9449, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", specifically states the following:

It is up to the authorization server when to supply a new nonce value for the client to use. The client is expected to use the existing supplied nonce in DPoP proofs until the server supplies a new nonce value.

TakahikoKawasaki avatar May 27 '24 16:05 TakahikoKawasaki

@TakahikoKawasaki Not sure that I understood the different between Uniqueness and Issuance Timing. My current understanding from the spec is that:

  • A server (AS or Credential Issuer) MAY return the same c_nonce on more than one response.
  • A client SHOULD (MUST?) use the same c_nonce on multiple requests, until a different c_nonce is present on a server response.

This requirements allows the use of "stateless" nonces, composed by a signed server timestamp. which ensure the nonce usage by the client happened in a given time window.

pmhsfelix avatar May 27 '24 17:05 pmhsfelix

@pmhsfelix

Pseudo server-side code explaining MULTIPLE USE and UNIQUENESS

// Determine the c_nonce value to be embedded in the server response.
String prepare_c_nonce_embedded_in_server_response(String current_c_nonce)
{
    // If the current c_nonce has not expired yet.
    if (is_c_nonce_expired(current_c_nonce) == false)
    {
        // MULTIPLE USE
        // Allow the wallet to continue to use the current c_nonce.
        return current_c_nonce;
    }

    // UNIQUENESS
    // Generate a new c_nonce whose value has never been used previously.
    return generate_new_c_nonce();
}

Pseudo server-side code explaining ONE-TIME USE and UNIQUENESS

// Determine the c_nonce value to be embedded in the server response.
String prepare_c_nonce_embedded_in_server_response(String current_c_nonce, boolean consumed)
{
    // ONE-TIME USE
    // If the current c_nonce has been consumed.
    if (consumed)
    {
        // UNIQUENESS
        // Generate a new c_nonce whose value has never been used previously.
        return generate_new_c_nonce();
    }

    // If the current c_nonce has expired.
    if (is_c_nonce_expired(current_c_nonce))
    {
        // A new c_nonce needs to be issued because the current one has expired.

        // UNIQUENESS
        // Generate a new c_nonce whose value has never been used previously.
        return generate_new_c_nonce();
    }

    // The current c_nonce is valid until it is consumed.
    return current_c_nonce;
}

TakahikoKawasaki avatar May 28 '24 07:05 TakahikoKawasaki

This one has been sitting stalled for a while - to keep the PR list to things we are actively wanting people to look at I'll closed it - please feel free to continue discussion on https://github.com/openid/OpenID4VCI/issues/313 or please do reopen if you think it can be un-stalled.

jogu avatar Sep 27 '24 09:09 jogu