Current section
Files
Jump to
Current section
Files
src/gose@cose@algorithm.erl
-module(gose@cose@algorithm).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gose/cose/algorithm.gleam").
-export([signature_alg_to_int/1, signature_alg_from_int/1, mac_alg_to_int/1, mac_alg_from_int/1, signing_alg_to_int/1, signing_alg_from_int/1, key_encryption_alg_to_int/1, key_encryption_alg_from_int/1, content_alg_to_int/1, content_alg_from_int/1]).
-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(
" COSE algorithm integer ID mapping ([RFC 9053](https://www.rfc-editor.org/rfc/rfc9053.html)).\n"
"\n"
" Maps between `gose/algorithm` types and COSE integer identifiers.\n"
).
-file("src/gose/cose/algorithm.gleam", 11).
?DOC(" Convert a signature algorithm to its COSE integer identifier.\n").
-spec signature_alg_to_int(gose@algorithm:digital_signature_alg()) -> integer().
signature_alg_to_int(Alg) ->
case Alg of
{ecdsa, ecdsa_p256} ->
-7;
{ecdsa, ecdsa_p384} ->
-35;
{ecdsa, ecdsa_p521} ->
-36;
{ecdsa, ecdsa_secp256k1} ->
-47;
eddsa ->
-8;
{rsa_pkcs1, rsa_pkcs1_sha256} ->
-257;
{rsa_pkcs1, rsa_pkcs1_sha384} ->
-258;
{rsa_pkcs1, rsa_pkcs1_sha512} ->
-259;
{rsa_pss, rsa_pss_sha256} ->
-37;
{rsa_pss, rsa_pss_sha384} ->
-38;
{rsa_pss, rsa_pss_sha512} ->
-39
end.
-file("src/gose/cose/algorithm.gleam", 28).
?DOC(" Parse a signature algorithm from its COSE integer identifier.\n").
-spec signature_alg_from_int(integer()) -> {ok,
gose@algorithm:digital_signature_alg()} |
{error, gose:gose_error()}.
signature_alg_from_int(Id) ->
case Id of
-257 ->
{ok, {rsa_pkcs1, rsa_pkcs1_sha256}};
-258 ->
{ok, {rsa_pkcs1, rsa_pkcs1_sha384}};
-259 ->
{ok, {rsa_pkcs1, rsa_pkcs1_sha512}};
-35 ->
{ok, {ecdsa, ecdsa_p384}};
-36 ->
{ok, {ecdsa, ecdsa_p521}};
-37 ->
{ok, {rsa_pss, rsa_pss_sha256}};
-38 ->
{ok, {rsa_pss, rsa_pss_sha384}};
-39 ->
{ok, {rsa_pss, rsa_pss_sha512}};
-47 ->
{ok, {ecdsa, ecdsa_secp256k1}};
-7 ->
{ok, {ecdsa, ecdsa_p256}};
-8 ->
{ok, eddsa};
_ ->
{error,
{parse_error,
<<"unknown COSE signature algorithm: "/utf8,
(erlang:integer_to_binary(Id))/binary>>}}
end.
-file("src/gose/cose/algorithm.gleam", 51).
?DOC(" Convert a MAC algorithm to its COSE integer identifier.\n").
-spec mac_alg_to_int(gose@algorithm:mac_alg()) -> integer().
mac_alg_to_int(Alg) ->
case Alg of
{hmac, hmac_sha256} ->
5;
{hmac, hmac_sha384} ->
6;
{hmac, hmac_sha512} ->
7
end.
-file("src/gose/cose/algorithm.gleam", 60).
?DOC(" Parse a MAC algorithm from its COSE integer identifier.\n").
-spec mac_alg_from_int(integer()) -> {ok, gose@algorithm:mac_alg()} |
{error, gose:gose_error()}.
mac_alg_from_int(Id) ->
case Id of
5 ->
{ok, {hmac, hmac_sha256}};
6 ->
{ok, {hmac, hmac_sha384}};
7 ->
{ok, {hmac, hmac_sha512}};
_ ->
{error,
{parse_error,
<<"unknown COSE MAC algorithm: "/utf8,
(erlang:integer_to_binary(Id))/binary>>}}
end.
-file("src/gose/cose/algorithm.gleam", 71).
?DOC(" Convert a signing algorithm to its COSE integer identifier.\n").
-spec signing_alg_to_int(gose@algorithm:signing_alg()) -> integer().
signing_alg_to_int(Alg) ->
case Alg of
{digital_signature, Sig_alg} ->
signature_alg_to_int(Sig_alg);
{mac, Mac_alg} ->
mac_alg_to_int(Mac_alg)
end.
-file("src/gose/cose/algorithm.gleam", 79).
?DOC(" Parse a signing algorithm from its COSE integer identifier.\n").
-spec signing_alg_from_int(integer()) -> {ok, gose@algorithm:signing_alg()} |
{error, gose:gose_error()}.
signing_alg_from_int(Id) ->
case signature_alg_from_int(Id) of
{ok, Alg} ->
{ok, {digital_signature, Alg}};
{error, _} ->
case mac_alg_from_int(Id) of
{ok, Alg@1} ->
{ok, {mac, Alg@1}};
{error, _} ->
{error,
{parse_error,
<<"unknown COSE signing algorithm: "/utf8,
(erlang:integer_to_binary(Id))/binary>>}}
end
end.
-file("src/gose/cose/algorithm.gleam", 99).
?DOC(
" Convert a key encryption algorithm to its COSE integer identifier.\n"
"\n"
" Some key encryption algorithms are JOSE-only and have no COSE\n"
" identifier, in which case this returns an error.\n"
).
-spec key_encryption_alg_to_int(gose@algorithm:key_encryption_alg()) -> {ok,
integer()} |
{error, gose:gose_error()}.
key_encryption_alg_to_int(Alg) ->
case Alg of
direct ->
{ok, -6};
{aes_key_wrap, aes_kw, aes128} ->
{ok, -3};
{aes_key_wrap, aes_kw, aes192} ->
{ok, -4};
{aes_key_wrap, aes_kw, aes256} ->
{ok, -5};
{ecdh_es, ecdh_es_direct} ->
{ok, -25};
{ecdh_es, {ecdh_es_aes_kw, aes128}} ->
{ok, -29};
{ecdh_es, {ecdh_es_aes_kw, aes192}} ->
{ok, -30};
{ecdh_es, {ecdh_es_aes_kw, aes256}} ->
{ok, -31};
{rsa_encryption, rsa_oaep_sha1} ->
{ok, -40};
{rsa_encryption, rsa_oaep_sha256} ->
{ok, -41};
{aes_key_wrap, aes_gcm_kw, _} ->
{error,
{invalid_state,
<<"no COSE identifier for algorithm: "/utf8,
(gleam@string:inspect(Alg))/binary>>}};
{cha_cha20_key_wrap, _} ->
{error,
{invalid_state,
<<"no COSE identifier for algorithm: "/utf8,
(gleam@string:inspect(Alg))/binary>>}};
{rsa_encryption, rsa_pkcs1v15} ->
{error,
{invalid_state,
<<"no COSE identifier for algorithm: "/utf8,
(gleam@string:inspect(Alg))/binary>>}};
{ecdh_es, {ecdh_es_cha_cha20_kw, _}} ->
{error,
{invalid_state,
<<"no COSE identifier for algorithm: "/utf8,
(gleam@string:inspect(Alg))/binary>>}};
{pbes2, _} ->
{error,
{invalid_state,
<<"no COSE identifier for algorithm: "/utf8,
(gleam@string:inspect(Alg))/binary>>}}
end.
-file("src/gose/cose/algorithm.gleam", 132).
?DOC(
" Parse a key encryption algorithm from its COSE integer identifier.\n"
"\n"
" Both ECDH-ES+HKDF-256 (-25) and ECDH-ES+HKDF-512 (-26) map to\n"
" `EcdhEs(EcdhEsDirect)` because the shared algorithm type does not\n"
" distinguish the HKDF variant. The HKDF variant is preserved at the\n"
" `cose/encrypt` layer via `EcdhEsDirectVariant`. Use\n"
" `new_ecdh_es_direct_recipient` and `ecdh_es_direct_decryptor` for\n"
" HKDF-512 support.\n"
).
-spec key_encryption_alg_from_int(integer()) -> {ok,
gose@algorithm:key_encryption_alg()} |
{error, gose:gose_error()}.
key_encryption_alg_from_int(Id) ->
case Id of
-25 ->
{ok, {ecdh_es, ecdh_es_direct}};
-26 ->
{ok, {ecdh_es, ecdh_es_direct}};
-29 ->
{ok, {ecdh_es, {ecdh_es_aes_kw, aes128}}};
-3 ->
{ok, {aes_key_wrap, aes_kw, aes128}};
-30 ->
{ok, {ecdh_es, {ecdh_es_aes_kw, aes192}}};
-31 ->
{ok, {ecdh_es, {ecdh_es_aes_kw, aes256}}};
-4 ->
{ok, {aes_key_wrap, aes_kw, aes192}};
-5 ->
{ok, {aes_key_wrap, aes_kw, aes256}};
-6 ->
{ok, direct};
-40 ->
{ok, {rsa_encryption, rsa_oaep_sha1}};
-41 ->
{ok, {rsa_encryption, rsa_oaep_sha256}};
_ ->
{error,
{parse_error,
<<"unknown COSE key encryption algorithm: "/utf8,
(erlang:integer_to_binary(Id))/binary>>}}
end.
-file("src/gose/cose/algorithm.gleam", 157).
?DOC(
" Convert a content encryption algorithm to its COSE integer identifier.\n"
"\n"
" Some content encryption algorithms are JOSE-only and have no COSE\n"
" identifier, in which case this returns an error.\n"
).
-spec content_alg_to_int(gose@algorithm:content_alg()) -> {ok, integer()} |
{error, gose:gose_error()}.
content_alg_to_int(Alg) ->
case Alg of
{aes_gcm, aes128} ->
{ok, 1};
{aes_gcm, aes192} ->
{ok, 2};
{aes_gcm, aes256} ->
{ok, 3};
cha_cha20_poly1305 ->
{ok, 24};
{aes_cbc_hmac, _} ->
{error,
{invalid_state,
<<"no COSE identifier for algorithm: "/utf8,
(gleam@string:inspect(Alg))/binary>>}};
x_cha_cha20_poly1305 ->
{error,
{invalid_state,
<<"no COSE identifier for algorithm: "/utf8,
(gleam@string:inspect(Alg))/binary>>}}
end.
-file("src/gose/cose/algorithm.gleam", 173).
?DOC(" Parse a content encryption algorithm from its COSE integer identifier.\n").
-spec content_alg_from_int(integer()) -> {ok, gose@algorithm:content_alg()} |
{error, gose:gose_error()}.
content_alg_from_int(Id) ->
case Id of
1 ->
{ok, {aes_gcm, aes128}};
2 ->
{ok, {aes_gcm, aes192}};
3 ->
{ok, {aes_gcm, aes256}};
24 ->
{ok, cha_cha20_poly1305};
_ ->
{error,
{parse_error,
<<"unknown COSE content encryption algorithm: "/utf8,
(erlang:integer_to_binary(Id))/binary>>}}
end.