- Implemented tests for RouterConfig, RoutingOptions, StaticInstanceConfig, and RouterConfigOptions to ensure default values are set correctly. - Added tests for RouterConfigProvider to validate configurations and ensure defaults are returned when no file is specified. - Created tests for ConfigValidationResult to check success and error scenarios. - Developed tests for ServiceCollectionExtensions to verify service registration for RouterConfig. - Introduced UdpTransportTests to validate serialization, connection, request-response, and error handling in UDP transport. - Added scripts for signing authority gaps and hashing DevPortal SDK snippets.
105 lines
3.6 KiB
C#
105 lines
3.6 KiB
C#
using System.Security.Cryptography.X509Certificates;
|
|
|
|
namespace StellaOps.Router.Transport.Tls;
|
|
|
|
/// <summary>
|
|
/// Utility class for loading certificates from various sources.
|
|
/// </summary>
|
|
public static class CertificateLoader
|
|
{
|
|
/// <summary>
|
|
/// Loads a server certificate from the options.
|
|
/// </summary>
|
|
/// <param name="options">The TLS transport options.</param>
|
|
/// <returns>The loaded certificate.</returns>
|
|
/// <exception cref="InvalidOperationException">Thrown when no certificate is configured.</exception>
|
|
public static X509Certificate2 LoadServerCertificate(TlsTransportOptions options)
|
|
{
|
|
// Direct certificate object takes precedence
|
|
if (options.ServerCertificate is not null)
|
|
{
|
|
return options.ServerCertificate;
|
|
}
|
|
|
|
// Load from path
|
|
if (string.IsNullOrEmpty(options.ServerCertificatePath))
|
|
{
|
|
throw new InvalidOperationException("Server certificate is not configured");
|
|
}
|
|
|
|
return LoadCertificateFromPath(
|
|
options.ServerCertificatePath,
|
|
options.ServerCertificateKeyPath,
|
|
options.ServerCertificatePassword);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads a client certificate from the options.
|
|
/// </summary>
|
|
/// <param name="options">The TLS transport options.</param>
|
|
/// <returns>The loaded certificate, or null if not configured.</returns>
|
|
public static X509Certificate2? LoadClientCertificate(TlsTransportOptions options)
|
|
{
|
|
// Direct certificate object takes precedence
|
|
if (options.ClientCertificate is not null)
|
|
{
|
|
return options.ClientCertificate;
|
|
}
|
|
|
|
// Load from path
|
|
if (string.IsNullOrEmpty(options.ClientCertificatePath))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return LoadCertificateFromPath(
|
|
options.ClientCertificatePath,
|
|
options.ClientCertificateKeyPath,
|
|
options.ClientCertificatePassword);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads a certificate from a file path.
|
|
/// </summary>
|
|
/// <param name="certPath">The certificate path (PEM or PFX).</param>
|
|
/// <param name="keyPath">The private key path (optional, for PEM).</param>
|
|
/// <param name="password">The password (optional, for PFX).</param>
|
|
/// <returns>The loaded certificate.</returns>
|
|
public static X509Certificate2 LoadCertificateFromPath(
|
|
string certPath,
|
|
string? keyPath = null,
|
|
string? password = null)
|
|
{
|
|
var extension = Path.GetExtension(certPath).ToLowerInvariant();
|
|
|
|
return extension switch
|
|
{
|
|
".pfx" or ".p12" => LoadPfxCertificate(certPath, password),
|
|
".pem" or ".crt" or ".cer" => LoadPemCertificate(certPath, keyPath),
|
|
_ => throw new InvalidOperationException($"Unsupported certificate format: {extension}")
|
|
};
|
|
}
|
|
|
|
private static X509Certificate2 LoadPfxCertificate(string pfxPath, string? password)
|
|
{
|
|
return X509CertificateLoader.LoadPkcs12FromFile(
|
|
pfxPath,
|
|
password,
|
|
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
|
|
}
|
|
|
|
private static X509Certificate2 LoadPemCertificate(string certPath, string? keyPath)
|
|
{
|
|
var certPem = File.ReadAllText(certPath);
|
|
|
|
if (string.IsNullOrEmpty(keyPath))
|
|
{
|
|
// Assume the key is in the same file
|
|
return X509Certificate2.CreateFromPem(certPem);
|
|
}
|
|
|
|
var keyPem = File.ReadAllText(keyPath);
|
|
return X509Certificate2.CreateFromPem(certPem, keyPem);
|
|
}
|
|
}
|