-
Notifications
You must be signed in to change notification settings - Fork 5
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
Es256_priv
Jwk always fails validate_signature
with Invalid_signature
#63
Comments
Es256_priv
Jwk always fails validate_signature
with Invalid_signature
Es256_priv
Jwk always fails validate_signature
with `Invalid_signature
Es256_priv
Jwk always fails validate_signature
with `Invalid_signature
Es256_priv
Jwk always fails validate_signature
with \
Invalid_signature`
Es256_priv
Jwk always fails validate_signature
with \
Invalid_signature`Es256_priv
Jwk always fails validate_signature
with Invalid_signature
It also appears that there are several failing tests around the ECDSA implementations - I tested with compiler versions |
@dmmulroy looking into this, but tests are passing: https://github.com/ulrikstrid/ocaml-jose/actions/runs/5646938425/job/15295950081?pr=64 |
@dmmulroy regarding the example in your image, even if the encoding is different, the key is the same. You can check that the bytes are exactly the same with:
|
@dmmulroy FWIW, this test program works for me. Could you give more details as to which versions you're running? open Jose
let read_file filename =
let ic = open_in filename in
let n = in_channel_length ic in
let s = really_input_string ic n in
close_in ic;
s
let test () =
let priv_pem = read_file "private_key.pem" in
let jwk = Jwk.of_priv_pem priv_pem |> Result.get_ok in
let header = Header.make_header jwk in
let jwt = Jwt.sign ~header ~payload:Jwt.empty_payload jwk |> Result.get_ok in
match Jwt.validate_signature ~jwk jwt with
| Ok _jwt -> Format.eprintf "success@."
| Error `Invalid_signature -> Format.eprintf "ERR(0): Invalid Signature@."
| Error (`Msg msg) -> Format.eprintf "ERR(1): %s@." msg
let () = test () |
Let me see if I can make a repo where it's reproducible - thanks for the quick help! |
Okay @anmonteiro - here's a repo with a opam lock file and a test private key that is causing the issue for me. https://github.com/dmmulroy/jose-jwk-test
|
On a cursory look, it looks like we're using the same versions. I'll take a closer look later. |
Small update - I think I have the problem narrowed down to Alcotest.test_case "Mirage_crypto_ec.P256.Dsa cstruct test" `Quick
(fun () ->
let open Jose.Utils in
let x = "q3zAwR_kUwtdLEwtB2oVfucXiLHmEhu9bJUFYjJxYGs" in
let y = "8h0D-ONoU-iZqrq28TyUxEULxuGwJZGMJYTMbeMshvI" in
let make_ES256_of_x_y (x, y) =
let x =
U_Base64.url_decode x |> U_Result.map Cstruct.of_string
in
let y =
U_Base64.url_decode y |> U_Result.map Cstruct.of_string
in
U_Result.both x y
|> U_Result.map (fun (x, y) ->
let four = Cstruct.create 1 in
Cstruct.set_uint8 four 0 4;
let point = Cstruct.concat [ four; x; y ] in
let k = Mirage_crypto_ec.P256.Dsa.pub_of_cstruct point in
k |> U_Result.get_exn)
in
let get_ES256_x_y key =
let point = Mirage_crypto_ec.P256.Dsa.pub_to_cstruct key in
let x_cs, y_cs = Cstruct.(split (shift point 1) 32) in
let x =
x_cs |> Cstruct.to_string |> U_Base64.url_encode_string
in
let y =
y_cs |> Cstruct.to_string |> U_Base64.url_encode_string
in
(x, y)
in
let pub_key = make_ES256_of_x_y (x, y) |> Result.get_ok in
let x', y' = get_ES256_x_y pub_key in
check_result_string "x" (Ok x) (Ok x');
check_result_string "y" (Ok y) (Ok y'));
|
and further: Alcotest.test_case "Mirage_crypto_ec.P256.Dsa cstruct test 2" `Quick
(fun () ->
let open Jose.Utils in
let x = "q3zAwR_kUwtdLEwtB2oVfucXiLHmEhu9bJUFYjJxYGs" in
let y = "8h0D-ONoU-iZqrq28TyUxEULxuGwJZGMJYTMbeMshvI" in
let make_cstruct_point_of_x_y (x, y) =
let x =
U_Base64.url_decode x |> U_Result.map Cstruct.of_string
in
let y =
U_Base64.url_decode y |> U_Result.map Cstruct.of_string
in
U_Result.both x y
|> U_Result.map (fun (x, y) ->
let four = Cstruct.create 1 in
Cstruct.set_uint8 four 0 4;
Cstruct.concat [ four; x; y ])
in
let get_cstruct_point_x_y key =
Mirage_crypto_ec.P256.Dsa.pub_to_cstruct key
in
let cstruct_point =
Result.get_ok @@ make_cstruct_point_of_x_y (x, y)
in
let key =
Result.get_ok
@@ Mirage_crypto_ec.P256.Dsa.pub_of_cstruct cstruct_point
in
let cstruct_point' = get_cstruct_point_x_y key in
check_result_string "cstruct point"
(Ok (Cstruct.to_string cstruct_point))
(Ok (Cstruct.to_string cstruct_point')));
|
I haven’t confirmed your findings but if you suspect a bug in mirage crypto then we should report that in that repo |
This is a bug in clang 14.0.3 and Apple hasn't patched it yet. See: mit-plv/fiat-crypto#1606 |
FTR that explains why I couldn't repro:
|
…age, mirage-crypto-rng-lwt, mirage-crypto-rng-eio, mirage-crypto-rng-async, mirage-crypto-pk and mirage-crypto-ec (0.11.2) CHANGES: * mirage-crypto-rng-eio: improve portability by using eio 0.7's monotonic clock interface instead of mtime.clock.os. (mirage/mirage-crypto#176 @TheLortex) * mirage-crypto-rng-eio: update to eio 0.12 (mirage/mirage-crypto#182 @talex5) * mirage-crypto-rng: fix typo in RNG setup (mirage/mirage-crypto#179 @samueldurantes) * macOS: on arm64 with clang 14.0.3, avoid instcombine (due to miscompilations) reported by @samoht mit-plv/fiat-crypto#1606 (comment) re-reported in ulrikstrid/ocaml-jose#63 and mirleft/ocaml-tls#478 (mirage/mirage-crypto#185 @hannesm @kit-ty-kate) * avoid "stringop-overflow" warning on PPC64 and S390x (spurious warnings) when in devel mode (mirage/mirage-crypto#178 mirage/mirage-crypto#184 @avsm @hannesm) * stricter C prototypes, unsigned/signed integers (mirage/mirage-crypto#175 @MisterDA @haesbaert @avsm @hannesm) * support DragonFlyBSD (mirage/mirage-crypto#181 @movepointsolutions) * support GNU/Hurd (mirage/mirage-crypto#174 @pinotree)
FWIW, mirage-crypto 0.11.2 avoids the miscompilation (PRed to opam-repository ocaml/opam-repository#24461) -- sorry it took so long to get this out of the door. |
…age, mirage-crypto-rng-lwt, mirage-crypto-rng-eio, mirage-crypto-rng-async, mirage-crypto-pk and mirage-crypto-ec (0.11.2) CHANGES: * mirage-crypto-rng-eio: improve portability by using eio 0.7's monotonic clock interface instead of mtime.clock.os. (mirage/mirage-crypto#176 @TheLortex) * mirage-crypto-rng-eio: update to eio 0.12 (mirage/mirage-crypto#182 @talex5) * mirage-crypto-rng: fix typo in RNG setup (mirage/mirage-crypto#179 @samueldurantes) * macOS: on arm64 with clang 14.0.3, avoid instcombine (due to miscompilations) reported by @samoht mit-plv/fiat-crypto#1606 (comment) re-reported in ulrikstrid/ocaml-jose#63 and mirleft/ocaml-tls#478 (mirage/mirage-crypto#185 @hannesm @kit-ty-kate) * avoid "stringop-overflow" warning on PPC64 and S390x (spurious warnings) when in devel mode (mirage/mirage-crypto#178 mirage/mirage-crypto#184 @avsm @hannesm) * stricter C prototypes, unsigned/signed integers (mirage/mirage-crypto#175 @MisterDA @haesbaert @avsm @hannesm) * support DragonFlyBSD (mirage/mirage-crypto#181 @movepointsolutions) * support GNU/Hurd (mirage/mirage-crypto#174 @pinotree)
I can't seem to properly sign and validate a JWT using a ES256 private key.
Steps to reproduce:
openssl ecparam -genkey -name prime256v1 -noout -out private_key.pem
Es256_priv Jwk.t
usingJwk.of_priv_pem
and paste in the above private key as the string argumentHeader.t
viaHeader.make_header
and using the createdjwk
let jwt = Jwt.sign ~header ~payload:Jwt.empty_payload jwk |> Result.get_ok;;
Jwt.validate_signature ~jwk jwt;;
The text was updated successfully, but these errors were encountered: