Add unit tests for Router configuration and transport layers
- 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.
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user