Uploaded image for project: 'OpenAM'
  1. OpenAM
  2. OPENAM-10478

kids used by AM for signing are not accessible to developers implementing a remote JWKs URI for AM

    Details

    • Type: Improvement
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 13.5.0, 14.0.0
    • Fix Version/s: None
    • Component/s: oauth2
    • Labels:
    • Sprint:
      AM Sustaining Sprint 34, AM Sustaining Sprint 35, AM Sustaining Sprint 36, AM Sustaining Sprint 37, AM Sustaining Sprint 38, AM Sustaining Sprint 39, AM Sustaining Sprint 40, AM Sustaining Sprint 41, AM Sustaining Sprint 42
    • Story Points:
      3
    • Support Ticket IDs:

      Description

      Description

      AM offers the possibility to configure your own remote URL where the providers JSON Web Key can be retrieved.
      The content behind this URL should be the JWKs set than the provider, AM, will used for encrypting tokens.

      For implementing this, the developer needs to have access to the list of the keys and the kid of each of them. The list of the keys can be done by accessing the keystore directly.
      However, the kid to use for each keys are unknown and therefore, developers that wishes to provide a remove Json web key URL can't do it today.

      What's need to be improved in AM

      AM signs a token, it uses one of the key from the keystore. Let's name this key 'Key_A'.
      At the same time, the developers will generate a JWKS set URI where one of the JWK matches the key 'Key_A'. Let's name this JWK 'JWK_A'.

      AM will need to add the kid of JWK_A when sign with Key_A.

      Solution 1

      AM compute the kid from the 'Key_A' and the developer should use the same algorithm to compute JWK_A.kid.
      Today, the implementation of AM is closer to this solution. The only problem is that the algorithm used by AM to compute the kid is private and is not a random value. The current kid is computed from the key and not a random generated number.

      Solution 2

      The developer specify in the OpenID provider configuration the kid to use for each of the keys in the keystore. Therefore, AM could read this configuration when it needs to insert the kid from a specific key. The key alias would be a good way to reference a key

      Solution 3

      The developer specify in the OpenID provider configuration the kid to use for each of the signing algorithm. The same way, AM can read the provider configuration to get the kid from the current JWS algorithm.

      Solution 3 is possible as AM doesn't offer the possibility to specify more than one key alias by JWS algorithm. So by specifying the JWS algorithm you want to use, AM is able to deduce the key that you actually want to use. The same way, AM will be able to deduce the kid you want to use for a specific JWS algorithm.

      Solution 1 - Possible workaround NOT RECOMMENDED

      I didn't really wanted to mention that workaround but as users have access to source code, I prefer this workaround to be explained by ForgeRock directly rather than you find it yourself:

      In solution 1, the problem is in the kid algorithm accessibility. By doing code inspection or reverse engineering, you may find the actual kid algorithm used by ForgeRock.
      Using a private method is on your own risk, ForgeRock reserves the right to modify this algorithm at any time. ForgeRock won't support this workaround.
      On top of that, our way of computing the kid is not great, and we are aware of it. Therefore, there is a good chance that ForgeRock actually changes it in the future release, sub release, security advisory or even hotfix.
      Implementing this workaround means that you will have to verify that your kid algorithm is still up to date with the version you're installing.

      In my opinion, the right way of fixing this problem, is to wait for solution 2 or 3, which are more likely to be the final solution (even solution 3 I would say).

      I will save you the job of looking at the src code, as I prefer you get it correctly. In 13.5.0, the following algorithm is used:

      RSA:

              String kid = Hash.hash(alias + key.getModulus().toString() + key.getPublicExponent().toString());
      

      EC

              String kid = Hash.hash(alias + ':' + curve.getStandardName() + ':' + x.toString() + ':' + y.toString());
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              quentin.castel Quentin CASTEL [X] (Inactive)
            • Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated: