From 15f83cf005b5487ccd220a309d50efdd85d8509f Mon Sep 17 00:00:00 2001 From: Tamer Wahba Date: Sat, 2 May 2026 15:46:10 -0400 Subject: [PATCH] Fixed: update server to send full certificate chain when provided --- src/NzbDrone.Host/Bootstrap.cs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Host/Bootstrap.cs b/src/NzbDrone.Host/Bootstrap.cs index 1d9309748b..2c48ea3543 100644 --- a/src/NzbDrone.Host/Bootstrap.cs +++ b/src/NzbDrone.Host/Bootstrap.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Data.SQLite; using System.IO; +using System.Linq; +using System.Net.Security; using System.Reflection; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; @@ -192,7 +194,13 @@ public static IHostBuilder CreateConsoleHostBuilder(string[] args, StartupContex { options.ConfigureHttpsDefaults(configureOptions => { - configureOptions.ServerCertificate = ValidateSslCertificate(sslCertPath, sslCertPassword); + var sslContext = ValidateSslCertificate(sslCertPath, sslCertPassword); + + configureOptions.ServerCertificate = sslContext.TargetCertificate; + configureOptions.OnAuthenticate = (context, authOptions) => + { + authOptions.ServerCertificateContext = sslContext; + }; }); } }); @@ -272,13 +280,13 @@ private static string BuildUrl(string scheme, string bindAddress, int port) return $"{scheme}://{bindAddress}:{port}"; } - private static X509Certificate2 ValidateSslCertificate(string cert, string password) + private static SslStreamCertificateContext ValidateSslCertificate(string cert, string password) { - X509Certificate2 certificate; + var certificateCollection = new X509Certificate2Collection(); try { - certificate = new X509Certificate2(cert, password, X509KeyStorageFlags.DefaultKeySet); + certificateCollection.Import(cert, password, X509KeyStorageFlags.DefaultKeySet); } catch (CryptographicException ex) { @@ -291,7 +299,17 @@ private static X509Certificate2 ValidateSslCertificate(string cert, string passw throw new RadarrStartupException(ex); } - return certificate; + var leafCert = certificateCollection.FirstOrDefault(c => c.HasPrivateKey); + + if (leafCert == null) + { + throw new RadarrStartupException( + $"The SSL certificate file {cert} does not contain a certificate with an associated private key"); + } + + certificateCollection.Remove(leafCert); + + return SslStreamCertificateContext.Create(leafCert, certificateCollection, offline: true); } } }