From c80b5c56ebd836dde623df0a82e5aea0d51defde Mon Sep 17 00:00:00 2001 From: Alexa <53471801+Alexa-RR@users.noreply.github.com> Date: Tue, 30 Jun 2026 14:34:48 +0300 Subject: [PATCH] Harden signing certificate base64 parsing --- .../Auth/IdentityServerIntegration.cs | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/DorkNet.Server/Auth/IdentityServerIntegration.cs b/DorkNet.Server/Auth/IdentityServerIntegration.cs index 608ed04..6b83f17 100644 --- a/DorkNet.Server/Auth/IdentityServerIntegration.cs +++ b/DorkNet.Server/Auth/IdentityServerIntegration.cs @@ -67,11 +67,56 @@ public sealed class IdentityServerSigningKeyProvider private static X509Certificate2 LoadCertificateFromBase64(string certificateBase64, string password) { var flags = X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.Exportable; - var compact = new string(certificateBase64.Where(c => !char.IsWhiteSpace(c)).ToArray()); - var bytes = Convert.FromBase64String(compact); + var compact = NormalizeCertificateBase64(certificateBase64); + byte[] bytes; + try + { + bytes = Convert.FromBase64String(compact); + } + catch (FormatException ex) + { + throw new InvalidOperationException( + "IdentityServer signing certificate base64 is invalid. " + + "Set IdentityServer__SigningCertificateBase64 to the PFX bytes encoded as base64, " + + "without a file path or shell assignment text.", + ex); + } return new X509Certificate2(bytes, password, flags); } + private static string NormalizeCertificateBase64(string value) + { + var text = value.Trim().Trim('"', '\''); + var equals = text.IndexOf('='); + if (equals > 0) + { + var key = text[..equals].Trim(); + if (key.Equals("IdentityServer__SigningCertificateBase64", StringComparison.OrdinalIgnoreCase) || + key.Equals("IdentityServer:SigningCertificateBase64", StringComparison.OrdinalIgnoreCase)) + text = text[(equals + 1)..].Trim().Trim('"', '\''); + } + + if (text.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) + { + var comma = text.IndexOf(','); + if (comma >= 0) + text = text[(comma + 1)..]; + } + + if (text.StartsWith("base64:", StringComparison.OrdinalIgnoreCase)) + text = text["base64:".Length..]; + + var compact = new string(text.Where(c => !char.IsWhiteSpace(c)).ToArray()) + .Replace('-', '+') + .Replace('_', '/'); + return (compact.Length % 4) switch + { + 2 => compact + "==", + 3 => compact + "=", + _ => compact, + }; + } + private static X509Certificate2 LoadOrCreateCertificate(string path, string password) { var flags = X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.Exportable;