JSON web tokens in OCaml

Add untracked directories

+110
+15
fuzz/dune
··· 1 + ; Crowbar fuzz testing for jsonwt 2 + ; 3 + ; To run: dune exec ocaml-jsonwt/fuzz/fuzz_jsonwt.exe 4 + ; With AFL: afl-fuzz -i fuzz/corpus -o fuzz/findings -- ./_build/default/ocaml-jsonwt/fuzz/fuzz_jsonwt.exe @@ 5 + 6 + (executable 7 + (name fuzz_jsonwt) 8 + (modules fuzz_jsonwt) 9 + (libraries jsonwt crowbar)) 10 + 11 + (rule 12 + (alias fuzz) 13 + (deps fuzz_jsonwt.exe) 14 + (action 15 + (run %{exe:fuzz_jsonwt.exe})))
+95
fuzz/fuzz_jsonwt.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + (* Crowbar-based fuzz testing for JWT parsing *) 7 + 8 + open Crowbar 9 + 10 + (* Test that JWT parsing never crashes on arbitrary input *) 11 + let test_parse_no_crash input = 12 + let _ = Jsonwt.parse input in 13 + () 14 + 15 + (* Test that JWT parsing in unsafe mode never crashes *) 16 + let test_parse_unsafe_no_crash input = 17 + let _ = Jsonwt.parse_unsafe input in 18 + () 19 + 20 + (* Test that nested JWT parsing never crashes *) 21 + let test_parse_nested_no_crash input = 22 + let _ = Jsonwt.parse_nested input in 23 + () 24 + 25 + (* Test header parsing never crashes *) 26 + let test_header_parse_no_crash input = 27 + let _ = Jsonwt.Header.of_json input in 28 + () 29 + 30 + (* Test claims parsing never crashes *) 31 + let test_claims_parse_no_crash input = 32 + let _ = Jsonwt.Claims.of_json input in 33 + () 34 + 35 + (* Test JWK parsing never crashes *) 36 + let test_jwk_parse_no_crash input = 37 + let _ = Jsonwt.Jwk.of_json input in 38 + () 39 + 40 + (* Test algorithm parsing never crashes *) 41 + let test_algorithm_parse_no_crash input = 42 + let _ = Jsonwt.Algorithm.of_string input in 43 + () 44 + 45 + (* Test base64url-like inputs (dots are JWT separators) *) 46 + let test_jwt_structure input1 input2 input3 = 47 + let token = input1 ^ "." ^ input2 ^ "." ^ input3 in 48 + let _ = Jsonwt.parse token in 49 + () 50 + 51 + (* Test error printing never crashes *) 52 + let () = 53 + let errors = 54 + [ 55 + Jsonwt.Invalid_json "test"; 56 + Jsonwt.Invalid_base64url "test"; 57 + Jsonwt.Invalid_structure "test"; 58 + Jsonwt.Invalid_header "test"; 59 + Jsonwt.Invalid_claims "test"; 60 + Jsonwt.Invalid_uri "test"; 61 + Jsonwt.Duplicate_claim "test"; 62 + Jsonwt.Unsupported_algorithm "test"; 63 + Jsonwt.Algorithm_not_allowed "test"; 64 + Jsonwt.Signature_mismatch; 65 + Jsonwt.Token_expired; 66 + Jsonwt.Token_not_yet_valid; 67 + Jsonwt.Invalid_issuer; 68 + Jsonwt.Invalid_audience; 69 + Jsonwt.Key_type_mismatch "test"; 70 + Jsonwt.Unsecured_not_allowed; 71 + Jsonwt.Nesting_too_deep; 72 + ] 73 + in 74 + List.iter 75 + (fun e -> 76 + let _ = Format.asprintf "%a" Jsonwt.pp_error e in 77 + let _ = Jsonwt.error_to_string e in 78 + ()) 79 + errors 80 + 81 + let () = 82 + add_test ~name:"jwt: parse no crash" [ bytes ] test_parse_no_crash; 83 + add_test ~name:"jwt: parse_unsafe no crash" [ bytes ] 84 + test_parse_unsafe_no_crash; 85 + add_test ~name:"jwt: parse_nested no crash" [ bytes ] 86 + test_parse_nested_no_crash; 87 + add_test ~name:"jwt: header parse no crash" [ bytes ] 88 + test_header_parse_no_crash; 89 + add_test ~name:"jwt: claims parse no crash" [ bytes ] 90 + test_claims_parse_no_crash; 91 + add_test ~name:"jwt: jwk parse no crash" [ bytes ] test_jwk_parse_no_crash; 92 + add_test ~name:"jwt: algorithm parse no crash" [ bytes ] 93 + test_algorithm_parse_no_crash; 94 + add_test ~name:"jwt: structured input" [ bytes; bytes; bytes ] 95 + test_jwt_structure