Closed potatosalad closed 9 years ago
My point in the discussion was that using custom implemented crypto algorithms has an implicit risk associated with them. They are less reviewed than those present in Erlang crypto module for example. That is not to say that they should not be used as there are some that are not even available in the Erlang distribution.
So the opt-in mechanism would be to make available by default only those algorithms (hashes, ciphers and whatever is needed) that are in the Erlang distribution. All else would raise (throw). As an example, aes_cbc128
and aes_cbc256
should be available by default but no aes_cbc192
.
If the user needs algorithms that are not available in crypto he could pass an application flag like use_erlang_jose_crypto_algorithms
to enable its use.
What do you think?
I agree that by default it should raise an error when a non-supported algorithm is used.
My current plan is to have the auto-detection from jose_sup.erl
assign the fallback module as something like jose_jwa_unsupported
for the AES algorithms so it can raise an appropriate error if someone attempts to use it. Any algorithms assigned to the unsupported module won't be present in jose_jwa:supports/0
or jose_jwa:ciphers/0
. I think having an application flag would also be the appropriate way to opt-in.
As far as the PS256, PS384, and PS512 algorithms go, I'm not sure what's best to do there. There is no native implementation in any version of Erlang, so I'm not sure if an opt-in method should apply there or not. The algorithms are based on RFC 3447 and the Haskell implementation from Crypto.PubKey.RSA.PSS
. Compared to the AES algorithms, the RSA PSS sign/verify implementation is much less complex.
:+1:
IMHO PS*\ should also be opt-in. The reasons we considered this as a good practice for AES also apply here. If the use case needs it, then I the user will be ok with enabling this.
It would also be nice to have some comment on code that points the person to Crypto.PubKey.RSA.PSS
.
I was trying to set up some Elixir documentation but am still swimming against all those acronyms Oo. If I survive I will send you a PR.
Commit potatosalad/erlang-jose@8848b172575fb7d7e1e2977e8ae0a21678d2157a on the cavp
branch has some of the fallback functionality added. There is some more information about the algorithm verification changes at issue #1.
The three application configuration options I added were:
crypto_fallback
(defaults to false
)crypto_aes_fallback
(defaults to value of crypto_fallback
)crypto_rsa_fallback
(defaults to value of crypto_fallback
)I also renamed some of the functions in jose_jwa
from supports/0
to crypto_supports/0
and ciphers/0
to crypto_ciphers/0
. jose_jwa/supports/0
now returns the list of supported algorithms as specified in the JOSE RFC documents:
# OTP 18
JOSE.JWA.supports
# [{:jwe,
# {:alg,
# ["A128GCMKW", "A128KW", "A192GCMKW", "A256GCMKW", "A256KW", "ECDH-ES",
# "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW", "PBES2-HS256+A128KW",
# "PBES2-HS512+A256KW", "RSA-OAEP", "RSA1_5", "dir"]},
# {:enc, ["A128CBC-HS256", "A128GCM", "A192GCM", "A256CBC-HS512", "A256GCM"]}},
# {:jws,
# {:alg,
# ["ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "RS256", "RS384",
# "RS512"]}}]
# OTP 17
JOSE.JWA.supports
# [{:jwe,
# {:alg,
# ["ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW", "RSA-OAEP",
# "RSA1_5", "dir"]},
# {:enc, ["A128CBC-HS256", "A256CBC-HS512"]}},
# {:jws,
# {:alg,
# ["ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "RS256", "RS384",
# "RS512"]}}]
The list of natively supported encryption algorithms is pretty sad on OTP 17 :grimacing:
All algorithms will show up as supported if the crypto_fallback
flag is set to true
.
There is also a jose_jwa:is_native_cipher/1
function that can check whether crypto
is being used directly or not for a specific AES cipher. I use it here to determine which algorithm is used by default for encryption/decryption.
I still have a couple of algorithms to informally verify:
I also want to pull the crypto detection code out of jose_sup
and move it into a gen_server
that will allow it to react to configuration changes.
Adding a note about the haskell implementation might be fine. My original implementation that was actually based on it is here: potatosalad/erlang-crypto_rsassa_pss. There were some issues discovered with the algorithm when I started running it against the triq property tests and so it was completely rewritten following RFC 3447 exactly. None of the original haskell implementation remains in this project, while the implementation in erlang-crypto_rsassa_pss is still heavily based on it.
I've actually changed the implementation slightly from my last comment:
There is only a single crypto_fallback
flag which enables or disables the use of the non-native algorithms. It can be turned on and off with jose_jwa:crypto_fallback/1
or JOSE.JWA.crypto_fallback/1
. By default, this flag is false
.
Nice work on this one @potatosalad! Your work is much appreciated. THanks.
Continuing the discussion from pull request bryanjos/joken#57.
See #1 for the full algorithm fallback table.
From @cs-victor-nascimento:
Currently, only the AES ciphers support any sort of fallback detection. The following algorithms have no fallback detection due to the fact that there is no working algorithm present in any version of OTP:
{"enc":"RSA-OAEP-256"}
){"alg":"PS256"}
,{"alg":"PS384"}
, and{"alg":"PS512"}
)