[Bug]: E2EE uses deprecated SHA-1 algorithm for it's CSR, breaking RHEL 9 compat
⚠️ Before submitting, please verify the following: ⚠️
- [X] This is a bug, not a question or a configuration issue.
- [X] This issue is not already reported on Github (I've searched it).
- [X] Nextcloud Server and Desktop Client are up to date. See Server Maintenance and Release Schedule and Desktop Releases for supported versions.
- [X] I agree to follow Nextcloud's Code of Conduct
Bug description
I've been trying to activate E2EE for a couple of weeks now on a fresh NC 27 setup, without luck. After fidling around, I extracted the CSR sent by NC desktop app, and realized it uses SHA-1 algorithm.
Since my Nextcloud server is RHEL 9, it doesn't allow SHA-1 usage since Redhat deprecated it because of collision attacks (beginning with 2011, more viable attacks succeed in 2019).
So far, I cannot get E2EE to work unless I reconfigure my server to allow legacy crypto algorithms, which I obviously won't.
Steps to reproduce
- Enable encryption in NC server
- Setup desktop client
- Click on "enable encryption" in client
Expected behavior
NC Desktop client should generate a 2048 bits (or 4096) private key, and create a CSR based on that key, using SHA-256 hashing algorithm. This CSR can be signed by current versions of openssl.
Which files are affected by this bug
Operating system
Windows
Which version of the operating system you are running.
Windows 10 22H2
Package
MSI installer
Nextcloud Server version
27.0.2.1
Nextcloud Desktop Client version
3.9.3
Is this bug present after an update or on a fresh install?
Fresh desktop client install
Are you using the Nextcloud Server Encryption module?
Encryption is Enabled
Are you using an external user-backend?
- [X] Default internal user-backend
Nextcloud Server logs
{"reqId":"ZOR5E-2cFdBYkFqYxz4qQgAAAEQ","level":3,"time":"2023-08-22T09:00:03+00:00","remoteAddr":"::ffff:XX.XX.XX.XX","user":"[email protected]","app":"PHP","method":"POST","url":"/ocs/v2.php/apps/end_to_end_encryption/api/v1/public-key?format=json","message":"openssl_csr_sign(): Signature did not match the certificate request at /var/www/cloud.mydomain.tld/ftp/www/apps/end_to_end_encryption/lib/SignatureHandler.php#53","userAgent":"Mozilla/5.0 (Windows) mirall/3.9.3stable-Win64 (build 20230818) (Nextcloud, windows-10.0.19044 ClientArchitecture: x86_64 OsArchitecture: x86_64)","version":"27.0.2.1","data":{"app":"PHP"}}
{"reqId":"ZOR5E-2cFdBYkFqYxz4qQgAAAEQ","level":3,"time":"2023-08-22T09:00:03+00:00","remoteAddr":"::ffff:XX.XX.XX.XX","user":"[email protected]","app":"end_to_end_encryption","method":"POST","url":"/ocs/v2.php/apps/end_to_end_encryption/api/v1/public-key?format=json","message":"could not sign the CSR, please make sure to submit a valid CSR","userAgent":"Mozilla/5.0 (Windows) mirall/3.9.3stable-Win64 (build 20230818) (Nextcloud, windows-10.0.19044 ClientArchitecture: x86_64 OsArchitecture: x86_64)","version":"27.0.2.1","exception":{"Exception":"BadMethodCallException","Message":"could not sign the CSR, please make sure to submit a valid CSR","Code":0,"Trace":[{"file":"/var/www/cloud.mydomain.tld/ftp/www/apps/end_to_end_encryption/lib/Controller/KeyController.php","line":189,"function":"sign","class":"OCA\\EndToEndEncryption\\SignatureHandler","type":"->"},{"file":"/var/www/cloud.mydomain.tld/ftp/www/lib/private/AppFramework/Http/Dispatcher.php","line":230,"function":"createPublicKey","class":"OCA\\EndToEndEncryption\\Controller\\KeyController","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/cloud.mydomain.tld/ftp/www/lib/private/AppFramework/Http/Dispatcher.php","line":137,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->"},{"file":"/var/www/cloud.mydomain.tld/ftp/www/lib/private/AppFramework/App.php","line":183,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->"},{"file":"/var/www/cloud.mydomain.tld/ftp/www/lib/private/Route/Router.php","line":315,"function":"main","class":"OC\\AppFramework\\App","type":"::"},{"file":"/var/www/cloud.mydomain.tld/ftp/www/ocs/v1.php","line":64,"function":"match","class":"OC\\Route\\Router","type":"->"},{"file":"/var/www/cloud.mydomain.tld/ftp/www/ocs/v2.php","line":23,"args":["/var/www/cloud.mydomain.tld/ftp/www/ocs/v1.php"],"function":"require_once"}],"File":"/var/www/cloud.mydomain.tld/ftp/www/apps/end_to_end_encryption/lib/SignatureHandler.php","Line":55,"message":"could not sign the CSR, please make sure to submit a valid CSR","exception":{},"CustomMessage":"could not sign the CSR, please make sure to submit a valid CSR"}}
Additional info
Original issue I worked on I'll link to the earlier bug reports I've documented: https://github.com/nextcloud/end_to_end_encryption/issues/424 Original issue on NC desktop: https://github.com/nextcloud/desktop/issues/5910
No response
I guess I found the offending line, in https://github.com/nextcloud/desktop/blob/e83c2c86e699b39d8c93f721da1824f6117020c9/src/libsync/clientsideencryption.cpp#L1380 where specifically SHA-1 is used.
I'm not a C++ guy, but I've seen that evp_sha1() and evp_sha256() functions both exist in the source code.
Mind having a look at this ? I cannot imagine using E2EE without proper encryption settings.
Also, I've seen in https://github.com/nextcloud/desktop/blob/e83c2c86e699b39d8c93f721da1824f6117020c9/src/libsync/clientsideencryption.cpp#L1284 that a 2048 bits RSA key is used. Since the certificates are signed for 7300 days in NC server, that gives us certificate validity until 2030. Security specialsts say that 2048 bits keys won't be secure anymore by those dates.
Here's a quick speed test between 2048, 3072 and 4096 bit keys on a Xeon 6338 hosted VM:
# openssl speed rsa2048 rsa3072 rsa4096
version: 3.0.7
built on: Thu Jul 13 00:00:00 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -O3 -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64-v2 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wa,--noexecstack -Wa,--generate-missing-build-notes=yes -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DZLIB -DNDEBUG -DPURIFY -DDEVRANDOM="\"/dev/urandom\"" -DREDHAT_FIPS_VERSION="\"3.0.7-38f89367593abbfc\"" -DSYSTEM_CIPHERS_FILE="/etc/crypto-policies/back-ends/openssl.config"
CPUINFO: OPENSSL_ia32cap=0xfffa32274fabffff:0x415f5ef1bf07ab
sign verify sign/s verify/s
rsa 2048 bits 0.000442s 0.000026s 2261.9 38745.5
rsa 3072 bits 0.002708s 0.000055s 369.3 18232.5
rsa 4096 bits 0.006066s 0.000094s 164.9 10668.4
As you can see, signature is really slower between various RSA keys (factor 6 up to 13), but verification speed isn't that highly impacted (factor 2 to 3).
So I'm advocating to higher the default RSA key size to at least 3072 bits to be future proof.
[EDIT] I've (quickly) read the rest of your encryption code. Looks like the code uses RSAES-OAEP with MGF1 mask generation, with a SHA256 hash for RSA encryption, and AES-GCM for symmetric encryption under the hood.
Both algorithm are secure AFAIK in 2023. But then again, AES-GCM key is 128 bits, which should be at least 256 bits to be "industry standard", ie being FIPS 140-2 validated.
Changing the RSA key size shouldn't have any implications as it would only be used for new encryption setups. Changing the AES key size would need to have a fallback scheme I guess, for 128 bit legacy keys. [/EDIT]
@deajan thanks for reporting this we indeed appreciate that kind of feedback regarding all of your feedback, I will make sure people are aware of it keep in mind that some feature work is currently being done and some of those calls to openssl may have already been modified/removed
@mgallien Thanks for your kind reply.
I've actually had a look at the other E2EE branches of the desktop client, still using SHA-1, but then again there might be branches out of the nextcloud git ;) Anyway, I'm glad to know desktop client will probably upgrade from current openssl 1.1.1k which is EOL this september. Newer openssl version 3.x deprecates SHA-1 anyway.
I am just puzzled that not more users ran into this specific issue, since RHEL 9 has been released 15 months ago. The whole Redhat ecosystem (RHEL/CentOS Stream/Oracle/Alma/Rocky/Fedora) won't sign SHA-1 CSRs anymore.
Bonne continuation Matthieu ;)
@mgallien I just saw your work for better e2ee init in 3.10-rc3. Any chance we get (at least) SHA-256 for the CSR ? That could be a one liner IMO.
Quite surprised that this bug has been up for more than a half year (orignal bug first reported in april https://github.com/nextcloud/end_to_end_encryption/issues/424).
Do none of the nextcloud customers run RHEL 9 or other distros with good security standards ? Is there perhaps an enterprise version that doesn't have that bug ? Shall I get the enterprise version perhaps ?
Any news about this ?
Really ? SHA-1 in 2024 ? This was reported back in August 2023, so it's been one year and still no way to use E2EE on RHEL 9 and alikes unless one doesn't care about security.
Was also hit be the issue after upgrading to fedora 41. Temporary workaround was to run: sudo update-crypto-policies --set FEDORA40, and to then reboot.
Perhaps something is finally happening, see https://github.com/nextcloud/desktop/commit/a8021a2dff20aeb1690a8f3019da24ce3738d383
For myself, I'm too scared to use E2EE from a product where out-of-date hash algorithms can stay for more than a year and half without anyone wondering about security implications, although I do understand that other bugs may require more attention.
@mgallien I experienced the bug again on a new Fedora installation. Desktop client version is v3.16.3. From what I understand, the fix should be included in the client, so not sure what could be wrong.