diff --git a/src/Agent/AutopilotMonitor.Agent.Core/Security/EnrollmentAwaiter.cs b/src/Agent/AutopilotMonitor.Agent.Core/Security/EnrollmentAwaiter.cs
index 8bab37d3..a7cc4b94 100644
--- a/src/Agent/AutopilotMonitor.Agent.Core/Security/EnrollmentAwaiter.cs
+++ b/src/Agent/AutopilotMonitor.Agent.Core/Security/EnrollmentAwaiter.cs
@@ -1,4 +1,6 @@
using System;
+using System.Linq;
+using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
@@ -19,11 +21,6 @@ namespace AutopilotMonitor.Agent.Core.Security
///
/// Polls the certificate store until a valid MDM certificate is found or the timeout expires.
///
- /// Optional specific certificate thumbprint to wait for
- /// Maximum wait time in minutes (0 = wait indefinitely)
- /// Logger for status output
- /// Cancellation token for clean shutdown
- /// The MDM certificate, or null if the timeout expired or was cancelled
public static async Task WaitForMdmCertificateAsync(
string thumbprint = null,
int timeoutMinutes = 480,
@@ -39,30 +36,36 @@ namespace AutopilotMonitor.Agent.Core.Security
while (!cancellationToken.IsCancellationRequested)
{
- // Lightweight check: opens cert store, scans by issuer+EKU, closes — takes milliseconds
- var cert = CertificateHelper.FindMdmCertificate(thumbprint);
+ var cert = CertificateHelper.FindMdmCertificate(thumbprint, logger);
- if (cert != null && CertificateHelper.IsCertificateValid(cert))
+ if (cert != null)
{
+ // No IsCertificateValid check here: freshly provisioned SCEP certs can have
+ // a NotBefore slightly in the future due to clock skew between device and CA.
+ // The cert existing in the store with correct issuer+EKU is sufficient.
var elapsed = DateTime.UtcNow - startTime;
- logger?.Info($"Await-enrollment: MDM certificate found after {FormatElapsed(elapsed)} — Issuer={cert.Issuer}, Thumbprint={cert.Thumbprint}");
+ logger?.Info($"Await-enrollment: MDM certificate found after {FormatElapsed(elapsed)} — " +
+ $"Issuer={cert.Issuer}, Thumbprint={cert.Thumbprint}, " +
+ $"Valid={cert.NotBefore:yyyy-MM-dd HH:mm:ss}..{cert.NotAfter:yyyy-MM-dd HH:mm:ss}");
return cert;
}
var totalElapsed = DateTime.UtcNow - startTime;
- // Check timeout
if (totalElapsed >= timeout)
{
logger?.Warning($"Await-enrollment: Timeout after {FormatElapsed(totalElapsed)} — no MDM certificate found");
+ LogCertificateStoreDetails(logger);
return null;
}
- // Periodic status log (every 1 minute)
+ // Periodic status with cert counts (every 1 minute)
if (DateTime.UtcNow - lastLogTime >= LogInterval)
{
var remaining = timeout - totalElapsed;
- logger?.Info($"Await-enrollment: Waiting for MDM certificate... (elapsed: {FormatElapsed(totalElapsed)}, remaining: {FormatElapsed(remaining)})");
+ var storeSummary = GetCertificateStoreSummary();
+ logger?.Info($"Await-enrollment: Waiting for MDM certificate... " +
+ $"(elapsed: {FormatElapsed(totalElapsed)}, remaining: {FormatElapsed(remaining)}, {storeSummary})");
lastLogTime = DateTime.UtcNow;
}
@@ -80,6 +83,79 @@ namespace AutopilotMonitor.Agent.Core.Security
return null;
}
+ ///
+ /// Returns a short summary of cert counts per store, e.g. "LocalMachine=2, CurrentUser=0".
+ ///
+ private static string GetCertificateStoreSummary()
+ {
+ try
+ {
+ int lmCount = 0, cuCount = 0;
+
+ using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
+ {
+ store.Open(OpenFlags.ReadOnly);
+ lmCount = store.Certificates.Count;
+ }
+
+ using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
+ {
+ store.Open(OpenFlags.ReadOnly);
+ cuCount = store.Certificates.Count;
+ }
+
+ return $"certs in store: LM={lmCount}, CU={cuCount}";
+ }
+ catch
+ {
+ return "certs in store: unknown";
+ }
+ }
+
+ ///
+ /// Full cert store dump — only on timeout to help diagnose why no MDM cert was matched.
+ ///
+ private static void LogCertificateStoreDetails(AgentLogger logger)
+ {
+ if (logger == null) return;
+
+ try
+ {
+ var stores = new[]
+ {
+ new { Location = StoreLocation.LocalMachine, Name = StoreName.My },
+ new { Location = StoreLocation.CurrentUser, Name = StoreName.My }
+ };
+
+ foreach (var storeInfo in stores)
+ {
+ using (var store = new X509Store(storeInfo.Name, storeInfo.Location))
+ {
+ store.Open(OpenFlags.ReadOnly);
+ var certs = store.Certificates.OfType().ToList();
+
+ logger.Info($"Await-enrollment: {storeInfo.Location}\\{storeInfo.Name} — {certs.Count} certificate(s):");
+
+ foreach (var cert in certs)
+ {
+ var hasClientAuth = cert.Extensions
+ .OfType()
+ .Any(ext => ext.EnhancedKeyUsages
+ .OfType()
+ .Any(oid => oid.Value == "1.3.6.1.5.5.7.3.2"));
+
+ logger.Info($" - Issuer={cert.Issuer}, Thumbprint={cert.Thumbprint}, " +
+ $"ClientAuth={hasClientAuth}, Valid={cert.NotBefore:yyyy-MM-dd}..{cert.NotAfter:yyyy-MM-dd}");
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.Warning($"Await-enrollment: Could not read certificate store: {ex.Message}");
+ }
+ }
+
private static string FormatElapsed(TimeSpan elapsed)
{
if (elapsed.TotalHours >= 1)
diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
index b570ddbf..8b84f570 100644
--- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
+++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
@@ -1 +1 @@
-391
+397