using Org.BouncyCastle.Crypto; using Org.BouncyCastle.X509; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CAUtilLib { public class CaUtil { public string RootPath = "/home/cert"; public const string RcaDirectoryName = "rca"; public const string TrustedDirectoryName = "tcrt"; public const string RcaKeyName = "rca_key.pem"; public const string RcaCertName = "rca.pem"; public string RcaKeyPath => Path.Combine(RootPath, RcaDirectoryName, RcaKeyName); public string RcaCertPath => Path.Combine(RootPath, RcaDirectoryName, RcaCertName); public string TrustedCertsPath => Path.Combine(RootPath, TrustedDirectoryName); public async Task CreateRootCA() { AsymmetricCipherKeyPair kp = BouncyCastleWrapper.GenerateRsaKeyPair(4096); var saveKeyResult = await BouncyCastleWrapper.TrySaveAsPemAsync(RcaKeyPath, new object[] { kp.Private }); if (!saveKeyResult) { return false; } var subject = BouncyCastleWrapper.CreateX509Name(commonName: "Zerova"); X509Certificate cert = BouncyCastleWrapper.GenerateSelfSignedRootCertificate(subject, kp); var saveCertResult = await BouncyCastleWrapper.TrySaveAsPemAsync(RcaCertPath, new object[] { cert, kp.Private }); if (!saveCertResult) { return false; } return true; } public async Task SignCsr(string csr) { var parsedCsr = BouncyCastleWrapper.LoadPemCsrFromString(csr); if (parsedCsr is null) { return null; } var rca = await BouncyCastleWrapper.LoadPemCertFromFile(RcaCertPath); if (rca is null) { return null; } var rcaKey = await BouncyCastleWrapper.LoadPemKeyFromFile(RcaKeyPath); if (rcaKey is null) { return null; } var generatedCrt = BouncyCastleWrapper.SignCertificate(parsedCsr, rca, rcaKey); return await BouncyCastleWrapper.ToStringAsPem(generatedCrt); } public async Task VerifyCrt(string crt) { var parsedCrt = BouncyCastleWrapper.LoadPemCertFromString(crt); if (parsedCrt is null) { return -1; } var isSignedByRca = await VerifyCrtSignedByRCA(parsedCrt!); if (isSignedByRca) { return 0; } var isSignedByTrusted = await VerifyCrtSignedByTrused(parsedCrt!); if (isSignedByTrusted) { return 1; } return -1; } private async Task VerifyCrtSignedByRCA(X509Certificate crt) { var rcaKey = await BouncyCastleWrapper.LoadPemKeyFromFile(RcaKeyPath); if (rcaKey is null) { return false; } return BouncyCastleWrapper.ValidateCert(crt, rcaKey.Public); } private async Task VerifyCrtSignedByTrused(X509Certificate crt) { var trustedCerts = Directory.GetFiles(TrustedCertsPath); foreach (var trustedCert in trustedCerts) { var cert = await BouncyCastleWrapper.LoadPemCertFromFile(trustedCert); var checkResult = BouncyCastleWrapper.ValidateCert(crt, cert.GetPublicKey()); if (checkResult) { return true; } } return false; } } }