-module(ywt@internal@core). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/ywt/internal/core.gleam"). -export([bits_decoder/0, int_decoder/0, bits_to_json/1, int_to_json/1, rsa_modulus_is_large_enough/1, bits_of_length_decoder/1, curve_decoder/0, named_curve/1, named_curve_size/1, rsa_padding/1, digest_type/1, digest_size/1]). -export_type([error/0, named_curve/0, padding/0, digest_type/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type error() :: malformed_token | invalid_header_encoding | invalid_payload_encoding | invalid_signature_encoding | {invalid_header_json, gleam@json:decode_error()} | {header_decoding_error, list(gleam@dynamic@decode:decode_error())} | unsupported_critical_header | unsupported_unencoded_payload | {invalid_payload_json, gleam@json:decode_error()} | no_matching_key | invalid_signature | {token_expired, gleam@time@timestamp:timestamp()} | {token_not_yet_valid, gleam@time@timestamp:timestamp()} | {invalid_issuer, list(binary()), binary()} | {invalid_audience, list(binary()), list(binary())} | {invalid_type, binary(), binary()} | {invalid_subject, list(binary()), binary()} | {invalid_id, list(binary()), binary()} | {missing_claim, binary()} | {claim_decoding_error, binary(), list(gleam@dynamic@decode:decode_error())} | {invalid_custom_claim, binary()} | {payload_decoding_error, list(gleam@dynamic@decode:decode_error())}. -type named_curve() :: secp256r1 | secp384r1 | secp521r1. -type padding() :: rsa_pkcs1_padding | rsa_pkcs1_pss_padding. -type digest_type() :: sha256 | sha384 | sha512. -file("src/ywt/internal/core.gleam", 72). ?DOC(false). -spec bits_decoder() -> gleam@dynamic@decode:decoder(bitstring()). bits_decoder() -> gleam@dynamic@decode:then( {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Str) -> case ywt@internal@base64url:decode(Str) of {ok, Bits} -> gleam@dynamic@decode:success(Bits); {error, _} -> gleam@dynamic@decode:failure(<<>>, <<"Base64Url"/utf8>>) end end ). -file("src/ywt/internal/core.gleam", 36). ?DOC(false). -spec int_decoder() -> gleam@dynamic@decode:decoder(bigi:big_int()). int_decoder() -> gleam@dynamic@decode:then( bits_decoder(), fun(Bits) -> case bigi_ffi:from_bytes(Bits, big_endian, unsigned) of {ok, Int} -> gleam@dynamic@decode:success(Int); {error, _} -> gleam@dynamic@decode:failure( bigi_ffi:zero(), <<"BigInt"/utf8>> ) end end ). -file("src/ywt/internal/core.gleam", 44). ?DOC(false). -spec bits_to_json(bitstring()) -> gleam@json:json(). bits_to_json(Bits) -> gleam@json:string(gleam@bit_array:base64_url_encode(Bits, false)). -file("src/ywt/internal/core.gleam", 54). ?DOC(false). -spec int_byte_size(bigi:big_int(), integer()) -> integer(). int_byte_size(Int, Bytes) -> case bigi_ffi:compare(Int, bigi_ffi:zero()) of gt -> int_byte_size(bigi_ffi:bitwise_shift_right(Int, 8), Bytes + 1); _ -> Bytes end. -file("src/ywt/internal/core.gleam", 48). ?DOC(false). -spec int_to_json(bigi:big_int()) -> gleam@json:json(). int_to_json(Int) -> Size = int_byte_size(Int, 0), Bytes@1 = case bigi_ffi:to_bytes(Int, big_endian, unsigned, Size) of {ok, Bytes} -> Bytes; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"ywt/internal/core"/utf8>>, function => <<"int_to_json"/utf8>>, line => 50, value => _assert_fail, start => 1615, 'end' => 1693, pattern_start => 1626, pattern_end => 1635}) end, gleam@json:string(gleam@bit_array:base64_url_encode(Bytes@1, false)). -file("src/ywt/internal/core.gleam", 61). ?DOC(false). -spec rsa_modulus_is_large_enough(bigi:big_int()) -> boolean(). rsa_modulus_is_large_enough(Modulus) -> Minimum_bits = 2048, Minimum_modulus = bigi_ffi:bitwise_shift_left( bigi_ffi:one(), Minimum_bits - 1 ), case bigi_ffi:compare(Modulus, Minimum_modulus) of lt -> false; eq -> true; gt -> true end. -file("src/ywt/internal/core.gleam", 80). ?DOC(false). -spec bits_of_length_decoder(integer()) -> gleam@dynamic@decode:decoder(bitstring()). bits_of_length_decoder(Byte_count) -> gleam@dynamic@decode:then( bits_decoder(), fun(Bits) -> case erlang:bit_size(Bits) =:= (Byte_count * 8) of true -> gleam@dynamic@decode:success(Bits); false -> gleam@dynamic@decode:failure( <<>>, <<"Base64UrlLength"/utf8>> ) end end ). -file("src/ywt/internal/core.gleam", 97). ?DOC(false). -spec curve_decoder() -> gleam@dynamic@decode:decoder(named_curve()). curve_decoder() -> gleam@dynamic@decode:then( {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Crv) -> case Crv of <<"P-256"/utf8>> -> gleam@dynamic@decode:success(secp256r1); <<"P-384"/utf8>> -> gleam@dynamic@decode:success(secp384r1); <<"P-521"/utf8>> -> gleam@dynamic@decode:success(secp521r1); _ -> gleam@dynamic@decode:failure(secp256r1, <<"crv"/utf8>>) end end ). -file("src/ywt/internal/core.gleam", 114). ?DOC(false). -spec named_curve(named_curve()) -> binary(). named_curve(Curve) -> case Curve of secp256r1 -> <<"P-256"/utf8>>; secp384r1 -> <<"P-384"/utf8>>; secp521r1 -> <<"P-521"/utf8>> end. -file("src/ywt/internal/core.gleam", 122). ?DOC(false). -spec named_curve_size(named_curve()) -> integer(). named_curve_size(Curve) -> case Curve of secp256r1 -> 32; secp384r1 -> 48; secp521r1 -> 66 end. -file("src/ywt/internal/core.gleam", 136). ?DOC(false). -spec rsa_padding(padding()) -> binary(). rsa_padding(Padding) -> case Padding of rsa_pkcs1_padding -> <<"RSASSA-PKCS1-v1_5"/utf8>>; rsa_pkcs1_pss_padding -> <<"RSA-PSS"/utf8>> end. -file("src/ywt/internal/core.gleam", 150). ?DOC(false). -spec digest_type(digest_type()) -> binary(). digest_type(Digest_type) -> case Digest_type of sha256 -> <<"SHA-256"/utf8>>; sha384 -> <<"SHA-384"/utf8>>; sha512 -> <<"SHA-512"/utf8>> end. -file("src/ywt/internal/core.gleam", 158). ?DOC(false). -spec digest_size(digest_type()) -> integer(). digest_size(Digest_type) -> case Digest_type of sha256 -> 32; sha384 -> 48; sha512 -> 64 end.