public async Task StartScanAsync(IServerObject server, SynchronizationContext ctx) { if (server == null) { return; } syncContext = ctx; lock (_lock) { _syncTable.Clear(); } _visitedNames.Clear(); redirected = globalErrors = globalWarnings = false; server.Log.Clear(); server.Log.AppendLine("**************************************************************************"); server.Log.AppendLine($"Processing '{server.ServerAddress}'"); server.Log.AppendLine("**************************************************************************"); server.Log.AppendLine($"Scan started: {DateTime.Now:dd-MM-yyyy HH:mm:ss}"); using (Entry = new ServerObjectWrapper(server)) { Entry.InternalChain = new X509Chain(!Config.AllowUserTrust); ServicePointManager.SecurityProtocol = (SecurityProtocolType)Config.SslProtocolsToUse; // execute main routine await createRequest(); } // calculate resulting status of the object getEffectiveStatus(); // release resources and close connections NativeEntry.Log.AppendLine("Finished!"); NativeEntry.Log.Progress = 100; NativeEntry.Log.AppendLine("Scan ended: " + DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss")); redirected = false; }
static Boolean serverCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { lock (_lock) { var request = (HttpWebRequest)sender; // normally, the key is presented, but the call to CT may mess this, so silently skip it. if (!_syncTable.ContainsKey(request.RequestUri.ToString())) { return(sslPolicyErrors == SslPolicyErrors.None && chain.ChainStatus.All(x => x.Status == X509ChainStatusFlags.NoError)); } CertProcessor processor = _syncTable[request.RequestUri.ToString()]; ServerObjectWrapper entry = processor.Entry; ICertProcessorConfig config = processor.Config; entry.InternalChain = new X509Chain(!config.AllowUserTrust); if (processor.redirected) { if (!processor._visitedNames.Add(request.Address.Host)) { entry.ServerObject.Log.AppendLine( $"We are redirected to an already visited host: {request.Address.Host}. Stop execution."); processor.shouldProceed = false; request.AllowAutoRedirect = false; return(true); } entry.ServerObject.Log.AppendLine("We are redirected. Entering the certificate validation callback function again."); entry.ServerObject.Log.AppendLine($"Redirected URL: {((HttpWebRequest)sender).Address.AbsoluteUri}"); entry.ServerObject.ChainStatus = 0; } else { entry.ServerObject.Log.AppendLine($"Server returned {chain.ChainElements.Count} certificates."); } if (chain.ChainElements.Count > 1) { entry.ServerObject.Log.AppendLine("Dumping certificates:"); for (Int32 index = 0; index < chain.ChainElements.Count; index++) { entry.ServerObject.Log.AppendLine($"=============================== Certificate {index} ==============================="); try { // there is a bug in .NET 4.5 on Windows 7 when calling ToString(true) on ECC cert entry.ServerObject.Log.AppendLine(chain.ChainElements[index].Certificate.ToString(true)); } catch { // fallback to brief dump entry.ServerObject.Log.AppendLine(chain.ChainElements[index].Certificate.ToString(false)); } entry.InternalChain.ChainPolicy.ExtraStore.Add(chain.ChainElements[index].Certificate); } } Boolean hasNameMismatch = ((Int32)sslPolicyErrors & (Int32)SslPolicyErrors.RemoteCertificateNameMismatch) > 0; processor.executeChain(chain); if (hasNameMismatch) { processor.addStatus(entry.ServerObject.Tree.Last().Flatten().Last(), new X509ChainStatus2 { Status = X509ChainStatusFlags2.NameMismatch }); } entry.InternalChain.Reset(); processor.redirected = true; } return(true); }