From 284adede6cc08f0fd1675978f9976b4c8ca5f430 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:31:33 +0200 Subject: [PATCH] fix(ssl): issue P-256 server certificates so Electron clients connect Server certificates now use a prime256v1 (P-256) EC key. The CA keeps secp521r1. BoringSSL-based Electron clients such as MongoDB Compass cannot use a P-521 server key. Add a feature test that checks the CA stays on P-521 and the server certificate uses P-256. It also checks that the server key matches its certificate and that the CA signature verifies. --- app/Helpers/SslHelper.php | 3 +- tests/Feature/SslCertificateKeyCurveTest.php | 36 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/Feature/SslCertificateKeyCurveTest.php diff --git a/app/Helpers/SslHelper.php b/app/Helpers/SslHelper.php index 13ad941f5f..dc3f1dd5fe 100644 --- a/app/Helpers/SslHelper.php +++ b/app/Helpers/SslHelper.php @@ -35,7 +35,8 @@ class SslHelper try { $privateKey = openssl_pkey_new([ 'private_key_type' => OPENSSL_KEYTYPE_EC, - 'curve_name' => 'secp521r1', + // Electron clients such as MongoDB Compass (BoringSSL) cannot use a P-521 server key. + 'curve_name' => $isCaCertificate ? 'secp521r1' : 'prime256v1', ]); if ($privateKey === false) { diff --git a/tests/Feature/SslCertificateKeyCurveTest.php b/tests/Feature/SslCertificateKeyCurveTest.php new file mode 100644 index 0000000000..be7686fae7 --- /dev/null +++ b/tests/Feature/SslCertificateKeyCurveTest.php @@ -0,0 +1,36 @@ +create(['team_id' => Team::factory()->create()->id]); + + $caCertificate = SslHelper::generateSslCertificate( + commonName: 'Coolify CA Certificate', + serverId: $server->id, + isCaCertificate: true, + validityDays: 10 * 365, + ); + + $serverCertificate = SslHelper::generateSslCertificate( + commonName: 'database', + serverId: $server->id, + caCert: $caCertificate->ssl_certificate, + caKey: $caCertificate->ssl_private_key, + ); + + expect(certificateCurve($caCertificate->ssl_certificate))->toBe('secp521r1') + ->and(certificateCurve($serverCertificate->ssl_certificate))->toBe('prime256v1') + ->and(openssl_x509_check_private_key($serverCertificate->ssl_certificate, $serverCertificate->ssl_private_key))->toBeTrue() + ->and(openssl_x509_verify($serverCertificate->ssl_certificate, openssl_pkey_get_public($caCertificate->ssl_certificate)))->toBe(1); +});