Subject: [jose] Comment on typ and cty

From: Samuel Erdtman <[email-masked]>
Date: Sun, 12 May 2013 00:10:52 +0200

Hi
I have just read through all the JOSE drafts and it has been a pleasure,
well done!

I would like to try to contribute with a suggestion. you might already have
thought of this, if so please tell me (I have not looked through the
mailing list archive in detail).

When I read the drafts I think that it is confusing how to determine that
we are looking at a JWT, JWE, JWS or JWK (maybe not so much the last one).
I know that I can read about this in section "4. JWE Header" in the JWE
specification but that is derived information i.e. interpretation of the
values (alg) to get the type. I would like to make more use of the typ
header in JWE/JWS and in the JWT move it form the header to the body. Then
I would like to make the use of cty header in JWE/JWS mandatory, since they
always have content. For the JWT I think we should remove cty, since it
does not have any content, the JWT is content. By removing typ and cty from
JWT header the JWT would have no header in it self. By doing this it would
be easy to detect the type by looking at the typ value and the cty value to
get the type of the unpacked content. I think this would simplify the
implementations. I also think this would simplify how to look at the JWT if
it has no header since it is not really needed, and last but not least
{"alg":"none"} could be removed, since it could be done by sending a JWT
without a header. This was a quick explanation I will try to flesh it out a
bit to make it simpler to follow.

First I think that it is confusing that the JWT has a header. The
attributes in the JWT header are typ and cty. Where cty is not recommended
to use (in normal cases) and typ would be more suitable in the body. if typ
would be moved to the body the head could identify the JWE/JWS instead, now
it looks like this for the JWT and the if it is a JWE or a JWS has to be
derived form alg:
{"typ":"JWT",
 "alg":"HS256"}
>From my perspective it would be clearer if it looked like this:
{"typ":"JWS",
 "cty":"JWT",
 "alg":"HS256"}

For unsigned and unencrypted JWT it seems like the current construct has
forced the {"alg":"none"} solution. If the JWT would just be a set of
attributes including {"typ":"JWT"} that construct would not be needed. An
unsigned and unencrypted JWT could look like this, simply no header:
.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.

Nesting a signed and encrypted JWT could look like this:
Most outer header:
{"typ":"JWE",
 "cty":"JWS",
 "alg":"RSA-OAEP",
 "enc":"A256GCM"}
Next header:
{"cty":"JWT",
 "alg":"HS256"}
Then there is just the JWT within the JWS, e.g.:
{"iss":"joe",
 "exp":1300819380,
 "http://example.com/is_root":true}
By doing it this way it is simple to look at the first layer and see that
it is a JWE (on the typ), decrypt it and do all the verifications. When
starting to process the second layer we know it is a JWS that we will
process (possible a JWS-JS) since it was mentioned in the outer layer by
cty. Finally when we have verified the JWS we know that the content is a
JWT so we know how to parse it before we start. As you can see typ is only
needed for the most outer layer then the cty will describe the next layer.

To summarise the changes
* Add typ to JWT body to be used when there is a unsigned and unencrypted
JWT
* Make cty REQUIRED in JWS and JWE since they will always have content
* Make typ REQUIRED for the outer most JWE or JWS, If it is just a JWT make
it mandatory for it.
* Remove header from JWT, the typ has been moved to the body and the cty is
not needed.
* Remove {"alg":"none"}

If you think this would be a good change I could create diff with the
changes.

Best Regards
Samuel Erdtman