diff --git a/app/Helpers/SslHelper.php b/app/Helpers/SslHelper.php index 4797113b7..51ac3bffa 100644 --- a/app/Helpers/SslHelper.php +++ b/app/Helpers/SslHelper.php @@ -2,6 +2,7 @@ namespace App\Helpers; +use App\Models\Server; use App\Models\SslCertificate; use Carbon\CarbonImmutable; @@ -9,18 +10,21 @@ class SslHelper { private const DEFAULT_ORGANIZATION_NAME = 'Coolify'; + private const DEFAULT_COUNTRY_CODE = 'ZZ'; + + private const DEFAULT_STATE = 'Default'; + public static function generateSslCertificate( string $commonName, - array $additionalSans = [], + array $subjectAlternativeNames = [], ?string $resourceType = null, ?int $resourceId = null, ?int $serverId = null, - ?string $organizationName = null, int $validityDays = 365, ?string $caCert = null, - ?string $caKey = null + ?string $caKey = null, + bool $isCaCertificate = false ): SslCertificate { - $organizationName ??= self::DEFAULT_ORGANIZATION_NAME; try { $privateKey = openssl_pkey_new([ @@ -36,13 +40,29 @@ class SslHelper throw new \RuntimeException('Failed to export private key: '.openssl_error_string()); } - $dn = [ + if (! is_null($serverId) && ! $isCaCertificate) { + $server = Server::find($serverId); + if ($server) { + $ip = $server->getIp; + if ($ip) { + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) { + $subjectAlternativeNames[] = "IP:$ip"; + } else { + $subjectAlternativeNames[] = "DNS:$ip"; + } + } + } + } + + $certificateSubject = [ 'commonName' => $commonName, - 'organizationName' => $organizationName, - 'subjectAltName' => implode(', ', array_merge(["DNS:$commonName"], $additionalSans)), + 'subjectAltName' => implode(', ', array_merge(["DNS:$commonName"], $subjectAlternativeNames)), + 'organizationName' => self::DEFAULT_ORGANIZATION_NAME, + 'countryName' => self::DEFAULT_COUNTRY_CODE, + 'stateOrProvinceName' => self::DEFAULT_STATE, ]; - $csr = openssl_csr_new($dn, $privateKey, [ + $csr = openssl_csr_new($certificateSubject, $privateKey, [ 'digest_alg' => 'sha512', 'config' => null, 'encrypt_key' => false, @@ -72,6 +92,12 @@ class SslHelper throw new \RuntimeException('Failed to export certificate: '.openssl_error_string()); } + SslCertificate::query() + ->where('resource_type', $resourceType) + ->where('resource_id', $resourceId) + ->where('server_id', $serverId) + ->delete(); + return SslCertificate::create([ 'ssl_certificate' => $certificateStr, 'ssl_private_key' => $privateKeyStr, @@ -79,6 +105,9 @@ class SslHelper 'resource_id' => $resourceId, 'server_id' => $serverId, 'valid_until' => CarbonImmutable::now()->addDays($validityDays), + 'is_ca_certificate' => $isCaCertificate, + 'common_name' => $commonName, + 'subject_alternative_names' => implode(', ', array_merge(["DNS:$commonName"], $subjectAlternativeNames)), ]); } catch (\Throwable $e) { throw new \RuntimeException('SSL Certificate generation failed: '.$e->getMessage(), 0, $e);