[erlang-questions] ERL-823: SSL cipher_suites too limited when compiling with OPENSSL_NO_EC=1
Nicholas Lundgaard
nalundgaard@REDACTED
Fri Jan 4 18:41:16 CET 2019
Thanks for your insights, all.
I've looked at Erlang/OTP 21 builds from our CentOS box that were built with no OPENSSL_NO_EC* set, and also just tried one built with OPENSSL_NO_EC2M set, as advised below. It looks like it's true that these options are ideal for my company's use, and in both cases we properly get an Erlang/OTP build that has a fine set of cipher suites that work with the underlying OpenSSL library on the OS.
It seems like there is still some potential problem with this setup, though: both the ssl and crypto modules claim to support EC curves that the underlying SSL library does not, in fact, support. A simple function that wraps a key-generate/sign/verify process in a try-catch can be used to verify this:
VerifyCurve = fun(Curve) ->
Msg = <<"hello world!">>,
try
{PublicKey, PrivKeyOut} = crypto:generate_key(ecdh,Curve),
Signature = crypto:sign(ecdsa, sha512, Msg, [PrivKeyOut, Curve]),
true = crypto:verify(ecdsa, sha512, <<"hello world!">>, Signature, [PublicKey, Curve]),
ok
catch
Err:Reason ->
{Err, Reason}
end
end.
When I run this on ssl:eccs/0 or crypto:ec_curves/0, I get this result:
2> [{C, VerifyCurve(C)} || C <- ssl:eccs()].
[{secp521r1,ok},
{brainpoolP512r1,ok},
{brainpoolP384r1,ok},
{secp384r1,ok},
{brainpoolP256r1,ok},
{secp256k1,ok},
{secp256r1,ok},
{secp224k1,{error,badarg}},
{secp224r1,{error,badarg}},
{secp192k1,{error,badarg}},
{secp192r1,{error,badarg}},
{secp160k1,{error,badarg}},
{secp160r1,{error,badarg}},
{secp160r2,{error,badarg}}]
3> rp([{C, VerifyCurve(C)} || C <- crypto:ec_curves()]).
[{secp160k1,{error,badarg}},
{secp160r1,{error,badarg}},
{secp160r2,{error,badarg}},
{secp192r1,{error,badarg}},
{secp192k1,{error,badarg}},
{secp224k1,{error,badarg}},
{secp224r1,{error,badarg}},
{secp256k1,ok},
{secp256r1,ok},
{secp384r1,ok},
{secp521r1,ok},
{prime192v1,{error,badarg}},
{prime192v2,{error,badarg}},
{prime192v3,{error,badarg}},
{prime239v1,{error,badarg}},
{prime239v2,{error,badarg}},
{prime239v3,{error,badarg}},
{prime256v1,ok},
{wtls7,{error,badarg}},
{wtls9,{error,badarg}},
{wtls12,{error,badarg}},
{brainpoolP160r1,{error,badarg}},
{brainpoolP160t1,{error,badarg}},
{brainpoolP192r1,{error,badarg}},
{brainpoolP192t1,{error,badarg}},
{brainpoolP224r1,{error,badarg}},
{brainpoolP224t1,{error,badarg}},
{brainpoolP256r1,ok},
{brainpoolP256t1,ok},
{brainpoolP320r1,ok},
{brainpoolP320t1,ok},
{brainpoolP384r1,ok},
{brainpoolP384t1,ok},
{brainpoolP512r1,ok},
{brainpoolP512t1,ok},
{secp112r1,{error,badarg}},
{secp112r2,{error,badarg}},
{secp128r1,{error,badarg}},
{secp128r2,{error,badarg}},
{wtls6,{error,badarg}},
{wtls8,{error,badarg}}]
So.. this is what actually is troubling me about an OTP that is installed this way: these two modules definitely report named curves that cause runtime errors. The underlying OpenSSL library definitely reports which ones it supports, so I guess my question is why doesn't ssl/crypto leverage this?
I think in point of fact, this concern isn't significant. It appears that Erlang/OTP 21 (built on RHEL/CentOS) has an SSL that works out of the box for most SSL connections, certainly to the hosts we care about (AWS services and ELBs/gateways in front of our infrastructure) and I'm guessing that's because the first 7 curves from "ssl:eccs/0" are, in fact, supported by the underlying OpenSSL library (and the list is in preference order). If I understand correctly, it would only be a problem to negotiate a connection with a peer who does not support any of the first 7 preferred curves.
So, I understand that a workaround that I could implement in my HTTPS clients in Erlang is to cull the list of eccs, which can be passed explicitly when connecting (e.g., [{eccs, [secp521r1, brainpoolP512r1, brainpoolP384r1, secp384r1, brainpoolP256r1, secp256k1, secp256r1]}]). However, I feel that this begs the question, what is the reason for the ssl/crypto modules not reporting a lack of support for unsupported curves?
Thanks again! I will copy-paste this comment into the ERL-823 issue as well, for the record.
Regards,
—Nicholas Lundgaard
On Fri, Jan 4, 2019, at 6:07 AM, Per Hedeland wrote:
> On 2019-01-04 10:38, Andreas Schultz wrote:
> > Nicholas Lundgaard <nalundgaard@REDACTED <mailto:nalundgaard@REDACTED>> schrieb am Do., 3. Jan. 2019 um 21:18 Uhr:
> >
> > Hi,
> >
> > I wanted to call ERL-823 (https://bugs.erlang.org/browse/ERL-823) to this list's attention. My company operates Erlang microservices in AWS on a kerl-built OTP installation on Amazon Linux
> > (RedHat/CentOS-based), and we've encountered a serious challenge to upgrading to OTP 21:
> >
> >
> > ECC Ciphers are supported since RHEL 7.6 (also newer CentOS versions), Amazon Linux 2018.03 also has support (`openssl ciphers -v` does contain ECDH ciphers).
>
> Actually I think there is some confusion here - also older versions of
> RHEL/CentOS(/Fedora?) support ECC cipher suites (I checked CentOS 7.2
> just now) - it is only a specific *set of curves* they don't support
> (and probably newer versions don't either), due to concerns about
> potential patents.
>
> And there was actually a time when you *had* to use the brutal
> OPENSSL_NO_EC=1 workaround/hack to get OTP crypto to work on these
> systems, since crypto.c couldn't handle this "partial" exclusion of
> curves - depending on how you built it (excluding static linking* of
> libcrypto), you would get a failure either at build or run time.
>
> But that was long ago, crypto.c was fixed in this respect already for
> OTP 17, in https://github.com/erlang/otp/commit/8837c1be2ba, by -
> Andreas Schultz! Thanks for that!:-)
>
> So, if you use OTP 17 or newer:
>
> - If you build with the libcrypto shipped with RHEL/CentOS, it will
> "just work", without the OPENSSL_NO_EC hack.
>
> - If you for some reason build with a libcrypto that *includes* the
> curves that are excluded on those systems, you can still do a build
> that works there, *and* makes ECC suites in general available, by
> using OPENSSL_NO_EC2M=1 *instead* of OPENSSL_NO_EC=1.
>
> I guess the moral is that if you are given a recipe for some problem,
> make sure that you understand why it is needed, so you can stop using
> it when the actual problem is fixed...:-)
>
> *) I Am Not A Lawyer, but I will still advise at least those shipping
> commercial products based on Erlang/OTP to look carefully into the
> general legal issues with statically linking libcrypto into those
> products. And after having done that, to think again about the wisdom
> of doing the static linking specifically to be able to include
> algorithms that may be patented.
>
> --Per Hedeland
>
More information about the erlang-questions
mailing list