oauth-wg / oauth-selective-disclosure-jwt

https://datatracker.ietf.org/doc/draft-ietf-oauth-selective-disclosure-jwt/
Other
54 stars 27 forks source link

Clarify algorithms for recursive disclosures #431

Closed bifurcation closed 17 hours ago

bifurcation commented 1 month ago

Fixes #372

There are three algorithms to consider when it comes to recursive disclosures:

  1. How the issuer generates the recursive disclosures
  2. How the holder selects disclosures to reveal in the context of recursion
  3. How the verifier unwinds recursive disclosures

(3) is adequately covered in the verification algorithm. The other two are currently uncovered. This PR clarifies (1) and (2).

Algorithm (1) doesn't really need formal definition for interoperability; an issuer can follow any process that ends up with an SD-JWT that will verify. However, it's useful to (1) provide an illustration, (2) provider a reminder that you have to go from most-specific redaction to least, from the leaves of the AST toward the issuer-signed claims, and (3) provide a clear requirement that an SD-JWT must contain any intermediate recursive disclosures. This PR adds a section that does these things.

For algorithm (2), I simply added a step to the holder processing that verifies that the disclosure selection process got all the required disclosures (including the intermediate ones). We could also be more prescriptive, providing a concrete algorithm that adds the required intermediate disclosures.

bifurcation commented 1 month ago

This is based on #394, which has accreted quite the pile of commits. Until that is merged and this PR is rebased, it's probably best to look at the last commit, which is the only new commit in this branch.

danielfett commented 3 weeks ago

Please rebase/merge main and resolve conflicts.

bc-pi commented 3 weeks ago

Please rebase/merge main and resolve conflicts.

just what the doctor ordered

Sakurann commented 3 weeks ago

Please rebase/merge main and resolve conflicts.

just what the doctor ordered

done

bc-pi commented 1 week ago

putting this here for posterity

        String[] disclosuresContent = new String[]
        {
                "[\"16_mAd0GiwaZokU26_0i0h\",\"DE\"]",
                "[\"fn9fN0rD-fFs2n303ZI-0c\",\"FR\"]",
                "[\"YIKesqOkXXNzMQtsX_-_lw\",\"UK\"]",
                "[\"4drfeTtSUK3aY_-PF12gcX\",\"nationalities\",\n" +
                "    [\n" +
                "        { \"...\": \"PmnlrRjhLcwf8zTDdK15HVGwHtPYjddvD362WjBLwro\" },\n" +
                "        { \"...\": \"r823HFN6Ba_lpSANYtXqqCBAH-TsQlIzfOK0lRAFLCM\" },\n" +
                "        { \"...\": \"nP5GYjwhFm6ESlAeC4NCaIliW4tz0hTrUeoJB3lb5TA\" }\n" +
                "    ]\n" +
                "]"
        };

        for (String disclosureContent : disclosuresContent)
        {
            String disclosure = Base64Url.encodeUtf8ByteRepresentation(disclosureContent);
            MessageDigest messageDigest = HashUtil.getMessageDigest(HashUtil.SHA_256);
            byte[] digestBytes = messageDigest.digest(disclosure.getBytes(StandardCharsets.UTF_8));
            System.out.println(" content    " + disclosureContent);
            System.out.println(" disclosure " + disclosure);
            System.out.println(" digest     " + Base64Url.encode(digestBytes));
            System.out.println();
        }