-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
jwt: add functions to parse a token #75924
base: main
Are you sure you want to change the base?
Conversation
blemouzy
commented
Jul 16, 2024
- Add a new function jwt_parse_payload to parse token payload
- Add a new function jwt_verify to verify token header and signature
0aa1230
to
1aa0cab
Compare
1aa0cab
to
2cce404
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is largely reasonable, but the strn*
usages are not correct.
subsys/jwt/jwt.c
Outdated
} | ||
builder_header = builder.base; | ||
builder_header_len = builder.buf - builder.base; | ||
res = strncmp(parser->header, builder_header, builder_header_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not correct, the strncmp will only check that the builder_header
matches a prefix of parser->header
. Is there a concern that the builder somehow didn't get a terminating nul?
Frankly, in this case, just use strcmp, since you are controlling the builder, and the buffer should always have the null termination.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a concern that the builder somehow didn't get a terminating nul?
Yes, there is.
jwt_init_parser
uses strchr
to find payload and signature positions in the token but .
(dot separators) are not overwrittent by \0
to avoid modifying the original jwt
input string.
So in tests/subsys/jwt/src/main.c
example:
jwt = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpb3Qtd29yay0xOTk0MTkiLCJleHAiOjE1MzAzMTIwMjYsImlhdCI6MTUzMDMwODQyNn0.VHKDT-dvWW3UDBGokkttP7P6DNDnd4jjz_wLsOvn9RVBoDAAVG1mQnlROPtOHyRTotWzFYf2g02-VyZoh326yDFXM-66U7ycqyUsJdWBZWYqub6iZ17l0hjodoSpZBJqPB6F9c8Q5u9x1gWVw2l2XNASQyTDIZ3db_GiQbx1SYnNtyxsospoKClIebee-EQkcut9jBPNyiKrzZRPuX0xCiPJYTumHdHSp0UPIDIij2hJl_tacXs-hz_ckqT5HZvJPsxgJCeXz3tP7IlgbeGbPFMFmaYNX4UxYD4XS10MPXUK4_qp8wK4EqjT2YBNF7xXi_sjWMj7isc0i0YSIl6_nQ"
| | |
header payload sign
parser->header = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpb3Qtd29yay0xOTk0MTkiLCJleHAiOjE1MzAzMTIwMjYsImlhdCI6MTUzMDMwODQyNn0.VHKDT-dvWW3UDBGokkttP7P6DNDnd4jjz_wLsOvn9RVBoDAAVG1mQnlROPtOHyRTotWzFYf2g02-VyZoh326yDFXM-66U7ycqyUsJdWBZWYqub6iZ17l0hjodoSpZBJqPB6F9c8Q5u9x1gWVw2l2XNASQyTDIZ3db_GiQbx1SYnNtyxsospoKClIebee-EQkcut9jBPNyiKrzZRPuX0xCiPJYTumHdHSp0UPIDIij2hJl_tacXs-hz_ckqT5HZvJPsxgJCeXz3tP7IlgbeGbPFMFmaYNX4UxYD4XS10MPXUK4_qp8wK4EqjT2YBNF7xXi_sjWMj7isc0i0YSIl6_nQ"
parser->header_len = 36
parser->payload = "eyJhdWQiOiJpb3Qtd29yay0xOTk0MTkiLCJleHAiOjE1MzAzMTIwMjYsImlhdCI6MTUzMDMwODQyNn0.VHKDT-dvWW3UDBGokkttP7P6DNDnd4jjz_wLsOvn9RVBoDAAVG1mQnlROPtOHyRTotWzFYf2g02-VyZoh326yDFXM-66U7ycqyUsJdWBZWYqub6iZ17l0hjodoSpZBJqPB6F9c8Q5u9x1gWVw2l2XNASQyTDIZ3db_GiQbx1SYnNtyxsospoKClIebee-EQkcut9jBPNyiKrzZRPuX0xCiPJYTumHdHSp0UPIDIij2hJl_tacXs-hz_ckqT5HZvJPsxgJCeXz3tP7IlgbeGbPFMFmaYNX4UxYD4XS10MPXUK4_qp8wK4EqjT2YBNF7xXi_sjWMj7isc0i0YSIl6_nQ"
parser->payload_len = 79
parser->sign = "VHKDT-dvWW3UDBGokkttP7P6DNDnd4jjz_wLsOvn9RVBoDAAVG1mQnlROPtOHyRTotWzFYf2g02-VyZoh326yDFXM-66U7ycqyUsJdWBZWYqub6iZ17l0hjodoSpZBJqPB6F9c8Q5u9x1gWVw2l2XNASQyTDIZ3db_GiQbx1SYnNtyxsospoKClIebee-EQkcut9jBPNyiKrzZRPuX0xCiPJYTumHdHSp0UPIDIij2hJl_tacXs-hz_ckqT5HZvJPsxgJCeXz3tP7IlgbeGbPFMFmaYNX4UxYD4XS10MPXUK4_qp8wK4EqjT2YBNF7xXi_sjWMj7isc0i0YSIl6_nQ"
parser->sign_len = 342
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That may be the case, but the strncmp is still incorrect, as it only compares the prefix. e.g. strncmp("Hello", "HelloWorld", 5) == 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two possibilities. Change the dot to a \0
and then put it back. Or do something complicated that does the comparison. If you know where the dot was you could check the length manually, and if equal, just do a memcmp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That may be the case, but the strncmp is still incorrect, as it only compares the prefix. e.g.
strncmp("Hello", "HelloWorld", 5) == 0
.
Understood.
If you know where the dot was you could check the length manually, and if equal, just do a memcmp.
I added this check.
subsys/jwt/jwt.c
Outdated
return -ENOSPC; | ||
} | ||
/* -1/+1 to also copy the dot */ | ||
strncpy(builder.buf, parser->payload - 1, parser->payload_len + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise here, strncpy
is definitely not the right thing to use, as it can leave the buffer not terminated. In this particular case, it always leave the buffer non-terminated. I'd just use memcpy
of the given length, and place the terminating nul manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, changed
subsys/jwt/jwt.c
Outdated
return res; | ||
} | ||
builder_sign_len = builder.buf - builder_sign; | ||
res = strncmp(parser->sign, builder_sign, builder_sign_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise here, we have control over the builder, so we know if is terminated (you would return errors if it doesn't fit), so just use strcmp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, changed
6636ea3
to
84f3fd8
Compare
subsys/jwt/jwt.c
Outdated
} | ||
builder_header = builder.base; | ||
builder_header_len = builder.buf - builder.base; | ||
res = strncmp(parser->header, builder_header, builder_header_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two possibilities. Change the dot to a \0
and then put it back. Or do something complicated that does the comparison. If you know where the dot was you could check the length manually, and if equal, just do a memcmp.
- Use base64url instead of base64 to explicitly show that Base64URL is used and not Base64 - Add encode suffix to prepare JWT verify function introduction Signed-off-by: Benjamin Lemouzy <blemouzy@centralp.fr>
84f3fd8
to
34de574
Compare
- Add a new function jwt_parse_payload to parse token payload - Add a new function jwt_verify to verify token header and signature Signed-off-by: Benjamin Lemouzy <blemouzy@centralp.fr>
Fix 'WARNING: Violation to rule 21.2 (Should not used a reserved identifier) - exp' Signed-off-by: Benjamin Lemouzy <blemouzy@centralp.fr>
34de574
to
70d0107
Compare
I'll try to do it another way. |