CertificateManager.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using InABox.Core;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Security.Cryptography.X509Certificates;
  6. using System.Text;
  7. using System.Timers;
  8. using Timer = System.Timers.Timer;
  9. namespace PRSServices;
  10. public enum CertificateStatus
  11. {
  12. Valid,
  13. Expired,
  14. NotFound,
  15. Error
  16. }
  17. public class CertificateManager
  18. {
  19. public string? CertificateFile { get; set; }
  20. private X509Certificate2? Certificate;
  21. private Timer? CertificateRefreshTimer;
  22. private Timer? CertificateHaltTimer;
  23. public delegate void UpdateCertificateEvent(X509Certificate2 certificate);
  24. public event UpdateCertificateEvent? UpdateCertificate;
  25. public delegate void CertificateExpiringEvent(DateTime expiry);
  26. public event CertificateExpiringEvent? CertificateExpiring;
  27. public delegate void CertificateExpiredEvent();
  28. public event CertificateExpiredEvent? CertificateExpired;
  29. public CertificateManager(string? filename = null)
  30. {
  31. CertificateFile = filename;
  32. }
  33. public void SetFile(string certificateFile)
  34. {
  35. CertificateFile = certificateFile;
  36. }
  37. public void SetCertificate(X509Certificate2 certificate)
  38. {
  39. Certificate = certificate;
  40. }
  41. public void Clear()
  42. {
  43. Certificate = null;
  44. }
  45. public void Stop()
  46. {
  47. CertificateRefreshTimer?.Stop();
  48. CertificateHaltTimer?.Dispose();
  49. CertificateHaltTimer = null;
  50. }
  51. public X509Certificate2? GetCertificate()
  52. {
  53. GetCertificate(out var certificate);
  54. return certificate;
  55. }
  56. public CertificateStatus CheckCertificate()
  57. {
  58. return GetCertificate(out var certificate);
  59. }
  60. public CertificateStatus GetCertificate(out X509Certificate2? certificate)
  61. {
  62. if(Certificate != null)
  63. {
  64. certificate = Certificate;
  65. return CertificateStatus.Valid;
  66. }
  67. certificate = null;
  68. CertificateStatus status;
  69. if (File.Exists(CertificateFile))
  70. {
  71. try
  72. {
  73. certificate = new X509Certificate2(CertificateFile);
  74. if (certificate.NotAfter > DateTime.Now)
  75. {
  76. Certificate = certificate;
  77. status = CertificateStatus.Valid;
  78. }
  79. else
  80. {
  81. status = CertificateStatus.Expired;
  82. certificate = null;
  83. }
  84. }
  85. catch (Exception)
  86. {
  87. status = CertificateStatus.Error;
  88. }
  89. }
  90. else
  91. {
  92. status = CertificateStatus.NotFound;
  93. }
  94. if(certificate is not null)
  95. {
  96. if (CertificateRefreshTimer == null)
  97. {
  98. CertificateRefreshTimer = new Timer(1000 * 60 * 60 * 24);
  99. CertificateRefreshTimer.Elapsed += CertificateTimer_Elapsed;
  100. CertificateRefreshTimer.AutoReset = true;
  101. }
  102. CertificateRefreshTimer.Start();
  103. }
  104. return status;
  105. }
  106. #region Certificate Management
  107. private void CertificateTimer_Elapsed(object? sender, ElapsedEventArgs e)
  108. {
  109. if (Certificate is not null)
  110. {
  111. X509Certificate2? cert = null;
  112. if (File.Exists(CertificateFile))
  113. {
  114. cert = new X509Certificate2(CertificateFile);
  115. }
  116. if (cert != null && cert.NotAfter > Certificate.NotAfter && cert.NotAfter > DateTime.Now)
  117. {
  118. Certificate = cert;
  119. UpdateCertificate?.Invoke(cert);
  120. }
  121. var expiry = Certificate.NotAfter;
  122. var untilExpiry = expiry - DateTime.Now;
  123. if (untilExpiry.TotalDays <= 7)
  124. {
  125. CertificateExpiring?.Invoke(expiry);
  126. if (untilExpiry.TotalDays <= 1)
  127. {
  128. CertificateRefreshTimer?.Stop();
  129. CertificateHaltTimer = new Timer(untilExpiry.TotalMilliseconds);
  130. CertificateHaltTimer.Elapsed += HTTPS_Halt_Elapsed;
  131. CertificateHaltTimer.AutoReset = false;
  132. CertificateHaltTimer.Start();
  133. }
  134. }
  135. }
  136. }
  137. /// <summary>
  138. /// Restarts listener in HTTP mode
  139. /// </summary>
  140. /// <param name="sender"></param>
  141. /// <param name="e"></param>
  142. private void HTTPS_Halt_Elapsed(object? sender, ElapsedEventArgs e)
  143. {
  144. CertificateHaltTimer?.Dispose();
  145. CertificateHaltTimer = null;
  146. CertificateExpired?.Invoke();
  147. }
  148. #endregion
  149. }