198 lines
7.4 KiB
C#
Executable File
198 lines
7.4 KiB
C#
Executable File
using System;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MarketAlly.AIPlugin.DevOps.Security
|
|
{
|
|
public class CryptographicValidator
|
|
{
|
|
private readonly AuditLogger _auditLogger;
|
|
|
|
public CryptographicValidator(AuditLogger auditLogger = null)
|
|
{
|
|
_auditLogger = auditLogger;
|
|
}
|
|
|
|
public async Task<bool> ValidateFileIntegrityAsync(string filePath, string expectedHash = null)
|
|
{
|
|
if (!File.Exists(filePath))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
using var sha256 = SHA256.Create();
|
|
using var fileStream = File.OpenRead(filePath);
|
|
var computedHash = await ComputeHashAsync(sha256, fileStream);
|
|
var hashString = Convert.ToHexString(computedHash);
|
|
|
|
await _auditLogger?.LogSecurityEventAsync(new SecurityAuditEvent
|
|
{
|
|
EventType = SecurityEventType.CryptographicOperation,
|
|
Severity = SecuritySeverity.Low,
|
|
Source = nameof(CryptographicValidator),
|
|
Details = "File integrity validation performed",
|
|
Metadata = new()
|
|
{
|
|
["filePath"] = filePath,
|
|
["computedHash"] = hashString,
|
|
["expectedHash"] = expectedHash
|
|
}
|
|
});
|
|
|
|
if (string.IsNullOrEmpty(expectedHash))
|
|
{
|
|
return true; // No expected hash to compare against
|
|
}
|
|
|
|
return string.Equals(hashString, expectedHash, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await _auditLogger?.LogSecurityEventAsync(new SecurityAuditEvent
|
|
{
|
|
EventType = SecurityEventType.CryptographicOperation,
|
|
Severity = SecuritySeverity.High,
|
|
Source = nameof(CryptographicValidator),
|
|
Details = $"File integrity validation failed: {ex.Message}",
|
|
Metadata = new()
|
|
{
|
|
["filePath"] = filePath,
|
|
["error"] = ex.Message
|
|
}
|
|
});
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<string> ComputeFileHashAsync(string filePath)
|
|
{
|
|
if (!File.Exists(filePath))
|
|
{
|
|
throw new FileNotFoundException($"File not found: {filePath}");
|
|
}
|
|
|
|
using var sha256 = SHA256.Create();
|
|
using var fileStream = File.OpenRead(filePath);
|
|
var hash = await ComputeHashAsync(sha256, fileStream);
|
|
return Convert.ToHexString(hash);
|
|
}
|
|
|
|
public async Task<bool> ValidateConfigurationSignatureAsync(string configPath, string signaturePath)
|
|
{
|
|
if (!File.Exists(configPath) || !File.Exists(signaturePath))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
// This is a simplified signature validation
|
|
// In production, you would use proper digital signatures with RSA/ECDSA
|
|
var configContent = await File.ReadAllTextAsync(configPath);
|
|
var expectedSignature = await File.ReadAllTextAsync(signaturePath);
|
|
|
|
var computedSignature = await ComputeContentSignatureAsync(configContent);
|
|
|
|
var isValid = string.Equals(computedSignature, expectedSignature, StringComparison.OrdinalIgnoreCase);
|
|
|
|
await _auditLogger?.LogSecurityEventAsync(new SecurityAuditEvent
|
|
{
|
|
EventType = SecurityEventType.ConfigurationValidated,
|
|
Severity = isValid ? SecuritySeverity.Low : SecuritySeverity.High,
|
|
Source = nameof(CryptographicValidator),
|
|
Details = $"Configuration signature validation: {(isValid ? "PASSED" : "FAILED")}",
|
|
Metadata = new()
|
|
{
|
|
["configPath"] = configPath,
|
|
["signaturePath"] = signaturePath,
|
|
["validationResult"] = isValid
|
|
}
|
|
});
|
|
|
|
return isValid;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await _auditLogger?.LogSecurityEventAsync(new SecurityAuditEvent
|
|
{
|
|
EventType = SecurityEventType.ConfigurationValidated,
|
|
Severity = SecuritySeverity.Critical,
|
|
Source = nameof(CryptographicValidator),
|
|
Details = $"Configuration signature validation error: {ex.Message}",
|
|
Metadata = new()
|
|
{
|
|
["configPath"] = configPath,
|
|
["signaturePath"] = signaturePath,
|
|
["error"] = ex.Message
|
|
}
|
|
});
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<string> ComputeContentSignatureAsync(string content)
|
|
{
|
|
using var sha256 = SHA256.Create();
|
|
var contentBytes = Encoding.UTF8.GetBytes(content);
|
|
var hash = await Task.Run(() => sha256.ComputeHash(contentBytes));
|
|
return Convert.ToHexString(hash);
|
|
}
|
|
|
|
public async Task<bool> ValidateJsonIntegrityAsync(string jsonContent)
|
|
{
|
|
try
|
|
{
|
|
// Validate JSON structure
|
|
using var document = JsonDocument.Parse(jsonContent);
|
|
|
|
// Additional integrity checks could be added here
|
|
// For example, checking for required fields, schema validation, etc.
|
|
|
|
await _auditLogger?.LogSecurityEventAsync(new SecurityAuditEvent
|
|
{
|
|
EventType = SecurityEventType.ConfigurationValidated,
|
|
Severity = SecuritySeverity.Low,
|
|
Source = nameof(CryptographicValidator),
|
|
Details = "JSON integrity validation passed",
|
|
Metadata = new()
|
|
{
|
|
["contentLength"] = jsonContent.Length,
|
|
["validJson"] = true
|
|
}
|
|
});
|
|
|
|
return true;
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
await _auditLogger?.LogSecurityEventAsync(new SecurityAuditEvent
|
|
{
|
|
EventType = SecurityEventType.ConfigurationValidated,
|
|
Severity = SecuritySeverity.Medium,
|
|
Source = nameof(CryptographicValidator),
|
|
Details = $"JSON integrity validation failed: {ex.Message}",
|
|
Metadata = new()
|
|
{
|
|
["contentLength"] = jsonContent.Length,
|
|
["validJson"] = false,
|
|
["error"] = ex.Message
|
|
}
|
|
});
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private async Task<byte[]> ComputeHashAsync(HashAlgorithm hashAlgorithm, Stream stream)
|
|
{
|
|
return await Task.Run(() => hashAlgorithm.ComputeHash(stream));
|
|
}
|
|
}
|
|
} |