JOSESwift icon indicating copy to clipboard operation
JOSESwift copied to clipboard

Add support for JWS unencoded detached payloads

Open visav-tietoevry opened this issue 2 years ago • 1 comments

Summary

Add option to skip base64url encoding of payload in JWS. This results in a compact serialization with detached payload.

Motivation for not encoding the payload is further described in RFC-7797 JSON Web Signature (JWS) Unencoded Payload Option.

One example use case where unencoded payload is needed is implementing JsonWebSignature2020 for JSON-LD document proofs. In this case, JWS is used as a signature, and the document itself is not embedded in the JWS. This suite takes JSON-LD document & it's proof without signature, does some steps to normalize them, computes SHA-256 digests, concatenates them and forms a JWS from this result, without using base64url encoding. Finally, resulting JWS is added to the document proof segment, without payload. Verifying end can then reproduce the steps to create the payload for JWS and verify the signature.

Changes

  • Add "b64" header parameter support to JWSHeader to enable unencoded payload
  • Replace asJOSESigningInput() with JWSSigningInput struct, which now contains the logic for signing input, controlled by "b64" header parameter
  • Add support for initializing JWS with detached payload, to enable verification of (unencoded) detached payloads

Caveats

  • Due to Unencoded Payload Content Restrictions, compact serialization of JWS with "b64" header parameter always yields a serialization with a detached payload. This was a choice to limit the scope of the PR to get minimum viable support for unencoded payload option.

Remarks

Following tests were failing for me at master (d542b31):

  • testDecryptingAliceSecretWithBobKey()
  • testDecryptingBobSecretWithAliceKey()

These test failures are not related to changes in this PR.

Tests

I found it a bit difficult to find a proper home for the unit tests of the added JWS functionality, so I chose to make a new test case class, JWSUnencodedPayloadTests, which was arbitrarily inherited from ECCryptoTestCase to get the required dependencies for signing & verifying.

I think these unit tests should be agnostic of the signature algorithm, but I couldn't find an easy way to do so without doing some bigger refactoring. If there's a simple way to mock Signer, please let me know.

visav-tietoevry avatar Apr 27 '22 13:04 visav-tietoevry