22

I have a .NET 3.5 desktop application that had been showing periodic slow downs in functionality whenever the test machine it was on was out of the office.
I managed to replicate the error on a machine in the office without an internet connection, but it was only when i used ANTS performance profiler that i got a clearer picture of what was going on.

In ANTS I saw a "Waiting for synchronization" taking up to 16 seconds that corresponded to the delay I could see in the application when NHibernate tried to load the System.Data.SqlServerCE.dll assembly.
If I tried the action again immediately it would work with no delay but if I left it for 5 minutes then it would be slow to load again the next time I tried it.

From my research so far it appears to be because the SqlServerCE dll is signed and so the system is trying to connect to get the certificate revocation lists and timing out.
Disabling the "Automatically detect settings" setting in the Internet Options LAN settings makes the problem go away, as does disabling the "Check for publishers certificate revocation".
But the admins where this application will be deployed are not going to be happy with the idea of disabling certificate checking on a per machine or per user basis so I really need to get the application level disabling of the CRL check working.

There is the well documented bug in .net 2.0 which describes this behaviour, and offers a possible fix with a config file element.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <runtime>
        <generatePublisherEvidence enabled="false"/>
    </runtime>
</configuration>

This is NOT working for me however even though I am using .net 3.5.
The SQLServerCE dll is being loaded dynamically by NHibernate and I wonder if the fact that it's dynamic could somehow be why the setting isn't working, but I don't know how I could check that.

Can anyone offer suggestions as to why the config setting might not work?
Or is there another way I could disable the check at the application level, perhaps a CAS policy setting that I can use to set an exception for the application when it's installed?
Or is there something I can change in the application to up the trust level or something like that?

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
Colm Clarke
  • 480
  • 1
  • 7
  • 23
  • 1
    Can you install the sqlserverCE assembly in the GAC on the server?, when the assemblies are installed in the GAC, theses assemblies are not verified in load time,only are checked during the installation in the GAC, check this article: http://msdn.microsoft.com/en-us/magazine/cc163610.aspx – majimenezp Nov 06 '13 at 19:38
  • 1
    I couldn't register the System.Data.SqlServerCe.dll from the application in the GAC as it was the private deployment version. Changing to the Desktop version allowed it to load from the GAC, but it hasn't made any difference to the performance. I see in ProcessMonitor that the other sqlce dlls (e.g. sqlceer40EN.dll) are being loaded too (from the SQL Server CE installation directory) and when the first of these is loaded I'm seeing the 15 second delay and calls to WinTrustVerify, etc., but they can't be registered in the GAC because they're not .NET dlls, so why are they being CRL checked? – Colm Clarke Nov 08 '13 at 13:22
  • 1
    it's seeem it's not possible to set a timeout o disable the certification revocation, but check this page: [fix slow application startup](http://rusanu.com/2009/07/24/fix-slow-application-startup-due-to-code-sign-validation/) this guy explain how in the windows registry set the timeout in the request,if you set in a low value, then will like disabling. – majimenezp Nov 12 '13 at 00:33
  • and here says [how certificate revocation works](http://technet.microsoft.com/en-us/library/ee619754(v=ws.10).aspx) that the default timeout it's 15 seconds, that coincide with the ANTS time detected event of "waiting syncronization" – majimenezp Nov 12 '13 at 00:35
  • Another thing, that you can do, it's change the registry with your application and set the timeout the lower as posible. – majimenezp Nov 12 '13 at 00:36
  • @majimenezp I tried those registry settings out and unfortunately they didn't help. Things are actually being a bit weird on this all now. The dlls that appear to be the cause of the hold up are native SQL Server CE dlls, and looking at the stack traces in ProcMon mscorwks.dll doesn't appear to be involved even though the checks on crypto and cert registry keys are being done under the .NET application. It's definitely still something to do with publisher certificate checking because unticking "Check for publisher revocation certificate" still works but something odd is going on. – Colm Clarke Nov 12 '13 at 17:53
  • Have you sniffed the actual CRL call when on a machine with an internet connection? (The CRL may be a red herring). Try to use .NET 4.0 libraries to prove that this is not a regression bug that was in 3.5. If you think that the assembly loading dynamically may be a problem, load it yourself at startup. a possible workaround may be to run something with the library in question (also at startup) in the background every 4.5 minutes to avoid the re-check fail. Try to recreate the problem in a small console app and post the code here. – RepDbg Nov 15 '13 at 01:03

3 Answers3

10

You can specify in code if you want to check the revocation list per application:

ServicePointManager.CheckCertificateRevocationList = false;
AnotherDeveloper
  • 1,242
  • 1
  • 15
  • 36
  • Colm, Is this the first httpwebrequest that is made by the application? I have seen cases where the first web request is extremely slow by a .NET application. – AnotherDeveloper Nov 13 '13 at 19:47
  • There seems to be no call outs to a web server, the slow down we are seeing is in the timeout when it cant find a connection, because the application doesn't have a web connection it will wait the full timeout until it gives up, however it will continue to do this timeout every 5 minutes roughly, I would have hoped that the first time it realized there was no connection it would simply stop trying there after but it doesn't. I have tried registry settings to reduce this timeout period but none of them worked either – Colm Clarke Nov 14 '13 at 10:01
4

In this blog posting (which cites another source) you have two options: disable CRL checking system wide or per app:

Disable CRL Checking Machine-Wide Control Panel -> Internet Options -> Advanced -> Under security, uncheck the Check for publisher's certificate revocation option

Disable CRL Checking For a Specific .Net Application See this Microsoft KB Article: http://support.microsoft.com/kb/936707

chue x
  • 18,573
  • 7
  • 56
  • 70
John Gasper
  • 672
  • 4
  • 12
  • @Nanhydrin, how does this not answer the question? The OP asks, "is there another way I could disable the check at the application level?" This answer seems to deal with exactly that. – Daniel Schilling Nov 11 '13 at 21:00
  • @Daniel-Schilling, the KB article says to use the generatePublisherEvidence element and the hotfix for .NET 2.0, right? This has been tried and hasn't worked and the application is .NET 3.5 which includes the hotfix by default. – Nanhydrin Nov 12 '13 at 12:33
  • 2
    I am also having the same issue. Setting `checkCertificateRevocationList="false"` has no effect, where unchecking the options in Internet Options _does_ work. I'd love to find a programmatic solution to this problem! – Mark Richman Jan 21 '15 at 13:46
0

What solved the problem for me: I (think I) had a problem with online revocation before, so I explicitly switched to offline. Due to to warning, I now had to change...

 _ = builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
     .AddCertificate(
         options =>
         {
             options.AllowedCertificateTypes = CertificateTypes.All;
             options.RevocationMode = X509RevocationMode.Offline;
         }
     );

... to ...

 _ = builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
     .AddCertificate(
         options =>
         {
             options.AllowedCertificateTypes = CertificateTypes.All;
             options.RevocationMode = X509RevocationMode.NoCheck;
         }
     );
Eike
  • 1,167
  • 10
  • 12